@@ -16,12 +16,23 @@ import { TerminalShellType } from '../terminalSuggestMain';
16
16
17
17
const isWindows = osIsWindows ( ) ;
18
18
19
+ export interface IExecutablesInPath {
20
+ completionResources : Set < ICompletionResource > | undefined ;
21
+ labels : Set < string > | undefined ;
22
+ }
23
+
19
24
export class PathExecutableCache implements vscode . Disposable {
20
25
private _disposables : vscode . Disposable [ ] = [ ] ;
21
26
22
27
private _cachedWindowsExeExtensions : { [ key : string ] : boolean | undefined } | undefined ;
23
28
private _cachedExes : Map < string , Set < ICompletionResource > | undefined > = new Map ( ) ;
24
29
30
+ private _inProgressRequest : {
31
+ env : ITerminalEnvironment ;
32
+ shellType : TerminalShellType | undefined ;
33
+ promise : Promise < IExecutablesInPath | undefined > ;
34
+ } | undefined ;
35
+
25
36
constructor ( ) {
26
37
if ( isWindows ) {
27
38
this . _cachedWindowsExeExtensions = vscode . workspace . getConfiguration ( SettingsIds . SuggestPrefix ) . get ( SettingsIds . CachedWindowsExecutableExtensionsSuffixOnly ) ;
@@ -41,15 +52,36 @@ export class PathExecutableCache implements vscode.Disposable {
41
52
}
42
53
43
54
refresh ( directory ?: string ) : void {
44
- console . trace ( 'clear cache' ) ;
45
55
if ( directory ) {
46
56
this . _cachedExes . delete ( directory ) ;
47
57
} else {
48
58
this . _cachedExes . clear ( ) ;
49
59
}
50
60
}
51
61
52
- async getExecutablesInPath ( env : ITerminalEnvironment = process . env , shellType ?: TerminalShellType ) : Promise < { completionResources : Set < ICompletionResource > | undefined ; labels : Set < string > | undefined } | undefined > {
62
+ async getExecutablesInPath ( env : ITerminalEnvironment = process . env , shellType ?: TerminalShellType ) : Promise < IExecutablesInPath | undefined > {
63
+ if ( this . _inProgressRequest &&
64
+ this . _inProgressRequest . env === env &&
65
+ this . _inProgressRequest . shellType === shellType
66
+ ) {
67
+ return this . _inProgressRequest . promise ;
68
+ }
69
+
70
+ const promise = this . _doGetExecutablesInPath ( env , shellType ) ;
71
+
72
+ this . _inProgressRequest = {
73
+ env,
74
+ shellType,
75
+ promise,
76
+ } ;
77
+
78
+ await promise ;
79
+ this . _inProgressRequest = undefined ;
80
+
81
+ return promise ;
82
+ }
83
+
84
+ private async _doGetExecutablesInPath ( env : ITerminalEnvironment , shellType ?: TerminalShellType ) : Promise < IExecutablesInPath | undefined > {
53
85
// Create cache key
54
86
let pathValue : string | undefined ;
55
87
if ( shellType === TerminalShellType . GitBash ) {
@@ -84,7 +116,7 @@ export class PathExecutableCache implements vscode.Disposable {
84
116
}
85
117
} else {
86
118
// Not cached, need to scan this directory
87
- promises . push ( this . _getExecutablesInPath ( pathDir , pathSeparator , labels ) ) ;
119
+ promises . push ( this . _getExecutablesInSinglePath ( pathDir , pathSeparator , labels ) ) ;
88
120
}
89
121
}
90
122
@@ -115,7 +147,7 @@ export class PathExecutableCache implements vscode.Disposable {
115
147
return { completionResources : executables , labels } ;
116
148
}
117
149
118
- private async _getExecutablesInPath ( path : string , pathSeparator : string , labels : Set < string > ) : Promise < Set < ICompletionResource > | undefined > {
150
+ private async _getExecutablesInSinglePath ( path : string , pathSeparator : string , labels : Set < string > ) : Promise < Set < ICompletionResource > | undefined > {
119
151
try {
120
152
const dirExists = await fs . stat ( path ) . then ( stat => stat . isDirectory ( ) ) . catch ( ( ) => false ) ;
121
153
if ( ! dirExists ) {
0 commit comments