diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-08-01 14:43:57 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-08-01 14:43:57 -0700 |
commit | 4eadfab873ac975326e15e9bdd9405928e0e9cd6 (patch) | |
tree | 08f406ad9f34d9f2c8bc6330baf8a78433df599f | |
parent | 0b4a373f69bf7e4684f03d622ee0c1f3be8e8df5 (diff) | |
download | txr-4eadfab873ac975326e15e9bdd9405928e0e9cd6.tar.gz txr-4eadfab873ac975326e15e9bdd9405928e0e9cd6.tar.bz2 txr-4eadfab873ac975326e15e9bdd9405928e0e9cd6.zip |
listener: support multi-line expressions in plain mode.
* linenoise/linenoise.c (linenoise): If we are in
noninteractive mode, then do not just read one line and return
it. If an enter_callback is defined then keep accumulating
lines while the callback indicates incomplete syntax, until
EOF occurs or the syntax appears complete. Return the lines
glued together, with \n characters replaced by \r, so the line
is correctly entered into the history, and the trailing LF
obliterated, as usual.
* txr.1: Documented new multi-line behavior of plain mode.
-rw-r--r-- | linenoise/linenoise.c | 44 | ||||
-rw-r--r-- | txr.1 | 8 |
2 files changed, 44 insertions, 8 deletions
diff --git a/linenoise/linenoise.c b/linenoise/linenoise.c index 99af2418..c25014cf 100644 --- a/linenoise/linenoise.c +++ b/linenoise/linenoise.c @@ -2528,17 +2528,45 @@ wchar_t *linenoise(lino_t *ls, const wchar_t *prompt) int ifd = lino_os.fileno_fn(ls->tty_ifs); if ( ls->noninteractive || !isatty(ifd)) { - /* Not a tty: read from file / pipe. */ - if (lino_os.getl_fn(ls->tty_ifs, ls->data, nelem(ls->data)) == 0) { - ls->error = (lino_os.eof_fn(ls->tty_ifs) ? lino_eof : lino_ioerr); - return 0; + wchar_t *ret = 0; + size_t len = 0, i; + + for (;;) { + size_t nlen; + /* Not a tty: read from file / pipe. */ + if (lino_os.getl_fn(ls->tty_ifs, ls->data, nelem(ls->data)) == 0) { + ls->error = (lino_os.eof_fn(ls->tty_ifs) ? lino_eof : lino_ioerr); + break; + } + + nlen = wcslen(ls->data); + + { + wchar_t *nret = lino_os.wrealloc_fn(ret, len + nlen + 1); + if (nret == 0) { + lino_os.free_fn(ret); + return 0; + } + wmemcpy(nret + len, ls->data, nlen + 1); + ret = nret; + len = len + nlen; + } + + if (!ls->enter_callback || ls->enter_callback(ret, ls->ce_ctx)) + break; } - count = wcslen(ls->data); + if (ret != 0) { + if (len && ret[len - 1] == '\n') + ret[len-1] = '\0'; - if (count && ls->data[count-1] == '\n') - ls->data[count-1] = '\0'; - return lino_os.wstrdup_fn(ls->data); + for (i = 0; i < len; i++) { + if (ret[i] == '\n') + ret[i] = '\r'; + } + } + + return ret; } else { wchar_t *ret = 0; #ifdef SIGWINCH @@ -82547,6 +82547,14 @@ for accessing evaluation results are established. Lines are still entered into the history, and the interactive profile is still processed, as usual. +Plain mode reads whole lines of input, yet recognizes multi-line expressions. +Whenever a line of input is read which represents incomplete syntax, another +line of input is read and appended to that line. This repeats until the +accumulated input represents complete syntax, and is then processed as a unit. + +Each unit of input is expected to represent a single expression, otherwise +an error is diagnosed. + .SS* Interactive Profile File Unless the |