@@ -179,9 +179,30 @@ export default class BashServer {
179
179
// eslint-disable-next-line no-console
180
180
return { contents : getMarkdownContent ( shellDocumentation ) }
181
181
}
182
- }
182
+ } else {
183
+ const symbolDocumentation = deduplicateSymbols ( {
184
+ symbols : this . analyzer . findSymbolsMatchingWord ( {
185
+ exactMatch : true ,
186
+ word,
187
+ } ) ,
188
+ currentUri,
189
+ } )
190
+ // do not return hover referencing for the current line
191
+ . filter ( symbol => symbol . location . range . start . line !== params . position . line )
192
+ . map ( ( symbol : LSP . SymbolInformation ) =>
193
+ symbol . location . uri !== currentUri
194
+ ? `${ symbolKindToDescription ( symbol . kind ) } defined in ${ path . relative (
195
+ currentUri ,
196
+ symbol . location . uri ,
197
+ ) } `
198
+ : `${ symbolKindToDescription ( symbol . kind ) } defined on line ${ symbol . location
199
+ . range . start . line + 1 } `,
200
+ )
183
201
184
- // FIXME: could also be a symbol
202
+ if ( symbolDocumentation . length === 1 ) {
203
+ return { contents : symbolDocumentation [ 0 ] }
204
+ }
205
+ }
185
206
186
207
return null
187
208
}
@@ -238,6 +259,7 @@ export default class BashServer {
238
259
? [ ]
239
260
: getCompletionItemsForSymbols ( {
240
261
symbols : this . analyzer . findSymbolsMatchingWord ( {
262
+ exactMatch : false ,
241
263
word,
242
264
} ) ,
243
265
currentUri,
@@ -304,42 +326,39 @@ export default class BashServer {
304
326
305
327
this . connection . console . log ( `onCompletionResolve name=${ name } type=${ type } ` )
306
328
307
- const getMarkdownCompletionItem = ( doc : string ) => ( {
308
- ...item ,
309
- // LSP.MarkupContent
310
- documentation : {
311
- value : [ '``` man' , doc , '```' ] . join ( '\n' ) ,
312
- // Passed as markdown for syntax highlighting
313
- kind : 'markdown' as const ,
314
- } ,
315
- } )
316
-
317
329
try {
318
- if ( type === CompletionItemDataType . Executable ) {
319
- const doc = await this . executables . documentation ( name )
320
- return getMarkdownCompletionItem ( doc )
321
- } else if ( type === CompletionItemDataType . Builtin ) {
322
- const doc = await Builtins . documentation ( name )
323
- return getMarkdownCompletionItem ( doc )
324
- } else if ( type === CompletionItemDataType . ReservedWord ) {
325
- const doc = await ReservedWords . documentation ( name )
326
- return getMarkdownCompletionItem ( doc )
327
- } else {
328
- return item
330
+ let documentation = null
331
+
332
+ if (
333
+ type === CompletionItemDataType . Executable ||
334
+ type === CompletionItemDataType . Builtin ||
335
+ type === CompletionItemDataType . ReservedWord
336
+ ) {
337
+ documentation = await getShellDocumentation ( { word : name } )
329
338
}
339
+
340
+ return documentation
341
+ ? {
342
+ ...item ,
343
+ documentation : getMarkdownContent ( documentation ) ,
344
+ }
345
+ : item
330
346
} catch ( error ) {
331
347
return item
332
348
}
333
349
}
334
350
}
335
351
336
- function getCompletionItemsForSymbols ( {
352
+ /**
353
+ * Deduplicate symbols by prioritizing the current file.
354
+ */
355
+ function deduplicateSymbols ( {
337
356
symbols,
338
357
currentUri,
339
358
} : {
340
359
symbols : LSP . SymbolInformation [ ]
341
360
currentUri : string
342
- } ) : BashCompletionItem [ ] {
361
+ } ) {
343
362
const isCurrentFile = ( { location : { uri } } : LSP . SymbolInformation ) =>
344
363
uri === currentUri
345
364
@@ -349,7 +368,7 @@ function getCompletionItemsForSymbols({
349
368
350
369
const symbolsOtherFiles = symbols
351
370
. filter ( s => ! isCurrentFile ( s ) )
352
- // Remove identical symbols
371
+ // Remove identical symbols matching current file
353
372
. filter (
354
373
symbolOtherFiles =>
355
374
! symbolsCurrentFile . some (
@@ -358,24 +377,33 @@ function getCompletionItemsForSymbols({
358
377
) ,
359
378
)
360
379
361
- return uniqueBasedOnHash (
362
- [ ...symbolsCurrentFile , ...symbolsOtherFiles ] ,
363
- getSymbolId ,
364
- ) . map ( ( symbol : LSP . SymbolInformation ) => ( {
365
- label : symbol . name ,
366
- kind : symbolKindToCompletionKind ( symbol . kind ) ,
367
- data : {
368
- name : symbol . name ,
369
- type : CompletionItemDataType . Symbol ,
370
- } ,
371
- documentation :
372
- symbol . location . uri !== currentUri
373
- ? `${ symbolKindToDescription ( symbol . kind ) } defined in ${ path . relative (
374
- currentUri ,
375
- symbol . location . uri ,
376
- ) } `
377
- : undefined ,
378
- } ) )
380
+ return uniqueBasedOnHash ( [ ...symbolsCurrentFile , ...symbolsOtherFiles ] , getSymbolId )
381
+ }
382
+
383
+ function getCompletionItemsForSymbols ( {
384
+ symbols,
385
+ currentUri,
386
+ } : {
387
+ symbols : LSP . SymbolInformation [ ]
388
+ currentUri : string
389
+ } ) : BashCompletionItem [ ] {
390
+ return deduplicateSymbols ( { symbols, currentUri } ) . map (
391
+ ( symbol : LSP . SymbolInformation ) => ( {
392
+ label : symbol . name ,
393
+ kind : symbolKindToCompletionKind ( symbol . kind ) ,
394
+ data : {
395
+ name : symbol . name ,
396
+ type : CompletionItemDataType . Symbol ,
397
+ } ,
398
+ documentation :
399
+ symbol . location . uri !== currentUri
400
+ ? `${ symbolKindToDescription ( symbol . kind ) } defined in ${ path . relative (
401
+ currentUri ,
402
+ symbol . location . uri ,
403
+ ) } `
404
+ : undefined ,
405
+ } ) ,
406
+ )
379
407
}
380
408
381
409
function symbolKindToCompletionKind ( s : LSP . SymbolKind ) : LSP . CompletionItemKind {
@@ -440,3 +468,9 @@ function symbolKindToDescription(s: LSP.SymbolKind): string {
440
468
return 'Keyword'
441
469
}
442
470
}
471
+
472
+ const getMarkdownContent = ( documentation : string ) : LSP . MarkupContent => ( {
473
+ value : [ '``` man' , documentation , '```' ] . join ( '\n' ) ,
474
+ // Passed as markdown for syntax highlighting
475
+ kind : 'markdown' as const ,
476
+ } )
0 commit comments