有什么方法可以让 Visual Studio 停止缩进命名空间吗?

发布于 2024-09-19 04:11:07 字数 400 浏览 5 评论 0 原文

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

例如:

namespace Foo
{
   void Bar();

   void Bar()
   {

   }

}

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

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

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

Visual Studio keeps trying to indent the code inside namespaces.

For example:

namespace Foo
{
   void Bar();

   void Bar()
   {

   }

}

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.

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.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

诗酒趁年少 2024-09-26 04:11:07

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

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

As KindDragon points out, Visual Studio 2013 Update 2 has an option to stop indenting.

You can uncheck TOOLS -> Options -> Text Editor -> C/C++ -> Formatting -> Indentation -> Indent namespace contents.

撩人痒 2024-09-26 04:11:07

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

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

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

Just don't insert anything before the first line of code. You could try the following approach to insert a null line of code (it seems to work in VS2005):

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

This seems to suppress the indentation, but compilers may issue warnings and code reviewers/maintainers may be surprised! (And quite rightly, in the usual case!)

溇涏 2024-09-26 04:11:07

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

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

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

我实际上更喜欢这种方式,因为当我看到 {.但这只是我。

Probably not what you wanted to hear, but a lot of people work around this by using macros:

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

Sounds dumb, but you'd be surprised how many system headers use this. (glibc's stl implentation, for instance, has _GLIBCXX_BEGIN_NAMESPACE() for this.)

I actually prefer this way, because I always tend to cringe when I see un-indented lines following a {. That's just me though.

掌心的温暖 2024-09-26 04:11:07

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

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 项目项。您只能在宏资源管理器中访问此模块(工具->宏->宏资源管理器)。

需要注意的是,它目前不支持“打包”命名空间,例如

namespace A { namespace B {
...
}
}

EDIT

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

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

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

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

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 {
...
}
}

EDIT

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.

山田美奈子 2024-09-26 04:11:07

您还可以在命名空间内转发声明您的类型(或其他内容),然后在外部实现,如下所示:

namespace test {
    class MyClass;
}

class test::MyClass {
//...
};

You could also forward declare your types (or whatever) inside the namespace then implement outside like this:

namespace test {
    class MyClass;
}

class test::MyClass {
//...
};
熟人话多 2024-09-26 04:11:07

Visual Studio 2017+

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

Visual Studio 2017+

enter image description here
You can get to this "Indent namespace contents" setting under Tools->Options then Text Editor->C/C++->Formatting->Indention. It's deep in the menus but extremely helpful once found.

水溶 2024-09-26 04:11:07

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

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

I understand the problem when there are nested namespaces. I used to pack all the namespaces in a single line to avoid the multiple indentation. It will leave one level, but that's not as bad as many levels. It's been so long since I have used VS that I hardly remember those days.

namespace outer { namespace middle { namespace inner {
    void Test();
    .....
}}}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文