@@ -12,15 +12,14 @@ import { IConfigurationService } from '../../../../../platform/configuration/com
12
12
import { IFileService } from '../../../../../platform/files/common/files.js' ;
13
13
import { createDecorator } from '../../../../../platform/instantiation/common/instantiation.js' ;
14
14
import { TerminalCapability , type ITerminalCapabilityStore } from '../../../../../platform/terminal/common/capabilities/capabilities.js' ;
15
- import { GeneralShellType , TerminalShellType , WindowsShellType } from '../../../../../platform/terminal/common/terminal.js' ;
15
+ import { GeneralShellType , ITerminalLogService , TerminalShellType , WindowsShellType } from '../../../../../platform/terminal/common/terminal.js' ;
16
16
import { TerminalSuggestSettingId } from '../common/terminalSuggestConfiguration.js' ;
17
17
import { TerminalCompletionItemKind , type ITerminalCompletion } from './terminalCompletionItem.js' ;
18
18
import { env as processEnv } from '../../../../../base/common/process.js' ;
19
19
import type { IProcessEnvironment } from '../../../../../base/common/platform.js' ;
20
20
import { timeout } from '../../../../../base/common/async.js' ;
21
21
import { gitBashToWindowsPath } from './terminalGitBashHelpers.js' ;
22
22
import { isEqual } from '../../../../../base/common/resources.js' ;
23
- import { ILogService } from '../../../../../platform/log/common/log.js' ;
24
23
25
24
export const ITerminalCompletionService = createDecorator < ITerminalCompletionService > ( 'terminalCompletionService' ) ;
26
25
@@ -104,7 +103,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
104
103
constructor (
105
104
@IConfigurationService private readonly _configurationService : IConfigurationService ,
106
105
@IFileService private readonly _fileService : IFileService ,
107
- @ILogService private readonly _logService : ILogService
106
+ @ITerminalLogService private readonly _logService : ITerminalLogService
108
107
) {
109
108
super ( ) ;
110
109
}
@@ -132,6 +131,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
132
131
}
133
132
134
133
async provideCompletions ( promptValue : string , cursorPosition : number , allowFallbackCompletions : boolean , shellType : TerminalShellType | undefined , capabilities : ITerminalCapabilityStore , token : CancellationToken , triggerCharacter ?: boolean , skipExtensionCompletions ?: boolean , explicitlyInvoked ?: boolean ) : Promise < ITerminalCompletion [ ] | undefined > {
134
+ this . _logService . trace ( 'TerminalCompletionService#provideCompletions' ) ;
135
135
if ( ! this . _providers || ! this . _providers . values || cursorPosition < 0 ) {
136
136
return undefined ;
137
137
}
@@ -178,6 +178,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
178
178
}
179
179
180
180
private async _collectCompletions ( providers : ITerminalCompletionProvider [ ] , shellType : TerminalShellType | undefined , promptValue : string , cursorPosition : number , allowFallbackCompletions : boolean , capabilities : ITerminalCapabilityStore , token : CancellationToken , explicitlyInvoked ?: boolean ) : Promise < ITerminalCompletion [ ] | undefined > {
181
+ this . _logService . trace ( 'TerminalCompletionService#_collectCompletions' ) ;
181
182
const completionPromises = providers . map ( async provider => {
182
183
if ( provider . shellTypes && shellType && ! provider . shellTypes . includes ( shellType ) ) {
183
184
return undefined ;
@@ -187,7 +188,10 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
187
188
let completions ;
188
189
try {
189
190
completions = await Promise . race ( [
190
- provider . provideCompletions ( promptValue , cursorPosition , allowFallbackCompletions , token ) ,
191
+ provider . provideCompletions ( promptValue , cursorPosition , allowFallbackCompletions , token ) . then ( result => {
192
+ this . _logService . trace ( `TerminalCompletionService#_collectCompletions provider ${ provider . id } finished` ) ;
193
+ return result ;
194
+ } ) ,
191
195
( async ( ) => { await timeout ( timeoutMs ) ; timedOut = true ; return undefined ; } ) ( )
192
196
] ) ;
193
197
} catch ( e ) {
@@ -202,6 +206,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
202
206
return undefined ;
203
207
}
204
208
const completionItems = Array . isArray ( completions ) ? completions : completions . items ?? [ ] ;
209
+ this . _logService . trace ( `TerminalCompletionService#_collectCompletions amend ${ completionItems . length } completion items` ) ;
205
210
if ( shellType === GeneralShellType . PowerShell ) {
206
211
for ( const completion of completionItems ) {
207
212
completion . isFileOverride ??= completion . kind === TerminalCompletionItemKind . Method && completion . replacementIndex === 0 ;
@@ -218,24 +223,29 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
218
223
}
219
224
if ( completions . resourceRequestConfig ) {
220
225
const resourceCompletions = await this . resolveResources ( completions . resourceRequestConfig , promptValue , cursorPosition , `core:path:ext:${ provider . id } ` , capabilities , shellType ) ;
226
+ this . _logService . trace ( `TerminalCompletionService#_collectCompletions dedupe` ) ;
221
227
if ( resourceCompletions ) {
228
+ const labels = new Set ( completionItems . map ( c => c . label ) ) ;
222
229
for ( const item of resourceCompletions ) {
223
- const labels = new Set ( completionItems . map ( c => c . label ) ) ;
224
230
// Ensure no duplicates such as .
225
231
if ( ! labels . has ( item . label ) ) {
226
232
completionItems . push ( item ) ;
227
233
}
228
234
}
229
235
}
236
+ this . _logService . trace ( `TerminalCompletionService#_collectCompletions dedupe done` ) ;
230
237
}
231
238
return completionItems ;
232
239
} ) ;
233
240
234
241
const results = await Promise . all ( completionPromises ) ;
242
+ this . _logService . trace ( 'TerminalCompletionService#_collectCompletions done' ) ;
235
243
return results . filter ( result => ! ! result ) . flat ( ) ;
236
244
}
237
245
238
246
async resolveResources ( resourceRequestConfig : TerminalResourceRequestConfig , promptValue : string , cursorPosition : number , provider : string , capabilities : ITerminalCapabilityStore , shellType ?: TerminalShellType ) : Promise < ITerminalCompletion [ ] | undefined > {
247
+ this . _logService . trace ( `TerminalCompletionService#resolveResources` ) ;
248
+
239
249
const useWindowsStylePath = resourceRequestConfig . pathSeparator === '\\' ;
240
250
if ( useWindowsStylePath ) {
241
251
// for tests, make sure the right path separator is used
@@ -360,6 +370,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
360
370
// - (absolute) `/src/|` -> `/src/`
361
371
// - (tilde) `~/|` -> `~/`
362
372
// - (tilde) `~/src/|` -> `~/src/`
373
+ this . _logService . trace ( `TerminalCompletionService#resolveResources cwd` ) ;
363
374
if ( foldersRequested ) {
364
375
let label : string ;
365
376
switch ( type ) {
@@ -394,7 +405,8 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
394
405
// - (relative) `cd ./src/` -> `cd ./src/folder1/`, ...
395
406
// - (absolute) `cd c:/src/` -> `cd c:/src/folder1/`, ...
396
407
// - (tilde) `cd ~/src/` -> `cd ~/src/folder1/`, ...
397
- for ( const child of stat . children ) {
408
+ this . _logService . trace ( `TerminalCompletionService#resolveResources direct children` ) ;
409
+ await Promise . all ( stat . children . map ( child => ( async ( ) => {
398
410
let kind : TerminalCompletionItemKind | undefined ;
399
411
let detail : string | undefined = undefined ;
400
412
if ( foldersRequested && child . isDirectory ) {
@@ -411,7 +423,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
411
423
}
412
424
}
413
425
if ( kind === undefined ) {
414
- continue ;
426
+ return ;
415
427
}
416
428
417
429
let label = lastWordFolder ;
@@ -431,7 +443,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
431
443
if ( child . isFile && fileExtensions ) {
432
444
const extension = child . name . split ( '.' ) . length > 1 ? child . name . split ( '.' ) . at ( - 1 ) : undefined ;
433
445
if ( extension && ! fileExtensions . includes ( extension ) ) {
434
- continue ;
446
+ return ;
435
447
}
436
448
}
437
449
@@ -455,11 +467,12 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
455
467
replacementIndex : cursorPosition - lastWord . length ,
456
468
replacementLength : lastWord . length
457
469
} ) ;
458
- }
470
+ } ) ( ) ) ) ;
459
471
460
472
// Support $CDPATH specially for the `cd` command only
461
473
//
462
474
// - (relative) `|` -> `/foo/vscode` (CDPATH has /foo which contains vscode folder)
475
+ this . _logService . trace ( `TerminalCompletionService#resolveResources CDPATH` ) ;
463
476
if ( type === 'relative' && foldersRequested ) {
464
477
if ( promptValue . startsWith ( 'cd ' ) ) {
465
478
const config = this . _configurationService . getValue ( TerminalSuggestSettingId . CdPath ) ;
@@ -500,6 +513,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
500
513
//
501
514
// - (relative) `|` -> `../`
502
515
// - (relative) `./src/|` -> `./src/../`
516
+ this . _logService . trace ( `TerminalCompletionService#resolveResources parent dir` ) ;
503
517
if ( type === 'relative' && foldersRequested ) {
504
518
let label = `..${ resourceRequestConfig . pathSeparator } ` ;
505
519
if ( lastWordFolder . length > 0 ) {
@@ -520,6 +534,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
520
534
// input.
521
535
//
522
536
// - (relative) `|` -> `~`
537
+ this . _logService . trace ( `TerminalCompletionService#resolveResources tilde` ) ;
523
538
if ( type === 'relative' && ! lastWordFolder . match ( / [ \\ \/ ] / ) ) {
524
539
let homeResource : URI | string | undefined ;
525
540
const home = this . _getHomeDir ( useWindowsStylePath , capabilities ) ;
@@ -541,6 +556,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
541
556
} ) ;
542
557
}
543
558
559
+ this . _logService . trace ( `TerminalCompletionService#resolveResources done` ) ;
544
560
return resourceCompletions ;
545
561
}
546
562
0 commit comments