有没有办法让Visual Studio停止缩进命名空间?

Tho*_*ini 61 c++ namespaces indentation visual-studio

Visual Studio不断尝试缩进命名空间内的代码.

例如:

namespace Foo
{
   void Bar();

   void Bar()
   {

   }

}
Run Code Online (Sandbox Code Playgroud)

现在,如果我手动取消缩进,那么它就会保持这种状态.但不幸的是,如果我之前添加一些东西void Bar();- 例如评论 - VS将继续尝试缩进它.

这太烦人了,基本上因为这个原因我几乎从不在C++中使用命名空间.我无法理解为什么它会尝试缩进它们(缩小整个文件的 1个甚至5个标签什么意思?),或者如何使它停止.

有没有办法阻止这种行为?一个配置选项,一个加载项,一个注册表设置,甚至是一个直接修改devenv.exe的hack.

use*_*953 46

正如KindDragon所指出的,Visual Studio 2013 Update 2有一个停止缩进的选项.

您可以取消选中工具 - >选项 - >文本编辑器 - > C/C++ - >格式化 - >缩进 - >缩进命名空间内容.

  • 它似乎再次被打破......至少在Update 4中.我希望他们能解决这个问题. (5认同)
  • 它确实破碎了.虽然你可以使用clang格式,只是简单地处理混乱. (2认同)
  • 这是最好的答案.按照我在VS 2015中的预期工作. (2认同)

bac*_*car 30

只是不要在第一行代码之前插入任何内容.你可以尝试以下方法来插入一行空代码(它似乎在VS2005中工作):

namespace foo
{; // !<---
void Test();
}
Run Code Online (Sandbox Code Playgroud)

这似乎压制了缩进,但编译器可能会发出警告,代码审阅者/维护者可能会感到惊讶!(而且通常情况下,这是正确的!)

  • 我也喜欢这个.似乎甚至一个扩展到空的宏都足以抑制缩进.所以你可以`#define SUPPRESS_INDENTATION`然后打开命名空间,如`namespace foo {SUPPRESS_INDENTATION` :) (9认同)

Ken*_*mon 13

可能不是你想听到的,但很多人通过使用宏来解决这个问题:

#define BEGIN_NAMESPACE(x) namespace x {
#define END_NAMESPACE }

听起来很愚蠢,但是你会惊讶地发现有多少系统头使用它.(例如,glibc的stl _GLIBCXX_BEGIN_NAMESPACE()实现就此而言.)

我实际上更喜欢这种方式,因为当我看到跟随的非缩进线时,我总是倾向于畏缩{.那只是我.

  • 我认为这更多是因为与旧编译器的兼容性而不是因为Visual Studio =) (8认同)
  • @andreas我认为你可以在不编辑所有源文件的情况下轻松更改整个lib的命名空间 (6认同)

Rod*_*Rod 13

这是一个可以帮助你的宏.如果检测到您当前正在创建缩进,它将删除缩进namespace.它并不完美,但到目前为止似乎有效.

Public Sub aftekeypress(ByVal key As String, ByVal sel As TextSelection, ByVal completion As Boolean) _
        Handles TextDocumentKeyPressEvents.AfterKeyPress
    If (Not completion And key = vbCr) Then
        'Only perform this if we are using smart indent
        If DTE.Properties("TextEditor", "C/C++").Item("IndentStyle").Value = 2 Then
            Dim textDocument As TextDocument = DTE.ActiveDocument.Object("TextDocument")
            Dim startPoint As EditPoint = sel.ActivePoint.CreateEditPoint()
            Dim matchPoint As EditPoint = sel.ActivePoint.CreateEditPoint()
            Dim findOptions As Integer = vsFindOptions.vsFindOptionsMatchCase + vsFindOptions.vsFindOptionsMatchWholeWord + vsFindOptions.vsFindOptionsBackwards
            If startPoint.FindPattern("namespace", findOptions, matchPoint) Then
                Dim lines = matchPoint.GetLines(matchPoint.Line, sel.ActivePoint.Line)
                ' Make sure we are still in the namespace {} but nothing has been typed
                If System.Text.RegularExpressions.Regex.IsMatch(lines, "^[\s]*(namespace[\s\w]+)?[\s\{]+$") Then
                    sel.Unindent()
                End If
            End If
        End If
    End If
End Sub
Run Code Online (Sandbox Code Playgroud)

由于它一直在运行,因此您需要确保在MyMacros 内的EnvironmentEvents项目项中安装宏.您只能在宏浏览器中访问此模块(工具 - >宏 - >宏浏览器).

需要注意的是,它目前不支持"压缩"命名空间,例如

namespace A { namespace B {
...
}
}
Run Code Online (Sandbox Code Playgroud)

编辑

要支持"压缩"命名空间(例如上面的示例)和/或支持命名空间后的注释,例如namespace A { /* Example */,您可以尝试使用以下行:

 If System.Text.RegularExpressions.Regex.IsMatch(lines, "^[\s]*(namespace.+)?[\s\{]+$") Then
Run Code Online (Sandbox Code Playgroud)

我还没有机会测试它,但似乎有效.


met*_*tor 7

您还可以在命名空间内转发声明您的类型(或其他),然后像这样在外部实现:

namespace test {
    class MyClass;
}

class test::MyClass {
//...
};
Run Code Online (Sandbox Code Playgroud)


Mic*_*all 6

Visual Studio 2017+

在此处输入图片说明 您可以在工具->选项然后文本编辑器->C/C++->格式->缩进下进入这个“缩进命名空间内容”设置。它在菜单的深处,但一旦找到就非常有帮助。