061_undo_tree_spec.lua 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. -- Tests for undo tree and :earlier and :later.
  2. local helpers = require('test.functional.helpers')(after_each)
  3. local feed_command = helpers.feed_command
  4. local write_file = helpers.write_file
  5. local command = helpers.command
  6. local source = helpers.source
  7. local expect = helpers.expect
  8. local clear = helpers.clear
  9. local feed = helpers.feed
  10. local eval = helpers.eval
  11. local eq = helpers.eq
  12. local function expect_empty_buffer()
  13. -- The space will be removed by helpers.dedent but is needed because dedent
  14. -- will fail if it can not find the common indent of the given lines.
  15. return expect(' ')
  16. end
  17. local function expect_line(line)
  18. return eq(line, eval('getline(".")'))
  19. end
  20. describe('undo tree:', function()
  21. before_each(clear)
  22. teardown(function()
  23. os.remove('Xtest.source')
  24. end)
  25. describe(':earlier and :later', function()
  26. before_each(function()
  27. os.remove('Xtest')
  28. end)
  29. teardown(function()
  30. os.remove('Xtest')
  31. end)
  32. it('time specifications, g- g+', function()
  33. -- We write the test text to a file in order to prevent nvim to record
  34. -- the inserting of the text into the undo history.
  35. write_file('Xtest', '\n123456789\n')
  36. -- `:earlier` and `:later` are (obviously) time-sensitive, so this test
  37. -- sometimes fails if the system is under load. It is wrapped in a local
  38. -- function to allow multiple attempts.
  39. local function test_earlier_later()
  40. clear()
  41. feed_command('e Xtest')
  42. -- Assert that no undo history is present.
  43. eq({}, eval('undotree().entries'))
  44. -- Delete three characters and undo.
  45. feed('Gxxx')
  46. expect_line('456789')
  47. feed('g-')
  48. expect_line('3456789')
  49. feed('g-')
  50. expect_line('23456789')
  51. feed('g-')
  52. expect_line('123456789')
  53. feed('g-')
  54. expect_line('123456789')
  55. -- Delete three other characters and go back in time step by step.
  56. feed('$xxx')
  57. expect_line('123456')
  58. command('sleep 1')
  59. feed('g-')
  60. expect_line('1234567')
  61. feed('g-')
  62. expect_line('12345678')
  63. feed('g-')
  64. expect_line('456789')
  65. feed('g-')
  66. expect_line('3456789')
  67. feed('g-')
  68. expect_line('23456789')
  69. feed('g-')
  70. expect_line('123456789')
  71. feed('g-')
  72. expect_line('123456789')
  73. feed('g-')
  74. expect_line('123456789')
  75. feed('10g+')
  76. expect_line('123456')
  77. -- Delay for two seconds and go some seconds forward and backward.
  78. command('sleep 2')
  79. feed('Aa<esc>')
  80. feed('Ab<esc>')
  81. feed('Ac<esc>')
  82. expect_line('123456abc')
  83. feed_command('earlier 1s')
  84. expect_line('123456')
  85. feed_command('earlier 3s')
  86. expect_line('123456789')
  87. feed_command('later 1s')
  88. expect_line('123456')
  89. feed_command('later 1h')
  90. expect_line('123456abc')
  91. end
  92. helpers.retry(2, nil, test_earlier_later)
  93. end)
  94. it('file-write specifications', function()
  95. feed('ione one one<esc>')
  96. feed_command('w Xtest')
  97. feed('otwo<esc>')
  98. feed('otwo<esc>')
  99. feed_command('w')
  100. feed('othree<esc>')
  101. feed_command('earlier 1f')
  102. expect([[
  103. one one one
  104. two
  105. two]])
  106. feed_command('earlier 1f')
  107. expect('one one one')
  108. feed_command('earlier 1f')
  109. expect_empty_buffer()
  110. feed_command('later 1f')
  111. expect('one one one')
  112. feed_command('later 1f')
  113. expect([[
  114. one one one
  115. two
  116. two]])
  117. feed_command('later 1f')
  118. expect([[
  119. one one one
  120. two
  121. two
  122. three]])
  123. end)
  124. end)
  125. it('scripts produce one undo-block for all changes by default', function()
  126. source([[
  127. normal Aaaaa
  128. normal obbbb
  129. normal occcc
  130. ]])
  131. expect([[
  132. aaaa
  133. bbbb
  134. cccc]])
  135. feed('u')
  136. expect_empty_buffer()
  137. end)
  138. it("setting 'undolevel' can break undo-blocks (inside scripts)", function()
  139. -- :source is required (because interactive changes are _not_ grouped,
  140. -- even with :undojoin).
  141. source([[
  142. normal Aaaaa
  143. set ul=100
  144. normal obbbb
  145. set ul=100
  146. normal occcc
  147. ]])
  148. expect([[
  149. aaaa
  150. bbbb
  151. cccc]])
  152. feed('u')
  153. expect([[
  154. aaaa
  155. bbbb]])
  156. feed('u')
  157. expect('aaaa')
  158. feed('u')
  159. expect_empty_buffer()
  160. end)
  161. it(':undojoin can join undo-blocks inside scripts', function()
  162. feed('Goaaaa<esc>')
  163. feed('obbbb<esc>u')
  164. expect_line('aaaa')
  165. source([[
  166. normal obbbb
  167. set ul=100
  168. undojoin
  169. normal occcc
  170. ]])
  171. feed('u')
  172. expect_line('aaaa')
  173. end)
  174. it('undo an expression-register', function()
  175. local normal_commands = 'o1\027a2\018=string(123)\n\027'
  176. write_file('Xtest.source', normal_commands)
  177. feed('oa<esc>')
  178. feed('ob<esc>')
  179. feed([[o1<esc>a2<C-R>=setline('.','1234')<cr><esc>]])
  180. expect([[
  181. a
  182. b
  183. 12034]])
  184. feed('uu')
  185. expect([[
  186. a
  187. b
  188. 1]])
  189. feed('oc<esc>')
  190. feed([[o1<esc>a2<C-R>=setline('.','1234')<cr><esc>]])
  191. expect([[
  192. a
  193. b
  194. 1
  195. c
  196. 12034]])
  197. feed('u')
  198. expect([[
  199. a
  200. b
  201. 1
  202. c
  203. 12]])
  204. feed('od<esc>')
  205. feed_command('so! Xtest.source')
  206. expect([[
  207. a
  208. b
  209. 1
  210. c
  211. 12
  212. d
  213. 12123]])
  214. feed('u')
  215. expect([[
  216. a
  217. b
  218. 1
  219. c
  220. 12
  221. d]])
  222. -- The above behaviour was tested in the legacy Vim test because the
  223. -- legacy tests were executed with ':so!'. The behavior differs for
  224. -- interactive use (even in Vim; see ":help :undojoin"):
  225. feed(normal_commands)
  226. expect([[
  227. a
  228. b
  229. 1
  230. c
  231. 12
  232. d
  233. 12123]])
  234. feed('u')
  235. expect([[
  236. a
  237. b
  238. 1
  239. c
  240. 12
  241. d
  242. 1]])
  243. end)
  244. end)