使vim indent C预处理程序指令与其他语句相同

时间:2013-04-16 21:33:53

标签: c vim indentation preprocessor-directive

一般信息

(注意:请一直阅读,因为我花了一些时间来组织它,确保我解决了我遇到的每个问题以及为什么一个提出的解决方案对我不起作用。)

我在vim中使用cindent自动进行缩进。它大部分时间都很好用。但是,cindent做了三个 Bad Things (在我看来)涉及C预处理器指令(以hash('#')开头的语句)。

如果它是相关的,我使用标签进行缩进,而我的.vimrc包含filetype indent on

Bad Thing 1

只要我输入一个预处理器指令,vim就会将它放在第1列(它完全取消缩进)。例如,当我输入时,这是vim对我的代码的作用

int main(void)
{
    while(1) {
        /* normal things */
#ifdef DEBUG
        printDebugInfo();
#endif
        /* normal things */
    }
}

然而,我希望它看起来像这样

int main(void)
{
    while(1) {
        /* normal things */
        #ifdef DEBUG
        printDebugInfo();
        #endif
        /* normal things */
    }
}

换句话说,我更喜欢vim像任何其他C / C ++语句一样处理预处理程序指令。

Bad Thing 2

当我使用==(或[movement]=跨越)具有预处理器指令的行时, vim将其放回第1列。 (这与Bad Thing 1一致,但仍然存在问题。)

Bad Thing 3

如果(由于Bad Thing 1或2或使用<<)预处理程序指令在第1列结束,它会“卡在那里”并且不会受到影响>>。增加缩进的唯一方法是I<Tab>i<Ctrl-t>。然后它变得“没有卡住”,我可以使用<<>>移动它。

解决方案失败

One solution建议将set cinkeys-=0#放入我的.vimrc修复了坏事1 - 3,但添加了新内容

Bad Thing 4(仅限cinkeys-=0#

第1列中的预处理程序指令不受==[movement]=的影响,这意味着在我用{{{}}手动缩进它们之前,我仍然无法自动修复它们的缩进1}}或插入制表符。

问题

有没有办法在不引入Bad Thing 4的情况下解决Bad Things 1 - 3?我可以强制vim处理以'#'开头的行,就像普通的C语句一样吗?

(或者我只是以有害的方式使用>>,这是vim告诉我停止的方式?)

我宁愿不修补vim和/或重新编译,但如果必须,我会这样做。

2 个答案:

答案 0 :(得分:5)

来自Vim documentation,在cinoptions下:

  

如果出现以下情况,Vim会在第1列中添加一行:

     
      
  • 如果'cinkeys'包含'#',则以'#'(预处理程序指令)开头。
  •   
  • 以标签开头(关键字后跟':',除了“case”和“default”),'cinoptions'不包含'L'条目   正值。
  •   
  • 任何缩进组合都会导致该行的缩进小于0。
  •   

因此,从0#删除cinkeys应该会覆盖该默认行为。 (这个想法出现在足够的地方on the interwebs。)

set cinkeys=0{,0},0),:,!^F,o,O,e

随着对cinkeys的改变,这就是我得到的,正是你要找的东西:

int main(void)
{
    while(1) {
        /* normal things */
        #ifdef DEBUG
        printDebugInfo();
        #endif
        /* normal things */
    }
}

答案 1 :(得分:3)

糟糕的解决方案4

==

如果您使用[movement]=cinkeys-=0#,这将缩小1个shiftwidth。将它与选项{{1}}结合起来对我有用。