To: vim_dev@googlegroups.com Subject: Patch 8.0.0408 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0408 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) Files: src/fold.c, src/testdir/test_fold.vim *** ../vim-8.0.0407/src/fold.c 2017-02-28 21:53:51.275626386 +0100 --- src/fold.c 2017-03-04 18:29:45.985625604 +0100 *************** *** 2505,2511 **** * 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) /* like lines are inserted */ --- 2505,2515 ---- * 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 == 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,2540 **** fp->fd_top = firstlnum; fold_changed = TRUE; } ! else if (flp->start != 0 && lvl == level ! && fp->fd_top != firstlnum) { ! /* 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); i = (int)(fp - (fold_T *)gap->ga_data); ! foldSplit(gap, i, flp->lnum, flp->lnum - 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. */ --- 2527,2570 ---- fp->fd_top = firstlnum; fold_changed = TRUE; } ! else if ((flp->start != 0 && lvl == level) ! || firstlnum != startlnum) { ! 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, 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,2548 **** --- 2573,2592 ---- || 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) *** ../vim-8.0.0407/src/testdir/test_fold.vim 2017-03-04 15:28:49.422383686 +0100 --- src/testdir/test_fold.vim 2017-03-04 18:39:30.289078439 +0100 *************** *** 117,119 **** --- 117,205 ---- set foldmethod& endfor endfunc + + func! Test_indent_fold_with_read() + new + set foldmethod=indent + call setline(1, repeat(["\a"], 4)) + for n in range(1, 4) + call assert_equal(1, foldlevel(n)) + endfor + + call writefile(["a", "", "\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 = "\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 *** ../vim-8.0.0407/src/version.c 2017-03-04 15:28:49.422383686 +0100 --- src/version.c 2017-03-04 18:39:29.289085913 +0100 *************** *** 766,767 **** --- 766,769 ---- { /* Add new patch number below this line */ + /**/ + 408, /**/ -- hundred-and-one symptoms of being an internet addict: 46. Your wife makes a new rule: "The computer cannot come to bed." /// 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 ///