patch 8.1.0362: cannot get the script line number when executing a function

Problem:    Cannot get the script line number when executing a function.
Solution:   Store the line number besides the script ID. (Ozaki Kiichi,
            closes #3362)  Also display the line number with ":verbose set".
This commit is contained in:
Bram Moolenaar
2018-09-10 21:05:02 +02:00
parent 6b0b83f768
commit f29c1c6aa3
24 changed files with 716 additions and 562 deletions

View File

@@ -832,11 +832,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|)
@@ -849,15 +850,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:
@@ -867,9 +869,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*

View File

@@ -3798,7 +3798,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
@@ -5931,6 +5934,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>|).

View File

@@ -2,7 +2,8 @@
# Common Makefile, defines the list of tests to run. # Common Makefile, defines the list of tests to run.
# #
# Individual tests, including the ones part of test_alot # Individual tests, including the ones part of test_alot.
# Please keep sorted up to test_alot.
NEW_TESTS = \ NEW_TESTS = \
test_arglist \ test_arglist \
test_arabic \ test_arabic \
@@ -52,6 +53,7 @@ NEW_TESTS = \
test_exists_autocmd \ test_exists_autocmd \
test_expand \ test_expand \
test_expand_dllpath \ test_expand_dllpath \
test_expand_func \
test_expr \ test_expr \
test_expr_utf8 \ test_expr_utf8 \
test_farsi \ test_farsi \

View File

@@ -5412,7 +5412,7 @@ chk_modeline(
char_u *save_sourcing_name; char_u *save_sourcing_name;
linenr_T save_sourcing_lnum; linenr_T save_sourcing_lnum;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
scid_T save_SID; sctx_T save_current_sctx;
#endif #endif
prev = -1; prev = -1;
@@ -5497,12 +5497,13 @@ chk_modeline(
if (*s != NUL) /* skip over an empty "::" */ if (*s != NUL) /* skip over an empty "::" */
{ {
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
save_SID = current_SID; save_current_sctx = current_sctx;
current_SID = SID_MODELINE; current_sctx.sc_sid = SID_MODELINE;
current_sctx.sc_lnum = 0;
#endif #endif
retval = do_set(s, OPT_MODELINE | OPT_LOCAL | flags); retval = do_set(s, OPT_MODELINE | OPT_LOCAL | flags);
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
current_SID = save_SID; current_sctx = save_current_sctx;
#endif #endif
if (retval == FAIL) /* stop if error found */ if (retval == FAIL) /* stop if error found */
break; break;

View File

@@ -1495,8 +1495,8 @@ list_vim_vars(int *first)
static void static void
list_script_vars(int *first) 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), list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid),
(char_u *)"s:", FALSE, first); (char_u *)"s:", FALSE, first);
} }
@@ -7202,7 +7202,7 @@ find_var_in_ht(
/* 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 &SCRIPT_SV(current_SID)->sv_var; case 's': return &SCRIPT_SV(current_sctx.sc_sid)->sv_var;
case 'g': return &globvars_var; case 'g': return &globvars_var;
case 'v': return &vimvars_var; case 'v': return &vimvars_var;
case 'b': return &curbuf->b_bufvar; case 'b': return &curbuf->b_bufvar;
@@ -7286,8 +7286,8 @@ find_var_ht(char_u *name, char_u **varname)
if (*name == 'l') /* l: local function variable */ if (*name == 'l') /* l: local function variable */
return get_funccal_local_ht(); return get_funccal_local_ht();
if (*name == 's' /* script variable */ if (*name == 's' /* script variable */
&& current_SID > 0 && current_SID <= ga_scripts.ga_len) && current_sctx.sc_sid > 0 && current_sctx.sc_sid <= ga_scripts.ga_len)
return &SCRIPT_VARS(current_SID); return &SCRIPT_VARS(current_sctx.sc_sid);
return NULL; return NULL;
} }
@@ -8729,20 +8729,25 @@ store_session_globals(FILE *fd)
* Should only be invoked when 'verbose' is non-zero. * Should only be invoked when 'verbose' is non-zero.
*/ */
void void
last_set_msg(scid_T scriptID) last_set_msg(sctx_T script_ctx)
{ {
char_u *p; char_u *p;
if (scriptID != 0) if (script_ctx.sc_sid != 0)
{ {
p = home_replace_save(NULL, get_scriptname(scriptID)); p = home_replace_save(NULL, get_scriptname(script_ctx.sc_sid));
if (p != NULL) if (p != NULL)
{ {
verbose_enter(); verbose_enter();
MSG_PUTS(_("\n\tLast set from ")); MSG_PUTS(_("\n\tLast set from "));
MSG_PUTS(p); MSG_PUTS(p);
vim_free(p); if (script_ctx.sc_lnum > 0)
{
MSG_PUTS(_(" line "));
msg_outnum((long)script_ctx.sc_lnum);
}
verbose_leave(); verbose_leave();
vim_free(p);
} }
} }
} }

