未验证 提交 27ace55a 编写于 作者: A Alex Ross 提交者: GitHub

Handle Run Active when terminal executible is WSL (#59136)

Fixes #36897
上级 1369c6e5
......@@ -500,6 +500,15 @@ export interface ITerminalInstance {
*/
sendText(text: string, addNewLine: boolean): void;
/**
* Takes a path and returns the properly escaped path to send to the terminal.
* On Windows, this included trying to prepare the path for WSL if needed.
*
* @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): Promise<string>;
/**
* Write text directly to the terminal, skipping the process if it exists.
* @param text The text to write.
......
......@@ -27,7 +27,6 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
import { PICK_WORKSPACE_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { TERMINAL_COMMAND_ID } from 'vs/workbench/parts/terminal/common/terminalCommands';
import { isWindows } from 'vs/base/common/platform';
import { Command } from 'vs/editor/browser/editorExtensions';
import { timeout } from 'vs/base/common/async';
import { FindReplaceState } from 'vs/editor/contrib/find/findState';
......@@ -655,23 +654,11 @@ export class RunActiveFileInTerminalAction extends Action {
this.notificationService.warn(nls.localize('workbench.action.terminal.runActiveFile.noFile', 'Only files on disk can be run in the terminal'));
return TPromise.as(void 0);
}
let uriPath: string = uri.fsPath;
const hasSpace = uriPath.indexOf(' ') !== -1;
if (hasSpace && isWindows) {
uriPath = '"' + uriPath + '"';
} else if (!isWindows) {
if (uriPath.indexOf('\\') !== 0) {
uriPath = uriPath.replace(/\\/g, '\\\\');
}
const hasDoubleQuote = uriPath.indexOf('"') !== -1;
if (!hasSpace && hasDoubleQuote) {
uriPath = '\'' + uriPath + '\'';
} else if (hasSpace) {
uriPath = uriPath.replace(/ /g, '\\ ');
}
}
instance.sendText(uriPath, true);
return this.terminalService.showPanel();
return instance.preparePathForTerminalAsync(uri.fsPath).then(path => {
instance.sendText(path, true);
return this.terminalService.showPanel();
});
}
}
......
......@@ -8,6 +8,7 @@ import * as nls from 'vs/nls';
import * as platform from 'vs/base/common/platform';
import * as dom from 'vs/base/browser/dom';
import * as paths from 'vs/base/common/paths';
import * as os from 'os';
import { Event, Emitter } from 'vs/base/common/event';
import { WindowsShellHelper } from 'vs/workbench/parts/terminal/node/windowsShellHelper';
import { Terminal as XTermTerminal, ISearchOptions } from 'vscode-xterm';
......@@ -34,6 +35,7 @@ import { ILogService } from 'vs/platform/log/common/log';
import { TerminalCommandTracker } from 'vs/workbench/parts/terminal/node/terminalCommandTracker';
import { TerminalProcessManager } from './terminalProcessManager';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { execFile } from 'child_process';
// How long in milliseconds should an average frame take to render for a notification to appear
// which suggests the fallback DOM-based renderer
......@@ -660,6 +662,48 @@ export class TerminalInstance implements ITerminalInstance {
}
}
public preparePathForTerminalAsync(path: string): Promise<string> {
return new Promise<string>(c => {
const hasSpace = path.indexOf(' ') !== -1;
if (platform.isWindows) {
const exe = this.shellLaunchConfig.executable;
// 17063 is the build number where wsl path was introduced.
// Update Windows uriPath to be executed in WSL.
if (((exe.indexOf('wsl') !== -1) || ((exe.indexOf('bash.exe') !== -1) && (exe.indexOf('git') === -1))) && (TerminalInstance.getWindowsBuildNumber() >= 17063)) {
execFile('bash.exe', ['-c', 'echo $(wslpath ' + this._escapeNonWindowsPath(path) + ')'], {}, (error, stdout, stderr) => {
c(this._escapeNonWindowsPath(stdout.trim()));
});
} else if (hasSpace) {
c('"' + path + '"');
}
} else if (!platform.isWindows) {
c(this._escapeNonWindowsPath(path));
}
});
}
private _escapeNonWindowsPath(path: string): string {
let newPath = path;
if (newPath.indexOf('\\') !== 0) {
newPath = newPath.replace(/\\/g, '\\\\');
}
if (!newPath && (newPath.indexOf('"') !== -1)) {
newPath = '\'' + newPath + '\'';
} else if (newPath.indexOf(' ') !== -1) {
newPath = newPath.replace(/ /g, '\\ ');
}
return newPath;
}
public static getWindowsBuildNumber(): number {
const osVersion = (/(\d+)\.(\d+)\.(\d+)/g).exec(os.release());
let buildNumber: number = 0;
if (osVersion && osVersion.length === 4) {
buildNumber = parseInt(osVersion[3]);
}
return buildNumber;
}
public setVisible(visible: boolean): void {
this._isVisible = visible;
if (this._wrapperElement) {
......
......@@ -6,7 +6,6 @@
import * as nls from 'vs/nls';
import * as pfs from 'vs/base/node/pfs';
import * as platform from 'vs/base/common/platform';
import * as os from 'os';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
......@@ -220,14 +219,10 @@ export class TerminalService extends AbstractTerminalService implements ITermina
const is32ProcessOn64Windows = process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432');
const system32Path = `${process.env['windir']}\\${is32ProcessOn64Windows ? 'Sysnative' : 'System32'}`;
const osVersion = (/(\d+)\.(\d+)\.(\d+)/g).exec(os.release());
let useWSLexe = false;
if (osVersion && osVersion.length === 4) {
const buildNumber = parseInt(osVersion[3]);
if (buildNumber >= 16299) {
useWSLexe = true;
}
if (TerminalInstance.getWindowsBuildNumber() >= 16299) {
useWSLexe = true;
}
const expectedLocations = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册