mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-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 vim/vim#6927)
4f25b1aba0
This commit is contained in:
parent
98ab0bb5f7
commit
ed65724e57
@ -99,7 +99,7 @@ void do_debug(char_u *cmd)
|
|||||||
xfree(debug_newval);
|
xfree(debug_newval);
|
||||||
debug_newval = NULL;
|
debug_newval = NULL;
|
||||||
}
|
}
|
||||||
char *sname = estack_sfile(false);
|
char *sname = estack_sfile(ESTACK_NONE);
|
||||||
if (sname != NULL) {
|
if (sname != NULL) {
|
||||||
msg(sname);
|
msg(sname);
|
||||||
}
|
}
|
||||||
@ -324,7 +324,7 @@ static void do_checkbacktracelevel(void)
|
|||||||
debug_backtrace_level = 0;
|
debug_backtrace_level = 0;
|
||||||
msg(_("frame is zero"));
|
msg(_("frame is zero"));
|
||||||
} else {
|
} else {
|
||||||
char *sname = estack_sfile(false);
|
char *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) {
|
||||||
@ -337,7 +337,7 @@ static void do_checkbacktracelevel(void)
|
|||||||
|
|
||||||
static void do_showbacktrace(char_u *cmd)
|
static void do_showbacktrace(char_u *cmd)
|
||||||
{
|
{
|
||||||
char *sname = estack_sfile(false);
|
char *sname = estack_sfile(ESTACK_NONE);
|
||||||
int max = get_maxbacktrace_level(sname);
|
int max = get_maxbacktrace_level(sname);
|
||||||
if (sname != NULL) {
|
if (sname != NULL) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -7719,6 +7719,7 @@ ssize_t find_cmdline_var(const char_u *src, size_t *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
|
||||||
@ -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_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
|
||||||
? _("E498: no :source file name to substitute for \"<sfile>\"")
|
? _("E498: no :source file name to substitute for \"<sfile>\"")
|
||||||
|
@ -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
|
// 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;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -490,7 +490,7 @@ static int throw_exception(void *value, except_type_T type, char *cmdname)
|
|||||||
entry->sfile = NULL;
|
entry->sfile = NULL;
|
||||||
excp->throw_lnum = entry->slnum;
|
excp->throw_lnum = entry->slnum;
|
||||||
} 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 = xstrdup("");
|
excp->throw_name = xstrdup("");
|
||||||
}
|
}
|
||||||
|
@ -555,7 +555,7 @@ static char *get_emsg_source(void)
|
|||||||
FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
if (SOURCING_NAME != NULL && other_sourcing_name()) {
|
if (SOURCING_NAME != NULL && other_sourcing_name()) {
|
||||||
char *sname = estack_sfile(false);
|
char *sname = estack_sfile(ESTACK_NONE);
|
||||||
char *tofree = sname;
|
char *tofree = sname;
|
||||||
|
|
||||||
if (sname == NULL) {
|
if (sname == NULL) {
|
||||||
|
@ -100,11 +100,11 @@ void estack_pop(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the current value for <sfile> in allocated memory.
|
/// Get the current value for <sfile> in allocated memory.
|
||||||
/// @param is_sfile true for <sfile> itself.
|
/// @param which ESTACK_SFILE for <sfile> and ESTACK_STACK for <stack>.
|
||||||
char *estack_sfile(bool is_sfile)
|
char *estack_sfile(estack_arg_T which)
|
||||||
{
|
{
|
||||||
estack_T *entry = ((estack_T *)exestack.ga_data) + exestack.ga_len - 1;
|
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) {
|
if (entry->es_name == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -135,14 +135,21 @@ char *estack_sfile(bool is_sfile)
|
|||||||
}
|
}
|
||||||
len += strlen(type_name);
|
len += strlen(type_name);
|
||||||
ga_grow(&ga, (int)len);
|
ga_grow(&ga, (int)len);
|
||||||
if (idx == exestack.ga_len - 1 || entry->es_lnum == 0) {
|
linenr_T lnum = 0;
|
||||||
// For the bottom entry: do not add the line number, it is used
|
if (idx == exestack.ga_len - 1) {
|
||||||
// in <slnum>. Also leave it out when the number is not set.
|
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",
|
vim_snprintf((char *)ga.ga_data + ga.ga_len, len, "%s%s%s",
|
||||||
type_name, entry->es_name, idx == exestack.ga_len - 1 ? "" : "..");
|
type_name, entry->es_name, idx == exestack.ga_len - 1 ? "" : "..");
|
||||||
} else {
|
} else {
|
||||||
vim_snprintf((char *)ga.ga_data + ga.ga_len, len, "%s%s[%" PRIdLINENR "]..",
|
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);
|
ga.ga_len += (int)strlen((char *)ga.ga_data + ga.ga_len);
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,13 @@ extern garray_T exestack;
|
|||||||
/// line number in the message source or zero
|
/// line number in the message source or zero
|
||||||
#define SOURCING_LNUM (((estack_T *)exestack.ga_data)[exestack.ga_len - 1].es_lnum)
|
#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 {
|
typedef struct scriptitem_S {
|
||||||
char_u *sn_name;
|
char_u *sn_name;
|
||||||
bool sn_prof_on; ///< true when script is/was profiled
|
bool sn_prof_on; ///< true when script is/was profiled
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
static void prepare_assert_error(garray_T *gap)
|
static void prepare_assert_error(garray_T *gap)
|
||||||
{
|
{
|
||||||
char buf[NUMBUFLEN];
|
char buf[NUMBUFLEN];
|
||||||
char *sname = estack_sfile(false);
|
char *sname = estack_sfile(ESTACK_NONE);
|
||||||
|
|
||||||
ga_init(gap, 1, 100);
|
ga_init(gap, 1, 100);
|
||||||
if (sname != NULL) {
|
if (sname != NULL) {
|
||||||
|
Loading…
Reference in New Issue
Block a user