Skip to content

Commit

Permalink
Fixes microsoft#78751 - normalize paths for shells
Browse files Browse the repository at this point in the history
  • Loading branch information
eamodio committed Oct 28, 2019
1 parent 70f8912 commit d4a73d0
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 15 deletions.
20 changes: 19 additions & 1 deletion src/vs/workbench/contrib/terminal/browser/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export interface ITerminalService {
* @param path The path to be escaped and formatted.
* @returns An escaped version of the path to be execuded in the terminal.
*/
preparePathForTerminalAsync(path: string, executable: string | undefined, title: string): Promise<string>;
preparePathForTerminalAsync(path: string, executable: string | undefined, title: string, shellType: TerminalShellType): Promise<string>;

extHostReady(remoteAuthority: string): void;
requestSpawnExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI | undefined, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void;
Expand All @@ -167,6 +167,14 @@ export interface ISearchOptions {
incremental?: boolean;
}

export enum WindowsShellType {
CommandPrompt,
PowerShell,
Wsl,
GitBash
}
export type TerminalShellType = WindowsShellType | undefined;

export interface ITerminalInstance {
/**
* The ID of the terminal instance, this is an arbitrary number only used to identify the
Expand Down Expand Up @@ -236,6 +244,11 @@ export interface ITerminalInstance {
*/
readonly title: string;

/**
* The shell type of the terminal.
*/
readonly shellType: TerminalShellType;

/**
* The focus state of the terminal before exiting.
*/
Expand Down Expand Up @@ -431,6 +444,11 @@ export interface ITerminalInstance {
*/
setTitle(title: string, eventSource: TitleEventSource): void;

/**
* Sets the shell type of the terminal instance.
*/
setShellType(shellType: TerminalShellType): void;

waitForTitle(): Promise<string>;

setDimensions(dimensions: ITerminalDimensions): void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,7 @@ export class RunActiveFileInTerminalAction extends Action {
return Promise.resolve(undefined);
}

return this.terminalService.preparePathForTerminalAsync(uri.fsPath, instance.shellLaunchConfig.executable, instance.title).then(path => {
return this.terminalService.preparePathForTerminalAsync(uri.fsPath, instance.shellLaunchConfig.executable, instance.title, instance.shellType).then(path => {
instance.sendText(path, true);
return this.terminalService.showPanel();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/term
import { TerminalLinkHandler } from 'vs/workbench/contrib/terminal/browser/terminalLinkHandler';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
import { ITerminalInstanceService, ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal';
import { ITerminalInstanceService, ITerminalInstance, TerminalShellType } from 'vs/workbench/contrib/terminal/browser/terminal';
import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/browser/terminalProcessManager';
import { Terminal as XTermTerminal, IBuffer, ITerminalAddon } from 'xterm';
import { SearchAddon, ISearchOptions } from 'xterm-addon-search';
Expand Down Expand Up @@ -182,6 +182,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
private _isVisible: boolean;
private _isDisposed: boolean;
private _skipTerminalCommands: string[];
private _shellType: TerminalShellType;
private _title: string = '';
private _wrapperElement: (HTMLElement & { xterm?: XTermTerminal }) | undefined;
private _xterm: XTermTerminal | undefined;
Expand Down Expand Up @@ -230,6 +231,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
public get hadFocusOnExit(): boolean { return this._hadFocusOnExit; }
public get isTitleSetByProcess(): boolean { return !!this._messageTitleDisposable; }
public get shellLaunchConfig(): IShellLaunchConfig { return this._shellLaunchConfig; }
public get shellType(): TerminalShellType { return this._shellType; }
public get commandTracker(): CommandTrackerAddon | undefined { return this._commandTrackerAddon; }
public get navigationMode(): INavigationMode | undefined { return this._navigationModeAddon; }

Expand Down Expand Up @@ -1342,6 +1344,10 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._processManager.ptyProcessReady.then(() => this._processManager.setDimensions(cols, rows));
}

public setShellType(shellType: TerminalShellType) {
this._shellType = shellType;
}

public setTitle(title: string | undefined, eventSource: TitleEventSource): void {
if (!title) {
return;
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/contrib/terminal/browser/terminalPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ export class TerminalPanel extends Panel {

const terminal = this._terminalService.getActiveInstance();
if (terminal) {
return this._terminalService.preparePathForTerminalAsync(path, terminal.shellLaunchConfig.executable, terminal.title).then(preparedPath => {
return this._terminalService.preparePathForTerminalAsync(path, terminal.shellLaunchConfig.executable, terminal.title, terminal.shellType).then(preparedPath => {
terminal.sendText(preparedPath, false);
});
}
Expand Down
43 changes: 33 additions & 10 deletions src/vs/workbench/contrib/terminal/browser/terminalService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IFileService } from 'vs/platform/files/common/files';
import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance';
import { ITerminalService, ITerminalInstance, ITerminalTab } from 'vs/workbench/contrib/terminal/browser/terminal';
import { ITerminalService, ITerminalInstance, ITerminalTab, TerminalShellType, WindowsShellType } from 'vs/workbench/contrib/terminal/browser/terminal';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
import { IQuickInputService, IQuickPickItem, IPickOptions } from 'vs/platform/quickinput/common/quickInput';
Expand Down Expand Up @@ -504,7 +504,7 @@ export class TerminalService implements ITerminalService {
});
}

public preparePathForTerminalAsync(originalPath: string, executable: string, title: string): Promise<string> {
public preparePathForTerminalAsync(originalPath: string, executable: string, title: string, shellType: TerminalShellType): Promise<string> {
return new Promise<string>(c => {
if (!executable) {
c(originalPath);
Expand All @@ -527,18 +527,41 @@ export class TerminalService implements ITerminalService {
if (isWindows) {
// 17063 is the build number where wsl path was introduced.
// Update Windows uriPath to be executed in WSL.
const lowerExecutable = executable.toLowerCase();
if (this._terminalNativeService.getWindowsBuildNumber() >= 17063 &&
(lowerExecutable.indexOf('wsl') !== -1 || (lowerExecutable.indexOf('bash.exe') !== -1 && lowerExecutable.toLowerCase().indexOf('git') === -1))) {
c(this._terminalNativeService.getWslPath(originalPath));
return;
} else if (hasSpace) {
c('"' + originalPath + '"');
if (shellType !== undefined) {
if (shellType === WindowsShellType.GitBash) {
c(originalPath.replace(/\\/g, '/'));
return;
}
else if (shellType === WindowsShellType.Wsl) {
if (this._terminalNativeService.getWindowsBuildNumber() >= 17063) {
c(this._terminalNativeService.getWslPath(originalPath));
} else {
c(originalPath.replace(/\\/g, '/'));
}
return;
}

if (hasSpace) {
c('"' + originalPath + '"');
} else {
c(originalPath);
}
} else {
c(originalPath);
const lowerExecutable = executable.toLowerCase();
if (this._terminalNativeService.getWindowsBuildNumber() >= 17063 &&
(lowerExecutable.indexOf('wsl') !== -1 || (lowerExecutable.indexOf('bash.exe') !== -1 && lowerExecutable.toLowerCase().indexOf('git') === -1))) {
c(this._terminalNativeService.getWslPath(originalPath));
return;
} else if (hasSpace) {
c('"' + originalPath + '"');
} else {
c(originalPath);
}
}

return;
}

c(escapeNonWindowsPath(originalPath));
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { IWindowsShellHelper, TitleEventSource } from 'vs/workbench/contrib/term
import { Terminal as XTermTerminal } from 'xterm';
import * as WindowsProcessTreeType from 'windows-process-tree';
import { Disposable } from 'vs/base/common/lifecycle';
import { ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal';
import { ITerminalInstance, TerminalShellType, WindowsShellType } from 'vs/workbench/contrib/terminal/browser/terminal';

const SHELL_EXECUTABLES = [
'cmd.exe',
Expand Down Expand Up @@ -83,6 +83,7 @@ export class WindowsShellHelper extends Disposable implements IWindowsShellHelpe
this.getShellName().then(title => {
if (!this._isDisposed) {
this._terminalInstance.setTitle(title, TitleEventSource.Process);
this._terminalInstance.setShellType(this.getShellType(title));
}
});
}
Expand Down Expand Up @@ -139,4 +140,26 @@ export class WindowsShellHelper extends Disposable implements IWindowsShellHelpe
});
return this._currentRequest;
}

public getShellType(executable: string): TerminalShellType {
switch (executable.toLowerCase()) {
case 'cmd.exe':
return WindowsShellType.CommandPrompt;
case 'powershell.exe':
case 'pwsh.exe':
return WindowsShellType.PowerShell;
case 'bash.exe':
return WindowsShellType.GitBash;
case 'wsl.exe':
case 'ubuntu.exe':
case 'ubuntu1804.exe':
case 'kali.exe':
case 'debian.exe':
case 'opensuse-42.exe':
case 'sles-12.exe':
return WindowsShellType.Wsl;
default:
return undefined;
}
}
}

0 comments on commit d4a73d0

Please sign in to comment.