Merge #8001 from justinmk/vimpatches

This commit is contained in:
Justin M. Keyes
2018-02-12 02:59:29 +01:00
committed by GitHub
36 changed files with 1646 additions and 278 deletions

View File

@@ -1407,18 +1407,22 @@ void set_curbuf(buf_T *buf, int action)
}
if (bufref_valid(&prevbufref) && !aborting()) {
win_T *previouswin = curwin;
if (prevbuf == curbuf)
u_sync(FALSE);
close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, prevbuf,
unload ? action : (action == DOBUF_GOTO
&& !P_HID(prevbuf)
&& !bufIsChanged(
prevbuf)) ? DOBUF_UNLOAD : 0, FALSE);
if (curwin != previouswin && win_valid(previouswin))
/* autocommands changed curwin, Grr! */
if (prevbuf == curbuf) {
u_sync(false);
}
close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL,
prevbuf,
unload
? action
: (action == DOBUF_GOTO && !buf_hide(prevbuf)
&& !bufIsChanged(prevbuf)) ? DOBUF_UNLOAD : 0,
false);
if (curwin != previouswin && win_valid(previouswin)) {
// autocommands changed curwin, Grr!
curwin = previouswin;
}
}
}
/* An autocommand may have deleted "buf", already entered it (e.g., when
* it did ":bunload") or aborted the script processing!
* If curwin->w_buffer is null, enter_buffer() will make it valid again */
@@ -4413,12 +4417,12 @@ do_arg_all (
}
wp->w_arg_idx = i;
if (i == opened_len && !keep_tabs) { /* close this window */
if (P_HID(buf) || forceit || buf->b_nwindows > 1
if (i == opened_len && !keep_tabs) { // close this window
if (buf_hide(buf) || forceit || buf->b_nwindows > 1
|| !bufIsChanged(buf)) {
/* If the buffer was changed, and we would like to hide it,
* try autowriting. */
if (!P_HID(buf) && buf->b_nwindows <= 1 && bufIsChanged(buf)) {
if (!buf_hide(buf) && buf->b_nwindows <= 1 && bufIsChanged(buf)) {
bufref_T bufref;
set_bufref(&bufref, buf);
(void)autowrite(buf, false);
@@ -4433,7 +4437,7 @@ do_arg_all (
&& (first_tabpage->tp_next == NULL || !had_tab)) {
use_firstwin = true;
} else {
win_close(wp, !P_HID(buf) && !bufIsChanged(buf));
win_close(wp, !buf_hide(buf) && !bufIsChanged(buf));
// check if autocommands removed the next window
if (!win_valid(wpnext)) {
// start all over...
@@ -4511,14 +4515,15 @@ do_arg_all (
new_curwin = curwin;
new_curtab = curtab;
}
(void)do_ecmd(0, alist_name(&AARGLIST(alist)[i]), NULL, NULL,
ECMD_ONE,
((P_HID(curwin->w_buffer)
|| bufIsChanged(curwin->w_buffer)) ? ECMD_HIDE : 0)
+ ECMD_OLDBUF, curwin);
if (use_firstwin)
++autocmd_no_leave;
use_firstwin = FALSE;
(void)do_ecmd(0, alist_name(&AARGLIST(alist)[i]), NULL, NULL, ECMD_ONE,
((buf_hide(curwin->w_buffer)
|| bufIsChanged(curwin->w_buffer))
? ECMD_HIDE : 0) + ECMD_OLDBUF,
curwin);
if (use_firstwin) {
autocmd_no_leave++;
}
use_firstwin = false;
}
os_breakcheck();
@@ -4705,14 +4710,14 @@ void ex_buffer_all(exarg_T *eap)
* Close superfluous windows.
*/
for (wp = lastwin; open_wins > count; ) {
r = (P_HID(wp->w_buffer) || !bufIsChanged(wp->w_buffer)
|| autowrite(wp->w_buffer, FALSE) == OK);
r = (buf_hide(wp->w_buffer) || !bufIsChanged(wp->w_buffer)
|| autowrite(wp->w_buffer, false) == OK);
if (!win_valid(wp)) {
/* BufWrite Autocommands made the window invalid, start over */
wp = lastwin;
} else if (r) {
win_close(wp, !P_HID(wp->w_buffer));
--open_wins;
win_close(wp, !buf_hide(wp->w_buffer));
open_wins--;
wp = lastwin;
} else {
wp = wp->w_prev;

View File

@@ -2013,9 +2013,10 @@ int getfile(int fnum, char_u *ffname, char_u *sfname, int setpm, linenr_T lnum,
} else
other = (fnum != curbuf->b_fnum);
if (other)
++no_wait_return; /* don't wait for autowrite message */
if (other && !forceit && curbuf->b_nwindows == 1 && !P_HID(curbuf)
if (other) {
no_wait_return++; // don't wait for autowrite message
}
if (other && !forceit && curbuf->b_nwindows == 1 && !buf_hide(curbuf)
&& curbufIsChanged() && autowrite(curbuf, forceit) == FAIL) {
if (p_confirm && p_write)
dialog_changed(curbuf, FALSE);
@@ -2032,17 +2033,19 @@ int getfile(int fnum, char_u *ffname, char_u *sfname, int setpm, linenr_T lnum,
if (setpm)
setpcmark();
if (!other) {
if (lnum != 0)
if (lnum != 0) {
curwin->w_cursor.lnum = lnum;
}
check_cursor_lnum();
beginline(BL_SOL | BL_FIX);
retval = 0; /* it's in the same file */
retval = 0; // it's in the same file
} else if (do_ecmd(fnum, ffname, sfname, NULL, lnum,
(P_HID(curbuf) ? ECMD_HIDE : 0) + (forceit ? ECMD_FORCEIT : 0),
curwin) == OK)
retval = -1; /* opened another file */
else
retval = 1; /* error encountered */
(buf_hide(curbuf) ? ECMD_HIDE : 0)
+ (forceit ? ECMD_FORCEIT : 0), curwin) == OK) {
retval = -1; // opened another file
} else {
retval = 1; // error encountered
}
theend:
xfree(free_me);

View File

@@ -1343,7 +1343,7 @@ void dialog_changed(buf_T *buf, int checkall)
/// hidden, autowriting it or unloading it.
bool can_abandon(buf_T *buf, int forceit)
{
return P_HID(buf)
return buf_hide(buf)
|| !bufIsChanged(buf)
|| buf->b_nwindows > 1
|| autowrite(buf, forceit) == OK
@@ -1860,12 +1860,12 @@ void do_argfile(exarg_T *eap, int argn)
// if 'hidden' set, only check for changed file when re-editing
// the same buffer
other = true;
if (P_HID(curbuf)) {
if (buf_hide(curbuf)) {
p = (char_u *)fix_fname((char *)alist_name(&ARGLIST[argn]));
other = otherfile(p);
xfree(p);
}
if ((!P_HID(curbuf) || !other)
if ((!buf_hide(curbuf) || !other)
&& check_changed(curbuf, CCGD_AW
| (other ? 0 : CCGD_MULTWIN)
| (eap->forceit ? CCGD_FORCEIT : 0)
@@ -1885,7 +1885,7 @@ void do_argfile(exarg_T *eap, int argn)
// argument index.
if (do_ecmd(0, alist_name(&ARGLIST[curwin->w_arg_idx]), NULL,
eap, ECMD_LAST,
(P_HID(curwin->w_buffer) ? ECMD_HIDE : 0)
(buf_hide(curwin->w_buffer) ? ECMD_HIDE : 0)
+ (eap->forceit ? ECMD_FORCEIT : 0), curwin) == FAIL) {
curwin->w_arg_idx = old_arg_idx;
} else if (eap->cmdidx != CMD_argdo) {
@@ -1902,7 +1902,7 @@ void ex_next(exarg_T *eap)
// check for changed buffer now, if this fails the argument list is not
// redefined.
if (P_HID(curbuf)
if (buf_hide(curbuf)
|| eap->cmdidx == CMD_snext
|| !check_changed(curbuf, CCGD_AW
| (eap->forceit ? CCGD_FORCEIT : 0)
@@ -2008,7 +2008,7 @@ void ex_listdo(exarg_T *eap)
if (eap->cmdidx == CMD_windo
|| eap->cmdidx == CMD_tabdo
|| P_HID(curbuf)
|| buf_hide(curbuf)
|| !check_changed(curbuf, CCGD_AW
| (eap->forceit ? CCGD_FORCEIT : 0)
| CCGD_EXCMD)) {
@@ -3840,7 +3840,7 @@ void ex_drop(exarg_T *eap)
// to split the current window or data could be lost.
// Skip the check if the 'hidden' option is set, as in this case the
// buffer won't be lost.
if (!P_HID(curbuf)) {
if (!buf_hide(curbuf)) {
emsg_off++;
split = check_changed(curbuf, CCGD_AW | CCGD_EXCMD);
emsg_off--;

View File

@@ -5986,13 +5986,12 @@ static void ex_quit(exarg_T *eap)
return;
}
/*
* If there are more files or windows we won't exit.
*/
if (check_more(FALSE, eap->forceit) == OK && only_one_window())
exiting = TRUE;
if ((!P_HID(curbuf)
&& check_changed(curbuf, (p_awa ? CCGD_AW : 0)
// If there are more files or windows we won't exit.
if (check_more(false, eap->forceit) == OK && only_one_window()) {
exiting = true;
}
if ((!buf_hide(wp->w_buffer)
&& check_changed(wp->w_buffer, (p_awa ? CCGD_AW : 0)
| (eap->forceit ? CCGD_FORCEIT : 0)
| CCGD_EXCMD))
|| check_more(true, eap->forceit) == FAIL
@@ -6008,8 +6007,8 @@ static void ex_quit(exarg_T *eap)
if (only_one_window() && (ONE_WINDOW || eap->addr_count == 0)) {
getout(0);
}
/* close window; may free buffer */
win_close(wp, !P_HID(wp->w_buffer) || eap->forceit);
// close window; may free buffer
win_close(wp, !buf_hide(wp->w_buffer) || eap->forceit);
}
}
@@ -6108,7 +6107,7 @@ ex_win_close (
buf_T *buf = win->w_buffer;
need_hide = (bufIsChanged(buf) && buf->b_nwindows <= 1);
if (need_hide && !P_HID(buf) && !forceit) {
if (need_hide && !buf_hide(buf) && !forceit) {
if ((p_confirm || cmdmod.confirm) && p_write) {
bufref_T bufref;
set_bufref(&bufref, buf);
@@ -6124,11 +6123,12 @@ ex_win_close (
}
/* free buffer when not hiding it or when it's a scratch buffer */
if (tp == NULL)
win_close(win, !need_hide && !P_HID(buf));
else
win_close_othertab(win, !need_hide && !P_HID(buf), tp);
// free buffer when not hiding it or when it's a scratch buffer
if (tp == NULL) {
win_close(win, !need_hide && !buf_hide(buf));
} else {
win_close_othertab(win, !need_hide && !buf_hide(buf), tp);
}
}
/*
@@ -6359,7 +6359,7 @@ static void ex_exit(exarg_T *eap)
getout(0);
}
// Quit current window, may free the buffer.
win_close(curwin, !P_HID(curwin->w_buffer));
win_close(curwin, !buf_hide(curwin->w_buffer));
}
}
@@ -6929,24 +6929,23 @@ do_exedit (
empty buffer */
setpcmark();
if (do_ecmd(0, (eap->cmdidx == CMD_enew ? NULL : eap->arg),
NULL, eap,
eap->do_ecmd_lnum,
(P_HID(curbuf) ? ECMD_HIDE : 0)
NULL, eap, eap->do_ecmd_lnum,
(buf_hide(curbuf) ? ECMD_HIDE : 0)
+ (eap->forceit ? ECMD_FORCEIT : 0)
// After a split we can use an existing buffer.
+ (old_curwin != NULL ? ECMD_OLDBUF : 0)
+ (eap->cmdidx == CMD_badd ? ECMD_ADDBUF : 0)
, old_curwin == NULL ? curwin : NULL) == FAIL) {
/* Editing the file failed. If the window was split, close it. */
// Editing the file failed. If the window was split, close it.
if (old_curwin != NULL) {
need_hide = (curbufIsChanged() && curbuf->b_nwindows <= 1);
if (!need_hide || P_HID(curbuf)) {
if (!need_hide || buf_hide(curbuf)) {
cleanup_T cs;
/* Reset the error/interrupt/exception state here so that
* aborting() returns FALSE when closing a window. */
enter_cleanup(&cs);
win_close(curwin, !need_hide && !P_HID(curbuf));
win_close(curwin, !need_hide && !buf_hide(curbuf));
/* Restore the error/interrupt/exception state if not
* discarded by a new aborting error, interrupt, or

View File

@@ -5230,12 +5230,12 @@ static void nv_gotofile(cmdarg_T *cap)
if (ptr != NULL) {
// do autowrite if necessary
if (curbufIsChanged() && curbuf->b_nwindows <= 1 && !P_HID(curbuf)) {
if (curbufIsChanged() && curbuf->b_nwindows <= 1 && !buf_hide(curbuf)) {
(void)autowrite(curbuf, false);
}
setpcmark();
(void)do_ecmd(0, ptr, NULL, NULL, ECMD_LAST,
P_HID(curbuf) ? ECMD_HIDE : 0, curwin);
buf_hide(curbuf) ? ECMD_HIDE : 0, curwin);
if (cap->nchar == 'F' && lnum >= 0) {
curwin->w_cursor.lnum = lnum;
check_cursor_lnum();

View File

@@ -454,9 +454,6 @@ EXTERN char_u *p_hf; // 'helpfile'
EXTERN long p_hh; // 'helpheight'
EXTERN char_u *p_hlg; // 'helplang'
EXTERN int p_hid; // 'hidden'
// Use P_HID to check if a buffer is to be hidden when it is no longer
// visible in a window.
# define P_HID(buf) (buf_hide(buf))
EXTERN char_u *p_hl; // 'highlight'
EXTERN int p_hls; // 'hlsearch'
EXTERN long p_hi; // 'history'

View File

@@ -1380,13 +1380,15 @@ int searchc(cmdarg_T *cap, int t_cmd)
lastc_bytelen += (*mb_char2bytes)(cap->ncharC2, lastc_bytes + lastc_bytelen);
}
}
} else { /* repeat previous search */
if (*lastc == NUL)
} else { // repeat previous search
if (*lastc == NUL && lastc_bytelen == 1) {
return FAIL;
if (dir) /* repeat in opposite direction */
}
if (dir) { // repeat in opposite direction
dir = -lastcdir;
else
} else {
dir = lastcdir;
}
t_cmd = last_t_cmd;
c = *lastc;
/* For multi-byte re-use last lastc_bytes[] and lastc_bytelen. */

View File

@@ -23,7 +23,6 @@ SCRIPTS_DEFAULT = \
test49.out \
test52.out \
test64.out \
test73.out \
ifneq ($(OS),Windows_NT)
SCRIPTS_DEFAULTS := $(SCRIPTS_DEFAULT) \
@@ -42,17 +41,21 @@ NEW_TESTS ?= \
test_changedtick.res \
test_charsearch.res \
test_cindent.res \
test_close_count.res \
test_cmdline.res \
test_command_count.res \
test_cscope.res \
test_curswant.res \
test_digraph.res \
test_edit.res \
test_erasebackword.res \
test_exists.res \
test_diffmode.res \
test_farsi.res \
test_file_size.res \
test_filter_map.res \
test_find_complete.res \
test_fixeol.res \
test_findfile.res \
test_fnameescape.res \
test_fold.res \
@@ -72,13 +75,13 @@ NEW_TESTS ?= \
test_langmap.res \
test_let.res \
test_lineending.res \
test_listdict.res \
test_listchars.res \
test_makeencoding.res \
test_marks.res \
test_match.res \
test_matchadd_conceal.res \
test_matchadd_conceal_utf8.res \
test_mksession.res \
test_mksession_utf8.res \
test_nested_function.res \
test_normal.res \
test_number.res \
@@ -94,7 +97,6 @@ NEW_TESTS ?= \
test_spell.res \
test_stat.res \
test_startup.res \
test_startup_utf8.res \
test_substitute.res \
test_syntax.res \
test_system.res \
@@ -109,6 +111,8 @@ NEW_TESTS ?= \
test_winbuf_close.res \
test_window_id.res \
test_writefile.res \
test_alot_latin.res \
test_alot_utf8.res \
test_alot.res
SCRIPTS_GUI := test16.out

View File

@@ -95,6 +95,10 @@ func RunTheTest(test)
" buffers.
%bwipe!
" The test may change the current directory. Save and restore the
" directory after executing the test.
let save_cwd = getcwd()
if exists("*SetUp")
try
call SetUp()
@@ -149,6 +153,8 @@ func RunTheTest(test)
break
endif
endwhile
exe 'cd ' . save_cwd
endfunc
func AfterTheTest()

View File

@@ -1,4 +1,4 @@
" Autoload script used by test55 and test60
" Autoload script used by test_listdict.vim, test_exists.vim and test_let.vim
let footest#x = 1
func footest#F()
return 0

View File

@@ -1,168 +0,0 @@
Tests for find completion.
STARTTEST
:set wildmode=full
:" Do all test in a separate window to avoid E211 when we recursively
:" delete the Xfind directory during cleanup
:"
:" This will cause a few errors, do it silently.
:set visualbell
:"
:" On windows a stale "Xfind" directory may exist, remove it so that
:" we start from a clean state.
:call delete("Xfind", "rf")
:new
:let cwd=getcwd()
:let test_out = cwd . '/test.out'
:call mkdir('Xfind')
:cd Xfind
:set path=
:find
:exec "w! " . test_out
:close
:new
:set path=.
:find
:exec "w >>" . test_out
:close
:new
:set path=.,,
:find
:exec "w >>" . test_out
:close
:new
:set path=./**
:find
:exec "w >>" . test_out
:close
:new
:" We shouldn't find any file at this point, test.out must be empty.
:call mkdir('in')
:cd in
:call mkdir('path')
:exec "cd " . cwd
:e Xfind/file.txt
SHoly Grail:w
:e Xfind/in/file.txt
SJimmy Hoffa:w
:e Xfind/in/stuff.txt
SAnother Holy Grail:w
:e Xfind/in/path/file.txt
SE.T.:w
:set path=Xfind/**
:find file
:exec "w >>" . test_out
:find file
:exec "w >>" . test_out
:find file
:exec "w >>" . test_out
:" Rerun the previous three find completions, using fullpath in 'path'
:exec "set path=" . cwd . "/Xfind/**"
:find file
:exec "w >>" . test_out
:find file
:exec "w >>" . test_out
:find file
:exec "w >>" . test_out
:" Same steps again, using relative and fullpath items that point to the same
:" recursive location.
:" This is to test that there are no duplicates in the completion list.
:exec "set path+=Xfind/**"
:find file
:exec "w >>" . test_out
:find file
:exec "w >>" . test_out
:find file
:exec "w >>" . test_out
:find file
:" Test find completion for directory of current buffer, which at this point
:" is Xfind/in/file.txt.
:set path=.
:find st
:exec "w >>" . test_out
:" Test find completion for empty path item ",," which is the current directory
:cd Xfind
:set path=,,
:find f
:exec "w >>" . test_out
:" Test shortening of
:"
:" foo/x/bar/voyager.txt
:" foo/y/bar/voyager.txt
:"
:" When current directory is above foo/ they should be shortened to (in order
:" of appearance):
:"
:" x/bar/voyager.txt
:" y/bar/voyager.txt
:call mkdir('foo')
:cd foo
:call mkdir('x')
:call mkdir('y')
:cd x
:call mkdir('bar')
:cd ..
:cd y
:call mkdir('bar')
:cd ..
:cd ..
:" We should now be in the Xfind directory
:e foo/x/bar/voyager.txt
SVoyager 1:w
:e foo/y/bar/voyager.txt
SVoyager 2:w
:exec "set path=" . cwd . "/Xfind/**"
:find voyager
:exec "w >>" . test_out
:find voyager
:exec "w >>" . test_out
:"
:" When current directory is .../foo/y/bar they should be shortened to (in
:" order of appearance):
:"
:" ./voyager.txt
:" x/bar/voyager.txt
:cd foo
:cd y
:cd bar
:find voyager
:exec "w >> " . test_out
:find voyager
:exec "w >> " . test_out
:" Check the opposite too:
:cd ..
:cd ..
:cd x
:cd bar
:find voyager
:exec "w >> " . test_out
:find voyager
:exec "w >> " . test_out
:" Check for correct handling of shorten_fname()'s behavior on windows
:exec "cd " . cwd . "/Xfind/in"
:find file
:exec "w >>" . test_out
:" Test for relative to current buffer 'path' item
:exec "cd " . cwd . "/Xfind/"
:set path=./path
:" Open the file where Jimmy Hoffa is found
:e in/file.txt
:" Find the file containing 'E.T.' in the Xfind/in/path directory
:find file
:exec "w >>" . test_out
:"
:" Test that completion works when path=.,,
:"
:set path=.,,
:" Open Jimmy Hoffa file
:e in/file.txt
:exec "w >>" . test_out
:" Search for the file containing Holy Grail in same directory as in/path.txt
:find stu
:exec "w >>" . test_out
:q
:exec "cd " . cwd
:call delete("Xfind", "rf")
:qa!
ENDTEST

View File

@@ -1,21 +0,0 @@
Holy Grail
Jimmy Hoffa
E.T.
Holy Grail
Jimmy Hoffa
E.T.
Holy Grail
Jimmy Hoffa
E.T.
Another Holy Grail
Holy Grail
Voyager 1
Voyager 2
Voyager 2
Voyager 1
Voyager 1
Voyager 2
Jimmy Hoffa
E.T.
Jimmy Hoffa
Another Holy Grail

View File

@@ -7,7 +7,6 @@ source test_cursor_func.vim
source test_ex_undo.vim
source test_execute_func.vim
source test_expr.vim
source test_expr_utf8.vim
source test_feedkeys.vim
source test_filter_cmd.vim
source test_filter_map.vim
@@ -28,6 +27,7 @@ source test_popup.vim
source test_recover.vim
source test_regexp_utf8.vim
source test_source_utf8.vim
source test_sha256.vim
source test_statusline.vim
source test_syn_attr.vim
source test_tabline.vim

View File

@@ -0,0 +1,10 @@
" A series of tests that can run in one Vim invocation.
" This makes testing go faster, since Vim doesn't need to restart.
" These tests use latin1 'encoding'. Setting 'encoding' is in the individual
" files, so that they can be run by themselves.
" Nvim does not allow setting 'encoding', so skip this test group.
finish
source test_regexp_latin.vim

View File

@@ -0,0 +1,17 @@
" A series of tests that can run in one Vim invocation.
" This makes testing go faster, since Vim doesn't need to restart.
" These tests use utf8 'encoding'. Setting 'encoding' is already done in
" runtest.vim. Checking for the multi_byte feature is in the individual
" files, so that they can be run by themselves.
source test_charsearch_utf8.vim
source test_expr_utf8.vim
source test_listlbr_utf8.vim
source test_matchadd_conceal_utf8.vim
source test_mksession_utf8.vim
source test_regexp_utf8.vim
source test_source_utf8.vim
source test_startup_utf8.vim
source test_utf8.vim
source test_utf8_comparisons.vim

View File

@@ -0,0 +1,22 @@
" Tests for related f{char} and t{char} using utf-8.
if !has('multi_byte')
finish
endif
" Test for t,f,F,T movement commands
function! Test_search_cmds()
new!
call setline(1, "・最初から最後まで最強のVimは最高")
1
normal! f最
call assert_equal([0, 1, 4, 0], getpos('.'))
normal! ;
call assert_equal([0, 1, 16, 0], getpos('.'))
normal! 2;
call assert_equal([0, 1, 43, 0], getpos('.'))
normal! ,
call assert_equal([0, 1, 28, 0], getpos('.'))
bw!
endfunction
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -0,0 +1,174 @@
" Tests for :[count]close! command
func Test_close_count()
enew! | only
let wids = [win_getid()]
for i in range(5)
new
call add(wids, win_getid())
endfor
4wincmd w
close!
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[5], wids[4], wids[3], wids[1], wids[0]], ids)
1close!
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[4], wids[3], wids[1], wids[0]], ids)
$close!
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[4], wids[3], wids[1]], ids)
1wincmd w
2close!
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[4], wids[1]], ids)
1wincmd w
new
call add(wids, win_getid())
new
call add(wids, win_getid())
2wincmd w
-1close!
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[6], wids[4], wids[1]], ids)
2wincmd w
+1close!
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[6], wids[4]], ids)
only!
endfunc
" Tests for :[count]hide command
func Test_hide_count()
enew! | only
let wids = [win_getid()]
for i in range(5)
new
call add(wids, win_getid())
endfor
4wincmd w
.hide
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[5], wids[4], wids[3], wids[1], wids[0]], ids)
1hide
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[4], wids[3], wids[1], wids[0]], ids)
$hide
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[4], wids[3], wids[1]], ids)
1wincmd w
2hide
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[4], wids[1]], ids)
1wincmd w
new
call add(wids, win_getid())
new
call add(wids, win_getid())
3wincmd w
-hide
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[7], wids[4], wids[1]], ids)
2wincmd w
+hide
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[7], wids[4]], ids)
only!
endfunc
" Tests for :[count]close! command with 'hidden'
func Test_hidden_close_count()
enew! | only
let wids = [win_getid()]
for i in range(5)
new
call add(wids, win_getid())
endfor
set hidden
$ hide
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[5], wids[4], wids[3], wids[2], wids[1]], ids)
$-1 close!
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[5], wids[4], wids[3], wids[1]], ids)
1wincmd w
.+close!
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[5], wids[3], wids[1]], ids)
set nohidden
only!
endfunc
" Tests for 'CTRL-W c' command to close windows.
func Test_winclose_command()
enew! | only
let wids = [win_getid()]
for i in range(5)
new
call add(wids, win_getid())
endfor
set hidden
4wincmd w
exe "normal \<C-W>c"
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[5], wids[4], wids[3], wids[1], wids[0]], ids)
exe "normal 1\<C-W>c"
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[4], wids[3], wids[1], wids[0]], ids)
exe "normal 9\<C-W>c"
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[4], wids[3], wids[1]], ids)
1wincmd w
exe "normal 2\<C-W>c"
let ids = []
windo call add(ids, win_getid())
call assert_equal([wids[4], wids[1]], ids)
set nohidden
only!
endfunc

View File

@@ -216,14 +216,16 @@ endfunc
func! Test_edit_08()
throw 'skipped: moved to test/functional/legacy/edit_spec.lua'
" reset insertmode from i_ctrl-r_=
let g:bufnr = bufnr('%')
new
call setline(1, ['abc'])
call cursor(1, 4)
call feedkeys(":set im\<cr>ZZZ\<c-r>=setbufvar(1,'&im', 0)\<cr>",'tnix')
call feedkeys(":set im\<cr>ZZZ\<c-r>=setbufvar(g:bufnr,'&im', 0)\<cr>",'tnix')
call assert_equal(['abZZZc'], getline(1,'$'))
call assert_equal([0, 1, 1, 0], getpos('.'))
call assert_false(0, '&im')
bw!
unlet g:bufnr
endfunc
func! Test_edit_09()
@@ -1308,3 +1310,16 @@ func! Test_edit_rightleft()
set norightleft
bw!
endfunc
func Test_edit_quit()
edit foo.txt
split
new
call setline(1, 'hello')
3wincmd w
redraw!
call assert_fails('1q', 'E37:')
bwipe! foo.txt
only
endfunc

View File

@@ -0,0 +1,25 @@
func Test_erasebackword()
if !has('multi_byte')
return
endif
set encoding=utf-8
enew
exe "normal o wwwこんにちわ世界ワールドvim \<C-W>"
call assert_equal(' wwwこんにちわ世界ワールド', getline('.'))
exe "normal o wwwこんにちわ世界ワールドvim \<C-W>\<C-W>"
call assert_equal(' wwwこんにちわ世界', getline('.'))
exe "normal o wwwこんにちわ世界ワールドvim \<C-W>\<C-W>\<C-W>"
call assert_equal(' wwwこんにちわ', getline('.'))
exe "normal o wwwこんにちわ世界ワールドvim \<C-W>\<C-W>\<C-W>\<C-W>"
call assert_equal(' www', getline('.'))
exe "normal o wwwこんにちわ世界ワールドvim \<C-W>\<C-W>\<C-W>\<C-W>\<C-W>"
call assert_equal(' ', getline('.'))
exe "normal o wwwこんにちわ世界ワールドvim \<C-W>\<C-W>\<C-W>\<C-W>\<C-W>\<C-W>"
call assert_equal('', getline('.'))
enew!
set encoding&
endfunc

View File

@@ -3,7 +3,7 @@ if !has('multi_byte')
finish
endif
func Test_strgetchar_utf8()
func Test_strgetchar()
call assert_equal(char2nr('á'), strgetchar('áxb', 0))
call assert_equal(char2nr('x'), strgetchar('áxb', 1))
@@ -16,7 +16,7 @@ func Test_strgetchar_utf8()
call assert_equal(char2nr('い'), strgetchar('あaい', 2))
endfunc
func Test_strcharpart_utf8()
func Test_strcharpart()
call assert_equal('áxb', strcharpart('áxb', 0))
call assert_equal('á', strcharpart('áxb', 0, 1))
call assert_equal('x', strcharpart('áxb', 1, 1))

View File

@@ -0,0 +1,157 @@
" Tests for the 'find' command completion.
" Do all the tests in a separate window to avoid E211 when we recursively
" delete the Xfind directory during cleanup
func Test_find_complete()
set belloff=all
" On windows a stale "Xfind" directory may exist, remove it so that
" we start from a clean state.
call delete("Xfind", "rf")
let cwd = getcwd()
let test_out = cwd . '/test.out'
call mkdir('Xfind')
cd Xfind
new
set path=
call assert_fails('call feedkeys(":find\t\n", "xt")', 'E345:')
close
new
set path=.
call assert_fails('call feedkeys(":find\t\n", "xt")', 'E32:')
close
new
set path=.,,
call assert_fails('call feedkeys(":find\t\n", "xt")', 'E32:')
close
new
set path=./**
call assert_fails('call feedkeys(":find\t\n", "xt")', 'E32:')
close
" We shouldn't find any file till this point
call mkdir('in/path', 'p')
exe 'cd ' . cwd
call writefile(['Holy Grail'], 'Xfind/file.txt')
call writefile(['Jimmy Hoffa'], 'Xfind/in/file.txt')
call writefile(['Another Holy Grail'], 'Xfind/in/stuff.txt')
call writefile(['E.T.'], 'Xfind/in/path/file.txt')
new
set path=Xfind/**
call feedkeys(":find file\t\n", "xt")
call assert_equal('Holy Grail', getline(1))
call feedkeys(":find file\t\t\n", "xt")
call assert_equal('Jimmy Hoffa', getline(1))
call feedkeys(":find file\t\t\t\n", "xt")
call assert_equal('E.T.', getline(1))
" Rerun the previous three find completions, using fullpath in 'path'
exec "set path=" . cwd . "/Xfind/**"
call feedkeys(":find file\t\n", "xt")
call assert_equal('Holy Grail', getline(1))
call feedkeys(":find file\t\t\n", "xt")
call assert_equal('Jimmy Hoffa', getline(1))
call feedkeys(":find file\t\t\t\n", "xt")
call assert_equal('E.T.', getline(1))
" Same steps again, using relative and fullpath items that point to the same
" recursive location.
" This is to test that there are no duplicates in the completion list.
set path+=Xfind/**
call feedkeys(":find file\t\n", "xt")
call assert_equal('Holy Grail', getline(1))
call feedkeys(":find file\t\t\n", "xt")
call assert_equal('Jimmy Hoffa', getline(1))
call feedkeys(":find file\t\t\t\n", "xt")
call assert_equal('E.T.', getline(1))
call feedkeys(":find file\t\t\n", "xt")
" Test find completion for directory of current buffer, which at this point
" is Xfind/in/file.txt.
set path=.
call feedkeys(":find st\t\n", "xt")
call assert_equal('Another Holy Grail', getline(1))
" Test find completion for empty path item ",," which is the current
" directory
cd Xfind
set path=,,
call feedkeys(":find f\t\n", "xt")
call assert_equal('Holy Grail', getline(1))
" Test shortening of
"
" foo/x/bar/voyager.txt
" foo/y/bar/voyager.txt
"
" When current directory is above foo/ they should be shortened to (in order
" of appearance):
"
" x/bar/voyager.txt
" y/bar/voyager.txt
call mkdir('foo/x/bar', 'p')
call mkdir('foo/y/bar', 'p')
call writefile(['Voyager 1'], 'foo/x/bar/voyager.txt')
call writefile(['Voyager 2'], 'foo/y/bar/voyager.txt')
exec "set path=" . cwd . "/Xfind/**"
call feedkeys(":find voyager\t\n", "xt")
call assert_equal('Voyager 1', getline(1))
call feedkeys(":find voyager\t\t\n", "xt")
call assert_equal('Voyager 2', getline(1))
"
" When current directory is .../foo/y/bar they should be shortened to (in
" order of appearance):
"
" ./voyager.txt
" x/bar/voyager.txt
cd foo/y/bar
call feedkeys(":find voyager\t\n", "xt")
call assert_equal('Voyager 2', getline(1))
call feedkeys(":find voyager\t\t\n", "xt")
call assert_equal('Voyager 1', getline(1))
" Check the opposite too:
cd ../../x/bar
call feedkeys(":find voyager\t\n", "xt")
call assert_equal('Voyager 1', getline(1))
call feedkeys(":find voyager\t\t\n", "xt")
call assert_equal('Voyager 2', getline(1))
" Check for correct handling of shorten_fname()'s behavior on windows
exec "cd " . cwd . "/Xfind/in"
call feedkeys(":find file\t\n", "xt")
call assert_equal('Jimmy Hoffa', getline(1))
" Test for relative to current buffer 'path' item
exec "cd " . cwd . "/Xfind/"
set path=./path
" Open the file where Jimmy Hoffa is found
e in/file.txt
" Find the file containing 'E.T.' in the Xfind/in/path directory
call feedkeys(":find file\t\n", "xt")
call assert_equal('E.T.', getline(1))
" Test that completion works when path=.,,
set path=.,,
" Open Jimmy Hoffa file
e in/file.txt
call assert_equal('Jimmy Hoffa', getline(1))
" Search for the file containing Holy Grail in same directory as in/path.txt
call feedkeys(":find stu\t\n", "xt")
call assert_equal('Another Holy Grail', getline(1))
enew | only
exe 'cd ' . cwd
call delete('Xfind', 'rf')
set path&
endfunc

View File

@@ -0,0 +1,48 @@
" Tests for 'fixeol' and 'eol'
func Test_fixeol()
" first write two test files with and without trailing EOL
" use Unix fileformat for consistency
set ff=unix
enew!
call setline('.', 'with eol')
w! XXEol
enew!
set noeol nofixeol
call setline('.', 'without eol')
w! XXNoEol
set eol fixeol
bwipe XXEol XXNoEol
" try editing files with 'fixeol' disabled
e! XXEol
normal ostays eol
set nofixeol
w! XXTestEol
e! XXNoEol
normal ostays without
set nofixeol
w! XXTestNoEol
bwipe! XXEol XXNoEol XXTestEol XXTestNoEol
set fixeol
" Append "END" to each file so that we can see what the last written char
" was.
normal ggdGaEND
w >>XXEol
w >>XXNoEol
w >>XXTestEol
w >>XXTestNoEol
call assert_equal(['with eol', 'END'], readfile('XXEol'))
call assert_equal(['without eolEND'], readfile('XXNoEol'))
call assert_equal(['with eol', 'stays eol', 'END'], readfile('XXTestEol'))
call assert_equal(['without eol', 'stays withoutEND'],
\ readfile('XXTestNoEol'))
call delete('XXEol')
call delete('XXNoEol')
call delete('XXTestEol')
call delete('XXTestNoEol')
set ff& fixeol& eol&
enew!
endfunc

View File

@@ -360,3 +360,24 @@ func! Test_move_folds_around_indent()
call assert_equal([0, 1, 1, 1, 1, 0, 0, 0, 1, 1], map(range(1, line('$')), 'foldlevel(v:val)'))
bw!
endfunc
" test for patch 7.3.637
" Cannot catch the error caused by a foldopen when there is no fold.
func Test_foldopen_exception()
enew!
let a = 'No error caught'
try
foldopen
catch
let a = matchstr(v:exception,'^[^ ]*')
endtry
call assert_equal('Vim(foldopen):E490:', a)
let a = 'No error caught'
try
foobar
catch
let a = matchstr(v:exception,'^[^ ]*')
endtry
call assert_match('E492:', a)
endfunc

View File

@@ -2,6 +2,11 @@
" Test for insert expansion
func Test_ins_complete()
edit test_ins_complete.vim
" The files in the current directory interferes with the files
" used by this test. So use a separate directory for the test.
call mkdir('Xdir')
cd Xdir
set ff=unix
call writefile(["test11\t36Gepeto\t/Tag/",
\ "asd\ttest11file\t36G",
@@ -89,4 +94,6 @@ func Test_ins_complete()
call delete('Xtest11.two')
call delete('Xtestdata')
set cpt& cot& def& tags& tagbsearch& hidden&
cd ..
call delete('Xdir', 'rf')
endfunc

View File

@@ -0,0 +1,63 @@
" Tests for 'listchars' display with 'list' and :list
source view_util.vim
func Test_listchars()
enew!
set ff=unix
set list
set listchars+=tab:>-,space:.,trail:<
call append(0, [
\ ' aa ',
\ ' bb ',
\ ' cccc ',
\ 'dd ee ',
\ ' '
\ ])
let expected = [
\ '>-------aa>-----$',
\ '..bb>---<<$',
\ '...cccc><$',
\ 'dd........ee<<>-$',
\ '<$'
\ ]
redraw!
for i in range(1, 5)
call cursor(i, 1)
call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
endfor
set listchars-=trail:<
let expected = [
\ '>-------aa>-----$',
\ '..bb>---..$',
\ '...cccc>.$',
\ 'dd........ee..>-$',
\ '.$'
\ ]
redraw!
for i in range(1, 5)
call cursor(i, 1)
call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
endfor
set listchars+=trail:<
set nolist
normal ggdG
call append(0, [
\ ' fff ',
\ ' gg ',
\ ' h ',
\ 'iii ',
\ ])
let l = split(execute("%list"), "\n")
call assert_equal([
\ '..fff>--<<$',
\ '>-------gg>-----$',
\ '.....h>-$',
\ 'iii<<<<><<$', '$'], l)
enew!
set listchars& ff&
endfunc

View File

@@ -0,0 +1,603 @@
" Tests for the List and Dict types
func TearDown()
" Run garbage collection after every test
call test_garbagecollect_now()
endfunc
" Tests for List type
" List creation
func Test_list_create()
" Creating List directly with different types
let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},]
call assert_equal("[1, 'as''d', [1, 2, function('strlen')], {'a': 1}]", string(l))
call assert_equal({'a' : 1}, l[-1])
call assert_equal(1, l[-4])
let x = 10
try
let x = l[-5]
catch
call assert_match('E684:', v:exception)
endtry
call assert_equal(10, x)
endfunc
" List slices
func Test_list_slice()
let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},]
call assert_equal([1, 'as''d', [1, 2, function('strlen')], {'a': 1}], l[:])
call assert_equal(['as''d', [1, 2, function('strlen')], {'a': 1}], l[1:])
call assert_equal([1, 'as''d', [1, 2, function('strlen')]], l[:-2])
call assert_equal([1, 'as''d', [1, 2, function('strlen')], {'a': 1}], l[0:8])
call assert_equal([], l[8:-1])
endfunc
" List identity
func Test_list_identity()
let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},]
let ll = l
let lx = copy(l)
call assert_true(l == ll)
call assert_false(l isnot ll)
call assert_true(l is ll)
call assert_true(l == lx)
call assert_false(l is lx)
call assert_true(l isnot lx)
endfunc
" removing items with :unlet
func Test_list_unlet()
let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},]
unlet l[2]
call assert_equal([1, 'as''d', {'a': 1}], l)
let l = range(8)
unlet l[:3]
unlet l[1:]
call assert_equal([4], l)
" removing items out of range: silently skip items that don't exist
let l = [0, 1, 2, 3]
call assert_fails('unlet l[2:1]', 'E684')
let l = [0, 1, 2, 3]
unlet l[2:2]
call assert_equal([0, 1, 3], l)
let l = [0, 1, 2, 3]
unlet l[2:3]
call assert_equal([0, 1], l)
let l = [0, 1, 2, 3]
unlet l[2:4]
call assert_equal([0, 1], l)
let l = [0, 1, 2, 3]
unlet l[2:5]
call assert_equal([0, 1], l)
let l = [0, 1, 2, 3]
call assert_fails('unlet l[-1:2]', 'E684')
let l = [0, 1, 2, 3]
unlet l[-2:2]
call assert_equal([0, 1, 3], l)
let l = [0, 1, 2, 3]
unlet l[-3:2]
call assert_equal([0, 3], l)
let l = [0, 1, 2, 3]
unlet l[-4:2]
call assert_equal([3], l)
let l = [0, 1, 2, 3]
unlet l[-5:2]
call assert_equal([3], l)
let l = [0, 1, 2, 3]
unlet l[-6:2]
call assert_equal([3], l)
endfunc
" assignment to a list
func Test_list_assign()
let l = [0, 1, 2, 3]
let [va, vb] = l[2:3]
call assert_equal([2, 3], [va, vb])
call assert_fails('let [va, vb] = l', 'E687')
call assert_fails('let [va, vb] = l[1:1]', 'E688')
endfunc
" test for range assign
func Test_list_range_assign()
let l = [0]
let l[:] = [1, 2]
call assert_equal([1, 2], l)
endfunc
" Tests for Dictionary type
func Test_dict()
" Creating Dictionary directly with different types
let d = {001: 'asd', 'b': [1, 2, function('strlen')], -1: {'a': 1},}
call assert_equal("{'1': 'asd', 'b': [1, 2, function('strlen')], '-1': {'a': 1}}", string(d))
call assert_equal('asd', d.1)
call assert_equal(['-1', '1', 'b'], sort(keys(d)))
call assert_equal(['asd', [1, 2, function('strlen')], {'a': 1}], values(d))
let v = []
for [key, val] in items(d)
call extend(v, [key, val])
unlet key val
endfor
call assert_equal(['1','asd','b',[1, 2, function('strlen')],'-1',{'a': 1}], v)
call extend(d, {3:33, 1:99})
call extend(d, {'b':'bbb', 'c':'ccc'}, "keep")
call assert_fails("call extend(d, {3:333,4:444}, 'error')", 'E737')
call assert_equal({'c': 'ccc', '1': 99, 'b': [1, 2, function('strlen')], '3': 33, '-1': {'a': 1}}, d)
call filter(d, 'v:key =~ ''[ac391]''')
call assert_equal({'c': 'ccc', '1': 99, '3': 33, '-1': {'a': 1}}, d)
endfunc
" Dictionary identity
func Test_dict_identity()
let d = {001: 'asd', 'b': [1, 2, function('strlen')], -1: {'a': 1},}
let dd = d
let dx = copy(d)
call assert_true(d == dd)
call assert_false(d isnot dd)
call assert_true(d is dd)
call assert_true(d == dx)
call assert_false(d is dx)
call assert_true(d isnot dx)
endfunc
" removing items with :unlet
func Test_dict_unlet()
let d = {'b':'bbb', '1': 99, '3': 33, '-1': {'a': 1}}
unlet d.b
unlet d[-1]
call assert_equal({'1': 99, '3': 33}, d)
endfunc
" manipulating a big Dictionary (hashtable.c has a border of 1000 entries)
func Test_dict_big()
let d = {}
for i in range(1500)
let d[i] = 3000 - i
endfor
call assert_equal([3000, 2900, 2001, 1600, 1501], [d[0], d[100], d[999], d[1400], d[1499]])
let str = ''
try
let n = d[1500]
catch
let str=substitute(v:exception, '\v(.{14}).*( \d{4}).*', '\1\2', '')
endtry
call assert_equal('Vim(let):E716: 1500', str)
" lookup each items
for i in range(1500)
call assert_equal(3000 - i, d[i])
endfor
let i += 1
" delete even items
while i >= 2
let i -= 2
unlet d[i]
endwhile
call assert_equal('NONE', get(d, 1500 - 100, 'NONE'))
call assert_equal(2999, d[1])
" delete odd items, checking value, one intentionally wrong
let d[33] = 999
let i = 1
while i < 1500
if i != 33
call assert_equal(3000 - i, d[i])
else
call assert_equal(999, d[i])
endif
unlet d[i]
let i += 2
endwhile
call assert_equal({}, d)
unlet d
endfunc
" Dictionary function
func Test_dict_func()
let d = {}
func d.func(a) dict
return a:a . len(self.data)
endfunc
let d.data = [1,2,3]
call assert_equal('len: 3', d.func('len: '))
let x = d.func('again: ')
call assert_equal('again: 3', x)
let Fn = d.func
call assert_equal('xxx3', Fn('xxx'))
endfunc
" Function in script-local List or Dict
func Test_script_local_dict_func()
let g:dict = {}
function g:dict.func() dict
return 'g:dict.func' . self.foo[1] . self.foo[0]('asdf')
endfunc
let g:dict.foo = ['-', 2, 3]
call insert(g:dict.foo, function('strlen'))
call assert_equal('g:dict.func-4', g:dict.func())
unlet g:dict
endfunc
" Nasty: remove func from Dict that's being called (works)
func Test_dict_func_remove_in_use()
let d = {1:1}
func d.func(a)
return "a:" . a:a
endfunc
let expected = 'a:' . string(get(d, 'func'))
call assert_equal(expected, d.func(string(remove(d, 'func'))))
endfunc
" Nasty: deepcopy() dict that refers to itself (fails when noref used)
func Test_dict_deepcopy()
let d = {1:1, 2:2}
let l = [4, d, 6]
let d[3] = l
let dc = deepcopy(d)
call assert_fails('call deepcopy(d, 1)', 'E698')
let l2 = [0, l, l, 3]
let l[1] = l2
let l3 = deepcopy(l2)
call assert_true(l3[1] is l3[2])
endfunc
" Locked variables
func Test_list_locked_var()
let expected = [
\ [['0000-000', 'ppppppp'],
\ ['0000-000', 'ppppppp'],
\ ['0000-000', 'ppppppp']],
\ [['1000-000', 'ppppppF'],
\ ['0000-000', 'ppppppp'],
\ ['0000-000', 'ppppppp']],
\ [['1100-100', 'ppFppFF'],
\ ['0000-000', 'ppppppp'],
\ ['0000-000', 'ppppppp']],
\ [['1110-110', 'pFFpFFF'],
\ ['0010-010', 'pFppFpp'],
\ ['0000-000', 'ppppppp']],
\ [['1111-111', 'FFFFFFF'],
\ ['0011-011', 'FFpFFpp'],
\ ['0000-000', 'ppppppp']]
\ ]
for depth in range(5)
for u in range(3)
unlet! l
let l = [0, [1, [2, 3]], {4: 5, 6: {7: 8}}]
exe "lockvar " . depth . " l"
if u == 1
exe "unlockvar l"
elseif u == 2
exe "unlockvar " . depth . " l"
endif
let ps = islocked("l").islocked("l[1]").islocked("l[1][1]").islocked("l[1][1][0]").'-'.islocked("l[2]").islocked("l[2]['6']").islocked("l[2]['6'][7]")
call assert_equal(expected[depth][u][0], ps)
let ps = ''
try
let l[1][1][0] = 99
let ps .= 'p'
catch
let ps .= 'F'
endtry
try
let l[1][1] = [99]
let ps .= 'p'
catch
let ps .= 'F'
endtry
try
let l[1] = [99]
let ps .= 'p'
catch
let ps .= 'F'
endtry
try
let l[2]['6'][7] = 99
let ps .= 'p'
catch
let ps .= 'F'
endtry
try
let l[2][6] = {99: 99}
let ps .= 'p'
catch
let ps .= 'F'
endtry
try
let l[2] = {99: 99}
let ps .= 'p'
catch
let ps .= 'F'
endtry
try
let l = [99]
let ps .= 'p'
catch
let ps .= 'F'
endtry
call assert_equal(expected[depth][u][1], ps)
endfor
endfor
endfunc
" Unletting locked variables
func Test_list_locked_var_unlet()
let expected = [
\ [['0000-000', 'ppppppp'],
\ ['0000-000', 'ppppppp'],
\ ['0000-000', 'ppppppp']],
\ [['1000-000', 'ppFppFp'],
\ ['0000-000', 'ppppppp'],
\ ['0000-000', 'ppppppp']],
\ [['1100-100', 'pFFpFFp'],
\ ['0000-000', 'ppppppp'],
\ ['0000-000', 'ppppppp']],
\ [['1110-110', 'FFFFFFp'],
\ ['0010-010', 'FppFppp'],
\ ['0000-000', 'ppppppp']],
\ [['1111-111', 'FFFFFFp'],
\ ['0011-011', 'FppFppp'],
\ ['0000-000', 'ppppppp']]
\ ]
for depth in range(5)
for u in range(3)
unlet! l
let l = [0, [1, [2, 3]], {4: 5, 6: {7: 8}}]
exe "lockvar " . depth . " l"
if u == 1
exe "unlockvar l"
elseif u == 2
exe "unlockvar " . depth . " l"
endif
let ps = islocked("l").islocked("l[1]").islocked("l[1][1]").islocked("l[1][1][0]").'-'.islocked("l[2]").islocked("l[2]['6']").islocked("l[2]['6'][7]")
call assert_equal(expected[depth][u][0], ps)
let ps = ''
try
unlet l[2]['6'][7]
let ps .= 'p'
catch
let ps .= 'F'
endtry
try
unlet l[2][6]
let ps .= 'p'
catch
let ps .= 'F'
endtry
try
unlet l[2]
let ps .= 'p'
catch
let ps .= 'F'
endtry
try
unlet l[1][1][0]
let ps .= 'p'
catch
let ps .= 'F'
endtry
try
unlet l[1][1]
let ps .= 'p'
catch
let ps .= 'F'
endtry
try
unlet l[1]
let ps .= 'p'
catch
let ps .= 'F'
endtry
try
unlet l
let ps .= 'p'
catch
let ps .= 'F'
endtry
call assert_equal(expected[depth][u][1], ps)
endfor
endfor
endfunc
" Locked variables and :unlet or list / dict functions
" No :unlet after lock on dict:
func Test_dict_lock_unlet()
unlet! d
let d = {'a': 99, 'b': 100}
lockvar 1 d
call assert_fails('unlet d.a', 'E741')
endfunc
" unlet after lock on dict item
func Test_dict_item_lock_unlet()
unlet! d
let d = {'a': 99, 'b': 100}
lockvar d.a
unlet d.a
call assert_equal({'b' : 100}, d)
endfunc
" filter() after lock on dict item
func Test_dict_lock_filter()
unlet! d
let d = {'a': 99, 'b': 100}
lockvar d.a
call filter(d, 'v:key != "a"')
call assert_equal({'b' : 100}, d)
endfunc
" map() after lock on dict
func Test_dict_lock_map()
unlet! d
let d = {'a': 99, 'b': 100}
lockvar 1 d
call map(d, 'v:val + 200')
call assert_equal({'a' : 299, 'b' : 300}, d)
endfunc
" No extend() after lock on dict item
func Test_dict_lock_extend()
unlet! d
let d = {'a': 99, 'b': 100}
lockvar d.a
call assert_fails("call extend(d, {'a' : 123})", 'E741')
call assert_equal({'a': 99, 'b': 100}, d)
endfunc
" No remove() of write-protected scope-level variable
func! Tfunc(this_is_a_long_parameter_name)
call assert_fails("call remove(a:, 'this_is_a_long_parameter_name')", 'E795')
endfun
func Test_dict_scope_var_remove()
call Tfunc('testval')
endfunc
" No extend() of write-protected scope-level variable
func! Tfunc(this_is_a_long_parameter_name)
call assert_fails("call extend(a:, {'this_is_a_long_parameter_name': 1234})", 'E742')
endfunc
func Test_dict_scope_var_extend()
call Tfunc('testval')
endfunc
" No :unlet of variable in locked scope
func Test_lock_var_unlet()
let b:testvar = 123
lockvar 1 b:
call assert_fails('unlet b:testvar', 'E741:')
unlockvar 1 b:
unlet! b:testvar
endfunc
" No :let += of locked list variable
func Test_let_lock_list()
let l = ['a', 'b', 3]
lockvar 1 l
call assert_fails("let l += ['x']", 'E741:')
call assert_equal(['a', 'b', 3], l)
unlet l
let l = [1, 2, 3, 4]
lockvar! l
call assert_equal([1, 2, 3, 4], l)
unlockvar l[1]
call assert_fails('unlet l[0:1]', 'E741:')
call assert_equal([1, 2, 3, 4], l)
call assert_fails('unlet l[1:2]', 'E741:')
call assert_equal([1, 2, 3, 4], l)
unlockvar l[1]
call assert_fails('let l[0:1] = [0, 1]', 'E741:')
call assert_equal([1, 2, 3, 4], l)
call assert_fails('let l[1:2] = [0, 1]', 'E741:')
call assert_equal([1, 2, 3, 4], l)
unlet l
endfunc
" lockvar/islocked() triggering script autoloading
func Test_lockvar_script_autoload()
let old_rtp = &rtp
set rtp+=./sautest
lockvar g:footest#x
unlockvar g:footest#x
call assert_equal(-1, islocked('g:footest#x'))
call assert_equal(0, exists('g:footest#x'))
call assert_equal(1, g:footest#x)
let &rtp = old_rtp
endfunc
" a:000 function argument test
func s:arg_list_test(...)
call assert_fails('let a:000 = [1, 2]', 'E46:')
call assert_fails('let a:000[0] = 9', 'E742:')
call assert_fails('let a:000[2] = [9, 10]', 'E742:')
call assert_fails('let a:000[3] = {9 : 10}', 'E742:')
" now the tests that should pass
let a:000[2][1] = 9
call extend(a:000[2], [5, 6])
let a:000[3][5] = 8
let a:000[3]['a'] = 12
call assert_equal([1, 2, [3, 9, 5, 6], {'a': 12, '5': 8}], a:000)
endfunc
func Test_func_arg_list()
call s:arg_list_test(1, 2, [3, 4], {5: 6})
endfunc
" Tests for reverse(), sort(), uniq()
func Test_reverse_sort_uniq()
let l = ['-0', 'A11', 2, 2, 'xaaa', 4, 'foo', 'foo6', 'foo', [0, 1, 2], 'x8', [0, 1, 2], 1.5]
call assert_equal(['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', 'foo', [0, 1, 2], 'x8', [0, 1, 2], 1.5], uniq(copy(l)))
call assert_equal([1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2, 'A11', '-0'], reverse(l))
call assert_equal([1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2, 'A11', '-0'], reverse(reverse(l)))
call assert_equal(['-0', 'A11', 'foo', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 2, 4, [0, 1, 2], [0, 1, 2]], sort(l))
call assert_equal([[0, 1, 2], [0, 1, 2], 4, 2, 2, 1.5, 'xaaa', 'x8', 'foo6', 'foo', 'foo', 'A11', '-0'], reverse(sort(l)))
call assert_equal(['-0', 'A11', 'foo', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 2, 4, [0, 1, 2], [0, 1, 2]], sort(reverse(sort(l))))
call assert_equal(['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 4, [0, 1, 2]], uniq(sort(l)))
let l=[7, 9, 'one', 18, 12, 22, 'two', 10.0e-16, -1, 'three', 0xff, 0.22, 'four']
call assert_equal([-1, 'one', 'two', 'three', 'four', 1.0e-15, 0.22, 7, 9, 12, 18, 22, 255], sort(copy(l), 'n'))
let l=[7, 9, 18, 12, 22, 10.0e-16, -1, 0xff, 0, -0, 0.22, 'bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', {}, []]
call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 1))
call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 'i'))
call assert_equal(['BAR', 'Bar', 'FOO', 'FOOBAR', 'Foo', 'bar', 'foo', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l)))
endfunc
" splitting a string to a List
func Test_str_split()
call assert_equal(['aa', 'bb'], split(' aa bb '))
call assert_equal(['aa', 'bb'], split(' aa bb ', '\W\+', 0))
call assert_equal(['', 'aa', 'bb', ''], split(' aa bb ', '\W\+', 1))
call assert_equal(['', '', 'aa', '', 'bb', '', ''], split(' aa bb ', '\W', 1))
call assert_equal(['aa', '', 'bb'], split(':aa::bb:', ':', 0))
call assert_equal(['', 'aa', '', 'bb', ''], split(':aa::bb:', ':', 1))
call assert_equal(['aa', '', 'bb', 'cc', ''], split('aa,,bb, cc,', ',\s*', 1))
call assert_equal(['a', 'b', 'c'], split('abc', '\zs'))
call assert_equal(['', 'a', '', 'b', '', 'c', ''], split('abc', '\zs', 1))
endfunc
" compare recursively linked list and dict
func Test_listdict_compare()
let l = [1, 2, 3, 4]
let d = {'1': 1, '2': l, '3': 3}
let l[1] = d
call assert_true(l == l)
call assert_true(d == d)
call assert_false(l != deepcopy(l))
call assert_false(d != deepcopy(d))
endfunc
" compare complex recursively linked list and dict
func Test_listdict_compare_complex()
let l = []
call add(l, l)
let dict4 = {"l": l}
call add(dict4.l, dict4)
let lcopy = deepcopy(l)
let dict4copy = deepcopy(dict4)
call assert_true(l == lcopy)
call assert_true(dict4 == dict4copy)
endfunc
func Test_listdict_extend()
" Pass the same List to extend()
let l = [1, 2, 3, 4, 5]
call extend(l, l)
call assert_equal([1, 2, 3, 4, 5, 1, 2, 3, 4, 5], l)
" Pass the same Dict to extend()
let d = { 'a': {'b': 'B'}}
call extend(d, d)
call assert_equal({'a': {'b': 'B'}}, d)
" Pass the same Dict to extend() with "error"
call assert_fails("call extend(d, d, 'error')", 'E737:')
call assert_equal({'a': {'b': 'B'}}, d)
endfunc

View File

@@ -1,5 +1,8 @@
" Test for linebreak and list option (non-utf8)
" Nvim does not allow setting 'encoding', so skip this test.
finish
set encoding=latin1
scriptencoding latin1

View File

@@ -99,6 +99,7 @@ func Test_mksession_utf8()
call delete('test_mks.out')
call delete(tmpfile)
let &wrap = wrap_save
set sessionoptions& splitbelow& fileencoding&
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -2337,3 +2337,45 @@ func! Test_normal54_Ctrl_bsl()
" clean up
bw!
endfunc
" Test for the gr (virtual replace) command
" Test for the bug fixed by 7.4.387
func Test_gr_command()
enew!
let save_cpo = &cpo
call append(0, ['First line', 'Second line', 'Third line'])
exe "normal i\<C-G>u"
call cursor(2, 1)
set cpo-=X
normal 4gro
call assert_equal('oooond line', getline(2))
undo
set cpo+=X
normal 4gro
call assert_equal('ooooecond line', getline(2))
let &cpo = save_cpo
enew!
endfunc
" When splitting a window the changelist position is wrong.
" Test the changelist position after splitting a window.
" Test for the bug fixed by 7.4.386
func Test_changelist()
let save_ul = &ul
enew!
call append('$', ['1', '2'])
exe "normal i\<C-G>u"
exe "normal Gkylpa\<C-G>u"
set ul=100
exe "normal Gylpa\<C-G>u"
set ul=100
normal gg
vsplit
normal g;
call assert_equal([3, 2], [line('.'), col('.')])
normal g;
call assert_equal([2, 2], [line('.'), col('.')])
call assert_fails('normal g;', 'E662:')
%bwipe!
let &ul = save_ul
endfunc

View File

@@ -590,7 +590,8 @@ func Test_popup_and_preview_autocommand()
call setline(2, ' os.')
$
call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<C-N>\<enter>\<esc>", 'tx')
call assert_equal(["import os", " os.EX_IOERR", ''], getline(1,'$'))
call assert_equal("import os", getline(1))
call assert_match(' os.\(EX_IOERR\|O_CREAT\)$', getline(2))
call assert_equal(1, winnr('$'))
" previewwindow option is not set
call assert_equal(0, &previewwindow)

View File

@@ -0,0 +1,32 @@
" Tests for regexp in latin1 encoding
set encoding=latin1
scriptencoding latin1
func s:equivalence_test()
let str = "A<><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD> B C D E<><45><EFBFBD><EFBFBD> F G H I<><49><EFBFBD><EFBFBD> J K L M N<> O<><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD> P Q R S T U<><55><EFBFBD><EFBFBD> V W X Y<> Z a<><61><EFBFBD><EFBFBD><EFBFBD><EFBFBD> b c d e<><65><EFBFBD><EFBFBD> f g h i<><69><EFBFBD><EFBFBD> j k l m n<> o<><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD> p q r s t u<><75><EFBFBD><EFBFBD> v w x y<><79> z"
let groups = split(str)
for group1 in groups
for c in split(group1, '\zs')
" next statement confirms that equivalence class matches every
" character in group
call assert_match('^[[=' . c . '=]]*$', group1)
for group2 in groups
if group2 != group1
" next statement converts that equivalence class doesn't match
" a character in any other group
call assert_equal(-1, match(group2, '[[=' . c . '=]]'))
endif
endfor
endfor
endfor
endfunc
func Test_equivalence_re1()
set re=1
call s:equivalence_test()
endfunc
func Test_equivalence_re2()
set re=2
call s:equivalence_test()
endfunc

View File

@@ -438,3 +438,18 @@ func Test_search_regexp()
set undolevels&
enew!
endfunc
" Test for search('multi-byte char', 'bce')
func Test_search_multibyte()
if !has('multi_byte')
return
endif
let save_enc = &encoding
set encoding=utf8
enew!
call append('$', '')
call cursor(2, 1)
call assert_equal(2, search('', 'bce', line('.')))
enew!
let &encoding = save_enc
endfunc

View File

@@ -0,0 +1,22 @@
" Tests for the sha256() function.
if !has('cryptv') || !exists('*sha256')
finish
endif
function Test_sha256()
" test for empty string:
call assert_equal(sha256(""), 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855')
"'test for 1 char:
call assert_equal(sha256("a"), 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb')
"
"test for 3 chars:
call assert_equal(sha256("abc"), 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad')
" test for contains meta char:
call assert_equal(sha256("foo\nbar"), '807eff6267f3f926a21d234f7b0cf867a86f47e07a532f15e8cc39ed110ca776')
" test for contains non-ascii char:
call assert_equal(sha256("\xde\xad\xbe\xef"), '5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953')
endfunction

View File

@@ -0,0 +1,168 @@
" Tests for the various 'formatoptions' settings
func Test_text_format()
enew!
setl noai tw=2 fo=t
call append('$', [
\ '{',
\ ' ',
\ '',
\ '}'])
exe "normal /^{/+1\n0"
normal gRa b
let lnum = line('.')
call assert_equal([
\ 'a',
\ 'b'], getline(lnum - 1, lnum))
normal ggdG
setl ai tw=2 fo=tw
call append('$', [
\ '{',
\ 'a b ',
\ '',
\ 'a ',
\ '}'])
exe "normal /^{/+1\n0"
normal gqgqjjllab
let lnum = line('.')
call assert_equal([
\ 'a ',
\ 'b ',
\ '',
\ 'a ',
\ 'b'], getline(lnum - 4, lnum))
normal ggdG
setl tw=3 fo=t
call append('$', [
\ '{',
\ "a \<C-A>",
\ '}'])
exe "normal /^{/+1\n0"
exe "normal gqgqo\na \<C-V>\<C-A>"
let lnum = line('.')
call assert_equal([
\ 'a',
\ "\<C-A>",
\ '',
\ 'a',
\ "\<C-A>"], getline(lnum - 4, lnum))
normal ggdG
setl tw=2 fo=tcq1 comments=:#
call append('$', [
\ '{',
\ 'a b',
\ '#a b',
\ '}'])
exe "normal /^{/+1\n0"
exe "normal gqgqjgqgqo\na b\n#a b"
let lnum = line('.')
call assert_equal([
\ 'a b',
\ '#a b',
\ '',
\ 'a b',
\ '#a b'], getline(lnum - 4, lnum))
normal ggdG
setl tw=5 fo=tcn comments=:#
call append('$', [
\ '{',
\ ' 1 a',
\ '# 1 a',
\ '}'])
exe "normal /^{/+1\n0"
exe "normal A b\<Esc>jA b"
let lnum = line('.')
call assert_equal([
\ ' 1 a',
\ ' b',
\ '# 1 a',
\ '# b'], getline(lnum - 3, lnum))
normal ggdG
setl tw=5 fo=t2a si
call append('$', [
\ '{',
\ '',
\ ' x a',
\ ' b',
\ ' c',
\ '',
\ '}'])
exe "normal /^{/+3\n0"
exe "normal i \<Esc>A_"
let lnum = line('.')
call assert_equal([
\ '',
\ ' x a',
\ ' b_',
\ ' c',
\ ''], getline(lnum - 2, lnum + 2))
normal ggdG
setl tw=5 fo=qn comments=:#
call append('$', [
\ '{',
\ '# 1 a b',
\ '}'])
exe "normal /^{/+1\n5|"
normal gwap
call assert_equal(5, col('.'))
let lnum = line('.')
call assert_equal([
\ '# 1 a',
\ '# b'], getline(lnum, lnum + 1))
normal ggdG
setl tw=5 fo=q2 comments=:#
call append('$', [
\ '{',
\ '# x',
\ '# a b',
\ '}'])
exe "normal /^{/+1\n0"
normal gwap
let lnum = line('.')
call assert_equal([
\ '# x a',
\ '# b'], getline(lnum, lnum + 1))
normal ggdG
setl tw& fo=a
call append('$', [
\ '{',
\ ' 1aa',
\ ' 2bb',
\ '}'])
exe "normal /^{/+2\n0"
normal I^^
call assert_equal('{ 1aa ^^2bb }', getline('.'))
normal ggdG
setl tw=20 fo=an12wcq comments=s1:/*,mb:*,ex:*/
call append('$', [
\ '/* abc def ghi jkl ',
\ ' * mno pqr stu',
\ ' */'])
exe "normal /mno pqr/\n"
normal A vwx yz
let lnum = line('.')
call assert_equal([
\ ' * mno pqr stu ',
\ ' * vwx yz',
\ ' */'], getline(lnum - 1, lnum + 1))
normal ggdG
setl tw=12 fo=tqnc comments=:#
call setline('.', '# 1 xxxxx')
normal A foobar
call assert_equal([
\ '# 1 xxxxx',
\ '# foobar'], getline(1, 2))
setl ai& tw& fo& si& comments&
enew!
endfunc

View File

@@ -0,0 +1,95 @@
" Tests for case-insensitive UTF-8 comparisons (utf_strnicmp() in mbyte.c)
" Also test "g~ap".
if !has("multi_byte")
finish
endif
function! Ch(a, op, b, expected)
call assert_equal(eval(printf('"%s" %s "%s"', a:a, a:op, a:b)), a:expected,
\ printf('"%s" %s "%s" should return %d', a:a, a:op, a:b, a:expected))
endfunction
function! Chk(a, b, result)
if a:result == 0
call Ch(a:a, '==?', a:b, 1)
call Ch(a:a, '!=?', a:b, 0)
call Ch(a:a, '<=?', a:b, 1)
call Ch(a:a, '>=?', a:b, 1)
call Ch(a:a, '<?', a:b, 0)
call Ch(a:a, '>?', a:b, 0)
elseif a:result > 0
call Ch(a:a, '==?', a:b, 0)
call Ch(a:a, '!=?', a:b, 1)
call Ch(a:a, '<=?', a:b, 0)
call Ch(a:a, '>=?', a:b, 1)
call Ch(a:a, '<?', a:b, 0)
call Ch(a:a, '>?', a:b, 1)
else
call Ch(a:a, '==?', a:b, 0)
call Ch(a:a, '!=?', a:b, 1)
call Ch(a:a, '<=?', a:b, 1)
call Ch(a:a, '>=?', a:b, 0)
call Ch(a:a, '<?', a:b, 1)
call Ch(a:a, '>?', a:b, 0)
endif
endfunction
function! Check(a, b, result)
call Chk(a:a, a:b, a:result)
call Chk(a:b, a:a, -a:result)
endfunction
function! LT(a, b)
call Check(a:a, a:b, -1)
endfunction
function! GT(a, b)
call Check(a:a, a:b, 1)
endfunction
function! EQ(a, b)
call Check(a:a, a:b, 0)
endfunction
function Test_comparisons()
call EQ('', '')
call LT('', 'a')
call EQ('abc', 'abc')
call EQ('Abc', 'abC')
call LT('ab', 'abc')
call LT('AB', 'abc')
call LT('ab', 'aBc')
call EQ('\xd0\xb9\xd1\x86\xd1\x83\xd0\xba\xd0\xb5\xd0\xbd', '\xd0\xb9\xd0\xa6\xd0\xa3\xd0\xba\xd0\x95\xd0\xbd')
call LT('\xd0\xb9\xd1\x86\xd1\x83\xd0\xba\xd0\xb5\xd0\xbd', '\xd0\xaf\xd1\x86\xd1\x83\xd0\xba\xd0\xb5\xd0\xbd')
call EQ('\xe2\x84\xaa', 'k')
call LT('\xe2\x84\xaa', 'kkkkkk')
call EQ('\xe2\x84\xaa\xe2\x84\xaa\xe2\x84\xaa', 'kkk')
call LT('kk', '\xe2\x84\xaa\xe2\x84\xaa\xe2\x84\xaa')
call EQ('\xe2\x84\xaa\xe2\x84\xa6k\xe2\x84\xaak\xcf\x89', 'k\xcf\x89\xe2\x84\xaakk\xe2\x84\xa6')
call EQ('Abc\x80', 'AbC\x80')
call LT('Abc\x80', 'AbC\x81')
call LT('Abc', 'AbC\x80')
call LT('abc\x80DEF', 'abc\x80def') " case folding stops at the first bad character
call LT('\xc3XYZ', '\xc3xyz')
call EQ('\xef\xbc\xba', '\xef\xbd\x9a') " FF3A (upper), FF5A (lower)
call GT('\xef\xbc\xba', '\xef\xbc\xff') " first string is ok and equals \xef\xbd\x9a after folding, second string is illegal and was left unchanged, then the strings were bytewise compared
call LT('\xc3', '\xc3\x83')
call EQ('\xc3\xa3xYz', '\xc3\x83XyZ')
for n in range(0x60, 0xFF)
call LT(printf('xYz\x%.2X', n-1), printf('XyZ\x%.2X', n))
endfor
for n in range(0x80, 0xBF)
call EQ(printf('xYz\xc2\x%.2XUvW', n), printf('XyZ\xc2\x%.2XuVw', n))
endfor
for n in range(0xC0, 0xFF)
call LT(printf('xYz\xc2\x%.2XUvW', n), printf('XyZ\xc2\x%.2XuVw', n))
endfor
endfunction
" test that g~ap changes one paragraph only.
function Test_gap()
new
call feedkeys("iabcd\n\ndefggg0g~ap", "tx")
call assert_equal(["ABCD", "", "defg"], getline(1,3))
endfunction

View File

@@ -2858,7 +2858,7 @@ close_others (
if (bufIsChanged(wp->w_buffer))
continue;
}
win_close(wp, !P_HID(wp->w_buffer) && !bufIsChanged(wp->w_buffer));
win_close(wp, !buf_hide(wp->w_buffer) && !bufIsChanged(wp->w_buffer));
}
if (message && !ONE_WINDOW)