]> granicus.if.org Git - vim/commitdiff
patch 9.0.1036: undo misbehaves when writing from an insert mode mapping v9.0.1036
authorBram Moolenaar <Bram@vim.org>
Thu, 8 Dec 2022 21:49:35 +0000 (21:49 +0000)
committerBram Moolenaar <Bram@vim.org>
Thu, 8 Dec 2022 21:49:35 +0000 (21:49 +0000)
Problem:    Undo misbehaves when writing from an insert mode mapping.
Solution:   Sync undo when writing. (closes #11674)

src/edit.c
src/testdir/dumps/Test_undo_after_write_1.dump [new file with mode: 0644]
src/testdir/dumps/Test_undo_after_write_2.dump [new file with mode: 0644]
src/testdir/dumps/Test_undo_after_write_2.vim [new file with mode: 0644]
src/testdir/test_undo.vim
src/version.c

index 43f7d9abb0712c87b93802057aec301bbb75f816..9e8346d1c2c2d778ca1dbdd4b7994a6a1840f933 100644 (file)
@@ -1049,12 +1049,19 @@ doESCkey:
 
        case K_COMMAND:             // <Cmd>command<CR>
        case K_SCRIPT_COMMAND:      // <ScriptCmd>command<CR>
-           do_cmdkey_command(c, 0);
+           {
+               do_cmdkey_command(c, 0);
+
 #ifdef FEAT_TERMINAL
-           if (term_use_loop())
-               // Started a terminal that gets the input, exit Insert mode.
-               goto doESCkey;
+               if (term_use_loop())
+                   // Started a terminal that gets the input, exit Insert mode.
+                   goto doESCkey;
 #endif
+               if (curbuf->b_u_synced)
+                   // The command caused undo to be synced.  Need to save the
+                   // line for undo before inserting the next char.
+                   ins_need_undo = TRUE;
+           }
            break;
 
        case K_CURSORHOLD:      // Didn't type something for a while.
diff --git a/src/testdir/dumps/Test_undo_after_write_1.dump b/src/testdir/dumps/Test_undo_after_write_1.dump
new file mode 100644 (file)
index 0000000..92410d4
--- /dev/null
@@ -0,0 +1,6 @@
+|t+0&#ffffff0|e|s>t| @70
+@75
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|1+0#0000000&| |l|i|n|e| |l|e|s@1|;| |b|e|f|o|r|e| |#|2| @1|0| |s|e|c|o|n|d|s| |a|g|o| @19|1|,|4| @10|A|l@1| 
diff --git a/src/testdir/dumps/Test_undo_after_write_2.dump b/src/testdir/dumps/Test_undo_after_write_2.dump
new file mode 100644 (file)
index 0000000..029e324
--- /dev/null
@@ -0,0 +1,6 @@
+> +0&#ffffff0@74
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|2+0#0000000&| |f|e|w|e|r| |l|i|n|e|s|;| |b|e|f|o|r|e| |#|1| @1|1| |s|e|c|o|n|d| |a|g|o| @18|0|,|0|-|1| @8|A|l@1| 
diff --git a/src/testdir/dumps/Test_undo_after_write_2.vim b/src/testdir/dumps/Test_undo_after_write_2.vim
new file mode 100644 (file)
index 0000000..d1d3c3d
--- /dev/null
@@ -0,0 +1,2 @@
+" Filter that changes the "1 second ago" message to "0 seconds ago".
+6s+|1| |s|e|c|o|n|d| |a|g|o| @18|+|0| |s|e|c|o|n|d|s| |a|g|o| @17|+e
index ce7b0dcf606e174045a97b3f625415f56f194e4c..2529e21085a3a56b1f44201707bb1b64f78566bd 100644 (file)
@@ -3,6 +3,9 @@
 " undo-able pieces.  Do that by setting 'undolevels'.
 " Also tests :earlier and :later.
 
+source check.vim
+source screendump.vim
+
 func Test_undotree()
   new
 
@@ -775,4 +778,30 @@ func Test_undo_mark()
   bwipe!
 endfunc
 
+func Test_undo_after_write()
+  " use a terminal to make undo work like when text is typed
+  CheckRunVimInTerminal
+
+  let lines =<< trim END
+      edit Xtestfile.txt
+      set undolevels=100 undofile
+      imap . <Cmd>write<CR>
+      write
+  END
+  call writefile(lines, 'Xtest_undo_after_write', 'D')
+  let buf = RunVimInTerminal('-S Xtest_undo_after_write', #{rows: 6})
+
+  call term_sendkeys(buf, "Otest.\<CR>boo!!!\<Esc>")
+  sleep 100m
+  call term_sendkeys(buf, "u")
+  call VerifyScreenDump(buf, 'Test_undo_after_write_1', {})
+
+  call term_sendkeys(buf, "u")
+  call VerifyScreenDump(buf, 'Test_undo_after_write_2', {})
+
+  call StopVimInTerminal(buf)
+  call delete('Xtestfile.txt')
+endfunc
+
+
 " vim: shiftwidth=2 sts=2 expandtab
index 7ae34f475b90178187918a4e929eed6b48dc80d6..9c162fbbbdebdad49d5e5b5cfc43d13b045c9d44 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1036,
 /**/
     1035,
 /**/