local t = require('test.testutil') local n = require('test.functional.testnvim')() local clear = n.clear local eq = t.eq local exec = n.exec local api = n.api local dedent = t.dedent local Screen = require('test.functional.ui.screen') ---@param reverse_tree {[integer]:integer} local function generate_undo_tree_from_rev(reverse_tree) for k, v in ipairs(reverse_tree) do exec('undo ' .. v) api.nvim_buf_set_lines(0, 0, -1, true, { tostring(k) }) end end ---@param buf integer ---@return string local function buf_get_lines_and_extmark(buf) local lines = api.nvim_buf_get_lines(buf, 0, -1, true) local ns = api.nvim_create_namespace('nvim.undotree') local extmarks = api.nvim_buf_get_extmarks(buf, ns, 0, -1, { details = true }) for i = #extmarks, 1, -1 do local extmark = extmarks[i] ---@type nil,integer,nil,vim.api.keyset.extmark_details local _, row, _, opts = unpack(extmark) local virt_lines = assert(opts.virt_lines) for _, v in ipairs(virt_lines) do local virt_line = v[1][1] table.insert(lines, row + 2, virt_line) end end return table.concat(lines, '\n') end local function strip_time(text) return text:gsub('%s-%(.-%)', '') end describe(':Undotree', function() before_each(function() clear({ args = { '--clean' } }) exec 'packadd nvim.undotree' end) it('works', function() api.nvim_set_current_line('foo') exec 'Undotree' local buf = api.nvim_get_current_buf() local win = api.nvim_get_current_win() eq( dedent [[ * 0 * 1]], strip_time(buf_get_lines_and_extmark(buf)) ) eq(2, api.nvim_win_get_cursor(win)[1]) exec 'wincmd w' -- Doing changes moves cursor in undotree exec 'undo' eq(1, api.nvim_win_get_cursor(win)[1]) api.nvim_set_current_line('bar') eq(3, api.nvim_win_get_cursor(win)[1]) eq( dedent [[ * 0 |\ | * 1 * 2]], strip_time(buf_get_lines_and_extmark(buf)) ) -- Moving the cursor in undotree changes the buffer eq('bar', api.nvim_get_current_line()) exec 'wincmd w' exec '2' exec 'wincmd w' eq('foo', api.nvim_get_current_line()) end) it('sync scroll pos when undo', function() local screen = Screen.new(30, 10) for _ = 1, n.api.nvim_get_option_value('lines', {}) do api.nvim_set_current_line('foo') end exec 'Undotree' exec 'wincmd w' exec 'silent undo' screen:expect([[ * 3 │^foo | * 4 │{1:~ }| * 5 │{1:~ }| * 6 │{1:~ }| * 7 │{1:~ }| * 8 │{1:~ }| {21:* 9 }│{1:~ }| * 10 │{1:~ }| {2: