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
commit86a73822c12bcdb40cad20f5e67ad3aa294a452a (patch)
tree08f406ad9f34d9f2c8bc6330baf8a78433df599f
parentcf3cc13790d504d7c6e289d0044b652fc63ed6cd (diff)
downloadtxr-86a73822c12bcdb40cad20f5e67ad3aa294a452a.tar.gz
txr-86a73822c12bcdb40cad20f5e67ad3aa294a452a.tar.bz2
txr-86a73822c12bcdb40cad20f5e67ad3aa294a452a.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