SnippetCompletionProvider.vb 5.8 KB
Newer Older
J
Jonathon Marolf 已提交
1 2 3
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
4

M
Matt Warren 已提交
5
Imports System.Collections.Immutable
6 7
Imports System.ComponentModel.Composition
Imports System.Threading.Tasks
8 9 10
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Completion
Imports Microsoft.CodeAnalysis.Editor
11
Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities
12
Imports Microsoft.CodeAnalysis.LanguageServices
13
Imports Microsoft.CodeAnalysis.Options
14 15 16 17
Imports Microsoft.CodeAnalysis.Shared.Extensions
Imports Microsoft.CodeAnalysis.Snippets
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.Text.Shared.Extensions
C
chborl 已提交
18
Imports Microsoft.CodeAnalysis.VisualBasic.Extensions
19 20 21 22 23
Imports Microsoft.VisualStudio.Editor
Imports Microsoft.VisualStudio.Text
Imports Microsoft.VisualStudio.Text.Editor

Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Snippets
M
Matt Warren 已提交
24
    <ExportCompletionProviderMef1("SnippetCompletionProvider", LanguageNames.VisualBasic)>
25
    Partial Friend Class SnippetCompletionProvider
D
David Barbet 已提交
26
        Inherits LSPCompletionProvider
M
Matt Warren 已提交
27
        Implements ICustomCommitCompletionProvider
28

29
        Private ReadOnly _threadingContext As IThreadingContext
B
beep boop 已提交
30
        Private ReadOnly _editorAdaptersFactoryService As IVsEditorAdaptersFactoryService
31 32

        <ImportingConstructor>
33 34
        Public Sub New(threadingContext As IThreadingContext, editorAdaptersFactoryService As IVsEditorAdaptersFactoryService)
            _threadingContext = threadingContext
B
beep boop 已提交
35
            Me._editorAdaptersFactoryService = editorAdaptersFactoryService
36 37
        End Sub

M
Matt Warren 已提交
38 39 40 41 42 43
        Friend Overrides ReadOnly Property IsSnippetProvider As Boolean
            Get
                Return True
            End Get
        End Property

44
        Public Overrides Async Function ProvideCompletionsAsync(context As CompletionContext) As Task
45 46 47 48
            Dim document = context.Document
            Dim position = context.Position
            Dim cancellationToken = context.CancellationToken

49 50 51
            Dim snippetInfoService = document.GetLanguageService(Of ISnippetInfoService)()

            If snippetInfoService Is Nothing Then
52
                Return
53 54 55 56
            End If

            Dim snippets = snippetInfoService.GetSnippetsIfAvailable()

57 58 59
            Dim syntaxTree = Await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(False)
            Dim syntaxFacts = document.GetLanguageService(Of ISyntaxFactsService)()
            Dim isPossibleTupleContext = syntaxFacts.IsPossibleTupleContext(syntaxTree, position, cancellationToken)
60

C
chborl 已提交
61
            If (IsInNonUserCode(syntaxTree, position, cancellationToken)) Then
C
chborl 已提交
62 63 64
                Return
            End If

65
            context.IsExclusive = ShouldBeExclusive(context.Options)
66
            context.AddItems(CreateCompletionItems(snippets, isPossibleTupleContext))
67 68
        End Function

69
        Private Function ShouldBeExclusive(options As OptionSet) As Boolean
R
Ravi Chande 已提交
70
            Return options.GetOption(CompletionOptions.SnippetsBehavior, LanguageNames.VisualBasic) = SnippetsRule.IncludeAfterTypingIdentifierQuestionTab
71 72
        End Function

M
Matt Warren 已提交
73 74 75 76
        Private Shared ReadOnly s_commitChars As Char() = {" "c, ";"c, "("c, ")"c, "["c, "]"c, "{"c, "}"c, "."c, ","c, ":"c, "+"c, "-"c, "*"c, "/"c, "\"c, "^"c, "<"c, ">"c, "'"c, "="c}
        Private Shared ReadOnly s_rules As CompletionItemRules = CompletionItemRules.Create(
            commitCharacterRules:=ImmutableArray.Create(CharacterSetModificationRule.Create(CharacterSetModificationKind.Replace, s_commitChars)))

77 78 79 80
        Private Shared ReadOnly s_tupleRules As CompletionItemRules = s_rules.
            WithCommitCharacterRule(CharacterSetModificationRule.Create(CharacterSetModificationKind.Remove, ":"c))

        Private Function CreateCompletionItems(snippets As IEnumerable(Of SnippetInfo), isTupleContext As Boolean) As IEnumerable(Of CompletionItem)
81

M
Matt Warren 已提交
82
            Return snippets.Select(Function(s) CommonCompletionItem.Create(
83
                                       s.Shortcut,
84
                                       displayTextSuffix:="",
85 86
                                       description:=s.Description.ToSymbolDisplayParts(),
                                       glyph:=Glyph.Snippet,
87
                                       rules:=If(isTupleContext, s_tupleRules, s_rules)))
88 89
        End Function

M
Matt Warren 已提交
90
        Friend Overrides Function IsInsertionTrigger(text As SourceText, characterPosition As Integer, options As OptionSet) As Boolean
91
            Return Char.IsLetterOrDigit(text(characterPosition)) AndAlso
92
                options.GetOption(CompletionOptions.TriggerOnTypingLetters2, LanguageNames.VisualBasic)
93 94
        End Function

D
David Barbet 已提交
95 96
        Friend Overrides ReadOnly Property TriggerCharacters As ImmutableHashSet(Of Char) = ImmutableHashSet(Of Char).Empty

C
CyrusNajmabadi 已提交
97 98 99 100 101
        Public Sub Commit(completionItem As CompletionItem,
                          textView As ITextView,
                          subjectBuffer As ITextBuffer,
                          triggerSnapshot As ITextSnapshot,
                          commitChar As Char?) Implements ICustomCommitCompletionProvider.Commit
102
            Dim snippetClient = SnippetExpansionClient.GetSnippetExpansionClient(_threadingContext, textView, subjectBuffer, _editorAdaptersFactoryService)
103

M
Matt Warren 已提交
104
            Dim trackingSpan = triggerSnapshot.CreateTrackingSpan(completionItem.Span.ToSpan(), SpanTrackingMode.EdgeInclusive)
105 106 107 108 109 110 111 112
            Dim currentSpan = trackingSpan.GetSpan(subjectBuffer.CurrentSnapshot)

            subjectBuffer.Replace(currentSpan, completionItem.DisplayText)

            Dim updatedSpan = trackingSpan.GetSpan(subjectBuffer.CurrentSnapshot)
            snippetClient.TryInsertExpansion(updatedSpan.Start, updatedSpan.Start + completionItem.DisplayText.Length)
        End Sub
    End Class
S
Sam Harwell 已提交
113
End Namespace