To: vim_dev@googlegroups.com Subject: Patch 8.0.0465 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0465 Problem: Off-by-one error in using :move with folding. Solution: Correct off-by-one mistakes and add more tests. (Matthew Malcomson) Files: src/fold.c, src/testdir/test_fold.vim *** ../vim-8.0.0464/src/fold.c 2017-03-16 13:54:03.515491515 +0100 --- src/fold.c 2017-03-16 15:35:45.882771962 +0100 *************** *** 3021,3028 **** static void truncate_fold(fold_T *fp, linenr_T end) { foldRemove(&fp->fd_nested, end - fp->fd_top, MAXLNUM); ! fp->fd_len = end - fp->fd_top + 1; } #define fold_end(fp) ((fp)->fd_top + (fp)->fd_len - 1) --- 3021,3029 ---- 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; } #define fold_end(fp) ((fp)->fd_top + (fp)->fd_len - 1) *************** *** 3062,3068 **** } else /* Case 2 truncate fold, folds after this one must be dealt with. */ ! truncate_fold(fp, line1); /* Look at the next fold, and treat that one as if it were the first * after "line1" (because now it is). */ --- 3063,3069 ---- } else /* Case 2 truncate fold, folds after this one must be dealt with. */ ! 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,3088 **** } else if (fp->fd_top > line2) { ! 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) { /* Case 8. -- ensure truncated at dest, shift up */ truncate_fold(fp, dest); --- 3079,3089 ---- } else if (fp->fd_top > line2) { ! 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) { /* Case 8. -- ensure truncated at dest, shift up */ truncate_fold(fp, dest); *** ../vim-8.0.0464/src/testdir/test_fold.vim 2017-03-14 21:53:54.114075276 +0100 --- src/testdir/test_fold.vim 2017-03-16 15:35:45.882771962 +0100 *************** *** 249,255 **** redraw! set fdm=manual call cursor(2, 1) ! norm! zR 7,12m0 let folds=repeat([-1], 18) call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$')) --- 249,255 ---- redraw! set fdm=manual call cursor(2, 1) ! %foldopen 7,12m0 let folds=repeat([-1], 18) call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$')) *************** *** 284,289 **** --- 284,299 ---- 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,313 **** call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c")) set fdm=indent call cursor(2, 1) ! norm! zR 7,12m0 let folds=repeat([-1], 18) call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$')) --- 317,323 ---- call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c")) set fdm=indent call cursor(2, 1) ! %foldopen 7,12m0 let folds=repeat([-1], 18) call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$')) *************** *** 339,343 **** --- 349,362 ---- 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 *** ../vim-8.0.0464/src/version.c 2017-03-16 15:13:41.928472168 +0100 --- src/version.c 2017-03-16 15:58:20.004901010 +0100 *************** *** 766,767 **** --- 766,769 ---- { /* Add new patch number below this line */ + /**/ + 465, /**/ -- There are three kinds of persons: Those who can count and those who can't. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///