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