[PATCH 06/11] vi: allow the '.' command to have a repetition count
Ron Yorston
rmy at pobox.com
Tue Apr 6 12:42:40 UTC 2021
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 <rmy at pobox.com>
---
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
More information about the busybox
mailing list