【问题标题】:Get AsyncCommand work with errormarker?让 AsyncCommand 与错误标记一起使用?
【发布时间】:2011-11-01 06:04:49
【问题描述】:

我在StackOverflow 上找到了AsyncCommand,发现它是一个了不起的工具!我试图让它与errormarker plugin 一起工作,但遇到了一些问题。

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

augroup errormarker
    autocmd QuickFixCmdPost make call <SID>SetErrorMarkers()
augroup END

根据:help,第二个参数(make)是文件的pattern(例如:*.html)。我不知道make文件模式是什么,我试过了

autocmd QuickFixCmdPost AsyncMake call <SID>SetErrorMarkers()

它不起作用(当然)。但我不知道我还能做什么。我用谷歌搜索了“AsyncCommand errormarker”,但什么也没得到。

有什么意见吗?任何建议表示赞赏。提前致谢。

【问题讨论】:

    标签: vim


    【解决方案1】:

    AsyncCommand 在幕后使用cgetfile 填充快速修复窗口。 cgetfile 似乎没有触发 QuickFixCmdPost 事件。为了让SetErrorMarkers() 在正确的时刻(或根本)开火。我们需要创建一个新事件或将 errormarker 插件耦合到 AsyncCommand 中。由于我们都是优秀且不懒惰的程序员,因此我将建议事件方法,因为它提供了更多的灵活性。

    既然你已经在编辑一个插件,我希望你不介意对 AsyncCommand 插件做一个小的补充。我假设您拥有来自github 的最新版本。

    我们将创建一个新的用户事件,AsyncCommand 将在cgetfile 之后触发。在文件中:autoload/asynchandler.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
    

    【讨论】:

    • 感谢您的回答!我试过你的解决方案,发现AsyncCommand比我们想象的要复杂:当User AsyncCommandQuickFixCmdPost被触发时,async-eventhandler实际上是不完整的,所以main(server)程序中的quickfix还没有设置,所以SetErrorMarkers() 不会设置任何内容。我找到了其他解决方案,它有效,但不像你的那样优雅,我会发布它:)
    【解决方案2】:

    我找到了解决办法。

    解决方案有效,但丑陋。

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

    我尝试了 Peter Rincker 的解决方案,但事实证明 AsyncCommandQuickFixCmdPost 被解雇得太早了。快速修复列表尚未设置。所以SetErrorMarkers() 什么都不做。

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

    asynccommand#run(cmd, handler)
    

    asynccommand#run("make", asynchandler#qf)
    // where asynchandler#qf is the handler to read quick fix list back.
    

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

    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 中添加了一个委托函数ExposeSetErrorMarkers() 来公开该函数。

    function! ExposeSetErrorMarkers()
        call s:SetErrorMarkers()
    endfunction
    

    此外,我在.vimrc 中添加了一些自动命令

    au BufWritePost *cpp AsyncMake
    au BufWritePost *cc  AsyncMake
    au BufWritePost *h   AsyncMake
    

    每次保存源文件时自动调用 AsyncMake。

    有效!丑,不过:P

    【讨论】:

      猜你喜欢
      • 2019-06-22
      • 1970-01-01
      • 2016-06-06
      • 1970-01-01
      • 2015-11-02
      • 1970-01-01
      • 1970-01-01
      • 2014-04-05
      • 2015-12-16
      相关资源
      最近更新 更多