mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-24 02:28:34 +01:00
Merge master.
This commit is contained in:
@@ -20,6 +20,8 @@ import { ExtHostDiagnostics } from 'vs/workbench/api/node/extHostDiagnostics';
|
||||
import { ExtHostTreeExplorers } from 'vs/workbench/api/node/extHostTreeExplorers';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { ExtHostQuickOpen } from 'vs/workbench/api/node/extHostQuickOpen';
|
||||
import { ExtHostProgress } from 'vs/workbench/api/node/extHostProgress';
|
||||
import { ExtHostSCM } from 'vs/workbench/api/node/extHostSCM';
|
||||
import { ExtHostHeapService } from 'vs/workbench/api/node/extHostHeapService';
|
||||
import { ExtHostStatusBar } from 'vs/workbench/api/node/extHostStatusBar';
|
||||
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
|
||||
@@ -59,6 +61,33 @@ function proposedApiFunction<T>(extension: IExtensionDescription, fn: T): T {
|
||||
}
|
||||
}
|
||||
|
||||
function proposed(extension: IExtensionDescription): Function {
|
||||
return (target: any, key: string, descriptor: any) => {
|
||||
let fnKey: string = null;
|
||||
let fn: Function = null;
|
||||
|
||||
if (typeof descriptor.value === 'function') {
|
||||
fnKey = 'value';
|
||||
fn = descriptor.value;
|
||||
} else if (typeof descriptor.get === 'function') {
|
||||
fnKey = 'get';
|
||||
fn = descriptor.get;
|
||||
}
|
||||
|
||||
if (!fn) {
|
||||
throw new Error('not supported');
|
||||
}
|
||||
|
||||
if (extension.enableProposedApi) {
|
||||
return;
|
||||
}
|
||||
|
||||
descriptor[fnKey] = () => {
|
||||
throw new Error(`${extension.id} cannot access proposed api`);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This method instantiates and returns the extension API surface
|
||||
*/
|
||||
@@ -78,14 +107,16 @@ export function createApiFactory(initData: IInitData, threadService: IThreadServ
|
||||
const extHostFileSystemEvent = col.define(ExtHostContext.ExtHostFileSystemEventService).set<ExtHostFileSystemEventService>(new ExtHostFileSystemEventService());
|
||||
const extHostQuickOpen = col.define(ExtHostContext.ExtHostQuickOpen).set<ExtHostQuickOpen>(new ExtHostQuickOpen(threadService));
|
||||
const extHostTerminalService = col.define(ExtHostContext.ExtHostTerminalService).set<ExtHostTerminalService>(new ExtHostTerminalService(threadService));
|
||||
const extHostSCM = col.define(ExtHostContext.ExtHostSCM).set<ExtHostSCM>(new ExtHostSCM(threadService));
|
||||
col.define(ExtHostContext.ExtHostExtensionService).set(extensionService);
|
||||
col.finish(false, threadService);
|
||||
|
||||
// Other instances
|
||||
const extHostMessageService = new ExtHostMessageService(threadService);
|
||||
const extHostStatusBar = new ExtHostStatusBar(threadService);
|
||||
const extHostProgress = new ExtHostProgress(threadService.get(MainContext.MainThreadProgress));
|
||||
const extHostOutputService = new ExtHostOutputService(threadService);
|
||||
const workspacePath = contextService.getWorkspace() ? contextService.getWorkspace().resource.fsPath : undefined;
|
||||
const workspacePath = contextService.hasWorkspace() ? contextService.getWorkspace().resource.fsPath : undefined;
|
||||
const extHostWorkspace = new ExtHostWorkspace(threadService, workspacePath);
|
||||
const extHostLanguages = new ExtHostLanguages(threadService);
|
||||
|
||||
@@ -96,7 +127,7 @@ export function createApiFactory(initData: IInitData, threadService: IThreadServ
|
||||
|
||||
if (extension.enableProposedApi) {
|
||||
|
||||
if (!initData.environment.enableProposedApi) {
|
||||
if (!initData.environment.enableProposedApi && !extension.isBuiltin) {
|
||||
extension.enableProposedApi = false;
|
||||
console.warn('PROPOSED API is only available when developing an extension');
|
||||
|
||||
@@ -180,6 +211,9 @@ export function createApiFactory(initData: IInitData, threadService: IThreadServ
|
||||
registerDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.DefinitionProvider): vscode.Disposable {
|
||||
return languageFeatures.registerDefinitionProvider(selector, provider);
|
||||
},
|
||||
registerTypeDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.TypeDefinitionProvider): vscode.Disposable {
|
||||
return languageFeatures.registerTypeDefinitionProvider(selector, provider);
|
||||
},
|
||||
registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable {
|
||||
return languageFeatures.registerHoverProvider(selector, provider);
|
||||
},
|
||||
@@ -274,11 +308,20 @@ export function createApiFactory(initData: IInitData, threadService: IThreadServ
|
||||
setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable<any>): vscode.Disposable {
|
||||
return extHostStatusBar.setStatusBarMessage(text, timeoutOrThenable);
|
||||
},
|
||||
withWindowProgress: proposedApiFunction(extension, <R>(task: (progress: vscode.Progress<string>, token: vscode.CancellationToken) => Thenable<R>): Thenable<R> => {
|
||||
return extHostProgress.withWindowProgress(extension, task);
|
||||
}),
|
||||
withScmProgress: proposedApiFunction(extension, (task: (progress: vscode.Progress<number>) => Thenable<any>) => {
|
||||
return extHostProgress.withScmProgress(extension, task);
|
||||
}),
|
||||
createOutputChannel(name: string): vscode.OutputChannel {
|
||||
return extHostOutputService.createOutputChannel(name);
|
||||
},
|
||||
createTerminal(name?: string, shellPath?: string, shellArgs?: string[]): vscode.Terminal {
|
||||
return extHostTerminalService.createTerminal(name, shellPath, shellArgs);
|
||||
createTerminal(nameOrOptions: vscode.TerminalOptions | string, shellPath?: string, shellArgs?: string[]): vscode.Terminal {
|
||||
if (typeof nameOrOptions === 'object') {
|
||||
return extHostTerminalService.createTerminalFromOptions(<vscode.TerminalOptions>nameOrOptions);
|
||||
}
|
||||
return extHostTerminalService.createTerminal(<string>nameOrOptions, shellPath, shellArgs);
|
||||
},
|
||||
// proposed API
|
||||
sampleFunction: proposedApiFunction(extension, () => {
|
||||
@@ -358,6 +401,32 @@ export function createApiFactory(initData: IInitData, threadService: IThreadServ
|
||||
}
|
||||
};
|
||||
|
||||
class SCM {
|
||||
|
||||
@proposed(extension)
|
||||
get activeProvider() {
|
||||
return extHostSCM.activeProvider;
|
||||
}
|
||||
|
||||
@proposed(extension)
|
||||
get onDidChangeActiveProvider() {
|
||||
return extHostSCM.onDidChangeActiveProvider;
|
||||
}
|
||||
|
||||
@proposed(extension)
|
||||
getResourceFromURI(uri) {
|
||||
return extHostSCM.getResourceFromURI(uri);
|
||||
}
|
||||
|
||||
@proposed(extension)
|
||||
registerSCMProvider(id, provider) {
|
||||
return extHostSCM.registerSCMProvider(id, provider);
|
||||
}
|
||||
}
|
||||
|
||||
// namespace: scm
|
||||
const scm: typeof vscode.scm = new SCM();
|
||||
|
||||
return {
|
||||
version: pkg.version,
|
||||
// namespaces
|
||||
@@ -367,6 +436,7 @@ export function createApiFactory(initData: IInitData, threadService: IThreadServ
|
||||
languages,
|
||||
window,
|
||||
workspace,
|
||||
scm,
|
||||
// types
|
||||
CancellationTokenSource: CancellationTokenSource,
|
||||
CodeLens: extHostTypes.CodeLens,
|
||||
@@ -466,7 +536,7 @@ function createExtensionPathIndex(extensionService: ExtHostExtensionService): TP
|
||||
function defineAPI(factory: IExtensionApiFactory, extensionPaths: TrieMap<IExtensionDescription>): void {
|
||||
|
||||
// each extension is meant to get its own api implementation
|
||||
const extApiImpl: { [id: string]: typeof vscode } = Object.create(null);
|
||||
const extApiImpl = new Map<string, typeof vscode>();
|
||||
let defaultApiImpl: typeof vscode;
|
||||
|
||||
const node_module = <any>require.__$__nodeRequire('module');
|
||||
@@ -479,9 +549,10 @@ function defineAPI(factory: IExtensionApiFactory, extensionPaths: TrieMap<IExten
|
||||
// get extension id from filename and api for extension
|
||||
const ext = extensionPaths.findSubstr(parent.filename);
|
||||
if (ext) {
|
||||
let apiImpl = extApiImpl[ext.id];
|
||||
let apiImpl = extApiImpl.get(ext.id);
|
||||
if (!apiImpl) {
|
||||
apiImpl = extApiImpl[ext.id] = factory(ext);
|
||||
apiImpl = factory(ext);
|
||||
extApiImpl.set(ext.id, apiImpl);
|
||||
}
|
||||
return apiImpl;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import { MainThreadLanguageFeatures } from './mainThreadLanguageFeatures';
|
||||
import { MainThreadLanguages } from './mainThreadLanguages';
|
||||
import { MainThreadMessageService } from './mainThreadMessageService';
|
||||
import { MainThreadOutputService } from './mainThreadOutputService';
|
||||
import { MainThreadProgress } from './mainThreadProgress';
|
||||
import { MainThreadQuickOpen } from './mainThreadQuickOpen';
|
||||
import { MainThreadStatusBar } from './mainThreadStatusBar';
|
||||
import { MainThreadStorage } from './mainThreadStorage';
|
||||
@@ -32,9 +33,9 @@ import { MainThreadTerminalService } from './mainThreadTerminalService';
|
||||
import { MainThreadWorkspace } from './mainThreadWorkspace';
|
||||
import { MainProcessExtensionService } from './mainThreadExtensionService';
|
||||
import { MainThreadFileSystemEventService } from './mainThreadFileSystemEventService';
|
||||
import { MainThreadSCM } from './mainThreadSCM';
|
||||
|
||||
// --- other interested parties
|
||||
import { MainProcessTextMateSyntax } from 'vs/editor/node/textMate/TMSyntax';
|
||||
import { MainProcessTextMateSnippet } from 'vs/editor/node/textMate/TMSnippets';
|
||||
import { JSONValidationExtensionPoint } from 'vs/platform/jsonschemas/common/jsonValidationExtensionPoint';
|
||||
import { LanguageConfigurationFileHandler } from 'vs/editor/node/languageConfigurationExtensionPoint';
|
||||
@@ -75,22 +76,23 @@ export class ExtHostContribution implements IWorkbenchContribution {
|
||||
col.define(MainContext.MainThreadLanguages).set(create(MainThreadLanguages));
|
||||
col.define(MainContext.MainThreadMessageService).set(create(MainThreadMessageService));
|
||||
col.define(MainContext.MainThreadOutputService).set(create(MainThreadOutputService));
|
||||
col.define(MainContext.MainThreadProgress).set(create(MainThreadProgress));
|
||||
col.define(MainContext.MainThreadQuickOpen).set(create(MainThreadQuickOpen));
|
||||
col.define(MainContext.MainThreadStatusBar).set(create(MainThreadStatusBar));
|
||||
col.define(MainContext.MainThreadStorage).set(create(MainThreadStorage));
|
||||
col.define(MainContext.MainThreadTelemetry).set(create(MainThreadTelemetry));
|
||||
col.define(MainContext.MainThreadTerminalService).set(create(MainThreadTerminalService));
|
||||
col.define(MainContext.MainThreadWorkspace).set(create(MainThreadWorkspace));
|
||||
col.define(MainContext.MainThreadSCM).set(create(MainThreadSCM));
|
||||
if (this.extensionService instanceof MainProcessExtensionService) {
|
||||
col.define(MainContext.MainProcessExtensionService).set(<MainProcessExtensionService>this.extensionService);
|
||||
}
|
||||
col.finish(true, this.threadService);
|
||||
|
||||
// Other interested parties
|
||||
let tmSyntax = create(MainProcessTextMateSyntax);
|
||||
create(MainProcessTextMateSnippet);
|
||||
create(JSONValidationExtensionPoint);
|
||||
this.instantiationService.createInstance(LanguageConfigurationFileHandler, tmSyntax);
|
||||
this.instantiationService.createInstance(LanguageConfigurationFileHandler);
|
||||
create(MainThreadFileSystemEventService);
|
||||
create(SaveParticipant);
|
||||
}
|
||||
@@ -99,4 +101,4 @@ export class ExtHostContribution implements IWorkbenchContribution {
|
||||
// Register File Tracker
|
||||
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(
|
||||
ExtHostContribution
|
||||
);
|
||||
);
|
||||
|
||||
@@ -151,8 +151,10 @@ export abstract class MainThreadErrorsShape {
|
||||
export abstract class MainThreadLanguageFeaturesShape {
|
||||
$unregister(handle: number): TPromise<any> { throw ni(); }
|
||||
$registerOutlineSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||
$registerCodeLensSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||
$registerCodeLensSupport(handle: number, selector: vscode.DocumentSelector, eventHandle: number): TPromise<any> { throw ni(); }
|
||||
$emitCodeLensEvent(eventHandle: number, event?: any): TPromise<any> { throw ni(); }
|
||||
$registerDeclaractionSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||
$registerImplementationSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||
$registerHoverProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||
$registerDocumentHighlightProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||
$registerReferenceSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||
@@ -183,8 +185,14 @@ export abstract class MainThreadOutputServiceShape {
|
||||
$close(channelId: string): TPromise<void> { throw ni(); }
|
||||
}
|
||||
|
||||
export abstract class MainThreadProgressShape {
|
||||
$progressStart(handle: number, extensionId: string, location: string): void { throw ni(); }
|
||||
$progressReport(handle: number, message: string): void { throw ni(); }
|
||||
$progressEnd(handle: number, err?: any): void { throw ni(); }
|
||||
}
|
||||
|
||||
export abstract class MainThreadTerminalServiceShape {
|
||||
$createTerminal(name?: string, shellPath?: string, shellArgs?: string[]): TPromise<number> { throw ni(); }
|
||||
$createTerminal(name?: string, shellPath?: string, shellArgs?: string[], waitOnExit?: boolean): TPromise<number> { throw ni(); }
|
||||
$dispose(terminalId: number): void { throw ni(); }
|
||||
$hide(terminalId: number): void { throw ni(); }
|
||||
$sendText(terminalId: number, text: string, addNewLine: boolean): void { throw ni(); }
|
||||
@@ -229,6 +237,27 @@ export abstract class MainProcessExtensionServiceShape {
|
||||
$onExtensionActivationFailed(extensionId: string): void { throw ni(); }
|
||||
}
|
||||
|
||||
export interface SCMProviderFeatures {
|
||||
label: string;
|
||||
supportsCommit: boolean;
|
||||
supportsOpen: boolean;
|
||||
supportsDrag: boolean;
|
||||
supportsOriginalResource: boolean;
|
||||
}
|
||||
|
||||
export type SCMRawResource = [
|
||||
string /*uri*/,
|
||||
string[] /*icons: light, dark*/,
|
||||
boolean /*strike through*/
|
||||
];
|
||||
export type SCMRawResourceGroup = [string /*id*/, string /*label*/, SCMRawResource[]];
|
||||
|
||||
export abstract class MainThreadSCMShape {
|
||||
$register(id: string, features: SCMProviderFeatures): void { throw ni(); }
|
||||
$unregister(id: string): void { throw ni(); }
|
||||
$onChange(id: string, resources: SCMRawResourceGroup[]): void { throw ni(); }
|
||||
}
|
||||
|
||||
// -- extension host
|
||||
|
||||
export abstract class ExtHostCommandsShape {
|
||||
@@ -329,6 +358,7 @@ export abstract class ExtHostLanguageFeaturesShape {
|
||||
$provideCodeLenses(handle: number, resource: URI): TPromise<modes.ICodeLensSymbol[]> { throw ni(); }
|
||||
$resolveCodeLens(handle: number, resource: URI, symbol: modes.ICodeLensSymbol): TPromise<modes.ICodeLensSymbol> { throw ni(); }
|
||||
$provideDefinition(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.Definition> { throw ni(); }
|
||||
$provideTypeDefinition(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.Definition> { throw ni(); }
|
||||
$provideHover(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.Hover> { throw ni(); }
|
||||
$provideDocumentHighlights(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.DocumentHighlight[]> { throw ni(); }
|
||||
$provideReferences(handle: number, resource: URI, position: editorCommon.IPosition, context: modes.ReferenceContext): TPromise<modes.Location[]> { throw ni(); }
|
||||
@@ -356,6 +386,13 @@ export abstract class ExtHostTerminalServiceShape {
|
||||
$acceptTerminalProcessId(id: number, processId: number): void { throw ni(); }
|
||||
}
|
||||
|
||||
export abstract class ExtHostSCMShape {
|
||||
$commit(id: string, message: string): TPromise<void> { throw ni(); }
|
||||
$open(id: string, resourceGroupId: string, uri: string): TPromise<void> { throw ni(); }
|
||||
$drag(id: string, fromResourceGroupId: string, fromUri: string, toResourceGroupId: string): TPromise<void> { throw ni(); }
|
||||
$getOriginalResource(id: string, uri: URI): TPromise<URI> { throw ni(); }
|
||||
}
|
||||
|
||||
// --- proxy identifiers
|
||||
|
||||
export const MainContext = {
|
||||
@@ -370,6 +407,7 @@ export const MainContext = {
|
||||
MainThreadLanguages: createMainId<MainThreadLanguagesShape>('MainThreadLanguages', MainThreadLanguagesShape),
|
||||
MainThreadMessageService: createMainId<MainThreadMessageServiceShape>('MainThreadMessageService', MainThreadMessageServiceShape),
|
||||
MainThreadOutputService: createMainId<MainThreadOutputServiceShape>('MainThreadOutputService', MainThreadOutputServiceShape),
|
||||
MainThreadProgress: createMainId<MainThreadProgressShape>('MainThreadProgress', MainThreadProgressShape),
|
||||
MainThreadQuickOpen: createMainId<MainThreadQuickOpenShape>('MainThreadQuickOpen', MainThreadQuickOpenShape),
|
||||
MainThreadStatusBar: createMainId<MainThreadStatusBarShape>('MainThreadStatusBar', MainThreadStatusBarShape),
|
||||
MainThreadStorage: createMainId<MainThreadStorageShape>('MainThreadStorage', MainThreadStorageShape),
|
||||
@@ -377,6 +415,7 @@ export const MainContext = {
|
||||
MainThreadTerminalService: createMainId<MainThreadTerminalServiceShape>('MainThreadTerminalService', MainThreadTerminalServiceShape),
|
||||
MainThreadWorkspace: createMainId<MainThreadWorkspaceShape>('MainThreadWorkspace', MainThreadWorkspaceShape),
|
||||
MainProcessExtensionService: createMainId<MainProcessExtensionServiceShape>('MainProcessExtensionService', MainProcessExtensionServiceShape),
|
||||
MainThreadSCM: createMainId<MainThreadSCMShape>('MainThreadSCM', MainThreadSCMShape)
|
||||
};
|
||||
|
||||
export const ExtHostContext = {
|
||||
@@ -392,5 +431,6 @@ export const ExtHostContext = {
|
||||
ExtHostLanguageFeatures: createExtId<ExtHostLanguageFeaturesShape>('ExtHostLanguageFeatures', ExtHostLanguageFeaturesShape),
|
||||
ExtHostQuickOpen: createExtId<ExtHostQuickOpenShape>('ExtHostQuickOpen', ExtHostQuickOpenShape),
|
||||
ExtHostExtensionService: createExtId<ExtHostExtensionServiceShape>('ExtHostExtensionService', ExtHostExtensionServiceShape),
|
||||
ExtHostTerminalService: createExtId<ExtHostTerminalServiceShape>('ExtHostTerminalService', ExtHostTerminalServiceShape)
|
||||
ExtHostTerminalService: createExtId<ExtHostTerminalServiceShape>('ExtHostTerminalService', ExtHostTerminalServiceShape),
|
||||
ExtHostSCM: createExtId<ExtHostSCMShape>('ExtHostSCM', ExtHostSCMShape)
|
||||
};
|
||||
|
||||
@@ -46,6 +46,14 @@ export class ExtHostApiCommands {
|
||||
],
|
||||
returns: 'A promise that resolves to an array of Location-instances.'
|
||||
});
|
||||
this._register('vscode.executeTypeDefinitionProvider', this._executeTypeDefinitionProvider, {
|
||||
description: 'Execute all implementation providers.',
|
||||
args: [
|
||||
{ name: 'uri', description: 'Uri of a text document', constraint: URI },
|
||||
{ name: 'position', description: 'Position of a symbol', constraint: types.Position }
|
||||
],
|
||||
returns: 'A promise that resolves to an array of Location-instance.'
|
||||
});
|
||||
this._register('vscode.executeHoverProvider', this._executeHoverProvider, {
|
||||
description: 'Execute all hover provider.',
|
||||
args: [
|
||||
@@ -265,6 +273,18 @@ export class ExtHostApiCommands {
|
||||
});
|
||||
}
|
||||
|
||||
private _executeTypeDefinitionProvider(resource: URI, position: types.Position): Thenable<types.Location[]> {
|
||||
const args = {
|
||||
resource,
|
||||
position: position && typeConverters.fromPosition(position)
|
||||
};
|
||||
return this._commands.executeCommand<modes.Location[]>('_executeTypeDefinitionProvider', args).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(typeConverters.location.to);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _executeHoverProvider(resource: URI, position: types.Position): Thenable<types.Hover[]> {
|
||||
const args = {
|
||||
resource,
|
||||
|
||||
@@ -26,7 +26,7 @@ interface CommandHandler {
|
||||
|
||||
export class ExtHostCommands extends ExtHostCommandsShape {
|
||||
|
||||
private _commands: { [n: string]: CommandHandler } = Object.create(null);
|
||||
private _commands = new Map<string, CommandHandler>();
|
||||
private _proxy: MainThreadCommandsShape;
|
||||
private _extHostEditors: ExtHostEditors;
|
||||
private _converter: CommandsConverter;
|
||||
@@ -52,15 +52,15 @@ export class ExtHostCommands extends ExtHostCommandsShape {
|
||||
throw new Error('invalid id');
|
||||
}
|
||||
|
||||
if (this._commands[id]) {
|
||||
if (this._commands.has(id)) {
|
||||
throw new Error('command with id already exists');
|
||||
}
|
||||
|
||||
this._commands[id] = { callback, thisArg, description };
|
||||
this._commands.set(id, { callback, thisArg, description });
|
||||
this._proxy.$registerCommand(id);
|
||||
|
||||
return new extHostTypes.Disposable(() => {
|
||||
if (delete this._commands[id]) {
|
||||
if (this._commands.delete(id)) {
|
||||
this._proxy.$unregisterCommand(id);
|
||||
}
|
||||
});
|
||||
@@ -68,7 +68,7 @@ export class ExtHostCommands extends ExtHostCommandsShape {
|
||||
|
||||
executeCommand<T>(id: string, ...args: any[]): Thenable<T> {
|
||||
|
||||
if (this._commands[id]) {
|
||||
if (this._commands.has(id)) {
|
||||
// we stay inside the extension host and support
|
||||
// to pass any kind of parameters around
|
||||
return this.$executeContributedCommand(id, ...args);
|
||||
@@ -97,7 +97,7 @@ export class ExtHostCommands extends ExtHostCommandsShape {
|
||||
}
|
||||
|
||||
$executeContributedCommand<T>(id: string, ...args: any[]): Thenable<T> {
|
||||
let command = this._commands[id];
|
||||
let command = this._commands.get(id);
|
||||
if (!command) {
|
||||
return TPromise.wrapError<T>(`Contributed command '${id}' does not exist.`);
|
||||
}
|
||||
@@ -139,12 +139,12 @@ export class ExtHostCommands extends ExtHostCommandsShape {
|
||||
|
||||
$getContributedCommandHandlerDescriptions(): TPromise<{ [id: string]: string | ICommandHandlerDescription }> {
|
||||
const result: { [id: string]: string | ICommandHandlerDescription } = Object.create(null);
|
||||
for (let id in this._commands) {
|
||||
let {description} = this._commands[id];
|
||||
this._commands.forEach((command, id) => {
|
||||
let {description} = command;
|
||||
if (description) {
|
||||
result[id] = description;
|
||||
}
|
||||
}
|
||||
});
|
||||
return TPromise.as(result);
|
||||
}
|
||||
}
|
||||
@@ -212,4 +212,4 @@ export class CommandsConverter {
|
||||
return this._commands.executeCommand(actualCmd.command, ...actualCmd.arguments);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,13 @@ import { DiagnosticSeverity } from './extHostTypes';
|
||||
|
||||
export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
|
||||
private static _maxDiagnosticsPerFile: number = 250;
|
||||
private static readonly _maxDiagnosticsPerFile: number = 250;
|
||||
|
||||
private readonly _name: string;
|
||||
|
||||
private _name: string;
|
||||
private _proxy: MainThreadDiagnosticsShape;
|
||||
|
||||
private _isDisposed = false;
|
||||
private _data: { [uri: string]: vscode.Diagnostic[] } = Object.create(null);
|
||||
private _data = new Map<string, vscode.Diagnostic[]>();
|
||||
|
||||
constructor(name: string, proxy: MainThreadDiagnosticsShape) {
|
||||
this._name = name;
|
||||
@@ -66,7 +66,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
}
|
||||
|
||||
// update single row
|
||||
this._data[first.toString()] = diagnostics;
|
||||
this._data.set(first.toString(), diagnostics);
|
||||
toSync = [first];
|
||||
|
||||
} else if (Array.isArray(first)) {
|
||||
@@ -83,19 +83,19 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
for (const {tuple} of sortedTuples) {
|
||||
const [uri, diagnostics] = tuple;
|
||||
if (!lastUri || uri.toString() !== lastUri.toString()) {
|
||||
if (lastUri && this._data[lastUri.toString()].length === 0) {
|
||||
delete this._data[lastUri.toString()];
|
||||
if (lastUri && this._data.get(lastUri.toString()).length === 0) {
|
||||
this._data.delete(lastUri.toString());
|
||||
}
|
||||
lastUri = uri;
|
||||
toSync.push(uri);
|
||||
this._data[uri.toString()] = [];
|
||||
this._data.set(uri.toString(), []);
|
||||
}
|
||||
|
||||
if (!diagnostics) {
|
||||
// [Uri, undefined] means clear this
|
||||
this._data[uri.toString()].length = 0;
|
||||
this._data.get(uri.toString()).length = 0;
|
||||
} else {
|
||||
this._data[uri.toString()].push(...diagnostics);
|
||||
this._data.get(uri.toString()).push(...diagnostics);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
const entries: [URI, IMarkerData[]][] = [];
|
||||
for (let uri of toSync) {
|
||||
let marker: IMarkerData[];
|
||||
let diagnostics = this._data[uri.toString()];
|
||||
let diagnostics = this._data.get(uri.toString());
|
||||
if (diagnostics) {
|
||||
|
||||
// no more than 250 diagnostics per file
|
||||
@@ -144,27 +144,27 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
|
||||
delete(uri: vscode.Uri): void {
|
||||
this._checkDisposed();
|
||||
delete this._data[uri.toString()];
|
||||
this._data.delete(uri.toString());
|
||||
this._proxy.$changeMany(this.name, [[<URI>uri, undefined]]);
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this._checkDisposed();
|
||||
this._data = Object.create(null);
|
||||
this._data.clear();
|
||||
this._proxy.$clear(this.name);
|
||||
}
|
||||
|
||||
forEach(callback: (uri: URI, diagnostics: vscode.Diagnostic[], collection: DiagnosticCollection) => any, thisArg?: any): void {
|
||||
this._checkDisposed();
|
||||
for (let key in this._data) {
|
||||
this._data.forEach((value, key) => {
|
||||
let uri = URI.parse(key);
|
||||
callback.apply(thisArg, [uri, this.get(uri), this]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get(uri: URI): vscode.Diagnostic[] {
|
||||
this._checkDisposed();
|
||||
let result = this._data[uri.toString()];
|
||||
let result = this._data.get(uri.toString());
|
||||
if (Array.isArray(result)) {
|
||||
return <vscode.Diagnostic[]>Object.freeze(result.slice(0));
|
||||
}
|
||||
@@ -172,7 +172,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
|
||||
has(uri: URI): boolean {
|
||||
this._checkDisposed();
|
||||
return Array.isArray(this._data[uri.toString()]);
|
||||
return Array.isArray(this._data.get(uri.toString()));
|
||||
}
|
||||
|
||||
private _checkDisposed() {
|
||||
|
||||
@@ -18,13 +18,6 @@ import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
|
||||
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
declare class WeakMap<K, V> {
|
||||
// delete(key: K): boolean;
|
||||
get(key: K): V;
|
||||
// has(key: K): boolean;
|
||||
set(key: K, value?: V): WeakMap<K, V>;
|
||||
}
|
||||
|
||||
export class ExtHostDocumentSaveParticipant extends ExtHostDocumentSaveParticipantShape {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
@@ -168,4 +161,4 @@ export class ExtHostDocumentSaveParticipant extends ExtHostDocumentSaveParticipa
|
||||
return TPromise.wrapError(new Error('concurrent_edits'));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,16 +20,14 @@ import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import { getWordAtText, ensureValidWordDefinition } from 'vs/editor/common/model/wordHelper';
|
||||
import { MainContext, MainThreadDocumentsShape, ExtHostDocumentsShape, IModelAddedData } from './extHost.protocol';
|
||||
|
||||
const _modeId2WordDefinition: {
|
||||
[modeId: string]: RegExp;
|
||||
} = Object.create(null);
|
||||
const _modeId2WordDefinition = new Map<string, RegExp>();
|
||||
|
||||
function setWordDefinitionFor(modeId: string, wordDefinition: RegExp): void {
|
||||
_modeId2WordDefinition[modeId] = wordDefinition;
|
||||
_modeId2WordDefinition.set(modeId, wordDefinition);
|
||||
}
|
||||
|
||||
function getWordDefinitionFor(modeId: string): RegExp {
|
||||
return _modeId2WordDefinition[modeId];
|
||||
return _modeId2WordDefinition.get(modeId);
|
||||
}
|
||||
|
||||
export class ExtHostDocuments extends ExtHostDocumentsShape {
|
||||
@@ -48,9 +46,9 @@ export class ExtHostDocuments extends ExtHostDocumentsShape {
|
||||
private _onDidSaveDocumentEventEmitter: Emitter<vscode.TextDocument>;
|
||||
public onDidSaveDocument: Event<vscode.TextDocument>;
|
||||
|
||||
private _documentData: { [modelUri: string]: ExtHostDocumentData; };
|
||||
private _documentLoader: { [modelUri: string]: TPromise<ExtHostDocumentData> };
|
||||
private _documentContentProviders: { [handle: number]: vscode.TextDocumentContentProvider; };
|
||||
private _documentData = new Map<string, ExtHostDocumentData>();
|
||||
private _documentLoader = new Map<string, TPromise<ExtHostDocumentData>>();
|
||||
private _documentContentProviders = new Map<number, vscode.TextDocumentContentProvider>();
|
||||
|
||||
private _proxy: MainThreadDocumentsShape;
|
||||
|
||||
@@ -69,17 +67,11 @@ export class ExtHostDocuments extends ExtHostDocumentsShape {
|
||||
|
||||
this._onDidSaveDocumentEventEmitter = new Emitter<vscode.TextDocument>();
|
||||
this.onDidSaveDocument = this._onDidSaveDocumentEventEmitter.event;
|
||||
|
||||
this._documentData = Object.create(null);
|
||||
this._documentLoader = Object.create(null);
|
||||
this._documentContentProviders = Object.create(null);
|
||||
}
|
||||
|
||||
public getAllDocumentData(): ExtHostDocumentData[] {
|
||||
const result: ExtHostDocumentData[] = [];
|
||||
for (let key in this._documentData) {
|
||||
result.push(this._documentData[key]);
|
||||
}
|
||||
this._documentData.forEach(data => result.push(data));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -87,7 +79,7 @@ export class ExtHostDocuments extends ExtHostDocumentsShape {
|
||||
if (!resource) {
|
||||
return;
|
||||
}
|
||||
const data = this._documentData[resource.toString()];
|
||||
const data = this._documentData.get(resource.toString());
|
||||
if (data) {
|
||||
return data;
|
||||
}
|
||||
@@ -95,21 +87,21 @@ export class ExtHostDocuments extends ExtHostDocumentsShape {
|
||||
|
||||
public ensureDocumentData(uri: URI): TPromise<ExtHostDocumentData> {
|
||||
|
||||
let cached = this._documentData[uri.toString()];
|
||||
let cached = this._documentData.get(uri.toString());
|
||||
if (cached) {
|
||||
return TPromise.as(cached);
|
||||
}
|
||||
|
||||
let promise = this._documentLoader[uri.toString()];
|
||||
let promise = this._documentLoader.get(uri.toString());
|
||||
if (!promise) {
|
||||
promise = this._proxy.$tryOpenDocument(uri).then(() => {
|
||||
delete this._documentLoader[uri.toString()];
|
||||
return this._documentData[uri.toString()];
|
||||
this._documentLoader.delete(uri.toString());
|
||||
return this._documentData.get(uri.toString());
|
||||
}, err => {
|
||||
delete this._documentLoader[uri.toString()];
|
||||
this._documentLoader.delete(uri.toString());
|
||||
return TPromise.wrapError(err);
|
||||
});
|
||||
this._documentLoader[uri.toString()] = promise;
|
||||
this._documentLoader.set(uri.toString(), promise);
|
||||
}
|
||||
|
||||
return promise;
|
||||
@@ -122,13 +114,13 @@ export class ExtHostDocuments extends ExtHostDocumentsShape {
|
||||
|
||||
const handle = ExtHostDocuments._handlePool++;
|
||||
|
||||
this._documentContentProviders[handle] = provider;
|
||||
this._documentContentProviders.set(handle, provider);
|
||||
this._proxy.$registerTextContentProvider(handle, scheme);
|
||||
|
||||
let subscription: IDisposable;
|
||||
if (typeof provider.onDidChange === 'function') {
|
||||
subscription = provider.onDidChange(uri => {
|
||||
if (this._documentData[uri.toString()]) {
|
||||
if (this._documentData.has(uri.toString())) {
|
||||
this.$provideTextDocumentContent(handle, <URI>uri).then(value => {
|
||||
return this._proxy.$onVirtualDocumentChange(<URI>uri, value);
|
||||
}, onUnexpectedError);
|
||||
@@ -136,7 +128,7 @@ export class ExtHostDocuments extends ExtHostDocumentsShape {
|
||||
});
|
||||
}
|
||||
return new Disposable(() => {
|
||||
if (delete this._documentContentProviders[handle]) {
|
||||
if (this._documentContentProviders.delete(handle)) {
|
||||
this._proxy.$unregisterTextContentProvider(handle);
|
||||
}
|
||||
if (subscription) {
|
||||
@@ -147,7 +139,7 @@ export class ExtHostDocuments extends ExtHostDocumentsShape {
|
||||
}
|
||||
|
||||
$provideTextDocumentContent(handle: number, uri: URI): TPromise<string> {
|
||||
const provider = this._documentContentProviders[handle];
|
||||
const provider = this._documentContentProviders.get(handle);
|
||||
if (!provider) {
|
||||
return TPromise.wrapError<string>(`unsupported uri-scheme: ${uri.scheme}`);
|
||||
}
|
||||
@@ -157,15 +149,15 @@ export class ExtHostDocuments extends ExtHostDocumentsShape {
|
||||
public $acceptModelAdd(initData: IModelAddedData): void {
|
||||
let data = new ExtHostDocumentData(this._proxy, initData.url, initData.value.lines, initData.value.EOL, initData.modeId, initData.versionId, initData.isDirty);
|
||||
let key = data.document.uri.toString();
|
||||
if (this._documentData[key]) {
|
||||
if (this._documentData.has(key)) {
|
||||
throw new Error('Document `' + key + '` already exists.');
|
||||
}
|
||||
this._documentData[key] = data;
|
||||
this._documentData.set(key, data);
|
||||
this._onDidAddDocumentEventEmitter.fire(data.document);
|
||||
}
|
||||
|
||||
public $acceptModelModeChanged(strURL: string, oldModeId: string, newModeId: string): void {
|
||||
let data = this._documentData[strURL];
|
||||
let data = this._documentData.get(strURL);
|
||||
|
||||
// Treat a mode change as a remove + add
|
||||
|
||||
@@ -175,33 +167,33 @@ export class ExtHostDocuments extends ExtHostDocumentsShape {
|
||||
}
|
||||
|
||||
public $acceptModelSaved(strURL: string): void {
|
||||
let data = this._documentData[strURL];
|
||||
let data = this._documentData.get(strURL);
|
||||
data._acceptIsDirty(false);
|
||||
this._onDidSaveDocumentEventEmitter.fire(data.document);
|
||||
}
|
||||
|
||||
public $acceptModelDirty(strURL: string): void {
|
||||
let document = this._documentData[strURL];
|
||||
let document = this._documentData.get(strURL);
|
||||
document._acceptIsDirty(true);
|
||||
}
|
||||
|
||||
public $acceptModelReverted(strURL: string): void {
|
||||
let document = this._documentData[strURL];
|
||||
let document = this._documentData.get(strURL);
|
||||
document._acceptIsDirty(false);
|
||||
}
|
||||
|
||||
public $acceptModelRemoved(strURL: string): void {
|
||||
if (!this._documentData[strURL]) {
|
||||
if (!this._documentData.has(strURL)) {
|
||||
throw new Error('Document `' + strURL + '` does not exist.');
|
||||
}
|
||||
let data = this._documentData[strURL];
|
||||
delete this._documentData[strURL];
|
||||
let data = this._documentData.get(strURL);
|
||||
this._documentData.delete(strURL);
|
||||
this._onDidRemoveDocumentEventEmitter.fire(data.document);
|
||||
data.dispose();
|
||||
}
|
||||
|
||||
public $acceptModelChanged(strURL: string, events: editorCommon.IModelContentChangedEvent2[], isDirty: boolean): void {
|
||||
let data = this._documentData[strURL];
|
||||
let data = this._documentData.get(strURL);
|
||||
data._acceptIsDirty(isDirty);
|
||||
data.onEvents(events);
|
||||
this._onDidChangeDocumentEventEmitter.fire({
|
||||
|
||||
@@ -30,7 +30,7 @@ export class ExtHostEditors extends ExtHostEditorsShape {
|
||||
public onDidChangeTextEditorViewColumn: Event<vscode.TextEditorViewColumnChangeEvent>;
|
||||
private _onDidChangeTextEditorViewColumn: Emitter<vscode.TextEditorViewColumnChangeEvent>;
|
||||
|
||||
private _editors: { [id: string]: ExtHostTextEditor };
|
||||
private _editors: Map<string, ExtHostTextEditor>;
|
||||
private _proxy: MainThreadEditorsShape;
|
||||
private _onDidChangeActiveTextEditor: Emitter<vscode.TextEditor>;
|
||||
private _onDidChangeVisibleTextEditors: Emitter<vscode.TextEditor[]>;
|
||||
@@ -56,17 +56,17 @@ export class ExtHostEditors extends ExtHostEditorsShape {
|
||||
this._proxy = threadService.get(MainContext.MainThreadEditors);
|
||||
this._onDidChangeActiveTextEditor = new Emitter<vscode.TextEditor>();
|
||||
this._onDidChangeVisibleTextEditors = new Emitter<vscode.TextEditor[]>();
|
||||
this._editors = Object.create(null);
|
||||
this._editors = new Map<string, ExtHostTextEditor>();
|
||||
|
||||
this._visibleEditorIds = [];
|
||||
}
|
||||
|
||||
getActiveTextEditor(): vscode.TextEditor {
|
||||
return this._editors[this._activeEditorId];
|
||||
return this._editors.get(this._activeEditorId);
|
||||
}
|
||||
|
||||
getVisibleTextEditors(): vscode.TextEditor[] {
|
||||
return this._visibleEditorIds.map(id => this._editors[id]);
|
||||
return this._visibleEditorIds.map(id => this._editors.get(id));
|
||||
}
|
||||
|
||||
get onDidChangeActiveTextEditor(): Event<vscode.TextEditor> {
|
||||
@@ -79,7 +79,7 @@ export class ExtHostEditors extends ExtHostEditorsShape {
|
||||
|
||||
showTextDocument(document: vscode.TextDocument, column: vscode.ViewColumn, preserveFocus: boolean): TPromise<vscode.TextEditor> {
|
||||
return this._proxy.$tryShowTextDocument(<URI>document.uri, TypeConverters.fromViewColumn(column), preserveFocus).then(id => {
|
||||
let editor = this._editors[id];
|
||||
let editor = this._editors.get(id);
|
||||
if (editor) {
|
||||
return editor;
|
||||
} else {
|
||||
@@ -97,11 +97,11 @@ export class ExtHostEditors extends ExtHostEditorsShape {
|
||||
$acceptTextEditorAdd(data: ITextEditorAddData): void {
|
||||
let document = this._extHostDocuments.getDocumentData(data.document);
|
||||
let newEditor = new ExtHostTextEditor(this._proxy, data.id, document, data.selections.map(TypeConverters.toSelection), data.options, TypeConverters.toViewColumn(data.editorPosition));
|
||||
this._editors[data.id] = newEditor;
|
||||
this._editors.set(data.id, newEditor);
|
||||
}
|
||||
|
||||
$acceptOptionsChanged(id: string, opts: IResolvedTextEditorConfiguration): void {
|
||||
let editor = this._editors[id];
|
||||
let editor = this._editors.get(id);
|
||||
editor._acceptOptions(opts);
|
||||
this._onDidChangeTextEditorOptions.fire({
|
||||
textEditor: editor,
|
||||
@@ -112,7 +112,7 @@ export class ExtHostEditors extends ExtHostEditorsShape {
|
||||
$acceptSelectionsChanged(id: string, event: ISelectionChangeEvent): void {
|
||||
const kind = TextEditorSelectionChangeKind.fromValue(event.source);
|
||||
const selections = event.selections.map(TypeConverters.toSelection);
|
||||
const textEditor = this._editors[id];
|
||||
const textEditor = this._editors.get(id);
|
||||
textEditor._acceptSelections(selections);
|
||||
this._onDidChangeTextEditorSelection.fire({
|
||||
textEditor,
|
||||
@@ -145,7 +145,7 @@ export class ExtHostEditors extends ExtHostEditorsShape {
|
||||
|
||||
$acceptEditorPositionData(data: ITextEditorPositionData): void {
|
||||
for (let id in data) {
|
||||
let textEditor = this._editors[id];
|
||||
let textEditor = this._editors.get(id);
|
||||
let viewColumn = TypeConverters.toViewColumn(data[id]);
|
||||
if (textEditor.viewColumn !== viewColumn) {
|
||||
textEditor._acceptViewColumn(viewColumn);
|
||||
@@ -165,9 +165,9 @@ export class ExtHostEditors extends ExtHostEditorsShape {
|
||||
this.$acceptActiveEditorAndVisibleEditors(this._activeEditorId, newVisibleEditors);
|
||||
}
|
||||
|
||||
let editor = this._editors[id];
|
||||
let editor = this._editors.get(id);
|
||||
editor.dispose();
|
||||
delete this._editors[id];
|
||||
this._editors.delete(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -303,6 +303,14 @@ export class ExtHostExtensionService extends AbstractExtensionService<ExtHostExt
|
||||
this._loadExtensionContext(extensionDescription)
|
||||
]).then(values => {
|
||||
return ExtHostExtensionService._callActivate(<IExtensionModule>values[0], <IExtensionContext>values[1]);
|
||||
}, (errors: any[]) => {
|
||||
// Avoid failing with an array of errors, fail with a single error
|
||||
if (errors[0]) {
|
||||
return TPromise.wrapError(errors[0]);
|
||||
}
|
||||
if (errors[1]) {
|
||||
return TPromise.wrapError(errors[1]);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { match } from 'vs/base/common/glob';
|
||||
import { Uri, FileSystemWatcher as _FileSystemWatcher } from 'vscode';
|
||||
import { FileSystemEvents, ExtHostFileSystemEventServiceShape } from './extHost.protocol';
|
||||
|
||||
export class FileSystemWatcher implements _FileSystemWatcher {
|
||||
class FileSystemWatcher implements _FileSystemWatcher {
|
||||
|
||||
private _onDidCreate = new Emitter<Uri>();
|
||||
private _onDidChange = new Emitter<Uri>();
|
||||
|
||||
@@ -10,20 +10,20 @@ export class ExtHostHeapService extends ExtHostHeapServiceShape {
|
||||
|
||||
private static _idPool = 0;
|
||||
|
||||
private _data: { [n: number]: any } = Object.create(null);
|
||||
private _data = new Map<number, any>();
|
||||
|
||||
keep(obj: any): number {
|
||||
const id = ExtHostHeapService._idPool++;
|
||||
this._data[id] = obj;
|
||||
this._data.set(id, obj);
|
||||
return id;
|
||||
}
|
||||
|
||||
delete(id: number): boolean {
|
||||
return this._data[id];
|
||||
return this._data.delete(id);
|
||||
}
|
||||
|
||||
get<T>(id: number): T {
|
||||
return this._data[id];
|
||||
return this._data.get(id);
|
||||
}
|
||||
|
||||
$onGarbageCollection(ids: number[]): void {
|
||||
@@ -31,4 +31,4 @@ export class ExtHostHeapService extends ExtHostHeapServiceShape {
|
||||
this.delete(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,29 @@ class DefinitionAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
class ImplementationAdapter {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _provider: vscode.TypeDefinitionProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, provider: vscode.TypeDefinitionProvider) {
|
||||
this._documents = documents;
|
||||
this._provider = provider;
|
||||
}
|
||||
|
||||
provideTypeDefinition(resource: URI, position: IPosition): TPromise<modes.Definition> {
|
||||
let doc = this._documents.getDocumentData(resource).document;
|
||||
let pos = TypeConverters.toPosition(position);
|
||||
return asWinJsPromise(token => this._provider.provideTypeDefinition(doc, pos, token)).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(TypeConverters.location.from);
|
||||
} else if (value) {
|
||||
return TypeConverters.location.from(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class HoverAdapter {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
@@ -514,7 +537,8 @@ class SuggestAdapter {
|
||||
//
|
||||
insertText: undefined,
|
||||
additionalTextEdits: item.additionalTextEdits && item.additionalTextEdits.map(TypeConverters.TextEdit.from),
|
||||
command: this._commands.toInternal(item.command)
|
||||
command: this._commands.toInternal(item.command),
|
||||
commitCharacters: item.commitCharacters
|
||||
};
|
||||
|
||||
// 'insertText'-logic
|
||||
@@ -613,7 +637,7 @@ class LinkProviderAdapter {
|
||||
type Adapter = OutlineAdapter | CodeLensAdapter | DefinitionAdapter | HoverAdapter
|
||||
| DocumentHighlightAdapter | ReferenceAdapter | QuickFixAdapter | DocumentFormattingAdapter
|
||||
| RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter
|
||||
| SuggestAdapter | SignatureHelpAdapter | LinkProviderAdapter;
|
||||
| SuggestAdapter | SignatureHelpAdapter | LinkProviderAdapter | ImplementationAdapter;
|
||||
|
||||
export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
@@ -624,7 +648,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
private _commands: ExtHostCommands;
|
||||
private _heapService: ExtHostHeapService;
|
||||
private _diagnostics: ExtHostDiagnostics;
|
||||
private _adapter: { [handle: number]: Adapter } = Object.create(null);
|
||||
private _adapter = new Map<number, Adapter>();
|
||||
|
||||
constructor(
|
||||
threadService: IThreadService,
|
||||
@@ -643,7 +667,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
private _createDisposable(handle: number): Disposable {
|
||||
return new Disposable(() => {
|
||||
delete this._adapter[handle];
|
||||
this._adapter.delete(handle);
|
||||
this._proxy.$unregister(handle);
|
||||
});
|
||||
}
|
||||
@@ -653,7 +677,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
}
|
||||
|
||||
private _withAdapter<A, R>(handle: number, ctor: { new (...args: any[]): A }, callback: (adapter: A) => TPromise<R>): TPromise<R> {
|
||||
let adapter = this._adapter[handle];
|
||||
let adapter = this._adapter.get(handle);
|
||||
if (!(adapter instanceof ctor)) {
|
||||
return TPromise.wrapError(new Error('no adapter found'));
|
||||
}
|
||||
@@ -664,7 +688,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerDocumentSymbolProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentSymbolProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new OutlineAdapter(this._documents, provider);
|
||||
this._adapter.set(handle, new OutlineAdapter(this._documents, provider));
|
||||
this._proxy.$registerOutlineSupport(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -677,9 +701,18 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerCodeLensProvider(selector: vscode.DocumentSelector, provider: vscode.CodeLensProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new CodeLensAdapter(this._documents, this._commands.converter, this._heapService, provider);
|
||||
this._proxy.$registerCodeLensSupport(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
const eventHandle = typeof provider.onDidChangeCodeLenses === 'function' ? this._nextHandle() : undefined;
|
||||
|
||||
this._adapter.set(handle, new CodeLensAdapter(this._documents, this._commands.converter, this._heapService, provider));
|
||||
this._proxy.$registerCodeLensSupport(handle, selector, eventHandle);
|
||||
let result = this._createDisposable(handle);
|
||||
|
||||
if (eventHandle !== undefined) {
|
||||
const subscription = provider.onDidChangeCodeLenses(_ => this._proxy.$emitCodeLensEvent(eventHandle));
|
||||
result = Disposable.from(result, subscription);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
$provideCodeLenses(handle: number, resource: URI): TPromise<modes.ICodeLensSymbol[]> {
|
||||
@@ -694,7 +727,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.DefinitionProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new DefinitionAdapter(this._documents, provider);
|
||||
this._adapter.set(handle, new DefinitionAdapter(this._documents, provider));
|
||||
this._proxy.$registerDeclaractionSupport(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -703,11 +736,22 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
return this._withAdapter(handle, DefinitionAdapter, adapter => adapter.provideDefinition(resource, position));
|
||||
}
|
||||
|
||||
registerTypeDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.TypeDefinitionProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter.set(handle, new ImplementationAdapter(this._documents, provider));
|
||||
this._proxy.$registerImplementationSupport(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideTypeDefinition(handle: number, resource: URI, position: IPosition): TPromise<modes.Definition> {
|
||||
return this._withAdapter(handle, ImplementationAdapter, adapter => adapter.provideTypeDefinition(resource, position));
|
||||
}
|
||||
|
||||
// --- extra info
|
||||
|
||||
registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new HoverAdapter(this._documents, provider);
|
||||
this._adapter.set(handle, new HoverAdapter(this._documents, provider));
|
||||
this._proxy.$registerHoverProvider(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -720,7 +764,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new DocumentHighlightAdapter(this._documents, provider);
|
||||
this._adapter.set(handle, new DocumentHighlightAdapter(this._documents, provider));
|
||||
this._proxy.$registerDocumentHighlightProvider(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -733,7 +777,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerReferenceProvider(selector: vscode.DocumentSelector, provider: vscode.ReferenceProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new ReferenceAdapter(this._documents, provider);
|
||||
this._adapter.set(handle, new ReferenceAdapter(this._documents, provider));
|
||||
this._proxy.$registerReferenceSupport(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -746,7 +790,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerCodeActionProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new QuickFixAdapter(this._documents, this._commands.converter, this._diagnostics, this._heapService, provider);
|
||||
this._adapter.set(handle, new QuickFixAdapter(this._documents, this._commands.converter, this._diagnostics, this._heapService, provider));
|
||||
this._proxy.$registerQuickFixSupport(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -759,7 +803,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerDocumentFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentFormattingEditProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new DocumentFormattingAdapter(this._documents, provider);
|
||||
this._adapter.set(handle, new DocumentFormattingAdapter(this._documents, provider));
|
||||
this._proxy.$registerDocumentFormattingSupport(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -770,7 +814,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerDocumentRangeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentRangeFormattingEditProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new RangeFormattingAdapter(this._documents, provider);
|
||||
this._adapter.set(handle, new RangeFormattingAdapter(this._documents, provider));
|
||||
this._proxy.$registerRangeFormattingSupport(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -781,7 +825,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerOnTypeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.OnTypeFormattingEditProvider, triggerCharacters: string[]): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new OnTypeFormattingAdapter(this._documents, provider);
|
||||
this._adapter.set(handle, new OnTypeFormattingAdapter(this._documents, provider));
|
||||
this._proxy.$registerOnTypeFormattingSupport(handle, selector, triggerCharacters);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -794,7 +838,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerWorkspaceSymbolProvider(provider: vscode.WorkspaceSymbolProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new NavigateTypeAdapter(provider, this._heapService);
|
||||
this._adapter.set(handle, new NavigateTypeAdapter(provider, this._heapService));
|
||||
this._proxy.$registerNavigateTypeSupport(handle);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -811,7 +855,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerRenameProvider(selector: vscode.DocumentSelector, provider: vscode.RenameProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new RenameAdapter(this._documents, provider);
|
||||
this._adapter.set(handle, new RenameAdapter(this._documents, provider));
|
||||
this._proxy.$registerRenameSupport(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -824,7 +868,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, triggerCharacters: string[]): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new SuggestAdapter(this._documents, this._commands.converter, this._heapService, provider);
|
||||
this._adapter.set(handle, new SuggestAdapter(this._documents, this._commands.converter, this._heapService, provider));
|
||||
this._proxy.$registerSuggestSupport(handle, selector, triggerCharacters);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -841,7 +885,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerSignatureHelpProvider(selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, triggerCharacters: string[]): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new SignatureHelpAdapter(this._documents, provider);
|
||||
this._adapter.set(handle, new SignatureHelpAdapter(this._documents, provider));
|
||||
this._proxy.$registerSignatureHelpProvider(handle, selector, triggerCharacters);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
@@ -854,7 +898,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerDocumentLinkProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentLinkProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new LinkProviderAdapter(this._documents, provider);
|
||||
this._adapter.set(handle, new LinkProviderAdapter(this._documents, provider));
|
||||
this._proxy.$registerDocumentLinkProvider(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
55
src/vs/workbench/api/node/extHostProgress.ts
Normal file
55
src/vs/workbench/api/node/extHostProgress.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { Progress, CancellationToken } from 'vscode';
|
||||
import { MainThreadProgressShape } from './extHost.protocol';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
export class ExtHostProgress {
|
||||
|
||||
private _proxy: MainThreadProgressShape;
|
||||
private _handles: number = 0;
|
||||
|
||||
constructor(proxy: MainThreadProgressShape) {
|
||||
this._proxy = proxy;
|
||||
}
|
||||
|
||||
withWindowProgress<R>(extension: IExtensionDescription, task: (progress: Progress<string>, token: CancellationToken) => Thenable<R>): Thenable<R> {
|
||||
return this._withProgress(extension, 'window', task);
|
||||
}
|
||||
|
||||
withScmProgress<R>(extension: IExtensionDescription, task: (progress: Progress<number>) => Thenable<R>): Thenable<R> {
|
||||
return this._withProgress(extension, 'scm', task);
|
||||
}
|
||||
|
||||
private _withProgress<R>(extension: IExtensionDescription, type: string, task: (progress: Progress<any>, token: CancellationToken) => Thenable<R>): Thenable<R> {
|
||||
const handle = this._handles++;
|
||||
|
||||
this._proxy.$progressStart(handle, extension.id, type);
|
||||
const progress = {
|
||||
report: (message: string) => {
|
||||
this._proxy.$progressReport(handle, message);
|
||||
}
|
||||
};
|
||||
|
||||
let p: Thenable<R>;
|
||||
|
||||
try {
|
||||
p = task(progress, null);
|
||||
} catch (err) {
|
||||
this._proxy.$progressEnd(handle);
|
||||
throw err;
|
||||
}
|
||||
|
||||
return p.then(result => {
|
||||
this._proxy.$progressEnd(handle);
|
||||
return result;
|
||||
}, err => {
|
||||
this._proxy.$progressEnd(handle, err);
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
}
|
||||
222
src/vs/workbench/api/node/extHostSCM.ts
Normal file
222
src/vs/workbench/api/node/extHostSCM.ts
Normal file
@@ -0,0 +1,222 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import Event, { Emitter, debounceEvent } from 'vs/base/common/event';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
|
||||
import { Disposable } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { MainContext, MainThreadSCMShape, SCMRawResource, SCMRawResourceGroup } from './extHost.protocol';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
function getIconPath(decorations: vscode.SCMResourceThemableDecorations) {
|
||||
if (!decorations) {
|
||||
return undefined;
|
||||
} else if (typeof decorations.iconPath === 'string') {
|
||||
return URI.file(decorations.iconPath).toString();
|
||||
} else if (decorations.iconPath) {
|
||||
return `${decorations.iconPath}`;
|
||||
}
|
||||
}
|
||||
|
||||
export interface Cache {
|
||||
[providerId: string]: {
|
||||
[groupId: string]: {
|
||||
resourceGroup: vscode.SCMResourceGroup,
|
||||
resources: { [uri: string]: vscode.SCMResource }
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export class ExtHostSCM {
|
||||
|
||||
private _proxy: MainThreadSCMShape;
|
||||
private _providers: { [id: string]: vscode.SCMProvider; } = Object.create(null);
|
||||
|
||||
private _onDidChangeActiveProvider = new Emitter<vscode.SCMProvider>();
|
||||
get onDidChangeActiveProvider(): Event<vscode.SCMProvider> { return this._onDidChangeActiveProvider.event; }
|
||||
|
||||
private _activeProvider: vscode.SCMProvider;
|
||||
get activeProvider(): vscode.SCMProvider | undefined { return this._activeProvider; }
|
||||
|
||||
private cache: Cache = Object.create(null);
|
||||
|
||||
constructor(threadService: IThreadService) {
|
||||
this._proxy = threadService.get(MainContext.MainThreadSCM);
|
||||
}
|
||||
|
||||
getResourceFromURI(uri: vscode.Uri): vscode.SCMResource | vscode.SCMResourceGroup | undefined {
|
||||
if (uri.scheme !== 'scm') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const providerId = uri.authority;
|
||||
const providerCache = this.cache[providerId];
|
||||
|
||||
if (!providerCache) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const match = /^\/([^/]+)(\/(.*))?$/.exec(uri.path);
|
||||
|
||||
if (!match) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const resourceGroupId = match[1];
|
||||
const resourceGroupRef = providerCache[resourceGroupId];
|
||||
|
||||
if (!resourceGroupRef) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const rawResourceUri = match[3];
|
||||
|
||||
if (!rawResourceUri) {
|
||||
return resourceGroupRef.resourceGroup;
|
||||
}
|
||||
|
||||
let resourceUri: string;
|
||||
|
||||
try {
|
||||
const rawResource = JSON.parse(rawResourceUri);
|
||||
const resource = URI.from(rawResource);
|
||||
resourceUri = resource.toString();
|
||||
} catch (err) {
|
||||
resourceUri = undefined;
|
||||
}
|
||||
|
||||
if (!resourceUri) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const resource = resourceGroupRef.resources[resourceUri];
|
||||
|
||||
if (!resource) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
registerSCMProvider(providerId: string, provider: vscode.SCMProvider): Disposable {
|
||||
if (this._providers[providerId]) {
|
||||
throw new Error(`Provider ${providerId} already registered`);
|
||||
}
|
||||
|
||||
// TODO@joao: should pluck all the things out of the provider
|
||||
this._providers[providerId] = provider;
|
||||
|
||||
this._proxy.$register(providerId, {
|
||||
label: provider.label,
|
||||
supportsCommit: !!provider.commit,
|
||||
supportsOpen: !!provider.open,
|
||||
supportsDrag: !!provider.drag,
|
||||
supportsOriginalResource: !!provider.getOriginalResource
|
||||
});
|
||||
|
||||
const onDidChange = debounceEvent(provider.onDidChange, (l, e) => e, 100);
|
||||
const onDidChangeListener = onDidChange(resourceGroups => {
|
||||
this.cache[providerId] = Object.create(null);
|
||||
|
||||
const rawResourceGroups = resourceGroups.map(g => {
|
||||
const resources: { [id: string]: vscode.SCMResource; } = Object.create(null);
|
||||
|
||||
const rawResources = g.resources.map(r => {
|
||||
const uri = r.uri.toString();
|
||||
const iconPath = getIconPath(r.decorations);
|
||||
const lightIconPath = r.decorations && getIconPath(r.decorations.light) || iconPath;
|
||||
const darkIconPath = r.decorations && getIconPath(r.decorations.dark) || iconPath;
|
||||
const icons: string[] = [];
|
||||
|
||||
if (lightIconPath || darkIconPath) {
|
||||
icons.push(lightIconPath);
|
||||
}
|
||||
|
||||
if (darkIconPath !== lightIconPath) {
|
||||
icons.push(darkIconPath);
|
||||
}
|
||||
|
||||
const strikeThrough = r.decorations && !!r.decorations.strikeThrough;
|
||||
resources[uri] = r;
|
||||
|
||||
return [uri, icons, strikeThrough] as SCMRawResource;
|
||||
});
|
||||
|
||||
this.cache[providerId][g.id] = { resourceGroup: g, resources };
|
||||
|
||||
return [g.id, g.label, rawResources] as SCMRawResourceGroup;
|
||||
});
|
||||
|
||||
this._proxy.$onChange(providerId, rawResourceGroups);
|
||||
});
|
||||
|
||||
return new Disposable(() => {
|
||||
onDidChangeListener.dispose();
|
||||
delete this._providers[providerId];
|
||||
this._proxy.$unregister(providerId);
|
||||
});
|
||||
}
|
||||
|
||||
$commit(providerId: string, message: string): TPromise<void> {
|
||||
const provider = this._providers[providerId];
|
||||
|
||||
if (!provider) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return asWinJsPromise(token => provider.commit(message, token));
|
||||
}
|
||||
|
||||
$open(providerId: string, resourceGroupId: string, uri: string): TPromise<void> {
|
||||
const provider = this._providers[providerId];
|
||||
|
||||
if (!provider) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
const providerCache = this.cache[providerId];
|
||||
const resourceGroup = providerCache[resourceGroupId];
|
||||
const resource = resourceGroup && resourceGroup.resources[uri];
|
||||
|
||||
if (!resource) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return asWinJsPromise(token => provider.open(resource, token));
|
||||
}
|
||||
|
||||
$drag(providerId: string, fromResourceGroupId: string, fromUri: string, toResourceGroupId: string): TPromise<void> {
|
||||
const provider = this._providers[providerId];
|
||||
|
||||
if (!provider) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
const providerCache = this.cache[providerId];
|
||||
const fromResourceGroup = providerCache[fromResourceGroupId];
|
||||
const resource = fromResourceGroup && fromResourceGroup.resources[fromUri];
|
||||
const toResourceGroup = providerCache[toResourceGroupId];
|
||||
const resourceGroup = toResourceGroup && toResourceGroup.resourceGroup;
|
||||
|
||||
if (!resource || !resourceGroup) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return asWinJsPromise(token => provider.drag(resource, resourceGroup, token));
|
||||
}
|
||||
|
||||
$getOriginalResource(id: string, uri: URI): TPromise<URI> {
|
||||
const provider = this._providers[id];
|
||||
|
||||
if (!provider) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return asWinJsPromise(token => provider.getOriginalResource(uri, token));
|
||||
}
|
||||
}
|
||||
@@ -20,14 +20,20 @@ export class ExtHostTerminal implements vscode.Terminal {
|
||||
private _pidPromise: TPromise<number>;
|
||||
private _pidPromiseComplete: TValueCallback<number>;
|
||||
|
||||
constructor(proxy: MainThreadTerminalServiceShape, name?: string, shellPath?: string, shellArgs?: string[]) {
|
||||
constructor(
|
||||
proxy: MainThreadTerminalServiceShape,
|
||||
name?: string,
|
||||
shellPath?: string,
|
||||
shellArgs?: string[],
|
||||
waitOnExit?: boolean
|
||||
) {
|
||||
this._name = name;
|
||||
this._queuedRequests = [];
|
||||
this._proxy = proxy;
|
||||
this._pidPromise = new TPromise<number>(c => {
|
||||
this._pidPromiseComplete = c;
|
||||
});
|
||||
this._proxy.$createTerminal(name, shellPath, shellArgs).then((id) => {
|
||||
this._proxy.$createTerminal(name, shellPath, shellArgs, waitOnExit).then((id) => {
|
||||
this._id = id;
|
||||
this._queuedRequests.forEach((r) => {
|
||||
r.run(this._proxy, this._id);
|
||||
@@ -107,6 +113,12 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
|
||||
return terminal;
|
||||
}
|
||||
|
||||
public createTerminalFromOptions(options: vscode.TerminalOptions): vscode.Terminal {
|
||||
let terminal = new ExtHostTerminal(this._proxy, options.name, options.shellPath, options.shellArgs, options.waitOnExit);
|
||||
this._terminals.push(terminal);
|
||||
return terminal;
|
||||
}
|
||||
|
||||
public get onDidCloseTerminal(): Event<vscode.Terminal> {
|
||||
return this._onDidCloseTerminal && this._onDidCloseTerminal.event;
|
||||
}
|
||||
|
||||
@@ -465,7 +465,7 @@ export class Uri extends URI { }
|
||||
export class WorkspaceEdit {
|
||||
|
||||
private _values: [Uri, TextEdit[]][] = [];
|
||||
private _index: { [uri: string]: number } = Object.create(null);
|
||||
private _index = new Map<string, number>();
|
||||
|
||||
replace(uri: Uri, range: Range, newText: string): void {
|
||||
let edit = new TextEdit(range, newText);
|
||||
@@ -486,21 +486,21 @@ export class WorkspaceEdit {
|
||||
}
|
||||
|
||||
has(uri: Uri): boolean {
|
||||
return typeof this._index[uri.toString()] !== 'undefined';
|
||||
return this._index.has(uri.toString());
|
||||
}
|
||||
|
||||
set(uri: Uri, edits: TextEdit[]): void {
|
||||
let idx = this._index[uri.toString()];
|
||||
const idx = this._index.get(uri.toString());
|
||||
if (typeof idx === 'undefined') {
|
||||
let newLen = this._values.push([uri, edits]);
|
||||
this._index[uri.toString()] = newLen - 1;
|
||||
this._index.set(uri.toString(), newLen - 1);
|
||||
} else {
|
||||
this._values[idx][1] = edits;
|
||||
}
|
||||
}
|
||||
|
||||
get(uri: Uri): TextEdit[] {
|
||||
let idx = this._index[uri.toString()];
|
||||
let idx = this._index.get(uri.toString());
|
||||
return typeof idx !== 'undefined' && this._values[idx][1];
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
'use strict';
|
||||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { relative, isEqualOrParent } from 'vs/base/common/paths';
|
||||
import { normalize } from 'vs/base/common/paths';
|
||||
import { relative } from 'path';
|
||||
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
|
||||
import { IResourceEdit } from 'vs/editor/common/services/bulkEdit';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
@@ -34,15 +35,24 @@ export class ExtHostWorkspace {
|
||||
let path: string;
|
||||
if (typeof pathOrUri === 'string') {
|
||||
path = pathOrUri;
|
||||
} else {
|
||||
} else if (typeof pathOrUri !== 'undefined') {
|
||||
path = pathOrUri.fsPath;
|
||||
}
|
||||
|
||||
if (isEqualOrParent(path, this._workspacePath)) {
|
||||
return relative(this._workspacePath, path) || path;
|
||||
if (!path) {
|
||||
return path;
|
||||
}
|
||||
|
||||
return path;
|
||||
if (!this._workspacePath) {
|
||||
return normalize(path);
|
||||
}
|
||||
|
||||
let result = relative(this._workspacePath, path);
|
||||
if (!result || result.indexOf('..') === 0) {
|
||||
return normalize(path);
|
||||
}
|
||||
|
||||
return normalize(result);
|
||||
}
|
||||
|
||||
findFiles(include: string, exclude: string, maxResults?: number, token?: vscode.CancellationToken): Thenable<vscode.Uri[]> {
|
||||
|
||||
@@ -106,7 +106,7 @@ export class MainThreadDocuments extends MainThreadDocumentsShape {
|
||||
url: model.uri,
|
||||
versionId: model.getVersionId(),
|
||||
value: model.toRawText(),
|
||||
modeId: model.getMode().getId(),
|
||||
modeId: model.getLanguageIdentifier().language,
|
||||
isDirty: this._textFileService.isDirty(modelUrl)
|
||||
});
|
||||
}
|
||||
@@ -117,7 +117,7 @@ export class MainThreadDocuments extends MainThreadDocumentsShape {
|
||||
if (!this._modelIsSynced[modelUrl.toString()]) {
|
||||
return;
|
||||
}
|
||||
this._proxy.$acceptModelModeChanged(model.uri.toString(), oldModeId, model.getMode().getId());
|
||||
this._proxy.$acceptModelModeChanged(model.uri.toString(), oldModeId, model.getLanguageIdentifier().language);
|
||||
}
|
||||
|
||||
private _onModelRemoved(model: editorCommon.IModel): void {
|
||||
|
||||
@@ -604,7 +604,7 @@ export class MainThreadEditorsTracker {
|
||||
}
|
||||
|
||||
private _findVisibleTextEditorIds(): string[] {
|
||||
let result = [];
|
||||
let result: string[] = [];
|
||||
let modelUris = Object.keys(this._model2TextEditors);
|
||||
for (let i = 0, len = modelUris.length; i < len; i++) {
|
||||
let editors = this._model2TextEditors[modelUris[i]];
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
import { FileChangeType, IFileService } from 'vs/platform/files/common/files';
|
||||
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { ExtHostContext, ExtHostFileSystemEventServiceShape, FileSystemEvents } from './extHost.protocol';
|
||||
|
||||
export class MainThreadFileSystemEventService {
|
||||
@@ -23,13 +22,6 @@ export class MainThreadFileSystemEventService {
|
||||
deleted: []
|
||||
};
|
||||
|
||||
const scheduler = new RunOnceScheduler(() => {
|
||||
proxy.$onFileEvent(events);
|
||||
events.created.length = 0;
|
||||
events.changed.length = 0;
|
||||
events.deleted.length = 0;
|
||||
}, 100);
|
||||
|
||||
fileService.onFileChanges(event => {
|
||||
for (let change of event.changes) {
|
||||
switch (change.type) {
|
||||
@@ -44,7 +36,11 @@ export class MainThreadFileSystemEventService {
|
||||
break;
|
||||
}
|
||||
}
|
||||
scheduler.schedule();
|
||||
|
||||
proxy.$onFileEvent(events);
|
||||
events.created.length = 0;
|
||||
events.changed.length = 0;
|
||||
events.deleted.length = 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,17 +12,6 @@ import { consumeSignals, GCSignal } from 'gc-signals';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
|
||||
|
||||
declare class WeakMap<K, V> {
|
||||
set(key: K, value?: V): WeakMap<K, V>;
|
||||
}
|
||||
|
||||
declare class Set<E> {
|
||||
add(e: E): this;
|
||||
has(e: E): boolean;
|
||||
delete(e: E): boolean;
|
||||
}
|
||||
|
||||
export const IHeapService = createDecorator<IHeapService>('heapService');
|
||||
|
||||
export interface IHeapService {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
|
||||
import * as vscode from 'vscode';
|
||||
import { IReadOnlyModel, ISingleEditOperation } from 'vs/editor/common/editorCommon';
|
||||
@@ -19,20 +20,24 @@ import { ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeature
|
||||
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
|
||||
import { LanguageConfiguration } from 'vs/editor/common/modes/languageConfiguration';
|
||||
import { IHeapService } from './mainThreadHeapService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
|
||||
export class MainThreadLanguageFeatures extends MainThreadLanguageFeaturesShape {
|
||||
|
||||
private _proxy: ExtHostLanguageFeaturesShape;
|
||||
private _heapService: IHeapService;
|
||||
private _modeService: IModeService;
|
||||
private _registrations: { [handle: number]: IDisposable; } = Object.create(null);
|
||||
|
||||
constructor(
|
||||
@IThreadService threadService: IThreadService,
|
||||
@IHeapService heapService: IHeapService
|
||||
@IHeapService heapService: IHeapService,
|
||||
@IModeService modeService: IModeService,
|
||||
) {
|
||||
super();
|
||||
this._proxy = threadService.get(ExtHostContext.ExtHostLanguageFeatures);
|
||||
this._heapService = heapService;
|
||||
this._modeService = modeService;
|
||||
}
|
||||
|
||||
$unregister(handle: number): TPromise<any> {
|
||||
@@ -57,15 +62,32 @@ export class MainThreadLanguageFeatures extends MainThreadLanguageFeaturesShape
|
||||
|
||||
// --- code lens
|
||||
|
||||
$registerCodeLensSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> {
|
||||
this._registrations[handle] = modes.CodeLensProviderRegistry.register(selector, <modes.CodeLensProvider>{
|
||||
$registerCodeLensSupport(handle: number, selector: vscode.DocumentSelector, eventHandle: number): TPromise<any> {
|
||||
|
||||
const provider = <modes.CodeLensProvider>{
|
||||
provideCodeLenses: (model: IReadOnlyModel, token: CancellationToken): modes.ICodeLensSymbol[] | Thenable<modes.ICodeLensSymbol[]> => {
|
||||
return this._heapService.trackRecursive(wireCancellationToken(token, this._proxy.$provideCodeLenses(handle, model.uri)));
|
||||
},
|
||||
resolveCodeLens: (model: IReadOnlyModel, codeLens: modes.ICodeLensSymbol, token: CancellationToken): modes.ICodeLensSymbol | Thenable<modes.ICodeLensSymbol> => {
|
||||
return this._heapService.trackRecursive(wireCancellationToken(token, this._proxy.$resolveCodeLens(handle, model.uri, codeLens)));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (typeof eventHandle === 'number') {
|
||||
const emitter = new Emitter<modes.CodeLensProvider>();
|
||||
this._registrations[eventHandle] = emitter;
|
||||
provider.onDidChange = emitter.event;
|
||||
}
|
||||
|
||||
this._registrations[handle] = modes.CodeLensProviderRegistry.register(selector, provider);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
$emitCodeLensEvent(eventHandle: number, event?: any): TPromise<any> {
|
||||
const obj = this._registrations[eventHandle];
|
||||
if (obj instanceof Emitter) {
|
||||
obj.fire(event);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -80,6 +102,15 @@ export class MainThreadLanguageFeatures extends MainThreadLanguageFeaturesShape
|
||||
return undefined;
|
||||
}
|
||||
|
||||
$registerImplementationSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> {
|
||||
this._registrations[handle] = modes.TypeDefinitionProviderRegistry.register(selector, <modes.TypeDefinitionProvider>{
|
||||
provideTypeDefinition: (model, position, token): Thenable<modes.Definition> => {
|
||||
return wireCancellationToken(token, this._proxy.$provideTypeDefinition(handle, model.uri, position));
|
||||
}
|
||||
});
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// --- extra info
|
||||
|
||||
$registerHoverProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any> {
|
||||
@@ -255,7 +286,11 @@ export class MainThreadLanguageFeatures extends MainThreadLanguageFeaturesShape
|
||||
};
|
||||
}
|
||||
|
||||
this._registrations[handle] = LanguageConfigurationRegistry.register(languageId, configuration);
|
||||
let languageIdentifier = this._modeService.getLanguageIdentifier(languageId);
|
||||
if (languageIdentifier) {
|
||||
this._registrations[handle] = LanguageConfigurationRegistry.register(languageIdentifier, configuration);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ export class MainThreadOutputService extends MainThreadOutputServiceShape {
|
||||
public $close(channelId: string): TPromise<void> {
|
||||
const panel = this._panelService.getActivePanel();
|
||||
if (panel && panel.getId() === OUTPUT_PANEL_ID && channelId === this._outputService.getActiveChannel().id) {
|
||||
this._partService.setPanelHidden(true);
|
||||
return this._partService.setPanelHidden(true);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
||||
55
src/vs/workbench/api/node/mainThreadProgress.ts
Normal file
55
src/vs/workbench/api/node/mainThreadProgress.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { IProgressService2, IProgress } from 'vs/platform/progress/common/progress';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { MainThreadProgressShape } from './extHost.protocol';
|
||||
|
||||
export class MainThreadProgress extends MainThreadProgressShape {
|
||||
|
||||
private _progressService: IProgressService2;
|
||||
private progress = new Map<number, { resolve: Function, reject: Function, progress: IProgress<any> }>();
|
||||
|
||||
constructor(
|
||||
@IProgressService2 progressService: IProgressService2
|
||||
) {
|
||||
super();
|
||||
this._progressService = progressService;
|
||||
}
|
||||
|
||||
|
||||
$progressStart(handle: number, extensionId: string, where: string): void {
|
||||
|
||||
const task = (progress: IProgress<any>) => {
|
||||
return new TPromise<any>((resolve, reject) => {
|
||||
this.progress.set(handle, { resolve, reject, progress });
|
||||
});
|
||||
};
|
||||
|
||||
switch (where) {
|
||||
case 'window':
|
||||
this._progressService.withWindowProgress(task);
|
||||
break;
|
||||
case 'scm':
|
||||
this._progressService.withViewletProgress('workbench.view.scm', task);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$progressReport(handle: number, message: any): void {
|
||||
this.progress.get(handle).progress.report(message);
|
||||
}
|
||||
|
||||
$progressEnd(handle: number, err: any): void {
|
||||
if (err) {
|
||||
this.progress.get(handle).reject(err);
|
||||
} else {
|
||||
this.progress.get(handle).resolve();
|
||||
}
|
||||
this.progress.delete(handle);
|
||||
}
|
||||
}
|
||||
157
src/vs/workbench/api/node/mainThreadSCM.ts
Normal file
157
src/vs/workbench/api/node/mainThreadSCM.ts
Normal file
@@ -0,0 +1,157 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
|
||||
import { ISCMService, ISCMProvider, ISCMResource, ISCMResourceGroup } from 'vs/workbench/services/scm/common/scm';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { ExtHostContext, MainThreadSCMShape, ExtHostSCMShape, SCMProviderFeatures, SCMRawResourceGroup } from './extHost.protocol';
|
||||
|
||||
class MainThreadSCMProvider implements ISCMProvider {
|
||||
|
||||
private _resources: ISCMResourceGroup[] = [];
|
||||
get resources(): ISCMResourceGroup[] { return this._resources; }
|
||||
|
||||
private _onDidChange = new Emitter<ISCMResourceGroup[]>();
|
||||
get onDidChange(): Event<ISCMResourceGroup[]> { return this._onDidChange.event; }
|
||||
|
||||
private disposables: IDisposable[] = [];
|
||||
|
||||
get id(): string { return this._id; }
|
||||
get label(): string { return this.features.label; }
|
||||
|
||||
constructor(
|
||||
private _id: string,
|
||||
private proxy: ExtHostSCMShape,
|
||||
private features: SCMProviderFeatures,
|
||||
@ISCMService scmService: ISCMService,
|
||||
@ICommandService private commandService: ICommandService
|
||||
) {
|
||||
scmService.onDidChangeProvider(this.onDidChangeProvider, this, this.disposables);
|
||||
this.disposables.push(scmService.registerSCMProvider(this));
|
||||
}
|
||||
|
||||
commit(message: string): TPromise<void> {
|
||||
if (!this.features.supportsCommit) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return this.proxy.$commit(this.id, message);
|
||||
}
|
||||
|
||||
open(resource: ISCMResource): TPromise<void> {
|
||||
if (!this.features.supportsOpen) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return this.proxy.$open(this.id, resource.resourceGroupId, resource.uri.toString());
|
||||
}
|
||||
|
||||
drag(from: ISCMResource, to: ISCMResourceGroup): TPromise<void> {
|
||||
if (!this.features.supportsDrag) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return this.proxy.$drag(this.id, from.resourceGroupId, from.uri.toString(), to.id);
|
||||
}
|
||||
|
||||
getOriginalResource(uri: URI): TPromise<URI> {
|
||||
if (!this.features.supportsOriginalResource) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return this.proxy.$getOriginalResource(this.id, uri);
|
||||
}
|
||||
|
||||
private onDidChangeProvider(provider: ISCMProvider): void {
|
||||
// if (provider === this) {
|
||||
// return
|
||||
// }
|
||||
}
|
||||
|
||||
$onChange(rawResourceGroups: SCMRawResourceGroup[]): void {
|
||||
this._resources = rawResourceGroups.map(rawGroup => {
|
||||
const [id, label, rawResources] = rawGroup;
|
||||
|
||||
const resources = rawResources.map(rawResource => {
|
||||
const [uri, icons, strikeThrough] = rawResource;
|
||||
|
||||
const icon = icons[0];
|
||||
const iconDark = icons[1] || icon;
|
||||
|
||||
const decorations = {
|
||||
icon: icon && URI.parse(icon),
|
||||
iconDark: iconDark && URI.parse(iconDark),
|
||||
strikeThrough
|
||||
};
|
||||
|
||||
return {
|
||||
resourceGroupId: id,
|
||||
uri: URI.parse(uri),
|
||||
decorations
|
||||
};
|
||||
});
|
||||
|
||||
return { id, label, resources };
|
||||
});
|
||||
|
||||
this._onDidChange.fire(this.resources);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.disposables = dispose(this.disposables);
|
||||
}
|
||||
}
|
||||
|
||||
export class MainThreadSCM extends MainThreadSCMShape {
|
||||
|
||||
private proxy: ExtHostSCMShape;
|
||||
private providers: { [id: string]: MainThreadSCMProvider; } = Object.create(null);
|
||||
|
||||
constructor(
|
||||
@IThreadService threadService: IThreadService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
) {
|
||||
super();
|
||||
this.proxy = threadService.get(ExtHostContext.ExtHostSCM);
|
||||
}
|
||||
|
||||
$register(id: string, features: SCMProviderFeatures): void {
|
||||
this.providers[id] = this.instantiationService.createInstance(MainThreadSCMProvider, id, this.proxy, features);
|
||||
}
|
||||
|
||||
$unregister(id: string): void {
|
||||
const provider = this.providers[id];
|
||||
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
|
||||
provider.dispose();
|
||||
delete this.providers[id];
|
||||
}
|
||||
|
||||
$onChange(id: string, rawResourceGroups: SCMRawResourceGroup[]): void {
|
||||
const provider = this.providers[id];
|
||||
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
|
||||
provider.$onChange(rawResourceGroups);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
Object.keys(this.providers)
|
||||
.forEach(id => this.providers[id].dispose());
|
||||
|
||||
this.providers = Object.create(null);
|
||||
}
|
||||
}
|
||||
@@ -70,23 +70,21 @@ class TrimWhitespaceParticipant implements INamedSaveParticpant {
|
||||
}
|
||||
|
||||
function findEditor(model: IModel, codeEditorService: ICodeEditorService): ICommonCodeEditor {
|
||||
let candidate: ICommonCodeEditor = null;
|
||||
|
||||
if (model.isAttachedToEditor()) {
|
||||
const allEditors = codeEditorService.listCodeEditors();
|
||||
for (let i = 0, len = allEditors.length; i < len; i++) {
|
||||
const editor = allEditors[i];
|
||||
const editorModel = editor.getModel();
|
||||
for (const editor of codeEditorService.listCodeEditors()) {
|
||||
if (editor.getModel() === model) {
|
||||
if (editor.isFocused()) {
|
||||
return editor; // favour focussed editor if there are multiple
|
||||
}
|
||||
|
||||
if (!editorModel) {
|
||||
continue; // empty editor
|
||||
}
|
||||
|
||||
if (model === editorModel) {
|
||||
return editor;
|
||||
candidate = editor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return candidate;
|
||||
}
|
||||
|
||||
export class FinalNewLineParticipant implements INamedSaveParticpant {
|
||||
@@ -158,7 +156,7 @@ class FormatOnSaveParticipant implements INamedSaveParticpant {
|
||||
|
||||
}).then(edits => {
|
||||
if (edits && versionNow === model.getVersionId()) {
|
||||
const editor = this._findEditor(model);
|
||||
const editor = findEditor(model, this._editorService);
|
||||
if (editor) {
|
||||
this._editsWithEditor(editor, edits);
|
||||
} else {
|
||||
@@ -194,24 +192,6 @@ class FormatOnSaveParticipant implements INamedSaveParticpant {
|
||||
forceMoveMarkers: true
|
||||
};
|
||||
}
|
||||
|
||||
private _findEditor(model: IModel) {
|
||||
if (!model.isAttachedToEditor()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let candidate: ICommonCodeEditor;
|
||||
for (const editor of this._editorService.listCodeEditors()) {
|
||||
if (editor.getModel() === model) {
|
||||
if (editor.isFocused()) {
|
||||
return editor;
|
||||
} else {
|
||||
candidate = editor;
|
||||
}
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
class ExtHostSaveParticipant implements INamedSaveParticpant {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
'use strict';
|
||||
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { ITerminalService, ITerminalInstance } from 'vs/workbench/parts/terminal/common/terminal';
|
||||
import { ITerminalService, ITerminalInstance, IShellLaunchConfig } from 'vs/workbench/parts/terminal/common/terminal';
|
||||
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape } from './extHost.protocol';
|
||||
@@ -30,8 +30,15 @@ export class MainThreadTerminalService extends MainThreadTerminalServiceShape {
|
||||
this._toDispose = dispose(this._toDispose);
|
||||
}
|
||||
|
||||
public $createTerminal(name?: string, shellPath?: string, shellArgs?: string[]): TPromise<number> {
|
||||
return TPromise.as(this.terminalService.createInstance(name, shellPath, shellArgs, true).id);
|
||||
public $createTerminal(name?: string, shellPath?: string, shellArgs?: string[], waitOnExit?: boolean): TPromise<number> {
|
||||
const shellLaunchConfig: IShellLaunchConfig = {
|
||||
name,
|
||||
executable: shellPath,
|
||||
args: shellArgs,
|
||||
waitOnExit,
|
||||
ignoreConfigurationCwd: true
|
||||
};
|
||||
return TPromise.as(this.terminalService.createInstance(shellLaunchConfig).id);
|
||||
}
|
||||
|
||||
public $show(terminalId: number, preserveFocus: boolean): void {
|
||||
|
||||
@@ -16,7 +16,7 @@ export class MainThreadTreeExplorers extends MainThreadTreeExplorersShape {
|
||||
private _proxy: ExtHostTreeExplorersShape;
|
||||
|
||||
constructor(
|
||||
@IThreadService private threadService: IThreadService,
|
||||
@IThreadService threadService: IThreadService,
|
||||
@ITreeExplorerService private treeExplorerService: ITreeExplorerService,
|
||||
@IMessageService private messageService: IMessageService,
|
||||
@ICommandService private commandService: ICommandService
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { isPromiseCanceledError } from 'vs/base/common/errors';
|
||||
import { ISearchService, QueryType } from 'vs/platform/search/common/search';
|
||||
import { IWorkspaceContextService, IWorkspace } from 'vs/platform/workspace/common/workspace';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { ICommonCodeEditor } from 'vs/editor/common/editorCommon';
|
||||
@@ -21,7 +21,7 @@ export class MainThreadWorkspace extends MainThreadWorkspaceShape {
|
||||
|
||||
private _activeSearches: { [id: number]: TPromise<Uri[]> } = Object.create(null);
|
||||
private _searchService: ISearchService;
|
||||
private _workspace: IWorkspace;
|
||||
private _contextService: IWorkspaceContextService;
|
||||
private _textFileService: ITextFileService;
|
||||
private _editorService: IWorkbenchEditorService;
|
||||
private _textModelResolverService: ITextModelResolverService;
|
||||
@@ -30,15 +30,15 @@ export class MainThreadWorkspace extends MainThreadWorkspaceShape {
|
||||
constructor(
|
||||
@ISearchService searchService: ISearchService,
|
||||
@IWorkspaceContextService contextService: IWorkspaceContextService,
|
||||
@ITextFileService textFileService,
|
||||
@IWorkbenchEditorService editorService,
|
||||
@ITextModelResolverService textModelResolverService,
|
||||
@ITextFileService textFileService: ITextFileService,
|
||||
@IWorkbenchEditorService editorService: IWorkbenchEditorService,
|
||||
@ITextModelResolverService textModelResolverService: ITextModelResolverService,
|
||||
@IFileService fileService: IFileService
|
||||
) {
|
||||
super();
|
||||
|
||||
this._searchService = searchService;
|
||||
this._workspace = contextService.getWorkspace();
|
||||
this._contextService = contextService;
|
||||
this._textFileService = textFileService;
|
||||
this._editorService = editorService;
|
||||
this._fileService = fileService;
|
||||
@@ -46,13 +46,13 @@ export class MainThreadWorkspace extends MainThreadWorkspaceShape {
|
||||
}
|
||||
|
||||
$startSearch(include: string, exclude: string, maxResults: number, requestId: number): Thenable<Uri[]> {
|
||||
|
||||
if (!this._workspace) {
|
||||
const workspace = this._contextService.getWorkspace();
|
||||
if (!workspace) {
|
||||
return;
|
||||
}
|
||||
|
||||
const search = this._searchService.search({
|
||||
folderResources: [this._workspace.resource],
|
||||
folderResources: [workspace.resource],
|
||||
type: QueryType.File,
|
||||
maxResults,
|
||||
includePattern: { [include]: true },
|
||||
@@ -99,7 +99,7 @@ export class MainThreadWorkspace extends MainThreadWorkspaceShape {
|
||||
}
|
||||
}
|
||||
|
||||
return bulkEdit(this._fileService, this._textModelResolverService, codeEditor, edits)
|
||||
return bulkEdit(this._textModelResolverService, codeEditor, edits, this._fileService)
|
||||
.then(() => true);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user