Vim 使用errormarker获取异步命令?

Vim 使用errormarker获取异步命令?,vim,Vim,我发现了,并且发现它是一个很棒的工具!我试图让它工作,但遇到了一些问题 我不知道到底是什么问题。我跟踪了errormarker的脚本,发现错误使用以下脚本将QuickFixCmdPost挂接到事件,并将标记设置到源文件的行 augroup errormarker autocmd QuickFixCmdPost make call <SID>SetErrorMarkers() augroup END 它不工作(当然)。但我不知道我还能做什么。我在谷歌上搜索了“AsyncCom

我发现了,并且发现它是一个很棒的工具!我试图让它工作,但遇到了一些问题

我不知道到底是什么问题。我跟踪了errormarker的脚本,发现错误使用以下脚本将
QuickFixCmdPost
挂接到事件,并将标记设置到源文件的行

augroup errormarker
    autocmd QuickFixCmdPost make call <SID>SetErrorMarkers()
augroup END
它不工作(当然)。但我不知道我还能做什么。我在谷歌上搜索了“AsyncCommand errormarker”,但一无所获


有什么评论吗?如有任何建议,我们将不胜感激。提前感谢。

AsyncCommand使用封面下的
cgetfile
填充quickfix窗口。似乎
cgetfile
不会触发
QuickFixCmdPost
事件。为了让
SetErrorMarkers()。我们需要创建一个新事件或将errormarker插件耦合到AsyncCommand中。因为我们在这里都是优秀的、不懒惰的程序员,所以我将建议使用evented方法,因为它提供了更多的灵活性

由于您已经在编辑一个插件,我希望您不介意对AsyncCommand插件进行一个小的添加。我假设您有来自的最新版本

我们将创建一个新的用户事件,AsyncCommand将在
cgetfile
之后触发该事件。在文件中:
autoload/asynchHandler.vim
在第63行之后插入以下行

doautocmd User AsyncCommandQuickFixCmdPost
应该是这样的:

exe 'botright ' . self.mode . "open"
let cmd = self.command . ' ' . a:temp_file_name
exe cmd
doautocmd User AsyncCommandQuickFixCmdPost
if type(self.title) == type("") && self.title != ""
augroup errormarker
    autocmd QuickFixCmdPost make call <SID>SetErrorMarkers()
    autocmd User AsyncCommandQuickFixCmdPost call <SID>SetErrorMarkers()
augroup END
现在,您可以编辑错误标记插件,如下所示:

exe 'botright ' . self.mode . "open"
let cmd = self.command . ' ' . a:temp_file_name
exe cmd
doautocmd User AsyncCommandQuickFixCmdPost
if type(self.title) == type("") && self.title != ""
augroup errormarker
    autocmd QuickFixCmdPost make call <SID>SetErrorMarkers()
    autocmd User AsyncCommandQuickFixCmdPost call <SID>SetErrorMarkers()
augroup END
augroup errormarker
autocmd QuickFixCmdPost发出调用SetErrorMarkers()
autocmd用户AsyncCommandQuickFixCmdPost调用SetErrorMarkers()
螺旋端
我找到了一个解决方案

解决方案是可行的,但很难看

关键是在正确的时间自动调用
errormarker
SetErrorMarkers()
函数

我尝试了Peter Rincker的解决方案,但结果发现
AsyncCommandQuickFixCmdPost
启动得太早了。尚未设置快速修复列表。所以
SetErrorMarkers()
什么也不做

我阅读了一些
AsyncCommand
的手册并跟踪了一些代码,
AsyncMake
实际上是一个包装器,它调用

asynccommand#run(cmd, handler)

因此,由于可以在正确的时间调用
asynchandler#qf
,我跟踪了
asynchandler#qf
的调用点,并在文件
asynccommand.vim
第92行调用
asynchandler#qf
中找到函数
asynccommand#done

function! asynccommand#done(temp_file_name)
  " Called on completion of the task
  let r = s:receivers[a:temp_file_name] "handlers are registered in s:receivers
  if type(r.dict) == type({})
    call call(r.func, [a:temp_file_name], r.dict)
  else
    call call(r.func, [a:temp_file_name])
  endif
  unlet s:receivers[a:temp_file_name]
  delete a:temp_file_name
endfunction
抓住你了

让我们在第101行添加一些代码来调用
SetErrorMarkers()
函数

  ...
  unlet s:receivers[a:temp_file_name]
  if exists("*ExposeSetErrorMarkers")
    call ExposeSetErrorMarkers()
  endif
  delete a:temp_file_name
  ...
注意,我们在这里调用的函数是ExposeSetErrorMarkers()
而不是
SetErrorMarkers()
。由于
SetErrorMarkers()
是脚本本地函数,因此无法从脚本外部调用。因此,我在
errormarker.vim
中添加了一个委托函数
exposeseterromarkers()
,以公开该函数

function! ExposeSetErrorMarkers()
    call s:SetErrorMarkers()
endfunction
此外,我在
.vimrc
中添加了一些自动命令

au BufWritePost *cpp AsyncMake
au BufWritePost *cc  AsyncMake
au BufWritePost *h   AsyncMake
每次保存源文件时自动调用AsyncMake


它起作用了!丑陋,但是:P

谢谢你的回答!我尝试了您的解决方案,发现AsyncCommand比我们想象的更复杂:当触发
用户AsyncCommandQuickFixCmdPost
时,async eventhandler实际上没有完成,因此主(服务器)程序中的quickfix尚未设置,因此
SetErrorMarkers()
将不会设置任何内容。我已经找到了其他解决方案,它可以工作,但没有你的那么优雅,我会发布它:)