From 22337dffd4760abeb5651f5b5ca01f90da44e9f7 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 7 Sep 2017 06:33:46 -0700 Subject: linenoise: visual feedback for incomplete entry. When a line of input is incomplete and the cursor is at the end of that line, hitting Enter causes an uncomfortable ambiguity. Although the cursor moves to the next line, it is not clear whether that is because the input is being accepted, or whether the expression which was entered is executing. For instance, these appear to behave the same way: > (while t[Enter][Enter]... > (while t)[Enter][Enter]... One is just waiting for more input; the other is sitting in an infinite loop just echoing the newline characters. To partially address this issue, we introduce a visual feedback mechanism. When Enter is issued at the end of an incomplete line, then immediately after the insertion of Enter, the character ! is flashed twice, alerting the user that the line is incomplete. In other situations, there isn't any feedback. An infinite loop or lengthy calculation like (while t) looks the same as code which is reading input like (get-line). * linenoise/linenoise.c (LINNOISE_FLASH_DELAY): New macro. (flash): New static function. (edit): Call flash to flash the ! character when Enter is issued at the end of an incomplete line, and we are not in paste mode. --- linenoise/linenoise.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/linenoise/linenoise.c b/linenoise/linenoise.c index a80ca3ab..09bc4c10 100644 --- a/linenoise/linenoise.c +++ b/linenoise/linenoise.c @@ -76,6 +76,7 @@ #define LINENOISE_MAX_LINE 1024 #define LINENOISE_MAX_DISP (LINENOISE_MAX_LINE * 8) #define LINENOISE_PAREN_DELAY 400000 +#define LINENOISE_FLASH_DELAY 200000 #define LINENOISE_MAX_UNDO 200 /* The lino_state structure represents the state during line editing. @@ -1355,6 +1356,26 @@ static void paren_jump(lino_t *l) } } +static void flash(lino_t *l, int ch) +{ + int i; + + if (l->dlen >= (int) sizeof l->data - 1) + return; + + for (i = 0; i < 2; i++) { + if (i > 0) + usec_delay(l, LINENOISE_FLASH_DELAY); + l->data[l->dlen++] = ch; + l->data[l->dlen] = 0; + refresh_line(l); + usec_delay(l, LINENOISE_FLASH_DELAY); + l->data[--l->dlen] = 0; + refresh_line(l); + } +} + + static void update_sel(lino_t *l) { if (l->selmode) { @@ -2023,6 +2044,8 @@ static int edit(lino_t *l, const char *prompt) l->error = lino_ioerr; goto out; } + if (l->dpos == l->dlen) + flash(l, '!'); break; } if (l->mlmode) @@ -2086,6 +2109,8 @@ static int edit(lino_t *l, const char *prompt) l->error = lino_ioerr; goto out; } + if (!paste && l->dpos == l->dlen) + flash(l, '!'); break; } if (l->mlmode) -- cgit v1.2.3