In the middle of a debug session can be nice to see current line: (this is for function but something for scripts can be done too)
function! ListFuncLines(func, lnum, context = 10) abort
" Capture verbose output
redir => l:out
silent execute 'verbose function ' . a:func
redir END
if empty(l:out)
echoerr "ListFuncLines: no output from ':verbose function " . a:func . "'"
return
endif
let l:lines = split(l:out, "\n")
let llines = len(l:lines)
let l:res = []
let start = max([a:lnum - a:context, 0])
let end = min([llines, a:lnum + a:context])
for l in range(start, end )
if l == a:lnum + 1
echohl ErrorMsg
endif
echo l:lines[l]
if l == a:lnum + 1
echohl None
endif
endfor
endfunction
this provides similar feature as list on gdb.
to ease usage, get current context and apply directly can be helpful. for that you need to inspect where
or bt
>let out=''
>redir => out
>where
2 BufRead Auto-órdenes para "*"
1 function <SNR>85_maybe_build_folds[9]
->0 <SNR>85_build_fold_data
line 64: where | redir END
>redir END
>echo out
2 BufRead Auto-órdenes para "*"
1 function <SNR>85_maybe_build_folds[9]
->0 <SNR>85_build_fold_data
line 64: where | redir END
>
but you cannot retrieve this output outside debug scope: like in a function.
The simplest way to show the error:
>let out = '' | redir => out | where | redir END | echo out
Error detected while processing BufRead Autocommands for "*"..function <SNR>85_maybe_build_folds[9]..<SNR>85_build_fold_data:
line 64:
E492: Not an editor command: where | redir END | echo out
>
once output is captured, you can parse it:
function! s:script_path_by_number(num) abort
for line in split(execute('scriptnames'), "\n")
let m = matchlist(line, '^\s*' . a:num . ':\s\+\(.*\)$')
if len(m)
return m[1]
endif
endfor
return ''
endfunction
function! GetWhereCurrentFrame(bt) abort
" Capture :where output
let l:out = a:bt
"redir => l:out
" debug where
"redir END
if empty(l:out)
echo "empty lines"
return {}
endif
let lines = split(l:out, "\n")
let n = len(lines)
" Find the line starting with '->' (current frame)
let idx = -1
for i in range(0, n - 1)
if lines[i] =~# '^\s*->'
let idx = i
break
endif
endfor
if idx == -1
return {}
endif
let funcline = lines[idx]
" Try to extract script-local <SNR>NN_name
let m = matchlist(funcline, '<SNR>\(\d\+\)_\(\S\+\)')
if len(m)
let scriptnum = str2nr(m[1])
let funcname = '<SNR>' . m[1] . '_' . m[2]
else
" fallback: extract the token after the arrow (->0 NAME) or after 'function'
let m2 = matchlist(funcline, '->\s*\d\+\s\+\(\S\+\)')
if len(m2)
let funcname = m2[1]
else
" last resort: trim arrow and whitespace
let funcname = substitute(funcline, '^\s*->\s*', '', '')
endif
let scriptnum = -1
endif
" Look for a following "line N: ..." or 'line N of "file"' entry within a few lines
let lnum = -1
let code = ''
let fname = ''
for j in range(idx + 1, min([n - 1, idx + 6]))
let l = lines[j]
let m1 = matchlist(l, '^\s*line\s\+\(\d\+\):\s*\(.*\)$')
if len(m1)
let lnum = str2nr(m1[1])
let code = m1[2]
break
endif
let m2 = matchlist(l, 'line\s\+\(\d\+\)\s\+of\s\+"\([^"]\+\)"')
if len(m2)
let lnum = str2nr(m2[1])
let fname = m2[2]
break
endif
endfor
" If we have a script number but no filename, map scriptnum -> path via :scriptnames
if fname ==# '' && scriptnum > 0
let fname = s:script_path_by_number(scriptnum)
endif
return {
\ 'func': funcname,
\ 'scriptnum': scriptnum,
\ 'fname': fname,
\ 'lnum': lnum,
\ 'code': code,
\ 'funcline': funcline,
\ 'verbose_lines': lines,
\ }
endfunction
getting as result (output indented for better view):
>echo GetWhereCurrentFrame(out)
{
'lnum': 64,
'scriptnum': 85,
'func': '<SNR>85_build_fold_data',
'code': 'while !empty(stack)',
'verbose_lines': [
' 2 BufRead Autocommands for "*"',
' 1 function <SNR>85_maybe_build_folds[9]',
'->0 <SNR>85_build_fold_data',
'line 64: while !empty(stack)'
],
'fname': '~/.vim/plugged/vim-tree-sitter/plugin/ts_helper.vim',
'funcline': '->0 <SNR>85_build_fold_data'
}
Is it possible to provide output from do_backtrace
in a function call (getcallstack
get_backtrace
) avoiding too parsing
or at least allow where
or backtrace
to detect where they are inside a debug session to avoid error E492
?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.