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 構造体 メンバ