Skip to content

Commit

Permalink
Merge remote-tracking branch 'vim/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
ychin committed Dec 20, 2020
2 parents 08d4327 + 17f700a commit a4252b3
Show file tree
Hide file tree
Showing 13 changed files with 184 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/dict.c
Expand Up @@ -1073,7 +1073,7 @@ dict_extend(dict_T *d1, dict_T *d2, char_u *action)
&& HI2DI(hi2)->di_tv.v_type == VAR_FUNC
&& var_wrong_func_name(hi2->hi_key, di1 == NULL))
break;
if (!valid_varname(hi2->hi_key))
if (!valid_varname(hi2->hi_key, TRUE))
break;
}
if (di1 == NULL)
Expand Down
2 changes: 1 addition & 1 deletion src/eval.c
Expand Up @@ -1049,7 +1049,7 @@ get_lval(
wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE
&& rettv->v_type == VAR_FUNC
&& var_wrong_func_name(key, lp->ll_di == NULL))
|| !valid_varname(key);
|| !valid_varname(key, TRUE);
if (len != -1)
key[len] = prevval;
if (wrong)
Expand Down
12 changes: 7 additions & 5 deletions src/evalvars.c
Expand Up @@ -3197,8 +3197,10 @@ set_var_const(
goto failed;
}

// Make sure the variable name is valid.
if (!valid_varname(varname))
// Make sure the variable name is valid. In Vim9 script an autoload
// variable must be prefixed with "g:".
if (!valid_varname(varname, !vim9script
|| STRNCMP(name, "g:", 2) == 0))
goto failed;

di = alloc(sizeof(dictitem_T) + STRLEN(varname));
Expand Down Expand Up @@ -3351,17 +3353,17 @@ value_check_lock(int lock, char_u *name, int use_gettext)
}

