Подтвердить что ты не робот

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

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

Например:

namespace Foo
{
   void Bar();

   void Bar()
   {

   }

}

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

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

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

4b9b3361

Ответ 1

Вот макрос, который может вам помочь. Он удалит отступ, если обнаружит, что вы в настоящее время создаете 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, Вы можете получить доступ только к этому модулю в проводнике макросов (Tools- > Macros- > Macro Explorer).

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

namespace A { namespace B {
...
}
}

ИЗМЕНИТЬ

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

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

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

Ответ 2

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

Вы можете снять флажок TOOLS → Options → Text Editor → C/С++ → Форматирование → Отступы → Содержание пространства имен indent.

Ответ 3

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

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

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

Ответ 4

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

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

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

Я действительно предпочитаю этот путь, потому что я всегда склоняюсь, когда вижу невидимые строки, следующие за {. Это только я, хотя.

Ответ 5

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

namespace test {
    class MyClass;
}

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

Ответ 6

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

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