mirror of
https://github.com/vim/vim.git
synced 2025-08-31 20:53:42 -04:00
patch 8.2.4726: cannot use expand() to get the script name
Problem: Cannot use expand() to get the script name. Solution: Support expand('<script>'). (closes #10121)
This commit is contained in:
parent
2ce97ae6aa
commit
6013d0045d
@ -939,7 +939,7 @@ Note: these are typed literally, they are not special keys!
|
|||||||
file name of the sourced file. *E498*
|
file name of the sourced file. *E498*
|
||||||
When executing a legacy function, is replaced with the call
|
When executing a legacy function, is replaced with the call
|
||||||
stack, as with <stack> (this is for backwards
|
stack, as with <stack> (this is for backwards
|
||||||
compatibility, using <stack> is preferred).
|
compatibility, using <stack> or <script> is preferred).
|
||||||
In Vim9 script using <sfile> in a function gives error
|
In Vim9 script using <sfile> in a function gives error
|
||||||
*E1245* .
|
*E1245* .
|
||||||
Note that filename-modifiers are useless when <sfile> is
|
Note that filename-modifiers are useless when <sfile> is
|
||||||
@ -951,6 +951,12 @@ Note: these are typed literally, they are not special keys!
|
|||||||
".." in between items. E.g.:
|
".." in between items. E.g.:
|
||||||
"function {function-name1}[{lnum}]..{function-name2}[{lnum}]"
|
"function {function-name1}[{lnum}]..{function-name2}[{lnum}]"
|
||||||
If there is no call stack you get error *E489* .
|
If there is no call stack you get error *E489* .
|
||||||
|
*:<script>* *<script>*
|
||||||
|
<script> When executing a `:source` command, is replaced with the file
|
||||||
|
name of the sourced file. When executing a function, is
|
||||||
|
replaced with the file name of the script where it is
|
||||||
|
defined.
|
||||||
|
If the file name cannot be determined you get error *E1274* .
|
||||||
*:<slnum>* *<slnum>*
|
*:<slnum>* *<slnum>*
|
||||||
<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*
|
||||||
|
@ -3258,3 +3258,5 @@ EXTERN char e_using_type_not_in_script_context_str[]
|
|||||||
#endif
|
#endif
|
||||||
EXTERN char e_nfa_regexp_missing_value_in_chr[]
|
EXTERN char e_nfa_regexp_missing_value_in_chr[]
|
||||||
INIT(= N_("E1273: (NFA regexp) missing value in '\\%%%c'"));
|
INIT(= N_("E1273: (NFA regexp) missing value in '\\%%%c'"));
|
||||||
|
EXTERN char e_no_script_file_name_to_substitute_for_script[]
|
||||||
|
INIT(= N_("E1274: No script file name to substitute for \"<script>\""));
|
||||||
|
@ -8957,8 +8957,10 @@ find_cmdline_var(char_u *src, int *usedlen)
|
|||||||
#define SPEC_SLNUM (SPEC_SFILE + 1)
|
#define SPEC_SLNUM (SPEC_SFILE + 1)
|
||||||
"<stack>", // call stack
|
"<stack>", // call stack
|
||||||
#define SPEC_STACK (SPEC_SLNUM + 1)
|
#define SPEC_STACK (SPEC_SLNUM + 1)
|
||||||
|
"<script>", // script file name
|
||||||
|
#define SPEC_SCRIPT (SPEC_STACK + 1)
|
||||||
"<afile>", // autocommand file name
|
"<afile>", // autocommand file name
|
||||||
#define SPEC_AFILE (SPEC_STACK + 1)
|
#define SPEC_AFILE (SPEC_SCRIPT + 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
|
||||||
@ -9226,14 +9228,28 @@ eval_vars(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SPEC_SFILE: // file name for ":so" command
|
case SPEC_SFILE: // file name for ":so" command
|
||||||
case SPEC_STACK: // call stack
|
result = estack_sfile(ESTACK_SFILE);
|
||||||
result = estack_sfile(spec_idx == SPEC_SFILE
|
|
||||||
? ESTACK_SFILE : ESTACK_STACK);
|
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
{
|
{
|
||||||
*errormsg = spec_idx == SPEC_SFILE
|
*errormsg = _(e_no_source_file_name_to_substitute_for_sfile);
|
||||||
? _(e_no_source_file_name_to_substitute_for_sfile)
|
return NULL;
|
||||||
: _(e_no_call_stack_to_substitute_for_stack);
|
}
|
||||||
|
resultbuf = result; // remember allocated string
|
||||||
|
break;
|
||||||
|
case SPEC_STACK: // call stack
|
||||||
|
result = estack_sfile(ESTACK_STACK);
|
||||||
|
if (result == NULL)
|
||||||
|
{
|
||||||
|
*errormsg = _(e_no_call_stack_to_substitute_for_stack);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
resultbuf = result; // remember allocated string
|
||||||
|
break;
|
||||||
|
case SPEC_SCRIPT: // script file name
|
||||||
|
result = estack_sfile(ESTACK_SCRIPT);
|
||||||
|
if (result == NULL)
|
||||||
|
{
|
||||||
|
*errormsg = _(e_no_script_file_name_to_substitute_for_script);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
resultbuf = result; // remember allocated string
|
resultbuf = result; // remember allocated string
|
||||||
|
@ -118,7 +118,8 @@ estack_pop(void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the current value for <sfile> in allocated memory.
|
* Get the current value for <sfile> in allocated memory.
|
||||||
* "which" is ESTACK_SFILE for <sfile> and ESTACK_STACK for <stack>.
|
* "which" is ESTACK_SFILE for <sfile>, ESTACK_STACK for <stack> or
|
||||||
|
* ESTACK_SCRIPT for <script>.
|
||||||
*/
|
*/
|
||||||
char_u *
|
char_u *
|
||||||
estack_sfile(estack_arg_T which UNUSED)
|
estack_sfile(estack_arg_T which UNUSED)
|
||||||
@ -156,6 +157,32 @@ estack_sfile(estack_arg_T which UNUSED)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If evaluated in a function return the path of the script where the
|
||||||
|
// function is defined, at script level the current script path is returned
|
||||||
|
// instead.
|
||||||
|
if (which == ESTACK_SCRIPT)
|
||||||
|
{
|
||||||
|
if (entry->es_type == ETYPE_UFUNC)
|
||||||
|
{
|
||||||
|
sctx_T *def_ctx = &entry->es_info.ufunc->uf_script_ctx;
|
||||||
|
|
||||||
|
if (def_ctx->sc_sid > 0)
|
||||||
|
return vim_strsave(SCRIPT_ITEM(def_ctx->sc_sid)->sn_name);
|
||||||
|
}
|
||||||
|
else if (exestack.ga_len > 0)
|
||||||
|
{
|
||||||
|
// Walk the stack backwards, starting from the current frame.
|
||||||
|
for (idx = exestack.ga_len - 1; idx; --idx)
|
||||||
|
{
|
||||||
|
entry = ((estack_T *)exestack.ga_data) + idx;
|
||||||
|
|
||||||
|
if (entry->es_type == ETYPE_SCRIPT)
|
||||||
|
return vim_strsave(entry->es_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Give information about each stack entry up to the root.
|
// Give information about each stack entry up to the root.
|
||||||
// For a function we compose the call stack, as it was done in the past:
|
// For a function we compose the call stack, as it was done in the past:
|
||||||
// "function One[123]..Two[456]..Three"
|
// "function One[123]..Two[456]..Three"
|
||||||
|
@ -159,4 +159,54 @@ func Test_expandcmd_shell_nonomatch()
|
|||||||
call assert_equal('$*', expandcmd('$*'))
|
call assert_equal('$*', expandcmd('$*'))
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_expand_script_source()
|
||||||
|
let lines0 =<< trim [SCRIPT]
|
||||||
|
let g:script_level[0] = expand('<script>:t')
|
||||||
|
so Xscript1
|
||||||
|
func F0()
|
||||||
|
let g:func_level[0] = expand('<script>:t')
|
||||||
|
endfunc
|
||||||
|
[SCRIPT]
|
||||||
|
|
||||||
|
let lines1 =<< trim [SCRIPT]
|
||||||
|
let g:script_level[1] = expand('<script>:t')
|
||||||
|
so Xscript2
|
||||||
|
func F1()
|
||||||
|
let g:func_level[1] = expand('<script>:t')
|
||||||
|
endfunc
|
||||||
|
[SCRIPT]
|
||||||
|
|
||||||
|
let lines2 =<< trim [SCRIPT]
|
||||||
|
let g:script_level[2] = expand('<script>:t')
|
||||||
|
func F2()
|
||||||
|
let g:func_level[2] = expand('<script>:t')
|
||||||
|
endfunc
|
||||||
|
[SCRIPT]
|
||||||
|
|
||||||
|
call writefile(lines0, 'Xscript0')
|
||||||
|
call writefile(lines1, 'Xscript1')
|
||||||
|
call writefile(lines2, 'Xscript2')
|
||||||
|
|
||||||
|
" Check the expansion of <script> at script and function level.
|
||||||
|
let g:script_level = ['', '', '']
|
||||||
|
let g:func_level = ['', '', '']
|
||||||
|
|
||||||
|
so Xscript0
|
||||||
|
call F0()
|
||||||
|
call F1()
|
||||||
|
call F2()
|
||||||
|
|
||||||
|
call assert_equal(['Xscript0', 'Xscript1', 'Xscript2'], g:script_level)
|
||||||
|
call assert_equal(['Xscript0', 'Xscript1', 'Xscript2'], g:func_level)
|
||||||
|
|
||||||
|
unlet g:script_level g:func_level
|
||||||
|
delfunc F0
|
||||||
|
delfunc F1
|
||||||
|
delfunc F2
|
||||||
|
|
||||||
|
call delete('Xscript0')
|
||||||
|
call delete('Xscript1')
|
||||||
|
call delete('Xscript2')
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@ -746,6 +746,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 */
|
||||||
|
/**/
|
||||||
|
4726,
|
||||||
/**/
|
/**/
|
||||||
4725,
|
4725,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user