Есть ли способ заставить Visual Studio прекратить отступы пространств имен?


Visual Studio продолжает пытаться отступить код внутри пространств имен.

например:

namespace Foo
{
   void Bar();

   void Bar()
   {

   }

}

теперь, если я снимаю отступ вручную, то он остается таким. Но к сожалению, если я добавлю что-то прямо перед void Bar(); - например, комментарий-VS будет продолжать пытаться отступить.

это так раздражает, что в основном из-за этой единственной причины я почти никогда не использую пространства имен в C++. Я не могу понять, почему он пытается отступить от них (какой смысл отступ 1 или даже 5 вкладок файл?), или как его остановить.

есть ли способ остановить это поведение? Параметр конфигурации, надстройка, параметр реестра, ад даже хак, который изменяет devenv.ехе напрямую.

7 56

7 ответов:

вот макрос, который может помочь вам. Он удалит отступ, если обнаружит, что вы в настоящее время создаете 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

так как он работает все время, вам нужно убедиться, что вы устанавливаете макрос внутри вашего EnvironmentEvents элемент проекта внутри MyMacros. Доступ к этому модулю возможен только в Обозревателе макросов (сервис->макросы->Обозреватель макросов).

одно примечание, в настоящее время это не так поддержка "упакованных" пространств имен, таких как

namespace A { namespace B {
...
}
}

EDIT

для поддержки "упакованных" пространств имен, таких как приведенный выше пример, и/или поддержки комментариев после пространства имен, таких как namespace A { /* Example */, можно попробовать использовать следующую строку:

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

у меня еще не было возможности проверить его много, но он, кажется, работает.

Как указывает KindDragon, Visual Studio 2013 Update 2 имеет возможность остановить отступ.

вы можете отключить Сервис -> Параметры -> текстовый редактор -> с/C++ -> формат -> абзац -> отступы содержимого пространства имен.

просто не вставляйте ничего перед первой строкой кода. Вы можете попробовать следующий подход для вставки нулевой строки кода (похоже, он работает в VS2005):

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

это, кажется, подавляет отступ, но компиляторы могут выдавать предупреждения и рецензенты кода / сопровождающие могут быть удивлены! (И совершенно справедливо, в обычном случае!)

вероятно, не то, что вы хотели услышать, но многие люди работают вокруг этого с помощью макросов:

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

звучит глупо, но вы будете удивлены, сколько системных заголовков используют это. (имплантирование stl glibc, например, имеет _GLIBCXX_BEGIN_NAMESPACE() для этого.)

Я на самом деле предпочитаю этот способ, потому что я всегда склонен съеживаться, когда я вижу без отступов строки после {. Но это всего лишь я.

вы также можете переслать объявление своих типов (или что-то еще) внутри пространства имен, а затем реализовать снаружи следующим образом:

namespace test {
    class MyClass;
}

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

Я понимаю проблему, когда есть вложенные пространства имен. Раньше я собирал все namespaces в одной строке, чтобы избежать множественного отступа. Он оставит один уровень, но это не так плохо, как много уровней. Прошло так много времени с тех пор, как я использовал VS, что я едва помню те дни.

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

Visual Studio 2017

меню отступа пространства имен VS2017

вы можете перейти к этому параметру "содержимое пространства имен отступа" в разделе Инструменты->Параметры, а затем текстовый редактор->C/C++->форматирование->отступ. Это глубоко в меню, но очень полезно, как только нашел.