aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthieu Coudron <mattator@gmail.com>2020-08-15 17:45:18 +0200
committerGitHub <noreply@github.com>2020-08-15 17:45:18 +0200
commit37aa9c9c94551ffed8ba5721d5b8ea8e172d7377 (patch)
treeedc210f304d4353dbeb4224b5e42941f332d7a1d /src
parent75aeb815b4db487186e1f4471b37f54430468c76 (diff)
parent056d99b0f6072030a8946303fce58a86fd83bf57 (diff)
downloadrneovim-37aa9c9c94551ffed8ba5721d5b8ea8e172d7377.tar.gz
rneovim-37aa9c9c94551ffed8ba5721d5b8ea8e172d7377.tar.bz2
rneovim-37aa9c9c94551ffed8ba5721d5b8ea8e172d7377.zip
Merge pull request #12713 from janlazo/vim-8.2.1347
vim-patch:8.1.{573,1674,2097,2098,2341},8.2.{1347,1360,1361,1364,1369,1377,1379,1386,1409,1410,1438,1441,1458}
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval.c5
-rw-r--r--src/nvim/eval.lua1
-rw-r--r--src/nvim/eval/funcs.c8
-rw-r--r--src/nvim/eval/userfunc.c7
-rw-r--r--src/nvim/ex_docmd.c76
-rw-r--r--src/nvim/ex_eval.c21
-rw-r--r--src/nvim/getchar.c3
-rw-r--r--src/nvim/option.c7
-rw-r--r--src/nvim/search.c5
-rw-r--r--src/nvim/shada.c2
-rw-r--r--src/nvim/testdir/summarize.vim1
-rw-r--r--src/nvim/testdir/test_autocmd.vim2
-rw-r--r--src/nvim/testdir/test_compiler.vim4
-rw-r--r--src/nvim/testdir/test_debugger.vim125
-rw-r--r--src/nvim/testdir/test_eval_stuff.vim24
-rw-r--r--src/nvim/testdir/test_expand_func.vim47
-rw-r--r--src/nvim/testdir/test_expr.vim3
-rw-r--r--src/nvim/testdir/test_filetype.vim7
-rw-r--r--src/nvim/testdir/test_filter_map.vim1
-rw-r--r--src/nvim/testdir/test_interrupt.vim27
-rw-r--r--src/nvim/testdir/test_mksession.vim122
-rw-r--r--src/nvim/testdir/test_options.vim10
-rw-r--r--src/nvim/testdir/test_usercommands.vim28
-rw-r--r--src/nvim/tui/tui.c5
24 files changed, 464 insertions, 77 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 0cad5fd6c1..b37fd85659 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -760,7 +760,7 @@ int eval_expr_typval(const typval_T *expr, typval_T *argv,
if (eval1_emsg(&s, rettv, true) == FAIL) {
return FAIL;
}
- if (*s != NUL) { // check for trailing chars after expr
+ if (*skipwhite(s) != NUL) { // check for trailing chars after expr
tv_clear(rettv);
emsgf(_(e_invexpr2), s);
return FAIL;
@@ -2086,6 +2086,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
tv_clear(&var1);
return NULL;
}
+ p = skipwhite(p);
}
// Optionally get the second index [ :expr].
@@ -5364,7 +5365,7 @@ static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate)
if (eval1(&start, &tv, false) == FAIL) { // recursive!
return FAIL;
}
- if (*start == '}') {
+ if (*skipwhite(start) == '}') {
return NOTDONE;
}
}
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 023c60f118..a5544435d2 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -191,6 +191,7 @@ return {
inputsave={},
inputsecret={args={1, 2}},
insert={args={2, 3}},
+ interrupt={args=0},
invert={args=1},
isdirectory={args=1},
isinf={args=1},
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 1a80d4d4bd..a81f789f0f 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -4717,6 +4717,14 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
+// "interrupt()" function
+static void f_interrupt(typval_T *argvars FUNC_ATTR_UNUSED,
+ typval_T *rettv FUNC_ATTR_UNUSED,
+ FunPtr fptr FUNC_ATTR_UNUSED)
+{
+ got_int = true;
+}
+
/*
* "invert(expr)" function
*/
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index 229f0e8dde..46eccd5181 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -3457,12 +3457,7 @@ bool set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID)
char_u *register_cfunc(cfunc_T cb, cfunc_free_T cb_free, void *state)
{
char_u *name = get_lambda_name();
- ufunc_T *fp = NULL;
-
- fp = xcalloc(1, offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
- if (fp == NULL) {
- return NULL;
- }
+ ufunc_T *fp = xcalloc(1, offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
fp->uf_refcount = 1;
fp->uf_varargs = true;
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 5bf6aa73c6..064cebe016 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -5026,8 +5026,13 @@ static int uc_add_command(char_u *name, size_t name_len, char_u *rep,
}
if (cmp == 0) {
- if (!force) {
- EMSG(_("E174: Command already exists: add ! to replace it"));
+ // Command can be replaced with "command!" and when sourcing the
+ // same script again, but only once.
+ if (!force
+ && (cmd->uc_script_ctx.sc_sid != current_sctx.sc_sid
+ || cmd->uc_script_ctx.sc_seq == current_sctx.sc_seq)) {
+ EMSG2(_("E174: Command already exists: add ! to replace it: %s"),
+ name);
goto fail;
}
@@ -8586,6 +8591,24 @@ static void ex_tag_cmd(exarg_T *eap, char_u *name)
eap->forceit, TRUE);
}
+enum {
+ SPEC_PERC = 0,
+ SPEC_HASH,
+ SPEC_CWORD,
+ SPEC_CCWORD,
+ SPEC_CEXPR,
+ SPEC_CFILE,
+ SPEC_SFILE,
+ SPEC_SLNUM,
+ SPEC_STACK,
+ SPEC_AFILE,
+ SPEC_ABUF,
+ SPEC_AMATCH,
+ SPEC_SFLNUM,
+ SPEC_SID,
+ // SPEC_CLIENT,
+};
+
/*
* Check "str" for starting with a special cmdline variable.
* If found return one of the SPEC_ values and set "*usedlen" to the length of
@@ -8596,30 +8619,21 @@ ssize_t find_cmdline_var(const char_u *src, size_t *usedlen)
{
size_t len;
static char *(spec_str[]) = {
- "%",
-#define SPEC_PERC 0
- "#",
-#define SPEC_HASH (SPEC_PERC + 1)
- "<cword>", // cursor word
-#define SPEC_CWORD (SPEC_HASH + 1)
- "<cWORD>", // cursor WORD
-#define SPEC_CCWORD (SPEC_CWORD + 1)
- "<cexpr>", // expr under cursor
-#define SPEC_CEXPR (SPEC_CCWORD + 1)
- "<cfile>", // cursor path name
-#define SPEC_CFILE (SPEC_CEXPR + 1)
- "<sfile>", // ":so" file name
-#define SPEC_SFILE (SPEC_CFILE + 1)
- "<slnum>", // ":so" file line number
-#define SPEC_SLNUM (SPEC_SFILE + 1)
- "<afile>", // autocommand file name
-#define SPEC_AFILE (SPEC_SLNUM + 1)
- "<abuf>", // autocommand buffer number
-#define SPEC_ABUF (SPEC_AFILE + 1)
- "<amatch>", // autocommand match name
-#define SPEC_AMATCH (SPEC_ABUF + 1)
- "<sflnum>", // script file line number
-#define SPEC_SFLNUM (SPEC_AMATCH + 1)
+ [SPEC_PERC] = "%",
+ [SPEC_HASH] = "#",
+ [SPEC_CWORD] = "<cword>", // cursor word
+ [SPEC_CCWORD] = "<cWORD>", // cursor WORD
+ [SPEC_CEXPR] = "<cexpr>", // expr under cursor
+ [SPEC_CFILE] = "<cfile>", // cursor path name
+ [SPEC_SFILE] = "<sfile>", // ":so" file name
+ [SPEC_SLNUM] = "<slnum>", // ":so" file line number
+ [SPEC_STACK] = "<stack>", // call stack
+ [SPEC_AFILE] = "<afile>", // autocommand file name
+ [SPEC_ABUF] = "<abuf>", // autocommand buffer number
+ [SPEC_AMATCH] = "<amatch>", // autocommand match name
+ [SPEC_SFLNUM] = "<sflnum>", // script file line number
+ [SPEC_SID] = "<SID>", // script ID: <SNR>123_
+ // [SPEC_CLIENT] = "<client>",
};
for (size_t i = 0; i < ARRAY_SIZE(spec_str); ++i) {
@@ -8866,6 +8880,16 @@ eval_vars (
result = (char_u *)strbuf;
break;
+ case SPEC_SID:
+ if (current_sctx.sc_sid <= 0) {
+ *errormsg = (char_u *)_(e_usingsid);
+ return NULL;
+ }
+ snprintf(strbuf, sizeof(strbuf), "<SNR>%" PRIdSCID "_",
+ current_sctx.sc_sid);
+ result = (char_u *)strbuf;
+ break;
+
default:
// should not happen
*errormsg = (char_u *)"";
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index 81274fcf2a..e99e5b01cd 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -87,17 +87,16 @@
*/
static int cause_abort = FALSE;
-/*
- * Return TRUE when immediately aborting on error, or when an interrupt
- * occurred or an exception was thrown but not caught. Use for ":{range}call"
- * to check whether an aborted function that does not handle a range itself
- * should be called again for the next line in the range. Also used for
- * cancelling expression evaluation after a function call caused an immediate
- * abort. Note that the first emsg() call temporarily resets "force_abort"
- * until the throw point for error messages has been reached. That is, during
- * cancellation of an expression evaluation after an aborting function call or
- * due to a parsing error, aborting() always returns the same value.
- */
+// Return true when immediately aborting on error, or when an interrupt
+// occurred or an exception was thrown but not caught. Use for ":{range}call"
+// to check whether an aborted function that does not handle a range itself
+// should be called again for the next line in the range. Also used for
+// cancelling expression evaluation after a function call caused an immediate
+// abort. Note that the first emsg() call temporarily resets "force_abort"
+// until the throw point for error messages has been reached. That is, during
+// cancellation of an expression evaluation after an aborting function call or
+// due to a parsing error, aborting() always returns the same value.
+// "got_int" is also set by calling interrupt().
int aborting(void)
{
return (did_emsg && force_abort) || got_int || current_exception;
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index dc11e4a232..c35398cd8d 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -456,6 +456,9 @@ void flush_buffers(flush_buffers_T flush_typeahead)
typebuf.tb_silent = 0;
cmd_silent = false;
typebuf.tb_no_abbr_cnt = 0;
+ if (++typebuf.tb_change_cnt == 0) {
+ typebuf.tb_change_cnt = 1;
+ }
}
/*
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 168160834b..a70a634966 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -1355,11 +1355,11 @@ int do_set(
// Disallow changing some options from modelines.
if (opt_flags & OPT_MODELINE) {
if (flags & (P_SECURE | P_NO_ML)) {
- errmsg = (char_u *)_("E520: Not allowed in a modeline");
+ errmsg = (char_u *)N_("E520: Not allowed in a modeline");
goto skip;
}
if ((flags & P_MLE) && !p_mle) {
- errmsg = (char_u *)_(
+ errmsg = (char_u *)N_(
"E992: Not allowed in a modeline when 'modelineexpr' is off");
goto skip;
}
@@ -1376,7 +1376,7 @@ int do_set(
// Disallow changing some options in the sandbox
if (sandbox != 0 && (flags & P_SECURE)) {
- errmsg = (char_u *)_(e_sandbox);
+ errmsg = e_sandbox;
goto skip;
}
@@ -1712,6 +1712,7 @@ int do_set(
#ifdef BACKSLASH_IN_FILENAME
&& !((flags & P_EXPAND)
&& vim_isfilec(arg[1])
+ && !ascii_iswhite(arg[1])
&& (arg[1] != '\\'
|| (s == newval
&& arg[2] != '\\')))
diff --git a/src/nvim/search.c b/src/nvim/search.c
index b105d99d7c..fc82e81472 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -1612,8 +1612,9 @@ static bool find_rawstring_end(char_u *linep, pos_T *startpos, pos_T *endpos)
if (lnum == endpos->lnum && (colnr_T)(p - line) >= endpos->col) {
break;
}
- if (*p == ')' && p[delim_len + 1] == '"'
- && STRNCMP(delim_copy, p + 1, delim_len) == 0) {
+ if (*p == ')'
+ && STRNCMP(delim_copy, p + 1, delim_len) == 0
+ && p[delim_len + 1] == '"') {
found = true;
break;
}
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index aa19d1db1f..2444910bb3 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -4148,7 +4148,7 @@ static inline size_t shada_init_jumps(
}
const char *const fname = (char *) (fm.fmark.fnum == 0
? (fm.fname == NULL ? NULL : fm.fname)
- : buf->b_ffname);
+ : buf ? buf->b_ffname : NULL);
if (fname == NULL) {
continue;
}
diff --git a/src/nvim/testdir/summarize.vim b/src/nvim/testdir/summarize.vim
index 7f8f758a71..da5856a2e7 100644
--- a/src/nvim/testdir/summarize.vim
+++ b/src/nvim/testdir/summarize.vim
@@ -1,3 +1,4 @@
+set cpo&vim
if 1
" This is executed only with the eval feature
set nocompatible
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index d116246ef3..3dd68873d4 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -1125,7 +1125,7 @@ func Test_change_mark_in_autocmds()
write
au! BufWritePre
- if executable('cat')
+ if has('unix')
write XtestFilter
write >> XtestFilter
diff --git a/src/nvim/testdir/test_compiler.vim b/src/nvim/testdir/test_compiler.vim
index 6bb602717f..9101f8cfa0 100644
--- a/src/nvim/testdir/test_compiler.vim
+++ b/src/nvim/testdir/test_compiler.vim
@@ -42,12 +42,12 @@ func Test_compiler_without_arg()
let a = split(execute('compiler'))
call assert_match(runtime .. '/compiler/ant.vim$', a[0])
call assert_match(runtime .. '/compiler/bcc.vim$', a[1])
- call assert_match(runtime .. '/compiler/xmlwf.vim$', a[-1])
+ call assert_match(runtime .. '/compiler/xo.vim$', a[-1])
endfunc
func Test_compiler_completion()
call feedkeys(":compiler \<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_match('^"compiler ant bcc .* xmlwf$', @:)
+ call assert_match('^"compiler ant bcc .* xmlwf xo$', @:)
call feedkeys(":compiler p\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"compiler pbx perl php pylint pyunit', @:)
diff --git a/src/nvim/testdir/test_debugger.vim b/src/nvim/testdir/test_debugger.vim
index 811717208e..59d51b855b 100644
--- a/src/nvim/testdir/test_debugger.vim
+++ b/src/nvim/testdir/test_debugger.vim
@@ -316,3 +316,128 @@ func Test_Debugger()
call delete('Xtest.vim')
endfunc
+
+" Test for setting a breakpoint on a :endif where the :if condition is false
+" and then quit the script. This should generate an interrupt.
+func Test_breakpt_endif_intr()
+ func F()
+ let g:Xpath ..= 'a'
+ if v:false
+ let g:Xpath ..= 'b'
+ endif
+ invalid_command
+ endfunc
+
+ let g:Xpath = ''
+ breakadd func 4 F
+ try
+ let caught_intr = 0
+ debuggreedy
+ call feedkeys(":call F()\<CR>quit\<CR>", "xt")
+ call F()
+ catch /^Vim:Interrupt$/
+ call assert_match('\.F, line 4', v:throwpoint)
+ let caught_intr = 1
+ endtry
+ 0debuggreedy
+ call assert_equal(1, caught_intr)
+ call assert_equal('a', g:Xpath)
+ breakdel *
+ delfunc F
+endfunc
+
+" Test for setting a breakpoint on a :else where the :if condition is false
+" and then quit the script. This should generate an interrupt.
+func Test_breakpt_else_intr()
+ func F()
+ let g:Xpath ..= 'a'
+ if v:false
+ let g:Xpath ..= 'b'
+ else
+ invalid_command
+ endif
+ invalid_command
+ endfunc
+
+ let g:Xpath = ''
+ breakadd func 4 F
+ try
+ let caught_intr = 0
+ debuggreedy
+ call feedkeys(":call F()\<CR>quit\<CR>", "xt")
+ call F()
+ catch /^Vim:Interrupt$/
+ call assert_match('\.F, line 4', v:throwpoint)
+ let caught_intr = 1
+ endtry
+ 0debuggreedy
+ call assert_equal(1, caught_intr)
+ call assert_equal('a', g:Xpath)
+ breakdel *
+ delfunc F
+endfunc
+
+" Test for setting a breakpoint on a :endwhile where the :while condition is
+" false and then quit the script. This should generate an interrupt.
+func Test_breakpt_endwhile_intr()
+ func F()
+ let g:Xpath ..= 'a'
+ while v:false
+ let g:Xpath ..= 'b'
+ endwhile
+ invalid_command
+ endfunc
+
+ let g:Xpath = ''
+ breakadd func 4 F
+ try
+ let caught_intr = 0
+ debuggreedy
+ call feedkeys(":call F()\<CR>quit\<CR>", "xt")
+ call F()
+ catch /^Vim:Interrupt$/
+ call assert_match('\.F, line 4', v:throwpoint)
+ let caught_intr = 1
+ endtry
+ 0debuggreedy
+ call assert_equal(1, caught_intr)
+ call assert_equal('a', g:Xpath)
+ breakdel *
+ delfunc F
+endfunc
+
+" Test for setting a breakpoint on an :endtry where an exception is pending to
+" be processed and then quit the script. This should generate an interrupt and
+" the thrown exception should be ignored.
+func Test_breakpt_endtry_intr()
+ func F()
+ try
+ let g:Xpath ..= 'a'
+ throw "abc"
+ endtry
+ invalid_command
+ endfunc
+
+ let g:Xpath = ''
+ breakadd func 4 F
+ try
+ let caught_intr = 0
+ let caught_abc = 0
+ debuggreedy
+ call feedkeys(":call F()\<CR>quit\<CR>", "xt")
+ call F()
+ catch /abc/
+ let caught_abc = 1
+ catch /^Vim:Interrupt$/
+ call assert_match('\.F, line 4', v:throwpoint)
+ let caught_intr = 1
+ endtry
+ 0debuggreedy
+ call assert_equal(1, caught_intr)
+ call assert_equal(0, caught_abc)
+ call assert_equal('a', g:Xpath)
+ breakdel *
+ delfunc F
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_eval_stuff.vim b/src/nvim/testdir/test_eval_stuff.vim
index 4b54a0d39f..061364fb73 100644
--- a/src/nvim/testdir/test_eval_stuff.vim
+++ b/src/nvim/testdir/test_eval_stuff.vim
@@ -108,3 +108,27 @@ func Test_skip_after_throw()
catch /something/
endtry
endfunc
+
+func Test_curly_assignment()
+ let s:svar = 'svar'
+ let g:gvar = 'gvar'
+ let lname = 'gvar'
+ let gname = 'gvar'
+ let {'s:'.lname} = {'g:'.gname}
+ call assert_equal('gvar', s:gvar)
+ let s:gvar = ''
+ let { 's:'.lname } = { 'g:'.gname }
+ call assert_equal('gvar', s:gvar)
+ let s:gvar = ''
+ let { 's:' . lname } = { 'g:' . gname }
+ call assert_equal('gvar', s:gvar)
+ let s:gvar = ''
+ let { 's:' .. lname } = { 'g:' .. gname }
+ call assert_equal('gvar', s:gvar)
+
+ unlet s:svar
+ unlet s:gvar
+ unlet g:gvar
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_expand_func.vim b/src/nvim/testdir/test_expand_func.vim
index fb29c3eb7a..9588d3b89d 100644
--- a/src/nvim/testdir/test_expand_func.vim
+++ b/src/nvim/testdir/test_expand_func.vim
@@ -1,5 +1,7 @@
" Tests for expand()
+source shared.vim
+
let s:sfile = expand('<sfile>')
let s:slnum = str2nr(expand('<slnum>'))
let s:sflnum = str2nr(expand('<sflnum>'))
@@ -16,6 +18,25 @@ func s:expand_sflnum()
return str2nr(expand('<sflnum>'))
endfunc
+" This test depends on the location in the test file, put it first.
+func Test_expand_sflnum()
+ call assert_equal(7, s:sflnum)
+ call assert_equal(24, str2nr(expand('<sflnum>')))
+
+ " Line-continuation
+ call assert_equal(
+ \ 27,
+ \ str2nr(expand('<sflnum>')))
+
+ " Call in script-local function
+ call assert_equal(18, s:expand_sflnum())
+
+ " Call in command
+ command Flnum echo expand('<sflnum>')
+ call assert_equal(36, str2nr(trim(execute('Flnum'))))
+ delcommand Flnum
+endfunc
+
func Test_expand_sfile()
call assert_match('test_expand_func\.vim$', s:sfile)
call assert_match('^function .*\.\.Test_expand_sfile$', expand('<sfile>'))
@@ -30,7 +51,7 @@ func Test_expand_sfile()
endfunc
func Test_expand_slnum()
- call assert_equal(4, s:slnum)
+ call assert_equal(6, s:slnum)
call assert_equal(2, str2nr(expand('<slnum>')))
" Line-continuation
@@ -47,20 +68,14 @@ func Test_expand_slnum()
delcommand Slnum
endfunc
-func Test_expand_sflnum()
- call assert_equal(5, s:sflnum)
- call assert_equal(52, str2nr(expand('<sflnum>')))
-
- " Line-continuation
- call assert_equal(
- \ 55,
- \ str2nr(expand('<sflnum>')))
-
- " Call in script-local function
- call assert_equal(16, s:expand_sflnum())
+func s:sid_test()
+ return 'works'
+endfunc
- " Call in command
- command Flnum echo expand('<sflnum>')
- call assert_equal(64, str2nr(trim(execute('Flnum'))))
- delcommand Flnum
+func Test_expand_SID()
+ let sid = expand('<SID>')
+ execute 'let g:sid_result = ' .. sid .. 'sid_test()'
+ call assert_equal('works', g:sid_result)
endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim
index 264d8b000f..b8d6f5aa7d 100644
--- a/src/nvim/testdir/test_expr.vim
+++ b/src/nvim/testdir/test_expr.vim
@@ -49,6 +49,9 @@ func Test_dict()
let d['a'] = 'aaa'
call assert_equal('none', d[''])
call assert_equal('aaa', d['a'])
+
+ let d[ 'b' ] = 'bbb'
+ call assert_equal('bbb', d[ 'b' ])
endfunc
func Test_strgetchar()
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index 2e280417ae..8cf7400f7a 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -73,7 +73,7 @@ let s:filename_checks = {
\ 'autoit': ['file.au3'],
\ 'automake': ['GNUmakefile.am'],
\ 'ave': ['file.ave'],
- \ 'awk': ['file.awk'],
+ \ 'awk': ['file.awk', 'file.gawk'],
\ 'b': ['file.mch', 'file.ref', 'file.imp'],
\ 'bc': ['file.bc'],
\ 'bdf': ['file.bdf'],
@@ -140,7 +140,7 @@ let s:filename_checks = {
\ 'dnsmasq': ['/etc/dnsmasq.conf'],
\ 'dockerfile': ['Dockerfile', 'file.Dockerfile'],
\ 'dosbatch': ['file.bat', 'file.sys'],
- \ 'dosini': ['.editorconfig', '/etc/pacman.conf', '/etc/yum.conf', 'file.ini'],
+ \ 'dosini': ['.editorconfig', '/etc/pacman.conf', '/etc/yum.conf', 'file.ini', 'npmrc', '.npmrc', 'php.ini', 'php.ini-5'],
\ 'dot': ['file.dot', 'file.gv'],
\ 'dracula': ['file.drac', 'file.drc', 'filelvs', 'filelpe'],
\ 'dsl': ['file.dsl'],
@@ -596,7 +596,8 @@ let s:script_checks = {
\ 'bc': [['#!/path/bc']],
\ 'sed': [['#!/path/sed']],
\ 'ocaml': [['#!/path/ocaml']],
- \ 'awk': [['#!/path/awk']],
+ \ 'awk': [['#!/path/awk'],
+ \ ['#!/path/gawk']],
\ 'wml': [['#!/path/wml']],
\ 'scheme': [['#!/path/scheme']],
\ 'cfengine': [['#!/path/cfengine']],
diff --git a/src/nvim/testdir/test_filter_map.vim b/src/nvim/testdir/test_filter_map.vim
index 1dd3a5b29f..a15567bcf2 100644
--- a/src/nvim/testdir/test_filter_map.vim
+++ b/src/nvim/testdir/test_filter_map.vim
@@ -11,6 +11,7 @@ func Test_filter_map_list_expr_string()
call assert_equal([2, 4, 6, 8], map([1, 2, 3, 4], 'v:val * 2'))
call assert_equal([0, 2, 4, 6], map([1, 2, 3, 4], 'v:key * 2'))
call assert_equal([9, 9, 9, 9], map([1, 2, 3, 4], 9))
+ call assert_equal([7, 7, 7], map([1, 2, 3], ' 7 '))
endfunc
" dict with expression string
diff --git a/src/nvim/testdir/test_interrupt.vim b/src/nvim/testdir/test_interrupt.vim
new file mode 100644
index 0000000000..111752d16a
--- /dev/null
+++ b/src/nvim/testdir/test_interrupt.vim
@@ -0,0 +1,27 @@
+" Test behavior of interrupt()
+
+let s:bufwritepre_called = 0
+let s:bufwritepost_called = 0
+
+func s:bufwritepre()
+ let s:bufwritepre_called = 1
+ call interrupt()
+endfunction
+
+func s:bufwritepost()
+ let s:bufwritepost_called = 1
+endfunction
+
+func Test_interrupt()
+ new Xfile
+ let n = 0
+ try
+ au BufWritePre Xfile call s:bufwritepre()
+ au BufWritePost Xfile call s:bufwritepost()
+ w!
+ catch /^Vim:Interrupt$/
+ endtry
+ call assert_equal(1, s:bufwritepre_called)
+ call assert_equal(0, s:bufwritepost_called)
+ call assert_equal(0, filereadable('Xfile'))
+endfunc
diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim
index 9c9e04be07..1e22f7e9c9 100644
--- a/src/nvim/testdir/test_mksession.vim
+++ b/src/nvim/testdir/test_mksession.vim
@@ -155,7 +155,7 @@ endfunc
" Verify that arglist is stored correctly to the session file.
func Test_mksession_arglist()
- argdel *
+ %argdel
next file1 file2 file3 file4
mksession! Xtest_mks.out
source Xtest_mks.out
@@ -307,6 +307,126 @@ func Test_mksession_quote_in_filename()
call delete('Xtest_mks_quoted.out')
endfunc
+" Test for storing global variables in a session file
+func Test_mksession_globals()
+ set sessionoptions+=globals
+
+ " create different global variables
+ let g:Global_string = "Sun is shining"
+ let g:Global_count = 100
+ let g:Global_pi = 3.14
+
+ mksession! Xtest_mks.out
+
+ unlet g:Global_string
+ unlet g:Global_count
+ unlet g:Global_pi
+
+ source Xtest_mks.out
+ call assert_equal("Sun is shining", g:Global_string)
+ call assert_equal(100, g:Global_count)
+ call assert_equal(3.14, g:Global_pi)
+
+ unlet g:Global_string
+ unlet g:Global_count
+ unlet g:Global_pi
+ call delete('Xtest_mks.out')
+ set sessionoptions&
+endfunc
+
+" Test for changing backslash to forward slash in filenames
+func Test_mksession_slash()
+ if exists('+shellslash')
+ throw 'Skipped: cannot use backslash in file name'
+ endif
+ enew
+ %bwipe!
+ e a\\b\\c
+ mksession! Xtest_mks1.out
+ set sessionoptions+=slash
+ mksession! Xtest_mks2.out
+
+ %bwipe!
+ source Xtest_mks1.out
+ call assert_equal('a/b/c', bufname(''))
+ %bwipe!
+ source Xtest_mks2.out
+ call assert_equal('a/b/c', bufname(''))
+
+ %bwipe!
+ call delete('Xtest_mks1.out')
+ call delete('Xtest_mks2.out')
+ set sessionoptions&
+endfunc
+
+" Test for storing global and local argument list in a session file
+func Test_mkseesion_arglocal()
+ enew | only
+ n a b c
+ new
+ arglocal
+ mksession! Xtest_mks.out
+
+ %bwipe!
+ %argdelete
+ argglobal
+ source Xtest_mks.out
+ call assert_equal(2, winnr('$'))
+ call assert_equal(2, arglistid(1))
+ call assert_equal(0, arglistid(2))
+
+ %bwipe!
+ %argdelete
+ argglobal
+ call delete('Xtest_mks.out')
+endfunc
+
+" Test for changing directory to the session file directory
+func Test_mksession_sesdir()
+ call mkdir('Xproj')
+ mksession! Xproj/Xtest_mks1.out
+ set sessionoptions-=curdir
+ set sessionoptions+=sesdir
+ mksession! Xproj/Xtest_mks2.out
+
+ source Xproj/Xtest_mks1.out
+ call assert_equal('testdir', fnamemodify(getcwd(), ':t'))
+ source Xproj/Xtest_mks2.out
+ call assert_equal('Xproj', fnamemodify(getcwd(), ':t'))
+ cd ..
+
+ set sessionoptions&
+ call delete('Xproj', 'rf')
+endfunc
+
+" Test for storing the 'lines' and 'columns' settings
+func Test_mksession_resize()
+ mksession! Xtest_mks1.out
+ set sessionoptions+=resize
+ mksession! Xtest_mks2.out
+
+ let lines = readfile('Xtest_mks1.out')
+ let found_resize = v:false
+ for line in lines
+ if line =~ '^set lines='
+ let found_resize = v:true
+ endif
+ endfor
+ call assert_equal(v:false, found_resize)
+ let lines = readfile('Xtest_mks2.out')
+ let found_resize = v:false
+ for line in lines
+ if line =~ '^set lines='
+ let found_resize = v:true
+ endif
+ endfor
+ call assert_equal(v:true, found_resize)
+
+ call delete('Xtest_mks1.out')
+ call delete('Xtest_mks2.out')
+ set sessionoptions&
+endfunc
+
func s:ClearMappings()
mapclear
omapclear
diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim
index 04a5c62f66..9e8da74db7 100644
--- a/src/nvim/testdir/test_options.vim
+++ b/src/nvim/testdir/test_options.vim
@@ -576,3 +576,13 @@ func Test_opt_boolean()
set number&
endfunc
+" Test for setting option value containing spaces with isfname+=32
+func Test_isfname_with_options()
+ set isfname+=32
+ setlocal keywordprg=:term\ help.exe
+ call assert_equal(':term help.exe', &keywordprg)
+ set isfname&
+ setlocal keywordprg&
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_usercommands.vim b/src/nvim/testdir/test_usercommands.vim
index 2c7cb7bab7..fdd3a9abeb 100644
--- a/src/nvim/testdir/test_usercommands.vim
+++ b/src/nvim/testdir/test_usercommands.vim
@@ -184,6 +184,34 @@ func Test_Ambiguous()
call assert_fails("\x4ei\041", 'E492: Not an editor command: Ni!')
endfunc
+func Test_redefine_on_reload()
+ call writefile(['command ExistingCommand echo "yes"'], 'Xcommandexists')
+ call assert_equal(0, exists(':ExistingCommand'))
+ source Xcommandexists
+ call assert_equal(2, exists(':ExistingCommand'))
+ " Redefining a command when reloading a script is OK.
+ source Xcommandexists
+ call assert_equal(2, exists(':ExistingCommand'))
+
+ " But redefining in another script is not OK.
+ call writefile(['command ExistingCommand echo "yes"'], 'Xcommandexists2')
+ call assert_fails('source Xcommandexists2', 'E174:')
+ call delete('Xcommandexists2')
+
+ " And defining twice in one script is not OK.
+ delcommand ExistingCommand
+ call assert_equal(0, exists(':ExistingCommand'))
+ call writefile([
+ \ 'command ExistingCommand echo "yes"',
+ \ 'command ExistingCommand echo "no"',
+ \ ], 'Xcommandexists')
+ call assert_fails('source Xcommandexists', 'E174:')
+ call assert_equal(2, exists(':ExistingCommand'))
+
+ call delete('Xcommandexists')
+ delcommand ExistingCommand
+endfunc
+
func Test_CmdUndefined()
call assert_fails('Doit', 'E492:')
au CmdUndefined Doit :command Doit let g:didit = 'yes'
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index bfd9435c49..860271d209 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -1817,9 +1817,8 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
|| tmux // per tmux manual page
// https://lists.gnu.org/archive/html/screen-devel/2013-03/msg00000.html
|| (true_screen
- && (!screen_host_linuxvt
- || (screen_host_linuxvt
- && (xterm_version || (vte_version > 0) || colorterm))))
+ && (screen_host_linuxvt
+ && (xterm_version || (vte_version > 0) || colorterm)))
// Since GNU Screen does not support DECSCUSR, DECSCUSR is wrapped
// in DCS and output to the host terminal.
|| st // #7641