From 2bc4df81e615f31a3ae8e8e81a439ce66d176c3e Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 5 Feb 2019 01:35:48 -0800 Subject: linenoise: bugfix: regression in mlmode line wrap. The following problem happens: when charaters are inserted past the end of the line such that it wraps, hitting backspace or any cursor movement causes a spurious scroll. This was caused on Nov 1 2018 by bf85503b (linenoise: avoid refresh for new text in multi-line mode). The reason is that the maxrows variable isn't updated when we trivially add a character without repainting. * linenoise/linenoise.c (lino state): Document special value for need_refresh: when it is 2, the refresh doesn't perform a any output, but recalculates maxrows. (refreh_multiline): If need_refresh is 2, bail after updating maxrows. (edit_insert): When trivially adding a character at the end and just outputting it, if in multi-line mode, set need_refresh to 2. --- linenoise/linenoise.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'linenoise') diff --git a/linenoise/linenoise.c b/linenoise/linenoise.c index 9236644b..49b1faec 100644 --- a/linenoise/linenoise.c +++ b/linenoise/linenoise.c @@ -131,7 +131,7 @@ struct lino_state { int maxrows; /* Maximum num of rows used so far (multiline mode) */ int history_index; /* The history index we are currently editing. */ int need_resize; /* Need resize flag. */ - int need_refresh; /* Need refresh. */ + int need_refresh; /* Need refresh: 1 == full; 2 == recalc maxrows only. */ int selmode; /* Visual selection being made. */ int selinclusive; /* Selections include character right of endpoint. */ int noninteractive; /* No character editing, even if input is tty. */ @@ -1146,6 +1146,9 @@ static void refresh_multiline(lino_t *l) { if (rows > l->maxrows) l->maxrows = rows; + if (l->need_refresh == 2) + return; + /* First step: clear all the lines used before. To do so start by * going to the last row. */ ab_init(&ab); @@ -1569,6 +1572,8 @@ static int edit_insert(lino_t *l, wchar_t c) { wchar_t str[2] = { c }; if (!lino_os.puts_fn(l->tty_ofs, str)) return -1; + if (l->mlmode) + l->need_refresh = 2; /* just recalculate l->maxrows */ } else { l->need_refresh = 1; } -- cgit v1.2.3