0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

patch 8.2.1653: expand('<stack>') does not include the final line number

Problem:    Expand('<stack>') does not include the final line number.
Solution:   Add the line nuber. (closes #6927)
This commit is contained in:
Bram Moolenaar
2020-09-10 19:25:05 +02:00
parent a953b5cf4f
commit 4f25b1aba0
10 changed files with 40 additions and 22 deletions

View File

@@ -105,7 +105,7 @@ do_debug(char_u *cmd)
vim_free(debug_newval); vim_free(debug_newval);
debug_newval = NULL; debug_newval = NULL;
} }
sname = estack_sfile(FALSE); sname = estack_sfile(ESTACK_NONE);
if (sname != NULL) if (sname != NULL)
msg((char *)sname); msg((char *)sname);
vim_free(sname); vim_free(sname);
@@ -344,7 +344,7 @@ do_checkbacktracelevel(void)
} }
else else
{ {
char_u *sname = estack_sfile(FALSE); char_u *sname = estack_sfile(ESTACK_NONE);
int max = get_maxbacktrace_level(sname); int max = get_maxbacktrace_level(sname);
if (debug_backtrace_level > max) if (debug_backtrace_level > max)
@@ -365,7 +365,7 @@ do_showbacktrace(char_u *cmd)
int i = 0; int i = 0;
int max; int max;
sname = estack_sfile(FALSE); sname = estack_sfile(ESTACK_NONE);
max = get_maxbacktrace_level(sname); max = get_maxbacktrace_level(sname);
if (sname != NULL) if (sname != NULL)
{ {

View File

@@ -8389,6 +8389,7 @@ find_cmdline_var(char_u *src, int *usedlen)
* '<cexpr>' to C-expression under the cursor * '<cexpr>' to C-expression under the cursor
* '<cfile>' to path name under the cursor * '<cfile>' to path name under the cursor
* '<sfile>' to sourced file name * '<sfile>' to sourced file name
* '<stack>' to call stack
* '<slnum>' to sourced file line number * '<slnum>' to sourced file line number
* '<afile>' to file name for autocommand * '<afile>' to file name for autocommand
* '<abuf>' to buffer number for autocommand * '<abuf>' to buffer number for autocommand
@@ -8606,7 +8607,8 @@ eval_vars(
case SPEC_SFILE: // file name for ":so" command case SPEC_SFILE: // file name for ":so" command
case SPEC_STACK: // call stack 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) if (result == NULL)
{ {
*errormsg = spec_idx == SPEC_SFILE *errormsg = spec_idx == SPEC_SFILE

View File

@@ -290,7 +290,7 @@ cause_errthrow(
// Get the source name and lnum now, it may change before // Get the source name and lnum now, it may change before
// reaching do_errthrow(). // reaching do_errthrow().
elem->sfile = estack_sfile(FALSE); elem->sfile = estack_sfile(ESTACK_NONE);
elem->slnum = SOURCING_LNUM; elem->slnum = SOURCING_LNUM;
} }
} }
@@ -549,7 +549,7 @@ throw_exception(void *value, except_type_T type, char_u *cmdname)
} }
else else
{ {
excp->throw_name = estack_sfile(FALSE); excp->throw_name = estack_sfile(ESTACK_NONE);
if (excp->throw_name == NULL) if (excp->throw_name == NULL)
excp->throw_name = vim_strsave((char_u *)""); excp->throw_name = vim_strsave((char_u *)"");
if (excp->throw_name == NULL) if (excp->throw_name == NULL)

View File

@@ -461,7 +461,7 @@ get_emsg_source(void)
if (SOURCING_NAME != NULL && other_sourcing_name()) if (SOURCING_NAME != NULL && other_sourcing_name())
{ {
char_u *sname = estack_sfile(FALSE); char_u *sname = estack_sfile(ESTACK_NONE);
char_u *tofree = sname; char_u *tofree = sname;
if (sname == NULL) if (sname == NULL)

View File

@@ -4,7 +4,7 @@ estack_T *estack_push(etype_T type, char_u *name, long lnum);
estack_T *estack_push_ufunc(ufunc_T *ufunc, long lnum); estack_T *estack_push_ufunc(ufunc_T *ufunc, long lnum);
int estack_top_is_ufunc(ufunc_T *ufunc, long lnum); int estack_top_is_ufunc(ufunc_T *ufunc, long lnum);
estack_T *estack_pop(void); estack_T *estack_pop(void);
char_u *estack_sfile(int is_sfile); char_u *estack_sfile(estack_arg_T which);
void ex_runtime(exarg_T *eap); void ex_runtime(exarg_T *eap);
int do_in_path(char_u *path, char_u *name, int flags, void (*callback)(char_u *fname, void *ck), void *cookie); int do_in_path(char_u *path, char_u *name, int flags, void (*callback)(char_u *fname, void *ck), void *cookie);
int do_in_runtimepath(char_u *name, int flags, void (*callback)(char_u *fname, void *ck), void *cookie); int do_in_runtimepath(char_u *name, int flags, void (*callback)(char_u *fname, void *ck), void *cookie);

View File

@@ -111,10 +111,10 @@ estack_pop(void)
/* /*
* Get the current value for <sfile> in allocated memory. * Get the current value for <sfile> in allocated memory.
* "is_sfile" is TRUE for <sfile> itself. * "which" is ESTACK_SFILE for <sfile> and ESTACK_STACK for <stack>.
*/ */
char_u * char_u *
estack_sfile(int is_sfile UNUSED) estack_sfile(estack_arg_T which UNUSED)
{ {
estack_T *entry; estack_T *entry;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
@@ -127,7 +127,7 @@ estack_sfile(int is_sfile UNUSED)
entry = ((estack_T *)exestack.ga_data) + exestack.ga_len - 1; entry = ((estack_T *)exestack.ga_data) + exestack.ga_len - 1;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
if (is_sfile && entry->es_type != ETYPE_UFUNC) if (which == ESTACK_SFILE && entry->es_type != ETYPE_UFUNC)
#endif #endif
{ {
if (entry->es_name == NULL) if (entry->es_name == NULL)
@@ -144,6 +144,8 @@ estack_sfile(int is_sfile UNUSED)
entry = ((estack_T *)exestack.ga_data) + idx; entry = ((estack_T *)exestack.ga_data) + idx;
if (entry->es_name != NULL) if (entry->es_name != NULL)
{ {
long lnum = 0;
len = STRLEN(entry->es_name) + 15; len = STRLEN(entry->es_name) + 15;
type_name = ""; type_name = "";
if (entry->es_type != last_type) if (entry->es_type != last_type)
@@ -159,15 +161,20 @@ estack_sfile(int is_sfile UNUSED)
len += STRLEN(type_name); len += STRLEN(type_name);
if (ga_grow(&ga, (int)len) == FAIL) if (ga_grow(&ga, (int)len) == FAIL)
break; break;
if (idx == exestack.ga_len - 1 || entry->es_lnum == 0) if (idx == exestack.ga_len - 1)
// For the bottom entry: do not add the line number, it is used lnum = which == ESTACK_STACK ? SOURCING_LNUM : 0;
// in <slnum>. Also leave it out when the number is not set. 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", vim_snprintf((char *)ga.ga_data + ga.ga_len, len, "%s%s%s",
type_name, entry->es_name, type_name, entry->es_name,
idx == exestack.ga_len - 1 ? "" : ".."); idx == exestack.ga_len - 1 ? "" : "..");
else else
vim_snprintf((char *)ga.ga_data + ga.ga_len, len, "%s%s[%ld]..", vim_snprintf((char *)ga.ga_data + ga.ga_len, len, "%s%s[%ld]..",
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); ga.ga_len += (int)STRLEN((char *)ga.ga_data + ga.ga_len);
} }
} }

View File

@@ -39,9 +39,9 @@ endfunc
func Test_expand_sfile_and_stack() func Test_expand_sfile_and_stack()
call assert_match('test_expand_func\.vim$', s:sfile) call assert_match('test_expand_func\.vim$', s:sfile)
let expected = 'script .*testdir/runtest.vim\[\d\+\]\.\.function RunTheTest\[\d\+\]\.\.Test_expand_sfile_and_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 .. '$', expand('<sfile>'))
call assert_match(expected , expand('<stack>')) call assert_match(expected .. '\[4\]' , expand('<stack>'))
" Call in script-local function " 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()) 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. " Use <stack> from sourced script.
let lines =<< trim END let lines =<< trim END
" comment here
let g:stack_value = expand('<stack>') let g:stack_value = expand('<stack>')
END END
call writefile(lines, 'Xstack') call writefile(lines, 'Xstack')
source Xstack source Xstack
call assert_match('\<Xstack$', g:stack_value) call assert_match('\<Xstack\[2\]', g:stack_value)
call delete('Xstack') call delete('Xstack')
endfunc endfunc

View File

@@ -22,7 +22,7 @@
prepare_assert_error(garray_T *gap) prepare_assert_error(garray_T *gap)
{ {
char buf[NUMBUFLEN]; char buf[NUMBUFLEN];
char_u *sname = estack_sfile(FALSE); char_u *sname = estack_sfile(ESTACK_NONE);
ga_init2(gap, 1, 100); ga_init2(gap, 1, 100);
if (sname != NULL) if (sname != NULL)

View File

@@ -750,6 +750,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 */
/**/
1653,
/**/ /**/
1652, 1652,
/**/ /**/

View File

@@ -2097,8 +2097,7 @@ typedef struct stat stat_T;
# define USE_PRINTF_FORMAT_ATTRIBUTE # define USE_PRINTF_FORMAT_ATTRIBUTE
#endif #endif
typedef enum typedef enum {
{
ASSERT_EQUAL, ASSERT_EQUAL,
ASSERT_NOTEQUAL, ASSERT_NOTEQUAL,
ASSERT_MATCH, ASSERT_MATCH,
@@ -2128,6 +2127,13 @@ typedef enum {
USEPOPUP_HIDDEN // use info popup initially hidden USEPOPUP_HIDDEN // use info popup initially hidden
} use_popup_T; } use_popup_T;
// Argument for estack_sfile().
typedef enum {
ESTACK_NONE,
ESTACK_SFILE,
ESTACK_STACK
} estack_arg_T;
// Flags for assignment functions. // Flags for assignment functions.
#define LET_IS_CONST 1 // ":const" #define LET_IS_CONST 1 // ":const"
#define LET_NO_COMMAND 2 // "var = expr" without ":let" or ":const" #define LET_NO_COMMAND 2 // "var = expr" without ":let" or ":const"