From 7b4c2276a89fca0dfedf73db07fbe20fff17a0de Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 25 Mar 2021 14:20:56 +0000 Subject: [PATCH] vi: fix word operations across line boundaries Commit 4b49422a0 (vi: fix changes to word at end of line. Closes 11796) fixed a problem where an operation on a word at the end of a line followed by a line starting with whitespace incorrectly joined the lines. However it also broke the case where operating on multiple words across a line boundary *should* join the lines. Fix this by detecting when trailing whitepace in a word operation includes a newline. Whitespace beyond the newline is excluded from consideration. function old new delta do_cmd 5083 5088 +5 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/0 up/down: 5/0) Total: 5 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- editors/vi.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/editors/vi.c b/editors/vi.c index abc0aeae8..1bc2d08ad 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -3774,14 +3774,16 @@ static void do_cmd(int c) place_cursor(0, 0); if (c1 == 27) { // ESC- user changed mind and wants out c = c1 = 27; // Escape- do nothing - } else if (strchr("wW", c1)) { - ml = 0; // multi-line ranges aren't allowed for words - if (c == 'c') { - // don't include trailing WS as part of word - while (isspace(*q) && q > p) { - q--; - } + } else if (c1 == 'w' || c1 == 'W') { + char *q0 = q; + // don't include trailing WS as part of word + while (q > p && isspace(*q)) { + if (*q-- == '\n') + q0 = q; } + // for non-change operations WS after NL is not part of word + if (c != 'c' && q != p && *q != '\n') + q = q0; dot = yank_delete(p, q, ml, yf, ALLOW_UNDO); // delete word } else if (strchr("^0bBeEft%$ lh\b\177", c1)) { // partial line copy text into a register and delete