键入时使用 Roslyn 的 CompletionSevice 的最有效方法是什么?
What's the most efficient way to use Roslyn's CompletionSevice when typing?
我正在查看 Roslyn 的 CompletionService
,ShouldTriggerCompletion
定义为
public virtual bool ShouldTriggerCompletion(
SourceText text,
int caretPosition,
CompletionTrigger trigger,
ImmutableHashSet<string> roles = null,
OptionSet options = null
) { … }
其中 CompletionTrigger
是单个 char Character
.
的包装器
这似乎意味着我应该在键入时在每个字符上调用 ShouldTriggerCompletion
— 但这意味着我需要在每个字符上更新 SourceText
,它分配一个 TextChange
的数组,一个新的 SourceText
和可能的其他东西,这取决于它的内部结构。
我对这个 API 的理解正确吗?打字时最有效的使用方法是什么?
编辑: 澄清一下,我知道我可以事后猜测它并且只调用它让我们说 .
。但我的目标是按照预期的方式使用 API,除了已经提供的优化之外,不进行任何优化。
这取决于您要做什么。
如果您确定知道文本的完成触发器,则可以通过在您认为合适的时候自行触发完成来避免调用 ShouldTriggerCompletion
。但是过早的优化并不是您自己重新实现它的好理由。 (您将破坏与在 Roslyn 沙箱中运行的其他程序集的兼容性;您可能会错过边缘情况;语言升级时您不会获得升级;等等)
此外,如果您是调用者,您可能不应该直接调用 ShouldTriggerCompletion
:GetCompletionsAsync
似乎更可能是您想要的。
however that would mean I need to update SourceText on each char, which allocates an array of TextChange, a new SourceText and potentially other things depending on its internal structure
是的,在 Visual Studio 中的每次击键我们都会创建一个新的 SourceText 和一个新的 Document/Project/Solution 快照。我们必须这样做,因为 所有 功能都取决于现有的文档实例。
对于我们来说,这样的操作是便宜的。 Visual Studio 中的文本编辑器组件已经为每次编辑创建了一个便宜的 ITextSnapshot
,它通过非常奇特的数据结构(想想字符串片段的二叉树)来实现,所以这是尽可能便宜的。当我们在编辑器中为文件创建 SourceText 时,我们创建了我们的 own derived type of SourceText 并且我们只是将数据请求转发给编辑器 ITextSnapshot
API。 SourceText 实际上拥有 ITextSnapshot
成员的子集并非巧合,因为我们正是为这种模式设计的!
我正在查看 Roslyn 的 CompletionService
,ShouldTriggerCompletion
定义为
public virtual bool ShouldTriggerCompletion(
SourceText text,
int caretPosition,
CompletionTrigger trigger,
ImmutableHashSet<string> roles = null,
OptionSet options = null
) { … }
其中 CompletionTrigger
是单个 char Character
.
这似乎意味着我应该在键入时在每个字符上调用 ShouldTriggerCompletion
— 但这意味着我需要在每个字符上更新 SourceText
,它分配一个 TextChange
的数组,一个新的 SourceText
和可能的其他东西,这取决于它的内部结构。
我对这个 API 的理解正确吗?打字时最有效的使用方法是什么?
编辑: 澄清一下,我知道我可以事后猜测它并且只调用它让我们说 .
。但我的目标是按照预期的方式使用 API,除了已经提供的优化之外,不进行任何优化。
这取决于您要做什么。
如果您确定知道文本的完成触发器,则可以通过在您认为合适的时候自行触发完成来避免调用 ShouldTriggerCompletion
。但是过早的优化并不是您自己重新实现它的好理由。 (您将破坏与在 Roslyn 沙箱中运行的其他程序集的兼容性;您可能会错过边缘情况;语言升级时您不会获得升级;等等)
此外,如果您是调用者,您可能不应该直接调用 ShouldTriggerCompletion
:GetCompletionsAsync
似乎更可能是您想要的。
however that would mean I need to update SourceText on each char, which allocates an array of TextChange, a new SourceText and potentially other things depending on its internal structure
是的,在 Visual Studio 中的每次击键我们都会创建一个新的 SourceText 和一个新的 Document/Project/Solution 快照。我们必须这样做,因为 所有 功能都取决于现有的文档实例。
对于我们来说,这样的操作是便宜的。 Visual Studio 中的文本编辑器组件已经为每次编辑创建了一个便宜的 ITextSnapshot
,它通过非常奇特的数据结构(想想字符串片段的二叉树)来实现,所以这是尽可能便宜的。当我们在编辑器中为文件创建 SourceText 时,我们创建了我们的 own derived type of SourceText 并且我们只是将数据请求转发给编辑器 ITextSnapshot
API。 SourceText 实际上拥有 ITextSnapshot
成员的子集并非巧合,因为我们正是为这种模式设计的!