vi/vim - 根据代码中特殊文件或标签的存在自定义格式

vi/vim - custom formatting depending on presence of special file or tag inside code

问题

有没有 simple/reliable 方法让 VIM、 在 project/directory 特定的基础上, 要么检测一个特殊文件(即:使用一些设置自定义 .vimrc),或者根据 源(.c) 或 header (.h) 文件? string/hash 必须映射到 .vimrc 文件中的 function/setting,并且不得包含实际设置本身。


背景

我有一个 mutli-developer 项目,我们都有一组通用的代码风格设置供我们的各种编辑器使用(主要是 and ),我们都严格遵守这些设置,例如换行样式(CRCR+LF),缩进(长度,hard-tabs 对比 expanded-as-spaces),依此类推。


问题

我正在创建一些新项目,由于我们无法控制的原因(即:我们必须使用静态代码分析工具),它们需要与我们不同的样式设置。在静态代码分析工具中有一些方法可以绕过它,但是有一个 non-technical/legal 要求我们避免禁用此工具的“功能”。

对于这些新项目中的每一个,我想以某种方式让 / aware of some special flag, either by the presence of a special file in the root of the project's directory structure, or by a special keyword/tag/hash/etc I could put inside a /* C-style block comment */. When / 意识到这个“触发器”的存在,我希望它调用一个函数来覆盖换行符的样式设置,缩进等。如果可能的话,是否也可以有几个相互排斥的这种“触发器”,以便每个人都有一个共同的 .vimrc 并且项目决定使用哪种样式?


问题 - redux

有没有直接的方法来完成这个?

... to change run-time settings based on the presence of a special tag/string/hash in a comment at the beginning of a c source (.c) or header (.h) file?

是的,它们叫做模式行。 http://vim.wikia.com/wiki/Modeline_magic

它们可以出现在文件的开头或结尾。

来自我的一些 C 源代码的示例:

/* vim:ft=c:expandtab:sw=4:ts=4:sts=4:
 */

有关详细信息,请参阅 vim 中的 :help modeline

一个解决方案: modelines (:help modeline) for Vim and file variables for Emacs.

这些是您在文件中放置的特殊注释,由您的编辑器解释。您可以使用它们来设置缩进样式、文件编码等。

在我看来,模式行是丑陋的噪音。

Vim的一个解决方案: .exrc (:help 'exrc').

您可以将项目特定的设置放在项目根目录下的 .exrc 文件中。该手册声称此解决方案是不安全的,但我看不出正常功能的成年人如何被它打败。 YMMV.

Vim的一个解决方案:目录特定的自动命令。

这是 :help 'exrc' 末尾提到的更安全的替代方案,但它要求每个贡献者向他自己的 vimrc 添加内容,所以……我猜没那么有用。

最终解决方案: editorconfig.

您将您的设置放在项目根目录的 .editorconfig 中,让每个贡献者的 IDE/editor 处理它。

中央配置

如果可以集中配置特定命令/本地异常,您可以将此类自动命令放入您的 ~/.vimrc:

:autocmd BufRead,BufNewFile /path/to/dir/* setlocal ts=4 sw=4

使用 :setlocal 而不是 :set 很重要,同样 :map <buffer> ...:command! -buffer ....

另一方面,如果您希望将特定配置与项目一起存储(并且不想通过 modelines 将其嵌入到所有文件中),您有以下内容两个选项:

具有 built-in 功能的本地配置

如果你总是从项目根目录启动Vim,built-in

:set exrc

允许从当前目录读取 .vimrc 文件。您可以将 :set ts=4 sw=4 命令放在那里。

通过插件进行本地配置

否则,你需要一个插件的帮助; vim.org 上有几个;我可以推荐 localrc plugin (especially with my own enhancements),它甚至允许本地 filetype-specific 配置。

请注意,从文件系统读取配置具有安全隐患;你可能想要 :set secure.

我已经介绍了这个答案中的主要替代方案:(是的,你的问题几乎是重复的:不同的表述,但相同的解决方案)。

  • Modelines 真的很有限:你必须使用 a plugin 来设置不是 vim 选项的东西。

  • .exrc不往后看当前目录

  • editorconfigrestricted to very specific options:不要指望转发插件规范,比如编译目录在哪里(这就是我支持多种编译模式的方式使用 CMake——其他人更喜欢使用 ccache 和调整 CMakeCache,但是当一个接一个地使用 g++ 和 clang++ 时,这并不适用),如何调用 linter,你的命名约定...

  • autocommand 不能缩放,不能轻松地从一个目录移植到另一个目录。

  • 最后,最好的解决方案是基于 插件 IMO:有很多插件解决方案,请参阅我的 non exhaustive list local_vimrc 插件的自述文件

  • 另请注意,自从我之前的回答以来,我已经开始 another experiment 来简化项目管理。例如,我引入了 p:variables ,它们是属于一个项目的所有缓冲区之间共享的变量。