aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/debugger.c6
-rw-r--r--src/nvim/ex_docmd.c3
-rw-r--r--src/nvim/ex_eval.c4
-rw-r--r--src/nvim/message.c2
-rw-r--r--src/nvim/runtime.c21
-rw-r--r--src/nvim/runtime.h7
-rw-r--r--src/nvim/testdir/test_expand_func.vim9
-rw-r--r--src/nvim/testing.c2
8 files changed, 35 insertions, 19 deletions
diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c
index 663f4feb08..72d776d1e4 100644
--- a/src/nvim/debugger.c
+++ b/src/nvim/debugger.c
@@ -99,7 +99,7 @@ void do_debug(char_u *cmd)
xfree(debug_newval);
debug_newval = NULL;
}
- char *sname = estack_sfile(false);
+ char *sname = estack_sfile(ESTACK_NONE);
if (sname != NULL) {
msg(sname);
}
@@ -324,7 +324,7 @@ static void do_checkbacktracelevel(void)
debug_backtrace_level = 0;
msg(_("frame is zero"));
} else {
- char *sname = estack_sfile(false);
+ char *sname = estack_sfile(ESTACK_NONE);
int max = get_maxbacktrace_level(sname);
if (debug_backtrace_level > max) {
@@ -337,7 +337,7 @@ static void do_checkbacktracelevel(void)
static void do_showbacktrace(char_u *cmd)
{
- char *sname = estack_sfile(false);
+ char *sname = estack_sfile(ESTACK_NONE);
int max = get_maxbacktrace_level(sname);
if (sname != NULL) {
int i = 0;
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 34768f62a9..de62d90610 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -7719,6 +7719,7 @@ ssize_t find_cmdline_var(const char_u *src, size_t *usedlen)
/// '<cexpr>' to C-expression under the cursor
/// '<cfile>' to path name under the cursor
/// '<sfile>' to sourced file name
+/// '<stack>' to call stack
/// '<slnum>' to sourced file line number
/// '<afile>' to file name for autocommand
/// '<abuf>' to buffer number for autocommand
@@ -7913,7 +7914,7 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum
case SPEC_SFILE: // file name for ":so" command
case SPEC_STACK: // call stack
- result = estack_sfile(spec_idx == SPEC_SFILE);
+ result = estack_sfile(spec_idx == SPEC_SFILE ? ESTACK_SFILE : ESTACK_STACK);
if (result == NULL) {
*errormsg = spec_idx == SPEC_SFILE
? _("E498: no :source file name to substitute for \"<sfile>\"")
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index 61456acc2a..c39bb16498 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -278,7 +278,7 @@ bool cause_errthrow(const char *mesg, bool severe, bool *ignore)
// Get the source name and lnum now, it may change before
// reaching do_errthrow().
- elem->sfile = estack_sfile(false);
+ elem->sfile = estack_sfile(ESTACK_NONE);
elem->slnum = SOURCING_LNUM;
}
return true;
@@ -490,7 +490,7 @@ static int throw_exception(void *value, except_type_T type, char *cmdname)
entry->sfile = NULL;
excp->throw_lnum = entry->slnum;
} else {
- excp->throw_name = estack_sfile(false);
+ excp->throw_name = estack_sfile(ESTACK_NONE);
if (excp->throw_name == NULL) {
excp->throw_name = xstrdup("");
}
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 62827ffabc..6910fc16ae 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -555,7 +555,7 @@ static char *get_emsg_source(void)
FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
{
if (SOURCING_NAME != NULL && other_sourcing_name()) {
- char *sname = estack_sfile(false);
+ char *sname = estack_sfile(ESTACK_NONE);
char *tofree = sname;
if (sname == NULL) {
diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c
index 1cafd22b0a..fba3dce92d 100644
--- a/src/nvim/runtime.c
+++ b/src/nvim/runtime.c
@@ -100,11 +100,11 @@ void estack_pop(void)
}
/// Get the current value for <sfile> in allocated memory.
-/// @param is_sfile true for <sfile> itself.
-char *estack_sfile(bool is_sfile)
+/// @param which ESTACK_SFILE for <sfile> and ESTACK_STACK for <stack>.
+char *estack_sfile(estack_arg_T which)
{
estack_T *entry = ((estack_T *)exestack.ga_data) + exestack.ga_len - 1;
- if (is_sfile && entry->es_type != ETYPE_UFUNC) {
+ if (which == ESTACK_SFILE && entry->es_type != ETYPE_UFUNC) {
if (entry->es_name == NULL) {
return NULL;
}
@@ -135,14 +135,21 @@ char *estack_sfile(bool is_sfile)
}
len += strlen(type_name);
ga_grow(&ga, (int)len);
- if (idx == exestack.ga_len - 1 || entry->es_lnum == 0) {
- // For the bottom entry: do not add the line number, it is used
- // in <slnum>. Also leave it out when the number is not set.
+ linenr_T lnum = 0;
+ if (idx == exestack.ga_len - 1) {
+ lnum = which == ESTACK_STACK ? SOURCING_LNUM : 0;
+ } else {
+ lnum = entry->es_lnum;
+ }
+ if (lnum == 0) {
+ // For the bottom entry of <sfile>: do not add the line number,
+ // it is used in <slnum>. Also leave it out when the number is
+ // not set.
vim_snprintf((char *)ga.ga_data + ga.ga_len, len, "%s%s%s",
type_name, entry->es_name, idx == exestack.ga_len - 1 ? "" : "..");
} else {
vim_snprintf((char *)ga.ga_data + ga.ga_len, len, "%s%s[%" PRIdLINENR "]..",
- type_name, entry->es_name, entry->es_lnum);
+ type_name, entry->es_name, lnum);
}
ga.ga_len += (int)strlen((char *)ga.ga_data + ga.ga_len);
}
diff --git a/src/nvim/runtime.h b/src/nvim/runtime.h
index 6f9f31c9c4..a255c6c096 100644
--- a/src/nvim/runtime.h
+++ b/src/nvim/runtime.h
@@ -42,6 +42,13 @@ extern garray_T exestack;
/// line number in the message source or zero
#define SOURCING_LNUM (((estack_T *)exestack.ga_data)[exestack.ga_len - 1].es_lnum)
+/// Argument for estack_sfile().
+typedef enum {
+ ESTACK_NONE,
+ ESTACK_SFILE,
+ ESTACK_STACK,
+} estack_arg_T;
+
typedef struct scriptitem_S {
char_u *sn_name;
bool sn_prof_on; ///< true when script is/was profiled
diff --git a/src/nvim/testdir/test_expand_func.vim b/src/nvim/testdir/test_expand_func.vim
index 388620f87e..3094aad3a4 100644
--- a/src/nvim/testdir/test_expand_func.vim
+++ b/src/nvim/testdir/test_expand_func.vim
@@ -39,9 +39,9 @@ endfunc
func Test_expand_sfile_and_stack()
call assert_match('test_expand_func\.vim$', s:sfile)
- let expected = 'script .*testdir/runtest.vim\[\d\+\]\.\.function RunTheTest\[\d\+\]\.\.Test_expand_sfile_and_stack$'
- call assert_match(expected , expand('<sfile>'))
- call assert_match(expected , expand('<stack>'))
+ let expected = 'script .*testdir/runtest.vim\[\d\+\]\.\.function RunTheTest\[\d\+\]\.\.Test_expand_sfile_and_stack'
+ call assert_match(expected .. '$', expand('<sfile>'))
+ call assert_match(expected .. '\[4\]' , expand('<stack>'))
" Call in script-local function
call assert_match('script .*testdir/runtest.vim\[\d\+\]\.\.function RunTheTest\[\d\+\]\.\.Test_expand_sfile_and_stack\[7\]\.\.<SNR>\d\+_expand_sfile$', s:expand_sfile())
@@ -53,11 +53,12 @@ func Test_expand_sfile_and_stack()
" Use <stack> from sourced script.
let lines =<< trim END
+ " comment here
let g:stack_value = expand('<stack>')
END
call writefile(lines, 'Xstack')
source Xstack
- call assert_match('\<Xstack$', g:stack_value)
+ call assert_match('\<Xstack\[2\]', g:stack_value)
call delete('Xstack')
endfunc
diff --git a/src/nvim/testing.c b/src/nvim/testing.c
index 97bc690363..e70e9f2cbd 100644
--- a/src/nvim/testing.c
+++ b/src/nvim/testing.c
@@ -18,7 +18,7 @@
static void prepare_assert_error(garray_T *gap)
{
char buf[NUMBUFLEN];
- char *sname = estack_sfile(false);
+ char *sname = estack_sfile(ESTACK_NONE);
ga_init(gap, 1, 100);
if (sname != NULL) {