neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit e45212101c5522fea5fbcd0c2a8e3a5920667d7f
parent b058a801e7515dd09154f60d7de0219f92635fb8
Author: zeertzjq <zeertzjq@outlook.com>
Date:   Tue,  2 Dec 2025 08:04:54 +0800

Merge pull request #36773 from zeertzjq/funccal-refcount

fix(eval): fix crash with :breakadd expr when calling user func
Diffstat:
Msrc/nvim/debugger.c | 6++++++
Msrc/nvim/eval/userfunc.c | 38+++++++++++++++++++++++++++-----------
Msrc/nvim/eval/vars.c | 18+++++++++---------
Mtest/functional/legacy/debugger_spec.lua | 130++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Mtest/old/testdir/test_debugger.vim | 732++++++++++++++++++++++++++++++++++++++++++-------------------------------------
5 files changed, 516 insertions(+), 408 deletions(-)

diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c @@ -828,17 +828,21 @@ static linenr_T debuggy_find(bool file, char *fname, linenr_T after, garray_T *g typval_T *const tv = eval_expr_no_emsg(bp); if (tv != NULL) { if (bp->dbg_val == NULL) { + xfree(debug_oldval); debug_oldval = typval_tostring(NULL, true); bp->dbg_val = tv; + xfree(debug_newval); debug_newval = typval_tostring(bp->dbg_val, true); line = true; } else { if (typval_compare(tv, bp->dbg_val, EXPR_IS, false) == OK && tv->vval.v_number == false) { line = true; + xfree(debug_oldval); debug_oldval = typval_tostring(bp->dbg_val, true); // Need to evaluate again, typval_compare() overwrites "tv". typval_T *const v = eval_expr_no_emsg(bp); + xfree(debug_newval); debug_newval = typval_tostring(v, true); tv_free(bp->dbg_val); bp->dbg_val = v; @@ -846,7 +850,9 @@ static linenr_T debuggy_find(bool file, char *fname, linenr_T after, garray_T *g tv_free(tv); } } else if (bp->dbg_val != NULL) { + xfree(debug_oldval); debug_oldval = typval_tostring(bp->dbg_val, true); + xfree(debug_newval); debug_newval = typval_tostring(NULL, true); tv_free(bp->dbg_val); bp->dbg_val = NULL; diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c @@ -3906,41 +3906,57 @@ funccall_T *get_funccal(void) return funccal; } -/// @return hashtable used for local variables in the current funccal or +/// @return dict used for local variables in the current funccal or /// NULL if there is no current funccal. -hashtab_T *get_funccal_local_ht(void) +dict_T *get_funccal_local_dict(void) { - if (current_funccal == NULL) { + if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount == 0) { return NULL; } - return &get_funccal()->fc_l_vars.dv_hashtab; + return &get_funccal()->fc_l_vars; +} + +/// @return hashtable used for local variables in the current funccal or +/// NULL if there is no current funccal. +hashtab_T *get_funccal_local_ht(void) +{ + dict_T *d = get_funccal_local_dict(); + return d != NULL ? &d->dv_hashtab : NULL; } /// @return the l: scope variable or /// NULL if there is no current funccal. dictitem_T *get_funccal_local_var(void) { - if (current_funccal == NULL) { + if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount == 0) { return NULL; } return (dictitem_T *)&get_funccal()->fc_l_vars_var; } -/// @return the hashtable used for argument in the current funccal or +/// @return the dict used for argument in the current funccal or /// NULL if there is no current funccal. -hashtab_T *get_funccal_args_ht(void) +dict_T *get_funccal_args_dict(void) { - if (current_funccal == NULL) { + if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount == 0) { return NULL; } - return &get_funccal()->fc_l_avars.dv_hashtab; + return &get_funccal()->fc_l_avars; +} + +/// @return the hashtable used for argument in the current funccal or +/// NULL if there is no current funccal. +hashtab_T *get_funccal_args_ht(void) +{ + dict_T *d = get_funccal_args_dict(); + return d != NULL ? &d->dv_hashtab : NULL; } /// @return the a: scope variable or /// NULL if there is no current funccal. dictitem_T *get_funccal_args_var(void) { - if (current_funccal == NULL) { + if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount == 0) { return NULL; } return (dictitem_T *)&get_funccal()->fc_l_avars_var; @@ -3949,7 +3965,7 @@ dictitem_T *get_funccal_args_var(void) /// List function variables, if there is a function. void list_func_vars(int *first) { - if (current_funccal != NULL) { + if (current_funccal != NULL && current_funccal->fc_l_vars.dv_refcount > 0) { list_hashtable_vars(&current_funccal->fc_l_vars.dv_hashtab, "l:", false, first); } diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c @@ -2483,7 +2483,6 @@ dictitem_T *find_var_in_ht(hashtab_T *const ht, int htname, const char *const va static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len, const char **varname, dict_T **d) { - funccall_T *funccal = get_funccal(); *d = NULL; if (name_len == 0) { @@ -2503,11 +2502,12 @@ static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len, cons return &compat_hashtab; } - if (funccal == NULL) { // global variable - *d = get_globvar_dict(); - } else { // l: variable - *d = &funccal->fc_l_vars; + *d = get_funccal_local_dict(); + if (*d != NULL) { // local variable + goto end; } + + *d = get_globvar_dict(); // global variable goto end; } @@ -2529,10 +2529,10 @@ static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len, cons *d = curtab->tp_vars; } else if (*name == 'v') { // v: variable *d = get_vimvar_dict(); - } else if (*name == 'a' && funccal != NULL) { // function argument - *d = &funccal->fc_l_avars; - } else if (*name == 'l' && funccal != NULL) { // local variable - *d = &funccal->fc_l_vars; + } else if (*name == 'a') { // a: function argument + *d = get_funccal_args_dict(); + } else if (*name == 'l') { // l: local variable + *d = get_funccal_local_dict(); } else if (*name == 's' // script variable && (current_sctx.sc_sid > 0 || current_sctx.sc_sid == SID_STR || current_sctx.sc_sid == SID_LUA) diff --git a/test/functional/legacy/debugger_spec.lua b/test/functional/legacy/debugger_spec.lua @@ -13,64 +13,112 @@ describe('debugger', function() local screen before_each(function() - screen = Screen.new(999, 10) + screen = Screen.new(999, 7) end) -- oldtest: Test_Debugger_breakadd_expr() + -- This doesn't seem to work as documented. The breakpoint is not + -- triggered until the next function call. it(':breakadd expr', function() - write_file('XdebugBreakExpr.vim', 'let g:Xtest_var += 1') + write_file( + 'XbreakExpr.vim', + [[ + func Foo() + eval 1 + eval 2 + endfunc + + let g:Xtest_var += 1 + call Foo() + let g:Xtest_var += 1 + call Foo()]] + ) finally(function() - os.remove('XdebugBreakExpr.vim') + os.remove('XbreakExpr.vim') end) - command('edit XdebugBreakExpr.vim') + command('edit XbreakExpr.vim') command(':let g:Xtest_var = 10') command(':breakadd expr g:Xtest_var') - feed(':source %<CR>') - screen:expect { - grid = [[ - ^let g:Xtest_var += 1{MATCH: *}| - {1:~{MATCH: *}}|*8 - :source %{MATCH: *}| - ]], - } - feed(':source %<CR>') - screen:expect { - grid = [[ + local initial_screen = [[ + ^func Foo(){MATCH: *}| + eval 1{MATCH: *}| + eval 2{MATCH: *}| + endfunc{MATCH: *}| + {MATCH: *}| let g:Xtest_var += 1{MATCH: *}| - {1:~{MATCH: *}}| - {3:{MATCH: *}}| - Breakpoint in "{MATCH:.*}XdebugBreakExpr.vim" line 1{MATCH: *}| + {MATCH: *}| + ]] + screen:expect(initial_screen) + + feed(':source %<CR>') + screen:expect([[ + Breakpoint in "Foo" line 1{MATCH: *}| Entering Debug mode. Type "cont" to continue.{MATCH: *}| Oldval = "10"{MATCH: *}| Newval = "11"{MATCH: *}| - {MATCH:.*}XdebugBreakExpr.vim{MATCH: *}| - line 1: let g:Xtest_var += 1{MATCH: *}| + {MATCH:.*}XbreakExpr.vim[7]..function Foo{MATCH: *}| + line 1: eval 1{MATCH: *}| >^{MATCH: *}| - ]], - } + ]]) feed('cont<CR>') - screen:expect { - grid = [[ - ^let g:Xtest_var += 1{MATCH: *}| - {1:~{MATCH: *}}|*8 - {MATCH: *}| - ]], - } - feed(':source %<CR>') - screen:expect { - grid = [[ - let g:Xtest_var += 1{MATCH: *}| - {1:~{MATCH: *}}| - {3:{MATCH: *}}| - Breakpoint in "{MATCH:.*}XdebugBreakExpr.vim" line 1{MATCH: *}| - Entering Debug mode. Type "cont" to continue.{MATCH: *}| + screen:expect([[ + >cont{MATCH: *}| + Breakpoint in "Foo" line 1{MATCH: *}| Oldval = "11"{MATCH: *}| Newval = "12"{MATCH: *}| - {MATCH:.*}XdebugBreakExpr.vim{MATCH: *}| - line 1: let g:Xtest_var += 1{MATCH: *}| + {MATCH:.*}XbreakExpr.vim[9]..function Foo{MATCH: *}| + line 1: eval 1{MATCH: *}| >^{MATCH: *}| - ]], - } + ]]) + feed('cont<CR>') + screen:expect(initial_screen) + + -- Check the behavior without the g: prefix. + -- The Oldval and Newval don't look right here. + command(':breakdel *') + command(':breakadd expr Xtest_var') + feed(':source %<CR>') + screen:expect([[ + Breakpoint in "Foo" line 1{MATCH: *}| + Entering Debug mode. Type "cont" to continue.{MATCH: *}| + Oldval = "13"{MATCH: *}| + Newval = "(does not exist)"{MATCH: *}| + {MATCH:.*}XbreakExpr.vim[7]..function Foo{MATCH: *}| + line 1: eval 1{MATCH: *}| + >^{MATCH: *}| + ]]) + feed('cont<CR>') + screen:expect([[ + {MATCH:.*}XbreakExpr.vim[7]..function Foo{MATCH: *}| + line 1: eval 1{MATCH: *}| + >cont{MATCH: *}| + Breakpoint in "Foo" line 2{MATCH: *}| + {MATCH:.*}XbreakExpr.vim[7]..function Foo{MATCH: *}| + line 2: eval 2{MATCH: *}| + >^{MATCH: *}| + ]]) + feed('cont<CR>') + screen:expect([[ + >cont{MATCH: *}| + Breakpoint in "Foo" line 1{MATCH: *}| + Oldval = "14"{MATCH: *}| + Newval = "(does not exist)"{MATCH: *}| + {MATCH:.*}XbreakExpr.vim[9]..function Foo{MATCH: *}| + line 1: eval 1{MATCH: *}| + >^{MATCH: *}| + ]]) + feed('cont<CR>') + screen:expect([[ + {MATCH:.*}XbreakExpr.vim[9]..function Foo{MATCH: *}| + line 1: eval 1{MATCH: *}| + >cont{MATCH: *}| + Breakpoint in "Foo" line 2{MATCH: *}| + {MATCH:.*}XbreakExpr.vim[9]..function Foo{MATCH: *}| + line 2: eval 2{MATCH: *}| + >^{MATCH: *}| + ]]) + feed('cont<CR>') + screen:expect(initial_screen) end) end) diff --git a/test/old/testdir/test_debugger.vim b/test/old/testdir/test_debugger.vim @@ -35,7 +35,7 @@ endfunc " Run a Vim debugger command " If the expected output argument is supplied, then check for it. -func RunDbgCmd(buf, cmd, ...) +func s:RunDbgCmd(buf, cmd, ...) call term_sendkeys(a:buf, a:cmd . "\r") call TermWait(a:buf) @@ -88,248 +88,248 @@ func Test_Debugger() let buf = RunVimInTerminal('-S XtestDebug.vim', {}) " Start the Vim debugger - call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()']) + call s:RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()']) " Create a few stack frames by stepping through functions - call RunDbgCmd(buf, 'step', ['line 1: let var1 = 1']) - call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bar(var1) + 9']) - call RunDbgCmd(buf, 'step', ['line 1: let var1 = 2 + a:var']) - call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bazz(var1) + 4']) - call RunDbgCmd(buf, 'step', ['line 1: try']) - call RunDbgCmd(buf, 'step', ['line 2: let var1 = 3 + a:var']) - call RunDbgCmd(buf, 'step', ['line 3: let var3 = "another var"']) + call s:RunDbgCmd(buf, 'step', ['line 1: let var1 = 1']) + call s:RunDbgCmd(buf, 'step', ['line 2: let var2 = Bar(var1) + 9']) + call s:RunDbgCmd(buf, 'step', ['line 1: let var1 = 2 + a:var']) + call s:RunDbgCmd(buf, 'step', ['line 2: let var2 = Bazz(var1) + 4']) + call s:RunDbgCmd(buf, 'step', ['line 1: try']) + call s:RunDbgCmd(buf, 'step', ['line 2: let var1 = 3 + a:var']) + call s:RunDbgCmd(buf, 'step', ['line 3: let var3 = "another var"']) " check backtrace - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'backtrace', [ \ ' 2 function Foo[2]', \ ' 1 Bar[2]', \ '->0 Bazz', \ 'line 3: let var3 = "another var"']) " Check variables in different stack frames - call RunDbgCmd(buf, 'echo var1', ['6']) + call s:RunDbgCmd(buf, 'echo var1', ['6']) - call RunDbgCmd(buf, 'up') - call RunDbgCmd(buf, 'back', [ + call s:RunDbgCmd(buf, 'up') + call s:RunDbgCmd(buf, 'back', [ \ ' 2 function Foo[2]', \ '->1 Bar[2]', \ ' 0 Bazz', \ 'line 3: let var3 = "another var"']) - call RunDbgCmd(buf, 'echo var1', ['3']) + call s:RunDbgCmd(buf, 'echo var1', ['3']) - call RunDbgCmd(buf, 'u') - call RunDbgCmd(buf, 'bt', [ + call s:RunDbgCmd(buf, 'u') + call s:RunDbgCmd(buf, 'bt', [ \ '->2 function Foo[2]', \ ' 1 Bar[2]', \ ' 0 Bazz', \ 'line 3: let var3 = "another var"']) - call RunDbgCmd(buf, 'echo var1', ['1']) + call s:RunDbgCmd(buf, 'echo var1', ['1']) " Undefined variables - call RunDbgCmd(buf, 'step') - call RunDbgCmd(buf, 'frame 2') - call RunDbgCmd(buf, 'echo var3', [ + call s:RunDbgCmd(buf, 'step') + call s:RunDbgCmd(buf, 'frame 2') + call s:RunDbgCmd(buf, 'echo var3', [ \ 'Error in function Foo[2]..Bar[2]..Bazz:', \ 'line 4:', \ 'E121: Undefined variable: var3']) " var3 is defined in this level with some other value - call RunDbgCmd(buf, 'fr 0') - call RunDbgCmd(buf, 'echo var3', ['another var']) - - call RunDbgCmd(buf, 'step') - call RunDbgCmd(buf, '') - call RunDbgCmd(buf, '') - call RunDbgCmd(buf, '') - call RunDbgCmd(buf, '') - call RunDbgCmd(buf, 'step', [ + call s:RunDbgCmd(buf, 'fr 0') + call s:RunDbgCmd(buf, 'echo var3', ['another var']) + + call s:RunDbgCmd(buf, 'step') + call s:RunDbgCmd(buf, '') + call s:RunDbgCmd(buf, '') + call s:RunDbgCmd(buf, '') + call s:RunDbgCmd(buf, '') + call s:RunDbgCmd(buf, 'step', [ \ 'function Foo[2]..Bar', \ 'line 3: End of function']) - call RunDbgCmd(buf, 'up') + call s:RunDbgCmd(buf, 'up') " Undefined var2 - call RunDbgCmd(buf, 'echo var2', [ + call s:RunDbgCmd(buf, 'echo var2', [ \ 'Error in function Foo[2]..Bar:', \ 'line 3:', \ 'E121: Undefined variable: var2']) " Var2 is defined with 10 - call RunDbgCmd(buf, 'down') - call RunDbgCmd(buf, 'echo var2', ['10']) + call s:RunDbgCmd(buf, 'down') + call s:RunDbgCmd(buf, 'echo var2', ['10']) " Backtrace movements - call RunDbgCmd(buf, 'b', [ + call s:RunDbgCmd(buf, 'b', [ \ ' 1 function Foo[2]', \ '->0 Bar', \ 'line 3: End of function']) " next command cannot go down, we are on bottom - call RunDbgCmd(buf, 'down', ['frame is zero']) - call RunDbgCmd(buf, 'up') + call s:RunDbgCmd(buf, 'down', ['frame is zero']) + call s:RunDbgCmd(buf, 'up') " next command cannot go up, we are on top - call RunDbgCmd(buf, 'up', ['frame at highest level: 1']) - call RunDbgCmd(buf, 'where', [ + call s:RunDbgCmd(buf, 'up', ['frame at highest level: 1']) + call s:RunDbgCmd(buf, 'where', [ \ '->1 function Foo[2]', \ ' 0 Bar', \ 'line 3: End of function']) " fil is not frame or finish, it is file - call RunDbgCmd(buf, 'fil', ['"[No Name]" --No lines in buffer--']) + call s:RunDbgCmd(buf, 'fil', ['"[No Name]" --No lines in buffer--']) " relative backtrace movement - call RunDbgCmd(buf, 'fr -1') - call RunDbgCmd(buf, 'frame', [ + call s:RunDbgCmd(buf, 'fr -1') + call s:RunDbgCmd(buf, 'frame', [ \ ' 1 function Foo[2]', \ '->0 Bar', \ 'line 3: End of function']) - call RunDbgCmd(buf, 'fr +1') - call RunDbgCmd(buf, 'fram', [ + call s:RunDbgCmd(buf, 'fr +1') + call s:RunDbgCmd(buf, 'fram', [ \ '->1 function Foo[2]', \ ' 0 Bar', \ 'line 3: End of function']) " go beyond limits does not crash - call RunDbgCmd(buf, 'fr 100', ['frame at highest level: 1']) - call RunDbgCmd(buf, 'fra', [ + call s:RunDbgCmd(buf, 'fr 100', ['frame at highest level: 1']) + call s:RunDbgCmd(buf, 'fra', [ \ '->1 function Foo[2]', \ ' 0 Bar', \ 'line 3: End of function']) - call RunDbgCmd(buf, 'frame -40', ['frame is zero']) - call RunDbgCmd(buf, 'fram', [ + call s:RunDbgCmd(buf, 'frame -40', ['frame is zero']) + call s:RunDbgCmd(buf, 'fram', [ \ ' 1 function Foo[2]', \ '->0 Bar', \ 'line 3: End of function']) " final result 19 - call RunDbgCmd(buf, 'cont', ['19']) + call s:RunDbgCmd(buf, 'cont', ['19']) " breakpoints tests " Start a debug session, so that reading the last line from the terminal " works properly. - call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()']) + call s:RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()']) " No breakpoints - call RunDbgCmd(buf, 'breakl', ['No breakpoints defined']) + call s:RunDbgCmd(buf, 'breakl', ['No breakpoints defined']) " Place some breakpoints - call RunDbgCmd(buf, 'breaka func Bar') - call RunDbgCmd(buf, 'breaklis', [' 1 func Bar line 1']) - call RunDbgCmd(buf, 'breakadd func 3 Bazz') - call RunDbgCmd(buf, 'breaklist', [' 1 func Bar line 1', + call s:RunDbgCmd(buf, 'breaka func Bar') + call s:RunDbgCmd(buf, 'breaklis', [' 1 func Bar line 1']) + call s:RunDbgCmd(buf, 'breakadd func 3 Bazz') + call s:RunDbgCmd(buf, 'breaklist', [' 1 func Bar line 1', \ ' 2 func Bazz line 3']) " Check whether the breakpoints are hit - call RunDbgCmd(buf, 'cont', [ + call s:RunDbgCmd(buf, 'cont', [ \ 'Breakpoint in "Bar" line 1', \ 'function Foo[2]..Bar', \ 'line 1: let var1 = 2 + a:var']) - call RunDbgCmd(buf, 'cont', [ + call s:RunDbgCmd(buf, 'cont', [ \ 'Breakpoint in "Bazz" line 3', \ 'function Foo[2]..Bar[2]..Bazz', \ 'line 3: let var3 = "another var"']) " Delete the breakpoints - call RunDbgCmd(buf, 'breakd 1') - call RunDbgCmd(buf, 'breakli', [' 2 func Bazz line 3']) - call RunDbgCmd(buf, 'breakdel func 3 Bazz') - call RunDbgCmd(buf, 'breakl', ['No breakpoints defined']) + call s:RunDbgCmd(buf, 'breakd 1') + call s:RunDbgCmd(buf, 'breakli', [' 2 func Bazz line 3']) + call s:RunDbgCmd(buf, 'breakdel func 3 Bazz') + call s:RunDbgCmd(buf, 'breakl', ['No breakpoints defined']) - call RunDbgCmd(buf, 'cont') + call s:RunDbgCmd(buf, 'cont') " Make sure the breakpoints are removed - call RunDbgCmd(buf, ':echo Foo()', ['19']) + call s:RunDbgCmd(buf, ':echo Foo()', ['19']) " Delete a non-existing breakpoint - call RunDbgCmd(buf, ':breakdel 2', ['E161: Breakpoint not found: 2']) + call s:RunDbgCmd(buf, ':breakdel 2', ['E161: Breakpoint not found: 2']) " Expression breakpoint - call RunDbgCmd(buf, ':breakadd func 2 Bazz') - call RunDbgCmd(buf, ':echo Bazz(1)', [ + call s:RunDbgCmd(buf, ':breakadd func 2 Bazz') + call s:RunDbgCmd(buf, ':echo Bazz(1)', [ \ 'Entering Debug mode. Type "cont" to continue.', \ 'function Bazz', \ 'line 2: let var1 = 3 + a:var']) - call RunDbgCmd(buf, 'step') - call RunDbgCmd(buf, 'step') - call RunDbgCmd(buf, 'breaka expr var3') - call RunDbgCmd(buf, 'breakl', [' 3 func Bazz line 2', + call s:RunDbgCmd(buf, 'step') + call s:RunDbgCmd(buf, 'step') + call s:RunDbgCmd(buf, 'breaka expr var3') + call s:RunDbgCmd(buf, 'breakl', [' 3 func Bazz line 2', \ ' 4 expr var3']) - call RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 5', + call s:RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 5', \ 'Oldval = "''another var''"', \ 'Newval = "''value2''"', \ 'function Bazz', \ 'line 5: catch']) - call RunDbgCmd(buf, 'breakdel *') - call RunDbgCmd(buf, 'breakl', ['No breakpoints defined']) + call s:RunDbgCmd(buf, 'breakdel *') + call s:RunDbgCmd(buf, 'breakl', ['No breakpoints defined']) " Check for error cases - call RunDbgCmd(buf, 'breakadd abcd', [ + call s:RunDbgCmd(buf, 'breakadd abcd', [ \ 'Error in function Bazz:', \ 'line 5:', \ 'E475: Invalid argument: abcd']) - call RunDbgCmd(buf, 'breakadd func', ['E475: Invalid argument: func']) - call RunDbgCmd(buf, 'breakadd func 2', ['E475: Invalid argument: func 2']) - call RunDbgCmd(buf, 'breaka func a()', ['E475: Invalid argument: func a()']) - call RunDbgCmd(buf, 'breakd abcd', ['E475: Invalid argument: abcd']) - call RunDbgCmd(buf, 'breakd func', ['E475: Invalid argument: func']) - call RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()']) - call RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a']) - call RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr']) - call RunDbgCmd(buf, 'breakd expr x', ['E161: Breakpoint not found: expr x']) + call s:RunDbgCmd(buf, 'breakadd func', ['E475: Invalid argument: func']) + call s:RunDbgCmd(buf, 'breakadd func 2', ['E475: Invalid argument: func 2']) + call s:RunDbgCmd(buf, 'breaka func a()', ['E475: Invalid argument: func a()']) + call s:RunDbgCmd(buf, 'breakd abcd', ['E475: Invalid argument: abcd']) + call s:RunDbgCmd(buf, 'breakd func', ['E475: Invalid argument: func']) + call s:RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()']) + call s:RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a']) + call s:RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr']) + call s:RunDbgCmd(buf, 'breakd expr x', ['E161: Breakpoint not found: expr x']) " finish the current function - call RunDbgCmd(buf, 'finish', [ + call s:RunDbgCmd(buf, 'finish', [ \ 'function Bazz', \ 'line 8: End of function']) - call RunDbgCmd(buf, 'cont') + call s:RunDbgCmd(buf, 'cont') " Test for :next - call RunDbgCmd(buf, ':debug echo Bar(1)') - call RunDbgCmd(buf, 'step') - call RunDbgCmd(buf, 'next') - call RunDbgCmd(buf, '', [ + call s:RunDbgCmd(buf, ':debug echo Bar(1)') + call s:RunDbgCmd(buf, 'step') + call s:RunDbgCmd(buf, 'next') + call s:RunDbgCmd(buf, '', [ \ 'function Bar', \ 'line 3: return var2']) - call RunDbgCmd(buf, 'c') + call s:RunDbgCmd(buf, 'c') " Test for :interrupt - call RunDbgCmd(buf, ':debug echo Bazz(1)') - call RunDbgCmd(buf, 'step') - call RunDbgCmd(buf, 'step') - call RunDbgCmd(buf, 'interrupt', [ + call s:RunDbgCmd(buf, ':debug echo Bazz(1)') + call s:RunDbgCmd(buf, 'step') + call s:RunDbgCmd(buf, 'step') + call s:RunDbgCmd(buf, 'interrupt', [ \ 'Exception thrown: Vim:Interrupt', \ 'function Bazz', \ 'line 5: catch']) - call RunDbgCmd(buf, 'c') + call s:RunDbgCmd(buf, 'c') " Test showing local variable in :def function - call RunDbgCmd(buf, ':breakadd func 2 Vim9Func') - call RunDbgCmd(buf, ':call Vim9Func()', ['line 2: for _ in [1, 2]']) - call RunDbgCmd(buf, 'next', ['line 2: for _ in [1, 2]']) - call RunDbgCmd(buf, 'echo cmd', ['confirm']) - call RunDbgCmd(buf, 'breakdel *') - call RunDbgCmd(buf, 'cont') + call s:RunDbgCmd(buf, ':breakadd func 2 Vim9Func') + call s:RunDbgCmd(buf, ':call Vim9Func()', ['line 2: for _ in [1, 2]']) + call s:RunDbgCmd(buf, 'next', ['line 2: for _ in [1, 2]']) + call s:RunDbgCmd(buf, 'echo cmd', ['confirm']) + call s:RunDbgCmd(buf, 'breakdel *') + call s:RunDbgCmd(buf, 'cont') " Test for :quit - call RunDbgCmd(buf, ':debug echo Foo()') - call RunDbgCmd(buf, 'breakdel *') - call RunDbgCmd(buf, 'breakadd func 3 Foo') - call RunDbgCmd(buf, 'breakadd func 3 Bazz') - call RunDbgCmd(buf, 'cont', [ + call s:RunDbgCmd(buf, ':debug echo Foo()') + call s:RunDbgCmd(buf, 'breakdel *') + call s:RunDbgCmd(buf, 'breakadd func 3 Foo') + call s:RunDbgCmd(buf, 'breakadd func 3 Bazz') + call s:RunDbgCmd(buf, 'cont', [ \ 'Breakpoint in "Bazz" line 3', \ 'function Foo[2]..Bar[2]..Bazz', \ 'line 3: let var3 = "another var"']) - call RunDbgCmd(buf, 'quit', [ + call s:RunDbgCmd(buf, 'quit', [ \ 'Breakpoint in "Foo" line 3', \ 'function Foo', \ 'line 3: return var2']) - call RunDbgCmd(buf, 'breakdel *') - call RunDbgCmd(buf, 'quit') - call RunDbgCmd(buf, 'enew! | only!') + call s:RunDbgCmd(buf, 'breakdel *') + call s:RunDbgCmd(buf, 'quit') + call s:RunDbgCmd(buf, 'enew! | only!') call StopVimInTerminal(buf) endfunc @@ -349,11 +349,11 @@ func Test_Debugger_breakadd() " Start Vim in a terminal let buf = RunVimInTerminal('XdebugBreakadd.vim', {}) - call RunDbgCmd(buf, ':breakadd file 2 XdebugBreakadd.vim') - call RunDbgCmd(buf, ':4 | breakadd here') - call RunDbgCmd(buf, ':source XdebugBreakadd.vim', ['line 2: let var2 = 20']) - call RunDbgCmd(buf, 'cont', ['line 4: let var4 = 40']) - call RunDbgCmd(buf, 'cont') + call s:RunDbgCmd(buf, ':breakadd file 2 XdebugBreakadd.vim') + call s:RunDbgCmd(buf, ':4 | breakadd here') + call s:RunDbgCmd(buf, ':source XdebugBreakadd.vim', ['line 2: let var2 = 20']) + call s:RunDbgCmd(buf, 'cont', ['line 4: let var4 = 40']) + call s:RunDbgCmd(buf, 'cont') call StopVimInTerminal(buf) @@ -364,35 +364,74 @@ func Test_Debugger_breakadd() endfunc " Test for expression breakpoint set using ":breakadd expr <expr>" +" FIXME: This doesn't seem to work as documented. The breakpoint is not +" triggered until the next function call. func Test_Debugger_breakadd_expr() CheckRunVimInTerminal CheckCWD let lines =<< trim END + func Foo() + eval 1 + eval 2 + endfunc + + let g:Xtest_var += 1 + call Foo() let g:Xtest_var += 1 + call Foo() END - call writefile(lines, 'XdebugBreakExpr.vim', 'D') + call writefile(lines, 'XbreakExpr.vim', 'D') " Start Vim in a terminal - let buf = RunVimInTerminal('XdebugBreakExpr.vim', {}) - call RunDbgCmd(buf, ':let g:Xtest_var = 10') - call RunDbgCmd(buf, ':breakadd expr g:Xtest_var') - call RunDbgCmd(buf, ':source %') + let buf = RunVimInTerminal('XbreakExpr.vim', {}) + call s:RunDbgCmd(buf, ':let g:Xtest_var = 10') + call s:RunDbgCmd(buf, ':breakadd expr g:Xtest_var') let expected =<< trim eval END Oldval = "10" Newval = "11" - {fnamemodify('XdebugBreakExpr.vim', ':p')} - line 1: let g:Xtest_var += 1 + {fnamemodify('XbreakExpr.vim', ':p')}[7]..function Foo + line 1: eval 1 END - call RunDbgCmd(buf, ':source %', expected) - call RunDbgCmd(buf, 'cont') + call s:RunDbgCmd(buf, ':source %', expected) let expected =<< trim eval END Oldval = "11" Newval = "12" - {fnamemodify('XdebugBreakExpr.vim', ':p')} - line 1: let g:Xtest_var += 1 + {fnamemodify('XbreakExpr.vim', ':p')}[9]..function Foo + line 1: eval 1 + END + call s:RunDbgCmd(buf, 'cont', expected) + call s:RunDbgCmd(buf, 'cont') + + " Check the behavior without the g: prefix. + " FIXME: The Oldval and Newval don't look right here. + call s:RunDbgCmd(buf, ':breakdel *') + call s:RunDbgCmd(buf, ':breakadd expr Xtest_var') + let expected =<< trim eval END + Oldval = "13" + Newval = "(does not exist)" + {fnamemodify('XbreakExpr.vim', ':p')}[7]..function Foo + line 1: eval 1 + END + call s:RunDbgCmd(buf, ':source %', expected) + let expected =<< trim eval END + {fnamemodify('XbreakExpr.vim', ':p')}[7]..function Foo + line 2: eval 2 + END + call s:RunDbgCmd(buf, 'cont', expected) + let expected =<< trim eval END + Oldval = "14" + Newval = "(does not exist)" + {fnamemodify('XbreakExpr.vim', ':p')}[9]..function Foo + line 1: eval 1 + END + call s:RunDbgCmd(buf, 'cont', expected) + let expected =<< trim eval END + {fnamemodify('XbreakExpr.vim', ':p')}[9]..function Foo + line 2: eval 2 END - call RunDbgCmd(buf, ':source %', expected) + call s:RunDbgCmd(buf, 'cont', expected) + call s:RunDbgCmd(buf, 'cont') call StopVimInTerminal(buf) endfunc @@ -431,19 +470,19 @@ func Test_Backtrace_Through_Source() let buf = RunVimInTerminal('-S Xtest1.vim', {}) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, \ ':debug call GlobalFunction()', \ ['cmd: call GlobalFunction()']) - call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()']) + call s:RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()']) - call RunDbgCmd(buf, 'backtrace', ['>backtrace', + call s:RunDbgCmd(buf, 'backtrace', ['>backtrace', \ '->0 function GlobalFunction', \ 'line 1: call CallAFunction()']) - call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()']) - call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim']) + call s:RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()']) + call s:RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim']) - call RunDbgCmd(buf, 'backtrace', ['>backtrace', + call s:RunDbgCmd(buf, 'backtrace', ['>backtrace', \ ' 2 function GlobalFunction[1]', \ ' 1 CallAFunction[1]', \ '->0 SourceAnotherFile', @@ -451,8 +490,8 @@ func Test_Backtrace_Through_Source() " Step into the 'source' command. Note that we print the full trace all the " way though the source command. - call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'step', ['line 1: func DoAThing()']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 3 function GlobalFunction[1]', \ ' 2 CallAFunction[1]', @@ -460,8 +499,8 @@ func Test_Backtrace_Through_Source() \ '->0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()']) - call RunDbgCmd( buf, 'up' ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'up' ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ ' 3 function GlobalFunction[1]', \ ' 2 CallAFunction[1]', @@ -469,8 +508,8 @@ func Test_Backtrace_Through_Source() \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'up' ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'up' ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ ' 3 function GlobalFunction[1]', \ '->2 CallAFunction[1]', @@ -478,8 +517,8 @@ func Test_Backtrace_Through_Source() \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'up' ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'up' ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ '->3 function GlobalFunction[1]', \ ' 2 CallAFunction[1]', @@ -487,8 +526,8 @@ func Test_Backtrace_Through_Source() \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'up', [ 'frame at highest level: 3' ] ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'up', [ 'frame at highest level: 3' ] ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ '->3 function GlobalFunction[1]', \ ' 2 CallAFunction[1]', @@ -496,8 +535,8 @@ func Test_Backtrace_Through_Source() \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'down' ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'down' ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ ' 3 function GlobalFunction[1]', \ '->2 CallAFunction[1]', @@ -505,8 +544,8 @@ func Test_Backtrace_Through_Source() \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'down' ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'down' ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ ' 3 function GlobalFunction[1]', \ ' 2 CallAFunction[1]', @@ -514,8 +553,8 @@ func Test_Backtrace_Through_Source() \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'down' ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'down' ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ ' 3 function GlobalFunction[1]', \ ' 2 CallAFunction[1]', @@ -523,12 +562,12 @@ func Test_Backtrace_Through_Source() \ '->0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'down', [ 'frame is zero' ] ) + call s:RunDbgCmd( buf, 'down', [ 'frame is zero' ] ) " step until we have another meaningful trace - call RunDbgCmd(buf, 'step', ['line 5: func File2Function()']) - call RunDbgCmd(buf, 'step', ['line 9: call File2Function()']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'step', ['line 5: func File2Function()']) + call s:RunDbgCmd(buf, 'step', ['line 9: call File2Function()']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 3 function GlobalFunction[1]', \ ' 2 CallAFunction[1]', @@ -536,9 +575,9 @@ func Test_Backtrace_Through_Source() \ '->0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 9: call File2Function()']) - call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) - call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) + call s:RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 5 function GlobalFunction[1]', \ ' 4 CallAFunction[1]', @@ -549,19 +588,19 @@ func Test_Backtrace_Through_Source() \ 'line 1: echo "DoAThing"']) " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim - call RunDbgCmd(buf, 'step', ['line 1: End of function']) - call RunDbgCmd(buf, 'step', ['line 1: End of function']) - call RunDbgCmd(buf, 'step', ['line 10: End of sourced file']) - call RunDbgCmd(buf, 'step', ['line 1: End of function']) - call RunDbgCmd(buf, 'step', ['line 2: call File2Function()']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'step', ['line 1: End of function']) + call s:RunDbgCmd(buf, 'step', ['line 1: End of function']) + call s:RunDbgCmd(buf, 'step', ['line 10: End of sourced file']) + call s:RunDbgCmd(buf, 'step', ['line 1: End of function']) + call s:RunDbgCmd(buf, 'step', ['line 2: call File2Function()']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 1 function GlobalFunction[1]', \ '->0 CallAFunction', \ 'line 2: call File2Function()']) - call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 2 function GlobalFunction[1]', \ ' 1 CallAFunction[2]', @@ -607,29 +646,29 @@ func Test_Backtrace_Autocmd() let buf = RunVimInTerminal('-S Xtest1.vim', {}) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, \ ':debug doautocmd User TestGlobalFunction', \ ['cmd: doautocmd User TestGlobalFunction']) - call RunDbgCmd(buf, 'step', ['cmd: call GlobalFunction() | echo "Done"']) + call s:RunDbgCmd(buf, 'step', ['cmd: call GlobalFunction() | echo "Done"']) " At this point the only thing in the stack is the autocommand - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ '->0 User Autocommands for "TestGlobalFunction"', \ 'cmd: call GlobalFunction() | echo "Done"']) " And now we're back into the call stack - call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 1 User Autocommands for "TestGlobalFunction"', \ '->0 function GlobalFunction', \ 'line 1: call CallAFunction()']) - call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()']) - call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim']) + call s:RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()']) + call s:RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 3 User Autocommands for "TestGlobalFunction"', \ ' 2 function GlobalFunction[1]', @@ -639,8 +678,8 @@ func Test_Backtrace_Autocmd() " Step into the 'source' command. Note that we print the full trace all the " way though the source command. - call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'step', ['line 1: func DoAThing()']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 4 User Autocommands for "TestGlobalFunction"', \ ' 3 function GlobalFunction[1]', @@ -649,8 +688,8 @@ func Test_Backtrace_Autocmd() \ '->0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()']) - call RunDbgCmd( buf, 'up' ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'up' ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ ' 4 User Autocommands for "TestGlobalFunction"', \ ' 3 function GlobalFunction[1]', @@ -659,8 +698,8 @@ func Test_Backtrace_Autocmd() \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'up' ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'up' ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ ' 4 User Autocommands for "TestGlobalFunction"', \ ' 3 function GlobalFunction[1]', @@ -669,8 +708,8 @@ func Test_Backtrace_Autocmd() \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'up' ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'up' ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ ' 4 User Autocommands for "TestGlobalFunction"', \ '->3 function GlobalFunction[1]', @@ -679,8 +718,8 @@ func Test_Backtrace_Autocmd() \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'up' ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'up' ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ '->4 User Autocommands for "TestGlobalFunction"', \ ' 3 function GlobalFunction[1]', @@ -689,8 +728,8 @@ func Test_Backtrace_Autocmd() \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'up', [ 'frame at highest level: 4' ] ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'up', [ 'frame at highest level: 4' ] ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ '->4 User Autocommands for "TestGlobalFunction"', \ ' 3 function GlobalFunction[1]', @@ -699,8 +738,8 @@ func Test_Backtrace_Autocmd() \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'down' ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'down' ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ ' 4 User Autocommands for "TestGlobalFunction"', \ '->3 function GlobalFunction[1]', @@ -710,8 +749,8 @@ func Test_Backtrace_Autocmd() \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'down' ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'down' ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ ' 4 User Autocommands for "TestGlobalFunction"', \ ' 3 function GlobalFunction[1]', @@ -720,8 +759,8 @@ func Test_Backtrace_Autocmd() \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'down' ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'down' ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ ' 4 User Autocommands for "TestGlobalFunction"', \ ' 3 function GlobalFunction[1]', @@ -730,8 +769,8 @@ func Test_Backtrace_Autocmd() \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'down' ) - call RunDbgCmd( buf, 'backtrace', [ + call s:RunDbgCmd( buf, 'down' ) + call s:RunDbgCmd( buf, 'backtrace', [ \ '>backtrace', \ ' 4 User Autocommands for "TestGlobalFunction"', \ ' 3 function GlobalFunction[1]', @@ -740,12 +779,12 @@ func Test_Backtrace_Autocmd() \ '->0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 1: func DoAThing()' ] ) - call RunDbgCmd( buf, 'down', [ 'frame is zero' ] ) + call s:RunDbgCmd( buf, 'down', [ 'frame is zero' ] ) " step until we have another meaningful trace - call RunDbgCmd(buf, 'step', ['line 5: func File2Function()']) - call RunDbgCmd(buf, 'step', ['line 9: call File2Function()']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'step', ['line 5: func File2Function()']) + call s:RunDbgCmd(buf, 'step', ['line 9: call File2Function()']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 4 User Autocommands for "TestGlobalFunction"', \ ' 3 function GlobalFunction[1]', @@ -754,9 +793,9 @@ func Test_Backtrace_Autocmd() \ '->0 script ' .. getcwd() .. '/Xtest2.vim', \ 'line 9: call File2Function()']) - call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) - call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) + call s:RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 6 User Autocommands for "TestGlobalFunction"', \ ' 5 function GlobalFunction[1]', @@ -768,20 +807,20 @@ func Test_Backtrace_Autocmd() \ 'line 1: echo "DoAThing"']) " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim - call RunDbgCmd(buf, 'step', ['line 1: End of function']) - call RunDbgCmd(buf, 'step', ['line 1: End of function']) - call RunDbgCmd(buf, 'step', ['line 10: End of sourced file']) - call RunDbgCmd(buf, 'step', ['line 1: End of function']) - call RunDbgCmd(buf, 'step', ['line 2: call File2Function()']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'step', ['line 1: End of function']) + call s:RunDbgCmd(buf, 'step', ['line 1: End of function']) + call s:RunDbgCmd(buf, 'step', ['line 10: End of sourced file']) + call s:RunDbgCmd(buf, 'step', ['line 1: End of function']) + call s:RunDbgCmd(buf, 'step', ['line 2: call File2Function()']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 2 User Autocommands for "TestGlobalFunction"', \ ' 1 function GlobalFunction[1]', \ '->0 CallAFunction', \ 'line 2: call File2Function()']) - call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 3 User Autocommands for "TestGlobalFunction"', \ ' 2 function GlobalFunction[1]', @@ -792,8 +831,8 @@ func Test_Backtrace_Autocmd() " Now unwind so that we get back to the original autocommand (and the second " cmd echo "Done") - call RunDbgCmd(buf, 'finish', ['line 1: End of function']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'finish', ['line 1: End of function']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 3 User Autocommands for "TestGlobalFunction"', \ ' 2 function GlobalFunction[1]', @@ -801,23 +840,23 @@ func Test_Backtrace_Autocmd() \ '->0 File2Function', \ 'line 1: End of function']) - call RunDbgCmd(buf, 'finish', ['line 2: End of function']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'finish', ['line 2: End of function']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 2 User Autocommands for "TestGlobalFunction"', \ ' 1 function GlobalFunction[1]', \ '->0 CallAFunction', \ 'line 2: End of function']) - call RunDbgCmd(buf, 'finish', ['line 1: End of function']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'finish', ['line 1: End of function']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 1 User Autocommands for "TestGlobalFunction"', \ '->0 function GlobalFunction', \ 'line 1: End of function']) - call RunDbgCmd(buf, 'step', ['cmd: echo "Done"']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'step', ['cmd: echo "Done"']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ '->0 User Autocommands for "TestGlobalFunction"', \ 'cmd: echo "Done"']) @@ -869,14 +908,14 @@ func Test_Backtrace_CmdLine() \ 'cmd: call GlobalFunction()'], #{msec: 5000}) " At this point the only thing in the stack is the cmdline - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ '->0 command line', \ 'cmd: call GlobalFunction()']) " And now we're back into the call stack - call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '>backtrace', \ ' 1 command line', \ '->0 function GlobalFunction', @@ -930,33 +969,32 @@ func Test_Backtrace_DefFunction() let buf = RunVimInTerminal('-S Xtest1.vim', {}) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, \ ':debug call GlobalFunction()', \ ['cmd: call GlobalFunction()']) - call RunDbgCmd(buf, 'step', ['line 1: var some = "some var"']) - call RunDbgCmd(buf, 'step', ['line 2: CallAFunction()']) - call RunDbgCmd(buf, 'echo some', ['some var']) + call s:RunDbgCmd(buf, 'step', ['line 1: var some = "some var"']) + call s:RunDbgCmd(buf, 'step', ['line 2: CallAFunction()']) + call s:RunDbgCmd(buf, 'echo some', ['some var']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'backtrace', [ \ '\V>backtrace', \ '\V->0 function GlobalFunction', \ '\Vline 2: CallAFunction()', \ ], \ #{match: 'pattern'}) - call RunDbgCmd(buf, 'step', ['line 1: SourceAnotherFile()']) - call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim']) + call s:RunDbgCmd(buf, 'step', ['line 1: SourceAnotherFile()']) + call s:RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim']) " Repeated line, because we fist are in the compiled function before the " EXEC and then in do_cmdline() before the :source command. - call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim']) - call RunDbgCmd(buf, 'step', ['line 1: vim9script']) - call RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number']) - call RunDbgCmd(buf, 'step', ['line 9: export def File2Function()']) - call RunDbgCmd(buf, 'step', ['line 9: def File2Function()']) - call RunDbgCmd(buf, 'step', ['line 13: defcompile']) - call RunDbgCmd(buf, 'step', ['line 14: File2Function()']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim']) + call s:RunDbgCmd(buf, 'step', ['line 1: vim9script']) + call s:RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number']) + call s:RunDbgCmd(buf, 'step', ['line 9: export def File2Function()']) + call s:RunDbgCmd(buf, 'step', ['line 13: defcompile']) + call s:RunDbgCmd(buf, 'step', ['line 14: File2Function()']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '\V>backtrace', \ '\V 3 function GlobalFunction[2]', \ '\V 2 <SNR>\.\*_CallAFunction[1]', @@ -966,8 +1004,8 @@ func Test_Backtrace_DefFunction() \ #{match: 'pattern'}) " Don't step into compiled functions... - call RunDbgCmd(buf, 'next', ['line 15: End of sourced file']) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'next', ['line 15: End of sourced file']) + call s:RunDbgCmd(buf, 'backtrace', [ \ '\V>backtrace', \ '\V 3 function GlobalFunction[2]', \ '\V 2 <SNR>\.\*_CallAFunction[1]', @@ -994,8 +1032,8 @@ func Test_DefFunction_expr() call writefile(file3, 'Xtest3.vim', 'D') let buf = RunVimInTerminal('-S Xtest3.vim', {}) - call RunDbgCmd(buf, ':breakadd expr g:someVar') - call RunDbgCmd(buf, ':call g:ChangeVar()', ['Oldval = "''foo''"', 'Newval = "''bar''"', 'function ChangeVar', 'line 2: echo "changed"']) + call s:RunDbgCmd(buf, ':breakadd expr g:someVar') + call s:RunDbgCmd(buf, ':call g:ChangeVar()', ['Oldval = "''foo''"', 'Newval = "''bar''"', 'function ChangeVar', 'line 2: echo "changed"']) call StopVimInTerminal(buf) endfunc @@ -1031,17 +1069,17 @@ func Test_debug_def_and_legacy_function() let buf = RunVimInTerminal('-S XtestDebug.vim', {}) - call RunDbgCmd(buf,':call SomeFunc()', ['line 2: echo "and"']) - call RunDbgCmd(buf,'next', ['line 3: echo "there"']) - call RunDbgCmd(buf,'next', ['line 4: breakadd func 2 LocalFunc']) + call s:RunDbgCmd(buf,':call SomeFunc()', ['line 2: echo "and"']) + call s:RunDbgCmd(buf,'next', ['line 3: echo "there"']) + call s:RunDbgCmd(buf,'next', ['line 4: breakadd func 2 LocalFunc']) " continue, next breakpoint is in LocalFunc() - call RunDbgCmd(buf,'cont', ['line 2: echo "second"']) + call s:RunDbgCmd(buf,'cont', ['line 2: echo "second"']) " continue, next breakpoint is in LegacyFunc() - call RunDbgCmd(buf,'cont', ['line 1: echo "legone"']) + call s:RunDbgCmd(buf,'cont', ['line 1: echo "legone"']) - call RunDbgCmd(buf, 'cont') + call s:RunDbgCmd(buf, 'cont') call StopVimInTerminal(buf) endfunc @@ -1104,68 +1142,68 @@ func Test_debug_def_function() let buf = RunVimInTerminal('-S Xtest.vim', {}) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, \ ':debug call Func()', \ ['cmd: call Func()']) - call RunDbgCmd(buf, 'next', ['result: 3']) + call s:RunDbgCmd(buf, 'next', ['result: 3']) call term_sendkeys(buf, "\r") - call RunDbgCmd(buf, 'cont') + call s:RunDbgCmd(buf, 'cont') - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, \ ':debug call FuncWithArgs("asdf", 42, 1, 2, 3)', \ ['cmd: call FuncWithArgs("asdf", 42, 1, 2, 3)']) - call RunDbgCmd(buf, 'step', ['line 1: echo text .. nr']) - call RunDbgCmd(buf, 'echo text', ['asdf']) - call RunDbgCmd(buf, 'echo nr', ['42']) - call RunDbgCmd(buf, 'echo items', ['[1, 2, 3]']) - call RunDbgCmd(buf, 'step', ['asdf42', 'function FuncWithArgs', 'line 2: for it in items']) - call RunDbgCmd(buf, 'step', ['function FuncWithArgs', 'line 2: for it in items']) - call RunDbgCmd(buf, 'echo it', ['0']) - call RunDbgCmd(buf, 'step', ['line 3: echo it']) - call RunDbgCmd(buf, 'echo it', ['1']) - call RunDbgCmd(buf, 'step', ['1', 'function FuncWithArgs', 'line 4: endfor']) - call RunDbgCmd(buf, 'step', ['line 2: for it in items']) - call RunDbgCmd(buf, 'echo it', ['1']) - call RunDbgCmd(buf, 'step', ['line 3: echo it']) - call RunDbgCmd(buf, 'step', ['2', 'function FuncWithArgs', 'line 4: endfor']) - call RunDbgCmd(buf, 'step', ['line 2: for it in items']) - call RunDbgCmd(buf, 'echo it', ['2']) - call RunDbgCmd(buf, 'step', ['line 3: echo it']) - call RunDbgCmd(buf, 'step', ['3', 'function FuncWithArgs', 'line 4: endfor']) - call RunDbgCmd(buf, 'step', ['line 2: for it in items']) - call RunDbgCmd(buf, 'step', ['line 5: echo "done"']) - call RunDbgCmd(buf, 'cont') - - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, 'step', ['line 1: echo text .. nr']) + call s:RunDbgCmd(buf, 'echo text', ['asdf']) + call s:RunDbgCmd(buf, 'echo nr', ['42']) + call s:RunDbgCmd(buf, 'echo items', ['[1, 2, 3]']) + call s:RunDbgCmd(buf, 'step', ['asdf42', 'function FuncWithArgs', 'line 2: for it in items']) + call s:RunDbgCmd(buf, 'step', ['function FuncWithArgs', 'line 2: for it in items']) + call s:RunDbgCmd(buf, 'echo it', ['0']) + call s:RunDbgCmd(buf, 'step', ['line 3: echo it']) + call s:RunDbgCmd(buf, 'echo it', ['1']) + call s:RunDbgCmd(buf, 'step', ['1', 'function FuncWithArgs', 'line 4: endfor']) + call s:RunDbgCmd(buf, 'step', ['line 2: for it in items']) + call s:RunDbgCmd(buf, 'echo it', ['1']) + call s:RunDbgCmd(buf, 'step', ['line 3: echo it']) + call s:RunDbgCmd(buf, 'step', ['2', 'function FuncWithArgs', 'line 4: endfor']) + call s:RunDbgCmd(buf, 'step', ['line 2: for it in items']) + call s:RunDbgCmd(buf, 'echo it', ['2']) + call s:RunDbgCmd(buf, 'step', ['line 3: echo it']) + call s:RunDbgCmd(buf, 'step', ['3', 'function FuncWithArgs', 'line 4: endfor']) + call s:RunDbgCmd(buf, 'step', ['line 2: for it in items']) + call s:RunDbgCmd(buf, 'step', ['line 5: echo "done"']) + call s:RunDbgCmd(buf, 'cont') + + call s:RunDbgCmd(buf, \ ':debug call FuncWithDict()', \ ['cmd: call FuncWithDict()']) - call RunDbgCmd(buf, 'step', ['line 1: var d = { a: 1, b: 2, }']) - call RunDbgCmd(buf, 'step', ['line 6: def Inner()']) - call RunDbgCmd(buf, 'cont') - - call RunDbgCmd(buf, ':breakadd func 1 FuncComment') - call RunDbgCmd(buf, ':call FuncComment()', ['function FuncComment', 'line 2: echo "first" .. "one"']) - call RunDbgCmd(buf, ':breakadd func 3 FuncComment') - call RunDbgCmd(buf, 'cont', ['function FuncComment', 'line 5: echo "second"']) - call RunDbgCmd(buf, 'cont') - - call RunDbgCmd(buf, ':breakadd func 2 FuncForLoop') - call RunDbgCmd(buf, ':call FuncForLoop()', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]']) - call RunDbgCmd(buf, 'step', ['line 2: for i in [11, 22, 33]']) - call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 3: eval i + 2']) - call RunDbgCmd(buf, 'echo i', ['11']) - call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 4: endfor']) - call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]']) - call RunDbgCmd(buf, 'next', ['line 3: eval i + 2']) - call RunDbgCmd(buf, 'echo i', ['22']) - - call RunDbgCmd(buf, 'breakdel *') - call RunDbgCmd(buf, 'cont') - - call RunDbgCmd(buf, ':breakadd func FuncWithSplitLine') - call RunDbgCmd(buf, ':call FuncWithSplitLine()', ['function FuncWithSplitLine', 'line 1: eval 1 + 2 | eval 2 + 3']) - - call RunDbgCmd(buf, 'cont') + call s:RunDbgCmd(buf, 'step', ['line 1: var d = { a: 1, b: 2, }']) + call s:RunDbgCmd(buf, 'step', ['line 6: def Inner()']) + call s:RunDbgCmd(buf, 'cont') + + call s:RunDbgCmd(buf, ':breakadd func 1 FuncComment') + call s:RunDbgCmd(buf, ':call FuncComment()', ['function FuncComment', 'line 2: echo "first" .. "one"']) + call s:RunDbgCmd(buf, ':breakadd func 3 FuncComment') + call s:RunDbgCmd(buf, 'cont', ['function FuncComment', 'line 5: echo "second"']) + call s:RunDbgCmd(buf, 'cont') + + call s:RunDbgCmd(buf, ':breakadd func 2 FuncForLoop') + call s:RunDbgCmd(buf, ':call FuncForLoop()', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]']) + call s:RunDbgCmd(buf, 'step', ['line 2: for i in [11, 22, 33]']) + call s:RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 3: eval i + 2']) + call s:RunDbgCmd(buf, 'echo i', ['11']) + call s:RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 4: endfor']) + call s:RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]']) + call s:RunDbgCmd(buf, 'next', ['line 3: eval i + 2']) + call s:RunDbgCmd(buf, 'echo i', ['22']) + + call s:RunDbgCmd(buf, 'breakdel *') + call s:RunDbgCmd(buf, 'cont') + + call s:RunDbgCmd(buf, ':breakadd func FuncWithSplitLine') + call s:RunDbgCmd(buf, ':call FuncWithSplitLine()', ['function FuncWithSplitLine', 'line 1: eval 1 + 2 | eval 2 + 3']) + + call s:RunDbgCmd(buf, 'cont') call StopVimInTerminal(buf) endfunc @@ -1185,14 +1223,14 @@ func Test_debug_def_function_with_lambda() let buf = RunVimInTerminal('-S XtestLambda.vim', {}) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, \ ':call g:Func()', \ ['function Func', 'line 2: [''b'']->map((_, v) => s)']) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, \ 'next', \ ['function Func', 'line 3: echo "done"']) - call RunDbgCmd(buf, 'cont') + call s:RunDbgCmd(buf, 'cont') call StopVimInTerminal(buf) endfunc @@ -1243,30 +1281,30 @@ func Test_debug_backtrace_level() \ ], #{msec: 5000}) " step through the initial declarations - call RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] ) - call RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] ) - call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] ) - call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] ) - call RunDbgCmd(buf, 'echo global_var', [ 'global' ] ) + call s:RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] ) + call s:RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] ) + call s:RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] ) + call s:RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] ) + call s:RunDbgCmd(buf, 'echo global_var', [ 'global' ] ) " step in to the first function - call RunDbgCmd(buf, 'step', [ 'line 11: call s:File1Func( ''arg1'' )' ] ) - call RunDbgCmd(buf, 'step', [ 'line 1: let s:file1_var .= a:arg' ] ) - call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] ) - call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] ) - call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] ) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, 'step', [ 'line 11: call s:File1Func( ''arg1'' )' ] ) + call s:RunDbgCmd(buf, 'step', [ 'line 1: let s:file1_var .= a:arg' ] ) + call s:RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] ) + call s:RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] ) + call s:RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] ) + call s:RunDbgCmd(buf, \'echo global_var', \[ 'E121: Undefined variable: global_var' ] ) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, \'echo local_var', \[ 'E121: Undefined variable: local_var' ] ) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, \'echo l:local_var', \[ 'E121: Undefined variable: l:local_var' ] ) " backtrace up - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'backtrace', [ \ '\V>backtrace', \ '\V 2 command line', \ '\V 1 script ' .. file1 .. '[11]', @@ -1274,9 +1312,9 @@ func Test_debug_backtrace_level() \ '\Vline 1: let s:file1_var .= a:arg', \ ], \ #{ match: 'pattern' } ) - call RunDbgCmd(buf, 'up', [ '>up' ] ) + call s:RunDbgCmd(buf, 'up', [ '>up' ] ) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'backtrace', [ \ '\V>backtrace', \ '\V 2 command line', \ '\V->1 script ' .. file1 .. '[11]', @@ -1287,25 +1325,25 @@ func Test_debug_backtrace_level() " Expression evaluation in the script frame (not the function frame) " FIXME: Unexpected in this scope (a: should not be visible) - call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] ) - call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] ) - call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] ) + call s:RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] ) + call s:RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] ) + call s:RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] ) " FIXME: Unexpected in this scope (global should be found) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, \'echo global_var', \[ 'E121: Undefined variable: global_var' ] ) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, \'echo local_var', \[ 'E121: Undefined variable: local_var' ] ) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, \'echo l:local_var', \[ 'E121: Undefined variable: l:local_var' ] ) " step while backtraced jumps to the latest frame - call RunDbgCmd(buf, 'step', [ + call s:RunDbgCmd(buf, 'step', [ \ 'line 2: let local_var = s:file1_var .. '' test1''' ] ) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'backtrace', [ \ '\V>backtrace', \ '\V 2 command line', \ '\V 1 script ' .. file1 .. '[11]', @@ -1314,13 +1352,13 @@ func Test_debug_backtrace_level() \ ], \ #{ match: 'pattern' } ) - call RunDbgCmd(buf, 'step', [ 'line 3: let g:global_var .= local_var' ] ) - call RunDbgCmd(buf, 'echo local_var', [ 'file1arg1 test1' ] ) - call RunDbgCmd(buf, 'echo l:local_var', [ 'file1arg1 test1' ] ) + call s:RunDbgCmd(buf, 'step', [ 'line 3: let g:global_var .= local_var' ] ) + call s:RunDbgCmd(buf, 'echo local_var', [ 'file1arg1 test1' ] ) + call s:RunDbgCmd(buf, 'echo l:local_var', [ 'file1arg1 test1' ] ) - call RunDbgCmd(buf, 'step', [ 'line 4: source Xtest2.vim' ] ) - call RunDbgCmd(buf, 'step', [ 'line 1: let s:file2_var = ''file2''' ] ) - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'step', [ 'line 4: source Xtest2.vim' ] ) + call s:RunDbgCmd(buf, 'step', [ 'line 1: let s:file2_var = ''file2''' ] ) + call s:RunDbgCmd(buf, 'backtrace', [ \ '\V>backtrace', \ '\V 3 command line', \ '\V 2 script ' .. file1 .. '[11]', @@ -1331,28 +1369,28 @@ func Test_debug_backtrace_level() \ #{ match: 'pattern' } ) " Expression evaluation in the script frame file2 (not the function frame) - call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] ) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] ) + call s:RunDbgCmd(buf, \ 'echo s:file1_var', \ [ 'E121: Undefined variable: s:file1_var' ] ) - call RunDbgCmd(buf, 'echo g:global_var', [ 'globalfile1arg1 test1' ] ) - call RunDbgCmd(buf, 'echo global_var', [ 'globalfile1arg1 test1' ] ) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, 'echo g:global_var', [ 'globalfile1arg1 test1' ] ) + call s:RunDbgCmd(buf, 'echo global_var', [ 'globalfile1arg1 test1' ] ) + call s:RunDbgCmd(buf, \'echo local_var', \[ 'E121: Undefined variable: local_var' ] ) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, \'echo l:local_var', \[ 'E121: Undefined variable: l:local_var' ] ) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, \ 'echo s:file2_var', \ [ 'E121: Undefined variable: s:file2_var' ] ) - call RunDbgCmd(buf, 'step', [ 'line 3: func s:File2Func( arg )' ] ) - call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] ) + call s:RunDbgCmd(buf, 'step', [ 'line 3: func s:File2Func( arg )' ] ) + call s:RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] ) " Up the stack to the other script context - call RunDbgCmd(buf, 'up') - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'up') + call s:RunDbgCmd(buf, 'backtrace', [ \ '\V>backtrace', \ '\V 3 command line', \ '\V 2 script ' .. file1 .. '[11]', @@ -1362,13 +1400,13 @@ func Test_debug_backtrace_level() \ ], \ #{ match: 'pattern' } ) " FIXME: Unexpected. Should see the a: and l: dicts from File1Func - call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] ) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] ) + call s:RunDbgCmd(buf, \ 'echo l:local_var', \ [ 'E121: Undefined variable: l:local_var' ] ) - call RunDbgCmd(buf, 'up') - call RunDbgCmd(buf, 'backtrace', [ + call s:RunDbgCmd(buf, 'up') + call s:RunDbgCmd(buf, 'backtrace', [ \ '\V>backtrace', \ '\V 3 command line', \ '\V->2 script ' .. file1 .. '[11]', @@ -1379,12 +1417,12 @@ func Test_debug_backtrace_level() \ #{ match: 'pattern' } ) " FIXME: Unexpected (wrong script vars are used) - call RunDbgCmd(buf, + call s:RunDbgCmd(buf, \ 'echo s:file1_var', \ [ 'E121: Undefined variable: s:file1_var' ] ) - call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] ) + call s:RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] ) - call RunDbgCmd(buf, 'cont') + call s:RunDbgCmd(buf, 'cont') call StopVimInTerminal(buf) endfunc