]> granicus.if.org Git - vim/commitdiff
patch 8.0.0465: off-by-one error in using :move with folding v8.0.0465
authorBram Moolenaar <Bram@vim.org>
Thu, 16 Mar 2017 14:59:14 +0000 (15:59 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 16 Mar 2017 14:59:14 +0000 (15:59 +0100)
Problem:    Off-by-one error in using :move with folding.
Solution:   Correct off-by-one mistakes and add more tests. (Matthew
            Malcomson)

src/fold.c
src/testdir/test_fold.vim
src/version.c

index 86baa32de3b36bbe0a7f7ad628c22c40b05b01a5..9606b68190733cfde10ed47d8bd375e096d3f42f 100644 (file)
@@ -3021,8 +3021,9 @@ foldReverseOrder(garray_T *gap, linenr_T start, linenr_T end)
     static void
 truncate_fold(fold_T *fp, linenr_T end)
 {
+    end += 1;
     foldRemove(&fp->fd_nested, end - fp->fd_top, MAXLNUM);
-    fp->fd_len = end - fp->fd_top + 1;
+    fp->fd_len = end - fp->fd_top;
 }
 
 #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)
        }
        else
            /* Case 2 truncate fold, folds after this one must be dealt with. */
-           truncate_fold(fp, line1);
+           truncate_fold(fp, line1 - 1);
 
        /* Look at the next fold, and treat that one as if it were the first
         * after  "line1" (because now it is). */
@@ -3078,11 +3079,11 @@ foldMoveRange(garray_T *gap, linenr_T line1, linenr_T line2, linenr_T dest)
     }
     else if (fp->fd_top > line2)
     {
-       for (; valid_fold(fp, gap) && fold_end(fp) < dest; fp++)
+       for (; valid_fold(fp, gap) && fold_end(fp) <= dest; fp++)
        /* Case 9. (for all case 9's) -- shift up. */
            fp->fd_top -= range_len;
 
-       if (valid_fold(fp, gap) && fp->fd_top < dest)
+       if (valid_fold(fp, gap) && fp->fd_top <= dest)
        {
            /* Case 8. -- ensure truncated at dest, shift up */
            truncate_fold(fp, dest);
index 19c94140d44bab944b811919cb6587c4292314b2..46c54e86142b469eebd56ab271acdbfb8abbdcb6 100644 (file)
@@ -249,7 +249,7 @@ func! Test_move_folds_around_manual()
   redraw!
   set fdm=manual
   call cursor(2, 1)
-  norm! zR
+  %foldopen
   7,12m0
   let folds=repeat([-1], 18)
   call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
@@ -284,6 +284,16 @@ func! Test_move_folds_around_manual()
   call assert_equal(0, foldlevel(6))
   call assert_equal(9, foldclosedend(7))
   call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
+  %d
+  " Ensure moving around the edges still works.
+  call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
+  set fdm=indent foldlevel=0
+  set fdm=manual
+  %foldopen
+  6m$
+  " The first fold has been truncated to the 5'th line.
+  " Second fold has been moved up because the moved line is now below it.
+  call assert_equal([0, 1, 1, 1, 1, 0, 0, 0, 1, 0], map(range(1, line('$')), 'foldlevel(v:val)'))
   bw!
 endfunc
 
@@ -307,7 +317,7 @@ func! Test_move_folds_around_indent()
   call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
   set fdm=indent
   call cursor(2, 1)
-  norm! zR
+  %foldopen
   7,12m0
   let folds=repeat([-1], 18)
   call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
@@ -339,5 +349,14 @@ func! Test_move_folds_around_indent()
   call assert_equal(1, foldlevel(6))
   call assert_equal(9, foldclosedend(7))
   call assert_equal([-1, 2, 2, 2, 2, 2, 2, 2, 2, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
+  " Ensure moving around the edges still works.
+  %d
+  call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
+  set fdm=indent foldlevel=0
+  %foldopen
+  6m$
+  " The first fold has been truncated to the 5'th line.
+  " Second fold has been moved up because the moved line is now below it.
+  call assert_equal([0, 1, 1, 1, 1, 0, 0, 0, 1, 1], map(range(1, line('$')), 'foldlevel(v:val)'))
   bw!
 endfunc
index efef5f8d9ea50666018fb1efa02d65aea4d2b113..3f4989539a69fa19dcab006f6f54c34569a2de54 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    465,
 /**/
     464,
 /**/