View File

@@ -4061,7 +4061,7 @@ common_function(typval_T *argvars, typval_T *rettv, int is_funcref)
* also be called from another script. Using trans_function_name() * also be called from another script. Using trans_function_name()
* 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. */
sprintf(sid_buf, "<SNR>%ld_", (long)current_SID); sprintf(sid_buf, "<SNR>%ld_", (long)current_sctx.sc_sid);
name = alloc((int)(STRLEN(sid_buf) + STRLEN(s + off) + 1)); name = alloc((int)(STRLEN(sid_buf) + STRLEN(s + off) + 1));
if (name != NULL) if (name != NULL)
{ {
@@ -7618,7 +7618,8 @@ get_maparg(typval_T *argvars, typval_T *rettv, int exact)
dict_add_number(dict, "noremap", mp->m_noremap ? 1L : 0L); dict_add_number(dict, "noremap", mp->m_noremap ? 1L : 0L);
dict_add_number(dict, "expr", mp->m_expr ? 1L : 0L); dict_add_number(dict, "expr", mp->m_expr ? 1L : 0L);
dict_add_number(dict, "silent", mp->m_silent ? 1L : 0L); dict_add_number(dict, "silent", mp->m_silent ? 1L : 0L);
dict_add_number(dict, "sid", (long)mp->m_script_ID); dict_add_number(dict, "sid", (long)mp->m_script_ctx.sc_sid);
dict_add_number(dict, "lnum", (long)mp->m_script_ctx.sc_lnum);
dict_add_number(dict, "buffer", (long)buffer_local); dict_add_number(dict, "buffer", (long)buffer_local);
dict_add_number(dict, "nowait", mp->m_nowait ? 1L : 0L); dict_add_number(dict, "nowait", mp->m_nowait ? 1L : 0L);
dict_add_string(dict, "mode", mapmode); dict_add_string(dict, "mode", mapmode);

View File

@@ -1866,9 +1866,9 @@ 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)
profile_start(&si->sn_pr_child); profile_start(&si->sn_pr_child);
} }
@@ -1883,9 +1883,9 @@ 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)
{ {
profile_end(&si->sn_pr_child); profile_end(&si->sn_pr_child);
@@ -2003,8 +2003,8 @@ script_dump_profile(FILE *fd)
int int
prof_def_func(void) 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;
} }
@@ -4351,7 +4351,7 @@ do_source(
char_u *firstline = NULL; char_u *firstline = NULL;
int retval = FAIL; int retval = FAIL;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
scid_T save_current_SID; sctx_T save_current_sctx;
static scid_T last_current_SID = 0; static scid_T last_current_SID = 0;
void *save_funccalp; void *save_funccalp;
int save_debug_break_level = debug_break_level; int save_debug_break_level = debug_break_level;
@@ -4521,13 +4521,15 @@ do_source(
* 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; save_current_sctx = current_sctx;
current_sctx.sc_lnum = 0;
# ifdef UNIX # ifdef UNIX
stat_ok = (mch_stat((char *)fname_exp, &st) >= 0); stat_ok = (mch_stat((char *)fname_exp, &st) >= 0);
# endif # endif
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;
--current_sctx.sc_sid)
{ {
si = &SCRIPT_ITEM(current_SID); si = &SCRIPT_ITEM(current_sctx.sc_sid);
if (si->sn_name != NULL if (si->sn_name != NULL
&& ( && (
# ifdef UNIX # ifdef UNIX
@@ -4541,13 +4543,13 @@ do_source(
fnamecmp(si->sn_name, fname_exp) == 0)) fnamecmp(si->sn_name, fname_exp) == 0))
break; break;
} }
if (current_SID == 0) if (current_sctx.sc_sid == 0)
{ {
current_SID = ++last_current_SID; current_sctx.sc_sid = ++last_current_SID;
if (ga_grow(&script_items, (int)(current_SID - script_items.ga_len)) if (ga_grow(&script_items,
== FAIL) (int)(current_sctx.sc_sid - script_items.ga_len)) == FAIL)
goto almosttheend; goto almosttheend;
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;
@@ -4555,7 +4557,7 @@ do_source(
SCRIPT_ITEM(script_items.ga_len).sn_prof_on = FALSE; SCRIPT_ITEM(script_items.ga_len).sn_prof_on = FALSE;
# endif # endif
} }
si = &SCRIPT_ITEM(current_SID); si = &SCRIPT_ITEM(current_sctx.sc_sid);
si->sn_name = fname_exp; si->sn_name = fname_exp;
fname_exp = NULL; fname_exp = NULL;
# ifdef UNIX # ifdef UNIX
@@ -4570,7 +4572,7 @@ do_source(
# endif # endif
/* 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);
} }
# ifdef FEAT_PROFILE # ifdef FEAT_PROFILE
@@ -4626,7 +4628,7 @@ do_source(
if (do_profiling == PROF_YES) if (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)
{ {
profile_end(&si->sn_pr_start); profile_end(&si->sn_pr_start);
@@ -4671,7 +4673,7 @@ do_source(
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
almosttheend: almosttheend:
current_SID = save_current_SID; current_sctx = save_current_sctx;
restore_funccal(save_funccalp); restore_funccal(save_funccalp);
# ifdef FEAT_PROFILE # ifdef FEAT_PROFILE
if (do_profiling == PROF_YES) if (do_profiling == PROF_YES)
@@ -5090,9 +5092,9 @@ 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
@@ -5125,9 +5127,9 @@ 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;
} }
@@ -5141,9 +5143,9 @@ 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)
{ {

View File

@@ -29,7 +29,7 @@ typedef struct ucmd
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 */
# ifdef FEAT_EVAL # ifdef FEAT_EVAL
scid_T uc_scriptID; /* SID where the command was defined */ sctx_T uc_script_ctx; /* SCTX where the command was defined */
# ifdef FEAT_CMDL_COMPL # ifdef FEAT_CMDL_COMPL
char_u *uc_compl_arg; /* completion argument if any */ char_u *uc_compl_arg; /* completion argument if any */
# endif # endif
@@ -3340,7 +3340,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;
} }
# endif # endif
# endif # endif
@@ -5920,7 +5921,8 @@ uc_add_command(
cmd->uc_def = def; cmd->uc_def = def;
cmd->uc_compl = compl; cmd->uc_compl = compl;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
cmd->uc_scriptID = current_SID; cmd->uc_script_ctx = current_sctx;
cmd->uc_script_ctx.sc_lnum += sourcing_lnum;
# ifdef FEAT_CMDL_COMPL # ifdef FEAT_CMDL_COMPL
cmd->uc_compl_arg = compl_arg; cmd->uc_compl_arg = compl_arg;
# endif # endif
@@ -6141,7 +6143,7 @@ uc_list(char_u *name, size_t name_len)
msg_outtrans_special(cmd->uc_rep, FALSE); msg_outtrans_special(cmd->uc_rep, FALSE);
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
if (p_verbose > 0) if (p_verbose > 0)
last_set_msg(cmd->uc_scriptID); last_set_msg(cmd->uc_script_ctx);
#endif #endif
out_flush(); out_flush();
ui_breakcheck(); ui_breakcheck();
@@ -6906,7 +6908,7 @@ do_ucmd(exarg_T *eap)
char_u *split_buf = NULL; char_u *split_buf = NULL;
ucmd_T *cmd; ucmd_T *cmd;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
scid_T save_current_SID = current_SID; sctx_T save_current_sctx = current_sctx;
#endif #endif
if (eap->cmdidx == CMD_USER) if (eap->cmdidx == CMD_USER)
@@ -7007,12 +7009,12 @@ do_ucmd(exarg_T *eap)
} }
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
current_SID = cmd->uc_scriptID; current_sctx.sc_sid = cmd->uc_script_ctx.sc_sid;
#endif #endif
(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);
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
current_SID = save_current_SID; current_sctx = save_current_sctx;
#endif #endif
vim_free(buf); vim_free(buf);
vim_free(split_buf); vim_free(split_buf);
@@ -10736,14 +10738,16 @@ find_cmdline_var(char_u *src, int *usedlen)
"<slnum>", /* ":so" file line number */ "<slnum>", /* ":so" file line number */
#define SPEC_SLNUM (SPEC_SFILE + 1) #define SPEC_SLNUM (SPEC_SFILE + 1)
"<afile>", /* autocommand file name */ "<afile>", /* autocommand file name */
#define SPEC_AFILE (SPEC_SLNUM + 1) #define SPEC_AFILE (SPEC_SLNUM + 1)
"<abuf>", /* autocommand buffer number */ "<abuf>", /* autocommand buffer number */
#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)
#ifdef FEAT_CLIENTSERVER #ifdef FEAT_CLIENTSERVER
"<client>" "<client>"
# define SPEC_CLIENT (SPEC_AMATCH + 1) # define SPEC_CLIENT (SPEC_SFLNUM + 1)
#endif #endif
}; };
@@ -10999,6 +11003,7 @@ 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)
{ {
@@ -11008,13 +11013,28 @@ eval_vars(
sprintf((char *)strbuf, "%ld", (long)sourcing_lnum); sprintf((char *)strbuf, "%ld", (long)sourcing_lnum);
result = strbuf; result = strbuf;
break; break;
#if defined(FEAT_CLIENTSERVER)
#ifdef FEAT_EVAL
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;
}
sprintf((char *)strbuf, "%ld",
(long)(current_sctx.sc_lnum + sourcing_lnum));
result = strbuf;
break;
#endif
#ifdef FEAT_CLIENTSERVER
case SPEC_CLIENT: /* Source of last submitted input */ case SPEC_CLIENT: /* Source of last submitted input */
sprintf((char *)strbuf, PRINTF_HEX_LONG_U, sprintf((char *)strbuf, PRINTF_HEX_LONG_U,
(long_u)clientWindow); (long_u)clientWindow);
result = strbuf; result = strbuf;
break; break;
#endif #endif
default: default:
result = (char_u *)""; /* avoid gcc warning */ result = (char_u *)""; /* avoid gcc warning */
break; break;

View File

@@ -5591,7 +5591,7 @@ call_user_expand_func(
{ {
int keep = 0; int keep = 0;
typval_T args[4]; typval_T args[4];
int save_current_SID = current_SID; sctx_T save_current_sctx = current_sctx;
char_u *pat = NULL; char_u *pat = NULL;
void *ret; void *ret;
struct cmdline_info save_ccline; struct cmdline_info save_ccline;
@@ -5621,12 +5621,12 @@ call_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;
ret = user_expand_func(xp->xp_arg, 3, args); 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;

View File

@@ -7700,7 +7700,7 @@ typedef struct AutoCmd
char nested; /* If autocommands nest here */ char nested; /* If autocommands nest here */
char last; /* last command in list */ char last; /* last command in list */
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
scid_T scriptID; /* script ID where defined */ sctx_T script_ctx; /* script context where defined */
#endif #endif
struct AutoCmd *next; /* Next AutoCmd in list */ struct AutoCmd *next; /* Next AutoCmd in list */
} AutoCmd; } AutoCmd;
@@ -7962,7 +7962,7 @@ show_autocmd(AutoPat *ap, event_T event)
msg_outtrans(ac->cmd); msg_outtrans(ac->cmd);
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
if (p_verbose > 0) if (p_verbose > 0)
last_set_msg(ac->scriptID); last_set_msg(ac->script_ctx);
#endif #endif
if (got_int) if (got_int)
return; return;
@@ -8845,7 +8845,8 @@ do_autocmd_event(
return FAIL; return FAIL;
ac->cmd = vim_strsave(cmd); ac->cmd = vim_strsave(cmd);
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
ac->scriptID = current_SID; ac->script_ctx = current_sctx;
ac->script_ctx.sc_lnum += sourcing_lnum;
#endif #endif
if (ac->cmd == NULL) if (ac->cmd == NULL)
{ {
@@ -9412,7 +9413,7 @@ apply_autocmds_group(
AutoPatCmd patcmd; AutoPatCmd patcmd;
AutoPat *ap; AutoPat *ap;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
scid_T save_current_SID; sctx_T save_current_sctx;
void *save_funccalp; void *save_funccalp;
char_u *save_cmdarg; char_u *save_cmdarg;
long save_cmdbang; long save_cmdbang;
@@ -9621,7 +9622,7 @@ apply_autocmds_group(
sourcing_lnum = 0; /* no line number here */ sourcing_lnum = 0; /* no line number here */
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
save_current_SID = current_SID; save_current_sctx = current_sctx;
# ifdef FEAT_PROFILE # ifdef FEAT_PROFILE
if (do_profiling == PROF_YES) if (do_profiling == PROF_YES)
@@ -9725,7 +9726,7 @@ apply_autocmds_group(
autocmd_bufnr = save_autocmd_bufnr; autocmd_bufnr = save_autocmd_bufnr;
autocmd_match = save_autocmd_match; autocmd_match = save_autocmd_match;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
current_SID = save_current_SID; current_sctx = save_current_sctx;
restore_funccal(save_funccalp); restore_funccal(save_funccalp);
# ifdef FEAT_PROFILE # ifdef FEAT_PROFILE
if (do_profiling == PROF_YES) if (do_profiling == PROF_YES)
@@ -9949,7 +9950,7 @@ getnextac(int c UNUSED, void *cookie, int indent UNUSED)
retval = vim_strsave(ac->cmd); retval = vim_strsave(ac->cmd);
autocmd_nested = ac->nested; autocmd_nested = ac->nested;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
current_SID = ac->scriptID; current_sctx = ac->script_ctx;
#endif #endif
if (ac->last) if (ac->last)
acp->nextcmd = NULL; acp->nextcmd = NULL;

View File

@@ -3677,7 +3677,8 @@ do_map(
mp->m_mode = mode; mp->m_mode = mode;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
mp->m_expr = expr; mp->m_expr = expr;
mp->m_script_ID = current_SID; mp->m_script_ctx = current_sctx;
mp->m_script_ctx.sc_lnum += sourcing_lnum;
#endif #endif
did_it = TRUE; did_it = TRUE;
} }
@@ -3783,7 +3784,8 @@ do_map(
mp->m_mode = mode; mp->m_mode = mode;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
mp->m_expr = expr; mp->m_expr = expr;
mp->m_script_ID = current_SID; mp->m_script_ctx = current_sctx;
mp->m_script_ctx.sc_lnum += sourcing_lnum;
#endif #endif
/* add the new entry in front of the abbrlist or maphash[] list */ /* add the new entry in front of the abbrlist or maphash[] list */
@@ -4097,7 +4099,7 @@ showmap(
} }
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
if (p_verbose > 0) if (p_verbose > 0)
last_set_msg(mp->m_script_ID); last_set_msg(mp->m_script_ctx);
#endif #endif
out_flush(); /* show one line at a time */ out_flush(); /* show one line at a time */
} }

View File

@@ -325,8 +325,8 @@ EXTERN int may_garbage_collect INIT(= FALSE);
EXTERN int want_garbage_collect INIT(= FALSE); EXTERN int want_garbage_collect INIT(= FALSE);
EXTERN int garbage_collect_at_exit INIT(= FALSE); EXTERN int garbage_collect_at_exit INIT(= FALSE);
/* 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});
#endif #endif
EXTERN int did_source_packages INIT(= FALSE); EXTERN int did_source_packages INIT(= FALSE);

View File

@@ -2912,13 +2912,13 @@ exe_pre_commands(mparm_T *parmp)
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");
# ifdef FEAT_EVAL # ifdef FEAT_EVAL
current_SID = SID_CMDARG; current_sctx.sc_sid = SID_CMDARG;
# endif # endif
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;
# ifdef FEAT_EVAL # ifdef FEAT_EVAL
current_SID = 0; current_sctx.sc_sid = 0;
# endif # endif
TIME_MSG("--cmd commands"); TIME_MSG("--cmd commands");
} }
@@ -2942,7 +2942,7 @@ exe_commands(mparm_T *parmp)
curwin->w_cursor.lnum = 0; curwin->w_cursor.lnum = 0;
sourcing_name = (char_u *)"command line"; sourcing_name = (char_u *)"command line";
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
current_SID = SID_CARG; current_sctx.sc_sid = SID_CARG;
#endif #endif
for (i = 0; i < parmp->n_commands; ++i) for (i = 0; i < parmp->n_commands; ++i)
{ {
@@ -2952,7 +2952,7 @@ exe_commands(mparm_T *parmp)
} }
sourcing_name = NULL; sourcing_name = NULL;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
current_SID = 0; current_sctx.sc_sid = 0;
#endif #endif
if (curwin->w_cursor.lnum == 0) if (curwin->w_cursor.lnum == 0)
curwin->w_cursor.lnum = 1; curwin->w_cursor.lnum = 1;
@@ -3159,7 +3159,7 @@ process_env(
char_u *save_sourcing_name; char_u *save_sourcing_name;
linenr_T save_sourcing_lnum; linenr_T save_sourcing_lnum;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
scid_T save_sid; sctx_T save_current_sctx;
#endif #endif
if ((initstr = mch_getenv(env)) != NULL && *initstr != NUL) if ((initstr = mch_getenv(env)) != NULL && *initstr != NUL)
@@ -3171,14 +3171,15 @@ process_env(
sourcing_name = env; sourcing_name = env;
sourcing_lnum = 0; sourcing_lnum = 0;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
save_sid = current_SID; save_current_sctx = current_sctx;
current_SID = SID_ENV; current_sctx.sc_sid = SID_ENV;
current_sctx.sc_lnum = 0;
#endif #endif
do_cmdline_cmd(initstr); do_cmdline_cmd(initstr);
sourcing_name = save_sourcing_name; sourcing_name = save_sourcing_name;
sourcing_lnum = save_sourcing_lnum; sourcing_lnum = save_sourcing_lnum;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
current_SID = save_sid; current_sctx = save_current_sctx;
#endif #endif
return OK; return OK;
} }

View File

@@ -2259,7 +2259,7 @@ execute_menu(exarg_T *eap, vimmenu_T *menu)
/* Use the Insert mode entry when returning to Insert mode. */ /* Use the Insert mode entry when returning to Insert mode. */
if (restart_edit if (restart_edit
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
&& !current_SID && !current_sctx.sc_sid
#endif #endif
) )
{ {
@@ -2333,7 +2333,7 @@ execute_menu(exarg_T *eap, vimmenu_T *menu)
* Otherwise put them in the typeahead buffer. */ * Otherwise put them in the typeahead buffer. */
if (eap == NULL if (eap == NULL
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
|| current_SID != 0 || current_sctx.sc_sid != 0
#endif #endif
) )
{ {

File diff suppressed because it is too large Load Diff

View File

@@ -119,7 +119,7 @@ int script_autoload(char_u *name, int reload);
int read_viminfo_varlist(vir_T *virp, int writing); int read_viminfo_varlist(vir_T *virp, int writing);
void write_viminfo_varlist(FILE *fp); void write_viminfo_varlist(FILE *fp);
int store_session_globals(FILE *fd); int store_session_globals(FILE *fd);
void last_set_msg(scid_T scriptID); void last_set_msg(sctx_T script_ctx);
void reset_v_option_vars(void); void reset_v_option_vars(void);
void prepare_assert_error(garray_T *gap); void prepare_assert_error(garray_T *gap);
void assert_error(garray_T *gap); void assert_error(garray_T *gap);

View File

@@ -74,6 +74,19 @@ typedef struct terminal_S term_T;
typedef struct VimMenu vimmenu_T; typedef struct VimMenu vimmenu_T;
#endif #endif
/*
* 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
linenr_T sc_lnum; // line number
} sctx_T;
/* /*
* Reference to a buffer that stores the value of buf_free_count. * Reference to a buffer that stores the value of buf_free_count.
* bufref_valid() only needs to check "buf" when the count differs. * bufref_valid() only needs to check "buf" when the count differs.
@@ -278,8 +291,8 @@ typedef struct
#endif #endif
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
int wo_scriptID[WV_COUNT]; /* SIDs for window-local options */ sctx_T 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
#endif #endif
} winopt_T; } winopt_T;
@@ -541,7 +554,7 @@ typedef struct expand
int xp_pattern_len; /* bytes in xp_pattern before cursor */ int xp_pattern_len; /* bytes in xp_pattern before cursor */
#if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL) #if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
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 */
#endif #endif
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
@@ -1071,7 +1084,7 @@ struct mapblock
char m_nowait; /* <nowait> used */ char m_nowait; /* <nowait> used */
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
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 */
#endif #endif
}; };
@@ -1361,7 +1374,7 @@ typedef struct
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 */
#endif #endif
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 */
@@ -2123,7 +2136,7 @@ struct file_buffer
int b_p_initialized; /* set when options initialized */ int b_p_initialized; /* set when options initialized */
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
int b_p_scriptID[BV_COUNT]; /* SIDs for buffer-local options */ sctx_T b_p_script_ctx[BV_COUNT]; /* SCTXs for buffer-local options */
#endif #endif
int b_p_ai; /* 'autoindent' */ int b_p_ai; /* 'autoindent' */

View File

@@ -58,7 +58,7 @@ struct hl_group
int sg_link; /* link to this highlight group ID */ int sg_link; /* link to this highlight group ID */
int sg_set; /* combination of SG_* flags */ int sg_set; /* combination of SG_* flags */
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
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 */
#endif #endif
}; };
@@ -7507,7 +7507,8 @@ do_highlight(
} }
else if (HL_TABLE()[from_id - 1].sg_link != to_id else if (HL_TABLE()[from_id - 1].sg_link != to_id
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
|| HL_TABLE()[from_id - 1].sg_scriptID != current_SID || HL_TABLE()[from_id - 1].sg_script_ctx.sc_sid
!= current_sctx.sc_sid
#endif #endif
|| HL_TABLE()[from_id - 1].sg_cleared) || HL_TABLE()[from_id - 1].sg_cleared)
{ {
@@ -7515,7 +7516,8 @@ do_highlight(
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;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
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;
#endif #endif
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);
@@ -8277,7 +8279,8 @@ do_highlight(
else else
set_hl_attr(idx); set_hl_attr(idx);
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
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;
#endif #endif
} }
@@ -8404,7 +8407,10 @@ 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;
}
#endif #endif
} }
@@ -9272,7 +9278,7 @@ highlight_list_one(int id)
highlight_list_arg(id, didh, LIST_STRING, 0, (char_u *)"cleared", ""); highlight_list_arg(id, didh, LIST_STRING, 0, (char_u *)"cleared", "");
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
if (p_verbose > 0) if (p_verbose > 0)
last_set_msg(sgp->sg_scriptID); last_set_msg(sgp->sg_script_ctx);
#endif #endif
} }

