3
3
4
4
using System ;
5
5
using System . Collections . Generic ;
6
+ using System . Linq ;
6
7
using System . Management . Automation ;
7
8
using System . Text ;
8
9
using System . Text . RegularExpressions ;
@@ -48,18 +49,20 @@ protected override CompletionRegistrationOptions CreateRegistrationOptions(Compl
48
49
{
49
50
_completionCapability = capability ;
50
51
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 ,
55
56
TriggerCharacters = new [ ] { "." , "-" , ":" , "\\ " , "$" , " " } ,
56
- } ;
57
+ } ;
57
58
}
58
59
59
60
public bool SupportsSnippets => _completionCapability ? . CompletionItem ? . SnippetSupport is true ;
60
61
61
62
public bool SupportsCommitCharacters => _completionCapability ? . CompletionItem ? . CommitCharactersSupport is true ;
62
63
64
+ public bool SupportsMarkdown => _completionCapability ? . CompletionItem ? . DocumentationFormat ? . Contains ( MarkupKind . Markdown ) is true ;
65
+
63
66
public override async Task < CompletionList > Handle ( CompletionParams request , CancellationToken cancellationToken )
64
67
{
65
68
int cursorLine = request . Position . Line + 1 ;
@@ -81,6 +84,61 @@ public override async Task<CompletionList> Handle(CompletionParams request, Canc
81
84
// Handler for "completionItem/resolve". In VSCode this is fired when a completion item is highlighted in the completion list.
82
85
public override async Task < CompletionItem > Handle ( CompletionItem request , CancellationToken cancellationToken )
83
86
{
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
+
84
142
// We currently only support this request for anything that returns a CommandInfo:
85
143
// functions, cmdlets, aliases. No detail means the module hasn't been imported yet and
86
144
// IntelliSense shouldn't import the module to get this info.
@@ -242,15 +300,19 @@ internal CompletionItem CreateCompletionItem(
242
300
CompletionResultType . Command => item with { Kind = CompletionItemKind . Function } ,
243
301
CompletionResultType . ProviderItem or CompletionResultType . ProviderContainer
244
302
=> 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
+ } ,
254
316
CompletionResultType . ParameterName => TryExtractType ( detail , out string type )
255
317
? item with { Kind = CompletionItemKind . Variable , Detail = type }
256
318
// The comparison operators (-eq, -not, -gt, etc) unfortunately come across as
@@ -265,8 +327,10 @@ CompletionResultType.ProviderItem or CompletionResultType.ProviderContainer
265
327
CompletionResultType . Type => detail . StartsWith ( "Class " , StringComparison . CurrentCulture )
266
328
// Custom classes come through as types but the PowerShell completion tooltip
267
329
// 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 } ,
270
334
CompletionResultType . Keyword or CompletionResultType . DynamicKeyword =>
271
335
item with { Kind = CompletionItemKind . Keyword } ,
272
336
_ => throw new ArgumentOutOfRangeException ( nameof ( result ) )
0 commit comments