@@ -616,54 +616,62 @@ class PersistedWidgetSize {
616
616
}
617
617
}
618
618
619
- export function parseCompletionsFromShell ( rawCompletions : PwshCompletion | PwshCompletion [ ] | CompressedPwshCompletion [ ] | CompressedPwshCompletion ) {
619
+ export function parseCompletionsFromShell ( rawCompletions : PwshCompletion | PwshCompletion [ ] | CompressedPwshCompletion [ ] | CompressedPwshCompletion ) : SimpleCompletionItem [ ] {
620
620
if ( ! rawCompletions ) {
621
621
return [ ] ;
622
622
}
623
+ let typedRawCompletions : PwshCompletion [ ] ;
623
624
if ( ! Array . isArray ( rawCompletions ) ) {
624
- return [ rawCompletions ] . map ( e => ( new SimpleCompletionItem ( {
625
- label : parseCompletionText ( e . CompletionText , e . ResultType ) ,
626
- icon : pwshTypeToIconMap [ e . ResultType ] ,
627
- detail : e . ToolTip ,
628
- isFile : e . ResultType === 3 ,
629
- } ) ) ) ;
630
- }
631
- if ( rawCompletions . length === 0 ) {
632
- return [ ] ;
633
- }
634
- if ( typeof rawCompletions [ 0 ] === 'string' ) {
635
- return [ rawCompletions as CompressedPwshCompletion ] . map ( e => ( new SimpleCompletionItem ( {
636
- label : parseCompletionText ( e [ 0 ] , e [ 1 ] ) ,
637
- icon : pwshTypeToIconMap [ e [ 1 ] ] ,
638
- detail : e [ 2 ] ,
639
- isFile : e [ 1 ] === 3 ,
640
- } ) ) ) ;
641
- }
642
- if ( Array . isArray ( rawCompletions [ 0 ] ) ) {
643
- return ( rawCompletions as CompressedPwshCompletion [ ] ) . map ( e => ( new SimpleCompletionItem ( {
644
- label : parseCompletionText ( e [ 0 ] , e [ 1 ] ) ,
645
- icon : pwshTypeToIconMap [ e [ 1 ] ] ,
646
- detail : e [ 2 ] ,
647
- isFile : e [ 1 ] === 3 ,
648
- } ) ) ) ;
625
+ typedRawCompletions = [ rawCompletions ] ;
626
+ } else {
627
+ if ( rawCompletions . length === 0 ) {
628
+ return [ ] ;
629
+ }
630
+ if ( typeof rawCompletions [ 0 ] === 'string' ) {
631
+ typedRawCompletions = [ rawCompletions as CompressedPwshCompletion ] . map ( e => ( {
632
+ CompletionText : e [ 0 ] ,
633
+ ResultType : e [ 1 ] ,
634
+ ToolTip : e [ 2 ] ,
635
+ } ) ) ;
636
+ } else if ( Array . isArray ( rawCompletions [ 0 ] ) ) {
637
+ typedRawCompletions = ( rawCompletions as CompressedPwshCompletion [ ] ) . map ( e => ( {
638
+ CompletionText : e [ 0 ] ,
639
+ ResultType : e [ 1 ] ,
640
+ ToolTip : e [ 2 ] ,
641
+ } ) ) ;
642
+ } else {
643
+ typedRawCompletions = rawCompletions as PwshCompletion [ ] ;
644
+ }
649
645
}
650
- return ( rawCompletions as PwshCompletion [ ] ) . map ( e => ( new SimpleCompletionItem ( {
651
- label : parseCompletionText ( e . CompletionText , e . ResultType ) ,
652
- icon : pwshTypeToIconMap [ e . ResultType ] ,
653
- detail : e . ToolTip ,
654
- isFile : e . ResultType === 3 ,
655
- } ) ) ) ;
646
+ return typedRawCompletions . map ( e => rawCompletionToSimpleCompletionItem ( e ) ) ;
656
647
}
657
648
658
- function parseCompletionText ( completionText : string , resultType : number ) : string {
649
+ function rawCompletionToSimpleCompletionItem ( rawCompletion : PwshCompletion ) : SimpleCompletionItem {
659
650
// HACK: Somewhere along the way from the powershell script to here, the path separator at the
660
651
// end of directories may go missing, likely because `\"` -> `"`. As a result, make sure there
661
652
// is a trailing separator at the end of all directory completions. This should not be done for
662
653
// `.` and `..` entries because they are optimized not for navigating to different directories
663
654
// but for passing as args.
664
- if ( resultType === 4 && ! completionText . match ( / ^ \. \. ? $ / ) && ! completionText . match ( / [ \\ \/ ] $ / ) ) {
665
- const separator = completionText . match
CD51
( / (?< sep > [ \\ \/ ] ) / ) ?. groups ?. sep ?? sep ;
666
- return completionText + separator ;
655
+ let label = rawCompletion . CompletionText ;
656
+ if ( rawCompletion . ResultType === 4 && ! label . match ( / ^ \. \. ? $ / ) && ! label . match ( / [ \\ \/ ] $ / ) ) {
657
+ const separator = label . match ( / (?< sep > [ \\ \/ ] ) / ) ?. groups ?. sep ?? sep ;
658
+ label = label + separator ;
667
659
}
668
- return completionText ;
660
+
661
+ // Pwsh gives executables a result type of 2, but we want to treat them as files wrt the sorting
662
+ // and file extension score boost. An example of where this improves the experience is typing
663
+ // `git`, `git.exe` should appear at the top and beat `git-lfs.exe`. Keep the same icon though.
664
+ const icon = pwshTypeToIconMap [ rawCompletion . ResultType ] ;
665
+ const isExecutable = rawCompletion . ResultType === 2 && rawCompletion . CompletionText . endsWith ( '.exe' ) ;
666
+ if ( isExecutable ) {
667
+ // icon = Codicon.play;
668
+ rawCompletion . ResultType = 3 ;
669
+ }
670
+
671
+ return new SimpleCompletionItem ( {
672
+ label,
673
+ icon,
674
+ detail : rawCompletion . ToolTip ,
675
+ isFile : rawCompletion . ResultType === 3 ,
676
+ } ) ;
669
677
}
0 commit comments