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

Reply via email to