mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-30 16:50:30 -04:00
Merge from vscode 8b5ebbb1b8f6b2127bbbd551ac10cc080482d5b4 (#5041)
This commit is contained in:
@@ -1060,10 +1060,10 @@ export class SCMViewlet extends ViewContainerViewlet implements IViewModel {
|
||||
const visibleViewDescriptors = this.viewsModel.visibleViewDescriptors;
|
||||
|
||||
const toSetVisible = this.viewsModel.viewDescriptors
|
||||
.filter(d => d instanceof RepositoryViewDescriptor && repositories.indexOf(d.repository) > -1 && visibleViewDescriptors.indexOf(d) === -1);
|
||||
.filter((d): d is RepositoryViewDescriptor => d instanceof RepositoryViewDescriptor && repositories.indexOf(d.repository) > -1 && visibleViewDescriptors.indexOf(d) === -1);
|
||||
|
||||
const toSetInvisible = visibleViewDescriptors
|
||||
.filter(d => d instanceof RepositoryViewDescriptor && repositories.indexOf(d.repository) === -1);
|
||||
.filter((d): d is RepositoryViewDescriptor => d instanceof RepositoryViewDescriptor && repositories.indexOf(d.repository) === -1);
|
||||
|
||||
let size: number | undefined;
|
||||
const oneToOne = toSetVisible.length === 1 && toSetInvisible.length === 1;
|
||||
@@ -1077,10 +1077,12 @@ export class SCMViewlet extends ViewContainerViewlet implements IViewModel {
|
||||
}
|
||||
}
|
||||
|
||||
viewDescriptor.repository.setSelected(false);
|
||||
this.viewsModel.setVisible(viewDescriptor.id, false);
|
||||
}
|
||||
|
||||
for (const viewDescriptor of toSetVisible) {
|
||||
viewDescriptor.repository.setSelected(true);
|
||||
this.viewsModel.setVisible(viewDescriptor.id, true, size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1972,7 +1972,7 @@ class TaskService extends Disposable implements ITaskService {
|
||||
return entries;
|
||||
}
|
||||
|
||||
private showQuickPick(tasks: Promise<Task[]> | Task[], placeHolder: string, defaultEntry?: TaskQuickPickEntry, group: boolean = false, sort: boolean = false, selectedEntry?: TaskQuickPickEntry): Promise<Task | undefined | null> {
|
||||
private showQuickPick(tasks: Promise<Task[]> | Task[], placeHolder: string, defaultEntry?: TaskQuickPickEntry, group: boolean = false, sort: boolean = false, selectedEntry?: TaskQuickPickEntry, additionalEntries?: TaskQuickPickEntry[]): Promise<TaskQuickPickEntry | undefined | null> {
|
||||
let _createEntries = (): Promise<TaskQuickPickEntry[]> => {
|
||||
if (Array.isArray(tasks)) {
|
||||
return Promise.resolve(this.createTaskQuickPickEntries(tasks, group, sort, selectedEntry));
|
||||
@@ -1984,6 +1984,9 @@ class TaskService extends Disposable implements ITaskService {
|
||||
if ((entries.length === 0) && defaultEntry) {
|
||||
entries.push(defaultEntry);
|
||||
}
|
||||
else if (entries.length > 1 && additionalEntries && additionalEntries.length > 0) {
|
||||
entries.push(additionalEntries[0]);
|
||||
}
|
||||
return entries;
|
||||
}), {
|
||||
placeHolder,
|
||||
@@ -1997,7 +2000,7 @@ class TaskService extends Disposable implements ITaskService {
|
||||
this.openConfig(task);
|
||||
}
|
||||
}
|
||||
}).then(entry => entry ? entry.task : undefined);
|
||||
});
|
||||
}
|
||||
|
||||
private showIgnoredFoldersMessage(): Promise<void> {
|
||||
@@ -2057,7 +2060,8 @@ class TaskService extends Disposable implements ITaskService {
|
||||
task: null
|
||||
},
|
||||
true).
|
||||
then((task) => {
|
||||
then((entry) => {
|
||||
let task: Task | undefined | null = entry ? entry.task : undefined;
|
||||
if (task === undefined) {
|
||||
return;
|
||||
}
|
||||
@@ -2137,7 +2141,8 @@ class TaskService extends Disposable implements ITaskService {
|
||||
label: nls.localize('TaskService.noBuildTask', 'No build task to run found. Configure Build Task...'),
|
||||
task: null
|
||||
},
|
||||
true).then((task) => {
|
||||
true).then((entry) => {
|
||||
let task: Task | undefined | null = entry ? entry.task : undefined;
|
||||
if (task === undefined) {
|
||||
return;
|
||||
}
|
||||
@@ -2185,7 +2190,8 @@ class TaskService extends Disposable implements ITaskService {
|
||||
label: nls.localize('TaskService.noTestTaskTerminal', 'No test task to run found. Configure Tasks...'),
|
||||
task: null
|
||||
}, true
|
||||
).then((task) => {
|
||||
).then((entry) => {
|
||||
let task: Task | undefined | null = entry ? entry.task : undefined;
|
||||
if (task === undefined) {
|
||||
return;
|
||||
}
|
||||
@@ -2206,15 +2212,29 @@ class TaskService extends Disposable implements ITaskService {
|
||||
if (!this.canRunCommand()) {
|
||||
return;
|
||||
}
|
||||
if (arg === 'terminateAll') {
|
||||
this.terminateAll();
|
||||
return;
|
||||
}
|
||||
let runQuickPick = (promise?: Promise<Task[]>) => {
|
||||
this.showQuickPick(promise || this.getActiveTasks(),
|
||||
nls.localize('TaskService.taskToTerminate', 'Select task to terminate'),
|
||||
{
|
||||
label: nls.localize('TaskService.noTaskRunning', 'No task is currently running'),
|
||||
task: null
|
||||
task: undefined
|
||||
},
|
||||
false, true
|
||||
).then(task => {
|
||||
false, true,
|
||||
undefined,
|
||||
[{
|
||||
label: nls.localize('TaskService.terminateAllRunningTasks', 'All running tasks'),
|
||||
id: 'terminateAll',
|
||||
task: undefined
|
||||
}]
|
||||
).then(entry => {
|
||||
if (entry && entry.id === 'terminateAll') {
|
||||
this.terminateAll();
|
||||
}
|
||||
let task: Task | undefined | null = entry ? entry.task : undefined;
|
||||
if (task === undefined || task === null) {
|
||||
return;
|
||||
}
|
||||
@@ -2270,7 +2290,8 @@ class TaskService extends Disposable implements ITaskService {
|
||||
task: null
|
||||
},
|
||||
false, true
|
||||
).then(task => {
|
||||
).then(entry => {
|
||||
let task: Task | undefined | null = entry ? entry.task : undefined;
|
||||
if (task === undefined || task === null) {
|
||||
return;
|
||||
}
|
||||
@@ -2482,7 +2503,8 @@ class TaskService extends Disposable implements ITaskService {
|
||||
this.showIgnoredFoldersMessage().then(() => {
|
||||
this.showQuickPick(tasks,
|
||||
nls.localize('TaskService.pickDefaultBuildTask', 'Select the task to be used as the default build task'), undefined, true, false, selectedEntry).
|
||||
then((task) => {
|
||||
then((entry) => {
|
||||
let task: Task | undefined | null = entry ? entry.task : undefined;
|
||||
if ((task === undefined) || (task === null)) {
|
||||
return;
|
||||
}
|
||||
@@ -2532,7 +2554,8 @@ class TaskService extends Disposable implements ITaskService {
|
||||
|
||||
this.showIgnoredFoldersMessage().then(() => {
|
||||
this.showQuickPick(tasks,
|
||||
nls.localize('TaskService.pickDefaultTestTask', 'Select the task to be used as the default test task'), undefined, true, false, selectedEntry).then((task) => {
|
||||
nls.localize('TaskService.pickDefaultTestTask', 'Select the task to be used as the default test task'), undefined, true, false, selectedEntry).then((entry) => {
|
||||
let task: Task | undefined | null = entry ? entry.task : undefined;
|
||||
if (!task) {
|
||||
return;
|
||||
}
|
||||
@@ -2565,7 +2588,8 @@ class TaskService extends Disposable implements ITaskService {
|
||||
task: null
|
||||
},
|
||||
false, true
|
||||
).then((task) => {
|
||||
).then((entry) => {
|
||||
let task: Task | undefined | null = entry ? entry.task : undefined;
|
||||
if (task === undefined || task === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -433,12 +433,10 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneRightT
|
||||
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Resize Pane Right', category);
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneUpTerminalAction, ResizePaneUpTerminalAction.ID, ResizePaneUpTerminalAction.LABEL, {
|
||||
primary: 0,
|
||||
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.UpArrow },
|
||||
mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.UpArrow }
|
||||
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Resize Pane Up', category);
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneDownTerminalAction, ResizePaneDownTerminalAction.ID, ResizePaneDownTerminalAction.LABEL, {
|
||||
primary: 0,
|
||||
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.DownArrow },
|
||||
mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.DownArrow }
|
||||
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Resize Pane Down', category);
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollToPreviousCommandAction, ScrollToPreviousCommandAction.ID, ScrollToPreviousCommandAction.LABEL, {
|
||||
|
||||
@@ -135,47 +135,7 @@ export class TerminalProcessManager implements ITerminalProcessManager {
|
||||
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(hasRemoteAuthority ? REMOTE_HOST_SCHEME : undefined);
|
||||
this._process = this._instantiationService.createInstance(TerminalProcessExtHostProxy, this._terminalId, shellLaunchConfig, activeWorkspaceRootUri, cols, rows);
|
||||
} else {
|
||||
if (!shellLaunchConfig.executable) {
|
||||
this._configHelper.mergeDefaultShellPathAndArgs(shellLaunchConfig);
|
||||
}
|
||||
|
||||
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file);
|
||||
const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, this._environmentService.userHome, activeWorkspaceRootUri, this._configHelper.config.cwd);
|
||||
|
||||
// Compel type system as process.env should not have any undefined entries
|
||||
let env: platform.IProcessEnvironment = {};
|
||||
|
||||
if (shellLaunchConfig.strictEnv) {
|
||||
// Only base the terminal process environment on this environment and add the
|
||||
// various mixins when strictEnv is false
|
||||
env = { ...shellLaunchConfig.env } as any;
|
||||
} else {
|
||||
// Merge process env with the env from config and from shellLaunchConfig
|
||||
env = { ...process.env } as any;
|
||||
|
||||
// Resolve env vars from config and shell
|
||||
const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : null;
|
||||
const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux');
|
||||
const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions();
|
||||
const envFromConfigValue = this._workspaceConfigurationService.inspect<{ [key: string]: string }>(`terminal.integrated.env.${platformKey}`);
|
||||
const allowedEnvFromConfig = (isWorkspaceShellAllowed ? envFromConfigValue.value : envFromConfigValue.user);
|
||||
const envFromConfig = terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, { ...allowedEnvFromConfig }, lastActiveWorkspaceRoot);
|
||||
const envFromShell = terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, { ...shellLaunchConfig.env }, lastActiveWorkspaceRoot);
|
||||
shellLaunchConfig.env = envFromShell;
|
||||
|
||||
terminalEnvironment.mergeEnvironments(env, envFromConfig);
|
||||
terminalEnvironment.mergeEnvironments(env, shellLaunchConfig.env);
|
||||
|
||||
// Sanitize the environment, removing any undesirable VS Code and Electron environment
|
||||
// variables
|
||||
sanitizeProcessEnvironment(env, 'VSCODE_IPC_HOOK_CLI');
|
||||
|
||||
// Adding other env keys necessary to create the process
|
||||
terminalEnvironment.addTerminalEnvironmentKeys(env, this._productService.version, platform.locale, this._configHelper.config.setLocaleVariables);
|
||||
}
|
||||
|
||||
this._logService.debug(`Terminal process launching`, shellLaunchConfig, initialCwd, cols, rows, env);
|
||||
this._process = this._terminalInstanceService.createTerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, this._configHelper.config.windowsEnableConpty);
|
||||
this._process = this._launchProcess(shellLaunchConfig, cols, rows);
|
||||
}
|
||||
this.processState = ProcessState.LAUNCHING;
|
||||
|
||||
@@ -211,6 +171,50 @@ export class TerminalProcessManager implements ITerminalProcessManager {
|
||||
}, LAUNCHING_DURATION);
|
||||
}
|
||||
|
||||
private _launchProcess(shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number): ITerminalChildProcess {
|
||||
if (!shellLaunchConfig.executable) {
|
||||
this._configHelper.mergeDefaultShellPathAndArgs(shellLaunchConfig);
|
||||
}
|
||||
|
||||
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file);
|
||||
const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, this._environmentService.userHome, activeWorkspaceRootUri, this._configHelper.config.cwd);
|
||||
|
||||
// Compel type system as process.env should not have any undefined entries
|
||||
let env: platform.IProcessEnvironment = {};
|
||||
|
||||
if (shellLaunchConfig.strictEnv) {
|
||||
// Only base the terminal process environment on this environment and add the
|
||||
// various mixins when strictEnv is false
|
||||
env = { ...shellLaunchConfig.env } as any;
|
||||
} else {
|
||||
// Merge process env with the env from config and from shellLaunchConfig
|
||||
env = { ...process.env } as any;
|
||||
|
||||
// Resolve env vars from config and shell
|
||||
const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : null;
|
||||
const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux');
|
||||
const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions();
|
||||
const envFromConfigValue = this._workspaceConfigurationService.inspect<{ [key: string]: string }>(`terminal.integrated.env.${platformKey}`);
|
||||
const allowedEnvFromConfig = (isWorkspaceShellAllowed ? envFromConfigValue.value : envFromConfigValue.user);
|
||||
const envFromConfig = terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, { ...allowedEnvFromConfig }, lastActiveWorkspaceRoot);
|
||||
const envFromShell = terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, { ...shellLaunchConfig.env }, lastActiveWorkspaceRoot);
|
||||
shellLaunchConfig.env = envFromShell;
|
||||
|
||||
terminalEnvironment.mergeEnvironments(env, envFromConfig);
|
||||
terminalEnvironment.mergeEnvironments(env, shellLaunchConfig.env);
|
||||
|
||||
// Sanitize the environment, removing any undesirable VS Code and Electron environment
|
||||
// variables
|
||||
sanitizeProcessEnvironment(env, 'VSCODE_IPC_HOOK_CLI');
|
||||
|
||||
// Adding other env keys necessary to create the process
|
||||
terminalEnvironment.addTerminalEnvironmentKeys(env, this._productService.version, platform.locale, this._configHelper.config.setLocaleVariables);
|
||||
}
|
||||
|
||||
this._logService.debug(`Terminal process launching`, shellLaunchConfig, initialCwd, cols, rows, env);
|
||||
return this._terminalInstanceService.createTerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, this._configHelper.config.windowsEnableConpty);
|
||||
}
|
||||
|
||||
public setDimensions(cols: number, rows: number): void {
|
||||
if (!this._process) {
|
||||
return;
|
||||
|
||||
@@ -22,6 +22,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance';
|
||||
import { IBrowserTerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
|
||||
export abstract class TerminalService extends CommonTerminalService implements ITerminalService {
|
||||
protected _configHelper: IBrowserTerminalConfigHelper;
|
||||
@@ -38,8 +39,9 @@ export abstract class TerminalService extends CommonTerminalService implements I
|
||||
@IWorkbenchEnvironmentService private _environmentService: IWorkbenchEnvironmentService,
|
||||
@IExtensionService extensionService: IExtensionService,
|
||||
@IFileService fileService: IFileService,
|
||||
@IRemoteAgentService remoteAgentService: IRemoteAgentService
|
||||
) {
|
||||
super(contextKeyService, panelService, lifecycleService, storageService, notificationService, dialogService, extensionService, fileService);
|
||||
super(contextKeyService, panelService, lifecycleService, storageService, notificationService, dialogService, extensionService, fileService, remoteAgentService);
|
||||
}
|
||||
|
||||
protected abstract _getDefaultShell(p: platform.Platform): string;
|
||||
|
||||
@@ -267,6 +267,7 @@ export interface ITerminalService {
|
||||
*/
|
||||
preparePathForTerminalAsync(path: string, executable: string | undefined, title: string): Promise<string>;
|
||||
|
||||
extHostReady(remoteAuthority: string): void;
|
||||
requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number): void;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { ITerminalService, ITerminalProcessExtHostProxy, IShellLaunchConfig, ITerminalChildProcess } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
|
||||
export class TerminalProcessExtHostProxy implements ITerminalChildProcess, ITerminalProcessExtHostProxy {
|
||||
private _disposables: IDisposable[] = [];
|
||||
@@ -44,15 +43,10 @@ export class TerminalProcessExtHostProxy implements ITerminalChildProcess, ITerm
|
||||
activeWorkspaceRootUri: URI,
|
||||
cols: number,
|
||||
rows: number,
|
||||
@ITerminalService private readonly _terminalService: ITerminalService,
|
||||
@IExtensionService private readonly _extensionService: IExtensionService
|
||||
@ITerminalService private readonly _terminalService: ITerminalService
|
||||
) {
|
||||
this._extensionService.whenInstalledExtensionsRegistered().then(() => {
|
||||
// TODO: MainThreadTerminalService is not ready at this point, fix this
|
||||
setTimeout(() => {
|
||||
this._terminalService.requestExtHostProcess(this, shellLaunchConfig, activeWorkspaceRootUri, cols, rows);
|
||||
}, 0);
|
||||
});
|
||||
this._terminalService.requestExtHostProcess(this, shellLaunchConfig, activeWorkspaceRootUri, cols, rows);
|
||||
setTimeout(() => this._onProcessTitleChanged.fire('Starting...'), 0);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
|
||||
@@ -19,6 +19,8 @@ import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
import { basename } from 'vs/base/common/path';
|
||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
|
||||
export abstract class TerminalService implements ITerminalService {
|
||||
public _serviceBrand: any;
|
||||
@@ -32,7 +34,7 @@ export abstract class TerminalService implements ITerminalService {
|
||||
return this._terminalTabs.reduce((p, c) => p.concat(c.terminalInstances), <ITerminalInstance[]>[]);
|
||||
}
|
||||
private _findState: FindReplaceState;
|
||||
|
||||
private _extHostsReady: { [authority: string]: boolean } = {};
|
||||
private _activeTabIndex: number;
|
||||
|
||||
public get activeTabIndex(): number { return this._activeTabIndex; }
|
||||
@@ -65,12 +67,13 @@ export abstract class TerminalService implements ITerminalService {
|
||||
constructor(
|
||||
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
|
||||
@IPanelService protected readonly _panelService: IPanelService,
|
||||
@ILifecycleService lifecycleService: ILifecycleService,
|
||||
@ILifecycleService readonly lifecycleService: ILifecycleService,
|
||||
@IStorageService protected readonly _storageService: IStorageService,
|
||||
@INotificationService protected readonly _notificationService: INotificationService,
|
||||
@IDialogService private readonly _dialogService: IDialogService,
|
||||
@IExtensionService private readonly _extensionService: IExtensionService,
|
||||
@IFileService protected readonly _fileService: IFileService
|
||||
@IFileService protected readonly _fileService: IFileService,
|
||||
@IRemoteAgentService readonly _remoteAgentService: IRemoteAgentService
|
||||
) {
|
||||
this._activeTabIndex = 0;
|
||||
this._isShuttingDown = false;
|
||||
@@ -116,15 +119,22 @@ export abstract class TerminalService implements ITerminalService {
|
||||
}
|
||||
|
||||
public requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number): void {
|
||||
// Ensure extension host is ready before requesting a process
|
||||
this._extensionService.whenInstalledExtensionsRegistered().then(() => {
|
||||
// TODO: MainThreadTerminalService is not ready at this point, fix this
|
||||
setTimeout(() => {
|
||||
this._onInstanceRequestExtHostProcess.fire({ proxy, shellLaunchConfig, activeWorkspaceRootUri, cols, rows });
|
||||
}, 500);
|
||||
this._extensionService.whenInstalledExtensionsRegistered().then(async () => {
|
||||
// Wait for the remoteAuthority to be ready (and listening for events) before proceeding
|
||||
const conn = this._remoteAgentService.getConnection();
|
||||
const remoteAuthority = conn ? conn.remoteAuthority : 'null';
|
||||
let retries = 0;
|
||||
while (!this._extHostsReady[remoteAuthority] && ++retries < 50) {
|
||||
await timeout(100);
|
||||
}
|
||||
this._onInstanceRequestExtHostProcess.fire({ proxy, shellLaunchConfig, activeWorkspaceRootUri, cols, rows });
|
||||
});
|
||||
}
|
||||
|
||||
public extHostReady(remoteAuthority: string): void {
|
||||
this._extHostsReady[remoteAuthority] = true;
|
||||
}
|
||||
|
||||
private _onBeforeShutdown(): boolean | Promise<boolean> {
|
||||
if (this.terminalInstances.length === 0) {
|
||||
// No terminal instances, don't veto
|
||||
|
||||
@@ -28,6 +28,7 @@ import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
||||
import { execFile } from 'child_process';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
|
||||
export class TerminalService extends BrowserTerminalService implements ITerminalService {
|
||||
public get configHelper(): ITerminalConfigHelper { return this._configHelper; }
|
||||
@@ -45,9 +46,10 @@ export class TerminalService extends BrowserTerminalService implements ITerminal
|
||||
@IDialogService dialogService: IDialogService,
|
||||
@IExtensionService extensionService: IExtensionService,
|
||||
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
|
||||
@IFileService fileService: IFileService
|
||||
@IFileService fileService: IFileService,
|
||||
@IRemoteAgentService remoteAgentService: IRemoteAgentService
|
||||
) {
|
||||
super(contextKeyService, panelService, layoutService, lifecycleService, storageService, notificationService, dialogService, instantiationService, environmentService, extensionService, fileService);
|
||||
super(contextKeyService, panelService, layoutService, lifecycleService, storageService, notificationService, dialogService, instantiationService, environmentService, extensionService, fileService, remoteAgentService);
|
||||
|
||||
this._configHelper = this._instantiationService.createInstance(TerminalConfigHelper, linuxDistro);
|
||||
ipc.on('vscode:openFiles', (_event: any, request: IOpenFileRequest) => {
|
||||
|
||||
@@ -8,6 +8,7 @@ import { URI } from 'vs/base/common/uri';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
|
||||
/**
|
||||
* Set when the find widget in a webview is visible.
|
||||
@@ -28,11 +29,6 @@ export interface IWebviewService {
|
||||
): Webview;
|
||||
}
|
||||
|
||||
export interface WebviewPortMapping {
|
||||
readonly port: number;
|
||||
readonly resolvedPort: number;
|
||||
}
|
||||
|
||||
export interface WebviewOptions {
|
||||
readonly allowSvgs?: boolean;
|
||||
readonly extension?: {
|
||||
@@ -46,7 +42,7 @@ export interface WebviewContentOptions {
|
||||
readonly allowScripts?: boolean;
|
||||
readonly svgWhiteList?: string[];
|
||||
readonly localResourceRoots?: ReadonlyArray<URI>;
|
||||
readonly portMappings?: ReadonlyArray<WebviewPortMapping>;
|
||||
readonly portMappings?: ReadonlyArray<modes.IWebviewPortMapping>;
|
||||
}
|
||||
|
||||
export interface Webview {
|
||||
|
||||
@@ -11,21 +11,22 @@ import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
import { endsWith } from 'vs/base/common/strings';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { EDITOR_FONT_DEFAULTS, IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import * as colorRegistry from 'vs/platform/theme/common/colorRegistry';
|
||||
import { DARK, ITheme, IThemeService, LIGHT } from 'vs/platform/theme/common/themeService';
|
||||
import { Webview, WebviewContentOptions, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview';
|
||||
import { registerFileProtocol, WebviewProtocol } from 'vs/workbench/contrib/webview/electron-browser/webviewProtocols';
|
||||
import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { areWebviewInputOptionsEqual } from '../browser/webviewEditorService';
|
||||
import { WebviewFindWidget } from '../browser/webviewFindWidget';
|
||||
import { WebviewContentOptions, WebviewPortMapping, WebviewOptions, Webview } from 'vs/workbench/contrib/webview/common/webview';
|
||||
import { ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IEditorOptions, EDITOR_FONT_DEFAULTS } from 'vs/editor/common/config/editorOptions';
|
||||
|
||||
export interface WebviewPortMapping {
|
||||
readonly port: number;
|
||||
@@ -153,7 +154,7 @@ class WebviewPortMappingProvider extends Disposable {
|
||||
constructor(
|
||||
session: WebviewSession,
|
||||
extensionLocation: URI | undefined,
|
||||
mappings: () => ReadonlyArray<WebviewPortMapping>,
|
||||
mappings: () => ReadonlyArray<modes.IWebviewPortMapping>,
|
||||
private readonly tunnelService: ITunnelService,
|
||||
extensionId: ExtensionIdentifier | undefined,
|
||||
@ITelemetryService telemetryService: ITelemetryService
|
||||
@@ -183,23 +184,23 @@ class WebviewPortMappingProvider extends Disposable {
|
||||
|
||||
const port = +localhostMatch[1];
|
||||
for (const mapping of mappings()) {
|
||||
if (mapping.port === port) {
|
||||
if (mapping.webviewPort === port) {
|
||||
if (extensionLocation && extensionLocation.scheme === REMOTE_HOST_SCHEME) {
|
||||
const tunnel = await this.getOrCreateTunnel(mapping.resolvedPort);
|
||||
const tunnel = await this.getOrCreateTunnel(mapping.extensionHostPort);
|
||||
if (tunnel) {
|
||||
return {
|
||||
redirectURL: details.url.replace(
|
||||
new RegExp(`^${uri.scheme}://localhost:${mapping.port}/`),
|
||||
new RegExp(`^${uri.scheme}://localhost:${mapping.webviewPort}/`),
|
||||
`${uri.scheme}://localhost:${tunnel.tunnelLocalPort}/`)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (mapping.port !== mapping.resolvedPort) {
|
||||
if (mapping.webviewPort !== mapping.extensionHostPort) {
|
||||
return {
|
||||
redirectURL: details.url.replace(
|
||||
new RegExp(`^${uri.scheme}://localhost:${mapping.port}/`),
|
||||
`${uri.scheme}://localhost:${mapping.resolvedPort}/`)
|
||||
new RegExp(`^${uri.scheme}://localhost:${mapping.webviewPort}/`),
|
||||
`${uri.scheme}://localhost:${mapping.extensionHostPort}/`)
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -416,7 +417,7 @@ export class WebviewElement extends Disposable implements Webview {
|
||||
this._register(new WebviewPortMappingProvider(
|
||||
session,
|
||||
_options.extension ? _options.extension.location : undefined,
|
||||
() => (this._contentOptions.portMappings || [{ port: 3000, resolvedPort: 4000 }]),
|
||||
() => (this._contentOptions.portMappings || []),
|
||||
tunnelService,
|
||||
_options.extension ? _options.extension.id : undefined,
|
||||
telemetryService
|
||||
|
||||
Reference in New Issue
Block a user