summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-08-01 14:43:57 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-08-01 14:43:57 -0700
commit4eadfab873ac975326e15e9bdd9405928e0e9cd6 (patch)
tree08f406ad9f34d9f2c8bc6330baf8a78433df599f
parent0b4a373f69bf7e4684f03d622ee0c1f3be8e8df5 (diff)
downloadtxr-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.c44
-rw-r--r--txr.18
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
diff --git a/txr.1 b/txr.1
index 91dc6042..62c791df 100644
--- a/txr.1
+++ b/txr.1
@@ -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