获取调用vim自动加载函数的文件名和行号
我正在尝试使用自动加载功能填充快速修复列表,即:获取调用vim自动加载函数的文件名和行号,vim,trace,autoload,Vim,Trace,Autoload,我正在尝试使用自动加载功能填充快速修复列表,即: function! myplugin#myfunc(msg) " this doesn't work from *inside* an autoload function let filename = fnamemodify(resolve(expand('<sfile>:p'))) " not sure if it's possible to get the line number from where " a
function! myplugin#myfunc(msg)
" this doesn't work from *inside* an autoload function
let filename = fnamemodify(resolve(expand('<sfile>:p')))
" not sure if it's possible to get the line number from where
" a function was called
let linenum = '?#'
" create qf dict object
" set filename, line number, bufnr, text, etc
" add dict to qflist
" setqflist(qfdictlist)
endfunction!
函数!myplugin#myfunc(msg)
“自动加载功能*内部*不起作用
让filename=fnamemodify(解析(展开(':p'))
“不确定是否可以从何处获取行号
“调用了一个函数
设linenum='?#'
“创建qf dict对象
设置文件名、行号、bufnr、文本等
“将dict添加到列表中
“设置QFLIST(qfdictlist)
结束函数!
我遇到的问题是,我无法从调用自动加载函数的代码中找到文件名和行号。有什么建议吗?开箱即用。这是不可能的 然而,根据具体情况,这里有一些线索
- 我试图编写一个函数,在捕获异常时从
解码调用堆栈。它仍然是实验性的。请参阅v:throwpoint
- 通过我的测试,我准确地知道哪个测试文件/行失败。为此,我必须解析UT文件,以便将调用者的行号插入到
命令中:Assert*
v:throwpoint
之外,调用堆栈不可用。唯一的其他解决方案是让调用者插入他们的引用(~\uuuu FILE\uuu
+~\uline\uu
)当调用时,唯一的自动化方法是将调用方脚本编译成另一个脚本,自动注入缺少的信息
到目前为止,了解上个月在vim dev邮件列表上有一个提议,以允许访问调用堆栈,但遗憾的是,只有在调试会话期间:
如果这一点被接受,它可能会在以后进行扩展,以提供一个viml函数来导出此信息
编辑:你的问题启发我为vim写了一篇文章:
它使用我的另一个函数来解码调用堆栈。开箱即用。这是不可能的 然而,根据具体情况,这里有一些线索
- 我试图编写一个函数,在捕获异常时从
解码调用堆栈。它仍然是实验性的。请参阅v:throwpoint
- 通过我的测试,我准确地知道哪个测试文件/行失败。为此,我必须解析UT文件,以便将调用者的行号插入到
命令中:Assert*
v:throwpoint
之外,调用堆栈不可用。唯一的其他解决方案是让调用者插入他们的引用(~\uuuu FILE\uuu
+~\uline\uu
)当调用时,唯一的自动化方法是将调用方脚本编译成另一个脚本,自动注入缺少的信息
到目前为止,了解上个月在vim dev邮件列表上有一个提议,以允许访问调用堆栈,但遗憾的是,只有在调试会话期间:
如果这一点被接受,它可能会在以后进行扩展,以提供一个viml函数来导出此信息
编辑:你的问题启发我为vim写了一篇文章:
它使用我的另一个函数来解码调用堆栈。好吧,如果你不能从自动加载函数中获取文件和行,你必须将其传递到你的函数中 通过自定义映射、命令或在
:autocmd
事件上以某种方式调用您的自动加载函数。从那里,您可以解析当前文件(展开(“%”)
和行号('line('))
)并将其传入
但是为什么你需要它?!对于正常的编辑任务,我无法想象为什么。如果你正在编写一个自定义的Vim调试插件,好吧,那可能会很有用。但是通过Vimscript调试是困难的(正如你所发现的),调用堆栈没有公开。最好使用内置的
:debug
和:breakadd
;到目前为止,我发现它们已经足够了。如果无法从自动加载函数中获取文件和行,则必须将其传递到函数中
通过自定义映射、命令或在:autocmd
事件上以某种方式调用您的自动加载函数。从那里,您可以解析当前文件(展开(“%”)
和行号('line('))
)并将其传入
但是为什么你需要它?!对于正常的编辑任务,我无法想象为什么。如果你正在编写一个自定义的Vim调试插件,好吧,那可能会很有用。但是通过Vimscript调试是困难的(正如你所发现的),调用堆栈没有公开。最好使用内置的
:debug
和:breakadd
;到目前为止,我发现它们已经足够了。什么是自动加载函数?好的,你的意思是自动加载脚本…我以为你在寻找某个函数,以便在触发某个事件时自动加载某个文件…你在寻找expand(“”)吗
?什么是自动加载功能?好的,你指的是自动加载脚本…我以为你在寻找某个函数,以便在触发某个事件时自动加载某个文件…你在寻找扩展(“”)
?作为一项学习练习,我一直在尝试一个“日志”插件——因为我认为它可能是有趣和/或潜在有用的东西(至少对我来说).Write now我用数组填充了一个缓冲区,但意识到最好利用quickfix并能够直接跳到消息生成的位置。我一直在尝试一个“日志”插件作为学习练习,因为我认为它可能会很有趣和/或潜在有用(至少对我来说是这样)。写现在我用数组填充缓冲区,但我意识到
" Function: lh#log#new(where, kind) {{{3
" - where: "vert"/""/...
" - kind: "qf"/"loc" for loclist
" NOTE: In order to obtain the name of the calling function, an exception is
" thrown and the backtrace is analysed.
" In order to work, this trick requires:
" - a reasonable callstack size (past a point, vim shortens the names returned
" by v:throwpoint
" - named functions ; i.e. functions defined on dictionaries (and not attached
" to them) will have their names mangled (actually it'll be a number) and
" lh#exception#callstack() won't be able to decode them.
" i.e.
" function s:foo() dict abort
" logger.log("here I am");
" endfunction
" let dict.foo = function('s:foo')
" will work correctly fill the quicklist/loclist, but
" function dict.foo() abort
" logger.log("here I am");
" endfunction
" won't
" TODO: add verbose levels
function! lh#log#new(where, kind) abort
let log = { 'winnr': bufwinnr('%'), 'kind': a:kind, 'where': a:where}
" open loc/qf window {{{4
function! s:open() abort dict
try
let buf = bufnr('%')
exe 'silent! '.(self.where). ' '.(self.kind == 'loc' ? 'l' : 'c').'open'
finally
call lh#buffer#find(buf)
endtry
endfunction
" add {{{4
function! s:add_loc(msg) abort dict
call setloclist(self.winnr, [a:msg], 'a')
endfunction
function! s:add_qf(msg) abort dict
call setqflist([a:msg], 'a')
endfunction
" clear {{{4
function! s:clear_loc() abort dict
call setloclist(self.winnr, [])
endfunction
function! s:clear_qf() abort dict
call setqflist([])
endfunction
" log {{{4
function! s:log(msg) abort dict
let data = { 'text': a:msg }
try
throw "dummy"
catch /.*/
let bt = lh#exception#callstack(v:throwpoint)
if len(bt) > 1
let data.filename = bt[1].script
let data.lnum = bt[1].pos
endif
endtry
call self._add(data)
endfunction
" reset {{{4
function! s:reset() dict abort
call self.clear()
call self.open()
return self
endfunction
" register methods {{{4
let log.open = function('s:open')
let log._add = function('s:add_'.a:kind)
let log.clear = function('s:clear_'.a:kind)
let log.log = function('s:log')
let log.reset = function('s:reset')
" open the window {{{4
call log.reset()
return log
endfunction