IIndentServiceProviderを実装したクラスを作成し、そのインスタンスを言語のServiceManagerに登録してください。もしすでにインデントサービスが登録されている場合は、それを削除して新たに作り直してください。
IIndentServiceProviderを実装したクラスで定義しなければならないメソッドについては、以下のAPIリファレンスをご覧ください。
- IIndentServiceProvider インターフェース メンバ
例えば、
- “{” + Enter押下時に自動で8文字インデントする。
- “}”押下時、その行のテキストが”}”のみだったら8文字アウトデントする。
といった実装をする場合は、以下のようなコードになります。
1. LanguageにIIndentServiceProviderを実装したクラスのインスタンスを登録する。
// LanguageにIIndentServiceProviderを実装したクラスのインスタンスを登録する。 _customLanguage.ServicesManager.RegisterService<IIndentServiceProvider>(new MyCustomIndentServiceProvider());
2. IIndentServiceProviderを実装したクラスを定義する。
// IIndentServiceProviderを実装したクラスの実体
internal class MyCustomIndentServiceProvider : IIndentServiceProvider
{
// Enterキー押下時、および、IsSignificantForIndentでtrueが返されたときに呼び出されるメソッド
public int CalculateLineIndent(TextDocument document, int lineIndex)
{
// 現在のTextDocumentのスナップショットを取得する。
TextDocumentSnapshot snapshot = document.CurrentSnapshot;
// 現在の行、現在の行のトークンの数、現在の行のインデント数を取得する。
SnapshotLineInfo currentLine = snapshot.LineFromIndex(lineIndex);
int currentLineTokenCount = currentLine.TokenCount;
int currentLineIndent = currentLine.GetIndent();
// 現在の行の文字列から空白を取り除くと"}"のみになる場合
if (currentLine.GetText(false).Trim() == "}")
{
// アウトデント
if (currentLineIndent >= 8) return currentLineIndent - 8;
else return 0;
}
// 前の行がある場合
if (lineIndex > 0)
{
// 1つ前の行、1つ前の行のトークンの数、1つ前の行のインデント数を取得する。
SnapshotLineInfo previousLine = snapshot.LineFromIndex(lineIndex - 1);
int previousLineTokenCount = previousLine.TokenCount;
int previousLineIndent = previousLine.GetIndent();
// 1つ前の行の最後が"{" + 改行の場合、インデントを8増やす。
if (previousLineTokenCount > 1)
{
Token previousLineLastToken = previousLine.GetTokenAtIndex(previousLineTokenCount - 1);
Token previousLineLastButOneToken = previousLine.GetTokenAtIndex(previousLine.TokenCount - 2);
if(previousLineLastButOneToken.Text == "{" && previousLineLastToken.Text == "\r\n")
{
int newIndent = currentLineIndent + 8;
return newIndent;
}
}
// 上記の条件に一つも当てはまらなかった場合は、1つ前の行のインデント数を返す
return previousLineIndent;
}
// 上記の条件に一つも当てはまらなかった場合は、現在の行のインデント数を返す
return currentLineIndent;
}
public bool? IsSignificantForIndent(Token token)
{
// "}"が入力された場合は、即座にCalculateLineIndentを呼び出す
if (token.Text == "}") return true;
return false;
}
}
実行結果

サンプル
APIリファレンス
- IIndentServiceProvider インターフェース メンバ
- RegisterService メソッド
- UnregisterService メソッド
- TextDocument クラス メンバ
- SnapshotLineInfo 構造体 メンバ
- Token 構造体 メンバ