Skip to content

Commit 40ebc0a

Browse files
committed
patch 8.0.0465: off-by-one error in using :move with folding
Problem: Off-by-one error in using :move with folding. Solution: Correct off-by-one mistakes and add more tests. (Matthew Malcomson)
1 parent f3757f0 commit 40ebc0a

File tree

3 files changed

+28
-6
lines changed

3 files changed

+28
-6
lines changed

src/fold.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3021,8 +3021,9 @@ foldReverseOrder(garray_T *gap, linenr_T start, linenr_T end)
30213021
static void
30223022
truncate_fold(fold_T *fp, linenr_T end)
30233023
{
3024+
end += 1;
30243025
foldRemove(&fp->fd_nested, end - fp->fd_top, MAXLNUM);
3025-
fp->fd_len = end - fp->fd_top + 1;
3026+
fp->fd_len = end - fp->fd_top;
30263027
}
30273028

30283029
#define fold_end(fp) ((fp)->fd_top + (fp)->fd_len - 1)
@@ -3062,7 +3063,7 @@ foldMoveRange(garray_T *gap, linenr_T line1, linenr_T line2, linenr_T dest)
30623063
}
30633064
else
30643065
/* Case 2 truncate fold, folds after this one must be dealt with. */
3065-
truncate_fold(fp, line1);
3066+
truncate_fold(fp, line1 - 1);
30663067

30673068
/* Look at the next fold, and treat that one as if it were the first
30683069
* after "line1" (because now it is). */
@@ -3078,11 +3079,11 @@ foldMoveRange(garray_T *gap, linenr_T line1, linenr_T line2, linenr_T dest)
30783079
}
30793080
else if (fp->fd_top > line2)
30803081
{
3081-
for (; valid_fold(fp, gap) && fold_end(fp) < dest; fp++)
3082+
for (; valid_fold(fp, gap) && fold_end(fp) <= dest; fp++)
30823083
/* Case 9. (for all case 9's) -- shift up. */
30833084
fp->fd_top -= range_len;
30843085

3085-
if (valid_fold(fp, gap) && fp->fd_top < dest)
3086+
if (valid_fold(fp, gap) && fp->fd_top <= dest)
30863087
{
30873088
/* Case 8. -- ensure truncated at dest, shift up */
30883089
truncate_fold(fp, dest);

src/testdir/test_fold.vim

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ func! Test_move_folds_around_manual()
249249
redraw!
250250
set fdm=manual
251251
call cursor(2, 1)
252-
norm! zR
252+
%foldopen
253253
7,12m0
254254
let folds=repeat([-1], 18)
255255
call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
@@ -284,6 +284,16 @@ func! Test_move_folds_around_manual()
284284
call assert_equal(0, foldlevel(6))
285285
call assert_equal(9, foldclosedend(7))
286286
call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
287+
%d
288+
" Ensure moving around the edges still works.
289+
call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
290+
set fdm=indent foldlevel=0
291+
set fdm=manual
292+
%foldopen
293+
6m$
294+
" The first fold has been truncated to the 5'th line.
295+
" Second fold has been moved up because the moved line is now below it.
296+
call assert_equal([0, 1, 1, 1, 1, 0, 0, 0, 1, 0], map(range(1, line('$')), 'foldlevel(v:val)'))
287297
bw!
288298
endfunc
289299

@@ -307,7 +317,7 @@ func! Test_move_folds_around_indent()
307317
call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
308318
set fdm=indent
309319
call cursor(2, 1)
310-
norm! zR
320+
%foldopen
311321
7,12m0
312322
let folds=repeat([-1], 18)
313323
call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
@@ -339,5 +349,14 @@ func! Test_move_folds_around_indent()
339349
call assert_equal(1, foldlevel(6))
340350
call assert_equal(9, foldclosedend(7))
341351
call assert_equal([-1, 2, 2, 2, 2, 2, 2, 2, 2, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
352+
" Ensure moving around the edges still works.
353+
%d
354+
call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
355+
set fdm=indent foldlevel=0
356+
%foldopen
357+
6m$
358+
" The first fold has been truncated to the 5'th line.
359+
" Second fold has been moved up because the moved line is now below it.
360+
call assert_equal([0, 1, 1, 1, 1, 0, 0, 0, 1, 1], map(range(1, line('$')), 'foldlevel(v:val)'))
342361
bw!
343362
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ static char *(features[]) =
764764

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
465,
767769
/**/
768770
464,
769771
/**/

0 commit comments

Comments
 (0)