fold_spec.lua 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. local helpers = require('test.functional.helpers')(after_each)
  2. local clear = helpers.clear
  3. local insert = helpers.insert
  4. local feed = helpers.feed
  5. local expect = helpers.expect
  6. local feed_command = helpers.feed_command
  7. local funcs = helpers.funcs
  8. local foldlevel = funcs.foldlevel
  9. local foldclosedend = funcs.foldclosedend
  10. local eq = helpers.eq
  11. describe('Folds', function()
  12. local tempfname = 'Xtest-fold.txt'
  13. clear()
  14. before_each(function() feed_command('enew!') end)
  15. after_each(function() os.remove(tempfname) end)
  16. it('manual folding adjusts with filter', function()
  17. insert([[
  18. 1
  19. 2
  20. 3
  21. 4
  22. 5
  23. 6
  24. 7
  25. 8
  26. 9
  27. 10
  28. 11
  29. 12
  30. 13
  31. 14
  32. 15
  33. 16
  34. 17
  35. 18
  36. 19
  37. 20]])
  38. feed_command('4,$fold', '%foldopen', '10,$fold', '%foldopen')
  39. feed_command('1,8! cat')
  40. feed('5ggzdzMGdd')
  41. expect([[
  42. 1
  43. 2
  44. 3
  45. 4
  46. 5
  47. 6
  48. 7
  49. 8
  50. 9]])
  51. end)
  52. describe('adjusting folds after :move', function()
  53. local function manually_fold_indent()
  54. -- setting foldmethod twice is a trick to get vim to set the folds for me
  55. feed_command('set foldmethod=indent', 'set foldmethod=manual')
  56. -- Ensure that all folds will get closed (makes it easier to test the
  57. -- length of folds).
  58. feed_command('set foldminlines=0')
  59. -- Start with all folds open (so :move ranges aren't affected by closed
  60. -- folds).
  61. feed_command('%foldopen!')
  62. end
  63. local function get_folds()
  64. local rettab = {}
  65. for i = 1, funcs.line('$') do
  66. table.insert(rettab, foldlevel(i))
  67. end
  68. return rettab
  69. end
  70. local function test_move_indent(insert_string, move_command)
  71. -- This test is easy because we just need to ensure that the resulting
  72. -- fold is the same as calculated when creating folds from scratch.
  73. insert(insert_string)
  74. feed_command(move_command)
  75. local after_move_folds = get_folds()
  76. -- Doesn't change anything, but does call foldUpdateAll()
  77. feed_command('set foldminlines=0')
  78. eq(after_move_folds, get_folds())
  79. -- Set up the buffer with insert_string for the manual fold testing.
  80. feed_command('enew!')
  81. insert(insert_string)
  82. manually_fold_indent()
  83. feed_command(move_command)
  84. end
  85. it('neither closes nor corrupts folds', function()
  86. test_move_indent([[
  87. a
  88. a
  89. a
  90. a
  91. a
  92. a
  93. a
  94. a
  95. a
  96. a
  97. a
  98. a
  99. a
  100. a
  101. a
  102. a
  103. a
  104. a]], '7,12m0')
  105. expect([[
  106. a
  107. a
  108. a
  109. a
  110. a
  111. a
  112. a
  113. a
  114. a
  115. a
  116. a
  117. a
  118. a
  119. a
  120. a
  121. a
  122. a
  123. a]])
  124. -- lines are not closed, folds are correct
  125. for i = 1,funcs.line('$') do
  126. eq(-1, funcs.foldclosed(i))
  127. if i == 1 or i == 7 or i == 13 then
  128. eq(0, foldlevel(i))
  129. elseif i == 4 then
  130. eq(2, foldlevel(i))
  131. else
  132. eq(1, foldlevel(i))
  133. end
  134. end
  135. -- folds are not corrupted
  136. feed('zM')
  137. eq(6, foldclosedend(2))
  138. eq(12, foldclosedend(8))
  139. eq(18, foldclosedend(14))
  140. end)
  141. it("doesn't split a fold when the move is within it", function()
  142. test_move_indent([[
  143. a
  144. a
  145. a
  146. a
  147. a
  148. a
  149. a
  150. a
  151. a
  152. a]], '5m6')
  153. eq({0, 1, 1, 2, 2, 2, 2, 1, 1, 0}, get_folds())
  154. end)
  155. it('truncates folds that end in the moved range', function()
  156. test_move_indent([[
  157. a
  158. a
  159. a
  160. a
  161. a
  162. a
  163. a]], '4,5m6')
  164. eq({0, 1, 2, 0, 0, 0, 0}, get_folds())
  165. end)
  166. it('moves folds that start between moved range and destination', function()
  167. test_move_indent([[
  168. a
  169. a
  170. a
  171. a
  172. a
  173. a
  174. a
  175. a
  176. a
  177. a
  178. a
  179. a
  180. a]], '3,4m$')
  181. eq({0, 1, 1, 0, 0, 1, 2, 1, 0, 0, 1, 0, 0}, get_folds())
  182. end)
  183. it('does not affect folds outside changed lines', function()
  184. test_move_indent([[
  185. a
  186. a
  187. a
  188. a
  189. a
  190. a
  191. a
  192. a
  193. a]], '4m5')
  194. eq({1, 1, 1, 0, 0, 0, 1, 1, 1}, get_folds())
  195. end)
  196. it('moves and truncates folds that start in moved range', function()
  197. test_move_indent([[
  198. a
  199. a
  200. a
  201. a
  202. a
  203. a
  204. a
  205. a
  206. a
  207. a]], '1,3m7')
  208. eq({0, 0, 0, 0, 0, 1, 2, 0, 0, 0}, get_folds())
  209. end)
  210. it('breaks a fold when moving text into it', function()
  211. test_move_indent([[
  212. a
  213. a
  214. a
  215. a
  216. a
  217. a
  218. a]], '$m4')
  219. eq({0, 1, 2, 2, 0, 0, 0}, get_folds())
  220. end)
  221. it('adjusts correctly when moving a range backwards', function()
  222. test_move_indent([[
  223. a
  224. a
  225. a
  226. a
  227. a]], '2,3m0')
  228. eq({1, 2, 0, 0, 0}, get_folds())
  229. end)
  230. it('handles shifting all remaining folds', function()
  231. test_move_indent([[
  232. a
  233. a
  234. a
  235. a
  236. a
  237. a
  238. a
  239. a
  240. a
  241. a
  242. a
  243. a
  244. a
  245. a
  246. a]], '13m7')
  247. eq({1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0}, get_folds())
  248. end)
  249. end)
  250. it('updates correctly on :read', function()
  251. -- luacheck: ignore 621
  252. helpers.write_file(tempfname, [[
  253. a
  254. a]])
  255. insert([[
  256. a
  257. a
  258. a
  259. a
  260. ]])
  261. feed_command('set foldmethod=indent', '2', '%foldopen')
  262. feed_command('read ' .. tempfname)
  263. -- Just to check we have the correct file text.
  264. expect([[
  265. a
  266. a
  267. a
  268. a
  269. a
  270. a
  271. ]])
  272. for i = 1,2 do
  273. eq(1, funcs.foldlevel(i))
  274. end
  275. for i = 3,5 do
  276. eq(0, funcs.foldlevel(i))
  277. end
  278. for i = 6,8 do
  279. eq(1, funcs.foldlevel(i))
  280. end
  281. end)
  282. it('combines folds when removing separating space', function()
  283. -- luacheck: ignore 621
  284. insert([[
  285. a
  286. a
  287. a
  288. a
  289. a
  290. a
  291. a
  292. a
  293. ]])
  294. feed_command('set foldmethod=indent', '3,5d')
  295. eq(5, funcs.foldclosedend(1))
  296. end)
  297. it("doesn't combine folds that have a specified end", function()
  298. insert([[
  299. {{{
  300. }}}
  301. {{{
  302. }}}
  303. ]])
  304. feed_command('set foldmethod=marker', '3,5d', '%foldclose')
  305. eq(2, funcs.foldclosedend(1))
  306. end)
  307. it('splits folds according to >N and <N with foldexpr', function()
  308. helpers.source([[
  309. function TestFoldExpr(lnum)
  310. let thisline = getline(a:lnum)
  311. if thisline == 'a'
  312. return 1
  313. elseif thisline == 'b'
  314. return 0
  315. elseif thisline == 'c'
  316. return '<1'
  317. elseif thisline == 'd'
  318. return '>1'
  319. endif
  320. return 0
  321. endfunction
  322. ]])
  323. helpers.write_file(tempfname, [[
  324. b
  325. b
  326. a
  327. a
  328. d
  329. a
  330. a
  331. c]])
  332. insert([[
  333. a
  334. a
  335. a
  336. a
  337. a
  338. a
  339. ]])
  340. feed_command('set foldmethod=expr', 'set foldexpr=TestFoldExpr(v:lnum)', '2', 'foldopen')
  341. feed_command('read ' .. tempfname, '%foldclose')
  342. eq(2, funcs.foldclosedend(1))
  343. eq(0, funcs.foldlevel(3))
  344. eq(0, funcs.foldlevel(4))
  345. eq(6, funcs.foldclosedend(5))
  346. eq(10, funcs.foldclosedend(7))
  347. eq(14, funcs.foldclosedend(11))
  348. end)
  349. end)