Mercurial > vim
changeset 22208:a607f02fd17a v8.2.1653
patch 8.2.1653: expand('<stack>') does not include the final line number
Commit: https://github.com/vim/vim/commit/4f25b1aba050b85fa97ca2316aa04dd4b0b22530
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Sep 10 19:25:05 2020 +0200
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 https://github.com/vim/vim/issues/6927)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 10 Sep 2020 19:30:05 +0200 |
parents | d32eb3b1201e |
children | 825fb261b141 |
files | src/debugger.c src/ex_docmd.c src/ex_eval.c src/message.c src/proto/scriptfile.pro src/scriptfile.c src/testdir/test_expand_func.vim src/testing.c src/version.c src/vim.h |
diffstat | 10 files changed, 40 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/src/debugger.c +++ b/src/debugger.c @@ -105,7 +105,7 @@ do_debug(char_u *cmd) vim_free(debug_newval); debug_newval = NULL; } - sname = estack_sfile(FALSE); + sname = estack_sfile(ESTACK_NONE); if (sname != NULL) msg((char *)sname); vim_free(sname); @@ -344,7 +344,7 @@ do_checkbacktracelevel(void) } else { - char_u *sname = estack_sfile(FALSE); + char_u *sname = estack_sfile(ESTACK_NONE); int max = get_maxbacktrace_level(sname); if (debug_backtrace_level > max) @@ -365,7 +365,7 @@ do_showbacktrace(char_u *cmd) int i = 0; int max; - sname = estack_sfile(FALSE); + sname = estack_sfile(ESTACK_NONE); max = get_maxbacktrace_level(sname); if (sname != NULL) {
--- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -8389,6 +8389,7 @@ find_cmdline_var(char_u *src, int *usedl * '<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 @@ -8606,7 +8607,8 @@ eval_vars( 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
--- a/src/ex_eval.c +++ b/src/ex_eval.c @@ -290,7 +290,7 @@ cause_errthrow( // 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; } } @@ -549,7 +549,7 @@ throw_exception(void *value, except_type } else { - excp->throw_name = estack_sfile(FALSE); + excp->throw_name = estack_sfile(ESTACK_NONE); if (excp->throw_name == NULL) excp->throw_name = vim_strsave((char_u *)""); if (excp->throw_name == NULL)
--- a/src/message.c +++ b/src/message.c @@ -461,7 +461,7 @@ get_emsg_source(void) if (SOURCING_NAME != NULL && other_sourcing_name()) { - char_u *sname = estack_sfile(FALSE); + char_u *sname = estack_sfile(ESTACK_NONE); char_u *tofree = sname; if (sname == NULL)
--- a/src/proto/scriptfile.pro +++ b/src/proto/scriptfile.pro @@ -4,7 +4,7 @@ estack_T *estack_push(etype_T type, char estack_T *estack_push_ufunc(ufunc_T *ufunc, long lnum); int estack_top_is_ufunc(ufunc_T *ufunc, long lnum); 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); 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);
--- a/src/scriptfile.c +++ b/src/scriptfile.c @@ -111,10 +111,10 @@ estack_pop(void) /* * 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 * -estack_sfile(int is_sfile UNUSED) +estack_sfile(estack_arg_T which UNUSED) { estack_T *entry; #ifdef FEAT_EVAL @@ -127,7 +127,7 @@ estack_sfile(int is_sfile UNUSED) entry = ((estack_T *)exestack.ga_data) + exestack.ga_len - 1; #ifdef FEAT_EVAL - if (is_sfile && entry->es_type != ETYPE_UFUNC) + if (which == ESTACK_SFILE && entry->es_type != ETYPE_UFUNC) #endif { if (entry->es_name == NULL) @@ -144,6 +144,8 @@ estack_sfile(int is_sfile UNUSED) entry = ((estack_T *)exestack.ga_data) + idx; if (entry->es_name != NULL) { + long lnum = 0; + len = STRLEN(entry->es_name) + 15; type_name = ""; if (entry->es_type != last_type) @@ -159,15 +161,20 @@ estack_sfile(int is_sfile UNUSED) len += STRLEN(type_name); if (ga_grow(&ga, (int)len) == FAIL) break; - 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. + 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[%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); } }
--- a/src/testdir/test_expand_func.vim +++ b/src/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
--- a/src/testing.c +++ b/src/testing.c @@ -22,7 +22,7 @@ prepare_assert_error(garray_T *gap) { char buf[NUMBUFLEN]; - char_u *sname = estack_sfile(FALSE); + char_u *sname = estack_sfile(ESTACK_NONE); ga_init2(gap, 1, 100); if (sname != NULL)
--- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1653, +/**/ 1652, /**/ 1651,
--- a/src/vim.h +++ b/src/vim.h @@ -2097,8 +2097,7 @@ typedef struct stat stat_T; # define USE_PRINTF_FORMAT_ATTRIBUTE #endif -typedef enum -{ +typedef enum { ASSERT_EQUAL, ASSERT_NOTEQUAL, ASSERT_MATCH, @@ -2128,6 +2127,13 @@ typedef enum { USEPOPUP_HIDDEN // use info popup initially hidden } use_popup_T; +// Argument for estack_sfile(). +typedef enum { + ESTACK_NONE, + ESTACK_SFILE, + ESTACK_STACK +} estack_arg_T; + // Flags for assignment functions. #define LET_IS_CONST 1 // ":const" #define LET_NO_COMMAND 2 // "var = expr" without ":let" or ":const"