【问题标题】:Vim: Conditionally use fugitive#statusline function in vimrcVim:有条件地在 vimrc 中使用 fugitive#statusline 函数
【发布时间】:2013-12-10 00:20:43
【问题描述】:

我在许多机器上使用相同的 vimrc,其中一些安装了 fugitive.vim,而另一些没有。我喜欢在状态行中包含fugitive#statusline(),但在没有安装插件的机器上,这会引发错误。

有没有办法在调用set statusline 之前检查这个函数是否存在?我试过使用existsy,但由于某种原因它不起作用(加载顺序?)

if exists("*fugitive#statusline")
  set statusline=%<\ %f\ %{fugitive#statusline()} ... (other stuff)
endif

我还尝试通过在命令前加上 silent! 来消除错误,但这似乎也不起作用。

【问题讨论】:

    标签: git vim


    【解决方案1】:

    这是一条捷径:

    set statusline+=%{exists('g:loaded_fugitive')?fugitive#statusline():''}
    

    【讨论】:

    • 这不起作用。我试过了,但是在执行vimrc 时,变量g:loaded_fugitive 要么为空要么不存在。
    • @Christopher: 请检查您的vim-fugitive 安装,因为g:loaded_fugitive 是在fugitive.vim 中定义的,并且每当评估状态行时都会进行这种插值,而不仅仅是vimrc被执行。
    • @tungd g:loaded_fugitive 没有理由被加载之前 vimrc 除非您使用某种方式手动触发加载。
    • @ZyX:实际上插件总是在vimrc 之后加载,这在:help initialization 中有明确记录。但是,这仍然可以按预期工作,因为 %{} 意味着只要状态行更新就评估表达式。
    • @tungd A,你是对的。我通常会避免这样的解决方案(我的意思是,在 1 就足够的情况下执行检查 100500 次),但它是有效的并且不会增加那么多开销。
    【解决方案2】:

    由于逃犯没有在autoload 目录中定义fugitive#statusline,遗憾的是无法使用silent! call / exists 技术嗅探它(谢谢@Christopher)。不过也有一些选择:

    • 按照@tungd 的建议,在'statusline' 选项中添加一个三元分支。
    • 在@Christopher 建议的after/plugin 文件中设置'statusline'。这解决了问题,但意味着您的状态行是在一个不太可能的地方定义的,因此最好在您的 ~/.vimrc 文件中添加一个很好的评论。
    • 只需在 ~/.vimrc 文件中定义函数即可。

    例子:

    if !exists('*fugitive#statusline')
      function! fugitive#statusline()
          return ''
      endfunction
    endif
    
    • 另一个选项是使用 Fugitive 定义的 Fugitive autocmd 事件。请注意,这只会在 Fugitive 检测到 git 目录时触发。

    在您的~/.vimrc 文件中添加这样的内容:

    augroup fugitive_status
      autocmd!
      autocmd user Fugitive set statusline=%<\ %f\ %{fugitive#statusline()} ...
    augroup END
    

    我个人认为@tungd 解决方案是最简单的。然而,只定义一个虚拟函数将是我的下一个选择。如果安装了 Fugitive,Fugitive 将覆盖它。最好的部分是这可以让您的'statusline' 选项保持整洁。

    【讨论】:

    • 虚拟函数应该包含return '' 我相信。否则返回数字0 将被显示。
    【解决方案3】:

    我想我已经弄清楚了如何实现这一目标。 fugitive#statusline() 是否存在需要在插件加载完成后进行。在此之前,不会加载与逃犯相关的变量或函数。

    将此代码文件添加到$VIMRUNTIME/after/plugin路径中:

    " $VIMRUNTIME/after/plugin/fugitive-statusline.vim
    if has("statusline") && exists('*fugitive#statusline')
        " git fugitive statusline
        set statusline=%<%f\ %h%m%r%{fugitive#statusline()}%=%-14.(%l,%c%V%)\ %P
    
        " show statusline always
        set laststatus=2
    
        " turn off ruler
        set noruler
    endif
    

    【讨论】:

    • 请解释一下。 autoload/ 中的文件仅在一种情况下自动加载:当有人试图使用未定义的函数或变量时。当我们强制加载可能触发自动加载的函数和变量时,有效地定义了第二次自动加载文件的原因。它不是在 vimrc 之后要获取的插件目录,无论其中的文件是否已经获取或其他类似的目录。
    • Fcking fugitive plugin 在plugin/fugitive.vim 中定义了这个函数,而不是在它应该位于的autoload/fugitive.vim 中(基于函数名称),这意味着我的解决方案没有 *工作 (它仍然不会触发乱序运行:它根本不会触发任何运行),Peter Rincker 的运行也没有。如果函数是在autoload/ 中定义的,那么之前的评论适用并且@Peter Rincker 的回答变得很好。仍然无法加载autoload/fugitive.vim 应该会造成任何麻烦,但它根本不存在。
    • ^^^ 将我的两个 cmets 复制到我的答案(它已被删除),因为我不确定您是否可以看到 cmets 到已删除的答案。跟随对话:“我们真的应该颠覆处理顺序,而是乱序运行 autoload/fugitive.vim 吗?这可能会产生意想不到的后果。 ——克里斯托弗”是我的评论回复的第一个评论。我的回答是用:runtime 加载autoload/fugitive.vim,然后检查函数是否存在。
    • @ZyX Fugitive 也确实让我陷入了困境。我已经删除了我的帖子,因为它不起作用。
    【解决方案4】:

    您可以尝试检查逃犯插件的加载变量吗?

    if exists('g:loaded_fugitive')
       set statusline=%<\ %f\ %{fugitive#statusline()} ... (other stuff)
    endif
    

    虽然如果 fugitive#statusline 的存在不起作用,这可能不会那么有效!

    【讨论】:

    • 这不起作用。我试过了,但是在执行vimrc 时变量g:loaded_fugitive 要么为空要么不存在。
    猜你喜欢
    • 2013-06-15
    • 1970-01-01
    • 2020-09-01
    • 1970-01-01
    • 2014-10-06
    • 2012-10-21
    • 1970-01-01
    • 1970-01-01
    • 2020-05-28
    相关资源
    最近更新 更多