Skip to content

Commit b62b538

Browse files
authored
Merge pull request microsoft#154539 from microsoft/tyriar/153109
Run recent command: Collapse $HOME into ~
2 parents a4272b7 + 4dd384b commit b62b538

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed

src/vs/platform/terminal/common/terminalEnvironment.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,26 @@ export function escapeNonWindowsPath(path: string): string {
1212
newPath = newPath.replace(bannedChars, '');
1313
return `'${newPath}'`;
1414
}
15+
16+
/**
17+
* Collapses the user's home directory into `~` if it exists within the path, this gives a shorter
18+
* path that is more suitable within the context of a terminal.
19+
*/
20+
export function collapseTildePath(path: string | undefined, userHome: string | undefined, separator: string): string {
21+
if (!path) {
22+
return '';
23+
}
24+
if (!userHome) {
25+
return path;
26+
}
27+
// Trim the trailing separator from the end if it exists
28+
if (userHome.match(/[\/\\]$/)) {
29+
userHome = userHome.slice(0, userHome.length - 1);
30+
}
31+
const normalizedPath = path.replace(/\\/g, '/').toLowerCase();
32+
const normalizedUserHome = userHome.replace(/\\/g, '/').toLowerCase();
33+
if (!normalizedPath.includes(normalizedUserHome)) {
34+
return path;
35+
}
36+
return `~${separator}${path.slice(userHome.length + 1)}`;
37+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { strictEqual } from 'assert';
7+
import { collapseTildePath } from 'vs/platform/terminal/common/terminalEnvironment';
8+
9+
suite('terminalEnvironment', () => {
10+
suite('collapseTildePath', () => {
11+
test('should return empty string for a falsy path', () => {
12+
strictEqual(collapseTildePath('', '/foo', '/'), '');
13+
strictEqual(collapseTildePath(undefined, '/foo', '/'), '');
14+
});
15+
test('should return path for a falsy user home', () => {
16+
strictEqual(collapseTildePath('/foo', '', '/'), '/foo');
17+
strictEqual(collapseTildePath('/foo', undefined, '/'), '/foo');
18+
});
19+
test('should not collapse when user home isn\'t present', () => {
20+
strictEqual(collapseTildePath('/foo', '/bar', '/'), '/foo');
21+
strictEqual(collapseTildePath('C:\\foo', 'C:\\bar', '\\'), 'C:\\foo');
22+
});
23+
test('should collapse with Windows separators', () => {
24+
strictEqual(collapseTildePath('C:\\foo\\bar', 'C:\\foo', '\\'), '~\\bar');
25+
strictEqual(collapseTildePath('C:\\foo\\bar', 'C:\\foo\\', '\\'), '~\\bar');
26+
strictEqual(collapseTildePath('C:\\foo\\bar\\baz', 'C:\\foo\\', '\\'), '~\\bar\\baz');
27+
strictEqual(collapseTildePath('C:\\foo\\bar\\baz', 'C:\\foo', '\\'), '~\\bar\\baz');
28+
});
29+
test('should collapse mixed case with Windows separators', () => {
30+
strictEqual(collapseTildePath('c:\\foo\\bar', 'C:\\foo', '\\'), '~\\bar');
31+
strictEqual(collapseTildePath('C:\\foo\\bar\\baz', 'c:\\foo', '\\'), '~\\bar\\baz');
32+
});
33+
test('should collapse with Posix separators', () => {
34+
strictEqual(collapseTildePath('/foo/bar', '/foo', '/'), '~/bar');
35+
strictEqual(collapseTildePath('/foo/bar', '/foo/', '/'), '~/bar');
36+
strictEqual(collapseTildePath('/foo/bar/baz', '/foo', '/'), '~/bar/baz');
37+
strictEqual(collapseTildePath('/foo/bar/baz', '/foo/', '/'), '~/bar/baz');
38+
});
39+
});
40+
});

src/vs/workbench/contrib/terminal/browser/terminalInstance.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
4747
import { ITerminalCommand, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities';
4848
import { TerminalCapabilityStoreMultiplexer } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore';
4949
import { IProcessDataEvent, IProcessPropertyMap, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, PosixShellType, ProcessPropertyType, TerminalIcon, TerminalLocation, TerminalSettingId, TerminalShellType, TitleEventSource, WindowsShellType } from 'vs/platform/terminal/common/terminal';
50-
import { escapeNonWindowsPath } from 'vs/platform/terminal/common/terminalEnvironment';
50+
import { escapeNonWindowsPath, collapseTildePath } from 'vs/platform/terminal/common/terminalEnvironment';
5151
import { activeContrastBorder, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground } from 'vs/platform/theme/common/colorRegistry';
5252
import { IColorTheme, ICssStyleCollector, IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService';
5353
import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
@@ -852,7 +852,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
852852
if (label.length === 0 || commandMap.has(label)) {
853853
continue;
854854
}
855-
let description = `${entry.cwd}`;
855+
let description = collapseTildePath(entry.cwd, this._userHome, this._processManager?.os === OperatingSystem.Windows ? '\\' : '/');
856856
if (entry.exitCode) {
857857
// Since you cannot get the last command's exit code on pwsh, just whether it failed
858858
// or not, -1 is treated specially as simply failed

0 commit comments

Comments
 (0)