未验证 提交 52a351f8 编写于 作者: D Daniel Imms 提交者: GitHub

Merge pull request #75455 from microsoft/tyriar/75091_default_shell_api

Implement API to get default shell
......@@ -1110,6 +1110,12 @@ declare module 'vscode' {
}
namespace window {
/**
* The detected default shell for the extension host, this is overridden by the
* `terminal.integrated.shell` setting for the extension host's platform.
*/
export const shell: string;
/**
* An event which fires when the [dimensions](#Terminal.dimensions) of the terminal change.
*/
......
......@@ -41,6 +41,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
this._toDispose.push(terminalService.onInstanceRequestExtHostProcess(request => this._onTerminalRequestExtHostProcess(request)));
this._toDispose.push(terminalService.onActiveInstanceChanged(instance => this._onActiveTerminalChanged(instance ? instance.id : null)));
this._toDispose.push(terminalService.onInstanceTitleChanged(instance => this._onTitleChanged(instance.id, instance.title)));
this._toDispose.push(terminalService.configHelper.onWorkspacePermissionsChanged(isAllowed => this._onWorkspacePermissionsChanged(isAllowed)));
// Set initial ext host state
this.terminalService.terminalInstances.forEach(t => {
......@@ -182,6 +183,10 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
this._proxy.$acceptTerminalTitleChange(terminalId, name);
}
private _onWorkspacePermissionsChanged(isAllowed: boolean): void {
this._proxy.$acceptWorkspacePermissionsChanged(isAllowed);
}
private _onTerminalRendererInput(terminalId: number, data: string): void {
this._proxy.$acceptTerminalRendererInput(terminalId, data);
}
......
......@@ -1122,6 +1122,7 @@ export interface ExtHostTerminalServiceShape {
$acceptProcessRequestInitialCwd(id: number): void;
$acceptProcessRequestCwd(id: number): void;
$acceptProcessRequestLatency(id: number): number;
$acceptWorkspacePermissionsChanged(isAllowed: boolean): void;
}
export interface ExtHostSCMShape {
......
......@@ -389,6 +389,9 @@ export function createApiFactory(
get terminals() {
return extHostTerminalService.terminals;
},
get shell() {
return extHostTerminalService.getDefaultShell(configProvider);
},
showTextDocument(documentOrUri: vscode.TextDocument | vscode.Uri, columnOrOptions?: vscode.ViewColumn | vscode.TextDocumentShowOptions, preserveFocus?: boolean): Thenable<vscode.TextEditor> {
let documentPromise: Promise<vscode.TextDocument>;
if (URI.isUri(documentOrUri)) {
......
......@@ -11,7 +11,7 @@ import * as platform from 'vs/base/common/platform';
import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
import { Event, Emitter } from 'vs/base/common/event';
import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, ShellLaunchConfigDto } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration';
import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration';
import { ILogService } from 'vs/platform/log/common/log';
import { EXT_HOST_CREATION_DELAY, IShellLaunchConfig, ITerminalEnvironment } from 'vs/workbench/contrib/terminal/common/terminal';
import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess';
......@@ -278,6 +278,9 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
private _terminalRenderers: ExtHostTerminalRenderer[] = [];
private _getTerminalPromises: { [id: number]: Promise<ExtHostTerminal> } = {};
// TODO: Pull this from main side
private _isWorkspaceShellAllowed: boolean = false;
public get activeTerminal(): ExtHostTerminal | undefined { return this._activeTerminal; }
public get terminals(): ExtHostTerminal[] { return this._terminals; }
......@@ -325,6 +328,16 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
return renderer;
}
public getDefaultShell(configProvider: ExtHostConfigProvider): string {
const fetchSetting = (key: string) => {
const setting = configProvider
.getConfiguration(key.substr(0, key.lastIndexOf('.')))
.inspect<string | string[]>(key.substr(key.lastIndexOf('.') + 1));
return this._apiInspectConfigToPlain<string | string[]>(setting);
};
return terminalEnvironment.getDefaultShell(fetchSetting, this._isWorkspaceShellAllowed, getDefaultShell(platform.platform));
}
public async resolveTerminalRenderer(id: number): Promise<vscode.TerminalRenderer> {
// Check to see if the extension host already knows about this terminal.
for (const terminalRenderer of this._terminalRenderers) {
......@@ -612,6 +625,10 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
});
return index;
}
public $acceptWorkspacePermissionsChanged(isAllowed: boolean): void {
this._isWorkspaceShellAllowed = isAllowed;
}
}
class ApiRequest {
......
......@@ -14,6 +14,7 @@ import { Terminal as XTermTerminal } from 'xterm';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IBrowserTerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminal';
import { mergeDefaultShellPathAndArgs } from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
import { Emitter, Event } from 'vs/base/common/event';
const MINIMUM_FONT_SIZE = 6;
const MAXIMUM_FONT_SIZE = 25;
......@@ -29,6 +30,9 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper {
private _lastFontMeasurement: ITerminalFont;
public config: ITerminalConfiguration;
private readonly _onWorkspacePermissionsChanged = new Emitter<boolean>();
public get onWorkspacePermissionsChanged(): Event<boolean> { return this._onWorkspacePermissionsChanged.event; }
public constructor(
private readonly _linuxDistro: LinuxDistro,
@IConfigurationService private readonly _configurationService: IConfigurationService,
......@@ -160,6 +164,7 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper {
}
public setWorkspaceShellAllowed(isAllowed: boolean): void {
this._onWorkspacePermissionsChanged.fire(isAllowed);
this._storageService.store(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, isAllowed, StorageScope.WORKSPACE);
}
......
......@@ -109,6 +109,9 @@ export interface ITerminalConfiguration {
export interface ITerminalConfigHelper {
config: ITerminalConfiguration;
onWorkspacePermissionsChanged: Event<boolean>;
configFontIsMonospace(): boolean;
getFont(): ITerminalFont;
/**
......@@ -210,6 +213,9 @@ export interface ITerminalService {
activeTabIndex: number;
configHelper: ITerminalConfigHelper;
terminalInstances: ITerminalInstance[];
terminalTabs: ITerminalTab[];
onActiveTabChanged: Event<void>;
onTabDisposed: Event<ITerminalTab>;
onInstanceCreated: Event<ITerminalInstance>;
......@@ -220,8 +226,6 @@ export interface ITerminalService {
onInstancesChanged: Event<void>;
onInstanceTitleChanged: Event<ITerminalInstance>;
onActiveInstanceChanged: Event<ITerminalInstance | undefined>;
terminalInstances: ITerminalInstance[];
terminalTabs: ITerminalTab[];
/**
* Creates a terminal.
......
......@@ -161,34 +161,55 @@ export function escapeNonWindowsPath(path: string): string {
return newPath;
}
export function mergeDefaultShellPathAndArgs(
shell: IShellLaunchConfig,
export function getDefaultShell(
fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined },
isWorkspaceShellAllowed: boolean,
defaultShell: string,
platformOverride: platform.Platform = platform.platform
): void {
): string {
const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux';
const shellConfigValue = fetchSetting(`terminal.integrated.shell.${platformKey}`);
const shellArgsConfigValue = fetchSetting(`terminal.integrated.shellArgs.${platformKey}`);
shell.executable = (isWorkspaceShellAllowed ? <string>shellConfigValue.value : <string>shellConfigValue.user) || (<string | null>shellConfigValue.default || defaultShell);
shell.args = (isWorkspaceShellAllowed ? <string[]>shellArgsConfigValue.value : <string[]>shellArgsConfigValue.user) || <string[]>shellArgsConfigValue.default;
let executable = (isWorkspaceShellAllowed ? <string>shellConfigValue.value : <string>shellConfigValue.user) || (<string | null>shellConfigValue.default || defaultShell);
// Change Sysnative to System32 if the OS is Windows but NOT WoW64. It's
// safe to assume that this was used by accident as Sysnative does not
// exist and will break the terminal in non-WoW64 environments.
if ((platformOverride === platform.Platform.Windows) && !process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432') && process.env.windir) {
const sysnativePath = path.join(process.env.windir, 'Sysnative').toLowerCase();
if (shell.executable && shell.executable.toLowerCase().indexOf(sysnativePath) === 0) {
shell.executable = path.join(process.env.windir, 'System32', shell.executable.substr(sysnativePath.length));
if (executable && executable.toLowerCase().indexOf(sysnativePath) === 0) {
executable = path.join(process.env.windir, 'System32', executable.substr(sysnativePath.length));
}
}
// Convert / to \ on Windows for convenience
if (shell.executable && platformOverride === platform.Platform.Windows) {
shell.executable = shell.executable.replace(/\//g, '\\');
if (executable && platformOverride === platform.Platform.Windows) {
executable = executable.replace(/\//g, '\\');
}
return executable;
}
function getDefaultShellArgs(
fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined },
isWorkspaceShellAllowed: boolean,
defaultShell: string,
platformOverride: platform.Platform = platform.platform
): string[] {
const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux';
const shellArgsConfigValue = fetchSetting(`terminal.integrated.shellArgs.${platformKey}`);
const args = (isWorkspaceShellAllowed ? <string[]>shellArgsConfigValue.value : <string[]>shellArgsConfigValue.user) || <string[]>shellArgsConfigValue.default;
return args;
}
export function mergeDefaultShellPathAndArgs(
shell: IShellLaunchConfig,
fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined },
isWorkspaceShellAllowed: boolean,
defaultShell: string,
platformOverride: platform.Platform = platform.platform
): void {
shell.executable = getDefaultShell(fetchSetting, isWorkspaceShellAllowed, defaultShell, platformOverride);
shell.args = getDefaultShellArgs(fetchSetting, isWorkspaceShellAllowed, defaultShell, platformOverride);
}
export function createTerminalEnvironment(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册