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 get_one_char 115 142 +27 do_cmd 4767 4786 +19 edit_file 887 836 -51 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 46/-51) Total: -5 bytes Signed-off-by: Ron Yorston <[email protected]> --- editors/vi.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/editors/vi.c b/editors/vi.c index 270a35840..e63b7ca7f 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -330,6 +330,8 @@ struct globals { #if ENABLE_FEATURE_VI_DOT_CMD smallint adding2q; // are we currently adding user input to q int lmc_len; // length of last_modifying_cmd + int dotcnt; // number of times to repeat '.' command + int ioqcnt; // working copy of repeat count char *ioq, *ioq_start; // pointer to string for get_one_char to "read" #endif #if ENABLE_FEATURE_VI_SEARCH @@ -451,6 +453,8 @@ struct globals { #endif #define adding2q (G.adding2q ) #define lmc_len (G.lmc_len ) +#define dotcnt (G.dotcnt ) +#define ioqcnt (G.ioqcnt ) #define ioq (G.ioq ) #define ioq_start (G.ioq_start ) #define last_search_pattern (G.last_search_pattern) @@ -1075,10 +1079,15 @@ static int get_one_char(void) if (ioq_start != NULL) { // there is a queue to get chars from. // careful with correct sign expansion! + redot: c = (unsigned char)*ioq++; if (c != '\0') return c; // the end of the q + if (--ioqcnt > 0) { + ioq = ioq_start; + goto redot; + } free(ioq_start); ioq_start = NULL; // read from STDIN: @@ -1856,13 +1865,9 @@ static char *bound_dot(char *p) // make sure text[0] <= P < "end" static void start_new_cmd_q(char c) { // get buffer for new cmd - // if there is a current cmd count put it in the buffer first - if (cmdcnt > 0) { - lmc_len = sprintf(last_modifying_cmd, "%u%c", cmdcnt, c); - } else { // just save char c onto queue - last_modifying_cmd[0] = c; - lmc_len = 1; - } + dotcnt = cmdcnt; + last_modifying_cmd[0] = c; + lmc_len = 1; adding2q = 1; } static void end_cmd_q(void) @@ -3492,6 +3497,9 @@ static void do_cmd(int c) // Stuff the last_modifying_cmd back into stdin // and let it be re-executed. if (lmc_len != 0) { + if (cmdcnt) // update saved count if current count is non-zero + dotcnt = cmdcnt; + ioqcnt = dotcnt; ioq = ioq_start = xstrndup(last_modifying_cmd, lmc_len); } break; -- 2.30.2 _______________________________________________ busybox mailing list [email protected] http://lists.busybox.net/mailman/listinfo/busybox
