Skip to content

Commit 89481fa

Browse files
authored
Merge pull request microsoft#239943 from microsoft/tyriar/239933
Normalize . and .. path prefix in terminal suggest
2 parents 9dd415f + d24c7f0 commit 89481fa

File tree

2 files changed

+51
-11
lines changed

2 files changed

+51
-11
lines changed

src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionService.ts

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
230230
lastWordFolder = lastWordFolder.replaceAll('/', '\\');
231231
}
232232

233-
const lastWordFolderHasDotPrefix = lastWordFolder.match(/^\.\.?[\\\/]/);
233+
const lastWordFolderHasDotPrefix = !!lastWordFolder.match(/^\.\.?[\\\/]/);
234234

235235
const lastWordFolderHasTildePrefix = lastWordFolder.match(/^~[\\\/]/);
236236
if (lastWordFolderHasTildePrefix) {
@@ -330,8 +330,14 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
330330
// `runOnEnter` is used.
331331
// - `./src/|` -> `./src/`
332332
if (foldersRequested) {
333+
let label = '.';
334+
335+
if (lastWordFolder.length > 0) {
336+
label = addPathRelativePrefix(lastWordFolder, resourceRequestConfig, lastWordFolderHasDotPrefix);
337+
}
338+
333339
resourceCompletions.push({
334-
label: lastWordFolder.length === 0 ? '.' : lastWordFolder,
340+
label,
335341
provider,
336342
kind: TerminalCompletionItemKind.Folder,
337343
detail: getFriendlyPath(cwd, resourceRequestConfig.pathSeparator),
@@ -357,14 +363,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
357363
const isDirectory = kind === TerminalCompletionItemKind.Folder;
358364
const resourceName = basename(stat.resource.fsPath);
359365

360-
let label = `${lastWordFolder}${resourceName}`;
361-
362-
// Normalize suggestion to add a ./ prefix to the start of the path if there isn't
363-
// one already. We may want to change this behavior in the future to go with
364-
// whatever format the user has
365-
if (!lastWordFolderHasDotPrefix) {
366-
label = `.${resourceRequestConfig.pathSeparator}${label}`;
367-
}
366+
let label = addPathRelativePrefix(`${lastWordFolder}${resourceName}`, resourceRequestConfig, lastWordFolderHasDotPrefix);
368367

369368
// Ensure directories end with a path separator
370369
if (isDirectory && !label.endsWith(resourceRequestConfig.pathSeparator)) {
@@ -430,9 +429,13 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
430429
// On Windows, the path seprators are normalized to `\`:
431430
// - `./src/|` -> `.\src\..\`
432431
if (foldersRequested) {
432+
let label = `..${resourceRequestConfig.pathSeparator}`;
433+
if (lastWordFolder.length > 0) {
434+
label = addPathRelativePrefix(lastWordFolder + label, resourceRequestConfig, lastWordFolderHasDotPrefix);
435+
}
433436
const parentDir = URI.joinPath(cwd, '..' + resourceRequestConfig.pathSeparator);
434437
resourceCompletions.push({
435-
label: lastWordFolder + '..' + resourceRequestConfig.pathSeparator,
438+
label,
436439
provider,
437440
kind: TerminalCompletionItemKind.Folder,
438441
detail: getFriendlyPath(parentDir, resourceRequestConfig.pathSeparator),
@@ -459,3 +462,14 @@ function getFriendlyPath(uri: URI, pathSeparator: string, kind?: TerminalComplet
459462
}
460463
return path;
461464
}
465+
466+
/**
467+
* Normalize suggestion to add a ./ prefix to the start of the path if there isn't one already. We
468+
* may want to change this behavior in the future to go with whatever format the user has.
469+
*/
470+
function addPathRelativePrefix(text: string, resourceRequestConfig: Pick<TerminalResourceRequestConfig, 'pathSeparator'>, lastWordFolderHasDotPrefix: boolean): string {
471+
if (!lastWordFolderHasDotPrefix) {
472+
return `.${resourceRequestConfig.pathSeparator}${text}`;
473+
}
474+
return text;
475+
}

src/vs/workbench/contrib/terminalContrib/suggest/test/browser/terminalCompletionService.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,32 @@ suite('TerminalCompletionService', () => {
402402
{ label: './../', detail: '/' }
403403
], { replacementIndex: 1, replacementLength: 9 });
404404
});
405+
406+
test('folder/| should normalize current and parent folders', async () => {
407+
const resourceRequestConfig: TerminalResourceRequestConfig = {
408+
cwd: URI.parse('file:///test'),
409+
foldersRequested: true,
410+
pathSeparator
411+
};
412+
validResources = [
413+
URI.parse('file:///'),
414+
URI.parse('file:///test'),
415+
URI.parse('file:///test/folder1'),
416+
URI.parse('file:///test/folder2'),
417+
];
418+
childResources = [
419+
{ resource: URI.parse('file:///test/folder1/'), isDirectory: true },
420+
{ resource: URI.parse('file:///test/folder2/'), isDirectory: true }
421+
];
422+
const result = await terminalCompletionService.resolveResources(resourceRequestConfig, 'test/', 5, provider, capabilities);
423+
424+
assertCompletions(result, [
425+
{ label: './test/', detail: '/test/' },
426+
{ label: './test/folder1/', detail: '/test/folder1/' },
427+
{ label: './test/folder2/', detail: '/test/folder2/' },
428+
{ label: './test/../', detail: '/' }
429+
], { replacementIndex: 0, replacementLength: 5 });
430+
});
405431
});
406432

407433
suite('cdpath', () => {

0 commit comments

Comments
 (0)