如何在vim中避免命名空间内容缩进?

35

如何设置vim在C++中不缩进命名空间的内容?

namespace < identifier >
{
    < statement_list > // Unwanted indentation
}

出人意料的是,'cinoptions' 并没有提供一种编辑命名空间内容缩进的方法。

5个回答

38

不确定它是何时引入的,但我安装的vim版本v7.3.353有一个cino选项,可以显式处理cpp命名空间。我当前正在使用的示例值为:

cino=N-s

根据:help cinoptions-values,这个值的含义为:

NN    Indent inside C++ namespace N characters extra compared to a
  normal block.  (default 0).

cino=                      cino=N-s 
  namespace {                namespace {
      void function();       void function();
  }                          }

  namespace my               namespace my
  {                          {
      void function();       void function();
  }                          }

OP发布的链接是v7.3.162版本


我之前使用的是vim v7.2版本,但它似乎没有这个选项(当时我已经仔细检查过了,现在我又进行了“三重检查”)。我现在将升级到v7.3版本。谢谢! - freitass
这与 cino=N0 相等吗? - nn0p
不一样的,有:h cino选项,然后是/namespace。 个人使用cino=(s,j1,N-s,这样我就可以打开我的... 函数(并在多行上缩进此打开) - Advis

11

cpp.vim可以解决你的问题,但如果你不想使用完整的Google代码风格,只需查看插件源代码并了解它如何处理命名空间即可。它非常简单:

function! IndentNamespace()
  let l:cline_num = line('.')
  let l:pline_num = prevnonblank(l:cline_num - 1)
  let l:pline = getline(l:pline_num)
  let l:retv = cindent('.')
  while l:pline =~# '\(^\s*{\s*\|^\s*//\|^\s*/\*\|\*/\s*$\)'
    let l:pline_num = prevnonblank(l:pline_num - 1)
    let l:pline = getline(l:pline_num)
  endwhile
  if l:pline =~# '^\s*namespace.*'
    let l:retv = 0
  endif
  return l:retv
endfunction

setlocal indentexpr=IndentNamespace()

基本上你所做的就是将最后一个非空行与/^\s*namespace/匹配,如果匹配则返回0(作为indentexpr的缩进位置);否则返回Vim内置的cindent机制的值。

我从插件中窃取了代码,删除了除了命名空间相关的内容,并将缩进函数重命名为IndentNamespace()。将此保存为~/.vim/indent/cpp.vim文件。


由于我将左花括号放在命名空间声明的下一行,所以这段代码无法正常工作。它会在前一个非空白行找到 {。尽管如此,这仍然是一个很好的解决方案。 - freitass
啊,你说得对。我想我从插件中删除了太多内容。:s 现在再试一次。修复程序将忽略命名空间行后的任何注释或作用域括号。 - wilhelmtell
非常抱歉这么晚才回复。我刚试了一下你的新方案,但还是不行。你建议的“全面”的Google编码风格脚本也不起作用。我还不知道原因。 - freitass

2

很多人都提到了Google C++风格非常不错。

我建议安装clang-format,我发现它比推荐的插件更好,然后在其上安装vim插件。

安装clang-format

Ubuntu:

sudo apt-get install clang-format
// or for older versions:
sudo apt-get install clang-format-3.6

Mac:

brew install clang-format

Vim插件:

rhysd/vim-clang-format

使用您喜欢的插件管理器进行安装。 查看插件链接以获取更多选项。默认样式为google,但也有llvm和其他样式。

如果您正在使用自定义版本的命令,则可能需要一个选项,例如:

示例:

let g:clang_format#command ="clang-format-3.6"

1

我使用cpp.vim,它受Google C++代码风格指南的启发。除其他之外,该脚本可以做到你所要求的。


0

我已经配置了vim,使其不缩进命名空间。这是我vimrc中相关的行:

autocmd Filetype cpp set shiftwidth=2
set cino=>2(0^-2g0h2

坦白说,我不记得如何解释语句,但:help cinoptions应该有助于解密它。一个注意点:我认为它配置为在使用以下格式时不缩进:
namespace foo 
{ // <- curly bracket on next line
...

对比

namespace foo { // <- same line

由于我专门将花括号放在下一行以用于命名空间,所以它可以实现我想要的效果,但如果您在其他函数声明、for循环等中使用该样式,则可能无法正常工作。


就像我说的那样,“cinoptions”(长为“cino”)本质上不会起作用。根据你粘贴的代码行,‘^-2’与‘shiftwidth=2’结合使用可以去除命名空间内容的缩进,但同时也会去除每个以0列开头的大括号块的缩进。 - freitass
是的,没错。cpp.vim 的解决方案看起来更好,我现在正在将其合并到我的 vim 配置中 :) - dimatura

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