IIndentServiceProviderを実装したクラスを作成し、そのインスタンスを言語のServiceManagerに登録してください。もしすでにインデントサービスが登録されている場合は、それを削除して新たに作り直してください。

IIndentServiceProviderを実装したクラスで定義しなければならないメソッドについては、以下のAPIリファレンスをご覧ください。

 

例えば、

  • “{” + 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リファレンス

 

Tagged:

製品について

Ultimate UI for WPF