test_undo.vim 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  1. " Tests for the undo tree.
  2. " Since this script is sourced we need to explicitly break changes up in
  3. " undo-able pieces. Do that by setting 'undolevels'.
  4. " Also tests :earlier and :later.
  5. source check.vim
  6. source screendump.vim
  7. func Test_undotree()
  8. new
  9. normal! Aabc
  10. set ul=100
  11. let d = undotree()
  12. call assert_equal(1, d.seq_last)
  13. call assert_equal(1, d.seq_cur)
  14. call assert_equal(0, d.save_last)
  15. call assert_equal(0, d.save_cur)
  16. call assert_equal(1, len(d.entries))
  17. call assert_equal(1, d.entries[0].newhead)
  18. call assert_equal(1, d.entries[0].seq)
  19. call assert_true(d.entries[0].time <= d.time_cur)
  20. normal! Adef
  21. set ul=100
  22. let d = undotree()
  23. call assert_equal(2, d.seq_last)
  24. call assert_equal(2, d.seq_cur)
  25. call assert_equal(0, d.save_last)
  26. call assert_equal(0, d.save_cur)
  27. call assert_equal(2, len(d.entries))
  28. call assert_equal(1, d.entries[0].seq)
  29. call assert_equal(1, d.entries[1].newhead)
  30. call assert_equal(2, d.entries[1].seq)
  31. call assert_true(d.entries[1].time <= d.time_cur)
  32. undo
  33. set ul=100
  34. let d = undotree()
  35. call assert_equal(2, d.seq_last)
  36. call assert_equal(1, d.seq_cur)
  37. call assert_equal(0, d.save_last)
  38. call assert_equal(0, d.save_cur)
  39. call assert_equal(2, len(d.entries))
  40. call assert_equal(1, d.entries[0].seq)
  41. call assert_equal(1, d.entries[1].curhead)
  42. call assert_equal(1, d.entries[1].newhead)
  43. call assert_equal(2, d.entries[1].seq)
  44. call assert_true(d.entries[1].time == d.time_cur)
  45. normal! Aghi
  46. set ul=100
  47. let d = undotree()
  48. call assert_equal(3, d.seq_last)
  49. call assert_equal(3, d.seq_cur)
  50. call assert_equal(0, d.save_last)
  51. call assert_equal(0, d.save_cur)
  52. call assert_equal(2, len(d.entries))
  53. call assert_equal(1, d.entries[0].seq)
  54. call assert_equal(2, d.entries[1].alt[0].seq)
  55. call assert_equal(1, d.entries[1].newhead)
  56. call assert_equal(3, d.entries[1].seq)
  57. call assert_true(d.entries[1].time <= d.time_cur)
  58. undo
  59. set ul=100
  60. let d = undotree()
  61. call assert_equal(3, d.seq_last)
  62. call assert_equal(1, d.seq_cur)
  63. call assert_equal(0, d.save_last)
  64. call assert_equal(0, d.save_cur)
  65. call assert_equal(2, len(d.entries))
  66. call assert_equal(1, d.entries[0].seq)
  67. call assert_equal(2, d.entries[1].alt[0].seq)
  68. call assert_equal(1, d.entries[1].curhead)
  69. call assert_equal(1, d.entries[1].newhead)
  70. call assert_equal(3, d.entries[1].seq)
  71. call assert_true(d.entries[1].time == d.time_cur)
  72. w! Xtest
  73. let d = undotree()
  74. call assert_equal(1, d.save_cur)
  75. call assert_equal(1, d.save_last)
  76. call delete('Xtest')
  77. bwipe! Xtest
  78. endfunc
  79. func FillBuffer()
  80. for i in range(1,13)
  81. put=i
  82. " Set 'undolevels' to split undo.
  83. exe "setg ul=" . &g:ul
  84. endfor
  85. endfunc
  86. func Test_undotree_bufnr()
  87. new
  88. let buf1 = bufnr()
  89. normal! Aabc
  90. set ul=100
  91. " Save undo tree without bufnr as ground truth for buffer 1
  92. let d1 = undotree()
  93. new
  94. let buf2 = bufnr()
  95. normal! Adef
  96. set ul=100
  97. normal! Aghi
  98. set ul=100
  99. " Save undo tree without bufnr as ground truth for buffer 2
  100. let d2 = undotree()
  101. " Check undotree() with bufnr argument
  102. let d = undotree(buf1)
  103. call assert_equal(d1, d)
  104. call assert_notequal(d2, d)
  105. let d = undotree(buf2)
  106. call assert_notequal(d1, d)
  107. call assert_equal(d2, d)
  108. " Switch buffers and check again
  109. wincmd p
  110. let d = undotree(buf1)
  111. call assert_equal(d1, d)
  112. let d = undotree(buf2)
  113. call assert_notequal(d1, d)
  114. call assert_equal(d2, d)
  115. " error cases
  116. call assert_fails('call undotree(-1)', 'E158:')
  117. call assert_fails('call undotree("nosuchbuf")', 'E158:')
  118. " after creating a buffer nosuchbuf, undotree('nosuchbuf') should
  119. " not error out
  120. new nosuchbuf
  121. let d = {'seq_last': 0, 'entries': [], 'time_cur': 0, 'save_last': 0, 'synced': 1, 'save_cur': 0, 'seq_cur': 0}
  122. call assert_equal(d, undotree("nosuchbuf"))
  123. " clean up
  124. bw nosuchbuf
  125. " Drop created windows
  126. set ul&
  127. new
  128. only!
  129. endfunc
  130. func Test_global_local_undolevels()
  131. new one
  132. set undolevels=5
  133. call FillBuffer()
  134. " will only undo the last 5 changes, end up with 13 - (5 + 1) = 7 lines
  135. earlier 10
  136. call assert_equal(5, &g:undolevels)
  137. call assert_equal(-123456, &l:undolevels)
  138. call assert_equal('7', getline('$'))
  139. new two
  140. setlocal undolevels=2
  141. call FillBuffer()
  142. " will only undo the last 2 changes, end up with 13 - (2 + 1) = 10 lines
  143. earlier 10
  144. call assert_equal(5, &g:undolevels)
  145. call assert_equal(2, &l:undolevels)
  146. call assert_equal('10', getline('$'))
  147. setlocal ul=10
  148. call assert_equal(5, &g:undolevels)
  149. call assert_equal(10, &l:undolevels)
  150. " Setting local value in "two" must not change local value in "one"
  151. wincmd p
  152. call assert_equal(5, &g:undolevels)
  153. call assert_equal(-123456, &l:undolevels)
  154. new three
  155. setglobal ul=50
  156. call assert_equal(50, &g:undolevels)
  157. call assert_equal(-123456, &l:undolevels)
  158. " Resetting the local 'undolevels' value to use the global value
  159. setlocal undolevels=5
  160. "setlocal undolevels<
  161. set undolevels<
  162. call assert_equal(-123456, &l:undolevels)
  163. " Drop created windows
  164. set ul&
  165. new
  166. only!
  167. endfunc
  168. func BackOne(expected)
  169. call feedkeys('g-', 'xt')
  170. call assert_equal(a:expected, getline(1))
  171. endfunc
  172. func Test_undo_del_chars()
  173. throw 'Skipped: Nvim does not support test_settime()'
  174. " Setup a buffer without creating undo entries
  175. new
  176. set ul=-1
  177. call setline(1, ['123-456'])
  178. set ul=100
  179. 1
  180. call test_settime(100)
  181. " Delete three characters and undo with g-
  182. call feedkeys('x', 'xt')
  183. call feedkeys('x', 'xt')
  184. call feedkeys('x', 'xt')
  185. call assert_equal('-456', getline(1))
  186. call BackOne('3-456')
  187. call BackOne('23-456')
  188. call BackOne('123-456')
  189. call assert_fails("BackOne('123-456')")
  190. :" Delete three other characters and go back in time with g-
  191. call feedkeys('$x', 'xt')
  192. call feedkeys('x', 'xt')
  193. call feedkeys('x', 'xt')
  194. call assert_equal('123-', getline(1))
  195. call test_settime(101)
  196. call BackOne('123-4')
  197. call BackOne('123-45')
  198. " skips '123-456' because it's older
  199. call BackOne('-456')
  200. call BackOne('3-456')
  201. call BackOne('23-456')
  202. call BackOne('123-456')
  203. call assert_fails("BackOne('123-456')")
  204. normal 10g+
  205. call assert_equal('123-', getline(1))
  206. :" Jump two seconds and go some seconds forward and backward
  207. call test_settime(103)
  208. call feedkeys("Aa\<Esc>", 'xt')
  209. call feedkeys("Ab\<Esc>", 'xt')
  210. call feedkeys("Ac\<Esc>", 'xt')
  211. call assert_equal('123-abc', getline(1))
  212. earlier 1s
  213. call assert_equal('123-', getline(1))
  214. earlier 3s
  215. call assert_equal('123-456', getline(1))
  216. later 1s
  217. call assert_equal('123-', getline(1))
  218. later 1h
  219. call assert_equal('123-abc', getline(1))
  220. close!
  221. endfunc
  222. func Test_undolist()
  223. new
  224. set ul=100
  225. let a = execute('undolist')
  226. call assert_equal("\nNothing to undo", a)
  227. " 1 leaf (2 changes).
  228. call feedkeys('achange1', 'xt')
  229. call feedkeys('achange2', 'xt')
  230. let a = execute('undolist')
  231. call assert_match("^\nnumber changes when *saved\n *2 *2 .*$", a)
  232. " 2 leaves.
  233. call feedkeys('u', 'xt')
  234. call feedkeys('achange3\<Esc>', 'xt')
  235. let a = execute('undolist')
  236. call assert_match("^\nnumber changes when *saved\n *2 *2 *.*\n *3 *2 .*$", a)
  237. close!
  238. endfunc
  239. func Test_U_command()
  240. new
  241. set ul=100
  242. call feedkeys("achange1\<Esc>", 'xt')
  243. call feedkeys("achange2\<Esc>", 'xt')
  244. norm! U
  245. call assert_equal('', getline(1))
  246. norm! U
  247. call assert_equal('change1change2', getline(1))
  248. close!
  249. endfunc
  250. func Test_undojoin()
  251. new
  252. call feedkeys("Goaaaa\<Esc>", 'xt')
  253. call feedkeys("obbbb\<Esc>", 'xt')
  254. call assert_equal(['aaaa', 'bbbb'], getline(2, '$'))
  255. call feedkeys("u", 'xt')
  256. call assert_equal(['aaaa'], getline(2, '$'))
  257. call feedkeys("obbbb\<Esc>", 'xt')
  258. undojoin
  259. " Note: next change must not be as if typed
  260. call feedkeys("occcc\<Esc>", 'x')
  261. call assert_equal(['aaaa', 'bbbb', 'cccc'], getline(2, '$'))
  262. call feedkeys("u", 'xt')
  263. call assert_equal(['aaaa'], getline(2, '$'))
  264. bwipe!
  265. endfunc
  266. func Test_undojoin_redo()
  267. new
  268. call setline(1, ['first line', 'second line'])
  269. call feedkeys("ixx\<Esc>", 'xt')
  270. call feedkeys(":undojoin | redo\<CR>", 'xt')
  271. call assert_equal('xxfirst line', getline(1))
  272. call assert_equal('second line', getline(2))
  273. bwipe!
  274. endfunc
  275. " undojoin not allowed after undo
  276. func Test_undojoin_after_undo()
  277. new
  278. call feedkeys("ixx\<Esc>u", 'xt')
  279. call assert_fails(':undojoin', 'E790:')
  280. bwipe!
  281. endfunc
  282. " undojoin is a noop when no change yet, or when 'undolevels' is negative
  283. func Test_undojoin_noop()
  284. new
  285. call feedkeys(":undojoin\<CR>", 'xt')
  286. call assert_equal([''], getline(1, '$'))
  287. setlocal undolevels=-1
  288. call feedkeys("ixx\<Esc>u", 'xt')
  289. call feedkeys(":undojoin\<CR>", 'xt')
  290. call assert_equal(['xx'], getline(1, '$'))
  291. bwipe!
  292. endfunc
  293. func Test_undo_write()
  294. call delete('Xtest')
  295. split Xtest
  296. call feedkeys("ione one one\<Esc>", 'xt')
  297. w!
  298. call feedkeys("otwo\<Esc>", 'xt')
  299. call feedkeys("otwo\<Esc>", 'xt')
  300. w
  301. call feedkeys("othree\<Esc>", 'xt')
  302. call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
  303. earlier 1f
  304. call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
  305. earlier 1f
  306. call assert_equal(['one one one'], getline(1, '$'))
  307. earlier 1f
  308. call assert_equal([''], getline(1, '$'))
  309. later 1f
  310. call assert_equal(['one one one'], getline(1, '$'))
  311. later 1f
  312. call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
  313. later 1f
  314. call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
  315. close!
  316. call delete('Xtest')
  317. bwipe! Xtest
  318. call assert_fails('earlier xyz', 'E475:')
  319. endfunc
  320. func Test_insert_expr()
  321. new
  322. " calling setline() triggers undo sync
  323. call feedkeys("oa\<Esc>", 'xt')
  324. call feedkeys("ob\<Esc>", 'xt')
  325. set ul=100
  326. call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
  327. call assert_equal(['a', 'b', '120', '34'], getline(2, '$'))
  328. call feedkeys("u", 'x')
  329. call assert_equal(['a', 'b', '12'], getline(2, '$'))
  330. call feedkeys("u", 'x')
  331. call assert_equal(['a', 'b'], getline(2, '$'))
  332. call feedkeys("oc\<Esc>", 'xt')
  333. set ul=100
  334. call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
  335. call assert_equal(['a', 'b', 'c', '120', '34'], getline(2, '$'))
  336. call feedkeys("u", 'x')
  337. call assert_equal(['a', 'b', 'c', '12'], getline(2, '$'))
  338. call feedkeys("od\<Esc>", 'xt')
  339. set ul=100
  340. call feedkeys("o1\<Esc>a2\<C-R>=string(123)\<CR>\<Esc>", 'x')
  341. call assert_equal(['a', 'b', 'c', '12', 'd', '12123'], getline(2, '$'))
  342. call feedkeys("u", 'x')
  343. call assert_equal(['a', 'b', 'c', '12', 'd'], getline(2, '$'))
  344. close!
  345. endfunc
  346. func Test_undofile_earlier()
  347. throw 'Skipped: Nvim does not support test_settime()'
  348. if has('win32')
  349. " FIXME: This test is flaky on MS-Windows.
  350. let g:test_is_flaky = 1
  351. endif
  352. " Issue #1254
  353. " create undofile with timestamps older than Vim startup time.
  354. let t0 = localtime() - 43200
  355. call test_settime(t0)
  356. new XfileEarlier
  357. call feedkeys("ione\<Esc>", 'xt')
  358. set ul=100
  359. call test_settime(t0 + 1)
  360. call feedkeys("otwo\<Esc>", 'xt')
  361. set ul=100
  362. call test_settime(t0 + 2)
  363. call feedkeys("othree\<Esc>", 'xt')
  364. set ul=100
  365. w
  366. wundo Xundofile
  367. bwipe!
  368. " restore normal timestamps.
  369. call test_settime(0)
  370. new XfileEarlier
  371. rundo Xundofile
  372. earlier 1d
  373. call assert_equal('', getline(1))
  374. bwipe!
  375. call delete('XfileEarlier')
  376. call delete('Xundofile')
  377. endfunc
  378. func Test_wundo_errors()
  379. new
  380. call setline(1, 'hello')
  381. call assert_fails('wundo! Xdoesnotexist/Xundofile', 'E828:')
  382. bwipe!
  383. endfunc
  384. " Check that reading a truncated undo file doesn't hang.
  385. func Test_undofile_truncated()
  386. new
  387. call setline(1, 'hello')
  388. set ul=100
  389. wundo Xundofile
  390. let contents = readfile('Xundofile', 'B')
  391. " try several sizes
  392. for size in range(20, 500, 33)
  393. call writefile(contents[0:size], 'Xundofile')
  394. call assert_fails('rundo Xundofile', 'E825:')
  395. endfor
  396. bwipe!
  397. call delete('Xundofile')
  398. endfunc
  399. func Test_rundo_errors()
  400. call assert_fails('rundo XfileDoesNotExist', 'E822:')
  401. call writefile(['abc'], 'Xundofile')
  402. call assert_fails('rundo Xundofile', 'E823:')
  403. call delete('Xundofile')
  404. endfunc
  405. func Test_undofile_next()
  406. set undofile
  407. new Xfoo.txt
  408. execute "norm ix\<c-g>uy\<c-g>uz\<Esc>"
  409. write
  410. bwipe
  411. next Xfoo.txt
  412. call assert_equal('xyz', getline(1))
  413. silent undo
  414. call assert_equal('xy', getline(1))
  415. silent undo
  416. call assert_equal('x', getline(1))
  417. bwipe!
  418. call delete('Xfoo.txt')
  419. call delete('.Xfoo.txt.un~')
  420. set undofile&
  421. endfunc
  422. " Test for undo working properly when executing commands from a register.
  423. " Also test this in an empty buffer.
  424. func Test_cmd_in_reg_undo()
  425. enew!
  426. let @a = "Ox\<Esc>jAy\<Esc>kdd"
  427. edit +/^$ test_undo.vim
  428. normal @au
  429. call assert_equal(0, &modified)
  430. return
  431. new
  432. normal @au
  433. call assert_equal(0, &modified)
  434. only!
  435. let @a = ''
  436. endfunc
  437. " This used to cause an illegal memory access
  438. func Test_undo_append()
  439. new
  440. call feedkeys("axx\<Esc>v", 'xt')
  441. undo
  442. norm o
  443. quit
  444. endfunc
  445. func Test_undo_0()
  446. new
  447. set ul=100
  448. normal i1
  449. undo
  450. normal i2
  451. undo
  452. normal i3
  453. undo 0
  454. let d = undotree()
  455. call assert_equal('', getline(1))
  456. call assert_equal(0, d.seq_cur)
  457. redo
  458. let d = undotree()
  459. call assert_equal('3', getline(1))
  460. call assert_equal(3, d.seq_cur)
  461. undo 2
  462. undo 0
  463. let d = undotree()
  464. call assert_equal('', getline(1))
  465. call assert_equal(0, d.seq_cur)
  466. redo
  467. let d = undotree()
  468. call assert_equal('2', getline(1))
  469. call assert_equal(2, d.seq_cur)
  470. undo 1
  471. undo 0
  472. let d = undotree()
  473. call assert_equal('', getline(1))
  474. call assert_equal(0, d.seq_cur)
  475. redo
  476. let d = undotree()
  477. call assert_equal('1', getline(1))
  478. call assert_equal(1, d.seq_cur)
  479. bwipe!
  480. endfunc
  481. " undo or redo are noop if there is nothing to undo or redo
  482. func Test_undo_redo_noop()
  483. new
  484. call assert_fails('undo 2', 'E830:')
  485. message clear
  486. undo
  487. let messages = split(execute('message'), "\n")
  488. call assert_equal('Already at oldest change', messages[-1])
  489. message clear
  490. redo
  491. let messages = split(execute('message'), "\n")
  492. call assert_equal('Already at newest change', messages[-1])
  493. bwipe!
  494. endfunc
  495. func Test_redo_empty_line()
  496. new
  497. exe "norm\x16r\x160"
  498. exe "norm."
  499. bwipe!
  500. endfunc
  501. funct Test_undofile()
  502. " Test undofile() without setting 'undodir'.
  503. if has('persistent_undo')
  504. call assert_equal(fnamemodify('.Xundofoo.un~', ':p'), undofile('Xundofoo'))
  505. else
  506. call assert_equal('', undofile('Xundofoo'))
  507. endif
  508. call assert_equal('', undofile(''))
  509. " Test undofile() with 'undodir' set to an existing directory.
  510. call mkdir('Xundodir')
  511. set undodir=Xundodir
  512. let cwd = getcwd()
  513. if has('win32')
  514. " Replace windows drive such as C:... into C%...
  515. let cwd = substitute(cwd, '^\([a-zA-Z]\):', '\1%', 'g')
  516. endif
  517. let cwd = substitute(cwd . '/Xundofoo', '/', '%', 'g')
  518. if has('persistent_undo')
  519. call assert_equal('Xundodir/' . cwd, undofile('Xundofoo'))
  520. else
  521. call assert_equal('', undofile('Xundofoo'))
  522. endif
  523. call assert_equal('', undofile(''))
  524. call delete('Xundodir', 'd')
  525. " Test undofile() with 'undodir' set to a non-existing directory.
  526. " call assert_equal('', 'Xundofoo'->undofile())
  527. if isdirectory('/tmp')
  528. set undodir=/tmp
  529. if has('osx')
  530. call assert_equal('/tmp/%private%tmp%file', undofile('///tmp/file'))
  531. else
  532. call assert_equal('/tmp/%tmp%file', undofile('///tmp/file'))
  533. endif
  534. endif
  535. set undodir&
  536. endfunc
  537. " Tests for the undo file
  538. " Explicitly break changes up in undo-able pieces by setting 'undolevels'.
  539. func Test_undofile_2()
  540. set undolevels=100 undofile
  541. edit Xtestfile
  542. call append(0, 'this is one line')
  543. call cursor(1, 1)
  544. " first a simple one-line change.
  545. set undolevels=100
  546. s/one/ONE/
  547. set undolevels=100
  548. write
  549. bwipe!
  550. edit Xtestfile
  551. undo
  552. call assert_equal('this is one line', getline(1))
  553. " change in original file fails check
  554. set noundofile
  555. edit! Xtestfile
  556. s/line/Line/
  557. write
  558. set undofile
  559. bwipe!
  560. edit Xtestfile
  561. undo
  562. call assert_equal('this is ONE Line', getline(1))
  563. " add 10 lines, delete 6 lines, undo 3
  564. set undofile
  565. call setbufline('%', 1, ['one', 'two', 'three', 'four', 'five', 'six',
  566. \ 'seven', 'eight', 'nine', 'ten'])
  567. set undolevels=100
  568. normal 3Gdd
  569. set undolevels=100
  570. normal dd
  571. set undolevels=100
  572. normal dd
  573. set undolevels=100
  574. normal dd
  575. set undolevels=100
  576. normal dd
  577. set undolevels=100
  578. normal dd
  579. set undolevels=100
  580. write
  581. bwipe!
  582. edit Xtestfile
  583. normal uuu
  584. call assert_equal(['one', 'two', 'six', 'seven', 'eight', 'nine', 'ten'],
  585. \ getline(1, '$'))
  586. " Test that reading the undofiles when setting undofile works
  587. set noundofile undolevels=0
  588. exe "normal i\n"
  589. undo
  590. edit! Xtestfile
  591. set undofile undolevels=100
  592. normal uuuuuu
  593. call assert_equal(['one', 'two', 'three', 'four', 'five', 'six', 'seven',
  594. \ 'eight', 'nine', 'ten'], getline(1, '$'))
  595. bwipe!
  596. call delete('Xtestfile')
  597. let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
  598. call delete(ufile)
  599. set undofile& undolevels&
  600. endfunc
  601. " Test 'undofile' using a file encrypted with 'zip' crypt method
  602. func Test_undofile_cryptmethod_zip()
  603. throw 'skipped: Nvim does not support cryptmethod'
  604. edit Xtestfile
  605. set undofile cryptmethod=zip
  606. call append(0, ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])
  607. call cursor(5, 1)
  608. set undolevels=100
  609. normal kkkdd
  610. set undolevels=100
  611. normal dd
  612. set undolevels=100
  613. normal dd
  614. set undolevels=100
  615. " encrypt the file using key 'foobar'
  616. call feedkeys("foobar\nfoobar\n")
  617. X
  618. write!
  619. bwipe!
  620. call feedkeys("foobar\n")
  621. edit Xtestfile
  622. set key=
  623. normal uu
  624. call assert_equal(['monday', 'wednesday', 'thursday', 'friday', ''],
  625. \ getline(1, '$'))
  626. bwipe!
  627. call delete('Xtestfile')
  628. let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
  629. call delete(ufile)
  630. set undofile& undolevels& cryptmethod&
  631. endfunc
  632. " Test 'undofile' using a file encrypted with 'blowfish' crypt method
  633. func Test_undofile_cryptmethod_blowfish()
  634. throw 'skipped: Nvim does not support cryptmethod'
  635. edit Xtestfile
  636. set undofile cryptmethod=blowfish
  637. call append(0, ['jan', 'feb', 'mar', 'apr', 'jun'])
  638. call cursor(5, 1)
  639. set undolevels=100
  640. exe 'normal kk0ifoo '
  641. set undolevels=100
  642. normal dd
  643. set undolevels=100
  644. exe 'normal ibar '
  645. set undolevels=100
  646. " encrypt the file using key 'foobar'
  647. call feedkeys("foobar\nfoobar\n")
  648. X
  649. write!
  650. bwipe!
  651. call feedkeys("foobar\n")
  652. edit Xtestfile
  653. set key=
  654. call search('bar')
  655. call assert_equal('bar apr', getline('.'))
  656. undo
  657. call assert_equal('apr', getline('.'))
  658. undo
  659. call assert_equal('foo mar', getline('.'))
  660. undo
  661. call assert_equal('mar', getline('.'))
  662. bwipe!
  663. call delete('Xtestfile')
  664. let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
  665. call delete(ufile)
  666. set undofile& undolevels& cryptmethod&
  667. endfunc
  668. " Test 'undofile' using a file encrypted with 'blowfish2' crypt method
  669. func Test_undofile_cryptmethod_blowfish2()
  670. throw 'skipped: Nvim does not support cryptmethod'
  671. edit Xtestfile
  672. set undofile cryptmethod=blowfish2
  673. call append(0, ['jan', 'feb', 'mar', 'apr', 'jun'])
  674. call cursor(5, 1)
  675. set undolevels=100
  676. exe 'normal kk0ifoo '
  677. set undolevels=100
  678. normal dd
  679. set undolevels=100
  680. exe 'normal ibar '
  681. set undolevels=100
  682. " encrypt the file using key 'foo2bar'
  683. call feedkeys("foo2bar\nfoo2bar\n")
  684. X
  685. write!
  686. bwipe!
  687. call feedkeys("foo2bar\n")
  688. edit Xtestfile
  689. set key=
  690. call search('bar')
  691. call assert_equal('bar apr', getline('.'))
  692. normal u
  693. call assert_equal('apr', getline('.'))
  694. normal u
  695. call assert_equal('foo mar', getline('.'))
  696. normal u
  697. call assert_equal('mar', getline('.'))
  698. bwipe!
  699. call delete('Xtestfile')
  700. let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
  701. call delete(ufile)
  702. set undofile& undolevels& cryptmethod&
  703. endfunc
  704. " Test for redoing with incrementing numbered registers
  705. func Test_redo_repeat_numbered_register()
  706. new
  707. for [i, v] in [[1, 'one'], [2, 'two'], [3, 'three'],
  708. \ [4, 'four'], [5, 'five'], [6, 'six'],
  709. \ [7, 'seven'], [8, 'eight'], [9, 'nine']]
  710. exe 'let @' .. i .. '="' .. v .. '\n"'
  711. endfor
  712. call feedkeys('"1p.........', 'xt')
  713. call assert_equal(['', 'one', 'two', 'three', 'four', 'five', 'six',
  714. \ 'seven', 'eight', 'nine', 'nine'], getline(1, '$'))
  715. bwipe!
  716. endfunc
  717. " Test for redo in insert mode using CTRL-O with multibyte characters
  718. func Test_redo_multibyte_in_insert_mode()
  719. new
  720. call feedkeys("a\<C-K>ft", 'xt')
  721. call feedkeys("uiHe\<C-O>.llo", 'xt')
  722. call assert_equal("He\ufb05llo", getline(1))
  723. bwipe!
  724. endfunc
  725. func Test_undo_mark()
  726. new
  727. " The undo is applied to the only line.
  728. call setline(1, 'hello')
  729. call feedkeys("ggyiw$p", 'xt')
  730. undo
  731. call assert_equal([0, 1, 1, 0], getpos("'["))
  732. call assert_equal([0, 1, 1, 0], getpos("']"))
  733. " The undo removes the last line.
  734. call feedkeys("Goaaaa\<Esc>", 'xt')
  735. call feedkeys("obbbb\<Esc>", 'xt')
  736. undo
  737. call assert_equal([0, 2, 1, 0], getpos("'["))
  738. call assert_equal([0, 2, 1, 0], getpos("']"))
  739. bwipe!
  740. endfunc
  741. func Test_undo_after_write()
  742. " use a terminal to make undo work like when text is typed
  743. CheckRunVimInTerminal
  744. let lines =<< trim END
  745. edit Xtestfile.txt
  746. set undolevels=100 undofile
  747. imap . <Cmd>write<CR>
  748. write
  749. END
  750. call writefile(lines, 'Xtest_undo_after_write', 'D')
  751. let buf = RunVimInTerminal('-S Xtest_undo_after_write', #{rows: 6})
  752. call term_sendkeys(buf, "Otest.\<CR>boo!!!\<Esc>")
  753. sleep 100m
  754. call term_sendkeys(buf, "u")
  755. call VerifyScreenDump(buf, 'Test_undo_after_write_1', {})
  756. call term_sendkeys(buf, "u")
  757. call VerifyScreenDump(buf, 'Test_undo_after_write_2', {})
  758. call StopVimInTerminal(buf)
  759. call delete('Xtestfile.txt')
  760. call delete('.Xtestfile.txt.un~')
  761. endfunc
  762. func Test_undo_range_normal()
  763. new
  764. call setline(1, ['asa', 'bsb'])
  765. let &l:undolevels = &l:undolevels
  766. %normal dfs
  767. call assert_equal(['a', 'b'], getline(1, '$'))
  768. undo
  769. call assert_equal(['asa', 'bsb'], getline(1, '$'))
  770. bwipe!
  771. endfunc
  772. " vim: shiftwidth=2 sts=2 expandtab