diff --git a/extensions/terminal-suggest/src/env/pathExecutableCache.ts b/extensions/terminal-suggest/src/env/pathExecutableCache.ts index c7cb9f77d88..6576bb59894 100644 --- a/extensions/terminal-suggest/src/env/pathExecutableCache.ts +++ b/extensions/terminal-suggest/src/env/pathExecutableCache.ts @@ -103,6 +103,7 @@ export class PathExecutableCache implements vscode.Disposable { // Extract executables from PATH const paths = pathValue.split(isWindows ? ';' : ':'); const pathSeparator = isWindows ? '\\' : '/'; + const promisePaths: string[] = []; const promises: Promise | undefined>[] = []; const labels: Set = new Set(); @@ -116,6 +117,7 @@ export class PathExecutableCache implements vscode.Disposable { } } else { // Not cached, need to scan this directory + promisePaths.push(pathDir); promises.push(this._getExecutablesInSinglePath(pathDir, pathSeparator, labels)); } } @@ -123,11 +125,9 @@ export class PathExecutableCache implements vscode.Disposable { // Process uncached directories if (promises.length > 0) { const resultSets = await Promise.all(promises); - let uncachedPathIndex = 0; - - for (const pathDir of paths) { + for (const [i, resultSet] of resultSets.entries()) { + const pathDir = promisePaths[i]; if (!this._cachedExes.has(pathDir)) { - const resultSet = resultSets[uncachedPathIndex++]; this._cachedExes.set(pathDir, resultSet || new Set()); } } @@ -135,7 +135,12 @@ export class PathExecutableCache implements vscode.Disposable { // Merge all results from all directories const executables = new Set(); + const processedPaths: Set = new Set(); for (const pathDir of paths) { + if (processedPaths.has(pathDir)) { + continue; + } + processedPaths.add(pathDir); const dirExecutables = this._cachedExes.get(pathDir); if (dirExecutables) { for (const executable of dirExecutables) { diff --git a/extensions/terminal-suggest/src/terminalSuggestMain.ts b/extensions/terminal-suggest/src/terminalSuggestMain.ts index 35a615e3ea4..710c596b580 100644 --- a/extensions/terminal-suggest/src/terminalSuggestMain.ts +++ b/extensions/terminal-suggest/src/terminalSuggestMain.ts @@ -252,13 +252,9 @@ export async function activate(context: vscode.ExtensionContext) { return; } - const [commandsInPath, shellGlobals] = await Promise.all([ - pathExecutableCache.getExecutablesInPath(terminal.shellIntegration?.env?.value, terminalShellType), - (async () => { - const executables = await pathExecutableCache.getExecutablesInPath(terminal.shellIntegration?.env?.value, terminalShellType); - return getShellGlobals(terminalShellType, executables?.labels, machineId, remoteAuthority); - })() - ]); + const commandsInPath = await pathExecutableCache.getExecutablesInPath(terminal.shellIntegration?.env?.value, terminalShellType); + const shellGlobals = await getShellGlobals(terminalShellType, commandsInPath?.labels, machineId, remoteAuthority); + const shellGlobalsArr = shellGlobals ?? []; if (!commandsInPath?.completionResources) { console.debug('#terminalCompletions No commands found in path'); diff --git a/extensions/terminal-suggest/src/test/env/pathExecutableCache.test.ts b/extensions/terminal-suggest/src/test/env/pathExecutableCache.test.ts index fa9bd131a4d..42b28d6d1dd 100644 --- a/extensions/terminal-suggest/src/test/env/pathExecutableCache.test.ts +++ b/extensions/terminal-suggest/src/test/env/pathExecutableCache.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import 'mocha'; -import { strictEqual } from 'node:assert'; +import { deepStrictEqual, strictEqual } from 'node:assert'; import type { MarkdownString } from 'vscode'; import { PathExecutableCache } from '../../env/pathExecutableCache'; @@ -16,12 +16,12 @@ suite('PathExecutableCache', () => { strictEqual(Array.from(result!.labels!).length, 0); }); - test('caching is working on successive calls', async () => { + test('results are the same on successive calls', async () => { const cache = new PathExecutableCache(); const env = { PATH: process.env.PATH }; const result = await cache.getExecutablesInPath(env); const result2 = await cache.getExecutablesInPath(env); - strictEqual(result, result2); + deepStrictEqual(result!.labels, result2!.labels); }); test('refresh clears the cache', async () => {