修正された回答:
ああ、なるほど。明示的なコマンドからではなく、入力による完了トリガーについて言及していると考えて、あなたの質問を解釈しました。C# エディターで "show whitespace" を有効にすると、ここで何を行うかを確認できます。"show completion" コマンドをトリガーすると、明示的に空白が認識されるため、仮想空間で浮遊することはありません。おそらくこれも行う必要があります。(または、シナリオを検出し、ApplicableTo スパンを調整することで最初の入力時に修正することもできますが、おそらく問題に値するものではありません。)
挿入する空白は IEditorOperations から取得できます。したがって、MEF は IEditorOperationsFactoryService をインポートしてから、次のようにします。
var editorOperations = editorOperationsFactoryService.GetEditorOperations(textView);
var whitespace = editorOperations.GetWhitespaceForVirtualSpace(textView.Caret.Position.VirtualBufferPosition);
if (whitespace.Length != 0)
{
textView.TextBuffer.Insert(textView.Caret.Position.BufferPosition, whitespace);
}
(冗談はさておき、私がこれに答えたとき、Roslyn C# および VB エディターでこれをどのように処理したか知りたいと思っていました。答えは「そうではありません」でしたが、コードの後半で純粋に運が良かったので、フィルタリングは引き続き機能しました。)
元の回答:
問題の説明から、次のように補完を実装していると思われます。文字が入力されようとしていることがわかっており (キーボード フィルターまたは を介してIOleCommandTarget
)、追跡スパンが空のスパンである ICompletionSession をトリガーします。現在のキャレット位置。
これを修正する最善の方法は、キーが押されてエディターに入る前ではなく、キーが押された後にセッションをトリガーすることです。これは、C# と VB の補完のために Roslyn 実装で行っていることです。次に、AugmentCompletionSession 呼び出しで CompletionSet を作成するときに、キャレットの周囲の空白以外の文字で構成される「適用対象」スパンを計算します。これを計算する最も簡単な方法GetWordExtent
は、テキスト構造ナビゲーターから呼び出すことです。
これにより、他のシナリオが正しく機能します。ユーザーが C と入力し、Esc キーを押して、引き続き識別子を入力するシナリオを考えてみましょう。完了を再度トリガーしたい場合は、とにかく「C」がスパンの一部としてカウントされるように計算を行う必要があります。