/*
* Check if a variable name is valid.
* Check if a variable name is valid. When "autoload" is true "#" is allowed.
* Return FALSE and give an error if not.
*/
int
valid_varname(char_u *varname)
valid_varname(char_u *varname, int autoload)
{
char_u *p;

for (p = varname; *p != NUL; ++p)
if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))
&& *p != AUTOLOAD_CHAR)
&& !(autoload && *p == AUTOLOAD_CHAR))
{
semsg(_(e_illvar), varname);
return FALSE;
Expand Down
9 changes: 4 additions & 5 deletions src/ex_eval.c
Expand Up @@ -606,6 +606,8 @@ discard_exception(except_T *excp, int was_finished)
{
char_u *saved_IObuff;

if (current_exception == excp)
current_exception = NULL;
if (excp == NULL)
{
internal_error("discard_exception()");
Expand Down Expand Up @@ -654,10 +656,7 @@ discard_exception(except_T *excp, int was_finished)
discard_current_exception(void)
{
if (current_exception != NULL)
{
discard_exception(current_exception, FALSE);
current_exception = NULL;
}
did_throw = FALSE;
need_rethrow = FALSE;
}
Expand Down Expand Up @@ -2284,8 +2283,8 @@ cleanup_conditionals(
// Cancel the pending exception. This is in the
// finally clause, so that the stack of the
// caught exceptions is not involved.
discard_exception((except_T *)
cstack->cs_exception[idx],
discard_exception(
(except_T *)cstack->cs_exception[idx],
FALSE);
}
else
Expand Down
2 changes: 1 addition & 1 deletion src/proto/evalvars.pro
Expand Up @@ -75,7 +75,7 @@ int var_check_lock(int flags, char_u *name, int use_gettext);
int var_check_fixed(int flags, char_u *name, int use_gettext);
int var_wrong_func_name(char_u *name, int new_var);
int value_check_lock(int lock, char_u *name, int use_gettext);
int valid_varname(char_u *varname);
int valid_varname(char_u *varname, int autoload);
void reset_v_option_vars(void);
void assert_error(garray_T *gap);
int var_exists(char_u *var);
Expand Down
47 changes: 47 additions & 0 deletions src/testdir/test_startup.vim
Expand Up @@ -743,6 +743,53 @@ func Test_t_arg()
call delete('Xfile1')
endfunc

" Test the '-T' argument which sets the 'term' option.
func Test_T_arg()
CheckNotGui
let after =<< trim [CODE]
call writefile([&term], "Xtest_T_arg")
qall
[CODE]

for t in ['builtin_dumb', 'builtin_ansi']
if RunVim([], after, '-T ' .. t)
let lines = readfile('Xtest_T_arg')
call assert_equal([t], lines)
endif
endfor

call delete('Xtest_T_arg')
endfunc

" Test the '-x' argument to read/write encrypted files.
func Test_x_arg()
CheckRunVimInTerminal
CheckFeature cryptv

" Create an encrypted file Xtest_x_arg.
let buf = RunVimInTerminal('-n -x Xtest_x_arg', #{rows: 10, wait_for_ruler: 0})
call WaitForAssert({-> assert_match('^Enter encryption key: ', term_getline(buf, 10))})
call term_sendkeys(buf, "foo\n")
call WaitForAssert({-> assert_match('^Enter same key again: ', term_getline(buf, 10))})
call term_sendkeys(buf, "foo\n")
call WaitForAssert({-> assert_match(' All$', term_getline(buf, 10))})
call term_sendkeys(buf, "itest\<Esc>:w\<Enter>")
call WaitForAssert({-> assert_match('"Xtest_x_arg" \[New\]\[blowfish2\] 1L, 5B written',
\ term_getline(buf, 10))})
call StopVimInTerminal(buf)

" Read the encrypted file and check that it contains the expected content "test"
let buf = RunVimInTerminal('-n -x Xtest_x_arg', #{rows: 10, wait_for_ruler: 0})
call WaitForAssert({-> assert_match('^Enter encryption key: ', term_getline(buf, 10))})
call term_sendkeys(buf, "foo\n")
call WaitForAssert({-> assert_match('^Enter same key again: ', term_getline(buf, 10))})
call term_sendkeys(buf, "foo\n")
call WaitForAssert({-> assert_match('^test', term_getline(buf, 1))})
call StopVimInTerminal(buf)

call delete('Xtest_x_arg')
endfunc

" Test for entering the insert mode on startup
func Test_start_insertmode()
let before =<< trim [CODE]
Expand Down
14 changes: 12 additions & 2 deletions src/testdir/test_vim9_disassemble.vim
Expand Up @@ -23,6 +23,7 @@ def s:ScriptFuncLoad(arg: string)
echo s:scriptvar
echo g:globalvar
echo get(g:, "global")
echo g:auto#var
echo b:buffervar
echo get(b:, "buffer")
echo w:windowvar
Expand Down Expand Up @@ -68,8 +69,14 @@ def Test_disassemble_load()
'echo get(g:, "global")\_s*' ..
'\d\+ LOAD g:\_s*' ..
'\d\+ PUSHS "global"\_s*' ..
'\d\+ BCALL get(argc 2).*' ..
' LOADB b:buffervar.*' ..
'\d\+ BCALL get(argc 2)\_s*' ..
'\d\+ ECHO 1\_s*' ..
'echo g:auto#var\_s*' ..
'\d\+ LOADAUTO g:auto#var\_s*' ..
'\d\+ ECHO 1\_s*' ..
'echo b:buffervar\_s*' ..
'\d\+ LOADB b:buffervar\_s*' ..
'\d\+ ECHO 1\_s*' ..
'echo get(b:, "buffer")\_s*' ..
'\d\+ LOAD b:\_s*' ..
'\d\+ PUSHS "buffer"\_s*' ..
Expand Down Expand Up @@ -197,6 +204,7 @@ def s:ScriptFuncStore()
v:char = 'abc'
s:scriptvar = 'sv'
g:globalvar = 'gv'
g:auto#var = 'av'
b:buffervar = 'bv'
w:windowvar = 'wv'
t:tabpagevar = 'tv'
Expand All @@ -220,6 +228,8 @@ def Test_disassemble_store()
' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' ..
'g:globalvar = ''gv''.*' ..
' STOREG g:globalvar.*' ..
'g:auto#var = ''av''.*' ..
' STOREAUTO g:auto#var.*' ..
'b:buffervar = ''bv''.*' ..
' STOREB b:buffervar.*' ..
'w:windowvar = ''wv''.*' ..
Expand Down
42 changes: 41 additions & 1 deletion src/testdir/test_vim9_script.vim
Expand Up @@ -2779,8 +2779,42 @@ def Test_vim9_copen()
quit
enddef

" test using a vim9script that is auto-loaded from an autocmd
" test using an auto-loaded function and variable
def Test_vim9_autoload()
var lines =<< trim END
vim9script
def some#gettest(): string
return 'test'
enddef
g:some#name = 'name'
END

mkdir('Xdir/autoload', 'p')
writefile(lines, 'Xdir/autoload/some.vim')
var save_rtp = &rtp
exe 'set rtp^=' .. getcwd() .. '/Xdir'

assert_equal('test', g:some#gettest())
assert_equal('name', g:some#name)
g:some#other = 'other'
assert_equal('other', g:some#other)

# upper case script name works
lines =<< trim END
vim9script
def Other#getOther(): string
return 'other'
enddef
END
writefile(lines, 'Xdir/autoload/Other.vim')
assert_equal('other', g:Other#getOther())

delete('Xdir', 'rf')
&rtp = save_rtp
enddef

" test using a vim9script that is auto-loaded from an autocmd
def Test_vim9_aucmd_autoload()
var lines =<< trim END
vim9script
def foo#test()
Expand Down Expand Up @@ -2842,6 +2876,12 @@ def Test_vim9_autoload_error()
delete('Xdidit')
delete('Xscript')
delete('Xruntime', 'rf')

lines =<< trim END
vim9script
var foo#bar = 'asdf'
END
CheckScriptFailure(lines, 'E461: Illegal variable name: foo#bar', 2)
enddef

def Test_script_var_in_autocmd()
Expand Down
12 changes: 11 additions & 1 deletion src/userfunc.c
Expand Up @@ -2654,8 +2654,18 @@ trans_function_name(
goto theend;
}

// In Vim9 script a user function is script-local by default.
// In Vim9 script a user function is script-local by default, unless it
// starts with a lower case character: dict.func().
vim9script = ASCII_ISUPPER(*start) && in_vim9script();
if (vim9script)
{
char_u *p;

// SomeScript#func() is a global function.
for (p = start; *p != NUL && *p != '('; ++p)
if (*p == AUTOLOAD_CHAR)
vim9script = FALSE;
}

/*
* Copy the function name to allocated memory.
Expand Down
8 changes: 8 additions & 0 deletions src/version.c
Expand Up @@ -765,6 +765,14 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2164,
/**/
2163,
/**/
2162,
/**/
2161,
/**/
2160,
/**/
Expand Down
2 changes: 2 additions & 0 deletions src/vim9.h
Expand Up @@ -24,6 +24,7 @@ typedef enum {
ISN_LOAD, // push local variable isn_arg.number
ISN_LOADV, // push v: variable isn_arg.number
ISN_LOADG, // push g: variable isn_arg.string
ISN_LOADAUTO, // push g: autoload variable isn_arg.string
ISN_LOADB, // push b: variable isn_arg.string
ISN_LOADW, // push w: variable isn_arg.string
ISN_LOADT, // push t: variable isn_arg.string
Expand All @@ -41,6 +42,7 @@ typedef enum {
ISN_STORE, // pop into local variable isn_arg.number
ISN_STOREV, // pop into v: variable isn_arg.number
ISN_STOREG, // pop into global variable isn_arg.string
ISN_STOREAUTO, // pop into global autoload variable isn_arg.string
ISN_STOREB, // pop into buffer-local variable isn_arg.string
ISN_STOREW, // pop into window-local variable isn_arg.string
ISN_STORET, // pop into tab-local variable isn_arg.string
Expand Down
24 changes: 20 additions & 4 deletions src/vim9compile.c
Expand Up @@ -2535,7 +2535,17 @@ compile_load(
case 's': res = compile_load_scriptvar(cctx, name,
NULL, NULL, error);
break;
case 'g': isn_type = ISN_LOADG; break;
case 'g': if (vim_strchr(name, AUTOLOAD_CHAR) == NULL)
isn_type = ISN_LOADG;
else
{
isn_type = ISN_LOADAUTO;
vim_free(name);
name = vim_strnsave(*arg, end - *arg);
if (name == NULL)
return FAIL;
}
break;
case 'w': isn_type = ISN_LOADW; break;
case 't': isn_type = ISN_LOADT; break;
case 'b': isn_type = ISN_LOADB; break;
Expand Down Expand Up @@ -2738,7 +2748,7 @@ compile_call(
if (compile_arguments(arg, cctx, &argcount) == FAIL)
goto theend;

is_autoload = vim_strchr(name, '#') != NULL;
is_autoload = vim_strchr(name, AUTOLOAD_CHAR) != NULL;
if (ASCII_ISLOWER(*name) && name[1] != ':' && !is_autoload)
{
int idx;
Expand Down Expand Up @@ -4986,7 +4996,10 @@ generate_loadvar(
generate_LOAD(cctx, ISN_LOADOPT, 0, name, type);
break;
case dest_global:
generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
if (vim_strchr(name, AUTOLOAD_CHAR) == NULL)
generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
else
generate_LOAD(cctx, ISN_LOADAUTO, 0, name, type);
break;
case dest_buffer:
generate_LOAD(cctx, ISN_LOADB, 0, name + 2, type);
Expand Down Expand Up @@ -5198,7 +5211,8 @@ generate_store_var(
opt_flags);
case dest_global:
// include g: with the name, easier to execute that way
return generate_STORE(cctx, ISN_STOREG, 0, name);
return generate_STORE(cctx, vim_strchr(name, AUTOLOAD_CHAR) == NULL
? ISN_STOREG : ISN_STOREAUTO, 0, name);
case dest_buffer:
// include b: with the name, easier to execute that way
return generate_STORE(cctx, ISN_STOREB, 0, name);
Expand Down Expand Up @@ -8007,6 +8021,7 @@ delete_instr(isn_T *isn)
{
case ISN_DEF:
case ISN_EXEC:
case ISN_LOADAUTO:
case ISN_LOADB:
case ISN_LOADENV:
case ISN_LOADG:
Expand All @@ -8017,6 +8032,7 @@ delete_instr(isn_T *isn)
case ISN_PUSHFUNC:
case ISN_PUSHS:
case ISN_RANGE:
case ISN_STOREAUTO:
case ISN_STOREB:
case ISN_STOREENV:
case ISN_STOREG:
Expand Down

0 comments on commit a4252b3

Please sign in to comment.