diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-12-09 07:24:09 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-09 07:24:09 +0800 |
commit | d82096edf8b870b79da40cc005803ee18c63e409 (patch) | |
tree | e8e3c0452677dfee45f1c7d62e5b600130919b6c | |
parent | ea39fc2cadc1d87109216da354a876427eeea31a (diff) | |
parent | 95044991e618827924ac47aeae8bd0eacc775f58 (diff) | |
download | rneovim-d82096edf8b870b79da40cc005803ee18c63e409.tar.gz rneovim-d82096edf8b870b79da40cc005803ee18c63e409.tar.bz2 rneovim-d82096edf8b870b79da40cc005803ee18c63e409.zip |
Merge pull request #21348 from zeertzjq/vim-9.0.1036
vim-patch:9.0.1036: undo misbehaves when writing from an insert mode mapping
-rw-r--r-- | src/nvim/edit.c | 6 | ||||
-rw-r--r-- | src/nvim/testdir/test_undo.vim | 29 | ||||
-rw-r--r-- | test/functional/editor/undo_spec.lua | 75 |
3 files changed, 110 insertions, 0 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c index ac2973ba68..09836e747f 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -908,6 +908,12 @@ check_pum: } pum_want.active = false; } + + if (curbuf->b_u_synced) { + // The K_EVENT, K_COMMAND, or K_LUA caused undo to be synced. + // Need to save the line for undo before inserting the next char. + ins_need_undo = true; + } break; case K_HOME: // <Home> diff --git a/src/nvim/testdir/test_undo.vim b/src/nvim/testdir/test_undo.vim index eb47af08d7..ee8b52caaf 100644 --- a/src/nvim/testdir/test_undo.vim +++ b/src/nvim/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 @@ -773,4 +776,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/test/functional/editor/undo_spec.lua b/test/functional/editor/undo_spec.lua index a041428cdc..d66ab352ef 100644 --- a/test/functional/editor/undo_spec.lua +++ b/test/functional/editor/undo_spec.lua @@ -9,6 +9,8 @@ local feed = helpers.feed local feed_command = helpers.feed_command local insert = helpers.insert local funcs = helpers.funcs +local exec = helpers.exec +local exec_lua = helpers.exec_lua local function lastmessage() local messages = funcs.split(funcs.execute('messages'), '\n') @@ -67,6 +69,79 @@ describe('u CTRL-R g- g+', function() undo_and_redo(4, 'u', '<C-r>', '1') undo_and_redo(4, 'g-', 'g+', '1') end) + + describe('undo works correctly when writing in Insert mode', function() + before_each(function() + exec([[ + edit Xtestfile.txt + set undolevels=100 undofile + write + ]]) + end) + + after_each(function() + command('bwipe!') + os.remove('Xtestfile.txt') + os.remove('Xtestfile.txt.un~') + end) + + -- oldtest: Test_undo_after_write() + it('using <Cmd> mapping', function() + command('imap . <Cmd>write<CR>') + feed('Otest.<CR>boo!!!<Esc>') + expect([[ + test + boo!!! + ]]) + + feed('u') + expect([[ + test + ]]) + + feed('u') + expect('') + end) + + it('using Lua mapping', function() + exec_lua([[ + vim.api.nvim_set_keymap('i', '.', '', {callback = function() + vim.cmd('write') + end}) + ]]) + feed('Otest.<CR>boo!!!<Esc>') + expect([[ + test + boo!!! + ]]) + + feed('u') + expect([[ + test + ]]) + + feed('u') + expect('') + end) + + it('using RPC call', function() + feed('Otest') + command('write') + feed('<CR>boo!!!<Esc>') + expect([[ + test + boo!!! + ]]) + + feed('u') + expect([[ + test + ]]) + + feed('u') + expect('') + end) + end) end) describe(':undo! command', function() |