vi: further fixes to undo after autoindent
authorRon Yorston <rmy@pobox.com>
Mon, 11 Feb 2019 08:29:15 +0000 (08:29 +0000)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 11 Feb 2019 10:47:20 +0000 (11:47 +0100)
Commit bb983f30e (vi: fix faulty undo after autoinsert) has a
number of problems:

- The commit message refers to 'autoinsert' when it really means
  'autoindent'.

- The indentation of undo_push_insert() was incorrect.

- Most seriously the commit only fixed the problem for cases where
  the indentation was exactly one character.  This is because undo_push()
  only allows single characters to be queued for UNDO_INS_QUEUED.

  Lifting this restriction allows the example given in the previous
  commit message (with a three character indent) to work.

function                                             old     new   delta
undo_push                                            406     435     +29
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 29/0)               Total: 29 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
editors/vi.c

index 899fcf57edc6bdb5a0b98ac1c3cca2fe3c31fc5b..065a1068eb6b422d8f924e93476e1cfc26ff50ef 100644 (file)
@@ -2314,16 +2314,18 @@ static void undo_push(char *src, unsigned int length, uint8_t u_type)   // Add to
                }
                break;
        case UNDO_INS_QUEUED:
-               if (length != 1)
+               if (length < 1)
                        return;
                switch (undo_queue_state) {
                case UNDO_EMPTY:
                        undo_queue_state = UNDO_INS;
                        undo_queue_spos = src;
                case UNDO_INS:
-                       undo_q++;       // Don't need to save any data for insertions
-                       if (undo_q == CONFIG_FEATURE_VI_UNDO_QUEUE_MAX)
-                               undo_queue_commit();
+                       while (length--) {
+                               undo_q++;       // Don't need to save any data for insertions
+                               if (undo_q == CONFIG_FEATURE_VI_UNDO_QUEUE_MAX)
+                                       undo_queue_commit();
+                       }
                        return;
                case UNDO_DEL:
                        // Switch from storing deleted text to inserted text
@@ -2372,16 +2374,16 @@ static void undo_push(char *src, unsigned int length, uint8_t u_type)   // Add to
 static void undo_push_insert(char *p, int len, int undo)
 {
        switch (undo) {
-               case ALLOW_UNDO:
-                       undo_push(p, len, UNDO_INS);
-                       break;
-               case ALLOW_UNDO_CHAIN:
-                       undo_push(p, len, UNDO_INS_CHAIN);
-                       break;
+       case ALLOW_UNDO:
+               undo_push(p, len, UNDO_INS);
+               break;
+       case ALLOW_UNDO_CHAIN:
+               undo_push(p, len, UNDO_INS_CHAIN);
+               break;
 # if ENABLE_FEATURE_VI_UNDO_QUEUE
-               case ALLOW_UNDO_QUEUED:
-                       undo_push(p, len, UNDO_INS_QUEUED);
-                       break;
+       case ALLOW_UNDO_QUEUED:
+               undo_push(p, len, UNDO_INS_QUEUED);
+               break;
 # endif
        }
 }