[git commit] vi: improve operations involving paragraph movement

Denys Vlasenko vda.linux at googlemail.com
Mon Mar 29 10:16:21 UTC 2021


commit: https://git.busybox.net/busybox/commit/?id=d56da680577ae5ad43833040a310706e8331c684
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

Movement by paragraph doesn't always involve whole lines.  If the
cursor is positioned in the middle of a line deleting to either end
of the paragraph will result in one partial line and zero or more
full lines.

Adjust the end of ranges delimited by paragraph movement to more
closely match what vi does.

function                                             old     new   delta
find_range                                           467     518     +51
at_eof                                                 -      49     +49
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/0 up/down: 100/0)             Total: 100 bytes

Signed-off-by: Ron Yorston <rmy at pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 editors/vi.c | 30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/editors/vi.c b/editors/vi.c
index 5d4b0f20e..323ca4427 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -3051,6 +3051,12 @@ static void int_handler(int sig)
 
 static void do_cmd(int c);
 
+static int at_eof(const char *s)
+{
+	// does 's' point to end of file, even with no terminating newline?
+	return ((s == end - 2 && s[1] == '\n') || s == end - 1);
+}
+
 static int find_range(char **start, char **stop, char c)
 {
 	char *save_dot, *p, *q, *t;
@@ -3064,7 +3070,7 @@ static int find_range(char **start, char **stop, char c)
 		buftype = WHOLE;
 		if (--cmdcnt > 0)
 			do_cmd('j');
-	} else if (strchr("^%$0bBeEfFtTh|\b\177", c)) {
+	} else if (strchr("^%$0bBeEfFtTh|{}\b\177", c)) {
 		// These cmds operate on char positions
 		buftype = PARTIAL;
 		do_cmd(c);		// execute movement cmd
@@ -3074,9 +3080,9 @@ static int find_range(char **start, char **stop, char c)
 		buftype = MULTI;
 		do_cmd(c);		// execute movement cmd
 		// step back one char, but not if we're at end of file
-		if (dot > p && !((dot == end - 2 && end[-1] == '\n') || dot == end - 1))
+		if (dot > p && !at_eof(dot))
 			dot--;
-	} else if (strchr("GHL+-jk{}\r\n", c)) {
+	} else if (strchr("GHL+-jk\r\n", c)) {
 		// these operate on whole lines
 		buftype = WHOLE;
 		do_cmd(c);		// execute movement cmd
@@ -3101,14 +3107,26 @@ static int find_range(char **start, char **stop, char c)
 		p = t;
 	}
 
+	// movements which don't include end of range
+	if (q > p) {
+		if (strchr("^0bBFTh|\b\177", c)) {
+			q--;
+		} else if (strchr("{}", c)) {
+			buftype = (p == begin_line(p) && (*q == '\n' || at_eof(q))) ?
+							WHOLE : MULTI;
+			if (!at_eof(q)) {
+				q--;
+				if (q > p && p != begin_line(p))
+					q--;
+			}
+		}
+	}
+
 	if (buftype == WHOLE) {
 		p = begin_line(p);
 		q = end_line(q);
 	}
 
-	// movements which don't include end of range
-	if (q > p && strchr("^0bBFTh|\b\177", c)) q--;
-
 	*start = p;
 	*stop = q;
 	dot = save_dot;


More information about the busybox-cvs mailing list