diff --git a/runtime/defaults.vim b/runtime/defaults.vim index 43ff1e0fbe..69668f1c00 100644 --- a/runtime/defaults.vim +++ b/runtime/defaults.vim @@ -1,7 +1,7 @@ " The default vimrc file. " " Maintainer: Bram Moolenaar -" Last change: 2016 Sep 02 +" Last change: 2017 Mar 08 " " This is loaded if no vimrc file was found. " Except when Vim is run with "-u NONE" or "-C". @@ -21,7 +21,10 @@ endif " Use Vim settings, rather than Vi settings (much better!). " This must be first, because it changes other options as a side effect. -set nocompatible +" Avoid side effects when it was already reset. +if &compatible + set nocompatible +endif " Allow backspacing over everything in insert mode. set backspace=indent,eol,start diff --git a/src/auto/configure b/src/auto/configure index 0474792047..9a32578b58 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -10225,15 +10225,25 @@ fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for /proc/self/exe" >&5 -$as_echo_n "checking for /proc/self/exe... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for /proc link to executable" >&5 +$as_echo_n "checking for /proc link to executable... " >&6; } if test -L "/proc/self/exe"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - $as_echo "#define HAVE_PROC_SELF_EXE 1" >>confdefs.h + { $as_echo "$as_me:${as_lineno-$LINENO}: result: /proc/self/exe" >&5 +$as_echo "/proc/self/exe" >&6; } + $as_echo "#define PROC_EXE_LINK \"/proc/self/exe\"" >>confdefs.h + +elif test -L "/proc/self/path/a.out"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: /proc/self/path/a.out" >&5 +$as_echo "/proc/self/path/a.out" >&6; } + $as_echo "#define PROC_EXE_LINK \"/proc/self/path/a.out\"" >>confdefs.h + +elif test -L "/proc/curproc/file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: /proc/curproc/file" >&5 +$as_echo "/proc/curproc/file" >&6; } + $as_echo "#define PROC_EXE_LINK \"/proc/curproc/file\"" >>confdefs.h else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi diff --git a/src/config.h.in b/src/config.h.in index a9bcf1ef33..f8a23ed78b 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -446,8 +446,8 @@ /* Define if fcntl()'s F_SETFD command knows about FD_CLOEXEC */ #undef HAVE_FD_CLOEXEC -/* Define if /proc/self/exe can be read */ -#undef HAVE_PROC_SELF_EXE +/* Define if /proc/self/exe or similar can be read */ +#undef PROC_EXE_LINK /* Define if you want Cygwin to use the WIN32 clipboard, not compatible with X11*/ #undef FEAT_CYGWIN_WIN32_CLIPBOARD diff --git a/src/configure.ac b/src/configure.ac index 0113f170fb..482773750e 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -3105,12 +3105,21 @@ dnl --------------------------------------------------------------------------- dnl end of GUI-checking dnl --------------------------------------------------------------------------- -AC_MSG_CHECKING([for /proc/self/exe]) +AC_MSG_CHECKING([for /proc link to executable]) if test -L "/proc/self/exe"; then - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_PROC_SELF_EXE) + dnl Linux + AC_MSG_RESULT([/proc/self/exe]) + AC_DEFINE(PROC_EXE_LINK, "/proc/self/exe") +elif test -L "/proc/self/path/a.out"; then + dnl Solaris + AC_MSG_RESULT([/proc/self/path/a.out]) + AC_DEFINE(PROC_EXE_LINK, "/proc/self/path/a.out") +elif test -L "/proc/curproc/file"; then + dnl FreeBSD + AC_MSG_RESULT([/proc/curproc/file]) + AC_DEFINE(PROC_EXE_LINK, "/proc/curproc/file") else - AC_MSG_RESULT(no) + AC_MSG_RESULT(no) fi dnl Check for Cygwin, which needs an extra source file if not using X11 diff --git a/src/dict.c b/src/dict.c index 70743059e4..a26419b6d1 100644 --- a/src/dict.c +++ b/src/dict.c @@ -356,12 +356,12 @@ dict_add_list(dict_T *d, char *key, list_T *list) item->di_tv.v_lock = 0; item->di_tv.v_type = VAR_LIST; item->di_tv.vval.v_list = list; + ++list->lv_refcount; if (dict_add(d, item) == FAIL) { dictitem_free(item); return FAIL; } - ++list->lv_refcount; return OK; } @@ -380,12 +380,12 @@ dict_add_dict(dict_T *d, char *key, dict_T *dict) item->di_tv.v_lock = 0; item->di_tv.v_type = VAR_DICT; item->di_tv.vval.v_dict = dict; + ++dict->dv_refcount; if (dict_add(d, item) == FAIL) { dictitem_free(item); return FAIL; } - ++dict->dv_refcount; return OK; } diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 64d7f6b847..df35f52da8 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -799,14 +799,8 @@ do_move(linenr_T line1, linenr_T line2, linenr_T dest) linenr_T num_lines; /* Num lines moved */ linenr_T last_line; /* Last line in file after adding new text */ #ifdef FEAT_FOLDING - int isFolded; - - /* Moving lines seems to corrupt the folds, delete folding info now - * and recreate it when finished. Don't do this for manual folding, it - * would delete all folds. */ - isFolded = hasAnyFolding(curwin) && !foldmethodIsManual(curwin); - if (isFolded) - deleteFoldRecurse(&curwin->w_folds); + win_T *win; + tabpage_T *tp; #endif if (dest >= line1 && dest < line2) @@ -851,24 +845,34 @@ do_move(linenr_T line1, linenr_T line2, linenr_T dest) * their final destination at the new text position -- webb */ last_line = curbuf->b_ml.ml_line_count; - mark_adjust(line1, line2, last_line - line2, 0L); - changed_lines(last_line - num_lines + 1, 0, last_line + 1, num_lines); + mark_adjust_nofold(line1, line2, last_line - line2, 0L); if (dest >= line2) { - mark_adjust(line2 + 1, dest, -num_lines, 0L); + mark_adjust_nofold(line2 + 1, dest, -num_lines, 0L); +#ifdef FEAT_FOLDING + FOR_ALL_TAB_WINDOWS(tp, win) { + if (win->w_buffer == curbuf) + foldMoveRange(&win->w_folds, line1, line2, dest); + } +#endif curbuf->b_op_start.lnum = dest - num_lines + 1; curbuf->b_op_end.lnum = dest; } else { - mark_adjust(dest + 1, line1 - 1, num_lines, 0L); + mark_adjust_nofold(dest + 1, line1 - 1, num_lines, 0L); +#ifdef FEAT_FOLDING + FOR_ALL_TAB_WINDOWS(tp, win) { + if (win->w_buffer == curbuf) + foldMoveRange(&win->w_folds, dest + 1, line1 - 1, line2); + } +#endif curbuf->b_op_start.lnum = dest + 1; curbuf->b_op_end.lnum = dest + num_lines; } curbuf->b_op_start.col = curbuf->b_op_end.col = 0; - mark_adjust(last_line - num_lines + 1, last_line, + mark_adjust_nofold(last_line - num_lines + 1, last_line, -(last_line - dest - extra), 0L); - changed_lines(last_line - num_lines + 1, 0, last_line + 1, -extra); /* * Now we delete the original text -- webb @@ -906,12 +910,6 @@ do_move(linenr_T line1, linenr_T line2, linenr_T dest) else changed_lines(dest + 1, 0, line1 + num_lines, 0L); -#ifdef FEAT_FOLDING - /* recreate folds */ - if (isFolded) - foldUpdateAll(curwin); -#endif - return OK; } diff --git a/src/fold.c b/src/fold.c index 826ad5c8dc..86baa32de3 100644 --- a/src/fold.c +++ b/src/fold.c @@ -2968,6 +2968,182 @@ foldRemove(garray_T *gap, linenr_T top, linenr_T bot) } } +/* foldReverseOrder() {{{2 */ + static void +foldReverseOrder(garray_T *gap, linenr_T start, linenr_T end) +{ + fold_T *left, *right; + fold_T tmp; + + for (; start < end; start++, end--) + { + left = (fold_T *)gap->ga_data + start; + right = (fold_T *)gap->ga_data + end; + tmp = *left; + *left = *right; + *right = tmp; + } +} + +/* foldMoveRange() {{{2 */ +/* + * Move folds within the inclusive range "line1" to "line2" to after "dest" + * requires "line1" <= "line2" <= "dest" + * + * There are the following situations for the first fold at or below line1 - 1. + * 1 2 3 4 + * 1 2 3 4 + * line1 2 3 4 + * 2 3 4 5 6 7 + * line2 3 4 5 6 7 + * 3 4 6 7 8 9 + * dest 4 7 8 9 + * 4 7 8 10 + * 4 7 8 10 + * + * In the following descriptions, "moved" means moving in the buffer, *and* in + * the fold array. + * Meanwhile, "shifted" just means moving in the buffer. + * 1. not changed + * 2. truncated above line1 + * 3. length reduced by line2 - line1, folds starting between the end of 3 and + * dest are truncated and shifted up + * 4. internal folds moved (from [line1, line2] to dest) + * 5. moved to dest. + * 6. truncated below line2 and moved. + * 7. length reduced by line2 - dest, folds starting between line2 and dest are + * removed, top is moved down by move_len. + * 8. truncated below dest and shifted up. + * 9. shifted up + * 10. not changed + */ + + 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) +#define valid_fold(fp, gap) ((fp) < ((fold_T *)(gap)->ga_data + (gap)->ga_len)) +#define fold_index(fp, gap) ((size_t)(fp - ((fold_T *)(gap)->ga_data))) + + void +foldMoveRange(garray_T *gap, linenr_T line1, linenr_T line2, linenr_T dest) +{ + fold_T *fp; + linenr_T range_len = line2 - line1 + 1; + linenr_T move_len = dest - line2; + int at_start = foldFind(gap, line1 - 1, &fp); + size_t move_start = 0, move_end = 0, dest_index = 0; + + if (at_start) + { + if (fold_end(fp) > dest) + { + /* Case 4 + * don't have to change this fold, but have to move nested folds. + */ + foldMoveRange(&fp->fd_nested, line1 - fp->fd_top, line2 - + fp->fd_top, dest - fp->fd_top); + return; + } + else if (fold_end(fp) > line2) + { + /* Case 3 + * Remove nested folds between line1 and line2 & reduce the + * length of fold by "range_len". + * Folds after this one must be dealt with. + */ + foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top, line2 - + fp->fd_top, MAXLNUM, -range_len); + fp->fd_len -= range_len; + } + 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). */ + fp = fp + 1; + } + + if (!valid_fold(fp, gap) || fp->fd_top > dest) + { + /* Case 10 + * No folds after "line1" and before "dest" + */ + return; + } + 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); + fp->fd_top -= range_len; + } + return; + } + else if (fold_end(fp) > dest) + { + /* Case 7 -- remove nested folds and shrink */ + foldMarkAdjustRecurse(&fp->fd_nested, line2 + 1 - fp->fd_top, dest - + fp->fd_top, MAXLNUM, -move_len); + fp->fd_len -= move_len; + fp->fd_top += move_len; + return; + } + + /* Case 5 or 6 + * changes rely on whether there are folds between the end of + * this fold and "dest". + */ + move_start = fold_index(fp, gap); + + for (; valid_fold(fp, gap) && fp->fd_top <= dest; fp++) + { + if (fp->fd_top <= line2) + { + /* 1. 2. or 3. */ + if (fold_end(fp) > line2) + /* 2. or 3., truncate before moving */ + truncate_fold(fp, line2); + + fp->fd_top += move_len; + continue; + } + + /* Record index of the first fold after the moved range. */ + if (move_end == 0) + move_end = fold_index(fp, gap); + + if (fold_end(fp) > dest) + truncate_fold(fp, dest); + + fp->fd_top -= range_len; + } + + dest_index = fold_index(fp, gap); + + /* + * All folds are now correct, but they are not necessarily in the correct + * order. We have to swap folds in the range [move_end, dest_index) with + * those in the range [move_start, move_end). + */ + foldReverseOrder(gap, move_start, dest_index - 1); + foldReverseOrder(gap, move_start, move_start + dest_index - move_end - 1); + foldReverseOrder(gap, move_start + dest_index - move_end, dest_index - 1); +} +#undef fold_end +#undef valid_fold +#undef fold_index + /* foldMerge() {{{2 */ /* * Merge two adjacent folds (and the nested ones in them). diff --git a/src/main.c b/src/main.c index 382fc24a49..59e247e0a3 100644 --- a/src/main.c +++ b/src/main.c @@ -3623,11 +3623,11 @@ set_progpath(char_u *argv0) { char_u *val = argv0; -# ifdef HAVE_PROC_SELF_EXE +# ifdef PROC_EXE_LINK char buf[PATH_MAX + 1]; ssize_t len; - len = readlink("/proc/self/exe", buf, PATH_MAX); + len = readlink(PROC_EXE_LINK, buf, PATH_MAX); if (len > 0) { buf[len] = NUL; diff --git a/src/mark.c b/src/mark.c index 194125eb00..0d21305bcf 100644 --- a/src/mark.c +++ b/src/mark.c @@ -37,6 +37,8 @@ static void cleanup_jumplist(void); #ifdef FEAT_VIMINFO static void write_one_filemark(FILE *fp, xfmark_T *fm, int c1, int c2); #endif +static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, + long amount_after, int adjust_folds); /* * Set named mark "c" at current cursor position. @@ -1028,6 +1030,27 @@ mark_adjust( linenr_T line2, long amount, long amount_after) +{ + mark_adjust_internal(line1, line2, amount, amount_after, TRUE); +} + + void +mark_adjust_nofold( + linenr_T line1, + linenr_T line2, + long amount, + long amount_after) +{ + mark_adjust_internal(line1, line2, amount, amount_after, FALSE); +} + + static void +mark_adjust_internal( + linenr_T line1, + linenr_T line2, + long amount, + long amount_after, + int adjust_folds UNUSED) { int i; int fnum = curbuf->b_fnum; @@ -1174,7 +1197,8 @@ mark_adjust( #ifdef FEAT_FOLDING /* adjust folds */ - foldMarkAdjust(win, line1, line2, amount, amount_after); + if (adjust_folds) + foldMarkAdjust(win, line1, line2, amount, amount_after); #endif } } diff --git a/src/misc2.c b/src/misc2.c index 4fcdd9e2e6..872777407f 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -3371,7 +3371,7 @@ vim_chdirfile(char_u *fname) * The Vim code assumes a trailing slash is only ignored for a directory. */ static int -illegal_slash(char *name) +illegal_slash(const char *name) { if (name[0] == NUL) return FALSE; /* no file name is not illegal */ @@ -3390,7 +3390,7 @@ vim_stat(const char *name, stat_T *stp) { /* On Solaris stat() accepts "file/" as if it was "file". Return -1 if * the name ends in "/" and it's not a directory. */ - return illegal_slash(n) ? -1 : stat(n, p); + return illegal_slash(name) ? -1 : stat(name, stp); } #endif diff --git a/src/proto/fold.pro b/src/proto/fold.pro index dce1803810..cda536b27e 100644 --- a/src/proto/fold.pro +++ b/src/proto/fold.pro @@ -31,6 +31,7 @@ void foldInitWin(win_T *new_win); int find_wl_entry(win_T *win, linenr_T lnum); void foldAdjustVisual(void); void foldAdjustCursor(void); +void foldMoveRange(garray_T *gap, linenr_T line1, linenr_T line2, linenr_T dest); void cloneFoldGrowArray(garray_T *from, garray_T *to); void deleteFoldRecurse(garray_T *gap); void foldMarkAdjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after); diff --git a/src/proto/mark.pro b/src/proto/mark.pro index 90be1a566e..ff1f441e81 100644 --- a/src/proto/mark.pro +++ b/src/proto/mark.pro @@ -19,6 +19,7 @@ void ex_jumps(exarg_T *eap); void ex_clearjumps(exarg_T *eap); void ex_changes(exarg_T *eap); void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after); +void mark_adjust_nofold(linenr_T line1, linenr_T line2, long amount, long amount_after); void mark_col_adjust(linenr_T lnum, colnr_T mincol, long lnum_amount, long col_amount); void copy_jumplist(win_T *from, win_T *to); void free_jumplist(win_T *wp); diff --git a/src/testdir/Make_dos.mak b/src/testdir/Make_dos.mak index f9d21a5fa8..fe2e2ba25f 100644 --- a/src/testdir/Make_dos.mak +++ b/src/testdir/Make_dos.mak @@ -44,6 +44,7 @@ $(DOSTMP_INFILES): $(*B).in # This moves test99.in to test99.in.bak temporarily. $(TEST_OUTFILES): $(DOSTMP)\$(*B).in -@if exist test.out DEL test.out + -@if exist $(DOSTMP)\$(*B).out DEL $(DOSTMP)\$(*B).out move $(*B).in $(*B).in.bak > nul copy $(DOSTMP)\$(*B).in $(*B).in > nul copy $(*B).ok test.ok > nul diff --git a/src/testdir/test45.in b/src/testdir/test45.in index 751e1378fb..c6d7c5064a 100644 --- a/src/testdir/test45.in +++ b/src/testdir/test45.in @@ -27,6 +27,7 @@ kYpj:call append("$", foldlevel(".")) /^2 b i jI :call append("$", "indent " . foldlevel(".")) k:call append("$", foldlevel(".")) +:set sw& :" test syntax folding :set fdm=syntax fdl=0 :syn region Hup start="dd" end="ii" fold contains=Fd1,Fd2,Fd3 diff --git a/src/testdir/test_fold.vim b/src/testdir/test_fold.vim index f10480bb4f..19c94140d4 100644 --- a/src/testdir/test_fold.vim +++ b/src/testdir/test_fold.vim @@ -1,5 +1,9 @@ " Test for folding +func! PrepIndent(arg) + return [a:arg] + repeat(["\t".a:arg], 5) +endfu + func! Test_address_fold() new call setline(1, ['int FuncName() {/*{{{*/', 1, 2, 3, 4, 5, '}/*}}}*/', @@ -219,3 +223,121 @@ func Test_update_folds_expr_read() bwipe! set foldmethod& foldexpr& endfunc + +func! Test_move_folds_around_manual() + new + let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c") + call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c")) + let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14] + " all folds closed + set foldenable foldlevel=0 fdm=indent + " needs a forced redraw + redraw! + set fdm=manual + call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) + call assert_equal(input, getline(1, '$')) + 7,12m0 + call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$')) + call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) + 10,12m0 + call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$')) + call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)')) + " moving should not close the folds + %d + call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c")) + set fdm=indent + 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, '$')) + call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) + norm! zM + " folds are not corrupted and all have been closed + call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)')) + %d + call setline(1, ["a", "\tb", "\tc", "\td", "\te"]) + set fdm=indent + redraw! + set fdm=manual + %foldopen + 3m4 + %foldclose + call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$')) + call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)')) + %d + call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"]) + set fdm=indent foldlevel=0 + set fdm=manual + %foldopen + 3m1 + %foldclose + call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$')) + call assert_equal(0, foldlevel(2)) + call assert_equal(5, foldclosedend(3)) + call assert_equal([-1, -1, 3, 3, 3, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)')) + 2,6m$ + %foldclose + call assert_equal(5, foldclosedend(2)) + 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)')) + bw! +endfunc + +func! Test_move_folds_around_indent() + new + let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c") + call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c")) + let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14] + " all folds closed + set fdm=indent + call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) + call assert_equal(input, getline(1, '$')) + 7,12m0 + call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$')) + call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) + 10,12m0 + call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$')) + call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)')) + " moving should not close the folds + %d + 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, '$')) + call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) + norm! zM + " folds are not corrupted and all have been closed + call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)')) + %d + call setline(1, ["a", "\tb", "\tc", "\td", "\te"]) + set fdm=indent + %foldopen + 3m4 + %foldclose + call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$')) + call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)')) + %d + call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"]) + set fdm=indent foldlevel=0 + %foldopen + 3m1 + %foldclose + call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$')) + call assert_equal(1, foldlevel(2)) + call assert_equal(5, foldclosedend(3)) + call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)')) + 2,6m$ + %foldclose + call assert_equal(9, foldclosedend(2)) + 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)')) + bw! +endfunc diff --git a/src/version.c b/src/version.c index 209c6920dd..8735b51a41 100644 --- a/src/version.c +++ b/src/version.c @@ -779,6 +779,22 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 464, +/**/ + 463, +/**/ + 462, +/**/ + 461, +/**/ + 460, +/**/ + 459, +/**/ + 458, +/**/ + 457, /**/ 456, /**/