aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/eval.txt22
-rw-r--r--runtime/syntax/man.vim15
-rw-r--r--src/nvim/buffer.c13
-rw-r--r--src/nvim/ex_cmds2.c16
-rw-r--r--src/nvim/keymap.h14
-rw-r--r--src/nvim/screen.c16
-rw-r--r--src/nvim/testdir/Makefile4
-rw-r--r--src/nvim/testdir/test40.in63
-rw-r--r--src/nvim/testdir/test40.ok11
-rw-r--r--src/nvim/testdir/test_alot.vim1
-rw-r--r--src/nvim/testdir/test_autocmd.vim1
-rw-r--r--src/nvim/testdir/test_clientserver.vim107
-rw-r--r--src/nvim/testdir/test_fold.vim167
-rw-r--r--src/nvim/testdir/test_sort.vim1184
-rw-r--r--src/nvim/testdir/test_substitute.vim180
-rw-r--r--src/nvim/testdir/test_swap.vim48
-rw-r--r--src/nvim/testdir/test_tagjump.vim56
-rw-r--r--src/nvim/testdir/test_vimscript.vim20
-rw-r--r--src/nvim/testdir/test_wordcount.vim108
-rw-r--r--test/functional/terminal/buffer_spec.lua22
-rw-r--r--test/functional/ui/screen.lua14
-rw-r--r--test/functional/ui/screen_basic_spec.lua5
-rw-r--r--test/includes/CMakeLists.txt7
-rw-r--r--test/includes/pre/uv.h (renamed from test/includes/pre/uv-errno.h)2
-rw-r--r--test/unit/os/fs_spec.lua2
25 files changed, 1989 insertions, 109 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 635c08556b..d71bbf2528 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2222,6 +2222,8 @@ remote_read({serverid} [, {timeout}])
String read reply string
remote_send({server}, {string} [, {idvar}])
String send key sequence
+remote_startserver({name}) none become server {name}
+ String send key sequence
remove({list}, {idx} [, {end}]) any remove items {idx}-{end} from {list}
remove({dict}, {key}) any remove entry {key} from {dict}
rename({from}, {to}) Number rename (move) file from {from} to {to}
@@ -6196,15 +6198,17 @@ reltimestr({time}) *reltimestr()*
< Also see |profiling|.
*remote_expr()* *E449*
-remote_expr({server}, {string} [, {idvar}])
+remote_expr({server}, {string} [, {idvar} [, {timeout}]])
Send the {string} to {server}. The string is sent as an
expression and the result is returned after evaluation.
The result must be a String or a |List|. A |List| is turned
into a String by joining the items with a line break in
between (not at the end), like with join(expr, "\n").
- If {idvar} is present, it is taken as the name of a
- variable and a {serverid} for later use with
+ If {idvar} is present and not empty, it is taken as the name
+ of a variable and a {serverid} for later use with
remote_read() is stored there.
+ If {timeout} is given the read times out after this many
+ seconds. Otherwise a timeout of 600 seconds is used.
See also |clientserver| |RemoteReply|.
This function is not available in the |sandbox|.
{only available when compiled with the |+clientserver| feature}
@@ -6248,9 +6252,10 @@ remote_peek({serverid} [, {retvar}]) *remote_peek()*
:let repl = ""
:echo "PEEK: ".remote_peek(id, "repl").": ".repl
-remote_read({serverid}) *remote_read()*
+remote_read({serverid}, [{timeout}]) *remote_read()*
Return the oldest available reply from {serverid} and consume
- it. It blocks until a reply is available.
+ it. Unless a {timeout} in seconds is given, it blocks until a
+ reply is available.
See also |clientserver|.
This function is not available in the |sandbox|.
{only available when compiled with the |+clientserver| feature}
@@ -6268,6 +6273,7 @@ remote_send({server}, {string} [, {idvar}])
See also |clientserver| |RemoteReply|.
This function is not available in the |sandbox|.
{only available when compiled with the |+clientserver| feature}
+
Note: Any errors will be reported in the server and may mess
up the display.
Examples: >
@@ -6279,6 +6285,12 @@ remote_send({server}, {string} [, {idvar}])
:echo remote_send("gvim", ":sleep 10 | echo ".
\ 'server2client(expand("<client>"), "HELLO")<CR>')
<
+ *remote_startserver()* *E941* *E942*
+remote_startserver({name})
+ Become the server {name}. This fails if already running as a
+ server, when |v:servername| is not empty.
+ {only available when compiled with the |+clientserver| feature}
+
remove({list}, {idx} [, {end}]) *remove()*
Without {end}: Remove the item at {idx} from |List| {list} and
return the item.
diff --git a/runtime/syntax/man.vim b/runtime/syntax/man.vim
index b8e605cb9a..9ae50d17a5 100644
--- a/runtime/syntax/man.vim
+++ b/runtime/syntax/man.vim
@@ -30,17 +30,28 @@ endif
if !exists('b:man_sect')
call man#init_pager()
endif
-if b:man_sect =~# '^[23]'
+if b:man_sect =~# '^[023]'
+ syntax case match
syntax include @c $VIMRUNTIME/syntax/c.vim
syntax match manCFuncDefinition display '\<\h\w*\>\ze\(\s\|\n\)*(' contained
+ syntax match manSentence display '\%(^ \{3,7}\u\|\. \u\)\_.\{-}
+ \\%(-$\|\.$\|:$\)\|
+ \ \{3,7}\a.*\%(\.\|:\)$' contained contains=manReference
syntax region manSynopsis start='^\%(
\SYNOPSIS\|
\SYNTAX\|
\SINTASSI\|
\SKŁADNIA\|
\СИНТАКСИС\|
- \書式\)$' end='^\%(\S.*\)\=\S$' keepend contains=manSectionHeading,@c,manCFuncDefinition
+ \書式\)$' end='^\%(\S.*\)\=\S$' keepend contains=manSentence,manSectionHeading,@c,manCFuncDefinition
highlight default link manCFuncDefinition Function
+
+ syntax region manExample start='^EXAMPLES\=$' end='^\%(\S.*\)\=\S$' keepend contains=manSentence,manSectionHeading,manSubHeading,@c,manCFuncDefinition
+
+ " XXX: groupthere doesn't seem to work
+ syntax sync minlines=500
+ "syntax sync match manSyncExample groupthere manExample '^EXAMPLES\=$'
+ "syntax sync match manSyncExample groupthere NONE '^\%(EXAMPLES\=\)\@!\%(\S.*\)\=\S$'
endif
" Prevent everything else from matching the last line
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 95eaf4dcf6..81bbc56eb9 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -1172,14 +1172,21 @@ do_buffer (
}
} else {
if (buf->terminal) {
- EMSG2(_("E89: %s will be killed(add ! to override)"),
- (char *)buf->b_fname);
+ if (p_confirm || cmdmod.confirm) {
+ if (!dialog_close_terminal(buf)) {
+ return FAIL;
+ }
+ } else {
+ EMSG2(_("E89: %s will be killed(add ! to override)"),
+ (char *)buf->b_fname);
+ return FAIL;
+ }
} else {
EMSGN(_("E89: No write since last change for buffer %" PRId64
" (add ! to override)"),
buf->b_fnum);
+ return FAIL;
}
- return FAIL;
}
}
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 46a7c869e1..f07bc0e137 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -1339,6 +1339,22 @@ void dialog_changed(buf_T *buf, int checkall)
}
}
+/// Ask the user whether to close the terminal buffer or not.
+///
+/// @param buf The terminal buffer.
+/// @return bool Whether to close the buffer or not.
+bool dialog_close_terminal(buf_T *buf)
+{
+ char_u buff[DIALOG_MSG_SIZE];
+
+ dialog_msg(buff, _("Close \"%s\"?"),
+ (buf->b_fname != NULL) ? buf->b_fname : (char_u *)"?");
+
+ int ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1);
+
+ return (ret == VIM_YES) ? true : false;
+}
+
/// Return true if the buffer "buf" can be abandoned, either by making it
/// hidden, autowriting it or unloading it.
bool can_abandon(buf_T *buf, int forceit)
diff --git a/src/nvim/keymap.h b/src/nvim/keymap.h
index 9c2a1656d5..baf8963aa8 100644
--- a/src/nvim/keymap.h
+++ b/src/nvim/keymap.h
@@ -170,10 +170,8 @@ enum key_extra {
, KE_MOUSE = 43 // mouse event start
- /*
- * Symbols for pseudo keys which are translated from the real key symbols
- * above.
- */
+ // Symbols for pseudo keys which are translated from the real key symbols
+ // above.
, KE_LEFTMOUSE = 44 // Left mouse button click
, KE_LEFTDRAG = 45 // Drag with left mouse button down
, KE_LEFTRELEASE = 46 // Left mouse button release
@@ -211,9 +209,9 @@ enum key_extra {
, KE_S_XF3 = 73
, KE_S_XF4 = 74
- /* NOTE: The scroll wheel events are inverted: i.e. UP is the same as
- * moving the actual scroll wheel down, LEFT is the same as moving the
- * scroll wheel right. */
+ // NOTE: The scroll wheel events are inverted: i.e. UP is the same as
+ // moving the actual scroll wheel down, LEFT is the same as moving the
+ // scroll wheel right.
, KE_MOUSEDOWN = 75 // scroll wheel pseudo-button Down
, KE_MOUSEUP = 76 // scroll wheel pseudo-button Up
, KE_MOUSELEFT = 77 // scroll wheel pseudo-button Left
@@ -249,7 +247,7 @@ enum key_extra {
, KE_EVENT = 102 // event
, KE_PASTE = 103 // special key to toggle the 'paste' option.
// sent only by UIs
- , KE_COMMAND = 104 // special key to execute command in any mode
+ , KE_COMMAND = 104 // <Cmd> special key
};
/*
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index ce5c994526..49aeaff3a6 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -6396,6 +6396,13 @@ int showmode(void)
/* Position on the last line in the window, column 0 */
msg_pos_mode();
attr = HL_ATTR(HLF_CM); // Highlight mode
+
+ // When the screen is too narrow to show the entire mode messsage,
+ // avoid scrolling and truncate instead.
+ msg_no_more = true;
+ int save_lines_left = lines_left;
+ lines_left = 0;
+
if (do_mode) {
MSG_PUTS_ATTR("--", attr);
// CTRL-X in Insert mode
@@ -6495,10 +6502,13 @@ int showmode(void)
msg_didout = FALSE; /* overwrite this message */
length = msg_col;
msg_col = 0;
- need_wait_return = nwr_save; /* never ask for hit-return for this */
- } else if (clear_cmdline && msg_silent == 0)
- /* Clear the whole command line. Will reset "clear_cmdline". */
+ msg_no_more = false;
+ lines_left = save_lines_left;
+ need_wait_return = nwr_save; // never ask for hit-return for this
+ } else if (clear_cmdline && msg_silent == 0) {
+ // Clear the whole command line. Will reset "clear_cmdline".
msg_clr_cmdline();
+ }
/* In Visual mode the size of the selected area must be redrawn. */
if (VIsual_active)
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index a161f14bc8..e3b717989e 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -17,7 +17,6 @@ SCRIPTS_DEFAULT = \
test14.out \
test24.out \
test37.out \
- test40.out \
test42.out \
test48.out \
test52.out \
@@ -41,6 +40,7 @@ NEW_TESTS ?= \
test_changedtick.res \
test_charsearch.res \
test_cindent.res \
+ test_clientserver.res \
test_close_count.res \
test_cmdline.res \
test_command_count.res \
@@ -102,6 +102,7 @@ NEW_TESTS ?= \
test_stat.res \
test_startup.res \
test_substitute.res \
+ test_swap.res \
test_syntax.res \
test_system.res \
test_tab.res \
@@ -114,6 +115,7 @@ NEW_TESTS ?= \
test_visual.res \
test_winbuf_close.res \
test_window_id.res \
+ test_wordcount.res \
test_writefile.res \
test_alot_latin.res \
test_alot_utf8.res \
diff --git a/src/nvim/testdir/test40.in b/src/nvim/testdir/test40.in
deleted file mode 100644
index b0285709e5..0000000000
--- a/src/nvim/testdir/test40.in
+++ /dev/null
@@ -1,63 +0,0 @@
-Test for "*Cmd" autocommands
-
-STARTTEST
-:set wildchar=^E
-:/^start/,$w! Xxx " write lines below to Xxx
-:au BufReadCmd XtestA 0r Xxx|$del
-:e XtestA " will read text of Xxd instead
-:au BufWriteCmd XtestA call append(line("$"), "write")
-:w " will append a line to the file
-:r XtestA " should not read anything
-: " now we have:
-: " 1 start of Xxx
-: " 2 test40
-: " 3 end of Xxx
-: " 4 write
-:au FileReadCmd XtestB '[r Xxx
-:2r XtestB " will read Xxx below line 2 instead
-: " 1 start of Xxx
-: " 2 test40
-: " 3 start of Xxx
-: " 4 test40
-: " 5 end of Xxx
-: " 6 end of Xxx
-: " 7 write
-:au FileWriteCmd XtestC '[,']copy $
-4GA1
-:4,5w XtestC " will copy lines 4 and 5 to the end
-:r XtestC " should not read anything
-: " 1 start of Xxx
-: " 2 test40
-: " 3 start of Xxx
-: " 4 test401
-: " 5 end of Xxx
-: " 6 end of Xxx
-: " 7 write
-: " 8 test401
-: " 9 end of Xxx
-:au FILEAppendCmd XtestD '[,']w! test.out
-:w >>XtestD " will write all lines to test.out
-:$r XtestD " should not read anything
-:$w >>test.out " append "end of Xxx" to test.out
-:au BufReadCmd XtestE 0r test.out|$del
-:sp XtestE " split window with test.out
-5Goasdf:"
-:au BufWriteCmd XtestE w! test.out
-:wall " will write other window to test.out
-: " 1 start of Xxx
-: " 2 test40
-: " 3 start of Xxx
-: " 4 test401
-: " 5 end of Xxx
-: " 6 asdf
-: " 7 end of Xxx
-: " 8 write
-: " 9 test401
-: " 10 end of Xxx
-: " 11 end of Xxx
-:qa!
-ENDTEST
-
-start of Xxx
- test40
-end of Xxx
diff --git a/src/nvim/testdir/test40.ok b/src/nvim/testdir/test40.ok
deleted file mode 100644
index b6501394f9..0000000000
--- a/src/nvim/testdir/test40.ok
+++ /dev/null
@@ -1,11 +0,0 @@
-start of Xxx
- test40
-start of Xxx
- test401
-end of Xxx
-asdf
-end of Xxx
-write
- test401
-end of Xxx
-end of Xxx
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
index 25e4fd5ae8..1a70ac152f 100644
--- a/src/nvim/testdir/test_alot.vim
+++ b/src/nvim/testdir/test_alot.vim
@@ -30,6 +30,7 @@ source test_put.vim
source test_recover.vim
source test_regexp_utf8.vim
source test_scroll_opt.vim
+source test_sort.vim
source test_source_utf8.vim
source test_sha256.vim
source test_statusline.vim
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index d42373920f..772b3f721c 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -1,6 +1,5 @@
" Tests for autocommands
-
func! s:cleanup_buffers() abort
for bnr in range(1, bufnr('$'))
if bufloaded(bnr) && bufnr('%') != bnr
diff --git a/src/nvim/testdir/test_clientserver.vim b/src/nvim/testdir/test_clientserver.vim
new file mode 100644
index 0000000000..60ef20e0b2
--- /dev/null
+++ b/src/nvim/testdir/test_clientserver.vim
@@ -0,0 +1,107 @@
+" Tests for the +clientserver feature.
+
+if !has('job') || !has('clientserver')
+ finish
+endif
+
+source shared.vim
+
+func Test_client_server()
+ let cmd = GetVimCommand()
+ if cmd == ''
+ return
+ endif
+ if has('x11')
+ if empty($DISPLAY)
+ throw 'Skipped: $DISPLAY is not set'
+ endif
+ try
+ call remote_send('xxx', '')
+ catch
+ if v:exception =~ 'E240:'
+ throw 'Skipped: no connection to the X server'
+ endif
+ " ignore other errors
+ endtry
+ endif
+
+ let name = 'XVIMTEST'
+ let cmd .= ' --servername ' . name
+ let g:job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
+ call WaitFor('job_status(g:job) == "run"')
+ if job_status(g:job) != 'run'
+ call assert_report('Cannot run the Vim server')
+ return
+ endif
+
+ " Takes a short while for the server to be active.
+ call WaitFor('serverlist() =~ "' . name . '"')
+ call assert_match(name, serverlist())
+
+ call remote_foreground(name)
+
+ call remote_send(name, ":let testvar = 'yes'\<CR>")
+ call WaitFor('remote_expr("' . name . '", "exists(\"testvar\") ? testvar : \"\"", "", 1) == "yes"')
+ call assert_equal('yes', remote_expr(name, "testvar", "", 2))
+
+ if has('unix') && has('gui') && !has('gui_running')
+ " Running in a terminal and the GUI is available: Tell the server to open
+ " the GUI and check that the remote command still works.
+ " Need to wait for the GUI to start up, otherwise the send hangs in trying
+ " to send to the terminal window.
+ if has('gui_athena') || has('gui_motif')
+ " For those GUIs, ignore the 'failed to create input context' error.
+ call remote_send(name, ":call test_ignore_error('E285') | gui -f\<CR>")
+ else
+ call remote_send(name, ":gui -f\<CR>")
+ endif
+ " Wait for the server to be up and answering requests.
+ sleep 100m
+ call WaitFor('remote_expr("' . name . '", "v:version", "", 1) != ""')
+ call assert_true(remote_expr(name, "v:version", "", 1) != "")
+
+ call remote_send(name, ":let testvar = 'maybe'\<CR>")
+ call WaitFor('remote_expr("' . name . '", "testvar", "", 1) == "maybe"')
+ call assert_equal('maybe', remote_expr(name, "testvar", "", 2))
+ endif
+
+ call assert_fails('call remote_send("XXX", ":let testvar = ''yes''\<CR>")', 'E241')
+
+ " Expression evaluated locally.
+ if v:servername == ''
+ call remote_startserver('MYSELF')
+ " May get MYSELF1 when running the test again.
+ call assert_match('MYSELF', v:servername)
+ endif
+ let g:testvar = 'myself'
+ call assert_equal('myself', remote_expr(v:servername, 'testvar'))
+
+ call remote_send(name, ":call server2client(expand('<client>'), 'got it')\<CR>", 'g:myserverid')
+ call assert_equal('got it', remote_read(g:myserverid, 2))
+
+ call remote_send(name, ":call server2client(expand('<client>'), 'another')\<CR>", 'g:myserverid')
+ let peek_result = 'nothing'
+ let r = remote_peek(g:myserverid, 'peek_result')
+ " unpredictable whether the result is already avaialble.
+ if r > 0
+ call assert_equal('another', peek_result)
+ elseif r == 0
+ call assert_equal('nothing', peek_result)
+ else
+ call assert_report('remote_peek() failed')
+ endif
+ let g:peek_result = 'empty'
+ call WaitFor('remote_peek(g:myserverid, "g:peek_result") > 0')
+ call assert_equal('another', g:peek_result)
+ call assert_equal('another', remote_read(g:myserverid, 2))
+
+ call remote_send(name, ":qa!\<CR>")
+ call WaitFor('job_status(g:job) == "dead"')
+ if job_status(g:job) != 'dead'
+ call assert_report('Server did not exit')
+ call job_stop(g:job, 'kill')
+ endif
+endfunc
+
+" Uncomment this line to get a debugging log
+" call ch_logfile('channellog', 'w')
diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim
index 951df349ce..6917378890 100644
--- a/src/nvim/testdir/test_fold.vim
+++ b/src/nvim/testdir/test_fold.vim
@@ -467,3 +467,170 @@ func Test_fold_error()
set foldmethod&
bw!
endfunc
+
+" Various fold related tests
+
+" Basic test if a fold can be created, opened, moving to the end and closed
+func Test_fold_manual()
+ enew!
+ set fdm=manual
+
+ let content = ['1 aa', '2 bb', '3 cc']
+ call append(0, content)
+ call cursor(1, 1)
+ normal zf2j
+ call assert_equal('1 aa', getline(foldclosed('.')))
+ normal zo
+ call assert_equal(-1, foldclosed('.'))
+ normal ]z
+ call assert_equal('3 cc', getline('.'))
+ normal zc
+ call assert_equal('1 aa', getline(foldclosed('.')))
+
+ set fdm&
+ enew!
+endfunc
+
+" test folding with markers.
+func Test_fold_marker()
+ enew!
+ set fdm=marker fdl=1 fdc=3
+
+ let content = ['4 dd {{{', '5 ee {{{ }}}', '6 ff }}}']
+ call append(0, content)
+ call cursor(2, 1)
+ call assert_equal(2, foldlevel('.'))
+ normal [z
+ call assert_equal(1, foldlevel('.'))
+ exe "normal jo{{ \<Esc>r{jj"
+ call assert_equal(1, foldlevel('.'))
+ normal kYpj
+ call assert_equal(0, foldlevel('.'))
+
+ set fdm& fdl& fdc&
+ enew!
+endfunc
+
+" test folding with indent
+func Test_fold_indent()
+ enew!
+ set fdm=indent sw=2
+
+ let content = ['1 aa', '2 bb', '3 cc']
+ call append(0, content)
+ call cursor(2, 1)
+ exe "normal i \<Esc>jI "
+ call assert_equal(2, foldlevel('.'))
+ normal k
+ call assert_equal(1, foldlevel('.'))
+
+ set fdm& sw&
+ enew!
+endfunc
+
+" test syntax folding
+func Test_fold_syntax()
+ if !has('syntax')
+ return
+ endif
+
+ enew!
+ set fdm=syntax fdl=0
+
+ syn region Hup start="dd" end="ii" fold contains=Fd1,Fd2,Fd3
+ syn region Fd1 start="ee" end="ff" fold contained
+ syn region Fd2 start="gg" end="hh" fold contained
+ syn region Fd3 start="commentstart" end="commentend" fold contained
+ let content = ['3 cc', '4 dd {{{', '5 ee {{{ }}}', '{{{{', '6 ff }}}',
+ \ '6 ff }}}', '7 gg', '8 hh', '9 ii']
+ call append(0, content)
+ normal Gzk
+ call assert_equal('9 ii', getline('.'))
+ normal k
+ call assert_equal('3 cc', getline('.'))
+ exe "normal jAcommentstart \<Esc>Acommentend"
+ set fdl=1
+ normal 3j
+ call assert_equal('7 gg', getline('.'))
+ set fdl=0
+ exe "normal zO\<C-L>j"
+ call assert_equal('8 hh', getline('.'))
+ syn clear Fd1 Fd2 Fd3 Hup
+
+ set fdm& fdl&
+ enew!
+endfunc
+
+func Flvl()
+ let l = getline(v:lnum)
+ if l =~ "bb$"
+ return 2
+ elseif l =~ "gg$"
+ return "s1"
+ elseif l =~ "ii$"
+ return ">2"
+ elseif l =~ "kk$"
+ return "0"
+ endif
+ return "="
+endfun
+
+" test expression folding
+func Test_fold_expr()
+ enew!
+ set fdm=expr fde=Flvl()
+
+ let content = ['1 aa',
+ \ '2 bb',
+ \ '3 cc',
+ \ '4 dd {{{commentstart commentend',
+ \ '5 ee {{{ }}}',
+ \ '{{{',
+ \ '6 ff }}}',
+ \ '6 ff }}}',
+ \ ' 7 gg',
+ \ ' 8 hh',
+ \ '9 ii',
+ \ 'a jj',
+ \ 'b kk']
+ call append(0, content)
+ call cursor(1, 1)
+ exe "normal /bb$\<CR>"
+ call assert_equal(2, foldlevel('.'))
+ exe "normal /hh$\<CR>"
+ call assert_equal(1, foldlevel('.'))
+ exe "normal /ii$\<CR>"
+ call assert_equal(2, foldlevel('.'))
+ exe "normal /kk$\<CR>"
+ call assert_equal(0, foldlevel('.'))
+
+ set fdm& fde&
+ enew!
+endfunc
+
+" Bug with fdm=indent and moving folds
+" Moving a fold a few times, messes up the folds below the moved fold.
+" Fixed by 7.4.700
+func Test_fold_move()
+ enew!
+ set fdm=indent sw=2 fdl=0
+
+ let content = ['', '', 'Line1', ' Line2', ' Line3',
+ \ 'Line4', ' Line5', ' Line6',
+ \ 'Line7', ' Line8', ' Line9']
+ call append(0, content)
+ normal zM
+ call cursor(4, 1)
+ move 2
+ move 1
+ call assert_equal(7, foldclosed(7))
+ call assert_equal(8, foldclosedend(7))
+ call assert_equal(0, foldlevel(9))
+ call assert_equal(10, foldclosed(10))
+ call assert_equal(11, foldclosedend(10))
+ call assert_equal('+-- 2 lines: Line2', foldtextresult(2))
+ call assert_equal('+-- 2 lines: Line8', foldtextresult(10))
+
+ set fdm& sw& fdl&
+ enew!
+endfunc
diff --git a/src/nvim/testdir/test_sort.vim b/src/nvim/testdir/test_sort.vim
new file mode 100644
index 0000000000..4fddb47b58
--- /dev/null
+++ b/src/nvim/testdir/test_sort.vim
@@ -0,0 +1,1184 @@
+" Test sort()
+
+:func Compare1(a, b) abort
+ call sort(range(3), 'Compare2')
+ return a:a - a:b
+:endfunc
+
+:func Compare2(a, b) abort
+ return a:a - a:b
+:endfunc
+
+func Test_sort_strings()
+ " numbers compared as strings
+ call assert_equal([1, 2, 3], sort([3, 2, 1]))
+ call assert_equal([13, 28, 3], sort([3, 28, 13]))
+endfunc
+
+func Test_sort_numeric()
+ call assert_equal([1, 2, 3], sort([3, 2, 1], 'n'))
+ call assert_equal([3, 13, 28], sort([13, 28, 3], 'n'))
+ " strings are not sorted
+ call assert_equal(['13', '28', '3'], sort(['13', '28', '3'], 'n'))
+endfunc
+
+func Test_sort_numbers()
+ call assert_equal([3, 13, 28], sort([13, 28, 3], 'N'))
+ call assert_equal(['3', '13', '28'], sort(['13', '28', '3'], 'N'))
+endfunc
+
+func Test_sort_float()
+ call assert_equal([0.28, 3, 13.5], sort([13.5, 0.28, 3], 'f'))
+endfunc
+
+func Test_sort_nested()
+ " test ability to call sort() from a compare function
+ call assert_equal([1, 3, 5], sort([3, 1, 5], 'Compare1'))
+endfunc
+
+func Test_sort_default()
+ " docs say omitted, empty or zero argument sorts on string representation.
+ call assert_equal(['2', 'A', 'AA', 'a', 1, 3.3], sort([3.3, 1, "2", "A", "a", "AA"]))
+ call assert_equal(['2', 'A', 'AA', 'a', 1, 3.3], sort([3.3, 1, "2", "A", "a", "AA"], ''))
+ call assert_equal(['2', 'A', 'AA', 'a', 1, 3.3], sort([3.3, 1, "2", "A", "a", "AA"], 0))
+ call assert_equal(['2', 'A', 'a', 'AA', 1, 3.3], sort([3.3, 1, "2", "A", "a", "AA"], 1))
+ call assert_fails('call sort([3.3, 1, "2"], 3)', "E474")
+endfunc
+
+" Tests for the :sort command
+func Test_sort_cmd()
+ let tests = [
+ \ {
+ \ 'name' : 'Alphabetical sort',
+ \ 'cmd' : '%sort',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ],
+ \ 'expected' : [
+ \ ' 123b',
+ \ 'a',
+ \ 'a122',
+ \ 'a123',
+ \ 'a321',
+ \ 'ab',
+ \ 'abc',
+ \ 'b123',
+ \ 'b321',
+ \ 'b321',
+ \ 'b321b',
+ \ 'b322b',
+ \ 'c123d',
+ \ 'c321d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Numeric sort',
+ \ 'cmd' : '%sort n',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'a',
+ \ 'x-22',
+ \ 'b321',
+ \ 'b123',
+ \ '',
+ \ 'c123d',
+ \ '-24',
+ \ ' 123b',
+ \ 'c321d',
+ \ '0',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '-24',
+ \ 'x-22',
+ \ '0',
+ \ 'a122',
+ \ 'a123',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b321',
+ \ 'b321b',
+ \ 'b322b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Hexadecimal sort',
+ \ 'cmd' : '%sort x',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ],
+ \ 'expected' : [
+ \ 'a',
+ \ 'ab',
+ \ 'abc',
+ \ ' 123b',
+ \ 'a122',
+ \ 'a123',
+ \ 'a321',
+ \ 'b123',
+ \ 'b321',
+ \ 'b321',
+ \ 'b321b',
+ \ 'b322b',
+ \ 'c123d',
+ \ 'c321d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Alphabetical unique sort',
+ \ 'cmd' : '%sort u',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ],
+ \ 'expected' : [
+ \ ' 123b',
+ \ 'a',
+ \ 'a122',
+ \ 'a123',
+ \ 'a321',
+ \ 'ab',
+ \ 'abc',
+ \ 'b123',
+ \ 'b321',
+ \ 'b321b',
+ \ 'b322b',
+ \ 'c123d',
+ \ 'c321d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Alphabetical reverse sort',
+ \ 'cmd' : '%sort!',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ],
+ \ 'expected' : [
+ \ 'c321d',
+ \ 'c123d',
+ \ 'b322b',
+ \ 'b321b',
+ \ 'b321',
+ \ 'b321',
+ \ 'b123',
+ \ 'abc',
+ \ 'ab',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'a',
+ \ ' 123b',
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Numeric reverse sort',
+ \ 'cmd' : '%sort! n',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ],
+ \ 'expected' : [
+ \ 'b322b',
+ \ 'b321b',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b321',
+ \ 'a321',
+ \ ' 123b',
+ \ 'c123d',
+ \ 'b123',
+ \ 'a123',
+ \ 'a122',
+ \ 'a',
+ \ 'ab',
+ \ 'abc'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Unique reverse sort',
+ \ 'cmd' : 'sort! u',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ],
+ \ 'expected' : [
+ \ 'c321d',
+ \ 'c123d',
+ \ 'b322b',
+ \ 'b321b',
+ \ 'b321',
+ \ 'b123',
+ \ 'abc',
+ \ 'ab',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'a',
+ \ ' 123b',
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Octal sort',
+ \ 'cmd' : 'sort o',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a122',
+ \ 'a123',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b321',
+ \ 'b321b',
+ \ 'b322b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Reverse hexadecimal sort',
+ \ 'cmd' : 'sort! x',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'c321d',
+ \ 'c123d',
+ \ 'b322b',
+ \ 'b321b',
+ \ 'b321',
+ \ 'b321',
+ \ 'b123',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ ' 123b',
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ ''
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Alpha (skip first character) sort',
+ \ 'cmd' : 'sort/./',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a122',
+ \ 'a123',
+ \ 'b123',
+ \ ' 123b',
+ \ 'c123d',
+ \ 'a321',
+ \ 'b321',
+ \ 'b321',
+ \ 'b321b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'ab',
+ \ 'abc'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Alpha (skip first 2 characters) sort',
+ \ 'cmd' : 'sort/../',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a321',
+ \ 'b321',
+ \ 'b321',
+ \ 'b321b',
+ \ 'c321d',
+ \ 'a122',
+ \ 'b322b',
+ \ 'a123',
+ \ 'b123',
+ \ ' 123b',
+ \ 'c123d',
+ \ 'abc'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alpha, unique, skip first 2 characters',
+ \ 'cmd' : 'sort/../u',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ 'a321',
+ \ 'b321',
+ \ 'b321b',
+ \ 'c321d',
+ \ 'a122',
+ \ 'b322b',
+ \ 'a123',
+ \ 'b123',
+ \ ' 123b',
+ \ 'c123d',
+ \ 'abc'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'numeric, skip first character',
+ \ 'cmd' : 'sort/./n',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a122',
+ \ 'a123',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b321',
+ \ 'b321b',
+ \ 'b322b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alpha, sort on first character',
+ \ 'cmd' : 'sort/./r',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ '',
+ \ '',
+ \ ' 123b',
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ 'c123d',
+ \ 'c321d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alpha, sort on first 2 characters',
+ \ 'cmd' : 'sort/../r',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'a',
+ \ '',
+ \ '',
+ \ ' 123b',
+ \ 'a123',
+ \ 'a122',
+ \ 'a321',
+ \ 'abc',
+ \ 'ab',
+ \ 'b123',
+ \ 'b321',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ 'c123d',
+ \ 'c321d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'numeric, sort on first character',
+ \ 'cmd' : 'sort/./rn',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alpha, skip past first digit',
+ \ 'cmd' : 'sort/\d/',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a321',
+ \ 'b321',
+ \ 'b321',
+ \ 'b321b',
+ \ 'c321d',
+ \ 'a122',
+ \ 'b322b',
+ \ 'a123',
+ \ 'b123',
+ \ ' 123b',
+ \ 'c123d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alpha, sort on first digit',
+ \ 'cmd' : 'sort/\d/r',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a123',
+ \ 'a122',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'numeric, skip past first digit',
+ \ 'cmd' : 'sort/\d/n',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b321',
+ \ 'b321b',
+ \ 'a122',
+ \ 'b322b',
+ \ 'a123',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'numeric, sort on first digit',
+ \ 'cmd' : 'sort/\d/rn',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a123',
+ \ 'a122',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alpha, skip past first 2 digits',
+ \ 'cmd' : 'sort/\d\d/',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a321',
+ \ 'b321',
+ \ 'b321',
+ \ 'b321b',
+ \ 'c321d',
+ \ 'a122',
+ \ 'b322b',
+ \ 'a123',
+ \ 'b123',
+ \ ' 123b',
+ \ 'c123d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'numeric, skip past first 2 digits',
+ \ 'cmd' : 'sort/\d\d/n',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b321',
+ \ 'b321b',
+ \ 'a122',
+ \ 'b322b',
+ \ 'a123',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'hexadecimal, skip past first 2 digits',
+ \ 'cmd' : 'sort/\d\d/x',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a321',
+ \ 'b321',
+ \ 'b321',
+ \ 'a122',
+ \ 'a123',
+ \ 'b123',
+ \ 'b321b',
+ \ 'c321d',
+ \ 'b322b',
+ \ ' 123b',
+ \ 'c123d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alpha, sort on first 2 digits',
+ \ 'cmd' : 'sort/\d\d/r',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a123',
+ \ 'a122',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'numeric, sort on first 2 digits',
+ \ 'cmd' : 'sort/\d\d/rn',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a123',
+ \ 'a122',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'hexadecimal, sort on first 2 digits',
+ \ 'cmd' : 'sort/\d\d/rx',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a123',
+ \ 'a122',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'binary',
+ \ 'cmd' : 'sort b',
+ \ 'input' : [
+ \ '0b111000',
+ \ '0b101100',
+ \ '0b101001',
+ \ '0b101001',
+ \ '0b101000',
+ \ '0b000000',
+ \ '0b001000',
+ \ '0b010000',
+ \ '0b101000',
+ \ '0b100000',
+ \ '0b101010',
+ \ '0b100010',
+ \ '0b100100',
+ \ '0b100010',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ '',
+ \ '',
+ \ '0b000000',
+ \ '0b001000',
+ \ '0b010000',
+ \ '0b100000',
+ \ '0b100010',
+ \ '0b100010',
+ \ '0b100100',
+ \ '0b101000',
+ \ '0b101000',
+ \ '0b101001',
+ \ '0b101001',
+ \ '0b101010',
+ \ '0b101100',
+ \ '0b111000'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'binary with leading characters',
+ \ 'cmd' : 'sort b',
+ \ 'input' : [
+ \ '0b100010',
+ \ '0b010000',
+ \ ' 0b101001',
+ \ 'b0b101100',
+ \ '0b100010',
+ \ ' 0b100100',
+ \ 'a0b001000',
+ \ '0b101000',
+ \ '0b101000',
+ \ 'a0b101001',
+ \ 'ab0b100000',
+ \ '0b101010',
+ \ '0b000000',
+ \ 'b0b111000',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ '',
+ \ '',
+ \ '0b000000',
+ \ 'a0b001000',
+ \ '0b010000',
+ \ 'ab0b100000',
+ \ '0b100010',
+ \ '0b100010',
+ \ ' 0b100100',
+ \ '0b101000',
+ \ '0b101000',
+ \ ' 0b101001',
+ \ 'a0b101001',
+ \ '0b101010',
+ \ 'b0b101100',
+ \ 'b0b111000'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'float',
+ \ 'cmd' : 'sort f',
+ \ 'input' : [
+ \ '1.234',
+ \ '0.88',
+ \ '123.456',
+ \ '1.15e-6',
+ \ '-1.1e3',
+ \ '-1.01e3',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ '',
+ \ '',
+ \ '-1.1e3',
+ \ '-1.01e3',
+ \ '1.15e-6',
+ \ '0.88',
+ \ '1.234',
+ \ '123.456'
+ \ ]
+ \ }
+ \ ]
+
+ for t in tests
+ enew!
+ call append(0, t.input)
+ $delete _
+ exe t.cmd
+ call assert_equal(t.expected, getline(1, '$'), t.name)
+ endfor
+
+ call assert_fails('sort no', 'E474')
+
+ enew!
+endfunc
diff --git a/src/nvim/testdir/test_substitute.vim b/src/nvim/testdir/test_substitute.vim
index 75ce24de46..dbd26be089 100644
--- a/src/nvim/testdir/test_substitute.vim
+++ b/src/nvim/testdir/test_substitute.vim
@@ -321,3 +321,183 @@ func Test_sub_cmd_8()
enew!
set titlestring&
endfunc
+
+" Test for *sub-replace-special* and *sub-replace-expression* on substitute().
+func Test_sub_replace_1()
+ " Run the tests with 'magic' on
+ set magic
+ set cpo&
+ call assert_equal('AA', substitute('A', 'A', '&&', ''))
+ call assert_equal('&', substitute('B', 'B', '\&', ''))
+ call assert_equal('C123456789987654321', substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', ''))
+ call assert_equal('d', substitute('D', 'D', 'd', ''))
+ call assert_equal('~', substitute('E', 'E', '~', ''))
+ call assert_equal('~', substitute('F', 'F', '\~', ''))
+ call assert_equal('Gg', substitute('G', 'G', '\ugg', ''))
+ call assert_equal('Hh', substitute('H', 'H', '\Uh\Eh', ''))
+ call assert_equal('iI', substitute('I', 'I', '\lII', ''))
+ call assert_equal('jJ', substitute('J', 'J', '\LJ\EJ', ''))
+ call assert_equal('Kk', substitute('K', 'K', '\Uk\ek', ''))
+ call assert_equal("l\<C-V>\<C-M>l",
+ \ substitute('lLl', 'L', "\<C-V>\<C-M>", ''))
+ call assert_equal("m\<C-M>m", substitute('mMm', 'M', '\r', ''))
+ call assert_equal("n\<C-V>\<C-M>n",
+ \ substitute('nNn', 'N', "\\\<C-V>\<C-M>", ''))
+ call assert_equal("o\no", substitute('oOo', 'O', '\n', ''))
+ call assert_equal("p\<C-H>p", substitute('pPp', 'P', '\b', ''))
+ call assert_equal("q\tq", substitute('qQq', 'Q', '\t', ''))
+ call assert_equal('r\r', substitute('rRr', 'R', '\\', ''))
+ call assert_equal('scs', substitute('sSs', 'S', '\c', ''))
+ call assert_equal("u\nu", substitute('uUu', 'U', "\n", ''))
+ call assert_equal("v\<C-H>v", substitute('vVv', 'V', "\b", ''))
+ call assert_equal("w\\w", substitute('wWw', 'W', "\\", ''))
+ call assert_equal("x\<C-M>x", substitute('xXx', 'X', "\r", ''))
+ call assert_equal("YyyY", substitute('Y', 'Y', '\L\uyYy\l\EY', ''))
+ call assert_equal("zZZz", substitute('Z', 'Z', '\U\lZzZ\u\Ez', ''))
+endfunc
+
+func Test_sub_replace_2()
+ " Run the tests with 'magic' off
+ set nomagic
+ set cpo&
+ call assert_equal('AA', substitute('A', 'A', '&&', ''))
+ call assert_equal('&', substitute('B', 'B', '\&', ''))
+ call assert_equal('C123456789987654321', substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', ''))
+ call assert_equal('d', substitute('D', 'D', 'd', ''))
+ call assert_equal('~', substitute('E', 'E', '~', ''))
+ call assert_equal('~', substitute('F', 'F', '\~', ''))
+ call assert_equal('Gg', substitute('G', 'G', '\ugg', ''))
+ call assert_equal('Hh', substitute('H', 'H', '\Uh\Eh', ''))
+ call assert_equal('iI', substitute('I', 'I', '\lII', ''))
+ call assert_equal('jJ', substitute('J', 'J', '\LJ\EJ', ''))
+ call assert_equal('Kk', substitute('K', 'K', '\Uk\ek', ''))
+ call assert_equal("l\<C-V>\<C-M>l",
+ \ substitute('lLl', 'L', "\<C-V>\<C-M>", ''))
+ call assert_equal("m\<C-M>m", substitute('mMm', 'M', '\r', ''))
+ call assert_equal("n\<C-V>\<C-M>n",
+ \ substitute('nNn', 'N', "\\\<C-V>\<C-M>", ''))
+ call assert_equal("o\no", substitute('oOo', 'O', '\n', ''))
+ call assert_equal("p\<C-H>p", substitute('pPp', 'P', '\b', ''))
+ call assert_equal("q\tq", substitute('qQq', 'Q', '\t', ''))
+ call assert_equal('r\r', substitute('rRr', 'R', '\\', ''))
+ call assert_equal('scs', substitute('sSs', 'S', '\c', ''))
+ call assert_equal("t\<C-M>t", substitute('tTt', 'T', "\r", ''))
+ call assert_equal("u\nu", substitute('uUu', 'U', "\n", ''))
+ call assert_equal("v\<C-H>v", substitute('vVv', 'V', "\b", ''))
+ call assert_equal('w\w', substitute('wWw', 'W', "\\", ''))
+ call assert_equal('XxxX', substitute('X', 'X', '\L\uxXx\l\EX', ''))
+ call assert_equal('yYYy', substitute('Y', 'Y', '\U\lYyY\u\Ey', ''))
+endfunc
+
+func Test_sub_replace_3()
+ set magic&
+ set cpo&
+ call assert_equal('a\a', substitute('aAa', 'A', '\="\\"', ''))
+ call assert_equal('b\\b', substitute('bBb', 'B', '\="\\\\"', ''))
+ call assert_equal("c\rc", substitute('cCc', 'C', "\\=\"\r\"", ''))
+ call assert_equal("d\\\rd", substitute('dDd', 'D', "\\=\"\\\\\r\"", ''))
+ call assert_equal("e\\\\\re", substitute('eEe', 'E', "\\=\"\\\\\\\\\r\"", ''))
+ call assert_equal('f\rf', substitute('fFf', 'F', '\="\\r"', ''))
+ call assert_equal('j\nj', substitute('jJj', 'J', '\="\\n"', ''))
+ call assert_equal("k\<C-M>k", substitute('kKk', 'K', '\="\r"', ''))
+ call assert_equal("l\nl", substitute('lLl', 'L', '\="\n"', ''))
+endfunc
+
+" Test for submatch() on substitute().
+func Test_sub_replace_4()
+ set magic&
+ set cpo&
+ call assert_equal('a\a', substitute('aAa', 'A',
+ \ '\=substitute(submatch(0), ".", "\\", "")', ''))
+ call assert_equal('b\b', substitute('bBb', 'B',
+ \ '\=substitute(submatch(0), ".", "\\\\", "")', ''))
+ call assert_equal("c\<C-V>\<C-M>c", substitute('cCc', 'C', '\=substitute(submatch(0), ".", "\<C-V>\<C-M>", "")', ''))
+ call assert_equal("d\<C-V>\<C-M>d", substitute('dDd', 'D', '\=substitute(submatch(0), ".", "\\\<C-V>\<C-M>", "")', ''))
+ call assert_equal("e\\\<C-V>\<C-M>e", substitute('eEe', 'E', '\=substitute(submatch(0), ".", "\\\\\<C-V>\<C-M>", "")', ''))
+ call assert_equal("f\<C-M>f", substitute('fFf', 'F', '\=substitute(submatch(0), ".", "\\r", "")', ''))
+ call assert_equal("j\nj", substitute('jJj', 'J', '\=substitute(submatch(0), ".", "\\n", "")', ''))
+ call assert_equal("k\rk", substitute('kKk', 'K', '\=substitute(submatch(0), ".", "\r", "")', ''))
+ call assert_equal("l\nl", substitute('lLl', 'L', '\=substitute(submatch(0), ".", "\n", "")', ''))
+endfunc
+
+func Test_sub_replace_5()
+ set magic&
+ set cpo&
+ call assert_equal('A123456789987654321', substitute('A123456789',
+ \ 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)',
+ \ '\=submatch(0) . submatch(9) . submatch(8) . ' .
+ \ 'submatch(7) . submatch(6) . submatch(5) . ' .
+ \ 'submatch(4) . submatch(3) . submatch(2) . submatch(1)',
+ \ ''))
+ call assert_equal("[['A123456789'], ['9'], ['8'], ['7'], ['6'], " .
+ \ "['5'], ['4'], ['3'], ['2'], ['1']]",
+ \ substitute('A123456789',
+ \ 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)',
+ \ '\=string([submatch(0, 1), submatch(9, 1), ' .
+ \ 'submatch(8, 1), submatch(7, 1), submatch(6, 1), ' .
+ \ 'submatch(5, 1), submatch(4, 1), submatch(3, 1), ' .
+ \ 'submatch(2, 1), submatch(1, 1)])',
+ \ ''))
+endfunc
+
+func Test_sub_replace_6()
+ set magic&
+ " set cpo+=/
+ call assert_equal('a', substitute('A', 'A', 'a', ''))
+ call assert_equal('%', substitute('B', 'B', '%', ''))
+ " set cpo-=/
+ call assert_equal('c', substitute('C', 'C', 'c', ''))
+ call assert_equal('%', substitute('D', 'D', '%', ''))
+endfunc
+
+func Test_sub_replace_7()
+ set magic&
+ set cpo&
+ call assert_equal('AA', substitute('AA', 'A.', '\=submatch(0)', ''))
+ call assert_equal("B\nB", substitute("B\nB", 'B.', '\=submatch(0)', ''))
+ call assert_equal("['B\n']B", substitute("B\nB", 'B.', '\=string(submatch(0, 1))', ''))
+ call assert_equal('-abab', substitute('-bb', '\zeb', 'a', 'g'))
+ call assert_equal('c-cbcbc', substitute('-bb', '\ze', 'c', 'g'))
+endfunc
+
+" Test for *:s%* on :substitute.
+func Test_sub_replace_8()
+ new
+ set magic&
+ set cpo&
+ $put =',,X'
+ s/\(^\|,\)\ze\(,\|X\)/\1N/g
+ call assert_equal('N,,NX', getline("$"))
+ $put =',,Y'
+ let cmd = ':s/\(^\|,\)\ze\(,\|Y\)/\1N/gc'
+ call feedkeys(cmd . "\<CR>a", "xt")
+ call assert_equal('N,,NY', getline("$"))
+ :$put =',,Z'
+ let cmd = ':s/\(^\|,\)\ze\(,\|Z\)/\1N/gc'
+ call feedkeys(cmd . "\<CR>yy", "xt")
+ call assert_equal('N,,NZ', getline("$"))
+ enew! | close
+endfunc
+
+func Test_sub_replace_9()
+ new
+ set magic&
+ set cpo&
+ $put ='xxx'
+ call feedkeys(":s/x/X/gc\<CR>yyq", "xt")
+ call assert_equal('XXx', getline("$"))
+ enew! | close
+endfunc
+
+func Test_sub_replace_10()
+ set magic&
+ set cpo&
+ call assert_equal('a1a2a3a', substitute('123', '\zs', 'a', 'g'))
+ call assert_equal('aaa', substitute('123', '\zs.', 'a', 'g'))
+ call assert_equal('1a2a3a', substitute('123', '.\zs', 'a', 'g'))
+ call assert_equal('a1a2a3a', substitute('123', '\ze', 'a', 'g'))
+ call assert_equal('a1a2a3', substitute('123', '\ze.', 'a', 'g'))
+ call assert_equal('aaa', substitute('123', '.\ze', 'a', 'g'))
+ call assert_equal('aa2a3a', substitute('123', '1\|\ze', 'a', 'g'))
+ call assert_equal('1aaa', substitute('123', '1\zs\|[23]', 'a', 'g'))
+endfunc
diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim
new file mode 100644
index 0000000000..245e1f18bb
--- /dev/null
+++ b/src/nvim/testdir/test_swap.vim
@@ -0,0 +1,48 @@
+" Tests for the swap feature
+
+" Tests for 'directory' option.
+func Test_swap_directory()
+ if !has("unix")
+ return
+ endif
+ let content = ['start of testfile',
+ \ 'line 2 Abcdefghij',
+ \ 'line 3 Abcdefghij',
+ \ 'end of testfile']
+ call writefile(content, 'Xtest1')
+
+ " '.', swap file in the same directory as file
+ set dir=.,~
+
+ " Verify that the swap file doesn't exist in the current directory
+ call assert_equal([], glob(".Xtest1*.swp", 1, 1, 1))
+ edit Xtest1
+ let swfname = split(execute("swapname"))[0]
+ call assert_equal([swfname], glob(swfname, 1, 1, 1))
+
+ " './dir', swap file in a directory relative to the file
+ set dir=./Xtest2,.,~
+
+ call mkdir("Xtest2")
+ edit Xtest1
+ call assert_equal([], glob(swfname, 1, 1, 1))
+ let swfname = "Xtest2/Xtest1.swp"
+ call assert_equal(swfname, split(execute("swapname"))[0])
+ call assert_equal([swfname], glob("Xtest2/*", 1, 1, 1))
+
+ " 'dir', swap file in directory relative to the current dir
+ set dir=Xtest.je,~
+
+ call mkdir("Xtest.je")
+ call writefile(content, 'Xtest2/Xtest3')
+ edit Xtest2/Xtest3
+ call assert_equal(["Xtest2/Xtest3"], glob("Xtest2/*", 1, 1, 1))
+ let swfname = "Xtest.je/Xtest3.swp"
+ call assert_equal(swfname, split(execute("swapname"))[0])
+ call assert_equal([swfname], glob("Xtest.je/*", 1, 1, 1))
+
+ set dir&
+ call delete("Xtest1")
+ call delete("Xtest2", "rf")
+ call delete("Xtest.je", "rf")
+endfunc
diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim
index dbab8d9e26..268a153077 100644
--- a/src/nvim/testdir/test_tagjump.vim
+++ b/src/nvim/testdir/test_tagjump.vim
@@ -174,4 +174,60 @@ func Test_tag_symbolic()
%bwipe!
endfunc
+" Tests for tag search with !_TAG_FILE_ENCODING.
+" Depends on the test83-tags2 and test83-tags3 files.
+func Test_tag_file_encoding()
+ throw 'skipped: Nvim removed test83-tags2, test83-tags3'
+ if has('vms')
+ return
+ endif
+
+ if !has('iconv') || iconv("\x82\x60", "cp932", "utf-8") != "\uff21"
+ return
+ endif
+
+ let save_enc = &encoding
+ set encoding=utf8
+
+ let content = ['text for tags1', 'abcdefghijklmnopqrs']
+ call writefile(content, 'Xtags1.txt')
+ let content = ['text for tags2', 'ABC']
+ call writefile(content, 'Xtags2.txt')
+ let content = ['text for tags3', 'ABC']
+ call writefile(content, 'Xtags3.txt')
+ let content = ['!_TAG_FILE_ENCODING utf-8 //', 'abcdefghijklmnopqrs Xtags1.txt /abcdefghijklmnopqrs']
+ call writefile(content, 'Xtags1')
+
+ " case1:
+ new
+ set tags=Xtags1
+ tag abcdefghijklmnopqrs
+ call assert_equal('Xtags1.txt', expand('%:t'))
+ call assert_equal('abcdefghijklmnopqrs', getline('.'))
+ close
+
+ " case2:
+ new
+ set tags=test83-tags2
+ tag /.BC
+ call assert_equal('Xtags2.txt', expand('%:t'))
+ call assert_equal('ABC', getline('.'))
+ close
+
+ " case3:
+ new
+ set tags=test83-tags3
+ tag abc50
+ call assert_equal('Xtags3.txt', expand('%:t'))
+ call assert_equal('ABC', getline('.'))
+ close
+
+ set tags&
+ let &encoding = save_enc
+ call delete('Xtags1.txt')
+ call delete('Xtags2.txt')
+ call delete('Xtags3.txt')
+ call delete('Xtags1')
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_vimscript.vim b/src/nvim/testdir/test_vimscript.vim
index 3cf51a3b0f..5b16f6d205 100644
--- a/src/nvim/testdir/test_vimscript.vim
+++ b/src/nvim/testdir/test_vimscript.vim
@@ -1274,6 +1274,26 @@ func Test_user_command_with_bang()
delcommand Nieuw
endfunc
+" Test for script-local function
+func <SID>DoLast()
+ call append(line('$'), "last line")
+endfunc
+
+func s:DoNothing()
+ call append(line('$'), "nothing line")
+endfunc
+
+func Test_script_local_func()
+ set nocp viminfo+=nviminfo
+ new
+ nnoremap <buffer> _x :call <SID>DoNothing()<bar>call <SID>DoLast()<bar>delfunc <SID>DoNothing<bar>delfunc <SID>DoLast<cr>
+
+ normal _x
+ call assert_equal('nothing line', getline(2))
+ call assert_equal('last line', getline(3))
+ enew! | close
+endfunc
+
"-------------------------------------------------------------------------------
" Modelines {{{1
" vim: ts=8 sw=4 tw=80 fdm=marker
diff --git a/src/nvim/testdir/test_wordcount.vim b/src/nvim/testdir/test_wordcount.vim
new file mode 100644
index 0000000000..75c4e4bffa
--- /dev/null
+++ b/src/nvim/testdir/test_wordcount.vim
@@ -0,0 +1,108 @@
+" Test for wordcount() function
+
+if !has('multi_byte')
+ finish
+endif
+
+func Test_wordcount()
+ let save_enc = &enc
+ set encoding=utf-8
+ set selection=inclusive fileformat=unix fileformats=unix
+
+ new
+
+ " Test 1: empty window
+ call assert_equal({'chars': 0, 'cursor_chars': 0, 'words': 0, 'cursor_words': 0,
+ \ 'bytes': 0, 'cursor_bytes': 0}, wordcount())
+
+ " Test 2: some words, cursor at start
+ call append(1, 'one two three')
+ call cursor([1, 1, 0])
+ call assert_equal({'chars': 15, 'cursor_chars': 1, 'words': 3, 'cursor_words': 0,
+ \ 'bytes': 15, 'cursor_bytes': 1}, wordcount())
+
+ " Test 3: some words, cursor at end
+ %d _
+ call append(1, 'one two three')
+ call cursor([2, 99, 0])
+ call assert_equal({'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3,
+ \ 'bytes': 15, 'cursor_bytes': 14}, wordcount())
+
+ " Test 4: some words, cursor at end, ve=all
+ set ve=all
+ %d _
+ call append(1, 'one two three')
+ call cursor([2, 99, 0])
+ call assert_equal({'chars': 15, 'cursor_chars': 15, 'words': 3, 'cursor_words': 3,
+ \ 'bytes': 15, 'cursor_bytes': 15}, wordcount())
+ set ve=
+
+ " Test 5: several lines with words
+ %d _
+ call append(1, ['one two three', 'one two three', 'one two three'])
+ call cursor([4, 99, 0])
+ call assert_equal({'chars': 43, 'cursor_chars': 42, 'words': 9, 'cursor_words': 9,
+ \ 'bytes': 43, 'cursor_bytes': 42}, wordcount())
+
+ " Test 6: one line with BOM set
+ %d _
+ call append(1, 'one two three')
+ set bomb
+ w! Xtest
+ call cursor([2, 99, 0])
+ call assert_equal({'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3,
+ \ 'bytes': 18, 'cursor_bytes': 14}, wordcount())
+ set nobomb
+ w!
+ call delete('Xtest')
+
+ " Test 7: one line with multibyte words
+ %d _
+ call append(1, ['Äne M¤ne Müh'])
+ call cursor([2, 99, 0])
+ call assert_equal({'chars': 14, 'cursor_chars': 13, 'words': 3, 'cursor_words': 3,
+ \ 'bytes': 17, 'cursor_bytes': 16}, wordcount())
+
+ " Test 8: several lines with multibyte words
+ %d _
+ call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
+ call cursor([3, 99, 0])
+ call assert_equal({'chars': 32, 'cursor_chars': 31, 'words': 7, 'cursor_words': 7,
+ \ 'bytes': 36, 'cursor_bytes': 35}, wordcount())
+
+ " Visual map to capture wordcount() in visual mode
+ vnoremap <expr> <F2> execute("let g:visual_stat = wordcount()")
+
+ " Test 9: visual mode, complete buffer
+ let g:visual_stat = {}
+ %d _
+ call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
+ " start visual mode and select the complete buffer
+ 0
+ exe "normal V2j\<F2>y"
+ call assert_equal({'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 32,
+ \ 'visual_words': 7, 'visual_bytes': 36}, g:visual_stat)
+
+ " Test 10: visual mode (empty)
+ %d _
+ call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
+ " start visual mode and select the complete buffer
+ 0
+ exe "normal v$\<F2>y"
+ call assert_equal({'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 1,
+ \ 'visual_words': 0, 'visual_bytes': 1}, g:visual_stat)
+
+ " Test 11: visual mode, single line
+ %d _
+ call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
+ " start visual mode and select the complete buffer
+ 2
+ exe "normal 0v$\<F2>y"
+ call assert_equal({'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 13,
+ \ 'visual_words': 3, 'visual_bytes': 16}, g:visual_stat)
+
+ set selection& fileformat& fileformats&
+ let &enc = save_enc
+ enew!
+ close
+endfunc
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
index 4ce33fef7b..c290031fbe 100644
--- a/test/functional/terminal/buffer_spec.lua
+++ b/test/functional/terminal/buffer_spec.lua
@@ -201,6 +201,28 @@ describe('terminal buffer', function()
feed([[<C-\><C-n>]])
feed_command('bdelete!')
end)
+
+ describe('handles confirmations', function()
+ it('with :confirm', function()
+ feed_command('terminal')
+ feed('<c-\\><c-n>')
+ feed_command('confirm bdelete')
+ screen:expect('Close "term://', nil, true, nil, true)
+ end)
+
+ it('with &confirm', function()
+ feed_command('terminal')
+ feed('<c-\\><c-n>')
+ feed_command('bdelete')
+ screen:expect('E89', nil, true, nil, true)
+ feed('<cr>')
+ eq('terminal', eval('&buftype'))
+ feed_command('set confirm | bdelete')
+ screen:expect('Close "term://', nil, true, nil, true)
+ feed('y')
+ neq('terminal', eval('&buftype'))
+ end)
+ end)
end)
describe('No heap-buffer-overflow when using', function()
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index 52e108f389..7607131e9b 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -172,9 +172,6 @@ end
function Screen:try_resize(columns, rows)
uimeths.try_resize(columns, rows)
- -- Give ourselves a chance to _handle_resize, which requires using
- -- self.sleep() (for the resize notification) rather than run()
- self:sleep(0.1)
end
function Screen:set_option(option, value)
@@ -210,11 +207,6 @@ function Screen:expect(expected, attr_ids, attr_ignore, condition, any)
row = row:sub(1, #row - 1) -- Last char must be the screen delimiter.
table.insert(expected_rows, row)
end
- if not any then
- assert(self._height == #expected_rows,
- "Expected screen state's row count(" .. #expected_rows
- .. ') differs from configured height(' .. self._height .. ') of Screen.')
- end
end
local ids = attr_ids or self._default_attr_ids
local ignore = attr_ignore or self._default_attr_ignore
@@ -225,6 +217,12 @@ function Screen:expect(expected, attr_ids, attr_ignore, condition, any)
return tostring(res)
end
end
+
+ if expected and not any and self._height ~= #expected_rows then
+ return ("Expected screen state's row count(" .. #expected_rows
+ .. ') differs from configured height(' .. self._height .. ') of Screen.')
+ end
+
local actual_rows = {}
for i = 1, self._height do
actual_rows[i] = self:_row_repr(self._rows[i], ids, ignore)
diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua
index 06e4a19354..6f04cde4d4 100644
--- a/test/functional/ui/screen_basic_spec.lua
+++ b/test/functional/ui/screen_basic_spec.lua
@@ -651,9 +651,10 @@ describe('Screen', function()
it('has minimum width/height values', function()
screen:try_resize(1, 1)
screen:expect([[
- {2:-- INS^ERT --}|
- |
+ resize^ |
+ {2:-- INSERT -} |
]])
+
feed('<esc>:ls')
screen:expect([[
resize |
diff --git a/test/includes/CMakeLists.txt b/test/includes/CMakeLists.txt
index 2846df0e37..4d7e962fbd 100644
--- a/test/includes/CMakeLists.txt
+++ b/test/includes/CMakeLists.txt
@@ -7,6 +7,13 @@ foreach(gen_include ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES})
list(APPEND gen_cflags ${CMAKE_INCLUDE_FLAG_C}${gen_include})
endforeach()
+get_directory_property(gen_cdefs COMPILE_DEFINITIONS)
+foreach(gen_cdef ${gen_cdefs})
+ if(NOT ${gen_cdef} MATCHES "INCLUDE_GENERATED_DECLARATIONS")
+ list(APPEND gen_cflags "-D${gen_cdef}")
+ endif()
+endforeach()
+
foreach(hfile ${PRE_HEADERS})
string(REGEX REPLACE ^pre/ post/ post_hfile ${hfile})
get_filename_component(hdir ${CMAKE_CURRENT_BINARY_DIR}/${post_hfile} PATH)
diff --git a/test/includes/pre/uv-errno.h b/test/includes/pre/uv.h
index 6b80f60e5c..da7818cd07 100644
--- a/test/includes/pre/uv-errno.h
+++ b/test/includes/pre/uv.h
@@ -1,4 +1,4 @@
-#include <uv-errno.h>
+#include <uv.h>
static const int kUV_ENOENT = UV_ENOENT;
static const int kUV_EEXIST = UV_EEXIST;
diff --git a/test/unit/os/fs_spec.lua b/test/unit/os/fs_spec.lua
index ae6dfe6423..ddb438eb3d 100644
--- a/test/unit/os/fs_spec.lua
+++ b/test/unit/os/fs_spec.lua
@@ -27,7 +27,7 @@ cimport('./src/nvim/fileio.h')
local fs = cimport('./src/nvim/os/os.h', './src/nvim/path.h')
cppimport('sys/stat.h')
cppimport('fcntl.h')
-cppimport('uv-errno.h')
+cppimport('uv.h')
local s = ''
for i = 0, 255 do