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

2022-01-14 00:00:00 visual-studio namespaces indentation c++

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

Visual Studio keeps trying to indent the code inside namespaces.

例如:

namespace Foo
{
   void Bar();

   void Bar()
   {

   }

}

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

Now, if I un-indent it manually then it stays that way. But unfortunately if I add something right before void Bar(); - such as a comment - VS will keep trying to indent it.

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

This is so annoying that basically because of this only reason I almost never use namespaces in C++. I can't understand why it tries to indent them (what's the point in indenting 1 or even 5 tabs the whole file?), or how to make it stop.

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

Is there a way to stop this behavior? A config option, an add-in, a registry setting, hell even a hack that modifies devenv.exe directly.

推荐答案

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

Here is a macro that could help you. It will remove indentation if it detects that you are currently creating a namespace. It is not perfect but seems to work so far.

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[sw]+)?[s{]+$") Then
                    sel.Unindent()
                End If
            End If
        End If
    End If
End Sub

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

Since it is running all the time, you need to make sure you are installing the macro inside in your EnvironmentEvents project item inside MyMacros. You can only access this module in the Macro Explorer (Tools->Macros->Macro Explorer).

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

One note, it does not currently support "packed" namespaces such as

namespace A { namespace B {
...
}
}

<小时>

编辑

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

To support "packed" namespaces such as the example above and/or support comments after the namespace, such as namespace A { /* Example */, you can try to use the following line instead:

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

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

I haven't had the chance to test it a lot yet, but it seems to be working.

相关文章