aboutsummaryrefslogtreecommitdiff
path: root/test/functional/editor/undo_spec.lua
blob: a041428cdc04a6318e54f18cbe007dcb831116d4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
local helpers = require('test.functional.helpers')(after_each)

local clear = helpers.clear
local command = helpers.command
local eval = helpers.eval
local expect = helpers.expect
local eq = helpers.eq
local feed = helpers.feed
local feed_command = helpers.feed_command
local insert = helpers.insert
local funcs = helpers.funcs

local function lastmessage()
  local messages = funcs.split(funcs.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<esc>')
    feed('o3<esc>')
    feed('u')
    if num_steps == 2 then return end
    feed('o4<esc>')
    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 = helpers.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', '<C-r>', '')
    undo_and_redo(0, 'g-', 'g+', '')
  end)
  it('undoes a change when at a leaf', function()
    undo_and_redo(1, 'u', '<C-r>', '')
    undo_and_redo(1, 'g-', 'g+', '')
  end)
  it('undoes a change when in a non-leaf', function()
    undo_and_redo(2, 'u', '<C-r>', '1')
    undo_and_redo(2, 'g-', 'g+', '1')
  end)
  it('undoes properly around a branch point', function()
    undo_and_redo(3, 'u', '<C-r>', [[
      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', '<C-r>', '1')
    undo_and_redo(4, 'g-', 'g+', '1')
  end)
end)

describe(':undo! command', function()
  before_each(function()
    clear()
    feed('i1 little bug in the code<Esc>')
    feed('o1 little bug in the code<Esc>')
    feed('oTake 1 down, patch it around<Esc>')
    feed('o99 little bugs in the code<Esc>')
  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('<C-r>')
    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('<C-r>')
    eq('Already at newest change', lastmessage())
  end)
  it('correctly sets alternative redo', function()
    feed('uo101 little bugs in the code<Esc>')
    feed_command('undo!')
    feed('<C-r>')
    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<Esc>')
    feed('o101 little bugs in the code<Esc>')
    feed_command('undo! 2')
    feed('<C-r><C-r>')
    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<Esc>')
    feed('o101 little bugs in the code<Esc>')
    feed_command('undo! 4')
    eq('E5767: Cannot use :undo! to redo or move to a different undo branch', eval('v:errmsg'))
  end)
end)