问题
有没有一种简单/可靠的方法可以让 VIM,在项目/目录特定的基础上,检测特殊文件(即:具有几个设置的自定义.vimrc
),或者根据 c 源 (.c
) 或标头 (.h
) 文件开头注释中存在特殊标记/字符串/哈希来更改运行时设置?字符串/哈希必须映射到.vimrc
文件中的函数/设置,并且不得包含实际设置本身。
>背景我有一个多开发人员项目,其中我们都有一组通用的代码样式设置,用于我们的各种编辑器(主要是 emacs 和 vim),我们都严格遵守这些设置,例如换行符样式(CR 与CR+
LF)、缩进(长度、硬制表符与扩展为空格)等等。
>问题我正在创建一些新项目,由于我们无法控制的原因(即:我们必须使用的静态代码分析工具),这些项目将需要与我们不同的样式设置。有一些方法可以在静态代码分析工具中绕过这一点,但有一个非技术/法律要求,即我们避免禁用此工具的"功能"。
对于这些新项目中的每一个,我想以某种方式让 vi/vim 知道一些特殊的标志,要么通过在项目目录结构的根目录中存在一个特殊文件,要么通过一个特殊的关键字/标签/哈希/等我可以放在一个/* C-style block comment */
中。当 vi/vim 知道这个"触发器"的存在时,我希望它调用一个函数来覆盖换行符、缩进等的样式设置。如果这是可能的,是否也可以有几个相互排斥的此类"触发器",以便每个人都有一个共同的.vimrc
,项目决定使用哪种风格?
>问题 - reux有没有一种简单的方法可以做到这一点?
一个解决方案:Vim的modelines(:help modeline
)和Emacs的文件变量。
这些是您放入文件中的特殊注释,由编辑器解释。您可以使用它们来设置缩进样式、文件编码等。
在我看来,模式是丑陋的噪音。
Vim:.exrc
(:help 'exrc'
的一个解决方案。
您可以将特定于项目的设置放在项目根目录下的.exrc
文件中。手册声称这个解决方案是不安全的,但我看不出正常运作的成年人如何被它击败。扬子晚报.
Vim的一个解决方案:特定于目录的自动命令。
这是:help 'exrc'
末尾提到的更安全的选择,但它需要每个贡献者在自己的vimrc
中添加东西,所以......我想没那么有用。
最终的解决方案:编辑器配置。
您将设置放在项目根目录的.editorconfig
中,并让每个贡献者的 IDE/编辑器来处理它。
...根据是否存在特殊 在 C 源 (.c) 开头的注释中的标记/字符串/哈希或 头 (.h) 文件?
是的,它们被称为模式。http://vim.wikia.com/wiki/Modeline_magic
它们可以出现在文件的开头或结尾。
我的一些C来源的例子:
/* vim:ft=c:expandtab:sw=4:ts=4:sts=4:
*/
有关更多信息,请参见 vim 中的:help modeline
。
中央配置
如果可以集中配置特定命令/本地异常,您可以将此类 autocmds 放入您的~/.vimrc
中:
:autocmd BufRead,BufNewFile /path/to/dir/* setlocal ts=4 sw=4
重要的是使用:setlocal
而不是:set
,同样:map <buffer> ...
和:command! -buffer ...
。
另一方面,如果您希望特定配置与项目一起存储(并且不想通过模式线将其嵌入到所有文件中),则有以下两个选项:
具有内置功能的本地配置
如果你总是从项目根目录启动 Vim,内置的
:set exrc
允许从当前目录中读取.vimrc
文件。您可以将:set ts=4 sw=4
命令放在那里。
通过插件进行本地配置
否则,您需要插件的帮助; vim.org 上有几个;我可以推荐 localrc 插件(尤其是我自己的增强功能),它甚至允许特定于本地文件类型的配置。
请注意,从文件系统读取配置具有安全隐患;您可能需要:set secure
。
我在这个答案中涵盖了主要的替代方案:https://stackoverflow.com/a/456889/15934(是的,你的问题几乎是重复的:不同的公式,但相同的解决方案)。
-
模式线确实是有限的:你必须使用插件来设置不是 vim 选项的东西。
-
.exrc
不查看当前目录后面 -
editorconfig仅限于非常具体的选项:不要指望转发插件规范,例如编译目录的位置(这就是我使用 CMake 支持多种编译模式的方式——其他人更喜欢使用 ccache 和调整 CMakeCache,但这在一个接一个地使用 g++ 和 clang++ 时效果不佳),如何调用 linter, 您的命名约定...
-
自动命令无法扩展,并且无法轻松地从一个目录移植到另一个目录。
-
最后,最好的解决方案是基于插件的IMO:有很多插件解决方案,请参阅我的
local_vimrc
插件自述文件末尾的非详尽列表 -
另请注意,自从我之前的回答以来,我启动了另一个简化项目管理的实验。例如,我介绍了
p:variables
,它们是属于项目的所有缓冲区之间共享的变量。