如何在ICompletionSource中异步更新完成结果?

时间:2014-08-25 14:15:06

标签: visual-studio-extensions visual-studio-sdk

我尝试在Visual Studio中为Google Dart语言实现代码完成。我已在ICompletionSource like this中成功实施了一些硬编码值:

class CompletionSource : ICompletionSource
{
    CompletionSourceProvider provider;
    ITextBuffer buffer;
    ITextDocumentFactoryService textDocumentFactory;
    DartAnalysisService analysisService;

    public CompletionSource(CompletionSourceProvider provider, ITextBuffer buffer, ITextDocumentFactoryService textDocumentFactory, DartAnalysisService analysisService)
    {
        this.provider = provider;
        this.buffer = buffer;
        this.textDocumentFactory = textDocumentFactory;
        this.analysisService = analysisService;
    }

    public void AugmentCompletionSession(ICompletionSession session, IList<CompletionSet> completionSets)
    {
        var triggerPoint = session.GetTriggerPoint(buffer.CurrentSnapshot);
        if (triggerPoint == null)
            return;

        var applicableTo = buffer.CurrentSnapshot.CreateTrackingSpan(new SnapshotSpan(triggerPoint.Value, 1), SpanTrackingMode.EdgeInclusive);

        var completions = new ObservableCollection<Completion>();
        completions.Add(new Completion("Something1"));
        completions.Add(new Completion("Something2"));
        completions.Add(new Completion("Something3"));

        completionSets.Add(new CompletionSet("All", "All", applicableTo, completions, Enumerable.Empty<Completion>()));
    }

    public void Dispose()
    {
        GC.SuppressFinalize(true);
    }
}

一切正常。但是,在实际实现中,获取完成的行为很慢(它由另一个进程处理),所以我需要能够在以后返回这些结果。

如果我同步完成所有工作,编辑器会在请求期间挂起(毫不奇怪)。

文档很差。我尝试了各种各样的事情;包括在IEnumerable<Completion>构造函数中使用CompletionSet个参数;将值插入ObservableCollection<Completion>,在会话和CompletionSet上调用Recalculate()

这是一个在1秒后将第二个值插入完成列表的实现。这不起作用;但对于任何想要尝试的人来说都是一个起点:

    public void AugmentCompletionSession(ICompletionSession session, IList<CompletionSet> completionSets)
    {
        var triggerPoint = session.GetTriggerPoint(buffer.CurrentSnapshot);
        if (triggerPoint == null)
            return;

        ITextDocument doc;
        if (!textDocumentFactory.TryGetTextDocument(buffer, out doc))
            return;

        var applicableTo = buffer.CurrentSnapshot.CreateTrackingSpan(new SnapshotSpan(triggerPoint.Value, 1), SpanTrackingMode.EdgeInclusive);

        var completions = new ObservableCollection<Completion>();
        completions.Add(new Completion("Hard-coded..."));

        var completionSet = new CompletionSet("All", "All", applicableTo, Enumerable.Empty<Completion>(), completions);
        completionSets.Add(completionSet);

        Task.Run(async () =>
        {
            await Task.Delay(1000); // Wait 1s
            completions.Add(new Completion("Danny")); // This doesn't update the code-completion list; why not?
        });
    }

1 个答案:

答案 0 :(得分:0)

您可以在IIntellisenseController的实现中异步触发完成,而不是异步更新完成源。当您检测到需要完成时,首先执行所需结果的后台计算,然后使用ICompletionBroker触发结果显示。