Stay in os_read_line on resize.
authorTimo Korvola <tkorvola@iki.fi>
Sun, 18 Feb 2018 18:24:46 +0000 (20:24 +0200)
committerTimo Korvola <tkorvola@iki.fi>
Sun, 18 Feb 2018 18:24:46 +0000 (20:24 +0200)
The callers of os_read_line weren't taking a return value of ZC_BAD
too well.  So just chop input to fit and keep editing.

Document that width is adjusted according to terminal width.

#42: Handle terminal resizing

src/curses/ux_input.c

index 8949284dec62defdc99355b64f88c26349cc4d38..e4d3f4c8b3d8e2595de0b8242f3fb9c55bcb43cf 100644 (file)
@@ -446,7 +446,9 @@ static void scrnset(int start, int c, int n)
  * after timeout/10 seconds (and the return value is ZC_TIME_OUT).
  *
  * The complete input line including the cursor must fit in "width"
- * screen units.
+ * screen units.  If the screen width changes during input, width
+ * is adjusted by the same amount.  bufmax is not adjusted: buf must
+ * contain space for at least bufmax + 1 characters (including final NUL).
  *
  * The function may be called once again to continue after timeouts,
  * misplaced mouse clicks or hot keys. In this case the "continued"
@@ -493,13 +495,16 @@ zchar os_read_line (int bufmax, zchar *buf, int timeout, int width,
        ch = unix_read_char(1);
        getyx(stdscr, y, x2);
         max = MIN(h_screen_width - margin, bufmax);
-       if (len >= max) {
-           /* The terminal has become too narrow for the current input. */
-           buf[len] = '\0';
-           return ZC_BAD;
+        /* The screen has shrunk and input no longer fits.  Chop. */
+       if (len > max) {
+           len = max;
+           if (scrpos > len)
+               scrpos = len;
+           if (searchpos > len)
+               searchpos = len;
        }
         switch (ch) {
-       case ZC_BACKSPACE:      /* Delete preceeding character */
+       case ZC_BACKSPACE:      /* Delete preceding character */
            if (scrpos != 0) {
                len--; scrpos--; searchpos = -1;
                scrnmove(x + scrpos, x + scrpos + 1, len - scrpos);