local t = require('test.testutil') local n = require('test.functional.testnvim')() local clear = n.clear local command = n.command local eval = n.eval local expect = n.expect local eq = t.eq local feed = n.feed local feed_command = n.feed_command local insert = n.insert local fn = n.fn local exec = n.exec local exec_lua = n.exec_lua local function lastmessage() local messages = fn.split(fn.execute('messages'), '\n') return messages[#messages] end describe('u CTRL-R g- g+', function() before_each(clear) local function create_history(num_steps) if num_steps == 0 then return end insert('1') if num_steps == 1 then return end feed('o2') feed('o3') feed('u') if num_steps == 2 then return end feed('o4') if num_steps == 3 then return end feed('u') end local function undo_and_redo(hist_pos, undo, redo, expect_str) command('enew!') create_history(hist_pos) local cur_contents = n.curbuf_contents() feed(undo) expect(expect_str) feed(redo) expect(cur_contents) end -- TODO Look for message saying 'Already at oldest change' it('does nothing when no changes have happened', function() undo_and_redo(0, 'u', '', '') undo_and_redo(0, 'g-', 'g+', '') end) it('undoes a change when at a leaf', function() undo_and_redo(1, 'u', '', '') undo_and_redo(1, 'g-', 'g+', '') end) it('undoes a change when in a non-leaf', function() undo_and_redo(2, 'u', '', '1') undo_and_redo(2, 'g-', 'g+', '1') end) it('undoes properly around a branch point', function() undo_and_redo( 3, 'u', '', [[ 1 2]] ) undo_and_redo( 3, 'g-', 'g+', [[ 1 2 3]] ) end) it('can find the previous sequence after undoing to a branch', function() undo_and_redo(4, 'u', '', '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 mapping', function() command('imap . write') feed('Otest.boo!!!') 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.boo!!!') expect([[ test boo!!! ]]) feed('u') expect([[ test ]]) feed('u') expect('') end) it('using RPC call', function() feed('Otest') command('write') feed('boo!!!') expect([[ test boo!!! ]]) feed('u') expect([[ test ]]) feed('u') expect('') end) end) end) describe(':undo! command', function() before_each(function() clear() feed('i1 little bug in the code') feed('o1 little bug in the code') feed('oTake 1 down, patch it around') feed('o99 little bugs in the code') end) it('works', function() feed_command('undo!') expect([[ 1 little bug in the code 1 little bug in the code Take 1 down, patch it around]]) feed('') eq('Already at newest change', lastmessage()) end) it('works with arguments', function() feed_command('undo! 2') expect([[ 1 little bug in the code 1 little bug in the code]]) feed('') eq('Already at newest change', lastmessage()) end) it('correctly sets alternative redo', function() feed('uo101 little bugs in the code') feed_command('undo!') feed('') expect([[ 1 little bug in the code 1 little bug in the code Take 1 down, patch it around 99 little bugs in the code]]) feed('uuoTake 2 down, patch them around') feed('o101 little bugs in the code') feed_command('undo! 2') feed('') expect([[ 1 little bug in the code 1 little bug in the code Take 1 down, patch it around 99 little bugs in the code]]) end) it('fails when attempting to redo or move to different undo branch', function() feed_command('undo! 4') eq('E5767: Cannot use :undo! to redo or move to a different undo branch', eval('v:errmsg')) feed('u') feed_command('undo! 4') eq('E5767: Cannot use :undo! to redo or move to a different undo branch', eval('v:errmsg')) feed('o101 little bugs in the code') feed('o101 little bugs in the code') feed_command('undo! 4') eq('E5767: Cannot use :undo! to redo or move to a different undo branch', eval('v:errmsg')) end) end)