commit e1bf3d6e8c8b52e910473d62f747176f22e206b1 from: Omar Polo date: Fri Jun 07 18:25:58 2024 UTC add mini-edit-external it's bound by default to C-x in the minibuffer keymap. It'll open an external editor to edit the content of the minibuffer. When the editor exits, we'll call the completion function with the content of the file. Stuff inputted with an external editor are not persisted to the history thought. That would require the UI to handle multiline strings which is currently impossible. commit - 3c7ed8d83ed06a3b7f30ceb6ba692e515f91e980 commit + e1bf3d6e8c8b52e910473d62f747176f22e206b1 blob - b2d69256bdb2e6b0a75dff773828e3988045022f blob + f98e328499a42678d5e82a73dfc56a7126464d7c --- cmd.c +++ cmd.c @@ -1176,4 +1176,12 @@ cmd_search(struct buffer *buffer) enter_minibuffer(sensible_self_insert, search_select, exit_minibuffer, NULL, NULL, NULL, 0); strlcpy(ministate.prompt, "Search: ", sizeof(ministate.prompt)); +} + +void +cmd_mini_edit_external(struct buffer *buffer) +{ + GUARD_READ_ONLY(); + + ui_edit_externally(); } blob - bb81e7198c325db75faf09ebfbca2e3a5f86d316 blob + 6031a71966db32d3279e35426e334c79e5d776b1 --- cmd.h +++ cmd.h @@ -42,6 +42,7 @@ CMD(cmd_mini_abort, "Abort the current minibuffer act CMD(cmd_mini_complete_and_exit, "Complete the current minibuffer action."); CMD(cmd_mini_delete_backward_char, "Delete the character before the point."); CMD(cmd_mini_delete_char, "Delete the character after the point."); +CMD(cmd_mini_edit_external, "Use an external editor to compose the text."); CMD(cmd_mini_goto_beginning, "Select the first completion."); CMD(cmd_mini_goto_end, "Select the last completion."); CMD(cmd_mini_kill_line, "Delete from point until the end of the line."); blob - ab7dfac0e780c559474ab835780372a9a766a5fe blob + 13220c95e1ac0c13dc33f87674639ee5752ef16f --- defaults.c +++ defaults.c @@ -502,6 +502,7 @@ load_default_keys(void) minibuffer_set_key("del", cmd_mini_delete_backward_char); minibuffer_set_key("backspace", cmd_mini_delete_backward_char); minibuffer_set_key("C-h", cmd_mini_delete_backward_char); + minibuffer_set_key("C-x", cmd_mini_edit_external); minibuffer_set_key("C-b", cmd_backward_char); minibuffer_set_key("C-f", cmd_forward_char); blob - 519753fc89a5c9e6738d0786725f9815c5668644 blob + 7ffc4801c3f0d75961f0597e18289164fe3aeb19 --- ui.c +++ ui.c @@ -1407,4 +1407,87 @@ again: clear(); ui_schedule_redraw(); } + +#define TMPFILE "/tmp/telescope.XXXXXXXXXX" + +void +ui_edit_externally(void) +{ + FILE *fp; + char buf[1024 + 1]; + size_t r, len = 0; + const char *editor; + char sfn[sizeof(TMPFILE)]; + pid_t pid; + int fd, ret, s; + if (!in_minibuffer) { + message("Not in minibuffer!"); + return; + } + + if (ministate.compl.must_select || ministate.donefn == NULL) { + message("Can't use an external editor to complete"); + return; + } + + strlcpy(sfn, TMPFILE, sizeof(sfn)); + if ((fd = mkstemp(sfn)) == -1) { + message("failed to create a temp file: %s", strerror(errno)); + return; + } + (void) write(fd, ministate.buf, strlen(ministate.buf)); + close(fd); + + if ((editor = getenv("VISUAL")) == NULL || + (editor = getenv("EDITOR")) == NULL) + editor = "ed"; + + endwin(); + fprintf(stderr, "%s: running %s %s\n", getprogname(), editor, sfn); + + switch (pid = fork()) { + case -1: + message("failed to fork: %s", strerror(errno)); + (void) unlink(sfn); + return; + case 0: + execlp(editor, editor, sfn, NULL); + warn("exec \"%s\" failed", editor); + _exit(1); + } + + do { + ret = waitpid(pid, &s, 0); + } while (ret == -1 && errno == EINTR); + + refresh(); + clear(); + ui_schedule_redraw(); + + if (WIFSIGNALED(s) || WEXITSTATUS(s) != 0) { + message("%s failed", editor); + (void) unlink(sfn); + return; + } + + if ((fp = fopen(sfn, "r")) == NULL) { + message("can't open temp file!"); + (void) unlink(sfn); + return; + } + (void) unlink(sfn); + + while (len < sizeof(buf) - 1) { + r = fread(buf + len, 1, sizeof(buf) - 1 - len, fp); + len += r; + if (r == 0) + break; + } + buf[len] = '\0'; + while (len > 0 && buf[len-1] == '\n') + buf[--len] = '\0'; + + ministate.donefn(buf); + exit_minibuffer(); +} blob - faa3c3ec05175a95c64bbbe4cf3be10c56e78e86 blob + fbcce36ac69ef321f6dbbeed10e560f77d5cb8c4 --- ui.h +++ ui.h @@ -158,5 +158,6 @@ void ui_read(const char *, void (*)(const char *, st void ui_other_window(void); void ui_suspend(void); void ui_end(void); +void ui_edit_externally(void); #endif