web-dev-qa-db-ja.com

Visual Studioで名前空間のインデントを停止する方法はありますか?

Visual Studioは、名前空間内のコードをインデントしようとし続けます。

例えば:

_namespace Foo
{
   void Bar();

   void Bar()
   {

   }

}
_

ここで、インデントを手動で解除すると、そのままになります。しかし残念ながら、コメントなど、void Bar();の直前に何かを追加すると、VSはインデントを試み続けます。

これは非常に煩わしいので、基本的にこの唯一の理由により、C++で名前空間を使用することはほとんどありません。なぜインデントしようとするのか(1つまたは5つのタブをインデントする意味は何ですかファイル全体?)、または停止させる方法がわかりません。

この動作を停止する方法はありますか?設定オプション、アドイン、レジストリ設定、devenv.exeを直接変更するハックさえも。

63
Thomas Bonini

ここにあなたを助けることができるマクロがあります。現在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

常に実行されているので、MyMacros内の EnvironmentEventsプロジェクト項目 内にマクロをインストールしていることを確認する必要があります。このモジュールにアクセスできるのは、マクロエクスプローラー(ツール->マクロ->マクロエクスプローラー)のみです。

1つの注意、それは現在のような「パックされた」名前空間をサポートしていません

namespace A { namespace B {
...
}
}

[〜#〜]編集[〜#〜]

上記の例のような「パックされた」名前空間をサポートしたり、namespace A { /* Example */などの名前空間の後のコメントをサポートしたりするには、代わりに次の行を使用してみます。

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

私はまだそれをテストする機会がありませんでした、しかしそれは働いているようです。

13
Rod

KindDragonが指摘するように、Visual Studio 2013 Update 2にはインデントを停止するオプションがあります。

TOOLS-> Options-> Text Editor-> C/C++-> Formatting-> Indentation-> Indent namespace contentsのチェックを外すことができます。

45
user64953

コードの最初の行の前には何も挿入しないでください。次の方法でコードのnull行を挿入してみてください(VS2005では機能するようです)。

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

これはインデントを抑制しているようですが、コンパイラが警告を出し、コードレビューア/メンテナが驚くかもしれません! (そして、当然のことながら、通常の場合!)

30
bacar

おそらくあなたが聞きたかったことではありませんが、多くの人がマクロを使用してこれを回避しています:

#define BEGIN_NAMESPACE(x)名前空間x {
#define END_NAMESPACE} 

馬鹿げているように聞こえますが、これを使用しているシステムヘッダーの数に驚くでしょう。 (たとえば、glibcのstl実装には、_GLIBCXX_BEGIN_NAMESPACE()があります。)

{の後にインデントされていない行が表示されると、常にしわが寄る傾向があるため、私は実際にこの方法を好みます。それは私だけです。

13
Ken Simon

名前空間内で型(またはその他)を転送宣言してから、次のように外部で実装することもできます。

namespace test {
    class MyClass;
}

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

ネストされた名前空間がある場合の問題を理解しています。複数のインデントを避けるために、すべてのnamespacesを1行にまとめていました。それは1つのレベルを残しますが、それは多くのレベルほど悪くはありません。 VSを使い始めてからずいぶん昔のことを覚えています。

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

Visual Studio 2017

名前空間インデントメニューVS2017

この「インデント名前空間のコンテンツ」設定には、「ツール」->「オプション」、「テキストエディター」->「C/C++」->「フォーマット」->「インデント」の順に選択できます。メニューの奥深くにありますが、見つかったら非常に役立ちます。

0
Michael Hall