test_fold.vim 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781
  1. " Test for folding
  2. source check.vim
  3. source view_util.vim
  4. source screendump.vim
  5. func PrepIndent(arg)
  6. return [a:arg] + repeat(["\t".a:arg], 5)
  7. endfu
  8. func Test_address_fold_new_default_commentstring()
  9. " Test with the new commentstring defaults, that includes padding after v9.1.464
  10. new
  11. call setline(1, ['int FuncName() {/* {{{ */', 1, 2, 3, 4, 5, '}/* }}} */',
  12. \ 'after fold 1', 'after fold 2', 'after fold 3'])
  13. setl fen fdm=marker
  14. " The next commands should all copy the same part of the buffer,
  15. " regardless of the addressing type, since the part to be copied
  16. " is folded away
  17. :1y
  18. call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
  19. :.y
  20. call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
  21. :.+y
  22. call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
  23. :.,.y
  24. call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
  25. :sil .1,.y
  26. call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
  27. " use silent to make E493 go away
  28. :sil .+,.y
  29. call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
  30. :,y
  31. call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
  32. :,+y
  33. call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */','after fold 1'], getreg(0,1,1))
  34. " using .+3 as second address should c opy the whole folded line + the next 3
  35. " lines
  36. :.,+3y
  37. call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */',
  38. \ 'after fold 1', 'after fold 2' , 'after fold 3'], getreg(0,1,1))
  39. :sil .,-2y
  40. call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
  41. " now test again with folding disabled
  42. set nofoldenable
  43. :1y
  44. call assert_equal(['int FuncName() {/* {{{ */'], getreg(0,1,1))
  45. :.y
  46. call assert_equal(['int FuncName() {/* {{{ */'], getreg(0,1,1))
  47. :.+y
  48. call assert_equal(['1'], getreg(0,1,1) )
  49. :.,.y
  50. call assert_equal(['int FuncName() {/* {{{ */'], getreg(0,1,1))
  51. " use silent to make E493 go away
  52. :sil .1,.y
  53. call assert_equal(['int FuncName() {/* {{{ */', '1'], getreg(0,1,1))
  54. " use silent to make E493 go away
  55. :sil .+,.y
  56. call assert_equal(['int FuncName() {/* {{{ */', '1'], getreg(0,1,1))
  57. :,y
  58. call assert_equal(['int FuncName() {/* {{{ */'], getreg(0,1,1))
  59. :,+y
  60. call assert_equal(['int FuncName() {/* {{{ */', '1'], getreg(0,1,1))
  61. " using .+3 as second address should c opy the whole folded line + the next 3
  62. " lines
  63. :.,+3y
  64. call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3'], getreg(0,1,1))
  65. :7
  66. :sil .,-2y
  67. call assert_equal(['4', '5', '}/* }}} */'], getreg(0,1,1))
  68. quit!
  69. endfunc
  70. func Test_address_fold_old_default_commentstring()
  71. " Test with the old commentstring defaults, before v9.1.464
  72. new
  73. call setline(1, ['int FuncName() {/*{{{*/', 1, 2, 3, 4, 5, '}/*}}}*/',
  74. \ 'after fold 1', 'after fold 2', 'after fold 3'])
  75. setl fen fdm=marker
  76. " The next commands should all copy the same part of the buffer,
  77. " regardless of the addressing type, since the part to be copied
  78. " is folded away
  79. :1y
  80. call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
  81. :.y
  82. call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
  83. :.+y
  84. call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
  85. :.,.y
  86. call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
  87. :sil .1,.y
  88. call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
  89. " use silent to make E493 go away
  90. :sil .+,.y
  91. call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
  92. :,y
  93. call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
  94. :,+y
  95. call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/','after fold 1'], getreg(0,1,1))
  96. " using .+3 as second address should copy the whole folded line + the next 3
  97. " lines
  98. :.,+3y
  99. call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/',
  100. \ 'after fold 1', 'after fold 2', 'after fold 3'], getreg(0,1,1))
  101. :sil .,-2y
  102. call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
  103. " now test again with folding disabled
  104. set nofoldenable
  105. :1y
  106. call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
  107. :.y
  108. call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
  109. :.+y
  110. call assert_equal(['1'], getreg(0,1,1))
  111. :.,.y
  112. call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
  113. " use silent to make E493 go away
  114. :sil .1,.y
  115. call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
  116. " use silent to make E493 go away
  117. :sil .+,.y
  118. call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
  119. :,y
  120. call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
  121. :,+y
  122. call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
  123. " using .+3 as second address should copy the whole folded line + the next 3
  124. " lines
  125. :.,+3y
  126. call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3'], getreg(0,1,1))
  127. :7
  128. :sil .,-2y
  129. call assert_equal(['4', '5', '}/*}}}*/'], getreg(0,1,1))
  130. quit!
  131. endfunc
  132. func Test_address_offsets()
  133. " check the help for :range-closed-fold
  134. enew
  135. call setline(1, [
  136. \ '1 one',
  137. \ '2 two',
  138. \ '3 three',
  139. \ '4 four FOLDED',
  140. \ '5 five FOLDED',
  141. \ '6 six',
  142. \ '7 seven',
  143. \ '8 eight',
  144. \])
  145. set foldmethod=manual
  146. normal 4Gvjzf
  147. 3,4+2yank
  148. call assert_equal([
  149. \ '3 three',
  150. \ '4 four FOLDED',
  151. \ '5 five FOLDED',
  152. \ '6 six',
  153. \ '7 seven',
  154. \ ], getreg(0,1,1))
  155. enew!
  156. call setline(1, [
  157. \ '1 one',
  158. \ '2 two',
  159. \ '3 three FOLDED',
  160. \ '4 four FOLDED',
  161. \ '5 five FOLDED',
  162. \ '6 six FOLDED',
  163. \ '7 seven',
  164. \ '8 eight',
  165. \])
  166. normal 3Gv3jzf
  167. 2,4-1yank
  168. call assert_equal([
  169. \ '2 two',
  170. \ '3 three FOLDED',
  171. \ '4 four FOLDED',
  172. \ '5 five FOLDED',
  173. \ '6 six FOLDED',
  174. \ ], getreg(0,1,1))
  175. bwipe!
  176. endfunc
  177. func Test_indent_fold()
  178. new
  179. call setline(1, ['', 'a', ' b', ' c'])
  180. setl fen fdm=indent
  181. 2
  182. norm! >>
  183. let a=map(range(1,4), 'foldclosed(v:val)')
  184. call assert_equal([-1,-1,-1,-1], a)
  185. bw!
  186. endfunc
  187. func Test_indent_fold2()
  188. new
  189. call setline(1, ['', '{{{', '}}}', '{{{', '}}}'])
  190. setl fen fdm=marker
  191. 2
  192. norm! >>
  193. let a=map(range(1,5), 'v:val->foldclosed()')
  194. call assert_equal([-1,-1,-1,4,4], a)
  195. bw!
  196. endfunc
  197. " Test for fold indent with indents greater than 'foldnestmax'
  198. func Test_indent_fold_max()
  199. new
  200. setlocal foldmethod=indent
  201. setlocal shiftwidth=2
  202. " 'foldnestmax' default value is 20
  203. call setline(1, "\t\t\t\t\t\ta")
  204. call assert_equal(20, foldlevel(1))
  205. setlocal foldnestmax=10
  206. call assert_equal(10, foldlevel(1))
  207. setlocal foldnestmax=-1
  208. call assert_equal(0, foldlevel(1))
  209. bw!
  210. endfunc
  211. func Test_indent_fold_tabstop()
  212. call setline(1, ['0', ' 1', ' 1', "\t2", "\t2"])
  213. setlocal shiftwidth=4
  214. setlocal foldcolumn=1
  215. setlocal foldlevel=2
  216. setlocal foldmethod=indent
  217. redraw
  218. call assert_equal('2 2', ScreenLines(5, 10)[0])
  219. vsplit
  220. windo diffthis
  221. botright new
  222. " This 'tabstop' value should not be used for folding in other buffers.
  223. setlocal tabstop=4
  224. diffoff!
  225. redraw
  226. call assert_equal('2 2', ScreenLines(5, 10)[0])
  227. bwipe!
  228. bwipe!
  229. endfunc
  230. func Test_manual_fold_with_filter()
  231. CheckExecutable cat
  232. for type in ['manual', 'marker']
  233. exe 'set foldmethod=' . type
  234. new
  235. call setline(1, range(1, 20))
  236. 4,$fold
  237. %foldopen
  238. 10,$fold
  239. %foldopen
  240. " This filter command should not have an effect
  241. 1,8! cat
  242. call feedkeys('5ggzdzMGdd', 'xt')
  243. call assert_equal(['1', '2', '3', '4', '5', '6', '7', '8', '9'], getline(1, '$'))
  244. bwipe!
  245. set foldmethod&
  246. endfor
  247. endfunc
  248. func Test_indent_fold_with_read()
  249. new
  250. set foldmethod=indent
  251. call setline(1, repeat(["\<Tab>a"], 4))
  252. for n in range(1, 4)
  253. call assert_equal(1, foldlevel(n))
  254. endfor
  255. call writefile(["a", "", "\<Tab>a"], 'Xfile')
  256. foldopen
  257. 2read Xfile
  258. %foldclose
  259. call assert_equal(1, foldlevel(1))
  260. call assert_equal(2, foldclosedend(1))
  261. call assert_equal(0, foldlevel(3))
  262. call assert_equal(0, foldlevel(4))
  263. call assert_equal(1, foldlevel(5))
  264. call assert_equal(7, 5->foldclosedend())
  265. bwipe!
  266. set foldmethod&
  267. call delete('Xfile')
  268. endfunc
  269. func Test_combining_folds_indent()
  270. new
  271. let one = "\<Tab>a"
  272. let zero = 'a'
  273. call setline(1, [one, one, zero, zero, zero, one, one, one])
  274. set foldmethod=indent
  275. 3,5d
  276. %foldclose
  277. call assert_equal(5, foldclosedend(1))
  278. set foldmethod&
  279. bwipe!
  280. endfunc
  281. func Test_combining_folds_marker()
  282. new
  283. call setline(1, ['{{{', '}}}', '', '', '', '{{{', '', '}}}'])
  284. set foldmethod=marker
  285. 3,5d
  286. %foldclose
  287. call assert_equal(2, foldclosedend(1))
  288. set foldmethod&
  289. bwipe!
  290. endfunc
  291. func Test_folds_marker_in_comment()
  292. new
  293. call setline(1, ['" foo', 'bar', 'baz'])
  294. setl fen fdm=marker
  295. setl com=sO:\"\ -,mO:\"\ \ ,eO:\"\",:\" cms=\"%s
  296. norm! zf2j
  297. setl nofen
  298. :1y
  299. call assert_equal(['" foo{{{'], getreg(0,1,1))
  300. :+2y
  301. call assert_equal(['baz"}}}'], getreg(0,1,1))
  302. set foldmethod&
  303. bwipe!
  304. endfunc
  305. func s:TestFoldExpr(lnum)
  306. let thisline = getline(a:lnum)
  307. if thisline == 'a'
  308. return 1
  309. elseif thisline == 'b'
  310. return 0
  311. elseif thisline == 'c'
  312. return '<1'
  313. elseif thisline == 'd'
  314. return '>1'
  315. endif
  316. return 0
  317. endfunction
  318. func Test_update_folds_expr_read()
  319. new
  320. call setline(1, ['a', 'a', 'a', 'a', 'a', 'a'])
  321. set foldmethod=expr
  322. set foldexpr=s:TestFoldExpr(v:lnum)
  323. 2
  324. foldopen
  325. call writefile(['b', 'b', 'a', 'a', 'd', 'a', 'a', 'c'], 'Xfile')
  326. read Xfile
  327. %foldclose
  328. call assert_equal(2, foldclosedend(1))
  329. call assert_equal(0, foldlevel(3))
  330. call assert_equal(0, 4->foldlevel())
  331. call assert_equal(6, foldclosedend(5))
  332. call assert_equal(10, foldclosedend(7))
  333. call assert_equal(14, foldclosedend(11))
  334. call delete('Xfile')
  335. bwipe!
  336. set foldmethod& foldexpr&
  337. endfunc
  338. " Test for what patch 8.1.0535 fixes.
  339. func Test_foldexpr_no_interrupt_addsub()
  340. new
  341. func! FoldFunc()
  342. call setpos('.', getcurpos())
  343. return '='
  344. endfunc
  345. set foldmethod=expr
  346. set foldexpr=FoldFunc()
  347. call setline(1, '1.2')
  348. exe "norm! $\<C-A>"
  349. call assert_equal('1.3', getline(1))
  350. bwipe!
  351. delfunc FoldFunc
  352. set foldmethod& foldexpr&
  353. endfunc
  354. " Fold function defined in another script
  355. func Test_foldexpr_compiled()
  356. throw 'Skipped: Vim9 script is N/A'
  357. new
  358. let lines =<< trim END
  359. vim9script
  360. def FoldFunc(): number
  361. return v:lnum
  362. enddef
  363. set foldmethod=expr
  364. set foldexpr=s:FoldFunc()
  365. END
  366. call writefile(lines, 'XfoldExpr', 'D')
  367. source XfoldExpr
  368. call setline(1, ['one', 'two', 'three'])
  369. redraw
  370. call assert_equal(1, foldlevel(1))
  371. call assert_equal(2, foldlevel(2))
  372. call assert_equal(3, foldlevel(3))
  373. bwipe!
  374. set foldmethod& foldexpr&
  375. endfunc
  376. func Check_foldlevels(expected)
  377. call assert_equal(a:expected, map(range(1, line('$')), 'foldlevel(v:val)'))
  378. endfunc
  379. func Test_move_folds_around_manual()
  380. new
  381. let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
  382. call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
  383. let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
  384. " all folds closed
  385. set foldenable foldlevel=0 fdm=indent
  386. " needs a forced redraw
  387. redraw!
  388. set fdm=manual
  389. call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
  390. call assert_equal(input, getline(1, '$'))
  391. 7,12m0
  392. call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
  393. call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
  394. 10,12m0
  395. call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$'))
  396. call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
  397. " moving should not close the folds
  398. %d
  399. call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
  400. set fdm=indent
  401. redraw!
  402. set fdm=manual
  403. call cursor(2, 1)
  404. %foldopen
  405. 7,12m0
  406. let folds=repeat([-1], 18)
  407. call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
  408. call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
  409. norm! zM
  410. " folds are not corrupted and all have been closed
  411. call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
  412. %d
  413. call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
  414. set fdm=indent
  415. redraw!
  416. set fdm=manual
  417. %foldopen
  418. 3m4
  419. %foldclose
  420. call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
  421. call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
  422. %d
  423. call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
  424. set fdm=indent foldlevel=0
  425. set fdm=manual
  426. %foldopen
  427. 3m1
  428. %foldclose
  429. call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
  430. call assert_equal(0, foldlevel(2))
  431. call assert_equal(5, foldclosedend(3))
  432. call assert_equal([-1, -1, 3, 3, 3, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
  433. 2,6m$
  434. %foldclose
  435. call assert_equal(5, foldclosedend(2))
  436. call assert_equal(0, foldlevel(6))
  437. call assert_equal(9, foldclosedend(7))
  438. call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
  439. %d
  440. " Ensure moving around the edges still works.
  441. call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
  442. set fdm=indent foldlevel=0
  443. set fdm=manual
  444. %foldopen
  445. 6m$
  446. " The first fold has been truncated to the 5'th line.
  447. " Second fold has been moved up because the moved line is now below it.
  448. call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 0])
  449. %delete
  450. set fdm=indent foldlevel=0
  451. call setline(1, [
  452. \ "a",
  453. \ "\ta",
  454. \ "\t\ta",
  455. \ "\t\ta",
  456. \ "\t\ta",
  457. \ "a",
  458. \ "a"])
  459. set fdm=manual
  460. %foldopen!
  461. 4,5m6
  462. call Check_foldlevels([0, 1, 2, 0, 0, 0, 0])
  463. %delete
  464. set fdm=indent
  465. call setline(1, [
  466. \ "\ta",
  467. \ "\t\ta",
  468. \ "\t\ta",
  469. \ "\t\ta",
  470. \ "\ta",
  471. \ "\t\ta",
  472. \ "\t\ta",
  473. \ "\t\ta",
  474. \ "\ta",
  475. \ "\t\ta",
  476. \ "\t\ta",
  477. \ "\t\ta",
  478. \ "\t\ta",
  479. \ "\ta",
  480. \ "a"])
  481. set fdm=manual
  482. %foldopen!
  483. 13m7
  484. call Check_foldlevels([1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0])
  485. bw!
  486. endfunc
  487. func Test_move_folds_around_indent()
  488. new
  489. let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
  490. call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
  491. let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
  492. " all folds closed
  493. set fdm=indent
  494. call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
  495. call assert_equal(input, getline(1, '$'))
  496. 7,12m0
  497. call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
  498. call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
  499. 10,12m0
  500. call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$'))
  501. call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
  502. " moving should not close the folds
  503. %d
  504. call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
  505. set fdm=indent
  506. call cursor(2, 1)
  507. %foldopen
  508. 7,12m0
  509. let folds=repeat([-1], 18)
  510. call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
  511. call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
  512. norm! zM
  513. " folds are not corrupted and all have been closed
  514. call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
  515. %d
  516. call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
  517. set fdm=indent
  518. %foldopen
  519. 3m4
  520. %foldclose
  521. call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
  522. call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
  523. %d
  524. call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
  525. set fdm=indent foldlevel=0
  526. %foldopen
  527. 3m1
  528. %foldclose
  529. call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
  530. call assert_equal(1, foldlevel(2))
  531. call assert_equal(5, foldclosedend(3))
  532. call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
  533. 2,6m$
  534. %foldclose
  535. call assert_equal(9, foldclosedend(2))
  536. call assert_equal(1, foldlevel(6))
  537. call assert_equal(9, foldclosedend(7))
  538. call assert_equal([-1, 2, 2, 2, 2, 2, 2, 2, 2, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
  539. " Ensure moving around the edges still works.
  540. %d
  541. call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
  542. set fdm=indent foldlevel=0
  543. %foldopen
  544. 6m$
  545. " The first fold has been truncated to the 5'th line.
  546. " Second fold has been moved up because the moved line is now below it.
  547. call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 1])
  548. bw!
  549. endfunc
  550. func Test_folddoopen_folddoclosed()
  551. new
  552. call setline(1, range(1, 9))
  553. set foldmethod=manual
  554. 1,3 fold
  555. 6,8 fold
  556. " Test without range.
  557. folddoopen s/$/o/
  558. folddoclosed s/$/c/
  559. call assert_equal(['1c', '2c', '3c',
  560. \ '4o', '5o',
  561. \ '6c', '7c', '8c',
  562. \ '9o'], getline(1, '$'))
  563. " Test with range.
  564. call setline(1, range(1, 9))
  565. 1,8 folddoopen s/$/o/
  566. 4,$ folddoclosed s/$/c/
  567. call assert_equal(['1', '2', '3',
  568. \ '4o', '5o',
  569. \ '6c', '7c', '8c',
  570. \ '9'], getline(1, '$'))
  571. set foldmethod&
  572. bw!
  573. endfunc
  574. func Test_fold_error()
  575. new
  576. call setline(1, [1, 2])
  577. for fm in ['indent', 'expr', 'syntax', 'diff']
  578. exe 'set foldmethod=' . fm
  579. call assert_fails('norm zf', 'E350:')
  580. call assert_fails('norm zd', 'E351:')
  581. call assert_fails('norm zE', 'E352:')
  582. endfor
  583. set foldmethod=manual
  584. call assert_fails('norm zd', 'E490:')
  585. call assert_fails('norm zo', 'E490:')
  586. call assert_fails('3fold', 'E16:')
  587. set foldmethod=marker
  588. set nomodifiable
  589. call assert_fails('1,2fold', 'E21:')
  590. set modifiable&
  591. set foldmethod&
  592. bw!
  593. endfunc
  594. func Test_foldtext_recursive()
  595. new
  596. call setline(1, ['{{{', 'some text', '}}}'])
  597. setlocal foldenable foldmethod=marker foldtext=foldtextresult(v\:foldstart)
  598. " This was crashing because of endless recursion.
  599. 2foldclose
  600. redraw
  601. call assert_equal(1, foldlevel(2))
  602. call assert_equal(1, foldclosed(2))
  603. call assert_equal(3, foldclosedend(2))
  604. bwipe!
  605. endfunc
  606. " Various fold related tests
  607. " Basic test if a fold can be created, opened, moving to the end and closed
  608. func Test_fold_manual()
  609. new
  610. set fdm=manual
  611. let content = ['1 aa', '2 bb', '3 cc']
  612. call append(0, content)
  613. call cursor(1, 1)
  614. normal zf2j
  615. call assert_equal('1 aa', getline(foldclosed('.')))
  616. normal zo
  617. call assert_equal(-1, foldclosed('.'))
  618. normal ]z
  619. call assert_equal('3 cc', getline('.'))
  620. normal zc
  621. call assert_equal('1 aa', getline(foldclosed('.')))
  622. " Create a fold inside a closed fold after setting 'foldlevel'
  623. %d _
  624. call setline(1, range(1, 5))
  625. 1,5fold
  626. normal zR
  627. 2,4fold
  628. set foldlevel=1
  629. 3fold
  630. call assert_equal([1, 3, 3, 3, 1], map(range(1, 5), {->foldlevel(v:val)}))
  631. set foldlevel&
  632. " Create overlapping folds (at the start and at the end)
  633. normal zE
  634. 2,3fold
  635. normal zR
  636. 3,4fold
  637. call assert_equal([0, 2, 2, 1, 0], map(range(1, 5), {->foldlevel(v:val)}))
  638. normal zE
  639. 3,4fold
  640. normal zR
  641. 2,3fold
  642. call assert_equal([0, 1, 2, 2, 0], map(range(1, 5), {->foldlevel(v:val)}))
  643. " Create a nested fold across two non-adjoining folds
  644. %d _
  645. call setline(1, range(1, 7))
  646. 1,2fold
  647. normal zR
  648. 4,5fold
  649. normal zR
  650. 6,7fold
  651. normal zR
  652. 1,5fold
  653. call assert_equal([2, 2, 1, 2, 2, 1, 1],
  654. \ map(range(1, 7), {->foldlevel(v:val)}))
  655. " A newly created nested fold should be closed
  656. %d _
  657. call setline(1, range(1, 6))
  658. 1,6fold
  659. normal zR
  660. 3,4fold
  661. normal zR
  662. 2,5fold
  663. call assert_equal([1, 2, 3, 3, 2, 1], map(range(1, 6), {->foldlevel(v:val)}))
  664. call assert_equal(2, foldclosed(4))
  665. call assert_equal(5, foldclosedend(4))
  666. " Test zO, zC and zA on a line with no folds.
  667. normal zE
  668. call assert_fails('normal zO', 'E490:')
  669. call assert_fails('normal zC', 'E490:')
  670. call assert_fails('normal zA', 'E490:')
  671. set fdm&
  672. bw!
  673. endfunc
  674. " test folding with markers.
  675. func Test_fold_marker()
  676. new
  677. set fdm=marker fdl=1 fdc=3
  678. let content = ['4 dd {{{', '5 ee {{{ }}}', '6 ff }}}']
  679. call append(0, content)
  680. call cursor(2, 1)
  681. call assert_equal(2, foldlevel('.'))
  682. normal [z
  683. call assert_equal(1, foldlevel('.'))
  684. exe "normal jo{{ \<Esc>r{jj"
  685. call assert_equal(1, foldlevel('.'))
  686. normal kYpj
  687. call assert_equal(0, foldlevel('.'))
  688. " Use only closing fold marker (without and with a count)
  689. set fdl&
  690. %d _
  691. call setline(1, ['one }}}', 'two'])
  692. call assert_equal([0, 0], [foldlevel(1), foldlevel(2)])
  693. %d _
  694. call setline(1, ['one }}}4', 'two'])
  695. call assert_equal([4, 3], [foldlevel(1), foldlevel(2)])
  696. set fdm& fdl& fdc&
  697. bw!
  698. endfunc
  699. " test create fold markers with C filetype
  700. func Test_fold_create_marker_in_C()
  701. bw!
  702. set fdm=marker fdl=9
  703. set filetype=c
  704. let content =<< trim [CODE]
  705. /*
  706. * comment
  707. *
  708. *
  709. */
  710. int f(int* p) {
  711. *p = 3;
  712. return 0;
  713. }
  714. [CODE]
  715. for c in range(len(content) - 1)
  716. bw!
  717. call append(0, content)
  718. call cursor(c + 1, 1)
  719. norm! zfG
  720. call assert_equal(content[c] . (c < 4 ? '{{{' : '/* {{{ */'), getline(c + 1))
  721. endfor
  722. set fdm& fdl&
  723. bw!
  724. endfunc
  725. " test folding with indent
  726. func Test_fold_indent()
  727. new
  728. set fdm=indent sw=2
  729. let content = ['1 aa', '2 bb', '3 cc']
  730. call append(0, content)
  731. call cursor(2, 1)
  732. exe "normal i \<Esc>jI "
  733. call assert_equal(2, foldlevel('.'))
  734. normal k
  735. call assert_equal(1, foldlevel('.'))
  736. set fdm& sw&
  737. bw!
  738. endfunc
  739. " test syntax folding
  740. func Test_fold_syntax()
  741. CheckFeature syntax
  742. new
  743. set fdm=syntax fdl=0
  744. syn region Hup start="dd" end="ii" fold contains=Fd1,Fd2,Fd3
  745. syn region Fd1 start="ee" end="ff" fold contained
  746. syn region Fd2 start="gg" end="hh" fold contained
  747. syn region Fd3 start="commentstart" end="commentend" fold contained
  748. let content = ['3 cc', '4 dd {{{', '5 ee {{{ }}}', '{{{{', '6 ff }}}',
  749. \ '6 ff }}}', '7 gg', '8 hh', '9 ii']
  750. call append(0, content)
  751. normal Gzk
  752. call assert_equal('9 ii', getline('.'))
  753. normal k
  754. call assert_equal('3 cc', getline('.'))
  755. exe "normal jAcommentstart \<Esc>Acommentend"
  756. set fdl=1
  757. normal 3j
  758. call assert_equal('7 gg', getline('.'))
  759. set fdl=0
  760. exe "normal zO\<C-L>j"
  761. call assert_equal('8 hh', getline('.'))
  762. syn clear Fd1 Fd2 Fd3 Hup
  763. set fdm& fdl&
  764. bw!
  765. endfunc
  766. func Flvl()
  767. let l = getline(v:lnum)
  768. if l =~ "bb$"
  769. return 2
  770. elseif l =~ "gg$"
  771. return "s1"
  772. elseif l =~ "ii$"
  773. return ">2"
  774. elseif l =~ "kk$"
  775. return "0"
  776. endif
  777. return "="
  778. endfun
  779. " test expression folding
  780. func Test_fold_expr()
  781. new
  782. set fdm=expr fde=Flvl()
  783. let content = ['1 aa',
  784. \ '2 bb',
  785. \ '3 cc',
  786. \ '4 dd {{{commentstart commentend',
  787. \ '5 ee {{{ }}}',
  788. \ '{{{',
  789. \ '6 ff }}}',
  790. \ '6 ff }}}',
  791. \ ' 7 gg',
  792. \ ' 8 hh',
  793. \ '9 ii',
  794. \ 'a jj',
  795. \ 'b kk']
  796. call append(0, content)
  797. call cursor(1, 1)
  798. exe "normal /bb$\<CR>"
  799. call assert_equal(2, foldlevel('.'))
  800. exe "normal /hh$\<CR>"
  801. call assert_equal(1, foldlevel('.'))
  802. exe "normal /ii$\<CR>"
  803. call assert_equal(2, foldlevel('.'))
  804. exe "normal /kk$\<CR>"
  805. call assert_equal(0, foldlevel('.'))
  806. set fdm& fde&
  807. bw!
  808. endfunc
  809. " Bug with fdm=indent and moving folds
  810. " Moving a fold a few times, messes up the folds below the moved fold.
  811. " Fixed by 7.4.700
  812. func Test_fold_move()
  813. new
  814. set fdm=indent sw=2 fdl=0
  815. let content = ['', '', 'Line1', ' Line2', ' Line3',
  816. \ 'Line4', ' Line5', ' Line6',
  817. \ 'Line7', ' Line8', ' Line9']
  818. call append(0, content)
  819. normal zM
  820. call cursor(4, 1)
  821. move 2
  822. move 1
  823. call assert_equal(7, foldclosed(7))
  824. call assert_equal(8, foldclosedend(7))
  825. call assert_equal(0, foldlevel(9))
  826. call assert_equal(10, foldclosed(10))
  827. call assert_equal(11, foldclosedend(10))
  828. call assert_equal('+-- 2 lines: Line2', foldtextresult(2))
  829. call assert_equal('+-- 2 lines: Line8', 10->foldtextresult())
  830. set fdm& sw& fdl&
  831. bw!
  832. endfunc
  833. " test for patch 7.3.637
  834. " Cannot catch the error caused by a foldopen when there is no fold.
  835. func Test_foldopen_exception()
  836. new
  837. let a = 'No error caught'
  838. try
  839. foldopen
  840. catch
  841. let a = matchstr(v:exception,'^[^ ]*')
  842. endtry
  843. call assert_equal('Vim(foldopen):E490:', a)
  844. let a = 'No error caught'
  845. try
  846. foobar
  847. catch
  848. let a = matchstr(v:exception,'^[^ ]*')
  849. endtry
  850. call assert_match('E492:', a)
  851. bw!
  852. endfunc
  853. func Test_fold_last_line_with_pagedown()
  854. new
  855. set fdm=manual
  856. let expect = '+-- 11 lines: 9---'
  857. let content = range(1,19)
  858. call append(0, content)
  859. normal dd9G
  860. normal zfG
  861. normal zt
  862. call assert_equal('9', getline(foldclosed('.')))
  863. call assert_equal('19', getline(foldclosedend('.')))
  864. call assert_equal(expect, ScreenLines(1, len(expect))[0])
  865. call feedkeys("\<C-F>", 'xt')
  866. call assert_equal(expect, ScreenLines(1, len(expect))[0])
  867. call feedkeys("\<C-F>", 'xt')
  868. call assert_equal(expect, ScreenLines(1, len(expect))[0])
  869. call feedkeys("\<C-B>\<C-F>\<C-F>", 'xt')
  870. call assert_equal(expect, ScreenLines(1, len(expect))[0])
  871. set fdm&
  872. bw!
  873. endfunc
  874. func Test_folds_with_rnu()
  875. CheckScreendump
  876. call writefile([
  877. \ 'set fdm=marker rnu foldcolumn=2',
  878. \ 'call setline(1, ["{{{1", "nline 1", "{{{1", "line 2"])',
  879. \ ], 'Xtest_folds_with_rnu')
  880. let buf = RunVimInTerminal('-S Xtest_folds_with_rnu', {})
  881. call VerifyScreenDump(buf, 'Test_folds_with_rnu_01', {})
  882. call term_sendkeys(buf, "j")
  883. call VerifyScreenDump(buf, 'Test_folds_with_rnu_02', {})
  884. " clean up
  885. call StopVimInTerminal(buf)
  886. call delete('Xtest_folds_with_rnu')
  887. endfunc
  888. func Test_folds_marker_in_comment2()
  889. new
  890. call setline(1, ['Lorem ipsum dolor sit', 'Lorem ipsum dolor sit', 'Lorem ipsum dolor sit'])
  891. setl fen fdm=marker
  892. setl commentstring=<!--%s-->
  893. setl comments=s:<!--,m:\ \ \ \ ,e:-->
  894. norm! zf2j
  895. setl nofen
  896. :1y
  897. call assert_equal(['Lorem ipsum dolor sit<!--{{{-->'], getreg(0,1,1))
  898. :+2y
  899. call assert_equal(['Lorem ipsum dolor sit<!--}}}-->'], getreg(0,1,1))
  900. set foldmethod&
  901. bwipe!
  902. endfunc
  903. func Test_fold_delete_with_marker()
  904. new
  905. call setline(1, ['func Func() {{{1', 'endfunc'])
  906. 1,2yank
  907. new
  908. set fdm=marker
  909. call setline(1, 'x')
  910. normal! Vp
  911. normal! zd
  912. call assert_equal(['func Func() ', 'endfunc'], getline(1, '$'))
  913. set fdm&
  914. bwipe!
  915. bwipe!
  916. endfunc
  917. func Test_fold_delete_with_marker_and_whichwrap()
  918. new
  919. let content1 = ['']
  920. let content2 = ['folded line 1 "{{{1', ' test', ' test2', ' test3', '', 'folded line 2 "{{{1', ' test', ' test2', ' test3']
  921. call setline(1, content1 + content2)
  922. set fdm=marker ww+=l
  923. normal! x
  924. call assert_equal(content2, getline(1, '$'))
  925. set fdm& ww&
  926. bwipe!
  927. endfunc
  928. func Test_fold_delete_first_line()
  929. new
  930. call setline(1, [
  931. \ '" x {{{1',
  932. \ '" a',
  933. \ '" aa',
  934. \ '" x {{{1',
  935. \ '" b',
  936. \ '" bb',
  937. \ '" x {{{1',
  938. \ '" c',
  939. \ '" cc',
  940. \ ])
  941. set foldmethod=marker
  942. 1
  943. normal dj
  944. call assert_equal([
  945. \ '" x {{{1',
  946. \ '" c',
  947. \ '" cc',
  948. \ ], getline(1,'$'))
  949. bwipe!
  950. set foldmethod&
  951. endfunc
  952. " Add a test for deleting the outer fold of a nested fold and promoting the
  953. " inner folds to one level up with already a fold at that level following the
  954. " nested fold.
  955. func Test_fold_delete_recursive_fold()
  956. new
  957. call setline(1, range(1, 7))
  958. 2,3fold
  959. normal zR
  960. 4,5fold
  961. normal zR
  962. 1,5fold
  963. normal zR
  964. 6,7fold
  965. normal zR
  966. normal 1Gzd
  967. normal 1Gzj
  968. call assert_equal(2, line('.'))
  969. normal zj
  970. call assert_equal(4, line('.'))
  971. normal zj
  972. call assert_equal(6, line('.'))
  973. bw!
  974. endfunc
  975. " Test for errors in 'foldexpr'
  976. func Test_fold_expr_error()
  977. new
  978. call setline(1, ['one', 'two', 'three'])
  979. " In a window with no folds, foldlevel() should return 0
  980. call assert_equal(0, foldlevel(1))
  981. " Return a list from the expression
  982. set foldexpr=[]
  983. set foldmethod=expr
  984. for i in range(3)
  985. call assert_equal(0, foldlevel(i))
  986. endfor
  987. " expression error
  988. set foldexpr=[{]
  989. set foldmethod=expr
  990. for i in range(3)
  991. call assert_equal(0, foldlevel(i))
  992. endfor
  993. set foldmethod& foldexpr&
  994. close!
  995. endfunc
  996. func Test_undo_fold_deletion()
  997. new
  998. set fdm=marker
  999. let lines =<< trim END
  1000. " {{{
  1001. " }}}1
  1002. " {{{
  1003. END
  1004. call setline(1, lines)
  1005. 3d
  1006. g/"/d
  1007. undo
  1008. redo
  1009. eval getline(1, '$')->assert_equal([''])
  1010. set fdm&vim
  1011. bwipe!
  1012. endfunc
  1013. " this was crashing
  1014. func Test_move_no_folds()
  1015. new
  1016. fold
  1017. setlocal fdm=expr
  1018. normal zj
  1019. bwipe!
  1020. endfunc
  1021. " this was crashing
  1022. func Test_fold_create_delete_create()
  1023. new
  1024. fold
  1025. fold
  1026. normal zd
  1027. fold
  1028. bwipe!
  1029. endfunc
  1030. " this was crashing
  1031. func Test_fold_create_delete()
  1032. new
  1033. norm zFzFzdzj
  1034. bwipe!
  1035. endfunc
  1036. func Test_fold_relative_move()
  1037. new
  1038. set fdm=indent sw=2 wrap tw=80
  1039. let longtext = repeat('x', &columns + 1)
  1040. let content = [ ' foo', ' ' .. longtext, ' baz',
  1041. \ longtext,
  1042. \ ' foo', ' ' .. longtext, ' baz'
  1043. \ ]
  1044. call append(0, content)
  1045. normal zM
  1046. for lnum in range(1, 3)
  1047. call cursor(lnum, 1)
  1048. call assert_true(foldclosed(line('.')))
  1049. normal gj
  1050. call assert_equal(2, winline())
  1051. endfor
  1052. call cursor(2, 1)
  1053. call assert_true(foldclosed(line('.')))
  1054. normal 2gj
  1055. call assert_equal(3, winline())
  1056. for lnum in range(5, 7)
  1057. call cursor(lnum, 1)
  1058. call assert_true(foldclosed(line('.')))
  1059. normal gk
  1060. call assert_equal(3, winline())
  1061. endfor
  1062. call cursor(6, 1)
  1063. call assert_true(foldclosed(line('.')))
  1064. normal 2gk
  1065. call assert_equal(2, winline())
  1066. set fdm& sw& wrap& tw&
  1067. bw!
  1068. endfunc
  1069. " Test for calling foldlevel() from a fold expression
  1070. let g:FoldLevels = []
  1071. func FoldExpr1(lnum)
  1072. let f = [a:lnum]
  1073. for i in range(1, line('$'))
  1074. call add(f, foldlevel(i))
  1075. endfor
  1076. call add(g:FoldLevels, f)
  1077. return getline(a:lnum)[0] == "\t"
  1078. endfunc
  1079. func Test_foldexpr_foldlevel()
  1080. new
  1081. call setline(1, ['one', "\ttwo", "\tthree"])
  1082. setlocal foldmethod=expr
  1083. setlocal foldexpr=FoldExpr1(v:lnum)
  1084. setlocal foldenable
  1085. setlocal foldcolumn=3
  1086. redraw!
  1087. call assert_equal([[1, -1, -1, -1], [2, -1, -1, -1], [3, 0, 1, -1]],
  1088. \ g:FoldLevels)
  1089. set foldmethod& foldexpr& foldenable& foldcolumn&
  1090. bw!
  1091. endfunc
  1092. " Test for returning different values from a fold expression
  1093. func FoldExpr2(lnum)
  1094. if a:lnum == 1 || a:lnum == 4
  1095. return -2
  1096. elseif a:lnum == 2
  1097. return 'a1'
  1098. elseif a:lnum == 3
  1099. return 's4'
  1100. endif
  1101. return '='
  1102. endfunc
  1103. func Test_foldexpr_2()
  1104. new
  1105. call setline(1, ['one', 'two', 'three', 'four'])
  1106. setlocal foldexpr=FoldExpr2(v:lnum)
  1107. setlocal foldmethod=expr
  1108. call assert_equal([0, 1, 1, 0], [foldlevel(1), foldlevel(2), foldlevel(3),
  1109. \ foldlevel(4)])
  1110. bw!
  1111. endfunc
  1112. " Test for the 'foldclose' option
  1113. func Test_foldclose_opt()
  1114. CheckScreendump
  1115. let lines =<< trim END
  1116. set foldmethod=manual foldclose=all foldopen=all
  1117. call setline(1, ['one', 'two', 'three', 'four'])
  1118. 2,3fold
  1119. func XsaveFoldLevels()
  1120. redraw!
  1121. call writefile([json_encode([foldclosed(1), foldclosed(2), foldclosed(3),
  1122. \ foldclosed(4)])], 'Xoutput', 'a')
  1123. endfunc
  1124. END
  1125. call writefile(lines, 'Xscript')
  1126. let rows = 10
  1127. let buf = RunVimInTerminal('-S Xscript', {'rows': rows})
  1128. call term_wait(buf)
  1129. call term_sendkeys(buf, ":set noruler\n")
  1130. call term_wait(buf)
  1131. call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
  1132. call term_sendkeys(buf, "2G")
  1133. call WaitForAssert({-> assert_equal('two', term_getline(buf, 2))})
  1134. call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
  1135. call term_sendkeys(buf, "4G")
  1136. call WaitForAssert({-> assert_equal('four', term_getline(buf, 3))})
  1137. call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
  1138. call term_sendkeys(buf, "3G")
  1139. call WaitForAssert({-> assert_equal('three', term_getline(buf, 3))})
  1140. call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
  1141. call term_sendkeys(buf, "1G")
  1142. call WaitForAssert({-> assert_equal('four', term_getline(buf, 3))})
  1143. call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
  1144. call term_sendkeys(buf, "2G")
  1145. call WaitForAssert({-> assert_equal('two', term_getline(buf, 2))})
  1146. call term_sendkeys(buf, "k")
  1147. call WaitForAssert({-> assert_equal('four', term_getline(buf, 3))})
  1148. " clean up
  1149. call StopVimInTerminal(buf)
  1150. call assert_equal(['[-1,2,2,-1]', '[-1,-1,-1,-1]', '[-1,2,2,-1]',
  1151. \ '[-1,-1,-1,-1]', '[-1,2,2,-1]'], readfile('Xoutput'))
  1152. call delete('Xscript')
  1153. call delete('Xoutput')
  1154. endfunc
  1155. " Test for foldtextresult()
  1156. func Test_foldtextresult()
  1157. new
  1158. call assert_equal('', foldtextresult(-1))
  1159. call assert_equal('', foldtextresult(0))
  1160. call assert_equal('', foldtextresult(1))
  1161. call setline(1, ['one', 'two', 'three', 'four'])
  1162. 2,3fold
  1163. call assert_equal('', foldtextresult(1))
  1164. call assert_equal('+-- 2 lines: two', foldtextresult(2))
  1165. setlocal foldtext=
  1166. call assert_equal('+-- 2 lines folded ', foldtextresult(2))
  1167. " Fold text for a C comment fold
  1168. %d _
  1169. setlocal foldtext&
  1170. call setline(1, ['', '/*', ' * Comment', ' */', ''])
  1171. 2,4fold
  1172. call assert_equal('+-- 3 lines: Comment', foldtextresult(2))
  1173. bw!
  1174. endfunc
  1175. " Test for merging two recursive folds when an intermediate line with no fold
  1176. " is removed
  1177. func Test_fold_merge_recursive()
  1178. new
  1179. call setline(1, [' one', ' two', 'xxxx', ' three',
  1180. \ ' four', "\tfive"])
  1181. setlocal foldmethod=indent shiftwidth=2
  1182. 3d_
  1183. %foldclose
  1184. call assert_equal([1, 5], [foldclosed(5), foldclosedend(1)])
  1185. bw!
  1186. endfunc
  1187. " Test for moving a line which is the start of a fold from a recursive fold to
  1188. " outside. The fold length should reduce.
  1189. func Test_fold_move_foldlevel()
  1190. new
  1191. call setline(1, ['a{{{', 'b{{{', 'c{{{', 'd}}}', 'e}}}', 'f}}}', 'g'])
  1192. setlocal foldmethod=marker
  1193. normal zR
  1194. call assert_equal([3, 2, 1], [foldlevel(4), foldlevel(5), foldlevel(6)])
  1195. 3move 7
  1196. call assert_equal([2, 1, 0], [foldlevel(3), foldlevel(4), foldlevel(5)])
  1197. call assert_equal(1, foldlevel(7))
  1198. " Move a line from outside a fold to inside the fold.
  1199. %d _
  1200. call setline(1, ['a', 'b{{{', 'c}}}'])
  1201. normal zR
  1202. 1move 2
  1203. call assert_equal([1, 1, 1], [foldlevel(1), foldlevel(2), foldlevel(3)])
  1204. " Move the start of one fold to inside another fold
  1205. %d _
  1206. call setline(1, ['a', 'b{{{', 'c}}}', 'd{{{', 'e}}}'])
  1207. normal zR
  1208. call assert_equal([0, 1, 1, 1, 1], [foldlevel(1), foldlevel(2),
  1209. \ foldlevel(3), foldlevel(4), foldlevel(5)])
  1210. 1,2move 4
  1211. call assert_equal([0, 1, 1, 2, 2], [foldlevel(1), foldlevel(2),
  1212. \ foldlevel(3), foldlevel(4), foldlevel(5)])
  1213. bw!
  1214. endfunc
  1215. " Test for using zj and zk to move downwards and upwards to the start and end
  1216. " of the next fold.
  1217. " Test for using [z and ]z in a closed fold to jump to the beginning and end
  1218. " of the fold.
  1219. func Test_fold_jump()
  1220. new
  1221. call setline(1, ["\t1", "\t2", "\t\t3", "\t\t4", "\t\t\t5", "\t\t\t6", "\t\t7", "\t\t8", "\t9", "\t10"])
  1222. setlocal foldmethod=indent
  1223. normal zR
  1224. normal zj
  1225. call assert_equal(3, line('.'))
  1226. normal zj
  1227. call assert_equal(5, line('.'))
  1228. call assert_beeps('normal zj')
  1229. call assert_equal(5, line('.'))
  1230. call assert_beeps('normal 9Gzj')
  1231. call assert_equal(9, line('.'))
  1232. normal Gzk
  1233. call assert_equal(8, line('.'))
  1234. normal zk
  1235. call assert_equal(6, line('.'))
  1236. call assert_beeps('normal zk')
  1237. call assert_equal(6, line('.'))
  1238. call assert_beeps('normal 2Gzk')
  1239. call assert_equal(2, line('.'))
  1240. " Using [z or ]z in a closed fold should not move the cursor
  1241. %d _
  1242. call setline(1, ["1", "\t2", "\t3", "\t4", "\t5", "\t6", "7"])
  1243. normal zR4Gzc
  1244. call assert_equal(4, line('.'))
  1245. call assert_beeps('normal [z')
  1246. call assert_equal(4, line('.'))
  1247. call assert_beeps('normal ]z')
  1248. call assert_equal(4, line('.'))
  1249. bw!
  1250. endfunc
  1251. " Test for using a script-local function for 'foldexpr'
  1252. func Test_foldexpr_scriptlocal_func()
  1253. func! s:FoldFunc()
  1254. let g:FoldLnum = v:lnum
  1255. endfunc
  1256. new | only
  1257. call setline(1, 'abc')
  1258. let g:FoldLnum = 0
  1259. set foldmethod=expr foldexpr=s:FoldFunc()
  1260. redraw!
  1261. call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
  1262. call assert_equal(expand('<SID>') .. 'FoldFunc()', &g:foldexpr)
  1263. call assert_equal(1, g:FoldLnum)
  1264. set foldmethod& foldexpr=
  1265. bw!
  1266. new | only
  1267. call setline(1, 'abc')
  1268. let g:FoldLnum = 0
  1269. set foldmethod=expr foldexpr=<SID>FoldFunc()
  1270. redraw!
  1271. call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
  1272. call assert_equal(expand('<SID>') .. 'FoldFunc()', &g:foldexpr)
  1273. call assert_equal(1, g:FoldLnum)
  1274. bw!
  1275. call setline(1, 'abc')
  1276. setlocal foldmethod& foldexpr&
  1277. setglobal foldmethod=expr foldexpr=s:FoldFunc()
  1278. call assert_equal(expand('<SID>') .. 'FoldFunc()', &g:foldexpr)
  1279. call assert_equal('0', &foldexpr)
  1280. enew!
  1281. call setline(1, 'abc')
  1282. redraw!
  1283. call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
  1284. call assert_equal(1, g:FoldLnum)
  1285. bw!
  1286. call setline(1, 'abc')
  1287. setlocal foldmethod& foldexpr&
  1288. setglobal foldmethod=expr foldexpr=<SID>FoldFunc()
  1289. call assert_equal(expand('<SID>') .. 'FoldFunc()', &g:foldexpr)
  1290. call assert_equal('0', &foldexpr)
  1291. enew!
  1292. call setline(1, 'abc')
  1293. redraw!
  1294. call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
  1295. call assert_equal(1, g:FoldLnum)
  1296. set foldmethod& foldexpr&
  1297. delfunc s:FoldFunc
  1298. bw!
  1299. endfunc
  1300. " Test for using a script-local function for 'foldtext'
  1301. func Test_foldtext_scriptlocal_func()
  1302. func! s:FoldText()
  1303. let g:FoldTextArgs = [v:foldstart, v:foldend]
  1304. return foldtext()
  1305. endfunc
  1306. new | only
  1307. call setline(1, range(50))
  1308. let g:FoldTextArgs = []
  1309. set foldtext=s:FoldText()
  1310. norm! 4Gzf4j
  1311. redraw!
  1312. call assert_equal(expand('<SID>') .. 'FoldText()', &foldtext)
  1313. call assert_equal(expand('<SID>') .. 'FoldText()', &g:foldtext)
  1314. call assert_equal([4, 8], g:FoldTextArgs)
  1315. set foldtext&
  1316. bw!
  1317. new | only
  1318. call setline(1, range(50))
  1319. let g:FoldTextArgs = []
  1320. set foldtext=<SID>FoldText()
  1321. norm! 8Gzf4j
  1322. redraw!
  1323. call assert_equal(expand('<SID>') .. 'FoldText()', &foldtext)
  1324. call assert_equal(expand('<SID>') .. 'FoldText()', &g:foldtext)
  1325. call assert_equal([8, 12], g:FoldTextArgs)
  1326. set foldtext&
  1327. bw!
  1328. call setline(1, range(50))
  1329. let g:FoldTextArgs = []
  1330. setlocal foldtext&
  1331. setglobal foldtext=s:FoldText()
  1332. call assert_equal(expand('<SID>') .. 'FoldText()', &g:foldtext)
  1333. call assert_equal('foldtext()', &foldtext)
  1334. enew!
  1335. call setline(1, range(50))
  1336. norm! 12Gzf4j
  1337. redraw!
  1338. call assert_equal(expand('<SID>') .. 'FoldText()', &foldtext)
  1339. call assert_equal([12, 16], g:FoldTextArgs)
  1340. set foldtext&
  1341. bw!
  1342. call setline(1, range(50))
  1343. let g:FoldTextArgs = []
  1344. setlocal foldtext&
  1345. setglobal foldtext=<SID>FoldText()
  1346. call assert_equal(expand('<SID>') .. 'FoldText()', &g:foldtext)
  1347. call assert_equal('foldtext()', &foldtext)
  1348. enew!
  1349. call setline(1, range(50))
  1350. norm! 16Gzf4j
  1351. redraw!
  1352. call assert_equal(expand('<SID>') .. 'FoldText()', &foldtext)
  1353. call assert_equal([16, 20], g:FoldTextArgs)
  1354. set foldtext&
  1355. bw!
  1356. delfunc s:FoldText
  1357. endfunc
  1358. " Test for setting 'foldtext' from the modeline and executing the expression
  1359. " in a sandbox
  1360. func Test_foldtext_in_modeline()
  1361. func ModelineFoldText()
  1362. call feedkeys('aFoo', 'xt')
  1363. return "folded text"
  1364. endfunc
  1365. let lines =<< trim END
  1366. func T()
  1367. let i = 1
  1368. endfunc
  1369. " vim: foldenable foldtext=ModelineFoldText()
  1370. END
  1371. call writefile(lines, 'Xmodelinefoldtext', 'D')
  1372. set modeline modelineexpr
  1373. split Xmodelinefoldtext
  1374. call cursor(1, 1)
  1375. normal! zf3j
  1376. call assert_equal('folded text', foldtextresult(1))
  1377. call assert_equal(lines, getbufline('', 1, '$'))
  1378. bw!
  1379. set modeline& modelineexpr&
  1380. delfunc ModelineFoldText
  1381. endfunc
  1382. " Test for setting 'foldexpr' from the modeline and executing the expression
  1383. " in a sandbox
  1384. func Test_foldexpr_in_modeline()
  1385. func ModelineFoldExpr()
  1386. call feedkeys('aFoo', 'xt')
  1387. return strlen(matchstr(getline(v:lnum),'^\s*'))
  1388. endfunc
  1389. let lines =<< trim END
  1390. aaa
  1391. bbb
  1392. ccc
  1393. ccc
  1394. bbb
  1395. aaa
  1396. " vim: foldenable foldmethod=expr foldexpr=ModelineFoldExpr()
  1397. END
  1398. call writefile(lines, 'Xmodelinefoldexpr', 'D')
  1399. set modeline modelineexpr
  1400. split Xmodelinefoldexpr
  1401. call assert_equal(2, foldlevel(3))
  1402. call assert_equal(lines, getbufline('', 1, '$'))
  1403. bw!
  1404. set modeline& modelineexpr&
  1405. delfunc ModelineFoldExpr
  1406. endfunc
  1407. " Make sure a fold containing a nested fold is split correctly when using
  1408. " foldmethod=indent
  1409. func Test_fold_split()
  1410. new
  1411. let lines =<< trim END
  1412. line 1
  1413. line 2
  1414. line 3
  1415. line 4
  1416. line 5
  1417. END
  1418. call setline(1, lines)
  1419. setlocal sw=2
  1420. setlocal foldmethod=indent foldenable
  1421. call assert_equal([0, 1, 1, 2, 2], range(1, 5)->map('foldlevel(v:val)'))
  1422. call append(2, 'line 2.5')
  1423. call assert_equal([0, 1, 0, 1, 2, 2], range(1, 6)->map('foldlevel(v:val)'))
  1424. 3d
  1425. call assert_equal([0, 1, 1, 2, 2], range(1, 5)->map('foldlevel(v:val)'))
  1426. bw!
  1427. endfunc
  1428. " Make sure that when you append under a blank line that is under a fold with
  1429. " the same indent level as your appended line, the fold expands across the
  1430. " blank line
  1431. func Test_indent_append_under_blank_line()
  1432. new
  1433. let lines =<< trim END
  1434. line 1
  1435. line 2
  1436. line 3
  1437. END
  1438. call setline(1, lines)
  1439. setlocal sw=2
  1440. setlocal foldmethod=indent foldenable
  1441. call assert_equal([0, 1, 1], range(1, 3)->map('foldlevel(v:val)'))
  1442. call append(3, '')
  1443. call append(4, ' line 5')
  1444. call assert_equal([0, 1, 1, 1, 1], range(1, 5)->map('foldlevel(v:val)'))
  1445. bw!
  1446. endfunc
  1447. " Make sure that when you delete 1 line of a fold whose length is 2 lines, the
  1448. " fold can't be closed since its length (1) is now less than foldminlines.
  1449. func Test_indent_one_line_fold_close()
  1450. let lines =<< trim END
  1451. line 1
  1452. line 2
  1453. line 3
  1454. END
  1455. new
  1456. setlocal sw=2 foldmethod=indent
  1457. call setline(1, lines)
  1458. " open all folds, delete line, then close all folds
  1459. normal zR
  1460. 3delete
  1461. normal zM
  1462. call assert_equal(-1, foldclosed(2)) " the fold should not be closed
  1463. " Now do the same, but delete line 2 this time; this covers different code.
  1464. " (Combining this code with the above code doesn't expose both bugs.)
  1465. 1,$delete
  1466. call setline(1, lines)
  1467. normal zR
  1468. 2delete
  1469. normal zM
  1470. call assert_equal(-1, foldclosed(2))
  1471. bw!
  1472. endfunc
  1473. " Make sure that when appending [an indented line then a blank line] right
  1474. " before a single indented line, the resulting extended fold can be closed
  1475. func Test_indent_append_blank_small_fold_close()
  1476. new
  1477. setlocal sw=2 foldmethod=indent
  1478. " at first, the fold at the second line can't be closed since it's smaller
  1479. " than foldminlines
  1480. let lines =<< trim END
  1481. line 1
  1482. line 4
  1483. END
  1484. call setline(1, lines)
  1485. call append(1, [' line 2', ''])
  1486. " close all folds
  1487. normal zM
  1488. call assert_notequal(-1, foldclosed(2)) " the fold should be closed now
  1489. bw!
  1490. endfunc
  1491. func Test_sort_closed_fold()
  1492. CheckExecutable sort
  1493. call setline(1, [
  1494. \ 'Section 1',
  1495. \ ' how',
  1496. \ ' now',
  1497. \ ' brown',
  1498. \ ' cow',
  1499. \ 'Section 2',
  1500. \ ' how',
  1501. \ ' now',
  1502. \ ' brown',
  1503. \ ' cow',
  1504. \])
  1505. setlocal foldmethod=indent sw=3
  1506. normal 2G
  1507. " The "!!" expands to ".,.+3" and must only sort four lines
  1508. call feedkeys("!!sort\<CR>", 'xt')
  1509. call assert_equal([
  1510. \ 'Section 1',
  1511. \ ' brown',
  1512. \ ' cow',
  1513. \ ' how',
  1514. \ ' now',
  1515. \ 'Section 2',
  1516. \ ' how',
  1517. \ ' now',
  1518. \ ' brown',
  1519. \ ' cow',
  1520. \ ], getline(1, 10))
  1521. bwipe!
  1522. endfunc
  1523. func Test_indent_with_L_command()
  1524. " The "L" command moved the cursor to line zero, causing the text saved for
  1525. " undo to use line number -1, which caused trouble for undo later.
  1526. new
  1527. sil! norm 8R V{zf8=Lu
  1528. bwipe!
  1529. endfunc
  1530. " Make sure that when there is a fold at the bottom of the buffer and a newline
  1531. " character is appended to the line, the fold gets expanded (instead of the new
  1532. " line not being part of the fold).
  1533. func Test_expand_fold_at_bottom_of_buffer()
  1534. new
  1535. " create a fold on the only line
  1536. fold
  1537. execute "normal A\<CR>"
  1538. call assert_equal([1, 1], range(1, 2)->map('foldlevel(v:val)'))
  1539. bwipe!
  1540. endfunc
  1541. func Test_fold_screenrow_motion()
  1542. call setline(1, repeat(['aaaa'], 5))
  1543. 1,4fold
  1544. norm Ggkzo
  1545. call assert_equal(1, line('.'))
  1546. endfunc
  1547. " This was using freed memory
  1548. func Test_foldcolumn_linebreak_control_char()
  1549. CheckFeature linebreak
  1550. 5vnew
  1551. setlocal foldcolumn=1 linebreak
  1552. call setline(1, "aaa\<C-A>b")
  1553. redraw
  1554. call assert_equal([' aaa^', ' Ab '], ScreenLines([1, 2], 5))
  1555. call assert_equal(screenattr(1, 5), screenattr(2, 2))
  1556. bwipe!
  1557. endfunc
  1558. " This used to cause invalid memory access
  1559. func Test_foldexpr_return_empty_string()
  1560. new
  1561. setlocal foldexpr='' foldmethod=expr
  1562. redraw
  1563. bwipe!
  1564. endfunc
  1565. " Make sure that when ending a fold that hasn't been started, it does not
  1566. " start a new fold.
  1567. func Test_foldexpr_end_fold()
  1568. new
  1569. setlocal foldmethod=expr
  1570. let &l:foldexpr = 'v:lnum == 2 ? "<2" : "="'
  1571. call setline(1, range(1, 3))
  1572. redraw
  1573. call assert_equal([0, 0, 0], range(1, 3)->map('foldlevel(v:val)'))
  1574. bwipe!
  1575. endfunc
  1576. " Test moving cursor down to or beyond start of folded end of buffer.
  1577. func Test_cursor_down_fold_eob()
  1578. call setline(1, range(1, 4))
  1579. norm Gzf2kj
  1580. call assert_equal(2, line('.'))
  1581. norm zojzc
  1582. call assert_equal(3, line('.'))
  1583. norm j
  1584. call assert_equal(3, line('.'))
  1585. norm k2j
  1586. call assert_equal(4, line('.'))
  1587. bwipe!
  1588. endfunc
  1589. " issue: #15455
  1590. func Test_cursor_fold_marker_undo()
  1591. new
  1592. call setline(1, ['{{{', '', 'This is a Line', '', 'This is a Line', '', '}}}'])
  1593. let &ul=&ul
  1594. setl foldmethod=marker
  1595. call cursor(2, 1)
  1596. norm! zo1vjdu
  1597. call assert_equal(1, foldlevel('.'))
  1598. bwipe!
  1599. new
  1600. call setline(1, ['', '{{{', '', 'This is a Line', '', 'This is a Line', '', '}}}'])
  1601. let &ul=&ul
  1602. setl foldmethod=marker
  1603. call cursor(3, 1)
  1604. norm! zo
  1605. norm! vjdu
  1606. call assert_equal(1, foldlevel('.'))
  1607. bwipe!
  1608. endfunc
  1609. " vim: shiftwidth=2 sts=2 expandtab