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

Posted

技术标签:

【中文标题】有没有办法让 Visual Studio 停止缩进命名空间?【英文标题】:Is there any way to make Visual Studio stop indenting namespaces? 【发布时间】:2011-04-13 06:35:04 【问题描述】:

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

例如:

namespace Foo

   void Bar();

   void Bar()
   

   


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

这太烦人了,基本上因为这个唯一的原因,我几乎从不在 C++ 中使用命名空间。我不明白为什么它会尝试缩进它们(缩进 1 个甚至 5 个制表符 整个文件 有什么意义?),或者如何让它停止。

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

【问题讨论】:

您可以完全禁用自动缩进。或者将其设置为缩进量较小(例如,2 个空格而不是 1 个制表符) 这(不可配置的缩进设置)是我多年前停止在 Visual Studio 中编辑文件的众多原因之一...... :) 我会将赏金奖励给找到没有副作用或副作用尽可能少的解决方案的人。目前最好的答案,IMO,是 bacar 的;如果没有提供更好的答案,我会将答案奖励给他。 这就是我使用 Eclipse CDT 的原因;) 可以在 Eclipse 中使用 VS 编译器,因此值得一试。 visualstudio.uservoice.com/forums/121579-visual-studio/… 【参考方案1】:

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

您可以取消选中 TOOLS -> Options -> Text Editor -> C/C++ -> Formatting -> Indentation -> Indent namespace contents。

【讨论】:

它似乎又坏了……至少在更新 4 中。我希望他们能修复它。 确实坏了。虽然您可以使用 clang 格式并简单地解决这个问题。 我刚试过VS2013 Update 5 CTP;它似乎又开始工作了。希望在正式的 Update 5 版本中保持这种状态。 这是最好的答案。在 VS 2015 中按预期工作。 问题是C++,但有谁知道visual-studio-2019 中是否有C# 的选项?我查看但在Indentation 选项中找不到Indent namespace contents 复选框。【参考方案2】:

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

namespace foo
; // !<---
void Test();

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

【讨论】:

我也喜欢这个。似乎即使是扩展为空的宏也足以抑制缩进。所以你可以#define SUPPRESS_INDENTATION 然后像namespace foo SUPPRESS_INDENTATION 这样打开命名空间:) 很好 - 意图更加清晰,编译器希望不太可能引发警告:) 虽然这是我最喜欢的解决方案,但我想提一下,这个技巧在 VS2013 中不起作用。 VS2013 中有一个用户配置设置可以防止这种情况发生(当它工作时;见其他答案)。【参考方案3】:

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

#define BEGIN_NAMESPACE(x) 命名空间 x #define END_NAMESPACE

听起来很愚蠢,但您会惊讶于有多少系统头文件使用它。 (例如,glibc 的 stl 实现有 _GLIBCXX_BEGIN_NAMESPACE() 。)

我实际上更喜欢这种方式,因为当我看到 后面没有缩进的行时,我总是会感到畏缩。但这只是我。

【讨论】:

我认为这更多是为了与旧编译器的兼容性,而不是因为 Visual Studio =) @andreas 我认为这样您就可以轻松更改整个库的命名空间,而无需编辑所有源文件【参考方案4】:

这是一个可以帮助您的宏。如果它检测到您当前正在创建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

由于它一直在运行,因此您需要确保将宏安装在 MyMacros 中的 EnvironmentEvents project item 中。您只能在宏资源管理器(工具->宏->宏资源管理器)中访问此模块。

请注意,它目前不支持“打包”命名空间,例如

namespace A  namespace B 
...



编辑

要支持“打包”命名空间(例如上面的示例)和/或支持命名空间后的 cmets,例如 namespace A /* Example */,您可以尝试使用以下行代替:

 If System.Text.RegularExpressions.Regex.IsMatch(lines, "^[\s]*(namespace.+)?[\s\]+$") Then

我还没有机会对其进行大量测试,但它似乎正在工作。

【讨论】:

非常感谢您的回答。我现在纠正了一个错误,但除此之外它工作得很好。感谢赏金。 适用于打字,但不适用于粘贴或例如Visual Assist 的“创建实现”功能,而 bacar 的解决方案确实可以解决问题。不过它更干净。 这个问题可能看起来很愚蠢,但我真的找不到答案:我们应该在哪里粘贴这个宏?【参考方案5】:

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

namespace test 
    class MyClass;


class test::MyClass 
//...
;

【讨论】:

【参考方案6】:

Visual Studio 2017+

您可以在 Tools->Options 然后 Text Editor->C/C++->Formatting->Indention 下访问此“缩进命名空间内容”设置。它在菜单的深处,但一旦找到就非常有用。

【讨论】:

请不要只留下链接答案! 您可以包含屏幕截图。无论如何,这是VS2017+的唯一正确答案。【参考方案7】:

我理解存在嵌套命名空间时的问题。我曾经将所有namespaces 打包在一行中以避免多重缩进。它会留下一个级别,但这并不像许多级别那么糟糕。好久没用VS了,已经不太记得那些日子了。

namespace outer  namespace middle  namespace inner 
    void Test();
    .....

【讨论】:

以上是关于有没有办法让 Visual Studio 停止缩进命名空间?的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio:如何在修改成员变量时停止调试器?

Visual Studio 2010 中的 C++ 访问修饰符自动缩进慢慢让我发疯 - 可以更改吗?

有没有办法通过Visual Studio菜单/工具栏优雅地关闭正在运行的应用程序?

禁用 Visual Studio 代码样式建议

有没有办法让 MySQL 与 Visual Studio 2012 Express 一起工作?

有没有办法让 Visual Studio Code 识别 PHP 文件中的 HTML 语法