如何使用命令或本地vimrc文件在多个vim配置之间切换?

89

我在几个组中工作,每个组在C语言方面都有自己的标签/缩进/空格规范。

是否有一种方法可以为每个组拥有单独可选择的VIM配置,以便在编辑文件时:

  • 我可以像 set group=1 这样做来选择配置
  • 使用位于工作目录中的本地 .vimrc 自动设置配置

请查看此链接:https://dev59.com/VmYq5IYBdhLWcg3whRHV#14407951 - Dmitry Frank
请参阅superuser上的问题[在两个不同的vim配置之间切换](https://superuser.com/questions/209075)。 - Hotschke
12个回答

66

我在$HOME/.vimrc文件中写了如下内容:

if filereadable(".vim.custom")
    so .vim.custom
endif

这使我能够在每个目录中放置一个.vim.custom文件,以加载特定于该目录的命令和选项。如果您正在处理具有深层目录结构的多个项目,则可能需要更复杂的东西(例如,向上遍历目录树,直到找到.vim.custom),但是相同的基本思想将适用。

更新:

现在我会做类似以下的事情,从与我正在编辑的文件相同的目录中读取.vim文件,而不管当前目录是什么。

let b:thisdir=expand("%:p:h")
let b:vim=b:thisdir."/.vim"
if (filereadable(b:vim))
    execute "source ".b:vim
endif

1
这太棒了,我从未见过这样的东西! - Jim Mitchener
1
这是一个适用于存储库中的项目的绝佳解决方案! - bradreaves
4
'exrc'选项已经允许进行非常类似的操作。它将在当前工作目录中加载.vimrc/.exrc/.gvimrc文件。 - jamessan
关于 exrc 的评论应该是正确的答案。其他的东西似乎都太过于hacky和复杂了。 - silvenon
1
这个有多安全?如果你下载了一些恶意代码,它可能会在当前文件夹中放置一个.vim文件,而你的小插件会读取它。我想如果你下载了恶意代码,那就什么都不保险了,但这似乎让它更容易实现。 - trysis
显示剩余3条评论

41

总结

有几种方法可以实现这一功能,其中大部分已经被提出,但我想用两种额外的方式来总结一下:

  • 每个目录使用不同的vimrc文件 - 缺点是必须在正确的目录下启动Vim:如果您的项目在~/project1中,并且您有~/project1/.vim.custom文件,然后执行cd ~ ; vim project1/file.c,则无法找到自定义设置。
  • 模型ine - 非常有效,但缺点是需要将其添加到所有文件中(并记住将它们添加到新文件)
  • 针对不同目录的自动命令 - 这非常有效
  • 扫描文件中特定的头部(见下文)- 这是我过去在为不同公司或明确定义的项目工作时最常用的一个
  • 当打开文件时检查的与目录相关的vimrc文件(见下文)。这是另一种相当容易实现的方法,特别是如果您的项目代码都在一个地方。

扫描文件头

在许多组织中,每个源文件的顶部都有一个标准的头部(包括版权声明和项目名称等)。如果是这种情况,则可以让Vim自动扫描文件的前10行(例如)以查找关键字。如果找到了它,就可以更改您的设置。我对此进行了修改,使其比我使用的形式更简单,但是创建一个~/.vim/after/filetype.vim(如果您还没有该文件),并添加类似于以下内容的内容:

au FileType * call <SID>ConfigureFiletypes(expand("<amatch>"))

" List of file types to customise
let s:GROUPNAMETypes = ['c', 'cpp', 'vhdl', 'c.doxygen']

func! <SID>CheckForGROUPNAMECode()
    " Check if any of the first ten lines contain "GROUPNAME".

    " Read the first ten lines into a variable
    let header = getline(1)
    for i in range(2, 10)
        let header = header . getline(i)
    endfor

    if header =~ '\<GROUPNAME\>'
        " Change the status line to make it clear which
        " group we're using
        setlocal statusline=%<%f\ (GROUPNAME)\ %h%m%r%=%-14.(%l,%c%V%)\ %P
        " Do other customisation here
        setlocal et
        " etc
    endif
endfunc

func! <SID>ConfigureFiletypes(filetype)
    if index(s:GROUPNAMETypes, a:filetype) != -1
        call <SID>CheckForGROUPNAMECode()
    endif
endfunc

每当打开任何类型的文件并设置文件类型(au FileType * 行),都会调用 ConfigureFiletypes 函数。这将检查文件类型是否在当前组(GROUPNAME)关联的文件类型列表中,本例中为'c'、'cpp'、'vhdl'或'c.doxygen'。如果是,则调用 CheckForGROUPNAMECode(),读取文件的前 10 行,如果它们包含 GROUPNAME,则进行一些自定义操作。除了设置 expandtabs 或其他内容之外,还将更改状态栏以清晰地显示组名,以便您一目了然地知道它已经生效。

打开时检查配置

与 JS Bangs 建议类似,拥有自定义配置文件可能会很有用。但是,考虑以下方法,它将在打开 .c 文件时检查是否存在与 .c 文件在同一目录下的 .vim.custom 文件。

au BufNewFile,BufRead *.c call CheckForCustomConfiguration()

function! CheckForCustomConfiguration()
    " Check for .vim.custom in the directory containing the newly opened file
    let custom_config_file = expand('%:p:h') . '/.vim.custom'
    if filereadable(custom_config_file)
        exe 'source' custom_config_file
    endif
endfunction

34

您还可以在.vimrc中放置autocommands,这些autocommands可以根据路径设置特定的选项。

au BufRead,BufNewFile /path/to/project1/* setl sw=4 et
au BufRead,BufNewFile /path/to/project2/* setl sw=3 noet

当您无法控制存储库以便无法在其中放置“.vim.custom”文件时,这非常好。我喜欢它可以保持存储库的清洁。谢谢。免责声明:如果路径以不友好的方式更改,则“ .vim.custom”版本可能更好,假设可以修改存储库。 - László Papp

17

合适的插件: http://www.vim.org/scripts/script.php?script_id=441

这个插件会在当前打开的文件所在的目录下,向上搜索所有 ".lvimrc" 文件,并且按照相反的顺序加载。默认情况下,它会一直搜索到根目录。可以通过全局变量来自定义要加载的文件名和数量。


3
Github 版本也支持使用 Pathogen 加载 :-) - Graza
另一个类似的插件是localrc.vim,它也允许针对特定文件类型设置每个目录的设置;我发现它非常重要。http://www.vim.org/scripts/script.php?script_id=3393 - Ingo Karkat

12
假设你的同伴不会抱怨,你总是可以在注释中为每个文件添加vim设置。
/*
 * vim:ts=4:sw=4:expandtab:...
 */

int main(int argc, char **argv)
{
    ...

2
我是大多数团队中唯一一个“开明”的开发人员,所以没有人应该介意。 这是一个非常不错的按文件解决方案。 - bradreaves
1
我更喜欢将它们添加到底部,这样它们就不会显眼,但我想这是一个风格问题。 - alexia

6
我为此创建了一个开源工具。忘记头文件、扫描、配置和本地vimrc文件。
试试swim。

游泳

swim 是一个快速工具,用于切换 vimrc 文件和创建方便的别名。以下是简短的使用列表。请查看 Github repo 以获取演示 gif 和下载说明:


使用方法

swim add ~/dotfiles/myVimrc favorite    #Add new swim alias
swim ls                                 #Show available swim aliases
swim add https://raw.githubusercontent.com/dawsonbotsford/swim/master/exampleVimrcs/vimrcWikia.vim example
swim with favorite         #Set alias favorite as primary .vimrc
swim with main             #Set alias main as primary .vimrc

阅读更多

https://github.com/dawsonbotsford/swim


4

在尝试了前面帖子中建议的localvimrc插件后,我非常喜欢在vim设置中具有非常方便的每个项目控制能力。它默认会在加载.lvirc文件之前询问确认,但也有设置可以自动加载.lvirc文件。某些人可能认为这是一个安全漏洞,但它确实如广告所述。

我选择将.lvirc文件加入到.gitignore中。或者,您可以将其作为共享设置(制表符/空格扩展、TabStop和其他项目特定的设置)一起检查。


1
这个脚本太棒了:https://github.com/MarcWeber/vim-addon-local-vimrc。1)现在它只会询问一次并将文件哈希标记为OK。2)它从根目录遍历目录树到当前目录,最后引用更高优先级的文件。 - Ciro Santilli OurBigBook.com
为什么要将 .lvimrc 文件加入到 .gitignore 中?这样做的目的是,所有使用 vim 并安装了插件的人都可以获得相同的设置。 - alexia
2
@nyuszika7h,有些设置必须强制执行,而其他设置则纯属个人喜好。对于必须强制应用到每个人的设置,EditorConfig 是更好的选择,因为它是编辑器无关的:https://github.com/editorconfig/editorconfig-vim - Ciro Santilli OurBigBook.com

1
这是对jamessan的变体。
function! ConditionalLoad()
    let cwd = getcwd()
    if getcwd() =~ $HOME . "/src/mobile"
        so $HOME/.vim.mobile
    endif
endfunction
autocmd VimEnter * call ConditionalLoad()

我经常启动vi而没有特定的文件要跳转,因此这使得根据当前工作目录有条件地加载配置成为可能。缺点是配置不是基于文件应用的,而是基于工作目录。

正是我所需要的。作为使用示例:我将此代码放置在~/.vimrc中,将/src/mobile更改为我的Symfony项目目录(在我的情况下是/www/symfony),并将.vim.mobile修改为.vim.symfony,然后将新的.vimrc配置放置在~/.vim.symfony文件中。 - jmarceli

1

正如sledge所提到的,该插件的使用是我见过和使用过的最佳选择。jerseyboy评论说,推荐的实用程序在加载之前需要确认(即在打开每个文件后)。为了避免这种情况,只需在您的主.vimrc中设置本地.lvimrc文件列表:

let g:localvimrc_whitelist='/development/kernel/.lvimrc'


1
我在几个小组中工作,每个小组都有自己的C语言标签/缩进/空格规范。我同时使用各种开源软件,创建单独的.vimrc文件并重新配置格式规范是不切实际的。十多年前,我最终厌倦了处理编辑器配置,编写了一个名为autotab的程序来处理它。
当使用Vim建议设置autotab时,每次您将文件加载到Vim中,autotab都会对其进行调用,并将Vim设置输出autotab传递给:set命令。
autotab从文件中读取数千行,分析它们并确定expandtab、tabstop和shiftwidth参数的设置。
它可以确定文件是使用硬制表符还是空格进行缩进,并确定缩进大小。如果文件使用制表符进行缩进,则根据使用各种制表符大小渲染文件示例并根据启发式技术(如内部元素的逐行对齐)来判断正确的制表符大小。
它的工作效果足够好,以至于我几年前就停止了算法调整。如果它感到困惑,几乎总是因为文件存在格式问题,例如同时使用多个约定。
它也“不可知”文件类型,并且可以很好地处理各种不同的语言。我不仅在C上使用它,还在shell脚本、Lisp、Makefiles、HTML等上使用它。
请注意,它不处理可能是项目特定的格式化其他参数,例如,在C文件中,switch语句中的case标签是否缩进,或者包装的函数参数列表是否仅缩进或与参数列表的开括号对齐。 Vim确实具有此类设置,因此可以合理地扩展该程序以分析样式并输出这些参数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接