aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-06-16 14:46:01 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2021-06-16 23:53:03 +0200
commitac04eb3657f99f6952971d8ceb8a82d73b783de8 (patch)
treeba7cf6b16960129600aafe9288657e75bb9f96b8
parentf1d21b743485defb39fada03b27878efb1e2f7e3 (diff)
downloadbusybox-w32-ac04eb3657f99f6952971d8ceb8a82d73b783de8.tar.gz
busybox-w32-ac04eb3657f99f6952971d8ceb8a82d73b783de8.tar.bz2
busybox-w32-ac04eb3657f99f6952971d8ceb8a82d73b783de8.zip
vi: up/down motion beyond end of file should fail
In traditional vi and vim line motion commands ('+'/'-'/'j'/'k') fail if the movement would exceed the bounds of the file. BusyBox vi allowed such commands to succeed, leaving the cursor on the first or last character of the file. Make BusyBox vi work like vi/vim. For the 'G'/'H'/'L' commands traditional vi treats an out of bounds result as an error, vim doesn't. BusyBox vi behaves like vim, both before and after this patch. function old new delta do_cmd 4785 4851 +66 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/0 up/down: 66/0) Total: 66 bytes Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--editors/vi.c63
1 files changed, 38 insertions, 25 deletions
diff --git a/editors/vi.c b/editors/vi.c
index 3daa0756b..231c62809 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -3635,24 +3635,30 @@ static void do_cmd(int c)
3635 case 10: // Newline ^J 3635 case 10: // Newline ^J
3636 case 'j': // j- goto next line, same col 3636 case 'j': // j- goto next line, same col
3637 case KEYCODE_DOWN: // cursor key Down 3637 case KEYCODE_DOWN: // cursor key Down
3638 case 13: // Carriage Return ^M
3639 case '+': // +- goto next line
3640 q = dot;
3638 do { 3641 do {
3639 dot_next(); // go to next B-o-l 3642 p = next_line(q);
3643 if (p == end_line(q)) {
3644 indicate_error();
3645 goto dc1;
3646 }
3647 q = p;
3640 } while (--cmdcnt > 0); 3648 } while (--cmdcnt > 0);
3641 // try to stay in saved column 3649 dot = q;
3642 dot = cindex == C_END ? end_line(dot) : move_to_col(dot, cindex); 3650 if (c == 13 || c == '+') {
3643 keep_index = TRUE; 3651 dot_skip_over_ws();
3652 } else {
3653 // try to stay in saved column
3654 dot = cindex == C_END ? end_line(dot) : move_to_col(dot, cindex);
3655 keep_index = TRUE;
3656 }
3644 break; 3657 break;
3645 case 12: // ctrl-L force redraw whole screen 3658 case 12: // ctrl-L force redraw whole screen
3646 case 18: // ctrl-R force redraw 3659 case 18: // ctrl-R force redraw
3647 redraw(TRUE); // this will redraw the entire display 3660 redraw(TRUE); // this will redraw the entire display
3648 break; 3661 break;
3649 case 13: // Carriage Return ^M
3650 case '+': // +- goto next line
3651 do {
3652 dot_next();
3653 } while (--cmdcnt > 0);
3654 dot_skip_over_ws();
3655 break;
3656 case 21: // ctrl-U scroll up half screen 3662 case 21: // ctrl-U scroll up half screen
3657 dot_scroll((rows - 2) / 2, -1); 3663 dot_scroll((rows - 2) / 2, -1);
3658 break; 3664 break;
@@ -3818,12 +3824,6 @@ static void do_cmd(int c)
3818 case ',': // ,- repeat latest search in opposite direction 3824 case ',': // ,- repeat latest search in opposite direction
3819 dot_to_char(c != ',' ? last_search_cmd : last_search_cmd ^ 0x20); 3825 dot_to_char(c != ',' ? last_search_cmd : last_search_cmd ^ 0x20);
3820 break; 3826 break;
3821 case '-': // -- goto prev line
3822 do {
3823 dot_prev();
3824 } while (--cmdcnt > 0);
3825 dot_skip_over_ws();
3826 break;
3827#if ENABLE_FEATURE_VI_DOT_CMD 3827#if ENABLE_FEATURE_VI_DOT_CMD
3828 case '.': // .- repeat the last modifying command 3828 case '.': // .- repeat the last modifying command
3829 // Stuff the last_modifying_cmd back into stdin 3829 // Stuff the last_modifying_cmd back into stdin
@@ -4029,9 +4029,10 @@ static void do_cmd(int c)
4029 if (cmdcnt > (rows - 1)) { 4029 if (cmdcnt > (rows - 1)) {
4030 cmdcnt = (rows - 1); 4030 cmdcnt = (rows - 1);
4031 } 4031 }
4032 if (--cmdcnt > 0) { 4032 while (--cmdcnt > 0) {
4033 do_cmd('+'); 4033 dot_next();
4034 } 4034 }
4035 dot_begin();
4035 dot_skip_over_ws(); 4036 dot_skip_over_ws();
4036 break; 4037 break;
4037 case 'I': // I- insert before first non-blank 4038 case 'I': // I- insert before first non-blank
@@ -4068,8 +4069,8 @@ static void do_cmd(int c)
4068 if (cmdcnt > (rows - 1)) { 4069 if (cmdcnt > (rows - 1)) {
4069 cmdcnt = (rows - 1); 4070 cmdcnt = (rows - 1);
4070 } 4071 }
4071 if (--cmdcnt > 0) { 4072 while (--cmdcnt > 0) {
4072 do_cmd('-'); 4073 dot_prev();
4073 } 4074 }
4074 dot_begin(); 4075 dot_begin();
4075 dot_skip_over_ws(); 4076 dot_skip_over_ws();
@@ -4234,12 +4235,24 @@ static void do_cmd(int c)
4234 } 4235 }
4235 case 'k': // k- goto prev line, same col 4236 case 'k': // k- goto prev line, same col
4236 case KEYCODE_UP: // cursor key Up 4237 case KEYCODE_UP: // cursor key Up
4238 case '-': // -- goto prev line
4239 q = dot;
4237 do { 4240 do {
4238 dot_prev(); 4241 p = prev_line(q);
4242 if (p == begin_line(q)) {
4243 indicate_error();
4244 goto dc1;
4245 }
4246 q = p;
4239 } while (--cmdcnt > 0); 4247 } while (--cmdcnt > 0);
4240 // try to stay in saved column 4248 dot = q;
4241 dot = cindex == C_END ? end_line(dot) : move_to_col(dot, cindex); 4249 if (c == '-') {
4242 keep_index = TRUE; 4250 dot_skip_over_ws();
4251 } else {
4252 // try to stay in saved column
4253 dot = cindex == C_END ? end_line(dot) : move_to_col(dot, cindex);
4254 keep_index = TRUE;
4255 }
4243 break; 4256 break;
4244 case 'r': // r- replace the current char with user input 4257 case 'r': // r- replace the current char with user input
4245 c1 = get_one_char(); // get the replacement char 4258 c1 = get_one_char(); // get the replacement char