summaryrefslogtreecommitdiffstats
path: root/linenoise
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-09-16 20:50:04 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-09-16 20:50:04 -0700
commit0007855e3b1b2114fb95c37ecd2e4daca6046a76 (patch)
tree6599133f8d99819b053a6795f1c032106cbdbef8 /linenoise
parentd8257ec1f490f80b5d168def3cb4e36d969fe526 (diff)
downloadtxr-0007855e3b1b2114fb95c37ecd2e4daca6046a76.tar.gz
txr-0007855e3b1b2114fb95c37ecd2e4daca6046a76.tar.bz2
txr-0007855e3b1b2114fb95c37ecd2e4daca6046a76.zip
linenoise: edit command line in external editor.
* linenoise/linenoise.c (tr, edit_in_editor): New static functions. (edit): edit_in_editor hooked in under Ctrl-X Ctrl-E. * txr.1: Documented.
Diffstat (limited to 'linenoise')
-rw-r--r--linenoise/linenoise.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/linenoise/linenoise.c b/linenoise/linenoise.c
index 515e775d..a8ed8ba1 100644
--- a/linenoise/linenoise.c
+++ b/linenoise/linenoise.c
@@ -1002,6 +1002,62 @@ static void edit_delete_prev_word(lino_t *l) {
refresh_line(l);
}
+static void tr(char *s, int find, int rep)
+{
+ for (; *s; s++)
+ if (*s == find)
+ *s = rep;
+}
+
+static void edit_in_editor(lino_t *l) {
+ char *template = ".linotmpXXXXXX";
+ FILE *fo = 0;
+ char *ed = getenv("EDITOR");
+ char path[128];
+
+ if (ed) {
+ char *ho = getenv("HOME");
+ int fd;
+
+ if (ho)
+ snprintf(path, sizeof path, "%s/%s", ho, template);
+ else
+ snprintf(path, sizeof path, "%s", template);
+
+ if ((fd = mkstemp(path)) != -1)
+ fo = fdopen(fd, "w");
+
+ if (!fo && fd != -1)
+ close(fd);
+ }
+
+ if (fo) {
+ char cmd[256];
+ snprintf(cmd, sizeof cmd, "%s %s", ed, path);
+ tr(l->data, '\r', '\n');
+ if (fputs(l->data, fo) != EOF && putc('\n', fo) != EOF &&
+ fflush(fo) == 0)
+ {
+ FILE *fi;
+ int nread;
+
+ if (system(cmd) == 0 && (fi = fopen(path, "r")) != 0) {
+ nread = fread(l->data, 1, sizeof l->data - 1, fi);
+ fclose(fi);
+ l->data[nread] = 0;
+ if (nread > 0 && l->data[nread - 1] == '\n')
+ l->data[--nread] = 0;
+ l->dpos = l->dlen = nread;
+ tr(l->data, '\n', '\r');
+ refresh_line(l);
+ }
+ }
+
+ fclose(fo);
+ remove(path);
+ }
+}
+
/* This function is the core of the line editing capability of linenoise.
* It expects 'fd' to be already in "raw mode" so that every key pressed
* will be returned ASAP to read().
@@ -1066,6 +1122,9 @@ static int edit(lino_t *l, const char *prompt)
extended = 0;
switch (c) {
+ case CTL('E'):
+ edit_in_editor(l);
+ break;
default:
generate_beep(l);
break;