mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -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:
64
src/fold.c
64
src/fold.c
@@ -2505,7 +2505,11 @@ foldUpdateIEMSRecurse(
|
|||||||
* before where we started looking, extend it. If it
|
* before where we started looking, extend it. If it
|
||||||
* starts at another line, update nested folds to keep
|
* starts at another line, update nested folds to keep
|
||||||
* their position, compensating for the new fd_top. */
|
* 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)
|
if (fp->fd_top > firstlnum)
|
||||||
/* like lines are inserted */
|
/* like lines are inserted */
|
||||||
@@ -2523,18 +2527,44 @@ foldUpdateIEMSRecurse(
|
|||||||
fp->fd_top = firstlnum;
|
fp->fd_top = firstlnum;
|
||||||
fold_changed = TRUE;
|
fold_changed = TRUE;
|
||||||
}
|
}
|
||||||
else if (flp->start != 0 && lvl == level
|
else if ((flp->start != 0 && lvl == level)
|
||||||
&& fp->fd_top != firstlnum)
|
|| firstlnum != startlnum)
|
||||||
{
|
{
|
||||||
/* Existing fold that includes startlnum must stop
|
linenr_T breakstart;
|
||||||
* if we find the start of a new fold at the same
|
linenr_T breakend;
|
||||||
* level. Split it. Delete contained folds at
|
|
||||||
* this point to split them too. */
|
/*
|
||||||
foldRemove(&fp->fd_nested, flp->lnum - fp->fd_top,
|
* Before there was a fold spanning from above
|
||||||
flp->lnum - fp->fd_top);
|
* 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);
|
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;
|
fp = (fold_T *)gap->ga_data + i + 1;
|
||||||
|
|
||||||
/* If using the "marker" or "syntax" method, we
|
/* If using the "marker" or "syntax" method, we
|
||||||
* need to continue until the end of the fold is
|
* need to continue until the end of the fold is
|
||||||
* found. */
|
* found. */
|
||||||
@@ -2543,6 +2573,20 @@ foldUpdateIEMSRecurse(
|
|||||||
|| getlevel == foldlevelSyntax)
|
|| getlevel == foldlevelSyntax)
|
||||||
finish = TRUE;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
if (fp->fd_top >= startlnum)
|
if (fp->fd_top >= startlnum)
|
||||||
|
@@ -117,3 +117,89 @@ func Test_manual_fold_with_filter()
|
|||||||
set foldmethod&
|
set foldmethod&
|
||||||
endfor
|
endfor
|
||||||
endfunc
|
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
|
||||||
|
@@ -764,6 +764,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
408,
|
||||||
/**/
|
/**/
|
||||||
407,
|
407,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user