2010-09-16 3 views
54

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

Например:

namespace Foo 
{ 
    void Bar(); 

    void Bar() 
    { 

    } 

} 

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

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

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

+0

Вы можете полностью отключить автоотмещение. Или установите его на отступ меньшую величину (скажем, 2 пробела вместо 1 вкладки) – jalf

+3

Это (неконфигурируемые настройки отступов) является одной из многих причин, по которым я прекратил редактировать файлы в Visual Studio несколько лет назад ... :) –

+1

Я буду присудить награду тому, кто найдет решение, которое не имеет побочных эффектов, или как можно меньше побочных эффектов. На данный момент лучшим ответом, ИМО, является бакар; если лучшие ответы не будут предоставлены, я дам ему ответ. –

ответ

13

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

Одно примечание, он не поддерживает «упакованные» пространств имен, таких как

namespace A { namespace B { 
... 
} 
} 

EDIT

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

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

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

+0

Большое спасибо за ваш ответ. Ошибка была исправлена, но, кроме того, она работает отлично. Граты на щедрость. –

+0

Черт, я уже начал тратить эту щедрость! ;-) – bacar

+0

Прекрасно работает для ввода, но не для вставки или, например, Visual Assist «Create Implementation», в то время как решение bacar действительно делает трюк. Тем не менее, он чист. – Adversus

12

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

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

Звуки немой, но вы будете удивлены, как много системных заголовков использовать это. (СТЛ implentation GLibC в, например, имеет _GLIBCXX_BEGIN_NAMESPACE() для этого.)

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

+8

Я думаю, что это больше для совместимости со старыми компиляторами, чем из-за Visual Studio =) –

+6

@andreas Я так думаю, что вы можете легко изменить пространство имен всей библиотеки без редактирования всех исходных файлов. –

3

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

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

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

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

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

+9

Мне это тоже нравится. Похоже, что даже макроса, который расширяется до нуля, достаточно, чтобы подавить отступы. Таким образом, вы можете '#define SUPPRESS_INDENTATION', а затем открыть пространство имен, например' namespace foo {SUPPRESS_INDENTATION' :) –

+0

Nice - намерение несколько яснее, а компилятор, скорее всего, с меньшей вероятностью будет предупреждать :) – bacar

+0

Хотя это было мое любимое решение , Я хотел бы упомянуть, что этот трюк не работает в VS2013. В VS2013 есть настройка пользовательской конфигурации, которая предотвращает это (когда она работает, см. Другой ответ). – jdknight

5

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

namespace test { 
    class MyClass; 
} 

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

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

Вы можете снять флажок TOOLS -> Параметры -> Текстовый редактор -> C/C++ -> Форматирование -> Отступы -> Содержание пространства отступов.

+5

Кажется, что он снова сломался ... По крайней мере, в обновлении 4. Надеюсь, они исправит это. – AzP

+2

Это действительно сломан. Хотя вы можете использовать формат clang и просто работать вокруг беспорядка. –

+1

Я просто попробовал VS2013 Update 5 CTP; он работает снова. Надеюсь, это останется в официальном выпуске Update 5. – jdknight

0

Visual Studio 2017

Namespace Indention Menu VS2017

Вы можете добраться до этого "отступом содержимого пространства имен", устанавливающих под Сервис-> Параметры, затем текст editor-> C/C++ -> Formatting-> Абзац. Это глубоко в меню, но очень полезно когда-то найти.

+1

, пожалуйста, не оставляйте только ссылки только на ответы! – monamona

Смежные вопросы