View File

@@ -6128,7 +6128,7 @@ replace_termcodes(
*/ */
if (STRNICMP(src, "<SID>", 5) == 0) if (STRNICMP(src, "<SID>", 5) == 0)
{ {
if (current_SID <= 0) if (current_sctx.sc_sid <= 0)
EMSG(_(e_usingsid)); EMSG(_(e_usingsid));
else else
{ {
@@ -6136,7 +6136,8 @@ replace_termcodes(
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, "%ld", (long)current_SID); sprintf((char *)result + dlen, "%ld",
(long)current_sctx.sc_sid);
dlen += (int)STRLEN(result + dlen); dlen += (int)STRLEN(result + dlen);
result[dlen++] = '_'; result[dlen++] = '_';
continue; continue;

View File

@@ -14,6 +14,7 @@ source test_ex_z.vim
source test_execute_func.vim source test_execute_func.vim
source test_expand.vim source test_expand.vim
source test_expand_dllpath.vim source test_expand_dllpath.vim
source test_expand_func.vim
source test_expr.vim source test_expr.vim
source test_feedkeys.vim source test_feedkeys.vim
source test_file_perm.vim source test_file_perm.vim

View 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

View File

@@ -13,19 +13,24 @@ 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))
map abc x<char-114>x map abc x<char-114>x

View File

@@ -302,7 +302,8 @@ get_lambda_tv(char_u **arg, typval_T *rettv, int 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;
@@ -505,11 +506,11 @@ fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error)
i = 3; i = 3;
if (eval_fname_sid(name)) /* "<SID>" or "s:" */ if (eval_fname_sid(name)) /* "<SID>" or "s:" */
{ {
if (current_SID <= 0) if (current_sctx.sc_sid <= 0)
*error = ERROR_SCRIPT; *error = ERROR_SCRIPT;
else else
{ {
sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); sprintf((char *)fname_buf + 3, "%ld_", (long)current_sctx.sc_sid);
i = (int)STRLEN(fname_buf); i = (int)STRLEN(fname_buf);
} }
} }
@@ -690,7 +691,7 @@ call_user_func(
{ {
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; sctx_T save_current_sctx;
int using_sandbox = FALSE; int using_sandbox = FALSE;
funccall_T *fc; funccall_T *fc;
int save_did_emsg; int save_did_emsg;
@@ -944,8 +945,8 @@ call_user_func(
} }
#endif #endif
save_current_SID = current_SID; 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;
@@ -1026,7 +1027,7 @@ call_user_func(
vim_free(sourcing_name); vim_free(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;
#ifdef FEAT_PROFILE #ifdef FEAT_PROFILE
if (do_profiling == PROF_YES) if (do_profiling == PROF_YES)
script_prof_restore(&wait_start); script_prof_restore(&wait_start);
@@ -1574,7 +1575,7 @@ list_func_head(ufunc_T *fp, int indent)
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);
} }
/* /*
@@ -1757,12 +1758,12 @@ trans_function_name(
|| eval_fname_sid(*pp)) || eval_fname_sid(*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;
} }
sprintf((char *)sid_buf, "%ld_", (long)current_SID); sprintf((char *)sid_buf, "%ld_", (long)current_sctx.sc_sid);
lead += (int)STRLEN(sid_buf); lead += (int)STRLEN(sid_buf);
} }
} }
@@ -2454,7 +2455,8 @@ ex_function(exarg_T *eap)
flags |= FC_SANDBOX; flags |= FC_SANDBOX;
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:

View File

@@ -794,6 +794,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
362,
/**/ /**/
361, 361,
/**/ /**/