Merge from vscode 3a6dcb42008d509900b3a3b2d695564eeb4dbdac (#5098)

This commit is contained in:
Alan Ren
2019-04-17 23:38:44 -07:00
committed by GitHub
parent 1fec26c6b3
commit b852f032d3
63 changed files with 676 additions and 413 deletions

View File

@@ -184,6 +184,12 @@ export class MainThreadCommentThread implements modes.CommentThread2 {
private _onDidChangeCollasibleState = new Emitter<modes.CommentThreadCollapsibleState | undefined>();
public onDidChangeCollasibleState = this._onDidChangeCollasibleState.event;
private _isDisposed: boolean;
get isDisposed(): boolean {
return this._isDisposed;
}
constructor(
public commentThreadHandle: number,
public controller: MainThreadCommentController,
@@ -191,7 +197,9 @@ export class MainThreadCommentThread implements modes.CommentThread2 {
public threadId: string,
public resource: string,
private _range: IRange
) { }
) {
this._isDisposed = false;
}
batchUpdate(
range: IRange,
@@ -210,7 +218,16 @@ export class MainThreadCommentThread implements modes.CommentThread2 {
this._collapsibleState = collapsibleState;
}
dispose() { }
dispose() {
this._isDisposed = true;
this._onDidChangeAcceptInputCommand.dispose();
this._onDidChangeAdditionalCommands.dispose();
this._onDidChangeCollasibleState.dispose();
this._onDidChangeComments.dispose();
this._onDidChangeInput.dispose();
this._onDidChangeLabel.dispose();
this._onDidChangeRange.dispose();
}
toJSON(): any {
return {
@@ -493,6 +510,8 @@ export class MainThreadComments extends Disposable implements MainThreadComments
return undefined;
}
console.log('createCommentThread', commentThreadHandle);
return provider.createCommentThread(commentThreadHandle, threadId, resource, range);
}

View File

@@ -46,23 +46,20 @@ export class MainThreadWindow implements MainThreadWindowShape {
}
async $openUri(uriComponent: UriComponents, options: IOpenUriOptions): Promise<boolean> {
const uri = URI.revive(uriComponent);
let uri = URI.revive(uriComponent);
if (options.allowTunneling && !!this.environmentService.configuration.remoteAuthority) {
if (uri.scheme === 'http' || uri.scheme === 'https') {
const port = this.getLocalhostPort(uri);
if (typeof port === 'number') {
const tunnel = await this.getOrCreateTunnel(port);
if (tunnel) {
const tunneledUrl = uri.toString().replace(
new RegExp(`^${uri.scheme}://localhost:${port}/`),
`${uri.scheme}://localhost:${tunnel.tunnelLocalPort}/`);
return this.windowsService.openExternal(tunneledUrl);
uri = uri.with({ authority: `localhost:${tunnel.tunnelLocalPort}` });
}
}
}
}
return this.windowsService.openExternal(uri.toString(true));
return this.windowsService.openExternal(encodeURI(uri.toString(true)));
}
private getLocalhostPort(uri: URI): number | undefined {

View File

@@ -22,6 +22,8 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import { ExtHostContext, ExtHostWorkspaceShape, IExtHostContext, MainContext, MainThreadWorkspaceShape, IWorkspaceData, ITextSearchComplete } from '../common/extHost.protocol';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { isEqualOrParent } from 'vs/base/common/resources';
@extHostNamedCustomer(MainContext.MainThreadWorkspace)
export class MainThreadWorkspace implements MainThreadWorkspaceShape {
@@ -40,7 +42,8 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape {
@IStatusbarService private readonly _statusbarService: IStatusbarService,
@IWindowService private readonly _windowService: IWindowService,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@ILabelService private readonly _labelService: ILabelService
@ILabelService private readonly _labelService: ILabelService,
@IEnvironmentService private readonly _environmentService: IEnvironmentService
) {
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostWorkspace);
this._contextService.getCompleteWorkspace().then(workspace => this._proxy.$initializeWorkspace(this.getWorkspaceData(workspace)));
@@ -110,6 +113,7 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape {
}
return {
configuration: workspace.configuration || undefined,
isUntitled: workspace.configuration ? isEqualOrParent(workspace.configuration, this._environmentService.untitledWorkspacesHome) : false,
folders: workspace.folders,
id: workspace.id,
name: this._labelService.getWorkspaceLabel(workspace)

View File

@@ -15,6 +15,7 @@ import { IWindowsService, IOpenSettings, IURIToOpen } from 'vs/platform/windows/
import { IDownloadService } from 'vs/platform/download/common/download';
import { IWorkspacesService, hasWorkspaceFileExtension } from 'vs/platform/workspaces/common/workspaces';
import { IRecent } from 'vs/platform/history/common/history';
import { Schemas } from 'vs/base/common/network';
// -----------------------------------------------------------------
// The following commands are registered on both sides separately.
@@ -51,7 +52,7 @@ export class OpenFolderAPICommand {
}
const options: IOpenSettings = { forceNewWindow: arg.forceNewWindow, noRecentEntry: arg.noRecentEntry };
uri = URI.revive(uri);
const uriToOpen: IURIToOpen = hasWorkspaceFileExtension(uri.path) ? { workspaceUri: uri } : { folderUri: uri };
const uriToOpen: IURIToOpen = (hasWorkspaceFileExtension(uri.path) || uri.scheme === Schemas.untitled) ? { workspaceUri: uri } : { folderUri: uri };
return executor.executeCommand('_files.windowOpen', [uriToOpen], options);
}
}

View File

@@ -68,6 +68,7 @@ export interface IStaticWorkspaceData {
id: string;
name: string;
configuration?: UriComponents | null;
isUntitled?: boolean | null;
}
export interface IWorkspaceData extends IStaticWorkspaceData {

View File

@@ -10,7 +10,7 @@ import { Emitter, Event } from 'vs/base/common/event';
import { TernarySearchTree } from 'vs/base/common/map';
import { Counter } from 'vs/base/common/numbers';
import { isLinux } from 'vs/base/common/platform';
import { basenameOrAuthority, dirname, isEqual, relativePath } from 'vs/base/common/resources';
import { basenameOrAuthority, dirname, isEqual, relativePath, basename } from 'vs/base/common/resources';
import { compare } from 'vs/base/common/strings';
import { URI } from 'vs/base/common/uri';
import { localize } from 'vs/nls';
@@ -24,6 +24,7 @@ import * as vscode from 'vscode';
import { ExtHostWorkspaceShape, IWorkspaceData, MainThreadMessageServiceShape, MainThreadWorkspaceShape, IMainContext, MainContext, IStaticWorkspaceData } from './extHost.protocol';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { Barrier } from 'vs/base/common/async';
import { Schemas } from 'vs/base/common/network';
export interface IExtHostWorkspaceProvider {
getWorkspaceFolder2(uri: vscode.Uri, resolveParent?: boolean): Promise<vscode.WorkspaceFolder | undefined>;
@@ -67,7 +68,7 @@ class ExtHostWorkspaceImpl extends Workspace {
return { workspace: null, added: [], removed: [] };
}
const { id, name, folders } = data;
const { id, name, folders, configuration, isUntitled } = data;
const newWorkspaceFolders: vscode.WorkspaceFolder[] = [];
// If we have an existing workspace, we try to find the folders that match our
@@ -95,7 +96,7 @@ class ExtHostWorkspaceImpl extends Workspace {
// make sure to restore sort order based on index
newWorkspaceFolders.sort((f1, f2) => f1.index < f2.index ? -1 : 1);
const workspace = new ExtHostWorkspaceImpl(id, name, newWorkspaceFolders);
const workspace = new ExtHostWorkspaceImpl(id, name, newWorkspaceFolders, configuration ? URI.revive(configuration) : null, !!isUntitled);
const { added, removed } = delta(oldWorkspace ? oldWorkspace.workspaceFolders : [], workspace.workspaceFolders, compareWorkspaceFolderByUri);
return { workspace, added, removed };
@@ -115,8 +116,8 @@ class ExtHostWorkspaceImpl extends Workspace {
private readonly _workspaceFolders: vscode.WorkspaceFolder[] = [];
private readonly _structure = TernarySearchTree.forPaths<vscode.WorkspaceFolder>();
constructor(id: string, private _name: string, folders: vscode.WorkspaceFolder[]) {
super(id, folders.map(f => new WorkspaceFolder(f)));
constructor(id: string, private _name: string, folders: vscode.WorkspaceFolder[], configuration: URI | null, private _isUntitled: boolean) {
super(id, folders.map(f => new WorkspaceFolder(f)), configuration);
// setup the workspace folder data structure
folders.forEach(folder => {
@@ -129,6 +130,10 @@ class ExtHostWorkspaceImpl extends Workspace {
return this._name;
}
get isUntitled(): boolean {
return this._isUntitled;
}
get workspaceFolders(): vscode.WorkspaceFolder[] {
return this._workspaceFolders.slice(0);
}
@@ -175,7 +180,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac
this._proxy = mainContext.getProxy(MainContext.MainThreadWorkspace);
this._messageService = mainContext.getProxy(MainContext.MainThreadMessageService);
this._confirmedWorkspace = data ? new ExtHostWorkspaceImpl(data.id, data.name, []) : undefined;
this._confirmedWorkspace = data ? new ExtHostWorkspaceImpl(data.id, data.name, [], data.configuration ? URI.revive(data.configuration) : null, !!data.isUntitled) : undefined;
}
$initializeWorkspace(data: IWorkspaceData): void {
@@ -197,6 +202,20 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac
return this._actualWorkspace ? this._actualWorkspace.name : undefined;
}
get workspaceFile(): vscode.Uri | undefined {
if (this._actualWorkspace) {
if (this._actualWorkspace.configuration) {
if (this._actualWorkspace.isUntitled) {
return URI.from({ scheme: Schemas.untitled, path: basename(dirname(this._actualWorkspace.configuration)) }); // Untitled Worspace: return untitled URI
}
return this._actualWorkspace.configuration; // Workspace: return the configuration location
}
}
return undefined;
}
private get _actualWorkspace(): ExtHostWorkspaceImpl | undefined {
return this._unconfirmedWorkspace || this._confirmedWorkspace;
}
@@ -365,7 +384,8 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac
id: this._actualWorkspace.id,
name: this._actualWorkspace.name,
configuration: this._actualWorkspace.configuration,
folders
folders,
isUntitled: this._actualWorkspace.isUntitled
} as IWorkspaceData, this._actualWorkspace).workspace || undefined;
}
}

View File

@@ -116,7 +116,7 @@ export function createApiFactory(
const extHostFileSystem = rpcProtocol.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(rpcProtocol, extHostLanguageFeatures));
const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpcProtocol, extHostDocumentsAndEditors));
const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands));
const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostLogService));
const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostWorkspace, extHostDocumentsAndEditors, extHostLogService));
// {{SQL CARBON EDIT}}
// const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(rpcProtocol, extHostWorkspace, extensionService, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService, extHostCommands));
const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService));
@@ -539,6 +539,12 @@ export function createApiFactory(
set name(value) {
throw errors.readonly();
},
get workspaceFile() {
return extHostWorkspace.workspaceFile;
},
set workspaceFile(value) {
throw errors.readonly();
},
updateWorkspaceFolders: (index, deleteCount, ...workspaceFoldersToAdd) => {
return extHostWorkspace.updateWorkspaceFolders(extension, index, deleteCount || 0, ...workspaceFoldersToAdd);
},

View File

@@ -65,6 +65,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
private readonly _mainThreadExtensionsProxy: MainThreadExtensionServiceShape;
private readonly _almostReadyToRunExtensions: Barrier;
private readonly _readyToStartExtensionHost: Barrier;
private readonly _readyToRunExtensions: Barrier;
private readonly _registry: ExtensionDescriptionRegistry;
private readonly _storage: ExtHostStorage;
@@ -101,6 +102,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
this._mainThreadExtensionsProxy = this._extHostContext.getProxy(MainContext.MainThreadExtensionService);
this._almostReadyToRunExtensions = new Barrier();
this._readyToStartExtensionHost = new Barrier();
this._readyToRunExtensions = new Barrier();
this._registry = new ExtensionDescriptionRegistry(initData.extensions);
this._storage = new ExtHostStorage(this._extHostContext);
@@ -171,7 +173,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
this._almostReadyToRunExtensions.open();
await this._extHostWorkspace.waitForInitializeCall();
this._readyToRunExtensions.open();
this._readyToStartExtensionHost.open();
} catch (err) {
errors.onUnexpectedError(err);
}
@@ -581,7 +583,8 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
}
this._started = true;
return this._readyToRunExtensions.wait()
return this._readyToStartExtensionHost.wait()
.then(() => this._readyToRunExtensions.open())
.then(() => this._handleEagerExtensions())
.then(() => this._handleExtensionTests())
.then(() => {

View File

@@ -13,10 +13,14 @@ 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 { ILogService } from 'vs/platform/log/common/log';
import { EXT_HOST_CREATION_DELAY, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal';
import { EXT_HOST_CREATION_DELAY, IShellLaunchConfig, ITerminalEnvironment } from 'vs/workbench/contrib/terminal/common/terminal';
import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess';
import { timeout } from 'vs/base/common/async';
import { sanitizeProcessEnvironment } from 'vs/base/common/processes';
import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
// {{SQL CARBON EDIT}}
// import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDebugService';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
const RENDERER_NO_PROCESS_ID = -1;
@@ -288,6 +292,8 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
constructor(
mainContext: IMainContext,
private _extHostConfiguration: ExtHostConfiguration,
private _extHostWorkspace: ExtHostWorkspace,
private _extHostDocumentsAndEditors: ExtHostDocumentsAndEditors,
private _logService: ILogService,
) {
this._proxy = mainContext.getProxy(MainContext.MainThreadTerminalService);
@@ -436,6 +442,16 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
}
}
private _apiInspectConfigToPlain<T>(
config: { key: string; defaultValue?: T; globalValue?: T; workspaceValue?: T, workspaceFolderValue?: T } | undefined
): { user: T | undefined, value: T | undefined, default: T | undefined } {
return {
user: config ? config.globalValue : undefined,
value: config ? config.workspaceValue : undefined,
default: config ? config.defaultValue : undefined,
};
}
public async $createProcess(id: number, shellLaunchConfigDto: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise<void> {
const shellLaunchConfig: IShellLaunchConfig = {
name: shellLaunchConfigDto.name,
@@ -447,57 +463,54 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
// Merge in shell and args from settings
const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux');
const configProvider = await this._extHostConfiguration.getConfigProvider();
if (!shellLaunchConfig.executable) {
const fetchSetting = (key: string) => {
const setting = configProvider
.getConfiguration(key.substr(0, key.lastIndexOf('.')))
.inspect<string | string[]>(key.substr(key.lastIndexOf('.') + 1));
return {
user: setting ? setting.globalValue : undefined,
value: setting ? setting.workspaceValue : undefined,
default: setting ? setting.defaultValue : undefined,
};
return this._apiInspectConfigToPlain<string | string[]>(setting);
};
terminalEnvironment.mergeDefaultShellPathAndArgs(shellLaunchConfig, fetchSetting, isWorkspaceShellAllowed || false);
}
// Get the initial cwd
const configProvider = await this._extHostConfiguration.getConfigProvider();
const terminalConfig = configProvider.getConfiguration('terminal.integrated');
const activeWorkspaceRootUri = URI.revive(activeWorkspaceRootUriComponents);
const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, os.homedir(), activeWorkspaceRootUri, terminalConfig.cwd);
// TODO: Pull in and resolve config settings
// // Resolve env vars from config and shell
// const lastActiveWorkspaceRoot = this._workspaceContextService.getWorkspaceFolder(lastActiveWorkspaceRootUri);
// const envFromConfig = terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, { ...terminalConfig.env[platformKey] }, lastActiveWorkspaceRoot);
const envFromConfig = { ...terminalConfig.env[platformKey] };
// const envFromShell = terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, { ...shellLaunchConfig.env }, lastActiveWorkspaceRoot);
// Merge process env with the env from config
const env = { ...process.env };
Object.keys(env).filter(k => env[k] === undefined).forEach(k => {
delete env[k];
});
const castedEnv = env as platform.IProcessEnvironment;
terminalEnvironment.mergeEnvironments(castedEnv, envFromConfig);
terminalEnvironment.mergeEnvironments(castedEnv, shellLaunchConfig.env);
// Sanitize the environment, removing any undesirable VS Code and Electron environment
// variables
sanitizeProcessEnvironment(castedEnv, 'VSCODE_IPC_HOOK_CLI');
// Continue env initialization, merging in the env from the launch
// config and adding keys that are needed to create the process
terminalEnvironment.addTerminalEnvironmentKeys(castedEnv, pkg.version, platform.locale, terminalConfig.get('setLocaleVariables') as boolean);
// Get the environment
const apiLastActiveWorkspace = await this._extHostWorkspace.getWorkspaceFolder(activeWorkspaceRootUri);
const lastActiveWorkspace = apiLastActiveWorkspace ? {
uri: apiLastActiveWorkspace.uri,
name: apiLastActiveWorkspace.name,
index: apiLastActiveWorkspace.index,
toResource: () => {
throw new Error('Not implemented');
}
} as IWorkspaceFolder : null;
const envFromConfig = this._apiInspectConfigToPlain(configProvider.getConfiguration('terminal.integrated').inspect<ITerminalEnvironment>(`env.${platformKey}`));
const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2();
// {{SQL CARBON EDIT}}
// const variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined;
const variableResolver = undefined;
const env = terminalEnvironment.createTerminalEnvironment(
shellLaunchConfig,
lastActiveWorkspace,
envFromConfig,
variableResolver,
isWorkspaceShellAllowed,
pkg.version,
terminalConfig.get<boolean>('setLocaleVariables', false)
);
// Fork the process and listen for messages
this._logService.debug(`Terminal process launching on ext host`, shellLaunchConfig, initialCwd, cols, rows, castedEnv);
const p = new TerminalProcess(shellLaunchConfig, initialCwd, cols, rows, castedEnv, terminalConfig.get('windowsEnableConpty') as boolean);
this._logService.debug(`Terminal process launching on ext host`, shellLaunchConfig, initialCwd, cols, rows, env);
const p = new TerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, terminalConfig.get('windowsEnableConpty') as boolean);
p.onProcessIdReady(pid => this._proxy.$sendProcessPid(id, pid));
p.onProcessTitleChanged(title => this._proxy.$sendProcessTitle(id, title));
p.onProcessData(data => this._proxy.$sendProcessData(id, data));
p.onProcessExit((exitCode) => this._onProcessExit(id, exitCode));
p.onProcessExit(exitCode => this._onProcessExit(id, exitCode));
this._terminalProcesses[id] = p;
}
@@ -541,7 +554,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
// Send exit event to main side
this._proxy.$sendProcessExit(id, exitCode);
}
private _getTerminalByIdEventually(id: number, retries: number = 5): Promise<ExtHostTerminal> {