[PATCH] vi: fix range selection by forward character motion

Denys Vlasenko vda.linux at googlemail.com
Tue Feb 2 13:43:41 UTC 2021


Applied, thanks!

On Mon, Feb 1, 2021 at 12:54 PM Ron Yorston <rmy at pobox.com> wrote:
>
> Selection of ranges for change/delete/yank by forward character
> motion commands (SPACE or 'l') was incorrect.  The range was
> always one character whereas vi allows the size of the range to
> be specified.
>
> Fix this by executing the motion command the required number of times.
> There is a complication when the range is at the end of a line.  We need
> to distinguish between a range which excludes the last character and
> one which includes it.  This requires comparing the actual range with
> that expected from the command count.  (With the additional quirk that
> a command count of zero is equivalent to a command count of one.)
>
> function                                             old     new   delta
> find_range                                           587     619     +32
> ------------------------------------------------------------------------------
> (add/remove: 0/0 grow/shrink: 1/0 up/down: 32/0)               Total: 32 bytes
>
> Signed-off-by: Ron Yorston <rmy at pobox.com>
> ---
>  editors/vi.c | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/editors/vi.c b/editors/vi.c
> index 01597fa5e..adfb2b87c 100644
> --- a/editors/vi.c
> +++ b/editors/vi.c
> @@ -3047,12 +3047,15 @@ static int find_range(char **start, char **stop, char c)
>                 do_cmd(c);              // execute movement cmd
>                 dot_end();              // find NL
>                 q = dot;
> -       } else {
> -               // nothing -- this causes any other values of c to
> -               // represent the one-character range under the
> -               // cursor.  this is correct for ' ' and 'l', but
> -               // perhaps no others.
> -               //
> +       } else /* if (c == ' ' || c == 'l') */ {
> +               // forward motion by character
> +               int tmpcnt = (cmdcnt ?: 1);
> +               do_cmd(c);              // execute movement cmd
> +               // exclude last char unless range isn't what we expected
> +               // this indicates we've hit EOL
> +               if (tmpcnt == dot - p)
> +                       dot--;
> +               q = dot;
>         }
>         if (q < p) {
>                 t = q;
> --
> 2.29.2
>
> _______________________________________________
> busybox mailing list
> busybox at busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox


More information about the busybox mailing list