aboutsummaryrefslogtreecommitdiff
path: root/editors/vi.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-04-06 16:48:07 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2021-04-11 00:18:55 +0200
commita54450248b063afd96530821020872bfc9ec9997 (patch)
tree37d9b739a45474ab8d8865af1fc965f8c582b731 /editors/vi.c
parentfe76569daa88429276e72dc0c51c0b58d275aee7 (diff)
downloadbusybox-w32-a54450248b063afd96530821020872bfc9ec9997.tar.gz
busybox-w32-a54450248b063afd96530821020872bfc9ec9997.tar.bz2
busybox-w32-a54450248b063afd96530821020872bfc9ec9997.zip
vi: allow the '.' command to have a repetition count
The '.' command repeats the last text change. When it has a repetition count replay the change the number of times requested. Update the stored count if it changes. For example, 3dw deletes 3 words . deletes another 3 words 2. deletes 2 words and changes the stored count . deletes 2 words function old new delta do_cmd 4746 4781 +35 .rodata 105133 105138 +5 edit_file 887 849 -38 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 40/-38) Total: 2 bytes v2: Change implementation to include repetition count in string. Otherwise repeating 'r' doesn't work properly. Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'editors/vi.c')
-rw-r--r--editors/vi.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/editors/vi.c b/editors/vi.c
index fad53174e..9a2d7b0d9 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -338,6 +338,7 @@ struct globals {
338 smallint adding2q; // are we currently adding user input to q 338 smallint adding2q; // are we currently adding user input to q
339 int lmc_len; // length of last_modifying_cmd 339 int lmc_len; // length of last_modifying_cmd
340 char *ioq, *ioq_start; // pointer to string for get_one_char to "read" 340 char *ioq, *ioq_start; // pointer to string for get_one_char to "read"
341 int dotcnt; // number of times to repeat '.' command
341#endif 342#endif
342#if ENABLE_FEATURE_VI_SEARCH 343#if ENABLE_FEATURE_VI_SEARCH
343 char *last_search_pattern; // last pattern from a '/' or '?' search 344 char *last_search_pattern; // last pattern from a '/' or '?' search
@@ -460,6 +461,7 @@ struct globals {
460#define lmc_len (G.lmc_len ) 461#define lmc_len (G.lmc_len )
461#define ioq (G.ioq ) 462#define ioq (G.ioq )
462#define ioq_start (G.ioq_start ) 463#define ioq_start (G.ioq_start )
464#define dotcnt (G.dotcnt )
463#define last_search_pattern (G.last_search_pattern) 465#define last_search_pattern (G.last_search_pattern)
464 466
465#define edit_file__cur_line (G.edit_file__cur_line) 467#define edit_file__cur_line (G.edit_file__cur_line)
@@ -1094,8 +1096,8 @@ static int get_one_char(void)
1094 } 1096 }
1095 // we are adding STDIN chars to q. 1097 // we are adding STDIN chars to q.
1096 c = readit(); 1098 c = readit();
1097 if (lmc_len >= ARRAY_SIZE(last_modifying_cmd) - 1) { 1099 if (lmc_len >= ARRAY_SIZE(last_modifying_cmd) - 2) {
1098 // last_modifying_cmd[] is too small, can't remeber the cmd 1100 // last_modifying_cmd[] is too small, can't remember the cmd
1099 // - drop it 1101 // - drop it
1100 adding2q = 0; 1102 adding2q = 0;
1101 lmc_len = 0; 1103 lmc_len = 0;
@@ -1863,13 +1865,9 @@ static char *bound_dot(char *p) // make sure text[0] <= P < "end"
1863static void start_new_cmd_q(char c) 1865static void start_new_cmd_q(char c)
1864{ 1866{
1865 // get buffer for new cmd 1867 // get buffer for new cmd
1866 // if there is a current cmd count put it in the buffer first 1868 dotcnt = cmdcnt ?: 1;
1867 if (cmdcnt > 0) { 1869 last_modifying_cmd[0] = c;
1868 lmc_len = sprintf(last_modifying_cmd, "%u%c", cmdcnt, c); 1870 lmc_len = 1;
1869 } else { // just save char c onto queue
1870 last_modifying_cmd[0] = c;
1871 lmc_len = 1;
1872 }
1873 adding2q = 1; 1871 adding2q = 1;
1874} 1872}
1875static void end_cmd_q(void) 1873static void end_cmd_q(void)
@@ -3515,7 +3513,10 @@ static void do_cmd(int c)
3515 // Stuff the last_modifying_cmd back into stdin 3513 // Stuff the last_modifying_cmd back into stdin
3516 // and let it be re-executed. 3514 // and let it be re-executed.
3517 if (lmc_len != 0) { 3515 if (lmc_len != 0) {
3518 ioq = ioq_start = xstrndup(last_modifying_cmd, lmc_len); 3516 if (cmdcnt) // update saved count if current count is non-zero
3517 dotcnt = cmdcnt;
3518 last_modifying_cmd[lmc_len] = '\0';
3519 ioq = ioq_start = xasprintf("%u%s", dotcnt, last_modifying_cmd);
3519 } 3520 }
3520 break; 3521 break;
3521#endif 3522#endif