123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524 |
- local t = require('test.testutil')
- local n = require('test.functional.testnvim')()
- local clear = n.clear
- local insert = n.insert
- local exec = n.exec
- local feed = n.feed
- local expect = n.expect
- local command = n.command
- local fn = n.fn
- local eq = t.eq
- local neq = t.neq
- describe('Folding', function()
- local tempfname = 'Xtest-fold.txt'
- setup(clear)
- before_each(function()
- command('bwipe! | new')
- end)
- after_each(function()
- os.remove(tempfname)
- end)
- it('manual folding adjusts with filter', function()
- insert([[
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20]])
- command('4,$fold')
- command('%foldopen')
- command('10,$fold')
- command('%foldopen')
- command('1,8! cat')
- feed('5ggzdzMGdd')
- expect([[
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9]])
- end)
- describe('adjusting folds after :move', function()
- local function manually_fold_indent()
- -- setting foldmethod twice is a trick to get vim to set the folds for me
- command('setlocal foldmethod=indent')
- command('setlocal foldmethod=manual')
- -- Ensure that all folds will get closed (makes it easier to test the
- -- length of folds).
- command('setlocal foldminlines=0')
- -- Start with all folds open (so :move ranges aren't affected by closed
- -- folds).
- command('%foldopen!')
- end
- local function get_folds()
- local rettab = {}
- for i = 1, fn.line('$') do
- table.insert(rettab, fn.foldlevel(i))
- end
- return rettab
- end
- local function test_move_indent(insert_string, move_command)
- -- This test is easy because we just need to ensure that the resulting
- -- fold is the same as calculated when creating folds from scratch.
- insert(insert_string)
- command(move_command)
- local after_move_folds = get_folds()
- -- Doesn't change anything, but does call foldUpdateAll()
- command('setlocal foldminlines=0')
- eq(after_move_folds, get_folds())
- -- Set up the buffer with insert_string for the manual fold testing.
- command('enew!')
- insert(insert_string)
- manually_fold_indent()
- command(move_command)
- end
- it('neither closes nor corrupts folds', function()
- test_move_indent(
- [[
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a]],
- '7,12m0'
- )
- expect([[
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a]])
- -- lines are not closed, folds are correct
- for i = 1, fn.line('$') do
- eq(-1, fn.foldclosed(i))
- if i == 1 or i == 7 or i == 13 then
- eq(0, fn.foldlevel(i))
- elseif i == 4 then
- eq(2, fn.foldlevel(i))
- else
- eq(1, fn.foldlevel(i))
- end
- end
- -- folds are not corrupted
- feed('zM')
- eq(6, fn.foldclosedend(2))
- eq(12, fn.foldclosedend(8))
- eq(18, fn.foldclosedend(14))
- end)
- it("doesn't split a fold when the move is within it", function()
- test_move_indent(
- [[
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a]],
- '5m6'
- )
- eq({ 0, 1, 1, 2, 2, 2, 2, 1, 1, 0 }, get_folds())
- end)
- it('truncates folds that end in the moved range', function()
- test_move_indent(
- [[
- a
- a
- a
- a
- a
- a
- a]],
- '4,5m6'
- )
- eq({ 0, 1, 2, 0, 0, 0, 0 }, get_folds())
- end)
- it('moves folds that start between moved range and destination', function()
- test_move_indent(
- [[
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a]],
- '3,4m$'
- )
- eq({ 0, 1, 1, 0, 0, 1, 2, 1, 0, 0, 1, 0, 0 }, get_folds())
- end)
- it('does not affect folds outside changed lines', function()
- test_move_indent(
- [[
- a
- a
- a
- a
- a
- a
- a
- a
- a]],
- '4m5'
- )
- eq({ 1, 1, 1, 0, 0, 0, 1, 1, 1 }, get_folds())
- end)
- it('moves and truncates folds that start in moved range', function()
- test_move_indent(
- [[
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a]],
- '1,3m7'
- )
- eq({ 0, 0, 0, 0, 0, 1, 2, 0, 0, 0 }, get_folds())
- end)
- it('breaks a fold when moving text into it', function()
- test_move_indent(
- [[
- a
- a
- a
- a
- a
- a
- a]],
- '$m4'
- )
- eq({ 0, 1, 2, 2, 0, 0, 0 }, get_folds())
- end)
- it('adjusts correctly when moving a range backwards', function()
- test_move_indent(
- [[
- a
- a
- a
- a
- a]],
- '2,3m0'
- )
- eq({ 1, 2, 0, 0, 0 }, get_folds())
- end)
- it('handles shifting all remaining folds', function()
- test_move_indent(
- [[
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a]],
- '13m7'
- )
- eq({ 1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0 }, get_folds())
- end)
- end)
- it('updates correctly on :read', function()
- -- luacheck: ignore 621
- t.write_file(
- tempfname,
- [[
- a
- a]]
- )
- insert([[
- a
- a
- a
- a
- ]])
- command('setlocal foldmethod=indent')
- command('2')
- command('%foldopen')
- command('read ' .. tempfname)
- -- Just to check we have the correct file text.
- expect([[
- a
- a
- a
- a
- a
- a
- ]])
- for i = 1, 2 do
- eq(1, fn.foldlevel(i))
- end
- for i = 3, 5 do
- eq(0, fn.foldlevel(i))
- end
- for i = 6, 8 do
- eq(1, fn.foldlevel(i))
- end
- end)
- it('combines folds when removing separating space', function()
- -- luacheck: ignore 621
- insert([[
- a
- a
- a
- a
- a
- a
- a
- a
- ]])
- command('setlocal foldmethod=indent')
- command('3,5d')
- eq(5, fn.foldclosedend(1))
- end)
- it("doesn't combine folds that have a specified end", function()
- insert([[
- {{{
- }}}
- {{{
- }}}
- ]])
- command('setlocal foldmethod=marker')
- command('3,5d')
- command('%foldclose')
- eq(2, fn.foldclosedend(1))
- end)
- it('splits folds according to >N and <N with foldexpr', function()
- n.source([[
- function TestFoldExpr(lnum)
- let thisline = getline(a:lnum)
- if thisline == 'a'
- return 1
- elseif thisline == 'b'
- return 0
- elseif thisline == 'c'
- return '<1'
- elseif thisline == 'd'
- return '>1'
- endif
- return 0
- endfunction
- ]])
- t.write_file(
- tempfname,
- [[
- b
- b
- a
- a
- d
- a
- a
- c]]
- )
- insert([[
- a
- a
- a
- a
- a
- a
- ]])
- command('setlocal foldmethod=expr foldexpr=TestFoldExpr(v:lnum)')
- command('2')
- command('foldopen')
- command('read ' .. tempfname)
- command('%foldclose')
- eq(2, fn.foldclosedend(1))
- eq(0, fn.foldlevel(3))
- eq(0, fn.foldlevel(4))
- eq(6, fn.foldclosedend(5))
- eq(10, fn.foldclosedend(7))
- eq(14, fn.foldclosedend(11))
- end)
- it('fdm=expr works correctly with :move #18668', function()
- exec([[
- set foldmethod=expr foldexpr=indent(v:lnum)
- let content = ['', '', 'Line1', ' Line2', ' Line3',
- \ 'Line4', ' Line5', ' Line6',
- \ 'Line7', ' Line8', ' Line9']
- call append(0, content)
- normal! zM
- call cursor(4, 1)
- move 2
- move 1
- ]])
- expect([[
- Line2
- Line3
- Line1
- Line4
- Line5
- Line6
- Line7
- Line8
- Line9
- ]])
- eq(0, fn.foldlevel(1))
- eq(3, fn.foldclosedend(2))
- eq(0, fn.foldlevel(4))
- eq(0, fn.foldlevel(5))
- eq(0, fn.foldlevel(6))
- eq(8, fn.foldclosedend(7))
- eq(0, fn.foldlevel(9))
- eq(11, fn.foldclosedend(10))
- eq(0, fn.foldlevel(12))
- end)
- it('no folds remain if :delete makes buffer empty #19671', function()
- command('setlocal foldmethod=manual')
- fn.setline(1, { 'foo', 'bar', 'baz' })
- command('2,3fold')
- command('%delete')
- eq(0, fn.foldlevel(1))
- end)
- it('multibyte fold markers work #20438', function()
- command('setlocal foldmethod=marker foldmarker=«,» commentstring=/*%s*/')
- insert([[
- bbbbb
- bbbbb
- bbbbb]])
- feed('zfgg')
- expect([[
- bbbbb/*«*/
- bbbbb
- bbbbb/*»*/]])
- eq(1, fn.foldlevel(1))
- end)
- it('fdm=indent updates correctly with visual blockwise insertion #22898', function()
- insert([[
- a
- b
- ]])
- command('setlocal foldmethod=indent shiftwidth=2')
- feed('gg0<C-v>jI <Esc>') -- indent both lines using visual blockwise mode
- eq(1, fn.foldlevel(1))
- eq(1, fn.foldlevel(2))
- end)
- it("fdm=indent doesn't open folds when inserting lower foldlevel line", function()
- insert([[
- insert an unindented line under this line
- keep the lines under this line folded
- keep this line folded 1
- keep this line folded 2
- ]])
- command('set foldmethod=indent shiftwidth=2 noautoindent')
- eq(1, fn.foldlevel(1))
- eq(1, fn.foldlevel(2))
- eq(2, fn.foldlevel(3))
- eq(2, fn.foldlevel(4))
- feed('zo') -- open the outer fold
- neq(-1, fn.foldclosed(3)) -- make sure the inner fold is not open
- feed('gg0oa<Esc>') -- insert unindented line
- eq(1, fn.foldlevel(1)) --| insert an unindented line under this line
- eq(0, fn.foldlevel(2)) --|a
- eq(1, fn.foldlevel(3)) --| keep the lines under this line folded
- eq(2, fn.foldlevel(4)) --| keep this line folded 1
- eq(2, fn.foldlevel(5)) --| keep this line folded 2
- neq(-1, fn.foldclosed(4)) -- make sure the inner fold is still not open
- end)
- end)
|