summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-12-08 21:49:35 +0000
committerBram Moolenaar <Bram@vim.org>2022-12-08 21:49:35 +0000
commit3f8f82772313af9f2417b06651f30988b63e1c96 (patch)
treebcb39bcc4421135334decdea16a3dc176c6afe94
parentd28d7b94f5a76a817585c115dbf6fecac9b0b4cd (diff)
downloadvim-git-3f8f82772313af9f2417b06651f30988b63e1c96.tar.gz
patch 9.0.1036: undo misbehaves when writing from an insert mode mappingv9.0.1036
Problem: Undo misbehaves when writing from an insert mode mapping. Solution: Sync undo when writing. (closes #11674)
-rw-r--r--src/edit.c15
-rw-r--r--src/testdir/dumps/Test_undo_after_write_1.dump6
-rw-r--r--src/testdir/dumps/Test_undo_after_write_2.dump6
-rw-r--r--src/testdir/dumps/Test_undo_after_write_2.vim2
-rw-r--r--src/testdir/test_undo.vim29
-rw-r--r--src/version.c2
6 files changed, 56 insertions, 4 deletions
diff --git a/src/edit.c b/src/edit.c
index 43f7d9abb..9e8346d1c 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -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
index 000000000..92410d446
--- /dev/null
+++ b/src/testdir/dumps/Test_undo_after_write_1.dump
@@ -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
index 000000000..029e3243e
--- /dev/null
+++ b/src/testdir/dumps/Test_undo_after_write_2.dump
@@ -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
index 000000000..d1d3c3d48
--- /dev/null
+++ b/src/testdir/dumps/Test_undo_after_write_2.vim
@@ -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
diff --git a/src/testdir/test_undo.vim b/src/testdir/test_undo.vim
index ce7b0dcf6..2529e2108 100644
--- a/src/testdir/test_undo.vim
+++ b/src/testdir/test_undo.vim
@@ -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
diff --git a/src/version.c b/src/version.c
index 7ae34f475..9c162fbbb 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1036,
+/**/
1035,
/**/
1034,