public override async Task <VSInternalInlineCompletionList?> HandleRequestAsync(VSInternalInlineCompletionRequest request, RequestContext context, CancellationToken cancellationToken)
    {
        Contract.ThrowIfNull(context.Document);

        // First get available snippets if any.
        var snippetInfoService = context.Document.Project.GetRequiredLanguageService <ISnippetInfoService>();
        var snippetInfo        = snippetInfoService.GetSnippetsIfAvailable();

        if (!snippetInfo.Any())
        {
            return(null);
        }

        // Then attempt to get the word at the requested position.
        var sourceText = await context.Document.GetTextAsync(cancellationToken).ConfigureAwait(false);

        var syntaxFactsService = context.Document.Project.GetRequiredLanguageService <ISyntaxFactsService>();
        var linePosition       = ProtocolConversions.PositionToLinePosition(request.Position);
        var position           = sourceText.Lines.GetPosition(linePosition);

        if (!SnippetUtilities.TryGetWordOnLeft(position, sourceText, syntaxFactsService, out var wordOnLeft))
        {
            return(null);
        }

        // Find the snippet with shortcut text that matches the typed word.
        var wordText = sourceText.GetSubText(wordOnLeft.Value).ToString();

        if (!BuiltInSnippets.Contains(wordText, StringComparer.OrdinalIgnoreCase))
        {
            return(null);
        }

        var matchingSnippetInfo = snippetInfo.First(s => wordText.Equals(s.Shortcut, StringComparison.OrdinalIgnoreCase));

        var parsedSnippet = _xmlSnippetParser.GetParsedXmlSnippet(matchingSnippetInfo, context);

        if (parsedSnippet == null)
        {
            return(null);
        }

        // Use the formatting options specified by the client to format the snippet.
        var formattingOptions = await ProtocolConversions.GetFormattingOptionsAsync(request.Options, context.Document, cancellationToken).ConfigureAwait(false);

        var formattedLspSnippet = await GetFormattedLspSnippetAsync(parsedSnippet, wordOnLeft.Value, context.Document, sourceText, formattingOptions, cancellationToken).ConfigureAwait(false);

        return(new VSInternalInlineCompletionList
        {
            Items = new VSInternalInlineCompletionItem[]
            {
                new VSInternalInlineCompletionItem
                {
                    Range = ProtocolConversions.TextSpanToRange(wordOnLeft.Value, sourceText),
                    Text = formattedLspSnippet,
                    TextFormat = InsertTextFormat.Snippet,
                }
            }
        });
    }
Example #2
0
        protected bool TryHandleTypedSnippet(ITextView textView, ITextBuffer subjectBuffer, CancellationToken cancellationToken)
        {
            AssertIsForeground();

            var document = subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null)
            {
                return(false);
            }

            var currentText        = subjectBuffer.AsTextContainer().CurrentText;
            var syntaxFactsService = document.GetLanguageService <ISyntaxFactsService>();

            var endPositionInSubjectBuffer = textView.GetCaretPoint(subjectBuffer);

            if (endPositionInSubjectBuffer == null)
            {
                return(false);
            }

            if (!SnippetUtilities.TryGetWordOnLeft(endPositionInSubjectBuffer.Value.Position, currentText, syntaxFactsService, out var span))
            {
                return(false);
            }

            if (!IsSnippetExpansionContext(document, span.Value.Start, cancellationToken))
            {
                return(false);
            }

            return(GetSnippetExpansionClient(textView, subjectBuffer).TryInsertExpansion(span.Value.Start, span.Value.End, cancellationToken));
        }