33
44using System ;
55using System . Collections . Generic ;
6+ using System . Linq ;
67using System . Management . Automation ;
78using System . Text ;
89using System . Text . RegularExpressions ;
@@ -48,18 +49,20 @@ protected override CompletionRegistrationOptions CreateRegistrationOptions(Compl
4849 {
4950 _completionCapability = capability ;
5051 return new CompletionRegistrationOptions ( )
51- {
52- // TODO: What do we do with the arguments?
53- DocumentSelector = LspUtils . PowerShellDocumentSelector ,
54- ResolveProvider = true ,
52+ {
53+ // TODO: What do we do with the arguments?
54+ DocumentSelector = LspUtils . PowerShellDocumentSelector ,
55+ ResolveProvider = true ,
5556 TriggerCharacters = new [ ] { "." , "-" , ":" , "\\ " , "$" , " " } ,
56- } ;
57+ } ;
5758 }
5859
5960 public bool SupportsSnippets => _completionCapability ? . CompletionItem ? . SnippetSupport is true ;
6061
6162 public bool SupportsCommitCharacters => _completionCapability ? . CompletionItem ? . CommitCharactersSupport is true ;
6263
64+ public bool SupportsMarkdown => _completionCapability ? . CompletionItem ? . DocumentationFormat ? . Contains ( MarkupKind . Markdown ) is true ;
65+
6366 public override async Task < CompletionList > Handle ( CompletionParams request , CancellationToken cancellationToken )
6467 {
6568 int cursorLine = request . Position . Line + 1 ;
@@ -81,6 +84,61 @@ public override async Task<CompletionList> Handle(CompletionParams request, Canc
8184 // Handler for "completionItem/resolve". In VSCode this is fired when a completion item is highlighted in the completion list.
8285 public override async Task < CompletionItem > Handle ( CompletionItem request , CancellationToken cancellationToken )
8386 {
87+ if ( SupportsMarkdown )
88+ {
89+ if ( request . Kind is CompletionItemKind . Method )
90+ {
91+ string documentation = FormatUtils . GetMethodDocumentation (
92+ _logger ,
93+ request . Data . ToString ( ) ,
94+ out MarkupKind kind ) ;
95+
96+ return request with
97+ {
98+ Documentation = new MarkupContent ( )
99+ {
100+ Kind = kind ,
101+ Value = documentation ,
102+ } ,
103+ } ;
104+ }
105+
106+ if ( request . Kind is CompletionItemKind . Class or CompletionItemKind . TypeParameter or CompletionItemKind . Enum )
107+ {
108+ string documentation = FormatUtils . GetTypeDocumentation (
109+ _logger ,
110+ request . Detail ,
111+ out MarkupKind kind ) ;
112+
113+ return request with
114+ {
115+ Detail = null ,
116+ Documentation = new MarkupContent ( )
117+ {
118+ Kind = kind ,
119+ Value = documentation ,
120+ } ,
121+ } ;
122+ }
123+
124+ if ( request . Kind is CompletionItemKind . EnumMember or CompletionItemKind . Property or CompletionItemKind . Field )
125+ {
126+ string documentation = FormatUtils . GetPropertyDocumentation (
127+ _logger ,
128+ request . Data . ToString ( ) ,
129+ out MarkupKind kind ) ;
130+
131+ return request with
132+ {
133+ Documentation = new MarkupContent ( )
134+ {
135+ Kind = kind ,
136+ Value = documentation ,
137+ } ,
138+ } ;
139+ }
140+ }
141+
84142 // We currently only support this request for anything that returns a CommandInfo:
85143 // functions, cmdlets, aliases. No detail means the module hasn't been imported yet and
86144 // IntelliSense shouldn't import the module to get this info.
@@ -242,15 +300,19 @@ internal CompletionItem CreateCompletionItem(
242300 CompletionResultType . Command => item with { Kind = CompletionItemKind . Function } ,
243301 CompletionResultType . ProviderItem or CompletionResultType . ProviderContainer
244302 => CreateProviderItemCompletion ( item , result , scriptFile , textToBeReplaced ) ,
245- ? item with
246- {
247- Kind = CompletionItemKind . Folder ,
248- InsertTextFormat = InsertTextFormat . Snippet ,
249- TextEdit = textEdit with { NewText = snippet }
250- }
251- : item with { Kind = CompletionItemKind . Folder } ,
252- CompletionResultType. Property => item with { Kind = CompletionItemKind . Property } ,
253- CompletionResultType . Method => item with { Kind = CompletionItemKind . Method } ,
303+ CompletionResultType . Property => item with
304+ {
305+ Kind = CompletionItemKind . Property ,
306+ Detail = SupportsMarkdown ? null : detail ,
307+ Data = SupportsMarkdown ? detail : null ,
308+ CommitCharacters = MaybeAddCommitCharacters ( "." ) ,
309+ } ,
310+ CompletionResultType . Method => item with
311+ {
312+ Kind = CompletionItemKind . Method ,
313+ Data = item . Detail ,
314+ Detail = SupportsMarkdown ? null : item . Detail ,
315+ } ,
254316 CompletionResultType . ParameterName => TryExtractType ( detail , out string type )
255317 ? item with { Kind = CompletionItemKind . Variable , Detail = type }
256318 // The comparison operators (-eq, -not, -gt, etc) unfortunately come across as
@@ -265,8 +327,10 @@ CompletionResultType.ProviderItem or CompletionResultType.ProviderContainer
265327 CompletionResultType . Type => detail . StartsWith ( "Class " , StringComparison . CurrentCulture )
266328 // Custom classes come through as types but the PowerShell completion tooltip
267329 // will start with "Class ", so we can more accurately display its icon.
268- ? item with { Kind = CompletionItemKind . Class }
269- : item with { Kind = CompletionItemKind . TypeParameter } ,
330+ ? item with { Kind = CompletionItemKind . Class , Detail = detail . Substring ( "Class " . Length ) }
331+ : detail . StartsWith ( "Enum " , StringComparison . CurrentCulture )
332+ ? item with { Kind = CompletionItemKind . Enum , Detail = detail . Substring ( "Enum " . Length ) }
333+ : item with { Kind = CompletionItemKind . TypeParameter } ,
270334 CompletionResultType . Keyword or CompletionResultType . DynamicKeyword =>
271335 item with { Kind = CompletionItemKind . Keyword } ,
272336 _ => throw new ArgumentOutOfRangeException ( nameof ( result ) )
0 commit comments