[PATCH] vi: cursor positioning after whole-line 'y'
Denys Vlasenko
vda.linux at googlemail.com
Tue May 4 12:54:46 UTC 2021
Applied, thank you
On Fri, Apr 30, 2021 at 1:56 PM Ron Yorston <rmy at pobox.com> wrote:
>
> 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 at 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 at busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox
More information about the busybox
mailing list