aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-04-30 12:56:12 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2021-05-04 14:51:48 +0200
commit24effc7a3f32b3d4e78779473ddc683848ac3cb0 (patch)
treef4f6285079cc73f641ed217015689d1894705dd1
parent147ac93a065e215545488337efbaa6dceebc04d0 (diff)
downloadbusybox-w32-24effc7a3f32b3d4e78779473ddc683848ac3cb0.tar.gz
busybox-w32-24effc7a3f32b3d4e78779473ddc683848ac3cb0.tar.bz2
busybox-w32-24effc7a3f32b3d4e78779473ddc683848ac3cb0.zip
vi: cursor positioning after whole-line 'y'
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> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--editors/vi.c25
1 files changed, 8 insertions, 17 deletions
diff --git a/editors/vi.c b/editors/vi.c
index 99babccbb..c7e7c67d5 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -3328,11 +3328,10 @@ static int at_eof(const char *s)
3328 3328
3329static int find_range(char **start, char **stop, int cmd) 3329static int find_range(char **start, char **stop, int cmd)
3330{ 3330{
3331 char *save_dot, *p, *q, *t; 3331 char *p, *q, *t;
3332 int buftype = -1; 3332 int buftype = -1;
3333 int c; 3333 int c;
3334 3334
3335 save_dot = dot;
3336 p = q = dot; 3335 p = q = dot;
3337 3336
3338#if ENABLE_FEATURE_VI_YANKMARK 3337#if ENABLE_FEATURE_VI_YANKMARK
@@ -3421,14 +3420,8 @@ static int find_range(char **start, char **stop, int cmd)
3421 } 3420 }
3422 } 3421 }
3423 3422
3424 if (buftype == WHOLE || cmd == '<' || cmd == '>') {
3425 p = begin_line(p);
3426 q = end_line(q);
3427 }
3428
3429 *start = p; 3423 *start = p;
3430 *stop = q; 3424 *stop = q;
3431 dot = save_dot;
3432 return buftype; 3425 return buftype;
3433} 3426}
3434 3427
@@ -3896,7 +3889,7 @@ static void do_cmd(int c)
3896 if (find_range(&p, &q, c) == -1) 3889 if (find_range(&p, &q, c) == -1)
3897 goto dc6; 3890 goto dc6;
3898 i = count_lines(p, q); // # of lines we are shifting 3891 i = count_lines(p, q); // # of lines we are shifting
3899 for ( ; i > 0; i--, p = next_line(p)) { 3892 for (p = begin_line(p); i > 0; i--, p = next_line(p)) {
3900 if (c == '<') { 3893 if (c == '<') {
3901 // shift left- remove tab or tabstop spaces 3894 // shift left- remove tab or tabstop spaces
3902 if (*p == '\t') { 3895 if (*p == '\t') {
@@ -4150,12 +4143,16 @@ static void do_cmd(int c)
4150# endif 4143# endif
4151 if (c == 'y' || c == 'Y') 4144 if (c == 'y' || c == 'Y')
4152 yf = YANKONLY; 4145 yf = YANKONLY;
4153 save_dot = dot;
4154#endif 4146#endif
4155 // determine range, and whether it spans lines 4147 // determine range, and whether it spans lines
4156 buftype = find_range(&p, &q, c); 4148 buftype = find_range(&p, &q, c);
4157 if (buftype == -1) // invalid range 4149 if (buftype == -1) // invalid range
4158 goto dc6; 4150 goto dc6;
4151 if (buftype == WHOLE) {
4152 save_dot = p; // final cursor position is start of range
4153 p = begin_line(p);
4154 q = end_line(q);
4155 }
4159 dot = yank_delete(p, q, buftype, yf, ALLOW_UNDO); // delete word 4156 dot = yank_delete(p, q, buftype, yf, ALLOW_UNDO); // delete word
4160 if (buftype == WHOLE) { 4157 if (buftype == WHOLE) {
4161 if (c == 'c') { 4158 if (c == 'c') {
@@ -4164,15 +4161,9 @@ static void do_cmd(int c)
4164 if (dot != (end-1)) { 4161 if (dot != (end-1)) {
4165 dot_prev(); 4162 dot_prev();
4166 } 4163 }
4167 } else if (c == 'd') { 4164 } else {
4168 dot_begin();
4169 dot_skip_over_ws();
4170 }
4171#if ENABLE_FEATURE_VI_YANKMARK
4172 else /* (c == 'y' || c == 'Y') */ {
4173 dot = save_dot; 4165 dot = save_dot;
4174 } 4166 }
4175#endif
4176 } 4167 }
4177 // if CHANGING, not deleting, start inserting after the delete 4168 // if CHANGING, not deleting, start inserting after the delete
4178 if (c == 'c') { 4169 if (c == 'c') {