diff options
| author | Ron Yorston <rmy@pobox.com> | 2021-03-28 13:21:34 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-03-29 12:16:21 +0200 |
| commit | 1e84daf054113b97dad2d1201b8ec7fbebc9aeb3 (patch) | |
| tree | b30495efb5a37331cabbad4c739ad8e33593dec3 | |
| parent | d4c46037a6c595c42aab22b6910c56f5ccadb96e (diff) | |
| download | busybox-w32-1e84daf054113b97dad2d1201b8ec7fbebc9aeb3.tar.gz busybox-w32-1e84daf054113b97dad2d1201b8ec7fbebc9aeb3.tar.bz2 busybox-w32-1e84daf054113b97dad2d1201b8ec7fbebc9aeb3.zip | |
vi: allow motion count for change/delete/yank/shift
The motion that determines the range of a change, delete, yank
or shift operation can have its own count. Thus the commands
'5dd' and 'd5d' are equivalent: both delete 5 lines.
When the command itself also has a count the two values are
multiplied. Thus the command '2d3w' deletes 6 words and '2D3G'
deletes from the current line to line 6.
(When dealing with structured data it might make sense to think in
units of 3 words so '2d3w' is deleting 2 such units. It doesn't
seem quite as sensible to express 'delete from current line to line 6'
as '2D3G' but vi permits it.)
function old new delta
get_motion_char - 68 +68
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/0 up/down: 68/0) Total: 68 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | editors/vi.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/editors/vi.c b/editors/vi.c index 5d96c1575..4e1a2390f 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
| @@ -1102,6 +1102,22 @@ static int get_one_char(void) | |||
| 1102 | # define get_one_char() readit() | 1102 | # define get_one_char() readit() |
| 1103 | #endif | 1103 | #endif |
| 1104 | 1104 | ||
| 1105 | // Get type of thing to operate on and adjust count | ||
| 1106 | static int get_motion_char(void) | ||
| 1107 | { | ||
| 1108 | int c, cnt; | ||
| 1109 | |||
| 1110 | c = get_one_char(); | ||
| 1111 | if (c != '0' && isdigit(c)) { | ||
| 1112 | // get any non-zero motion count | ||
| 1113 | for (cnt = 0; isdigit(c); c = get_one_char()) | ||
| 1114 | cnt = cnt * 10 + (c - '0'); | ||
| 1115 | cmdcnt = (cmdcnt ?: 1) * cnt; | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | return c; | ||
| 1119 | } | ||
| 1120 | |||
| 1105 | // Get input line (uses "status line" area) | 1121 | // Get input line (uses "status line" area) |
| 1106 | static char *get_input_line(const char *prompt) | 1122 | static char *get_input_line(const char *prompt) |
| 1107 | { | 1123 | { |
| @@ -3532,7 +3548,7 @@ static void do_cmd(int c) | |||
| 3532 | case '<': // <- Left shift something | 3548 | case '<': // <- Left shift something |
| 3533 | case '>': // >- Right shift something | 3549 | case '>': // >- Right shift something |
| 3534 | cnt = count_lines(text, dot); // remember what line we are on | 3550 | cnt = count_lines(text, dot); // remember what line we are on |
| 3535 | c1 = get_one_char(); // get the type of thing to delete | 3551 | c1 = get_motion_char(); // get the type of thing to operate on |
| 3536 | find_range(&p, &q, c1); | 3552 | find_range(&p, &q, c1); |
| 3537 | yank_delete(p, q, WHOLE, YANKONLY, NO_UNDO); // save copy before change | 3553 | yank_delete(p, q, WHOLE, YANKONLY, NO_UNDO); // save copy before change |
| 3538 | p = begin_line(p); | 3554 | p = begin_line(p); |
| @@ -3778,7 +3794,7 @@ static void do_cmd(int c) | |||
| 3778 | #endif | 3794 | #endif |
| 3779 | c1 = 'y'; | 3795 | c1 = 'y'; |
| 3780 | if (c != 'Y') { | 3796 | if (c != 'Y') { |
| 3781 | c1 = get_one_char(); // get the type of thing to delete | 3797 | c1 = get_motion_char(); // get the type of thing to operate on |
| 3782 | if (c1 == 27) // ESC- user changed mind and wants out | 3798 | if (c1 == 27) // ESC- user changed mind and wants out |
| 3783 | goto dc6; | 3799 | goto dc6; |
| 3784 | } | 3800 | } |
