Visual Studioは、名前空間内のコードをインデントしようとし続けます。
例えば:
_namespace Foo
{
void Bar();
void Bar()
{
}
}
_
ここで、インデントを手動で解除すると、そのままになります。しかし残念ながら、コメントなど、void Bar();
の直前に何かを追加すると、VSはインデントを試み続けます。
これは非常に煩わしいので、基本的にこの唯一の理由により、C++で名前空間を使用することはほとんどありません。なぜインデントしようとするのか(1つまたは5つのタブをインデントする意味は何ですかファイル全体?)、または停止させる方法がわかりません。
この動作を停止する方法はありますか?設定オプション、アドイン、レジストリ設定、devenv.exeを直接変更するハックさえも。
ここにあなたを助けることができるマクロがあります。現在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
私はまだそれをテストする機会がありませんでした、しかしそれは働いているようです。
KindDragonが指摘するように、Visual Studio 2013 Update 2にはインデントを停止するオプションがあります。
TOOLS-> Options-> Text Editor-> C/C++-> Formatting-> Indentation-> Indent namespace contentsのチェックを外すことができます。
コードの最初の行の前には何も挿入しないでください。次の方法でコードのnull行を挿入してみてください(VS2005では機能するようです)。
namespace foo
{; // !<---
void Test();
}
これはインデントを抑制しているようですが、コンパイラが警告を出し、コードレビューア/メンテナが驚くかもしれません! (そして、当然のことながら、通常の場合!)
おそらくあなたが聞きたかったことではありませんが、多くの人がマクロを使用してこれを回避しています:
#define BEGIN_NAMESPACE(x)名前空間x { #define END_NAMESPACE}
馬鹿げているように聞こえますが、これを使用しているシステムヘッダーの数に驚くでしょう。 (たとえば、glibcのstl実装には、_GLIBCXX_BEGIN_NAMESPACE()
があります。)
{
の後にインデントされていない行が表示されると、常にしわが寄る傾向があるため、私は実際にこの方法を好みます。それは私だけです。
名前空間内で型(またはその他)を転送宣言してから、次のように外部で実装することもできます。
namespace test {
class MyClass;
}
class test::MyClass {
//...
};
ネストされた名前空間がある場合の問題を理解しています。複数のインデントを避けるために、すべてのnamespace
sを1行にまとめていました。それは1つのレベルを残しますが、それは多くのレベルほど悪くはありません。 VSを使い始めてからずいぶん昔のことを覚えています。
namespace outer { namespace middle { namespace inner {
void Test();
.....
}}}
Visual Studio 2017
この「インデント名前空間のコンテンツ」設定には、「ツール」->「オプション」、「テキストエディター」->「C/C++」->「フォーマット」->「インデント」の順に選択できます。メニューの奥深くにありますが、見つかったら非常に役立ちます。