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

List:       busybox
Subject:    [PATCH 03/10] vi: remember cursor column during vertical motion
From:       Ron Yorston <rmy () pobox ! com>
Date:       2021-03-28 12:20:01
Message-ID: 60607471.gExujGvL9wg/j/4M%rmy () pobox ! com
[Download RAW message or body]

When the 'j'/'k' commands or up/down arrow keys are used to move
the cursor vertically 'vi' remembers the original cursor column
and positions the cursor there if possible.  Also, if the '$'
command has been used to position the cursor at the end of a line
vertical movements keep the cursor at the end of the line.

Make BusyBox 'vi' do the same.

function                                             old     new   delta
refresh                                              674     694     +20
do_cmd                                              4853    4861      +8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 28/0)               Total: 28 bytes

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

diff --git a/editors/vi.c b/editors/vi.c
index f4da38071..2c724a448 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -263,6 +263,8 @@ enum {
 	S_OVER_WS = 3,		// used in skip_thing() for moving "dot"
 	S_END_PUNCT = 4,	// used in skip_thing() for moving "dot"
 	S_END_ALNUM = 5,	// used in skip_thing() for moving "dot"
+
+	C_END = -1,	// cursor is at end of line due to '$' command
 };
 
 
@@ -354,6 +356,8 @@ struct globals {
 	sigjmp_buf restart;     // int_handler() jumps to location remembered here
 #endif
 	struct termios term_orig; // remember what the cooked mode was
+	int cindex;               // saved character index for up/down motion
+	smallint keep_index;      // retain saved character index
 #if ENABLE_FEATURE_VI_COLON
 	char *initial_cmds[3];  // currently 2 entries, NULL terminated
 #endif
@@ -462,6 +466,8 @@ struct globals {
 #define context_end    (G.context_end   )
 #define restart        (G.restart       )
 #define term_orig      (G.term_orig     )
+#define cindex         (G.cindex        )
+#define keep_index     (G.keep_index    )
 #define initial_cmds   (G.initial_cmds  )
 #define readbuffer     (G.readbuffer    )
 #define scr_out_buf    (G.scr_out_buf   )
@@ -992,6 +998,9 @@ static void refresh(int full_screen)
 
 	place_cursor(crow, ccol);
 
+	if (!keep_index)
+		cindex = ccol + offset;
+
 	old_offset = offset;
 #undef old_offset
 }
@@ -3096,6 +3105,7 @@ static void do_cmd(int c)
 //	cnt = yf = 0; // quiet the compiler
 //	p = q = save_dot = buf; // quiet the compiler
 	memset(buf, '\0', sizeof(buf));
+	keep_index = FALSE;
 
 	show_status_line();
 
@@ -3220,9 +3230,10 @@ static void do_cmd(int c)
 	case KEYCODE_DOWN:	// cursor key Down
 		do {
 			dot_next();		// go to next B-o-l
-			// try stay in same col
-			dot = move_to_col(dot, ccol + offset);
 		} while (--cmdcnt > 0);
+		// try to stay in saved column
+		dot = cindex == C_END ? end_line(dot) : move_to_col(dot, cindex);
+		keep_index = TRUE;
 		break;
 	case 12:			// ctrl-L  force redraw whole screen
 	case 18:			// ctrl-R  force redraw
@@ -3348,6 +3359,8 @@ static void do_cmd(int c)
 				break;
 			dot_next();
 		}
+		cindex = C_END;
+		keep_index = TRUE;
 		break;
 	case '%':			// %- find matching char of pair () [] {}
 		for (q = dot; q < end && *q != '\n'; q++) {
@@ -3827,8 +3840,10 @@ static void do_cmd(int c)
 	case KEYCODE_UP:		// cursor key Up
 		do {
 			dot_prev();
-			dot = move_to_col(dot, ccol + offset);	// try stay in same col
 		} while (--cmdcnt > 0);
+		// try to stay in saved column
+		dot = cindex == C_END ? end_line(dot) : move_to_col(dot, cindex);
+		keep_index = TRUE;
 		break;
 	case 'r':			// r- replace the current char with user input
 		c1 = get_one_char();	// get the replacement char
-- 
2.30.2

_______________________________________________
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