0
0
mirror of https://github.com/vim/vim.git synced 2025-09-14 23:14:27 -04:00

patch 8.0.0408: updating folds does not always work properly

Problem:    Updating folds does not work properly when inserting a file and a
            few other situations.
Solution:   Adjust the way folds are updated. (Matthew Malcomson)
This commit is contained in:
Bram Moolenaar 2017-03-04 18:42:39 +01:00
parent 3f3897e41f
commit eadbc2b461
3 changed files with 142 additions and 10 deletions

View File

@ -2505,7 +2505,11 @@ foldUpdateIEMSRecurse(
* before where we started looking, extend it. If it
* starts at another line, update nested folds to keep
* their position, compensating for the new fd_top. */
if (fp->fd_top >= startlnum && fp->fd_top != firstlnum)
if (fp->fd_top == firstlnum)
{
/* have found a fold beginning where we want */
}
else if (fp->fd_top >= startlnum)
{
if (fp->fd_top > firstlnum)
/* like lines are inserted */
@ -2523,18 +2527,44 @@ foldUpdateIEMSRecurse(
fp->fd_top = firstlnum;
fold_changed = TRUE;
}
else if (flp->start != 0 && lvl == level
&& fp->fd_top != firstlnum)
else if ((flp->start != 0 && lvl == level)
|| firstlnum != startlnum)
{
/* Existing fold that includes startlnum must stop
* if we find the start of a new fold at the same
* level. Split it. Delete contained folds at
* this point to split them too. */
foldRemove(&fp->fd_nested, flp->lnum - fp->fd_top,
flp->lnum - fp->fd_top);
linenr_T breakstart;
linenr_T breakend;
/*
* Before there was a fold spanning from above
* startlnum to below firstlnum. This fold is valid
* above startlnum (because we are not updating
* that range), but there should now be a break in
* it.
* If the break is because we are now forced to
* start a new fold at the level "level" at line
* fline->lnum, then we need to split the fold at
* fline->lnum.
* If the break is because the range
* [startlnum, firstlnum) is now at a lower indent
* than "level", we need to split the fold in this
* range.
* Any splits have to be done recursively.
*/
if (firstlnum != startlnum)
{
breakstart = startlnum;
breakend = firstlnum;
}
else
{
breakstart = flp->lnum;
breakend = flp->lnum;
}
foldRemove(&fp->fd_nested, breakstart - fp->fd_top,
breakend - fp->fd_top);
i = (int)(fp - (fold_T *)gap->ga_data);
foldSplit(gap, i, flp->lnum, flp->lnum - 1);
foldSplit(gap, i, breakstart, breakend - 1);
fp = (fold_T *)gap->ga_data + i + 1;
/* If using the "marker" or "syntax" method, we
* need to continue until the end of the fold is
* found. */
@ -2543,6 +2573,20 @@ foldUpdateIEMSRecurse(
|| getlevel == foldlevelSyntax)
finish = TRUE;
}
if (fp->fd_top == startlnum && concat)
{
i = (int)(fp - (fold_T *)gap->ga_data);
if (i != 0)
{
fp2 = fp - 1;
if (fp2->fd_top + fp2->fd_len == fp->fd_top)
{
foldMerge(fp2, gap, fp);
fp = fp2;
}
}
}
break;
}
if (fp->fd_top >= startlnum)

View File

@ -117,3 +117,89 @@ func Test_manual_fold_with_filter()
set foldmethod&
endfor
endfunc
func! Test_indent_fold_with_read()
new
set foldmethod=indent
call setline(1, repeat(["\<Tab>a"], 4))
for n in range(1, 4)
call assert_equal(1, foldlevel(n))
endfor
call writefile(["a", "", "\<Tab>a"], 'Xfile')
foldopen
2read Xfile
%foldclose
call assert_equal(1, foldlevel(1))
call assert_equal(2, foldclosedend(1))
call assert_equal(0, foldlevel(3))
call assert_equal(0, foldlevel(4))
call assert_equal(1, foldlevel(5))
call assert_equal(7, foldclosedend(5))
bwipe!
set foldmethod&
call delete('Xfile')
endfunc
func Test_combining_folds_indent()
new
let one = "\<Tab>a"
let zero = 'a'
call setline(1, [one, one, zero, zero, zero, one, one, one])
set foldmethod=indent
3,5d
%foldclose
call assert_equal(5, foldclosedend(1))
set foldmethod&
bwipe!
endfunc
func Test_combining_folds_marker()
new
call setline(1, ['{{{', '}}}', '', '', '', '{{{', '', '}}}'])
set foldmethod=marker
3,5d
%foldclose
call assert_equal(2, foldclosedend(1))
set foldmethod&
bwipe!
endfunc
func s: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
func Test_update_folds_expr_read()
new
call setline(1, ['a', 'a', 'a', 'a', 'a', 'a'])
set foldmethod=expr
set foldexpr=s:TestFoldExpr(v:lnum)
2
foldopen
call writefile(['b', 'b', 'a', 'a', 'd', 'a', 'a', 'c'], 'Xfile')
read Xfile
%foldclose
call assert_equal(2, foldclosedend(1))
call assert_equal(0, foldlevel(3))
call assert_equal(0, foldlevel(4))
call assert_equal(6, foldclosedend(5))
call assert_equal(10, foldclosedend(7))
call assert_equal(14, foldclosedend(11))
call delete('Xfile')
bwipe!
set foldmethod& foldexpr&
endfunc

View File

@ -764,6 +764,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
408,
/**/
407,
/**/