mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge #10869 'vim-patch:8.1.{0309,0362,0365,0515,1946}'
This commit is contained in:
commit
8b06231612
@ -816,11 +816,12 @@ it, no matter how many backslashes.
|
|||||||
\\# \#
|
\\# \#
|
||||||
Also see |`=|.
|
Also see |`=|.
|
||||||
|
|
||||||
*:<cword>* *:<cWORD>* *:<cfile>* *<cfile>*
|
*:<cword>* *<cword>* *:<cWORD>* *<cWORD>*
|
||||||
*:<sfile>* *<sfile>* *:<afile>* *<afile>*
|
*:<cexpr>* *<cexpr>* *:<cfile>* *<cfile>*
|
||||||
*:<abuf>* *<abuf>* *:<amatch>* *<amatch>*
|
*:<afile>* *<afile>* *:<abuf>* *<abuf>*
|
||||||
*:<cexpr>* *<cexpr>*
|
*:<amatch>* *<amatch>*
|
||||||
*<slnum>* *E495* *E496* *E497* *E499* *E500*
|
*:<sfile>* *<sfile>* *:<slnum>* *<slnum>*
|
||||||
|
*:<sflnum>* *<sflnum>* *E499* *E500*
|
||||||
Note: these are typed literally, they are not special keys!
|
Note: these are typed literally, they are not special keys!
|
||||||
<cword> is replaced with the word under the cursor (like |star|)
|
<cword> is replaced with the word under the cursor (like |star|)
|
||||||
<cWORD> is replaced with the WORD under the cursor (see |WORD|)
|
<cWORD> is replaced with the WORD under the cursor (see |WORD|)
|
||||||
@ -833,15 +834,16 @@ Note: these are typed literally, they are not special keys!
|
|||||||
|gf| uses)
|
|gf| uses)
|
||||||
<afile> When executing autocommands, is replaced with the file name
|
<afile> When executing autocommands, is replaced with the file name
|
||||||
of the buffer being manipulated, or the file for a read or
|
of the buffer being manipulated, or the file for a read or
|
||||||
write.
|
write. *E495*
|
||||||
<abuf> When executing autocommands, is replaced with the currently
|
<abuf> When executing autocommands, is replaced with the currently
|
||||||
effective buffer number (for ":r file" and ":so file" it is
|
effective buffer number (for ":r file" and ":so file" it is
|
||||||
the current buffer, the file being read/sourced is not in a
|
the current buffer, the file being read/sourced is not in a
|
||||||
buffer).
|
buffer). *E496*
|
||||||
<amatch> When executing autocommands, is replaced with the match for
|
<amatch> When executing autocommands, is replaced with the match for
|
||||||
which this autocommand was executed. It differs from
|
which this autocommand was executed. *E497*
|
||||||
<afile> only when the file name isn't used to match with
|
It differs from <afile> only when the file name isn't used
|
||||||
(for FileType, Syntax and SpellFileMissing events).
|
to match with (for FileType, Syntax and SpellFileMissing
|
||||||
|
events).
|
||||||
<sfile> When executing a ":source" command, is replaced with the
|
<sfile> When executing a ":source" command, is replaced with the
|
||||||
file name of the sourced file. *E498*
|
file name of the sourced file. *E498*
|
||||||
When executing a function, is replaced with:
|
When executing a function, is replaced with:
|
||||||
@ -851,9 +853,12 @@ Note: these are typed literally, they are not special keys!
|
|||||||
Note that filename-modifiers are useless when <sfile> is
|
Note that filename-modifiers are useless when <sfile> is
|
||||||
used inside a function.
|
used inside a function.
|
||||||
<slnum> When executing a ":source" command, is replaced with the
|
<slnum> When executing a ":source" command, is replaced with the
|
||||||
line number. *E842*
|
line number. *E842*
|
||||||
When executing a function it's the line number relative to
|
When executing a function it's the line number relative to
|
||||||
the start of the function.
|
the start of the function.
|
||||||
|
<sflnum> When executing a script, is replaced with the line number.
|
||||||
|
It differs from <slnum> in that <sflnum> is replaced with
|
||||||
|
the script line number in any situation. *E961*
|
||||||
|
|
||||||
*filename-modifiers*
|
*filename-modifiers*
|
||||||
*:_%:* *::8* *::p* *::.* *::~* *::h* *::t* *::r* *::e* *::s* *::gs* *::S*
|
*:_%:* *::8* *::p* *::.* *::~* *::h* *::t* *::r* *::e* *::s* *::gs* *::S*
|
||||||
|
@ -3595,7 +3595,10 @@ expand({expr} [, {nosuf} [, {list}]]) *expand()*
|
|||||||
<abuf> autocmd buffer number (as a String!)
|
<abuf> autocmd buffer number (as a String!)
|
||||||
<amatch> autocmd matched name
|
<amatch> autocmd matched name
|
||||||
<sfile> sourced script file or function name
|
<sfile> sourced script file or function name
|
||||||
<slnum> sourced script file line number
|
<slnum> sourced script line number or function
|
||||||
|
line number
|
||||||
|
<sflnum> script file line number, also when in
|
||||||
|
a function
|
||||||
<cword> word under the cursor
|
<cword> word under the cursor
|
||||||
<cWORD> WORD under the cursor
|
<cWORD> WORD under the cursor
|
||||||
<client> the {clientid} of the last received
|
<client> the {clientid} of the last received
|
||||||
@ -5705,6 +5708,7 @@ maparg({name} [, {mode} [, {abbr} [, {dict}]]]) *maparg()*
|
|||||||
(|mapmode-ic|)
|
(|mapmode-ic|)
|
||||||
"sid" The script local ID, used for <sid> mappings
|
"sid" The script local ID, used for <sid> mappings
|
||||||
(|<SID>|).
|
(|<SID>|).
|
||||||
|
"lnum" The line number in "sid", zero if unknown.
|
||||||
"nowait" Do not wait for other, longer mappings.
|
"nowait" Do not wait for other, longer mappings.
|
||||||
(|:map-<nowait>|).
|
(|:map-<nowait>|).
|
||||||
|
|
||||||
@ -9255,9 +9259,13 @@ See |:verbose-cmd| for more information.
|
|||||||
deleted if there are no more references to it.
|
deleted if there are no more references to it.
|
||||||
*E127* *E122*
|
*E127* *E122*
|
||||||
When a function by this name already exists and [!] is
|
When a function by this name already exists and [!] is
|
||||||
not used an error message is given. When [!] is used,
|
not used an error message is given. There is one
|
||||||
an existing function is silently replaced. Unless it
|
exception: When sourcing a script again, a function
|
||||||
is currently being executed, that is an error.
|
that was previously defined in that script will be
|
||||||
|
silently replaced.
|
||||||
|
When [!] is used, an existing function is silently
|
||||||
|
replaced. Unless it is currently being executed, that
|
||||||
|
is an error.
|
||||||
NOTE: Use ! wisely. If used without care it can cause
|
NOTE: Use ! wisely. If used without care it can cause
|
||||||
an existing function to be replaced unexpectedly,
|
an existing function to be replaced unexpectedly,
|
||||||
which is hard to debug.
|
which is hard to debug.
|
||||||
|
@ -391,8 +391,10 @@ void set_option_to(uint64_t channel_id, void *to, int type,
|
|||||||
stringval = (char *)value.data.string.data;
|
stringval = (char *)value.data.string.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const scid_T save_current_SID = current_SID;
|
const sctx_T save_current_sctx = current_sctx;
|
||||||
current_SID = channel_id == LUA_INTERNAL_CALL ? SID_LUA : SID_API_CLIENT;
|
current_sctx.sc_sid =
|
||||||
|
channel_id == LUA_INTERNAL_CALL ? SID_LUA : SID_API_CLIENT;
|
||||||
|
current_sctx.sc_lnum = 0;
|
||||||
current_channel_id = channel_id;
|
current_channel_id = channel_id;
|
||||||
|
|
||||||
const int opt_flags = (type == SREQ_WIN && !(flags & SOPT_GLOBAL))
|
const int opt_flags = (type == SREQ_WIN && !(flags & SOPT_GLOBAL))
|
||||||
@ -401,7 +403,7 @@ void set_option_to(uint64_t channel_id, void *to, int type,
|
|||||||
set_option_value_for(name.data, numval, stringval,
|
set_option_value_for(name.data, numval, stringval,
|
||||||
opt_flags, type, to, err);
|
opt_flags, type, to, err);
|
||||||
|
|
||||||
current_SID = save_current_SID;
|
current_sctx = save_current_sctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
|
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
|
||||||
|
@ -5064,7 +5064,6 @@ chk_modeline(
|
|||||||
int retval = OK;
|
int retval = OK;
|
||||||
char_u *save_sourcing_name;
|
char_u *save_sourcing_name;
|
||||||
linenr_T save_sourcing_lnum;
|
linenr_T save_sourcing_lnum;
|
||||||
scid_T save_SID;
|
|
||||||
|
|
||||||
prev = -1;
|
prev = -1;
|
||||||
for (s = ml_get(lnum); *s != NUL; s++) {
|
for (s = ml_get(lnum); *s != NUL; s++) {
|
||||||
@ -5152,15 +5151,17 @@ chk_modeline(
|
|||||||
|
|
||||||
if (*s != NUL) { // skip over an empty "::"
|
if (*s != NUL) { // skip over an empty "::"
|
||||||
const int secure_save = secure;
|
const int secure_save = secure;
|
||||||
save_SID = current_SID;
|
const sctx_T save_current_sctx = current_sctx;
|
||||||
current_SID = SID_MODELINE;
|
current_sctx.sc_sid = SID_MODELINE;
|
||||||
|
current_sctx.sc_seq = 0;
|
||||||
|
current_sctx.sc_lnum = 0;
|
||||||
// Make sure no risky things are executed as a side effect.
|
// Make sure no risky things are executed as a side effect.
|
||||||
secure = 1;
|
secure = 1;
|
||||||
|
|
||||||
retval = do_set(s, OPT_MODELINE | OPT_LOCAL | flags);
|
retval = do_set(s, OPT_MODELINE | OPT_LOCAL | flags);
|
||||||
|
|
||||||
secure = secure_save;
|
secure = secure_save;
|
||||||
current_SID = save_SID;
|
current_sctx = save_current_sctx;
|
||||||
if (retval == FAIL) { // stop if error found
|
if (retval == FAIL) { // stop if error found
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -255,8 +255,8 @@ typedef struct {
|
|||||||
long wo_winbl;
|
long wo_winbl;
|
||||||
# define w_p_winbl w_onebuf_opt.wo_winbl // 'winblend'
|
# define w_p_winbl w_onebuf_opt.wo_winbl // 'winblend'
|
||||||
|
|
||||||
LastSet wo_scriptID[WV_COUNT]; // SIDs for window-local options
|
LastSet wo_script_ctx[WV_COUNT]; // SCTXs for window-local options
|
||||||
# define w_p_scriptID w_onebuf_opt.wo_scriptID
|
# define w_p_script_ctx w_onebuf_opt.wo_script_ctx
|
||||||
} winopt_T;
|
} winopt_T;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -344,17 +344,17 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
typedef struct mapblock mapblock_T;
|
typedef struct mapblock mapblock_T;
|
||||||
struct mapblock {
|
struct mapblock {
|
||||||
mapblock_T *m_next; /* next mapblock in list */
|
mapblock_T *m_next; // next mapblock in list
|
||||||
char_u *m_keys; /* mapped from, lhs */
|
char_u *m_keys; // mapped from, lhs
|
||||||
char_u *m_str; /* mapped to, rhs */
|
char_u *m_str; // mapped to, rhs
|
||||||
char_u *m_orig_str; /* rhs as entered by the user */
|
char_u *m_orig_str; // rhs as entered by the user
|
||||||
int m_keylen; /* strlen(m_keys) */
|
int m_keylen; // strlen(m_keys)
|
||||||
int m_mode; /* valid mode */
|
int m_mode; // valid mode
|
||||||
int m_noremap; /* if non-zero no re-mapping for m_str */
|
int m_noremap; // if non-zero no re-mapping for m_str
|
||||||
char m_silent; /* <silent> used, don't echo commands */
|
char m_silent; // <silent> used, don't echo commands
|
||||||
char m_nowait; /* <nowait> used */
|
char m_nowait; // <nowait> used
|
||||||
char m_expr; /* <expr> used, m_str is an expression */
|
char m_expr; // <expr> used, m_str is an expression
|
||||||
scid_T m_script_ID; /* ID of script where map was defined */
|
sctx_T m_script_ctx; // SCTX where map was defined
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -622,9 +622,9 @@ struct file_buffer {
|
|||||||
* They are here because their value depends on the type of file
|
* They are here because their value depends on the type of file
|
||||||
* or contents of the file being edited.
|
* or contents of the file being edited.
|
||||||
*/
|
*/
|
||||||
bool b_p_initialized; /* set when options initialized */
|
bool b_p_initialized; // set when options initialized
|
||||||
|
|
||||||
LastSet b_p_scriptID[BV_COUNT]; // SIDs for buffer-local options
|
LastSet b_p_script_ctx[BV_COUNT]; // SCTXs for buffer-local options
|
||||||
|
|
||||||
int b_p_ai; ///< 'autoindent'
|
int b_p_ai; ///< 'autoindent'
|
||||||
int b_p_ai_nopaste; ///< b_p_ai saved for paste mode
|
int b_p_ai_nopaste; ///< b_p_ai saved for paste mode
|
||||||
|
@ -1815,13 +1815,11 @@ static void list_vim_vars(int *first)
|
|||||||
list_hashtable_vars(&vimvarht, "v:", false, first);
|
list_hashtable_vars(&vimvarht, "v:", false, first);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// List script-local variables, if there is a script.
|
||||||
* List script-local variables, if there is a script.
|
|
||||||
*/
|
|
||||||
static void list_script_vars(int *first)
|
static void list_script_vars(int *first)
|
||||||
{
|
{
|
||||||
if (current_SID > 0 && current_SID <= ga_scripts.ga_len) {
|
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= ga_scripts.ga_len) {
|
||||||
list_hashtable_vars(&SCRIPT_VARS(current_SID), "s:", false, first);
|
list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid), "s:", false, first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5981,7 +5979,8 @@ static int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate)
|
|||||||
fp->uf_varargs = true;
|
fp->uf_varargs = true;
|
||||||
fp->uf_flags = flags;
|
fp->uf_flags = flags;
|
||||||
fp->uf_calls = 0;
|
fp->uf_calls = 0;
|
||||||
fp->uf_script_ID = current_SID;
|
fp->uf_script_ctx = current_sctx;
|
||||||
|
fp->uf_script_ctx.sc_lnum += sourcing_lnum - newlines.ga_len;
|
||||||
|
|
||||||
pt->pt_func = fp;
|
pt->pt_func = fp;
|
||||||
pt->pt_refcount = 1;
|
pt->pt_refcount = 1;
|
||||||
@ -6329,11 +6328,11 @@ static char_u *fname_trans_sid(const char_u *const name,
|
|||||||
fname_buf[2] = (int)KE_SNR;
|
fname_buf[2] = (int)KE_SNR;
|
||||||
int i = 3;
|
int i = 3;
|
||||||
if (eval_fname_sid((const char *)name)) { // "<SID>" or "s:"
|
if (eval_fname_sid((const char *)name)) { // "<SID>" or "s:"
|
||||||
if (current_SID <= 0) {
|
if (current_sctx.sc_sid <= 0) {
|
||||||
*error = ERROR_SCRIPT;
|
*error = ERROR_SCRIPT;
|
||||||
} else {
|
} else {
|
||||||
snprintf((char *)fname_buf + 3, FLEN_FIXED + 1, "%" PRId64 "_",
|
snprintf((char *)fname_buf + 3, FLEN_FIXED + 1, "%" PRId64 "_",
|
||||||
(int64_t)current_SID);
|
(int64_t)current_sctx.sc_sid);
|
||||||
i = (int)STRLEN(fname_buf);
|
i = (int)STRLEN(fname_buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9433,7 +9432,7 @@ static void common_function(typval_T *argvars, typval_T *rettv,
|
|||||||
// would also work, but some plugins depend on the name being
|
// would also work, but some plugins depend on the name being
|
||||||
// printable text.
|
// printable text.
|
||||||
snprintf(sid_buf, sizeof(sid_buf), "<SNR>%" PRId64 "_",
|
snprintf(sid_buf, sizeof(sid_buf), "<SNR>%" PRId64 "_",
|
||||||
(int64_t)current_SID);
|
(int64_t)current_sctx.sc_sid);
|
||||||
name = xmalloc(STRLEN(sid_buf) + STRLEN(s + off) + 1);
|
name = xmalloc(STRLEN(sid_buf) + STRLEN(s + off) + 1);
|
||||||
STRCPY(name, sid_buf);
|
STRCPY(name, sid_buf);
|
||||||
STRCAT(name, s + off);
|
STRCAT(name, s + off);
|
||||||
@ -12874,7 +12873,8 @@ void mapblock_fill_dict(dict_T *const dict,
|
|||||||
tv_dict_add_nr(dict, S_LEN("noremap"), noremap_value);
|
tv_dict_add_nr(dict, S_LEN("noremap"), noremap_value);
|
||||||
tv_dict_add_nr(dict, S_LEN("expr"), mp->m_expr ? 1 : 0);
|
tv_dict_add_nr(dict, S_LEN("expr"), mp->m_expr ? 1 : 0);
|
||||||
tv_dict_add_nr(dict, S_LEN("silent"), mp->m_silent ? 1 : 0);
|
tv_dict_add_nr(dict, S_LEN("silent"), mp->m_silent ? 1 : 0);
|
||||||
tv_dict_add_nr(dict, S_LEN("sid"), (varnumber_T)mp->m_script_ID);
|
tv_dict_add_nr(dict, S_LEN("sid"), (varnumber_T)mp->m_script_ctx.sc_sid);
|
||||||
|
tv_dict_add_nr(dict, S_LEN("lnum"), (varnumber_T)mp->m_script_ctx.sc_lnum);
|
||||||
tv_dict_add_nr(dict, S_LEN("buffer"), (varnumber_T)buffer_value);
|
tv_dict_add_nr(dict, S_LEN("buffer"), (varnumber_T)buffer_value);
|
||||||
tv_dict_add_nr(dict, S_LEN("nowait"), mp->m_nowait ? 1 : 0);
|
tv_dict_add_nr(dict, S_LEN("nowait"), mp->m_nowait ? 1 : 0);
|
||||||
tv_dict_add_allocated_str(dict, S_LEN("mode"), mapmode);
|
tv_dict_add_allocated_str(dict, S_LEN("mode"), mapmode);
|
||||||
@ -14549,7 +14549,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
ADD(args, vim_to_object(tv));
|
ADD(args, vim_to_object(tv));
|
||||||
}
|
}
|
||||||
|
|
||||||
scid_T save_current_SID;
|
sctx_T save_current_sctx;
|
||||||
uint8_t *save_sourcing_name, *save_autocmd_fname, *save_autocmd_match;
|
uint8_t *save_sourcing_name, *save_autocmd_fname, *save_autocmd_match;
|
||||||
linenr_T save_sourcing_lnum;
|
linenr_T save_sourcing_lnum;
|
||||||
int save_autocmd_bufnr;
|
int save_autocmd_bufnr;
|
||||||
@ -14558,7 +14558,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
if (l_provider_call_nesting) {
|
if (l_provider_call_nesting) {
|
||||||
// If this is called from a provider function, restore the scope
|
// If this is called from a provider function, restore the scope
|
||||||
// information of the caller.
|
// information of the caller.
|
||||||
save_current_SID = current_SID;
|
save_current_sctx = current_sctx;
|
||||||
save_sourcing_name = sourcing_name;
|
save_sourcing_name = sourcing_name;
|
||||||
save_sourcing_lnum = sourcing_lnum;
|
save_sourcing_lnum = sourcing_lnum;
|
||||||
save_autocmd_fname = autocmd_fname;
|
save_autocmd_fname = autocmd_fname;
|
||||||
@ -14566,7 +14566,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
save_autocmd_bufnr = autocmd_bufnr;
|
save_autocmd_bufnr = autocmd_bufnr;
|
||||||
save_funccalp = save_funccal();
|
save_funccalp = save_funccal();
|
||||||
|
|
||||||
current_SID = provider_caller_scope.SID;
|
current_sctx = provider_caller_scope.script_ctx;
|
||||||
sourcing_name = provider_caller_scope.sourcing_name;
|
sourcing_name = provider_caller_scope.sourcing_name;
|
||||||
sourcing_lnum = provider_caller_scope.sourcing_lnum;
|
sourcing_lnum = provider_caller_scope.sourcing_lnum;
|
||||||
autocmd_fname = provider_caller_scope.autocmd_fname;
|
autocmd_fname = provider_caller_scope.autocmd_fname;
|
||||||
@ -14584,7 +14584,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
Object result = rpc_send_call(chan_id, method, args, &err);
|
Object result = rpc_send_call(chan_id, method, args, &err);
|
||||||
|
|
||||||
if (l_provider_call_nesting) {
|
if (l_provider_call_nesting) {
|
||||||
current_SID = save_current_SID;
|
current_sctx = save_current_sctx;
|
||||||
sourcing_name = save_sourcing_name;
|
sourcing_name = save_sourcing_name;
|
||||||
sourcing_lnum = save_sourcing_lnum;
|
sourcing_lnum = save_sourcing_lnum;
|
||||||
autocmd_fname = save_autocmd_fname;
|
autocmd_fname = save_autocmd_fname;
|
||||||
@ -20145,7 +20145,7 @@ static dictitem_T *find_var_in_ht(hashtab_T *const ht,
|
|||||||
if (varname_len == 0) {
|
if (varname_len == 0) {
|
||||||
// Must be something like "s:", otherwise "ht" would be NULL.
|
// Must be something like "s:", otherwise "ht" would be NULL.
|
||||||
switch (htname) {
|
switch (htname) {
|
||||||
case 's': return (dictitem_T *)&SCRIPT_SV(current_SID)->sv_var;
|
case 's': return (dictitem_T *)&SCRIPT_SV(current_sctx.sc_sid)->sv_var;
|
||||||
case 'g': return (dictitem_T *)&globvars_var;
|
case 'g': return (dictitem_T *)&globvars_var;
|
||||||
case 'v': return (dictitem_T *)&vimvars_var;
|
case 'v': return (dictitem_T *)&vimvars_var;
|
||||||
case 'b': return (dictitem_T *)&curbuf->b_bufvar;
|
case 'b': return (dictitem_T *)&curbuf->b_bufvar;
|
||||||
@ -20282,8 +20282,9 @@ static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len,
|
|||||||
} else if (*name == 'l' && current_funccal != NULL) { // local variable
|
} else if (*name == 'l' && current_funccal != NULL) { // local variable
|
||||||
*d = &get_funccal()->l_vars;
|
*d = &get_funccal()->l_vars;
|
||||||
} else if (*name == 's' // script variable
|
} else if (*name == 's' // script variable
|
||||||
&& current_SID > 0 && current_SID <= ga_scripts.ga_len) {
|
&& current_sctx.sc_sid > 0
|
||||||
*d = &SCRIPT_SV(current_SID)->sv_dict;
|
&& current_sctx.sc_sid <= ga_scripts.ga_len) {
|
||||||
|
*d = &SCRIPT_SV(current_sctx.sc_sid)->sv_dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
@ -21529,7 +21530,11 @@ void ex_function(exarg_T *eap)
|
|||||||
|
|
||||||
fp = find_func(name);
|
fp = find_func(name);
|
||||||
if (fp != NULL) {
|
if (fp != NULL) {
|
||||||
if (!eap->forceit) {
|
// Function can be replaced with "function!" and when sourcing the
|
||||||
|
// same script again, but only once.
|
||||||
|
if (!eap->forceit
|
||||||
|
&& (fp->uf_script_ctx.sc_sid != current_sctx.sc_sid
|
||||||
|
|| fp->uf_script_ctx.sc_seq == current_sctx.sc_seq)) {
|
||||||
emsg_funcname(e_funcexts, name);
|
emsg_funcname(e_funcexts, name);
|
||||||
goto erret;
|
goto erret;
|
||||||
}
|
}
|
||||||
@ -21654,7 +21659,8 @@ void ex_function(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
fp->uf_flags = flags;
|
fp->uf_flags = flags;
|
||||||
fp->uf_calls = 0;
|
fp->uf_calls = 0;
|
||||||
fp->uf_script_ID = current_SID;
|
fp->uf_script_ctx = current_sctx;
|
||||||
|
fp->uf_script_ctx.sc_lnum += sourcing_lnum - newlines.ga_len - 1;
|
||||||
goto ret_free;
|
goto ret_free;
|
||||||
|
|
||||||
erret:
|
erret:
|
||||||
@ -21841,12 +21847,12 @@ trans_function_name(
|
|||||||
if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name))
|
if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name))
|
||||||
|| eval_fname_sid((const char *)(*pp))) {
|
|| eval_fname_sid((const char *)(*pp))) {
|
||||||
// It's "s:" or "<SID>".
|
// It's "s:" or "<SID>".
|
||||||
if (current_SID <= 0) {
|
if (current_sctx.sc_sid <= 0) {
|
||||||
EMSG(_(e_usingsid));
|
EMSG(_(e_usingsid));
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
sid_buf_len = snprintf(sid_buf, sizeof(sid_buf),
|
sid_buf_len = snprintf(sid_buf, sizeof(sid_buf),
|
||||||
"%" PRIdSCID "_", current_SID);
|
"%" PRIdSCID "_", current_sctx.sc_sid);
|
||||||
lead += sid_buf_len;
|
lead += sid_buf_len;
|
||||||
}
|
}
|
||||||
} else if (!(flags & TFN_INT)
|
} else if (!(flags & TFN_INT)
|
||||||
@ -21963,8 +21969,9 @@ static void list_func_head(ufunc_T *fp, int indent, bool force)
|
|||||||
msg_puts(" closure");
|
msg_puts(" closure");
|
||||||
}
|
}
|
||||||
msg_clr_eos();
|
msg_clr_eos();
|
||||||
if (p_verbose > 0)
|
if (p_verbose > 0) {
|
||||||
last_set_msg(fp->uf_script_ID);
|
last_set_msg(fp->uf_script_ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find a function by name, return pointer to it in ufuncs.
|
/// Find a function by name, return pointer to it in ufuncs.
|
||||||
@ -22161,14 +22168,29 @@ void func_dump_profile(FILE *fd)
|
|||||||
if (fp->uf_prof_initialized) {
|
if (fp->uf_prof_initialized) {
|
||||||
sorttab[st_len++] = fp;
|
sorttab[st_len++] = fp;
|
||||||
|
|
||||||
if (fp->uf_name[0] == K_SPECIAL)
|
if (fp->uf_name[0] == K_SPECIAL) {
|
||||||
fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3);
|
fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3);
|
||||||
else
|
} else {
|
||||||
fprintf(fd, "FUNCTION %s()\n", fp->uf_name);
|
fprintf(fd, "FUNCTION %s()\n", fp->uf_name);
|
||||||
if (fp->uf_tm_count == 1)
|
}
|
||||||
|
if (fp->uf_script_ctx.sc_sid != 0) {
|
||||||
|
bool should_free;
|
||||||
|
const LastSet last_set = (LastSet){
|
||||||
|
.script_ctx = fp->uf_script_ctx,
|
||||||
|
.channel_id = 0,
|
||||||
|
};
|
||||||
|
char_u *p = get_scriptname(last_set, &should_free);
|
||||||
|
fprintf(fd, " Defined: %s line %" PRIdLINENR "\n",
|
||||||
|
p, fp->uf_script_ctx.sc_lnum);
|
||||||
|
if (should_free) {
|
||||||
|
xfree(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fp->uf_tm_count == 1) {
|
||||||
fprintf(fd, "Called 1 time\n");
|
fprintf(fd, "Called 1 time\n");
|
||||||
else
|
} else {
|
||||||
fprintf(fd, "Called %d times\n", fp->uf_tm_count);
|
fprintf(fd, "Called %d times\n", fp->uf_tm_count);
|
||||||
|
}
|
||||||
fprintf(fd, "Total time: %s\n", profile_msg(fp->uf_tm_total));
|
fprintf(fd, "Total time: %s\n", profile_msg(fp->uf_tm_total));
|
||||||
fprintf(fd, " Self time: %s\n", profile_msg(fp->uf_tm_self));
|
fprintf(fd, " Self time: %s\n", profile_msg(fp->uf_tm_self));
|
||||||
fprintf(fd, "\n");
|
fprintf(fd, "\n");
|
||||||
@ -22654,7 +22676,6 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
|
|||||||
{
|
{
|
||||||
char_u *save_sourcing_name;
|
char_u *save_sourcing_name;
|
||||||
linenr_T save_sourcing_lnum;
|
linenr_T save_sourcing_lnum;
|
||||||
scid_T save_current_SID;
|
|
||||||
bool using_sandbox = false;
|
bool using_sandbox = false;
|
||||||
funccall_T *fc;
|
funccall_T *fc;
|
||||||
int save_did_emsg;
|
int save_did_emsg;
|
||||||
@ -22908,8 +22929,8 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
|
|||||||
script_prof_save(&wait_start);
|
script_prof_save(&wait_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
save_current_SID = current_SID;
|
const sctx_T save_current_sctx = current_sctx;
|
||||||
current_SID = fp->uf_script_ID;
|
current_sctx = fp->uf_script_ctx;
|
||||||
save_did_emsg = did_emsg;
|
save_did_emsg = did_emsg;
|
||||||
did_emsg = FALSE;
|
did_emsg = FALSE;
|
||||||
|
|
||||||
@ -22983,7 +23004,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
|
|||||||
xfree(sourcing_name);
|
xfree(sourcing_name);
|
||||||
sourcing_name = save_sourcing_name;
|
sourcing_name = save_sourcing_name;
|
||||||
sourcing_lnum = save_sourcing_lnum;
|
sourcing_lnum = save_sourcing_lnum;
|
||||||
current_SID = save_current_SID;
|
current_sctx = save_current_sctx;
|
||||||
if (do_profiling_yes) {
|
if (do_profiling_yes) {
|
||||||
script_prof_restore(&wait_start);
|
script_prof_restore(&wait_start);
|
||||||
}
|
}
|
||||||
@ -23603,10 +23624,10 @@ int store_session_globals(FILE *fd)
|
|||||||
* Display script name where an item was last set.
|
* Display script name where an item was last set.
|
||||||
* Should only be invoked when 'verbose' is non-zero.
|
* Should only be invoked when 'verbose' is non-zero.
|
||||||
*/
|
*/
|
||||||
void last_set_msg(scid_T scriptID)
|
void last_set_msg(sctx_T script_ctx)
|
||||||
{
|
{
|
||||||
const LastSet last_set = (LastSet){
|
const LastSet last_set = (LastSet){
|
||||||
.script_id = scriptID,
|
.script_ctx = script_ctx,
|
||||||
.channel_id = 0,
|
.channel_id = 0,
|
||||||
};
|
};
|
||||||
option_last_set_msg(last_set);
|
option_last_set_msg(last_set);
|
||||||
@ -23617,12 +23638,16 @@ void last_set_msg(scid_T scriptID)
|
|||||||
/// Should only be invoked when 'verbose' is non-zero.
|
/// Should only be invoked when 'verbose' is non-zero.
|
||||||
void option_last_set_msg(LastSet last_set)
|
void option_last_set_msg(LastSet last_set)
|
||||||
{
|
{
|
||||||
if (last_set.script_id != 0) {
|
if (last_set.script_ctx.sc_sid != 0) {
|
||||||
bool should_free;
|
bool should_free;
|
||||||
char_u *p = get_scriptname(last_set, &should_free);
|
char_u *p = get_scriptname(last_set, &should_free);
|
||||||
verbose_enter();
|
verbose_enter();
|
||||||
MSG_PUTS(_("\n\tLast set from "));
|
MSG_PUTS(_("\n\tLast set from "));
|
||||||
MSG_PUTS(p);
|
MSG_PUTS(p);
|
||||||
|
if (last_set.script_ctx.sc_lnum > 0) {
|
||||||
|
MSG_PUTS(_(" line "));
|
||||||
|
msg_outnum((long)last_set.script_ctx.sc_lnum);
|
||||||
|
}
|
||||||
if (should_free) {
|
if (should_free) {
|
||||||
xfree(p);
|
xfree(p);
|
||||||
}
|
}
|
||||||
@ -24068,7 +24093,7 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
|
|||||||
// Save caller scope information
|
// Save caller scope information
|
||||||
struct caller_scope saved_provider_caller_scope = provider_caller_scope;
|
struct caller_scope saved_provider_caller_scope = provider_caller_scope;
|
||||||
provider_caller_scope = (struct caller_scope) {
|
provider_caller_scope = (struct caller_scope) {
|
||||||
.SID = current_SID,
|
.script_ctx = current_sctx,
|
||||||
.sourcing_name = sourcing_name,
|
.sourcing_name = sourcing_name,
|
||||||
.sourcing_lnum = sourcing_lnum,
|
.sourcing_lnum = sourcing_lnum,
|
||||||
.autocmd_fname = autocmd_fname,
|
.autocmd_fname = autocmd_fname,
|
||||||
|
@ -248,6 +248,18 @@ typedef int scid_T;
|
|||||||
/// Format argument for scid_T
|
/// Format argument for scid_T
|
||||||
#define PRIdSCID "d"
|
#define PRIdSCID "d"
|
||||||
|
|
||||||
|
// SCript ConteXt (SCTX): identifies a script script line.
|
||||||
|
// When sourcing a script "sc_lnum" is zero, "sourcing_lnum" is the current
|
||||||
|
// line number. When executing a user function "sc_lnum" is the line where the
|
||||||
|
// function was defined, "sourcing_lnum" is the line number inside the
|
||||||
|
// function. When stored with a function, mapping, option, etc. "sc_lnum" is
|
||||||
|
// the line number in the script "sc_sid".
|
||||||
|
typedef struct {
|
||||||
|
scid_T sc_sid; // script ID
|
||||||
|
int sc_seq; // sourcing sequence number
|
||||||
|
linenr_T sc_lnum; // line number
|
||||||
|
} sctx_T;
|
||||||
|
|
||||||
// Structure to hold info for a function that is currently being executed.
|
// Structure to hold info for a function that is currently being executed.
|
||||||
typedef struct funccall_S funccall_T;
|
typedef struct funccall_S funccall_T;
|
||||||
|
|
||||||
@ -275,7 +287,7 @@ struct ufunc {
|
|||||||
proftime_T uf_tml_wait; ///< start wait time for current line
|
proftime_T uf_tml_wait; ///< start wait time for current line
|
||||||
int uf_tml_idx; ///< index of line being timed; -1 if none
|
int uf_tml_idx; ///< index of line being timed; -1 if none
|
||||||
int uf_tml_execed; ///< line being timed was executed
|
int uf_tml_execed; ///< line being timed was executed
|
||||||
scid_T uf_script_ID; ///< ID of script where function was defined,
|
sctx_T uf_script_ctx; ///< SCTX where function was defined,
|
||||||
///< used for s: variables
|
///< used for s: variables
|
||||||
int uf_refcount; ///< reference count, see func_name_refcount()
|
int uf_refcount; ///< reference count, see func_name_refcount()
|
||||||
funccall_T *uf_scoped; ///< l: local variables for closure
|
funccall_T *uf_scoped; ///< l: local variables for closure
|
||||||
|
@ -1080,8 +1080,8 @@ void script_prof_save(
|
|||||||
{
|
{
|
||||||
scriptitem_T *si;
|
scriptitem_T *si;
|
||||||
|
|
||||||
if (current_SID > 0 && current_SID <= script_items.ga_len) {
|
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) {
|
||||||
si = &SCRIPT_ITEM(current_SID);
|
si = &SCRIPT_ITEM(current_sctx.sc_sid);
|
||||||
if (si->sn_prof_on && si->sn_pr_nest++ == 0) {
|
if (si->sn_prof_on && si->sn_pr_nest++ == 0) {
|
||||||
si->sn_pr_child = profile_start();
|
si->sn_pr_child = profile_start();
|
||||||
}
|
}
|
||||||
@ -1094,8 +1094,8 @@ void script_prof_restore(proftime_T *tm)
|
|||||||
{
|
{
|
||||||
scriptitem_T *si;
|
scriptitem_T *si;
|
||||||
|
|
||||||
if (current_SID > 0 && current_SID <= script_items.ga_len) {
|
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) {
|
||||||
si = &SCRIPT_ITEM(current_SID);
|
si = &SCRIPT_ITEM(current_sctx.sc_sid);
|
||||||
if (si->sn_prof_on && --si->sn_pr_nest == 0) {
|
if (si->sn_prof_on && --si->sn_pr_nest == 0) {
|
||||||
si->sn_pr_child = profile_end(si->sn_pr_child);
|
si->sn_pr_child = profile_end(si->sn_pr_child);
|
||||||
// don't count wait time
|
// don't count wait time
|
||||||
@ -1192,8 +1192,8 @@ static void script_dump_profile(FILE *fd)
|
|||||||
/// profiled.
|
/// profiled.
|
||||||
bool prof_def_func(void)
|
bool prof_def_func(void)
|
||||||
{
|
{
|
||||||
if (current_SID > 0) {
|
if (current_sctx.sc_sid > 0) {
|
||||||
return SCRIPT_ITEM(current_SID).sn_pr_force;
|
return SCRIPT_ITEM(current_sctx.sc_sid).sn_pr_force;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -3033,8 +3033,8 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
|
|||||||
char_u *fname_exp;
|
char_u *fname_exp;
|
||||||
char_u *firstline = NULL;
|
char_u *firstline = NULL;
|
||||||
int retval = FAIL;
|
int retval = FAIL;
|
||||||
scid_T save_current_SID;
|
|
||||||
static scid_T last_current_SID = 0;
|
static scid_T last_current_SID = 0;
|
||||||
|
static int last_current_SID_seq = 0;
|
||||||
void *save_funccalp;
|
void *save_funccalp;
|
||||||
int save_debug_break_level = debug_break_level;
|
int save_debug_break_level = debug_break_level;
|
||||||
scriptitem_T *si = NULL;
|
scriptitem_T *si = NULL;
|
||||||
@ -3161,12 +3161,16 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
|
|||||||
|
|
||||||
// Check if this script was sourced before to finds its SID.
|
// Check if this script was sourced before to finds its SID.
|
||||||
// If it's new, generate a new SID.
|
// If it's new, generate a new SID.
|
||||||
save_current_SID = current_SID;
|
// Always use a new sequence number.
|
||||||
|
const sctx_T save_current_sctx = current_sctx;
|
||||||
|
current_sctx.sc_seq = ++last_current_SID_seq;
|
||||||
|
current_sctx.sc_lnum = 0;
|
||||||
FileID file_id;
|
FileID file_id;
|
||||||
bool file_id_ok = os_fileid((char *)fname_exp, &file_id);
|
bool file_id_ok = os_fileid((char *)fname_exp, &file_id);
|
||||||
assert(script_items.ga_len >= 0);
|
assert(script_items.ga_len >= 0);
|
||||||
for (current_SID = script_items.ga_len; current_SID > 0; current_SID--) {
|
for (current_sctx.sc_sid = script_items.ga_len; current_sctx.sc_sid > 0;
|
||||||
si = &SCRIPT_ITEM(current_SID);
|
current_sctx.sc_sid--) {
|
||||||
|
si = &SCRIPT_ITEM(current_sctx.sc_sid);
|
||||||
// Compare dev/ino when possible, it catches symbolic links.
|
// Compare dev/ino when possible, it catches symbolic links.
|
||||||
// Also compare file names, the inode may change when the file was edited.
|
// Also compare file names, the inode may change when the file was edited.
|
||||||
bool file_id_equal = file_id_ok && si->file_id_valid
|
bool file_id_equal = file_id_ok && si->file_id_valid
|
||||||
@ -3176,15 +3180,15 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (current_SID == 0) {
|
if (current_sctx.sc_sid == 0) {
|
||||||
current_SID = ++last_current_SID;
|
current_sctx.sc_sid = ++last_current_SID;
|
||||||
ga_grow(&script_items, (int)(current_SID - script_items.ga_len));
|
ga_grow(&script_items, (int)(current_sctx.sc_sid - script_items.ga_len));
|
||||||
while (script_items.ga_len < current_SID) {
|
while (script_items.ga_len < current_sctx.sc_sid) {
|
||||||
script_items.ga_len++;
|
script_items.ga_len++;
|
||||||
SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
|
SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
|
||||||
SCRIPT_ITEM(script_items.ga_len).sn_prof_on = false;
|
SCRIPT_ITEM(script_items.ga_len).sn_prof_on = false;
|
||||||
}
|
}
|
||||||
si = &SCRIPT_ITEM(current_SID);
|
si = &SCRIPT_ITEM(current_sctx.sc_sid);
|
||||||
si->sn_name = fname_exp;
|
si->sn_name = fname_exp;
|
||||||
fname_exp = vim_strsave(si->sn_name); // used for autocmd
|
fname_exp = vim_strsave(si->sn_name); // used for autocmd
|
||||||
if (file_id_ok) {
|
if (file_id_ok) {
|
||||||
@ -3195,7 +3199,7 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allocate the local script variables to use for this script.
|
// Allocate the local script variables to use for this script.
|
||||||
new_script_vars(current_SID);
|
new_script_vars(current_sctx.sc_sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l_do_profiling == PROF_YES) {
|
if (l_do_profiling == PROF_YES) {
|
||||||
@ -3236,7 +3240,7 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
|
|||||||
|
|
||||||
if (l_do_profiling == PROF_YES) {
|
if (l_do_profiling == PROF_YES) {
|
||||||
// Get "si" again, "script_items" may have been reallocated.
|
// Get "si" again, "script_items" may have been reallocated.
|
||||||
si = &SCRIPT_ITEM(current_SID);
|
si = &SCRIPT_ITEM(current_sctx.sc_sid);
|
||||||
if (si->sn_prof_on) {
|
if (si->sn_prof_on) {
|
||||||
si->sn_pr_start = profile_end(si->sn_pr_start);
|
si->sn_pr_start = profile_end(si->sn_pr_start);
|
||||||
si->sn_pr_start = profile_sub_wait(wait_start, si->sn_pr_start);
|
si->sn_pr_start = profile_sub_wait(wait_start, si->sn_pr_start);
|
||||||
@ -3277,7 +3281,7 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
|
|||||||
debug_break_level++;
|
debug_break_level++;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_SID = save_current_SID;
|
current_sctx = save_current_sctx;
|
||||||
restore_funccal(save_funccalp);
|
restore_funccal(save_funccalp);
|
||||||
if (l_do_profiling == PROF_YES) {
|
if (l_do_profiling == PROF_YES) {
|
||||||
prof_child_exit(&wait_start); // leaving a child now
|
prof_child_exit(&wait_start); // leaving a child now
|
||||||
@ -3338,7 +3342,7 @@ char_u *get_scriptname(LastSet last_set, bool *should_free)
|
|||||||
{
|
{
|
||||||
*should_free = false;
|
*should_free = false;
|
||||||
|
|
||||||
switch (last_set.script_id) {
|
switch (last_set.script_ctx.sc_sid) {
|
||||||
case SID_MODELINE:
|
case SID_MODELINE:
|
||||||
return (char_u *)_("modeline");
|
return (char_u *)_("modeline");
|
||||||
case SID_CMDARG:
|
case SID_CMDARG:
|
||||||
@ -3358,7 +3362,8 @@ char_u *get_scriptname(LastSet last_set, bool *should_free)
|
|||||||
return IObuff;
|
return IObuff;
|
||||||
default:
|
default:
|
||||||
*should_free = true;
|
*should_free = true;
|
||||||
return home_replace_save(NULL, SCRIPT_ITEM(last_set.script_id).sn_name);
|
return home_replace_save(NULL,
|
||||||
|
SCRIPT_ITEM(last_set.script_ctx.sc_sid).sn_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3585,10 +3590,10 @@ void script_line_start(void)
|
|||||||
scriptitem_T *si;
|
scriptitem_T *si;
|
||||||
sn_prl_T *pp;
|
sn_prl_T *pp;
|
||||||
|
|
||||||
if (current_SID <= 0 || current_SID > script_items.ga_len) {
|
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
si = &SCRIPT_ITEM(current_SID);
|
si = &SCRIPT_ITEM(current_sctx.sc_sid);
|
||||||
if (si->sn_prof_on && sourcing_lnum >= 1) {
|
if (si->sn_prof_on && sourcing_lnum >= 1) {
|
||||||
// Grow the array before starting the timer, so that the time spent
|
// Grow the array before starting the timer, so that the time spent
|
||||||
// here isn't counted.
|
// here isn't counted.
|
||||||
@ -3616,10 +3621,10 @@ void script_line_exec(void)
|
|||||||
{
|
{
|
||||||
scriptitem_T *si;
|
scriptitem_T *si;
|
||||||
|
|
||||||
if (current_SID <= 0 || current_SID > script_items.ga_len) {
|
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
si = &SCRIPT_ITEM(current_SID);
|
si = &SCRIPT_ITEM(current_sctx.sc_sid);
|
||||||
if (si->sn_prof_on && si->sn_prl_idx >= 0) {
|
if (si->sn_prof_on && si->sn_prl_idx >= 0) {
|
||||||
si->sn_prl_execed = true;
|
si->sn_prl_execed = true;
|
||||||
}
|
}
|
||||||
@ -3631,10 +3636,10 @@ void script_line_end(void)
|
|||||||
scriptitem_T *si;
|
scriptitem_T *si;
|
||||||
sn_prl_T *pp;
|
sn_prl_T *pp;
|
||||||
|
|
||||||
if (current_SID <= 0 || current_SID > script_items.ga_len) {
|
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
si = &SCRIPT_ITEM(current_SID);
|
si = &SCRIPT_ITEM(current_sctx.sc_sid);
|
||||||
if (si->sn_prof_on && si->sn_prl_idx >= 0
|
if (si->sn_prof_on && si->sn_prl_idx >= 0
|
||||||
&& si->sn_prl_idx < si->sn_prl_ga.ga_len) {
|
&& si->sn_prl_idx < si->sn_prl_ga.ga_len) {
|
||||||
if (si->sn_prl_execed) {
|
if (si->sn_prl_execed) {
|
||||||
|
@ -143,9 +143,9 @@ struct exarg {
|
|||||||
struct expand {
|
struct expand {
|
||||||
int xp_context; // type of expansion
|
int xp_context; // type of expansion
|
||||||
char_u *xp_pattern; // start of item to expand
|
char_u *xp_pattern; // start of item to expand
|
||||||
size_t xp_pattern_len; // bytes in xp_pattern before cursor
|
size_t xp_pattern_len; // bytes in xp_pattern before cursor
|
||||||
char_u *xp_arg; // completion function
|
char_u *xp_arg; // completion function
|
||||||
int xp_scriptID; // SID for completion function
|
sctx_T xp_script_ctx; // SCTX for completion function
|
||||||
int xp_backslash; // one of the XP_BS_ values
|
int xp_backslash; // one of the XP_BS_ values
|
||||||
#ifndef BACKSLASH_IN_FILENAME
|
#ifndef BACKSLASH_IN_FILENAME
|
||||||
int xp_shell; // TRUE for a shell command, more
|
int xp_shell; // TRUE for a shell command, more
|
||||||
|
@ -84,14 +84,14 @@ static int ex_pressedreturn = FALSE;
|
|||||||
static int did_lcd;
|
static int did_lcd;
|
||||||
|
|
||||||
typedef struct ucmd {
|
typedef struct ucmd {
|
||||||
char_u *uc_name; /* The command name */
|
char_u *uc_name; // The command name
|
||||||
uint32_t uc_argt; /* The argument type */
|
uint32_t uc_argt; // The argument type
|
||||||
char_u *uc_rep; /* The command's replacement string */
|
char_u *uc_rep; // The command's replacement string
|
||||||
long uc_def; /* The default value for a range/count */
|
long uc_def; // The default value for a range/count
|
||||||
int uc_compl; /* completion type */
|
int uc_compl; // completion type
|
||||||
int uc_addr_type; /* The command's address type */
|
int uc_addr_type; // The command's address type
|
||||||
scid_T uc_scriptID; /* SID where the command was defined */
|
sctx_T uc_script_ctx; // SCTX where the command was defined
|
||||||
char_u *uc_compl_arg; /* completion argument if any */
|
char_u *uc_compl_arg; // completion argument if any
|
||||||
} ucmd_T;
|
} ucmd_T;
|
||||||
|
|
||||||
#define UC_BUFFER 1 /* -buffer: local to current buffer */
|
#define UC_BUFFER 1 /* -buffer: local to current buffer */
|
||||||
@ -1471,22 +1471,6 @@ static char_u * do_one_cmd(char_u **cmdlinep,
|
|||||||
|| (cstack->cs_idx >= 0
|
|| (cstack->cs_idx >= 0
|
||||||
&& !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE)));
|
&& !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE)));
|
||||||
|
|
||||||
/* Count this line for profiling if ea.skip is FALSE. */
|
|
||||||
if (do_profiling == PROF_YES && !ea.skip) {
|
|
||||||
if (getline_equal(fgetline, cookie, get_func_line))
|
|
||||||
func_line_exec(getline_cookie(fgetline, cookie));
|
|
||||||
else if (getline_equal(fgetline, cookie, getsourceline))
|
|
||||||
script_line_exec();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* May go to debug mode. If this happens and the ">quit" debug command is
|
|
||||||
* used, throw an interrupt exception and skip the next command. */
|
|
||||||
dbg_check_breakpoint(&ea);
|
|
||||||
if (!ea.skip && got_int) {
|
|
||||||
ea.skip = TRUE;
|
|
||||||
(void)do_intthrow(cstack);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Skip over the range to find the command. Let "p" point to after it.
|
// 3. Skip over the range to find the command. Let "p" point to after it.
|
||||||
//
|
//
|
||||||
// We need the command to know what kind of range it uses.
|
// We need the command to know what kind of range it uses.
|
||||||
@ -1498,22 +1482,61 @@ static char_u * do_one_cmd(char_u **cmdlinep,
|
|||||||
}
|
}
|
||||||
p = find_command(&ea, NULL);
|
p = find_command(&ea, NULL);
|
||||||
|
|
||||||
/*
|
// Count this line for profiling if skip is TRUE.
|
||||||
* 4. Parse a range specifier of the form: addr [,addr] [;addr] ..
|
if (do_profiling == PROF_YES
|
||||||
*
|
&& (!ea.skip || cstack->cs_idx == 0
|
||||||
* where 'addr' is:
|
|| (cstack->cs_idx > 0
|
||||||
*
|
&& (cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE)))) {
|
||||||
* % (entire file)
|
int skip = did_emsg || got_int || current_exception;
|
||||||
* $ [+-NUM]
|
|
||||||
* 'x [+-NUM] (where x denotes a currently defined mark)
|
if (ea.cmdidx == CMD_catch) {
|
||||||
* . [+-NUM]
|
skip = !skip && !(cstack->cs_idx >= 0
|
||||||
* [+-NUM]..
|
&& (cstack->cs_flags[cstack->cs_idx] & CSF_THROWN)
|
||||||
* NUM
|
&& !(cstack->cs_flags[cstack->cs_idx] & CSF_CAUGHT));
|
||||||
*
|
} else if (ea.cmdidx == CMD_else || ea.cmdidx == CMD_elseif) {
|
||||||
* The ea.cmd pointer is updated to point to the first character following the
|
skip = skip || !(cstack->cs_idx >= 0
|
||||||
* range spec. If an initial address is found, but no second, the upper bound
|
&& !(cstack->cs_flags[cstack->cs_idx]
|
||||||
* is equal to the lower.
|
& (CSF_ACTIVE | CSF_TRUE)));
|
||||||
*/
|
} else if (ea.cmdidx == CMD_finally) {
|
||||||
|
skip = false;
|
||||||
|
} else if (ea.cmdidx != CMD_endif
|
||||||
|
&& ea.cmdidx != CMD_endfor
|
||||||
|
&& ea.cmdidx != CMD_endtry
|
||||||
|
&& ea.cmdidx != CMD_endwhile) {
|
||||||
|
skip = ea.skip;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!skip) {
|
||||||
|
if (getline_equal(fgetline, cookie, get_func_line)) {
|
||||||
|
func_line_exec(getline_cookie(fgetline, cookie));
|
||||||
|
} else if (getline_equal(fgetline, cookie, getsourceline)) {
|
||||||
|
script_line_exec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// May go to debug mode. If this happens and the ">quit" debug command is
|
||||||
|
// used, throw an interrupt exception and skip the next command.
|
||||||
|
dbg_check_breakpoint(&ea);
|
||||||
|
if (!ea.skip && got_int) {
|
||||||
|
ea.skip = TRUE;
|
||||||
|
(void)do_intthrow(cstack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Parse a range specifier of the form: addr [,addr] [;addr] ..
|
||||||
|
//
|
||||||
|
// where 'addr' is:
|
||||||
|
//
|
||||||
|
// % (entire file)
|
||||||
|
// $ [+-NUM]
|
||||||
|
// 'x [+-NUM] (where x denotes a currently defined mark)
|
||||||
|
// . [+-NUM]
|
||||||
|
// [+-NUM]..
|
||||||
|
// NUM
|
||||||
|
//
|
||||||
|
// The ea.cmd pointer is updated to point to the first character following the
|
||||||
|
// range spec. If an initial address is found, but no second, the upper bound
|
||||||
|
// is equal to the lower.
|
||||||
|
|
||||||
// ea.addr_type for user commands is set by find_ucmd
|
// ea.addr_type for user commands is set by find_ucmd
|
||||||
if (!IS_USER_CMDIDX(ea.cmdidx)) {
|
if (!IS_USER_CMDIDX(ea.cmdidx)) {
|
||||||
@ -2564,7 +2587,8 @@ find_ucmd (
|
|||||||
}
|
}
|
||||||
if (xp != NULL) {
|
if (xp != NULL) {
|
||||||
xp->xp_arg = uc->uc_compl_arg;
|
xp->xp_arg = uc->uc_compl_arg;
|
||||||
xp->xp_scriptID = uc->uc_scriptID;
|
xp->xp_script_ctx = uc->uc_script_ctx;
|
||||||
|
xp->xp_script_ctx.sc_lnum += sourcing_lnum;
|
||||||
}
|
}
|
||||||
/* Do not search for further abbreviations
|
/* Do not search for further abbreviations
|
||||||
* if this is an exact match. */
|
* if this is an exact match. */
|
||||||
@ -4879,7 +4903,8 @@ static int uc_add_command(char_u *name, size_t name_len, char_u *rep,
|
|||||||
cmd->uc_argt = argt;
|
cmd->uc_argt = argt;
|
||||||
cmd->uc_def = def;
|
cmd->uc_def = def;
|
||||||
cmd->uc_compl = compl;
|
cmd->uc_compl = compl;
|
||||||
cmd->uc_scriptID = current_SID;
|
cmd->uc_script_ctx = current_sctx;
|
||||||
|
cmd->uc_script_ctx.sc_lnum += sourcing_lnum;
|
||||||
cmd->uc_compl_arg = compl_arg;
|
cmd->uc_compl_arg = compl_arg;
|
||||||
cmd->uc_addr_type = addr_type;
|
cmd->uc_addr_type = addr_type;
|
||||||
|
|
||||||
@ -5070,9 +5095,10 @@ static void uc_list(char_u *name, size_t name_len)
|
|||||||
IObuff[len] = '\0';
|
IObuff[len] = '\0';
|
||||||
msg_outtrans(IObuff);
|
msg_outtrans(IObuff);
|
||||||
|
|
||||||
msg_outtrans_special(cmd->uc_rep, FALSE);
|
msg_outtrans_special(cmd->uc_rep, false);
|
||||||
if (p_verbose > 0)
|
if (p_verbose > 0) {
|
||||||
last_set_msg(cmd->uc_scriptID);
|
last_set_msg(cmd->uc_script_ctx);
|
||||||
|
}
|
||||||
ui_flush();
|
ui_flush();
|
||||||
os_breakcheck();
|
os_breakcheck();
|
||||||
if (got_int)
|
if (got_int)
|
||||||
@ -5716,7 +5742,7 @@ static void do_ucmd(exarg_T *eap)
|
|||||||
size_t split_len = 0;
|
size_t split_len = 0;
|
||||||
char_u *split_buf = NULL;
|
char_u *split_buf = NULL;
|
||||||
ucmd_T *cmd;
|
ucmd_T *cmd;
|
||||||
scid_T save_current_SID = current_SID;
|
const sctx_T save_current_sctx = current_sctx;
|
||||||
|
|
||||||
if (eap->cmdidx == CMD_USER)
|
if (eap->cmdidx == CMD_USER)
|
||||||
cmd = USER_CMD(eap->useridx);
|
cmd = USER_CMD(eap->useridx);
|
||||||
@ -5797,10 +5823,10 @@ static void do_ucmd(exarg_T *eap)
|
|||||||
buf = xmalloc(totlen + 1);
|
buf = xmalloc(totlen + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
current_SID = cmd->uc_scriptID;
|
current_sctx.sc_sid = cmd->uc_script_ctx.sc_sid;
|
||||||
(void)do_cmdline(buf, eap->getline, eap->cookie,
|
(void)do_cmdline(buf, eap->getline, eap->cookie,
|
||||||
DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_KEYTYPED);
|
DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_KEYTYPED);
|
||||||
current_SID = save_current_SID;
|
current_sctx = save_current_sctx;
|
||||||
xfree(buf);
|
xfree(buf);
|
||||||
xfree(split_buf);
|
xfree(split_buf);
|
||||||
}
|
}
|
||||||
@ -8538,6 +8564,8 @@ ssize_t find_cmdline_var(const char_u *src, size_t *usedlen)
|
|||||||
#define SPEC_ABUF (SPEC_AFILE + 1)
|
#define SPEC_ABUF (SPEC_AFILE + 1)
|
||||||
"<amatch>", // autocommand match name
|
"<amatch>", // autocommand match name
|
||||||
#define SPEC_AMATCH (SPEC_ABUF + 1)
|
#define SPEC_AMATCH (SPEC_ABUF + 1)
|
||||||
|
"<sflnum>", // script file line number
|
||||||
|
#define SPEC_SFLNUM (SPEC_AMATCH + 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
for (size_t i = 0; i < ARRAY_SIZE(spec_str); ++i) {
|
for (size_t i = 0; i < ARRAY_SIZE(spec_str); ++i) {
|
||||||
@ -8764,7 +8792,8 @@ eval_vars (
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SPEC_SLNUM: /* line in file for ":so" command */
|
|
||||||
|
case SPEC_SLNUM: // line in file for ":so" command
|
||||||
if (sourcing_name == NULL || sourcing_lnum == 0) {
|
if (sourcing_name == NULL || sourcing_lnum == 0) {
|
||||||
*errormsg = (char_u *)_("E842: no line number to use for \"<slnum>\"");
|
*errormsg = (char_u *)_("E842: no line number to use for \"<slnum>\"");
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -8772,6 +8801,17 @@ eval_vars (
|
|||||||
snprintf(strbuf, sizeof(strbuf), "%" PRIdLINENR, sourcing_lnum);
|
snprintf(strbuf, sizeof(strbuf), "%" PRIdLINENR, sourcing_lnum);
|
||||||
result = (char_u *)strbuf;
|
result = (char_u *)strbuf;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SPEC_SFLNUM: // line in script file
|
||||||
|
if (current_sctx.sc_lnum + sourcing_lnum == 0) {
|
||||||
|
*errormsg = (char_u *)_("E961: no line number to use for \"<sflnum>\"");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
snprintf((char *)strbuf, sizeof(strbuf), "%" PRIdLINENR,
|
||||||
|
current_sctx.sc_lnum + sourcing_lnum);
|
||||||
|
result = (char_u *)strbuf;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// should not happen
|
// should not happen
|
||||||
*errormsg = (char_u *)"";
|
*errormsg = (char_u *)"";
|
||||||
@ -10193,7 +10233,7 @@ Dictionary commands_array(buf_T *buf)
|
|||||||
|
|
||||||
PUT(d, "name", STRING_OBJ(cstr_to_string((char *)cmd->uc_name)));
|
PUT(d, "name", STRING_OBJ(cstr_to_string((char *)cmd->uc_name)));
|
||||||
PUT(d, "definition", STRING_OBJ(cstr_to_string((char *)cmd->uc_rep)));
|
PUT(d, "definition", STRING_OBJ(cstr_to_string((char *)cmd->uc_rep)));
|
||||||
PUT(d, "script_id", INTEGER_OBJ(cmd->uc_scriptID));
|
PUT(d, "script_id", INTEGER_OBJ(cmd->uc_script_ctx.sc_sid));
|
||||||
PUT(d, "bang", BOOLEAN_OBJ(!!(cmd->uc_argt & BANG)));
|
PUT(d, "bang", BOOLEAN_OBJ(!!(cmd->uc_argt & BANG)));
|
||||||
PUT(d, "bar", BOOLEAN_OBJ(!!(cmd->uc_argt & TRLBAR)));
|
PUT(d, "bar", BOOLEAN_OBJ(!!(cmd->uc_argt & TRLBAR)));
|
||||||
PUT(d, "register", BOOLEAN_OBJ(!!(cmd->uc_argt & REGSTR)));
|
PUT(d, "register", BOOLEAN_OBJ(!!(cmd->uc_argt & REGSTR)));
|
||||||
|
@ -1909,7 +1909,7 @@ static int command_line_changed(CommandLineState *s)
|
|||||||
redrawcmdline();
|
redrawcmdline();
|
||||||
s->did_incsearch = true;
|
s->did_incsearch = true;
|
||||||
} else if (s->firstc == ':'
|
} else if (s->firstc == ':'
|
||||||
&& current_SID == 0 // only if interactive
|
&& current_sctx.sc_sid == 0 // only if interactive
|
||||||
&& *p_icm != NUL // 'inccommand' is set
|
&& *p_icm != NUL // 'inccommand' is set
|
||||||
&& curbuf->b_p_ma // buffer is modifiable
|
&& curbuf->b_p_ma // buffer is modifiable
|
||||||
&& cmdline_star == 0 // not typing a password
|
&& cmdline_star == 0 // not typing a password
|
||||||
@ -5072,7 +5072,7 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
|
|||||||
char_u keep = 0;
|
char_u keep = 0;
|
||||||
typval_T args[4];
|
typval_T args[4];
|
||||||
char_u *pat = NULL;
|
char_u *pat = NULL;
|
||||||
int save_current_SID = current_SID;
|
const sctx_T save_current_sctx = current_sctx;
|
||||||
struct cmdline_info save_ccline;
|
struct cmdline_info save_ccline;
|
||||||
|
|
||||||
if (xp->xp_arg == NULL || xp->xp_arg[0] == '\0' || xp->xp_line == NULL)
|
if (xp->xp_arg == NULL || xp->xp_arg[0] == '\0' || xp->xp_line == NULL)
|
||||||
@ -5098,14 +5098,15 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
|
|||||||
save_ccline = ccline;
|
save_ccline = ccline;
|
||||||
ccline.cmdbuff = NULL;
|
ccline.cmdbuff = NULL;
|
||||||
ccline.cmdprompt = NULL;
|
ccline.cmdprompt = NULL;
|
||||||
current_SID = xp->xp_scriptID;
|
current_sctx = xp->xp_script_ctx;
|
||||||
|
|
||||||
void *const ret = user_expand_func(xp->xp_arg, 3, args);
|
void *const ret = user_expand_func(xp->xp_arg, 3, args);
|
||||||
|
|
||||||
ccline = save_ccline;
|
ccline = save_ccline;
|
||||||
current_SID = save_current_SID;
|
current_sctx = save_current_sctx;
|
||||||
if (ccline.cmdbuff != NULL)
|
if (ccline.cmdbuff != NULL) {
|
||||||
ccline.cmdbuff[ccline.cmdlen] = keep;
|
ccline.cmdbuff[ccline.cmdlen] = keep;
|
||||||
|
}
|
||||||
|
|
||||||
xfree(pat);
|
xfree(pat);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -103,7 +103,7 @@ typedef struct AutoCmd {
|
|||||||
bool once; // "One shot": removed after execution
|
bool once; // "One shot": removed after execution
|
||||||
char nested; // If autocommands nest here
|
char nested; // If autocommands nest here
|
||||||
char last; // last command in list
|
char last; // last command in list
|
||||||
scid_T scriptID; // script ID where defined
|
sctx_T script_ctx; // script context where defined
|
||||||
struct AutoCmd *next; // Next AutoCmd in list
|
struct AutoCmd *next; // Next AutoCmd in list
|
||||||
} AutoCmd;
|
} AutoCmd;
|
||||||
|
|
||||||
@ -5422,20 +5422,25 @@ static void show_autocmd(AutoPat *ap, event_T event)
|
|||||||
if (ac->cmd == NULL) { /* skip removed commands */
|
if (ac->cmd == NULL) { /* skip removed commands */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (msg_col >= 14)
|
if (msg_col >= 14) {
|
||||||
msg_putchar('\n');
|
msg_putchar('\n');
|
||||||
|
}
|
||||||
msg_col = 14;
|
msg_col = 14;
|
||||||
if (got_int)
|
if (got_int) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
msg_outtrans(ac->cmd);
|
msg_outtrans(ac->cmd);
|
||||||
if (p_verbose > 0)
|
if (p_verbose > 0) {
|
||||||
last_set_msg(ac->scriptID);
|
last_set_msg(ac->script_ctx);
|
||||||
if (got_int)
|
}
|
||||||
|
if (got_int) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (ac->next != NULL) {
|
if (ac->next != NULL) {
|
||||||
msg_putchar('\n');
|
msg_putchar('\n');
|
||||||
if (got_int)
|
if (got_int) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6241,7 +6246,8 @@ static int do_autocmd_event(event_T event, char_u *pat, bool once, int nested,
|
|||||||
prev_ac = &ac->next;
|
prev_ac = &ac->next;
|
||||||
ac = xmalloc(sizeof(AutoCmd));
|
ac = xmalloc(sizeof(AutoCmd));
|
||||||
ac->cmd = vim_strsave(cmd);
|
ac->cmd = vim_strsave(cmd);
|
||||||
ac->scriptID = current_SID;
|
ac->script_ctx = current_sctx;
|
||||||
|
ac->script_ctx.sc_lnum += sourcing_lnum;
|
||||||
ac->next = NULL;
|
ac->next = NULL;
|
||||||
*prev_ac = ac;
|
*prev_ac = ac;
|
||||||
ac->once = once;
|
ac->once = once;
|
||||||
@ -6675,7 +6681,6 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
|
|||||||
static int nesting = 0;
|
static int nesting = 0;
|
||||||
AutoPatCmd patcmd;
|
AutoPatCmd patcmd;
|
||||||
AutoPat *ap;
|
AutoPat *ap;
|
||||||
scid_T save_current_SID;
|
|
||||||
void *save_funccalp;
|
void *save_funccalp;
|
||||||
char_u *save_cmdarg;
|
char_u *save_cmdarg;
|
||||||
long save_cmdbang;
|
long save_cmdbang;
|
||||||
@ -6860,7 +6865,7 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
|
|||||||
save_sourcing_lnum = sourcing_lnum;
|
save_sourcing_lnum = sourcing_lnum;
|
||||||
sourcing_lnum = 0; /* no line number here */
|
sourcing_lnum = 0; /* no line number here */
|
||||||
|
|
||||||
save_current_SID = current_SID;
|
const sctx_T save_current_sctx = current_sctx;
|
||||||
|
|
||||||
if (do_profiling == PROF_YES)
|
if (do_profiling == PROF_YES)
|
||||||
prof_child_enter(&wait_time); /* doesn't count for the caller itself */
|
prof_child_enter(&wait_time); /* doesn't count for the caller itself */
|
||||||
@ -6954,7 +6959,7 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
|
|||||||
autocmd_fname = save_autocmd_fname;
|
autocmd_fname = save_autocmd_fname;
|
||||||
autocmd_bufnr = save_autocmd_bufnr;
|
autocmd_bufnr = save_autocmd_bufnr;
|
||||||
autocmd_match = save_autocmd_match;
|
autocmd_match = save_autocmd_match;
|
||||||
current_SID = save_current_SID;
|
current_sctx = save_current_sctx;
|
||||||
restore_funccal(save_funccalp);
|
restore_funccal(save_funccalp);
|
||||||
if (do_profiling == PROF_YES)
|
if (do_profiling == PROF_YES)
|
||||||
prof_child_exit(&wait_time);
|
prof_child_exit(&wait_time);
|
||||||
@ -7147,7 +7152,7 @@ char_u *getnextac(int c, void *cookie, int indent)
|
|||||||
au_del_cmd(ac);
|
au_del_cmd(ac);
|
||||||
}
|
}
|
||||||
autocmd_nested = ac->nested;
|
autocmd_nested = ac->nested;
|
||||||
current_SID = ac->scriptID;
|
current_sctx = ac->script_ctx;
|
||||||
if (ac->last) {
|
if (ac->last) {
|
||||||
acp->nextcmd = NULL;
|
acp->nextcmd = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2957,7 +2957,8 @@ int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
|
|||||||
mp->m_silent = args->silent;
|
mp->m_silent = args->silent;
|
||||||
mp->m_mode = mode;
|
mp->m_mode = mode;
|
||||||
mp->m_expr = args->expr;
|
mp->m_expr = args->expr;
|
||||||
mp->m_script_ID = current_SID;
|
mp->m_script_ctx = current_sctx;
|
||||||
|
mp->m_script_ctx.sc_lnum += sourcing_lnum;
|
||||||
did_it = true;
|
did_it = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3032,7 +3033,8 @@ int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
|
|||||||
mp->m_silent = args->silent;
|
mp->m_silent = args->silent;
|
||||||
mp->m_mode = mode;
|
mp->m_mode = mode;
|
||||||
mp->m_expr = args->expr;
|
mp->m_expr = args->expr;
|
||||||
mp->m_script_ID = current_SID;
|
mp->m_script_ctx = current_sctx;
|
||||||
|
mp->m_script_ctx.sc_lnum += sourcing_lnum;
|
||||||
|
|
||||||
// add the new entry in front of the abbrlist or maphash[] list
|
// add the new entry in front of the abbrlist or maphash[] list
|
||||||
if (is_abbrev) {
|
if (is_abbrev) {
|
||||||
@ -3375,9 +3377,10 @@ showmap (
|
|||||||
msg_outtrans_special(s, FALSE);
|
msg_outtrans_special(s, FALSE);
|
||||||
xfree(s);
|
xfree(s);
|
||||||
}
|
}
|
||||||
if (p_verbose > 0)
|
if (p_verbose > 0) {
|
||||||
last_set_msg(mp->m_script_ID);
|
last_set_msg(mp->m_script_ctx);
|
||||||
ui_flush(); /* show one line at a time */
|
}
|
||||||
|
ui_flush(); // show one line at a time
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if a map exists that has given string in the rhs
|
/// Check if a map exists that has given string in the rhs
|
||||||
|
@ -332,8 +332,8 @@ EXTERN int garbage_collect_at_exit INIT(= false);
|
|||||||
#define SID_LUA -7 // for Lua scripts/chunks
|
#define SID_LUA -7 // for Lua scripts/chunks
|
||||||
#define SID_API_CLIENT -8 // for API clients
|
#define SID_API_CLIENT -8 // for API clients
|
||||||
|
|
||||||
// ID of script being sourced or was sourced to define the current function.
|
// Script CTX being sourced or was sourced to define the current function.
|
||||||
EXTERN scid_T current_SID INIT(= 0);
|
EXTERN sctx_T current_sctx INIT(= { 0 COMMA 0 COMMA 0 });
|
||||||
// ID of the current channel making a client API call
|
// ID of the current channel making a client API call
|
||||||
EXTERN uint64_t current_channel_id INIT(= 0);
|
EXTERN uint64_t current_channel_id INIT(= 0);
|
||||||
|
|
||||||
@ -342,8 +342,8 @@ EXTERN bool did_source_packages INIT(= false);
|
|||||||
// Scope information for the code that indirectly triggered the current
|
// Scope information for the code that indirectly triggered the current
|
||||||
// provider function call
|
// provider function call
|
||||||
EXTERN struct caller_scope {
|
EXTERN struct caller_scope {
|
||||||
scid_T SID;
|
sctx_T script_ctx;
|
||||||
uint8_t *sourcing_name, *autocmd_fname, *autocmd_match;
|
uint8_t *sourcing_name, *autocmd_fname, *autocmd_match;
|
||||||
linenr_T sourcing_lnum;
|
linenr_T sourcing_lnum;
|
||||||
int autocmd_bufnr;
|
int autocmd_bufnr;
|
||||||
void *funccalp;
|
void *funccalp;
|
||||||
|
@ -824,7 +824,8 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
|
|||||||
|
|
||||||
// Allocate space for the translation. Worst case a single character is
|
// Allocate space for the translation. Worst case a single character is
|
||||||
// replaced by 6 bytes (shifted special key), plus a NUL at the end.
|
// replaced by 6 bytes (shifted special key), plus a NUL at the end.
|
||||||
result = xmalloc(from_len * 6 + 1);
|
const size_t buf_len = from_len * 6 + 1;
|
||||||
|
result = xmalloc(buf_len);
|
||||||
|
|
||||||
src = from;
|
src = from;
|
||||||
|
|
||||||
@ -849,14 +850,15 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
|
|||||||
// Replace <SID> by K_SNR <script-nr> _.
|
// Replace <SID> by K_SNR <script-nr> _.
|
||||||
// (room: 5 * 6 = 30 bytes; needed: 3 + <nr> + 1 <= 14)
|
// (room: 5 * 6 = 30 bytes; needed: 3 + <nr> + 1 <= 14)
|
||||||
if (end - src >= 4 && STRNICMP(src, "<SID>", 5) == 0) {
|
if (end - src >= 4 && STRNICMP(src, "<SID>", 5) == 0) {
|
||||||
if (current_SID <= 0) {
|
if (current_sctx.sc_sid <= 0) {
|
||||||
EMSG(_(e_usingsid));
|
EMSG(_(e_usingsid));
|
||||||
} else {
|
} else {
|
||||||
src += 5;
|
src += 5;
|
||||||
result[dlen++] = K_SPECIAL;
|
result[dlen++] = K_SPECIAL;
|
||||||
result[dlen++] = (int)KS_EXTRA;
|
result[dlen++] = (int)KS_EXTRA;
|
||||||
result[dlen++] = (int)KE_SNR;
|
result[dlen++] = (int)KE_SNR;
|
||||||
sprintf((char *)result + dlen, "%" PRId64, (int64_t)current_SID);
|
snprintf((char *)result + dlen, buf_len - dlen, "%" PRId64,
|
||||||
|
(int64_t)current_sctx.sc_sid);
|
||||||
dlen += STRLEN(result + dlen);
|
dlen += STRLEN(result + dlen);
|
||||||
result[dlen++] = '_';
|
result[dlen++] = '_';
|
||||||
continue;
|
continue;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#else
|
#else
|
||||||
# ifndef INIT
|
# ifndef INIT
|
||||||
# define INIT(...) __VA_ARGS__
|
# define INIT(...) __VA_ARGS__
|
||||||
|
# define COMMA ,
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1638,11 +1638,12 @@ static void exe_pre_commands(mparm_T *parmp)
|
|||||||
if (cnt > 0) {
|
if (cnt > 0) {
|
||||||
curwin->w_cursor.lnum = 0; /* just in case.. */
|
curwin->w_cursor.lnum = 0; /* just in case.. */
|
||||||
sourcing_name = (char_u *)_("pre-vimrc command line");
|
sourcing_name = (char_u *)_("pre-vimrc command line");
|
||||||
current_SID = SID_CMDARG;
|
current_sctx.sc_sid = SID_CMDARG;
|
||||||
for (i = 0; i < cnt; ++i)
|
for (i = 0; i < cnt; i++) {
|
||||||
do_cmdline_cmd(cmds[i]);
|
do_cmdline_cmd(cmds[i]);
|
||||||
|
}
|
||||||
sourcing_name = NULL;
|
sourcing_name = NULL;
|
||||||
current_SID = 0;
|
current_sctx.sc_sid = 0;
|
||||||
TIME_MSG("--cmd commands");
|
TIME_MSG("--cmd commands");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1663,16 +1664,18 @@ static void exe_commands(mparm_T *parmp)
|
|||||||
if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1)
|
if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1)
|
||||||
curwin->w_cursor.lnum = 0;
|
curwin->w_cursor.lnum = 0;
|
||||||
sourcing_name = (char_u *)"command line";
|
sourcing_name = (char_u *)"command line";
|
||||||
current_SID = SID_CARG;
|
current_sctx.sc_sid = SID_CARG;
|
||||||
for (i = 0; i < parmp->n_commands; ++i) {
|
current_sctx.sc_seq = 0;
|
||||||
|
for (i = 0; i < parmp->n_commands; i++) {
|
||||||
do_cmdline_cmd(parmp->commands[i]);
|
do_cmdline_cmd(parmp->commands[i]);
|
||||||
if (parmp->cmds_tofree[i])
|
if (parmp->cmds_tofree[i])
|
||||||
xfree(parmp->commands[i]);
|
xfree(parmp->commands[i]);
|
||||||
}
|
}
|
||||||
sourcing_name = NULL;
|
sourcing_name = NULL;
|
||||||
current_SID = 0;
|
current_sctx.sc_sid = 0;
|
||||||
if (curwin->w_cursor.lnum == 0)
|
if (curwin->w_cursor.lnum == 0) {
|
||||||
curwin->w_cursor.lnum = 1;
|
curwin->w_cursor.lnum = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!exmode_active)
|
if (!exmode_active)
|
||||||
msg_scroll = FALSE;
|
msg_scroll = FALSE;
|
||||||
@ -1858,12 +1861,14 @@ static int execute_env(char *env)
|
|||||||
linenr_T save_sourcing_lnum = sourcing_lnum;
|
linenr_T save_sourcing_lnum = sourcing_lnum;
|
||||||
sourcing_name = (char_u *)env;
|
sourcing_name = (char_u *)env;
|
||||||
sourcing_lnum = 0;
|
sourcing_lnum = 0;
|
||||||
scid_T save_sid = current_SID;
|
const sctx_T save_current_sctx = current_sctx;
|
||||||
current_SID = SID_ENV;
|
current_sctx.sc_sid = SID_ENV;
|
||||||
|
current_sctx.sc_seq = 0;
|
||||||
|
current_sctx.sc_lnum = 0;
|
||||||
do_cmdline_cmd((char *)initstr);
|
do_cmdline_cmd((char *)initstr);
|
||||||
sourcing_name = save_sourcing_name;
|
sourcing_name = save_sourcing_name;
|
||||||
sourcing_lnum = save_sourcing_lnum;
|
sourcing_lnum = save_sourcing_lnum;
|
||||||
current_SID = save_sid;
|
current_sctx = save_current_sctx;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
@ -1370,7 +1370,7 @@ void ex_emenu(exarg_T *eap)
|
|||||||
|
|
||||||
/* Found the menu, so execute.
|
/* Found the menu, so execute.
|
||||||
* Use the Insert mode entry when returning to Insert mode. */
|
* Use the Insert mode entry when returning to Insert mode. */
|
||||||
if (((State & INSERT) || restart_edit) && !current_SID) {
|
if (((State & INSERT) || restart_edit) && !current_sctx.sc_sid) {
|
||||||
mode = (char_u *)"Insert";
|
mode = (char_u *)"Insert";
|
||||||
idx = MENU_INDEX_INSERT;
|
idx = MENU_INDEX_INSERT;
|
||||||
} else if (State & CMDLINE) {
|
} else if (State & CMDLINE) {
|
||||||
@ -1431,7 +1431,7 @@ void ex_emenu(exarg_T *eap)
|
|||||||
if (menu->strings[idx] != NULL) {
|
if (menu->strings[idx] != NULL) {
|
||||||
// When executing a script or function execute the commands right now.
|
// When executing a script or function execute the commands right now.
|
||||||
// Otherwise put them in the typeahead buffer.
|
// Otherwise put them in the typeahead buffer.
|
||||||
if (current_SID != 0) {
|
if (current_sctx.sc_sid != 0) {
|
||||||
exec_normal_cmd(menu->strings[idx], menu->noremap[idx],
|
exec_normal_cmd(menu->strings[idx], menu->noremap[idx],
|
||||||
menu->silent[idx]);
|
menu->silent[idx]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -200,7 +200,7 @@ typedef struct vimoption {
|
|||||||
// local option: indirect option index
|
// local option: indirect option index
|
||||||
char_u *def_val[2]; // default values for variable (vi and vim)
|
char_u *def_val[2]; // default values for variable (vi and vim)
|
||||||
LastSet last_set; // script in which the option was last set
|
LastSet last_set; // script in which the option was last set
|
||||||
# define SCRIPTID_INIT , 0
|
# define SCTX_INIT , { 0, 0, 0 }
|
||||||
} vimoption_T;
|
} vimoption_T;
|
||||||
|
|
||||||
#define VI_DEFAULT 0 // def_val[VI_DEFAULT] is Vi default value
|
#define VI_DEFAULT 0 // def_val[VI_DEFAULT] is Vi default value
|
||||||
@ -896,7 +896,7 @@ set_option_default(
|
|||||||
*flagsp = *flagsp & ~P_INSECURE;
|
*flagsp = *flagsp & ~P_INSECURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
|
set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1384,10 +1384,10 @@ int do_set(
|
|||||||
if (varp == options[opt_idx].var) {
|
if (varp == options[opt_idx].var) {
|
||||||
option_last_set_msg(options[opt_idx].last_set);
|
option_last_set_msg(options[opt_idx].last_set);
|
||||||
} else if ((int)options[opt_idx].indir & PV_WIN) {
|
} else if ((int)options[opt_idx].indir & PV_WIN) {
|
||||||
option_last_set_msg(curwin->w_p_scriptID[
|
option_last_set_msg(curwin->w_p_script_ctx[
|
||||||
(int)options[opt_idx].indir & PV_MASK]);
|
(int)options[opt_idx].indir & PV_MASK]);
|
||||||
} else if ((int)options[opt_idx].indir & PV_BUF) {
|
} else if ((int)options[opt_idx].indir & PV_BUF) {
|
||||||
option_last_set_msg(curbuf->b_p_scriptID[
|
option_last_set_msg(curbuf->b_p_script_ctx[
|
||||||
(int)options[opt_idx].indir & PV_MASK]);
|
(int)options[opt_idx].indir & PV_MASK]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2359,13 +2359,12 @@ static void redraw_titles(void)
|
|||||||
|
|
||||||
static int shada_idx = -1;
|
static int shada_idx = -1;
|
||||||
|
|
||||||
/*
|
// Set a string option to a new value (without checking the effect).
|
||||||
* Set a string option to a new value (without checking the effect).
|
// The string is copied into allocated memory.
|
||||||
* The string is copied into allocated memory.
|
// if ("opt_idx" == -1) "name" is used, otherwise "opt_idx" is used.
|
||||||
* if ("opt_idx" == -1) "name" is used, otherwise "opt_idx" is used.
|
// When "set_sid" is zero set the scriptID to current_sctx.sc_sid. When
|
||||||
* When "set_sid" is zero set the scriptID to current_SID. When "set_sid" is
|
// "set_sid" is SID_NONE don't set the scriptID. Otherwise set the scriptID to
|
||||||
* SID_NONE don't set the scriptID. Otherwise set the scriptID to "set_sid".
|
// "set_sid".
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
set_string_option_direct(
|
set_string_option_direct(
|
||||||
char_u *name,
|
char_u *name,
|
||||||
@ -2417,9 +2416,18 @@ set_string_option_direct(
|
|||||||
free_string_option(*varp);
|
free_string_option(*varp);
|
||||||
*varp = empty_option;
|
*varp = empty_option;
|
||||||
}
|
}
|
||||||
if (set_sid != SID_NONE)
|
if (set_sid != SID_NONE) {
|
||||||
set_option_scriptID_idx(idx, opt_flags,
|
sctx_T script_ctx;
|
||||||
set_sid == 0 ? current_SID : set_sid);
|
|
||||||
|
if (set_sid == 0) {
|
||||||
|
script_ctx = current_sctx;
|
||||||
|
} else {
|
||||||
|
script_ctx.sc_sid = set_sid;
|
||||||
|
script_ctx.sc_seq = 0;
|
||||||
|
script_ctx.sc_lnum = 0;
|
||||||
|
}
|
||||||
|
set_option_sctx_idx(idx, opt_flags, script_ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3296,12 +3304,10 @@ ambw_end:
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Remember where the option was set.
|
// Remember where the option was set.
|
||||||
set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
|
set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
|
||||||
/*
|
// Free string options that are in allocated memory.
|
||||||
* Free string options that are in allocated memory.
|
// Use "free_oldval", because recursiveness may change the flags under
|
||||||
* Use "free_oldval", because recursiveness may change the flags under
|
// our fingers (esp. init_highlight()).
|
||||||
* our fingers (esp. init_highlight()).
|
|
||||||
*/
|
|
||||||
if (free_oldval) {
|
if (free_oldval) {
|
||||||
free_string_option(oldval);
|
free_string_option(oldval);
|
||||||
}
|
}
|
||||||
@ -3786,15 +3792,16 @@ static bool parse_winhl_opt(win_T *wp)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set the script_ctx for an option, taking care of setting the buffer- or
|
||||||
* Set the scriptID for an option, taking care of setting the buffer- or
|
// window-local value.
|
||||||
* window-local value.
|
static void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
|
||||||
*/
|
|
||||||
static void set_option_scriptID_idx(int opt_idx, int opt_flags, int id)
|
|
||||||
{
|
{
|
||||||
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
|
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
|
||||||
int indir = (int)options[opt_idx].indir;
|
int indir = (int)options[opt_idx].indir;
|
||||||
const LastSet last_set = { id, current_channel_id };
|
const LastSet last_set = { .script_ctx =
|
||||||
|
{ script_ctx.sc_sid, script_ctx.sc_seq,
|
||||||
|
script_ctx.sc_lnum + sourcing_lnum },
|
||||||
|
current_channel_id };
|
||||||
|
|
||||||
// Remember where the option was set. For local options need to do that
|
// Remember where the option was set. For local options need to do that
|
||||||
// in the buffer or window structure.
|
// in the buffer or window structure.
|
||||||
@ -3803,9 +3810,9 @@ static void set_option_scriptID_idx(int opt_idx, int opt_flags, int id)
|
|||||||
}
|
}
|
||||||
if (both || (opt_flags & OPT_LOCAL)) {
|
if (both || (opt_flags & OPT_LOCAL)) {
|
||||||
if (indir & PV_BUF) {
|
if (indir & PV_BUF) {
|
||||||
curbuf->b_p_scriptID[indir & PV_MASK] = last_set;
|
curbuf->b_p_script_ctx[indir & PV_MASK] = last_set;
|
||||||
} else if (indir & PV_WIN) {
|
} else if (indir & PV_WIN) {
|
||||||
curwin->w_p_scriptID[indir & PV_MASK] = last_set;
|
curwin->w_p_script_ctx[indir & PV_MASK] = last_set;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3832,7 +3839,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
|
|||||||
|
|
||||||
*(int *)varp = value; // set the new value
|
*(int *)varp = value; // set the new value
|
||||||
// Remember where the option was set.
|
// Remember where the option was set.
|
||||||
set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
|
set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
|
||||||
|
|
||||||
|
|
||||||
// May set global value for local option.
|
// May set global value for local option.
|
||||||
@ -4310,7 +4317,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
|
|||||||
|
|
||||||
*pp = value;
|
*pp = value;
|
||||||
// Remember where the option was set.
|
// Remember where the option was set.
|
||||||
set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
|
set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
|
||||||
|
|
||||||
// For these options we want to fix some invalid values.
|
// For these options we want to fix some invalid values.
|
||||||
if (pp == &p_window) {
|
if (pp == &p_window) {
|
||||||
|
@ -838,7 +838,7 @@ enum {
|
|||||||
|
|
||||||
/// Stores an identifier of a script or channel that last set an option.
|
/// Stores an identifier of a script or channel that last set an option.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
scid_T script_id; /// Script ID or one of SID_* special values.
|
sctx_T script_ctx; /// script context where the option was last set
|
||||||
uint64_t channel_id; /// Only used when script_id is SID_API_CLIENT.
|
uint64_t channel_id; /// Only used when script_id is SID_API_CLIENT.
|
||||||
} LastSet;
|
} LastSet;
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ struct hl_group {
|
|||||||
int sg_attr; ///< Screen attr @see ATTR_ENTRY
|
int sg_attr; ///< Screen attr @see ATTR_ENTRY
|
||||||
int sg_link; ///< link to this highlight group ID
|
int sg_link; ///< link to this highlight group ID
|
||||||
int sg_set; ///< combination of flags in \ref SG_SET
|
int sg_set; ///< combination of flags in \ref SG_SET
|
||||||
scid_T sg_scriptID; ///< script in which the group was last set
|
sctx_T sg_script_ctx; ///< script in which the group was last set
|
||||||
// for terminal UIs
|
// for terminal UIs
|
||||||
int sg_cterm; ///< "cterm=" highlighting attr
|
int sg_cterm; ///< "cterm=" highlighting attr
|
||||||
///< (combination of \ref HlAttrFlags)
|
///< (combination of \ref HlAttrFlags)
|
||||||
@ -6565,13 +6565,15 @@ void do_highlight(const char *line, const bool forceit, const bool init)
|
|||||||
EMSG(_("E414: group has settings, highlight link ignored"));
|
EMSG(_("E414: group has settings, highlight link ignored"));
|
||||||
}
|
}
|
||||||
} else if (HL_TABLE()[from_id - 1].sg_link != to_id
|
} else if (HL_TABLE()[from_id - 1].sg_link != to_id
|
||||||
|| HL_TABLE()[from_id - 1].sg_scriptID != current_SID
|
|| HL_TABLE()[from_id - 1].sg_script_ctx.sc_sid
|
||||||
|
!= current_sctx.sc_sid
|
||||||
|| HL_TABLE()[from_id - 1].sg_cleared) {
|
|| HL_TABLE()[from_id - 1].sg_cleared) {
|
||||||
if (!init) {
|
if (!init) {
|
||||||
HL_TABLE()[from_id - 1].sg_set |= SG_LINK;
|
HL_TABLE()[from_id - 1].sg_set |= SG_LINK;
|
||||||
}
|
}
|
||||||
HL_TABLE()[from_id - 1].sg_link = to_id;
|
HL_TABLE()[from_id - 1].sg_link = to_id;
|
||||||
HL_TABLE()[from_id - 1].sg_scriptID = current_SID;
|
HL_TABLE()[from_id - 1].sg_script_ctx = current_sctx;
|
||||||
|
HL_TABLE()[from_id - 1].sg_script_ctx.sc_lnum += sourcing_lnum;
|
||||||
HL_TABLE()[from_id - 1].sg_cleared = false;
|
HL_TABLE()[from_id - 1].sg_cleared = false;
|
||||||
redraw_all_later(SOME_VALID);
|
redraw_all_later(SOME_VALID);
|
||||||
|
|
||||||
@ -6950,7 +6952,8 @@ void do_highlight(const char *line, const bool forceit, const bool init)
|
|||||||
} else {
|
} else {
|
||||||
set_hl_attr(idx);
|
set_hl_attr(idx);
|
||||||
}
|
}
|
||||||
HL_TABLE()[idx].sg_scriptID = current_SID;
|
HL_TABLE()[idx].sg_script_ctx = current_sctx;
|
||||||
|
HL_TABLE()[idx].sg_script_ctx.sc_lnum += sourcing_lnum;
|
||||||
}
|
}
|
||||||
xfree(key);
|
xfree(key);
|
||||||
xfree(arg);
|
xfree(arg);
|
||||||
@ -7034,7 +7037,8 @@ static void highlight_clear(int idx)
|
|||||||
// Clear the script ID only when there is no link, since that is not
|
// Clear the script ID only when there is no link, since that is not
|
||||||
// cleared.
|
// cleared.
|
||||||
if (HL_TABLE()[idx].sg_link == 0) {
|
if (HL_TABLE()[idx].sg_link == 0) {
|
||||||
HL_TABLE()[idx].sg_scriptID = 0;
|
HL_TABLE()[idx].sg_script_ctx.sc_sid = 0;
|
||||||
|
HL_TABLE()[idx].sg_script_ctx.sc_lnum = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7084,8 +7088,9 @@ static void highlight_list_one(const int id)
|
|||||||
|
|
||||||
if (!didh)
|
if (!didh)
|
||||||
highlight_list_arg(id, didh, LIST_STRING, 0, (char_u *)"cleared", "");
|
highlight_list_arg(id, didh, LIST_STRING, 0, (char_u *)"cleared", "");
|
||||||
if (p_verbose > 0)
|
if (p_verbose > 0) {
|
||||||
last_set_msg(sgp->sg_scriptID);
|
last_set_msg(sgp->sg_script_ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Outputs a highlight when doing ":hi MyHighlight"
|
/// Outputs a highlight when doing ":hi MyHighlight"
|
||||||
|
0
src/nvim/testdir/screendump.vim
Normal file
0
src/nvim/testdir/screendump.vim
Normal file
@ -11,6 +11,7 @@ source test_ex_equal.vim
|
|||||||
source test_ex_undo.vim
|
source test_ex_undo.vim
|
||||||
source test_ex_z.vim
|
source test_ex_z.vim
|
||||||
source test_execute_func.vim
|
source test_execute_func.vim
|
||||||
|
source test_expand_func.vim
|
||||||
source test_expr.vim
|
source test_expr.vim
|
||||||
source test_feedkeys.vim
|
source test_feedkeys.vim
|
||||||
source test_filter_cmd.vim
|
source test_filter_cmd.vim
|
||||||
|
66
src/nvim/testdir/test_expand_func.vim
Normal file
66
src/nvim/testdir/test_expand_func.vim
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
" Tests for expand()
|
||||||
|
|
||||||
|
let s:sfile = expand('<sfile>')
|
||||||
|
let s:slnum = str2nr(expand('<slnum>'))
|
||||||
|
let s:sflnum = str2nr(expand('<sflnum>'))
|
||||||
|
|
||||||
|
func s:expand_sfile()
|
||||||
|
return expand('<sfile>')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func s:expand_slnum()
|
||||||
|
return str2nr(expand('<slnum>'))
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func s:expand_sflnum()
|
||||||
|
return str2nr(expand('<sflnum>'))
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_expand_sfile()
|
||||||
|
call assert_match('test_expand_func\.vim$', s:sfile)
|
||||||
|
call assert_match('^function .*\.\.Test_expand_sfile$', expand('<sfile>'))
|
||||||
|
|
||||||
|
" Call in script-local function
|
||||||
|
call assert_match('^function .*\.\.Test_expand_sfile\[5\]\.\.<SNR>\d\+_expand_sfile$', s:expand_sfile())
|
||||||
|
|
||||||
|
" Call in command
|
||||||
|
command Sfile echo expand('<sfile>')
|
||||||
|
call assert_match('^function .*\.\.Test_expand_sfile$', trim(execute('Sfile')))
|
||||||
|
delcommand Sfile
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_expand_slnum()
|
||||||
|
call assert_equal(4, s:slnum)
|
||||||
|
call assert_equal(2, str2nr(expand('<slnum>')))
|
||||||
|
|
||||||
|
" Line-continuation
|
||||||
|
call assert_equal(
|
||||||
|
\ 5,
|
||||||
|
\ str2nr(expand('<slnum>')))
|
||||||
|
|
||||||
|
" Call in script-local function
|
||||||
|
call assert_equal(1, s:expand_slnum())
|
||||||
|
|
||||||
|
" Call in command
|
||||||
|
command Slnum echo expand('<slnum>')
|
||||||
|
call assert_equal(14, str2nr(trim(execute('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())
|
||||||
|
|
||||||
|
" Call in command
|
||||||
|
command Flnum echo expand('<sflnum>')
|
||||||
|
call assert_equal(64, str2nr(trim(execute('Flnum'))))
|
||||||
|
delcommand Flnum
|
||||||
|
endfunc
|
@ -1067,6 +1067,33 @@ func Test_func_range_with_edit()
|
|||||||
bwipe!
|
bwipe!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_func_exists_on_reload()
|
||||||
|
call writefile(['func ExistingFunction()', 'echo "yes"', 'endfunc'], 'Xfuncexists')
|
||||||
|
call assert_equal(0, exists('*ExistingFunction'))
|
||||||
|
source Xfuncexists
|
||||||
|
call assert_equal(1, exists('*ExistingFunction'))
|
||||||
|
" Redefining a function when reloading a script is OK.
|
||||||
|
source Xfuncexists
|
||||||
|
call assert_equal(1, exists('*ExistingFunction'))
|
||||||
|
|
||||||
|
" But redefining in another script is not OK.
|
||||||
|
call writefile(['func ExistingFunction()', 'echo "yes"', 'endfunc'], 'Xfuncexists2')
|
||||||
|
call assert_fails('source Xfuncexists2', 'E122:')
|
||||||
|
|
||||||
|
delfunc ExistingFunction
|
||||||
|
call assert_equal(0, exists('*ExistingFunction'))
|
||||||
|
call writefile([
|
||||||
|
\ 'func ExistingFunction()', 'echo "yes"', 'endfunc',
|
||||||
|
\ 'func ExistingFunction()', 'echo "no"', 'endfunc',
|
||||||
|
\ ], 'Xfuncexists')
|
||||||
|
call assert_fails('source Xfuncexists', 'E122:')
|
||||||
|
call assert_equal(1, exists('*ExistingFunction'))
|
||||||
|
|
||||||
|
call delete('Xfuncexists2')
|
||||||
|
call delete('Xfuncexists')
|
||||||
|
delfunc ExistingFunction
|
||||||
|
endfunc
|
||||||
|
|
||||||
sandbox function Fsandbox()
|
sandbox function Fsandbox()
|
||||||
normal ix
|
normal ix
|
||||||
endfunc
|
endfunc
|
||||||
|
@ -10,23 +10,30 @@ function Test_maparg()
|
|||||||
set cpo-=<
|
set cpo-=<
|
||||||
set encoding=utf8
|
set encoding=utf8
|
||||||
" Test maparg() with a string result
|
" Test maparg() with a string result
|
||||||
|
let sid = s:SID()
|
||||||
|
let lnum = expand('<sflnum>')
|
||||||
map foo<C-V> is<F4>foo
|
map foo<C-V> is<F4>foo
|
||||||
vnoremap <script> <buffer> <expr> <silent> bar isbar
|
vnoremap <script> <buffer> <expr> <silent> bar isbar
|
||||||
let sid = s:SID()
|
|
||||||
call assert_equal("is<F4>foo", maparg('foo<C-V>'))
|
call assert_equal("is<F4>foo", maparg('foo<C-V>'))
|
||||||
call assert_equal({'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>',
|
call assert_equal({'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>',
|
||||||
\ 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': sid, 'rhs': 'is<F4>foo',
|
\ 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': sid, 'lnum': lnum + 1,
|
||||||
\ 'buffer': 0}, maparg('foo<C-V>', '', 0, 1))
|
\ 'rhs': 'is<F4>foo', 'buffer': 0},
|
||||||
|
\ maparg('foo<C-V>', '', 0, 1))
|
||||||
call assert_equal({'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v',
|
call assert_equal({'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v',
|
||||||
\ 'nowait': 0, 'expr': 1, 'sid': sid, 'rhs': 'isbar', 'buffer': 1},
|
\ 'nowait': 0, 'expr': 1, 'sid': sid, 'lnum': lnum + 2,
|
||||||
|
\ 'rhs': 'isbar', 'buffer': 1},
|
||||||
\ maparg('bar', '', 0, 1))
|
\ maparg('bar', '', 0, 1))
|
||||||
|
let lnum = expand('<sflnum>')
|
||||||
map <buffer> <nowait> foo bar
|
map <buffer> <nowait> foo bar
|
||||||
call assert_equal({'silent': 0, 'noremap': 0, 'lhs': 'foo', 'mode': ' ',
|
call assert_equal({'silent': 0, 'noremap': 0, 'lhs': 'foo', 'mode': ' ',
|
||||||
\ 'nowait': 1, 'expr': 0, 'sid': sid, 'rhs': 'bar', 'buffer': 1},
|
\ 'nowait': 1, 'expr': 0, 'sid': sid, 'lnum': lnum + 1, 'rhs': 'bar',
|
||||||
|
\ 'buffer': 1},
|
||||||
\ maparg('foo', '', 0, 1))
|
\ maparg('foo', '', 0, 1))
|
||||||
|
let lnum = expand('<sflnum>')
|
||||||
tmap baz foo
|
tmap baz foo
|
||||||
call assert_equal({'silent': 0, 'noremap': 0, 'lhs': 'baz', 'mode': 't',
|
call assert_equal({'silent': 0, 'noremap': 0, 'lhs': 'baz', 'mode': 't',
|
||||||
\ 'nowait': 0, 'expr': 0, 'sid': sid, 'rhs': 'foo', 'buffer': 0},
|
\ 'nowait': 0, 'expr': 0, 'sid': sid, 'lnum': lnum + 1, 'rhs': 'foo',
|
||||||
|
\ 'buffer': 0},
|
||||||
\ maparg('baz', 't', 0, 1))
|
\ maparg('baz', 't', 0, 1))
|
||||||
|
|
||||||
map abc x<char-114>x
|
map abc x<char-114>x
|
||||||
|
@ -216,7 +216,7 @@ func Test_set_completion()
|
|||||||
|
|
||||||
" Expand files and directories.
|
" Expand files and directories.
|
||||||
call feedkeys(":set tags=./\<C-A>\<C-B>\"\<CR>", 'tx')
|
call feedkeys(":set tags=./\<C-A>\<C-B>\"\<CR>", 'tx')
|
||||||
call assert_match('./samples/ ./sautest/ ./setup.vim ./shared.vim', @:)
|
call assert_match('./samples/ ./sautest/ ./screendump.vim ./setup.vim ./shared.vim', @:)
|
||||||
|
|
||||||
call feedkeys(":set tags=./\\\\ dif\<C-A>\<C-B>\"\<CR>", 'tx')
|
call feedkeys(":set tags=./\\\\ dif\<C-A>\<C-B>\"\<CR>", 'tx')
|
||||||
call assert_equal('"set tags=./\\ diff diffexpr diffopt', @:)
|
call assert_equal('"set tags=./\\ diff diffexpr diffopt', @:)
|
||||||
|
@ -3,6 +3,8 @@ if !has('profile')
|
|||||||
finish
|
finish
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
source screendump.vim
|
||||||
|
|
||||||
func Test_profile_func()
|
func Test_profile_func()
|
||||||
let lines = [
|
let lines = [
|
||||||
\ 'profile start Xprofile_func.log',
|
\ 'profile start Xprofile_func.log',
|
||||||
@ -49,36 +51,260 @@ func Test_profile_func()
|
|||||||
" - Unlike Foo3(), Foo2() should not be deleted since there is a check
|
" - Unlike Foo3(), Foo2() should not be deleted since there is a check
|
||||||
" for v:profiling.
|
" for v:profiling.
|
||||||
" - Bar() is not reported since it does not match "profile func Foo*".
|
" - Bar() is not reported since it does not match "profile func Foo*".
|
||||||
call assert_equal(28, len(lines))
|
call assert_equal(30, len(lines))
|
||||||
|
|
||||||
call assert_equal('FUNCTION Foo1()', lines[0])
|
call assert_equal('FUNCTION Foo1()', lines[0])
|
||||||
call assert_equal('Called 2 times', lines[1])
|
call assert_match('Defined:.*Xprofile_func.vim', lines[1])
|
||||||
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2])
|
call assert_equal('Called 2 times', lines[2])
|
||||||
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3])
|
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[3])
|
||||||
call assert_equal('', lines[4])
|
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[4])
|
||||||
call assert_equal('count total (s) self (s)', lines[5])
|
call assert_equal('', lines[5])
|
||||||
call assert_equal('', lines[6])
|
call assert_equal('count total (s) self (s)', lines[6])
|
||||||
call assert_equal('FUNCTION Foo2()', lines[7])
|
call assert_equal('', lines[7])
|
||||||
call assert_equal('Called 1 time', lines[8])
|
call assert_equal('FUNCTION Foo2()', lines[8])
|
||||||
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[9])
|
call assert_equal('Called 1 time', lines[10])
|
||||||
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[10])
|
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[11])
|
||||||
call assert_equal('', lines[11])
|
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[12])
|
||||||
call assert_equal('count total (s) self (s)', lines[12])
|
call assert_equal('', lines[13])
|
||||||
call assert_match('^\s*1\s\+.*\slet l:count = 100$', lines[13])
|
call assert_equal('count total (s) self (s)', lines[14])
|
||||||
call assert_match('^\s*101\s\+.*\swhile l:count > 0$', lines[14])
|
call assert_match('^\s*1\s\+.*\slet l:count = 100$', lines[15])
|
||||||
call assert_match('^\s*100\s\+.*\s let l:count = l:count - 1$', lines[15])
|
call assert_match('^\s*101\s\+.*\swhile l:count > 0$', lines[16])
|
||||||
call assert_match('^\s*100\s\+.*\sendwhile$', lines[16])
|
call assert_match('^\s*100\s\+.*\s let l:count = l:count - 1$', lines[17])
|
||||||
call assert_equal('', lines[17])
|
call assert_match('^\s*101\s\+.*\sendwhile$', lines[18])
|
||||||
call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[18])
|
call assert_equal('', lines[19])
|
||||||
call assert_equal('count total (s) self (s) function', lines[19])
|
call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[20])
|
||||||
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[20])
|
call assert_equal('count total (s) self (s) function', lines[21])
|
||||||
call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[21])
|
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[22])
|
||||||
call assert_equal('', lines[22])
|
call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[23])
|
||||||
call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[23])
|
call assert_equal('', lines[24])
|
||||||
call assert_equal('count total (s) self (s) function', lines[24])
|
call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[25])
|
||||||
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[25])
|
call assert_equal('count total (s) self (s) function', lines[26])
|
||||||
call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[26])
|
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[27])
|
||||||
call assert_equal('', lines[27])
|
call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[28])
|
||||||
|
call assert_equal('', lines[29])
|
||||||
|
|
||||||
|
call delete('Xprofile_func.vim')
|
||||||
|
call delete('Xprofile_func.log')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_profile_func_with_ifelse()
|
||||||
|
let lines = [
|
||||||
|
\ "func! Foo1()",
|
||||||
|
\ " if 1",
|
||||||
|
\ " let x = 0",
|
||||||
|
\ " elseif 1",
|
||||||
|
\ " let x = 1",
|
||||||
|
\ " else",
|
||||||
|
\ " let x = 2",
|
||||||
|
\ " endif",
|
||||||
|
\ "endfunc",
|
||||||
|
\ "func! Foo2()",
|
||||||
|
\ " if 0",
|
||||||
|
\ " let x = 0",
|
||||||
|
\ " elseif 1",
|
||||||
|
\ " let x = 1",
|
||||||
|
\ " else",
|
||||||
|
\ " let x = 2",
|
||||||
|
\ " endif",
|
||||||
|
\ "endfunc",
|
||||||
|
\ "func! Foo3()",
|
||||||
|
\ " if 0",
|
||||||
|
\ " let x = 0",
|
||||||
|
\ " elseif 0",
|
||||||
|
\ " let x = 1",
|
||||||
|
\ " else",
|
||||||
|
\ " let x = 2",
|
||||||
|
\ " endif",
|
||||||
|
\ "endfunc",
|
||||||
|
\ "call Foo1()",
|
||||||
|
\ "call Foo2()",
|
||||||
|
\ "call Foo3()",
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
call writefile(lines, 'Xprofile_func.vim')
|
||||||
|
call system(v:progpath
|
||||||
|
\ . ' -es -u NONE -U NONE -i NONE --noplugin'
|
||||||
|
\ . ' -c "profile start Xprofile_func.log"'
|
||||||
|
\ . ' -c "profile func Foo*"'
|
||||||
|
\ . ' -c "so Xprofile_func.vim"'
|
||||||
|
\ . ' -c "qall!"')
|
||||||
|
call assert_equal(0, v:shell_error)
|
||||||
|
|
||||||
|
let lines = readfile('Xprofile_func.log')
|
||||||
|
|
||||||
|
" - Foo1() should pass 'if' block.
|
||||||
|
" - Foo2() should pass 'elseif' block.
|
||||||
|
" - Foo3() should pass 'else' block.
|
||||||
|
call assert_equal(57, len(lines))
|
||||||
|
|
||||||
|
call assert_equal('FUNCTION Foo1()', lines[0])
|
||||||
|
call assert_match('Defined:.*Xprofile_func.vim', lines[1])
|
||||||
|
call assert_equal('Called 1 time', lines[2])
|
||||||
|
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[3])
|
||||||
|
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[4])
|
||||||
|
call assert_equal('', lines[5])
|
||||||
|
call assert_equal('count total (s) self (s)', lines[6])
|
||||||
|
call assert_match('^\s*1\s\+.*\sif 1$', lines[7])
|
||||||
|
call assert_match('^\s*1\s\+.*\s let x = 0$', lines[8])
|
||||||
|
call assert_match( '^\s\+elseif 1$', lines[9])
|
||||||
|
call assert_match( '^\s\+let x = 1$', lines[10])
|
||||||
|
call assert_match( '^\s\+else$', lines[11])
|
||||||
|
call assert_match( '^\s\+let x = 2$', lines[12])
|
||||||
|
call assert_match('^\s*1\s\+.*\sendif$', lines[13])
|
||||||
|
call assert_equal('', lines[14])
|
||||||
|
call assert_equal('FUNCTION Foo2()', lines[15])
|
||||||
|
call assert_equal('Called 1 time', lines[17])
|
||||||
|
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[18])
|
||||||
|
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[19])
|
||||||
|
call assert_equal('', lines[20])
|
||||||
|
call assert_equal('count total (s) self (s)', lines[21])
|
||||||
|
call assert_match('^\s*1\s\+.*\sif 0$', lines[22])
|
||||||
|
call assert_match( '^\s\+let x = 0$', lines[23])
|
||||||
|
call assert_match('^\s*1\s\+.*\selseif 1$', lines[24])
|
||||||
|
call assert_match('^\s*1\s\+.*\s let x = 1$', lines[25])
|
||||||
|
call assert_match( '^\s\+else$', lines[26])
|
||||||
|
call assert_match( '^\s\+let x = 2$', lines[27])
|
||||||
|
call assert_match('^\s*1\s\+.*\sendif$', lines[28])
|
||||||
|
call assert_equal('', lines[29])
|
||||||
|
call assert_equal('FUNCTION Foo3()', lines[30])
|
||||||
|
call assert_equal('Called 1 time', lines[32])
|
||||||
|
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[33])
|
||||||
|
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[34])
|
||||||
|
call assert_equal('', lines[35])
|
||||||
|
call assert_equal('count total (s) self (s)', lines[36])
|
||||||
|
call assert_match('^\s*1\s\+.*\sif 0$', lines[37])
|
||||||
|
call assert_match( '^\s\+let x = 0$', lines[38])
|
||||||
|
call assert_match('^\s*1\s\+.*\selseif 0$', lines[39])
|
||||||
|
call assert_match( '^\s\+let x = 1$', lines[40])
|
||||||
|
call assert_match('^\s*1\s\+.*\selse$', lines[41])
|
||||||
|
call assert_match('^\s*1\s\+.*\s let x = 2$', lines[42])
|
||||||
|
call assert_match('^\s*1\s\+.*\sendif$', lines[43])
|
||||||
|
call assert_equal('', lines[44])
|
||||||
|
call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[45])
|
||||||
|
call assert_equal('count total (s) self (s) function', lines[46])
|
||||||
|
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[47])
|
||||||
|
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[48])
|
||||||
|
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[49])
|
||||||
|
call assert_equal('', lines[50])
|
||||||
|
call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[51])
|
||||||
|
call assert_equal('count total (s) self (s) function', lines[52])
|
||||||
|
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[53])
|
||||||
|
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[54])
|
||||||
|
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[55])
|
||||||
|
call assert_equal('', lines[56])
|
||||||
|
|
||||||
|
call delete('Xprofile_func.vim')
|
||||||
|
call delete('Xprofile_func.log')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_profile_func_with_trycatch()
|
||||||
|
let lines = [
|
||||||
|
\ "func! Foo1()",
|
||||||
|
\ " try",
|
||||||
|
\ " let x = 0",
|
||||||
|
\ " catch",
|
||||||
|
\ " let x = 1",
|
||||||
|
\ " finally",
|
||||||
|
\ " let x = 2",
|
||||||
|
\ " endtry",
|
||||||
|
\ "endfunc",
|
||||||
|
\ "func! Foo2()",
|
||||||
|
\ " try",
|
||||||
|
\ " throw 0",
|
||||||
|
\ " catch",
|
||||||
|
\ " let x = 1",
|
||||||
|
\ " finally",
|
||||||
|
\ " let x = 2",
|
||||||
|
\ " endtry",
|
||||||
|
\ "endfunc",
|
||||||
|
\ "func! Foo3()",
|
||||||
|
\ " try",
|
||||||
|
\ " throw 0",
|
||||||
|
\ " catch",
|
||||||
|
\ " throw 1",
|
||||||
|
\ " finally",
|
||||||
|
\ " let x = 2",
|
||||||
|
\ " endtry",
|
||||||
|
\ "endfunc",
|
||||||
|
\ "call Foo1()",
|
||||||
|
\ "call Foo2()",
|
||||||
|
\ "try",
|
||||||
|
\ " call Foo3()",
|
||||||
|
\ "catch",
|
||||||
|
\ "endtry",
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
call writefile(lines, 'Xprofile_func.vim')
|
||||||
|
call system(v:progpath
|
||||||
|
\ . ' -es -u NONE -U NONE -i NONE --noplugin'
|
||||||
|
\ . ' -c "profile start Xprofile_func.log"'
|
||||||
|
\ . ' -c "profile func Foo*"'
|
||||||
|
\ . ' -c "so Xprofile_func.vim"'
|
||||||
|
\ . ' -c "qall!"')
|
||||||
|
call assert_equal(0, v:shell_error)
|
||||||
|
|
||||||
|
let lines = readfile('Xprofile_func.log')
|
||||||
|
|
||||||
|
" - Foo1() should pass 'try' 'finally' blocks.
|
||||||
|
" - Foo2() should pass 'catch' 'finally' blocks.
|
||||||
|
" - Foo3() should not pass 'endtry'.
|
||||||
|
call assert_equal(57, len(lines))
|
||||||
|
|
||||||
|
call assert_equal('FUNCTION Foo1()', lines[0])
|
||||||
|
call assert_match('Defined:.*Xprofile_func.vim', lines[1])
|
||||||
|
call assert_equal('Called 1 time', lines[2])
|
||||||
|
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[3])
|
||||||
|
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[4])
|
||||||
|
call assert_equal('', lines[5])
|
||||||
|
call assert_equal('count total (s) self (s)', lines[6])
|
||||||
|
call assert_match('^\s*1\s\+.*\stry$', lines[7])
|
||||||
|
call assert_match('^\s*1\s\+.*\s let x = 0$', lines[8])
|
||||||
|
call assert_match( '^\s\+catch$', lines[9])
|
||||||
|
call assert_match( '^\s\+let x = 1$', lines[10])
|
||||||
|
call assert_match('^\s*1\s\+.*\sfinally$', lines[11])
|
||||||
|
call assert_match('^\s*1\s\+.*\s let x = 2$', lines[12])
|
||||||
|
call assert_match('^\s*1\s\+.*\sendtry$', lines[13])
|
||||||
|
call assert_equal('', lines[14])
|
||||||
|
call assert_equal('FUNCTION Foo2()', lines[15])
|
||||||
|
call assert_equal('Called 1 time', lines[17])
|
||||||
|
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[18])
|
||||||
|
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[19])
|
||||||
|
call assert_equal('', lines[20])
|
||||||
|
call assert_equal('count total (s) self (s)', lines[21])
|
||||||
|
call assert_match('^\s*1\s\+.*\stry$', lines[22])
|
||||||
|
call assert_match('^\s*1\s\+.*\s throw 0$', lines[23])
|
||||||
|
call assert_match('^\s*1\s\+.*\scatch$', lines[24])
|
||||||
|
call assert_match('^\s*1\s\+.*\s let x = 1$', lines[25])
|
||||||
|
call assert_match('^\s*1\s\+.*\sfinally$', lines[26])
|
||||||
|
call assert_match('^\s*1\s\+.*\s let x = 2$', lines[27])
|
||||||
|
call assert_match('^\s*1\s\+.*\sendtry$', lines[28])
|
||||||
|
call assert_equal('', lines[29])
|
||||||
|
call assert_equal('FUNCTION Foo3()', lines[30])
|
||||||
|
call assert_equal('Called 1 time', lines[32])
|
||||||
|
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[33])
|
||||||
|
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[34])
|
||||||
|
call assert_equal('', lines[35])
|
||||||
|
call assert_equal('count total (s) self (s)', lines[36])
|
||||||
|
call assert_match('^\s*1\s\+.*\stry$', lines[37])
|
||||||
|
call assert_match('^\s*1\s\+.*\s throw 0$', lines[38])
|
||||||
|
call assert_match('^\s*1\s\+.*\scatch$', lines[39])
|
||||||
|
call assert_match('^\s*1\s\+.*\s throw 1$', lines[40])
|
||||||
|
call assert_match('^\s*1\s\+.*\sfinally$', lines[41])
|
||||||
|
call assert_match('^\s*1\s\+.*\s let x = 2$', lines[42])
|
||||||
|
call assert_match( '^\s\+endtry$', lines[43])
|
||||||
|
call assert_equal('', lines[44])
|
||||||
|
call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[45])
|
||||||
|
call assert_equal('count total (s) self (s) function', lines[46])
|
||||||
|
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[47])
|
||||||
|
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[48])
|
||||||
|
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[49])
|
||||||
|
call assert_equal('', lines[50])
|
||||||
|
call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[51])
|
||||||
|
call assert_equal('count total (s) self (s) function', lines[52])
|
||||||
|
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[53])
|
||||||
|
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[54])
|
||||||
|
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[55])
|
||||||
|
call assert_equal('', lines[56])
|
||||||
|
|
||||||
call delete('Xprofile_func.vim')
|
call delete('Xprofile_func.vim')
|
||||||
call delete('Xprofile_func.log')
|
call delete('Xprofile_func.log')
|
||||||
@ -123,7 +349,7 @@ func Test_profile_file()
|
|||||||
call assert_equal(' " a comment', lines[9])
|
call assert_equal(' " a comment', lines[9])
|
||||||
" if self and total are equal we only get one number
|
" if self and total are equal we only get one number
|
||||||
call assert_match('^\s*20\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[10])
|
call assert_match('^\s*20\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[10])
|
||||||
call assert_match('^\s*20\s\+\d\+\.\d\+\s\+endfor$', lines[11])
|
call assert_match('^\s*22\s\+\d\+\.\d\+\s\+endfor$', lines[11])
|
||||||
" if self and total are equal we only get one number
|
" if self and total are equal we only get one number
|
||||||
call assert_match('^\s*2\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[12])
|
call assert_match('^\s*2\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[12])
|
||||||
call assert_equal('', lines[13])
|
call assert_equal('', lines[13])
|
||||||
@ -249,18 +475,19 @@ func Test_profdel_func()
|
|||||||
call assert_equal(0, v:shell_error)
|
call assert_equal(0, v:shell_error)
|
||||||
|
|
||||||
let lines = readfile('Xprofile_file.log')
|
let lines = readfile('Xprofile_file.log')
|
||||||
call assert_equal(24, len(lines))
|
call assert_equal(26, len(lines))
|
||||||
|
|
||||||
" Check that:
|
" Check that:
|
||||||
" - Foo1() is called twice (profdel not invoked)
|
" - Foo1() is called twice (profdel not invoked)
|
||||||
" - Foo2() is called once (profdel invoked after it was called)
|
" - Foo2() is called once (profdel invoked after it was called)
|
||||||
" - Foo3() is not called (profdel invoked before it was called)
|
" - Foo3() is not called (profdel invoked before it was called)
|
||||||
call assert_equal('FUNCTION Foo1()', lines[0])
|
call assert_equal('FUNCTION Foo1()', lines[0])
|
||||||
call assert_equal('Called 2 times', lines[1])
|
call assert_match('Defined:.*Xprofile_file.vim', lines[1])
|
||||||
call assert_equal('FUNCTION Foo2()', lines[7])
|
call assert_equal('Called 2 times', lines[2])
|
||||||
call assert_equal('Called 1 time', lines[8])
|
call assert_equal('FUNCTION Foo2()', lines[8])
|
||||||
call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[14])
|
call assert_equal('Called 1 time', lines[10])
|
||||||
call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[19])
|
call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[16])
|
||||||
|
call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[21])
|
||||||
|
|
||||||
call delete('Xprofile_file.vim')
|
call delete('Xprofile_file.vim')
|
||||||
call delete('Xprofile_file.log')
|
call delete('Xprofile_file.log')
|
||||||
@ -282,13 +509,42 @@ func Test_profdel_star()
|
|||||||
call assert_equal(0, v:shell_error)
|
call assert_equal(0, v:shell_error)
|
||||||
|
|
||||||
let lines = readfile('Xprofile_file.log')
|
let lines = readfile('Xprofile_file.log')
|
||||||
call assert_equal(15, len(lines))
|
call assert_equal(16, len(lines))
|
||||||
|
|
||||||
call assert_equal('FUNCTION Foo()', lines[0])
|
call assert_equal('FUNCTION Foo()', lines[0])
|
||||||
call assert_equal('Called 1 time', lines[1])
|
call assert_match('Defined:.*Xprofile_file.vim', lines[1])
|
||||||
call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[7])
|
call assert_equal('Called 1 time', lines[2])
|
||||||
call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[11])
|
call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[8])
|
||||||
|
call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[12])
|
||||||
|
|
||||||
call delete('Xprofile_file.vim')
|
call delete('Xprofile_file.vim')
|
||||||
call delete('Xprofile_file.log')
|
call delete('Xprofile_file.log')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" When typing the function it won't have a script ID, test that this works.
|
||||||
|
func Test_profile_typed_func()
|
||||||
|
if !CanRunVimInTerminal()
|
||||||
|
throw 'Skipped: cannot run Vim in a terminal window'
|
||||||
|
endif
|
||||||
|
|
||||||
|
let lines =<< trim END
|
||||||
|
profile start XprofileTypedFunc
|
||||||
|
END
|
||||||
|
call writefile(lines, 'XtestProfile')
|
||||||
|
let buf = RunVimInTerminal('-S XtestProfile', #{})
|
||||||
|
|
||||||
|
call term_sendkeys(buf, ":func DoSomething()\<CR>"
|
||||||
|
\ .. "echo 'hello'\<CR>"
|
||||||
|
\ .. "endfunc\<CR>")
|
||||||
|
call term_sendkeys(buf, ":profile func DoSomething\<CR>")
|
||||||
|
call term_sendkeys(buf, ":call DoSomething()\<CR>")
|
||||||
|
call term_wait(buf, 200)
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
let lines = readfile('XprofileTypedFunc')
|
||||||
|
call assert_equal("FUNCTION DoSomething()", lines[0])
|
||||||
|
call assert_equal("Called 1 time", lines[1])
|
||||||
|
|
||||||
|
" clean up
|
||||||
|
call delete('XprofileTypedFunc')
|
||||||
|
call delete('XtestProfile')
|
||||||
|
endfunc
|
||||||
|
@ -29,6 +29,7 @@ describe('nvim_get_keymap', function()
|
|||||||
nowait=0,
|
nowait=0,
|
||||||
mode='n',
|
mode='n',
|
||||||
noremap=1,
|
noremap=1,
|
||||||
|
lnum=0,
|
||||||
}
|
}
|
||||||
|
|
||||||
it('returns empty list when no map', function()
|
it('returns empty list when no map', function()
|
||||||
@ -250,6 +251,7 @@ describe('nvim_get_keymap', function()
|
|||||||
buffer=0,
|
buffer=0,
|
||||||
nowait=0,
|
nowait=0,
|
||||||
noremap=1,
|
noremap=1,
|
||||||
|
lnum=0,
|
||||||
}
|
}
|
||||||
local function cpomap(lhs, rhs, mode)
|
local function cpomap(lhs, rhs, mode)
|
||||||
local ret = shallowcopy(cpo_table)
|
local ret = shallowcopy(cpo_table)
|
||||||
@ -306,6 +308,7 @@ describe('nvim_get_keymap', function()
|
|||||||
buffer=0,
|
buffer=0,
|
||||||
nowait=0,
|
nowait=0,
|
||||||
noremap=1,
|
noremap=1,
|
||||||
|
lnum=0,
|
||||||
}
|
}
|
||||||
command('nnoremap \\|<Char-0x20><Char-32><Space><Bar> \\|<Char-0x20><Char-32><Space> <Bar>')
|
command('nnoremap \\|<Char-0x20><Char-32><Space><Bar> \\|<Char-0x20><Char-32><Space> <Bar>')
|
||||||
eq({space_table}, meths.get_keymap('n'))
|
eq({space_table}, meths.get_keymap('n'))
|
||||||
@ -345,6 +348,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
|
|||||||
to_return.expr = not opts.expr and 0 or 1
|
to_return.expr = not opts.expr and 0 or 1
|
||||||
to_return.sid = not opts.sid and 0 or opts.sid
|
to_return.sid = not opts.sid and 0 or opts.sid
|
||||||
to_return.buffer = not opts.buffer and 0 or opts.buffer
|
to_return.buffer = not opts.buffer and 0 or opts.buffer
|
||||||
|
to_return.lnum = not opts.lnum and 0 or opts.lnum
|
||||||
|
|
||||||
return to_return
|
return to_return
|
||||||
end
|
end
|
||||||
|
@ -21,6 +21,7 @@ describe('maparg()', function()
|
|||||||
nowait=0,
|
nowait=0,
|
||||||
mode='n',
|
mode='n',
|
||||||
noremap=1,
|
noremap=1,
|
||||||
|
lnum=0,
|
||||||
}
|
}
|
||||||
|
|
||||||
it('returns a dictionary', function()
|
it('returns a dictionary', function()
|
||||||
@ -148,6 +149,7 @@ describe('maparg()', function()
|
|||||||
nowait = 0,
|
nowait = 0,
|
||||||
sid = 0,
|
sid = 0,
|
||||||
silent = 0,
|
silent = 0,
|
||||||
|
lnum = 0,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -49,9 +49,9 @@ describe('maparg()', function()
|
|||||||
-- Assert buffer contents.
|
-- Assert buffer contents.
|
||||||
expect([[
|
expect([[
|
||||||
is<F4>foo
|
is<F4>foo
|
||||||
{'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>', 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': 0, 'rhs': 'is<F4>foo', 'buffer': 0}
|
{'lnum': 0, 'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>', 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': 0, 'rhs': 'is<F4>foo', 'buffer': 0}
|
||||||
{'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v', 'nowait': 0, 'expr': 1, 'sid': 0, 'rhs': 'isbar', 'buffer': 1}
|
{'lnum': 0, 'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v', 'nowait': 0, 'expr': 1, 'sid': 0, 'rhs': 'isbar', 'buffer': 1}
|
||||||
{'silent': 0, 'noremap': 0, 'lhs': 'foo', 'mode': ' ', 'nowait': 1, 'expr': 0, 'sid': 0, 'rhs': 'bar', 'buffer': 1}
|
{'lnum': 0, 'silent': 0, 'noremap': 0, 'lhs': 'foo', 'mode': ' ', 'nowait': 1, 'expr': 0, 'sid': 0, 'rhs': 'bar', 'buffer': 1}
|
||||||
xrx
|
xrx
|
||||||
yRy
|
yRy
|
||||||
abcd]])
|
abcd]])
|
||||||
|
Loading…
Reference in New Issue
Block a user