[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    [PATCH] vi: cursor positioning after whole-line 'y'
From:       Ron Yorston <rmy () pobox ! com>
Date:       2021-04-30 11:56:12
Message-ID: 608bf05c.GVbeYXlOE9uOiv17%rmy () pobox ! com
[Download RAW message or body]

The 'y' command to yank text should leave the cursor at the start
of the range.  This mostly works correctly in BusyBox vi but not
for whole-line yanks with backward motion, e.g. '2yk' to yank two
lines backwards.  In this case the cursor is left at the end of the
range.

Fix this by returning the actual range from find_range().  Cursor
positioning following whole-line deletion is inconsistent between
vim and traditional vi.  For BusyBox vi chose the option that uses
least code without being exactly compatible with either.

Also, find_range() preserved the value of 'dot', the current cursor
position.  Since this isn't used by either caller of find_range()
we can save a few bytes by not bothering.

function                                             old     new   delta
do_cmd                                              4730    4759     +29
find_range                                           749     686     -63
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 29/-63)            Total: -34 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
---
 editors/vi.c | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/editors/vi.c b/editors/vi.c
index edcf84240..63c7537c2 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -3328,11 +3328,10 @@ static int at_eof(const char *s)
 
 static int find_range(char **start, char **stop, int cmd)
 {
-	char *save_dot, *p, *q, *t;
+	char *p, *q, *t;
 	int buftype = -1;
 	int c;
 
-	save_dot = dot;
 	p = q = dot;
 
 #if ENABLE_FEATURE_VI_YANKMARK
@@ -3421,14 +3420,8 @@ static int find_range(char **start, char **stop, int cmd)
 		}
 	}
 
-	if (buftype == WHOLE || cmd == '<' || cmd == '>') {
-		p = begin_line(p);
-		q = end_line(q);
-	}
-
 	*start = p;
 	*stop = q;
-	dot = save_dot;
 	return buftype;
 }
 
@@ -3896,7 +3889,7 @@ static void do_cmd(int c)
 		if (find_range(&p, &q, c) == -1)
 			goto dc6;
 		i = count_lines(p, q);	// # of lines we are shifting
-		for ( ; i > 0; i--, p = next_line(p)) {
+		for (p = begin_line(p); i > 0; i--, p = next_line(p)) {
 			if (c == '<') {
 				// shift left- remove tab or tabstop spaces
 				if (*p == '\t') {
@@ -4150,12 +4143,16 @@ static void do_cmd(int c)
 # endif
 		if (c == 'y' || c == 'Y')
 			yf = YANKONLY;
-		save_dot = dot;
 #endif
 		// determine range, and whether it spans lines
 		buftype = find_range(&p, &q, c);
 		if (buftype == -1)	// invalid range
 			goto dc6;
+		if (buftype == WHOLE) {
+			save_dot = p;	// final cursor position is start of range
+			p = begin_line(p);
+			q = end_line(q);
+		}
 		dot = yank_delete(p, q, buftype, yf, ALLOW_UNDO);	// delete word
 		if (buftype == WHOLE) {
 			if (c == 'c') {
@@ -4164,15 +4161,9 @@ static void do_cmd(int c)
 				if (dot != (end-1)) {
 					dot_prev();
 				}
-			} else if (c == 'd') {
-				dot_begin();
-				dot_skip_over_ws();
-			}
-#if ENABLE_FEATURE_VI_YANKMARK
-			else /* (c == 'y' || c == 'Y') */ {
+			} else {
 				dot = save_dot;
 			}
-#endif
 		}
 		// if CHANGING, not deleting, start inserting after the delete
 		if (c == 'c') {
-- 
2.31.1

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic