/*--------------------------------------------------------------------------------------------- * 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 Event, {Emitter} from 'vs/base/common/event'; import Severity from 'vs/base/common/severity'; import {TPromise} from 'vs/base/common/winjs.base'; import {onUnexpectedError} from 'vs/base/common/errors'; import {sequence} from 'vs/base/common/async'; import {Range as EditorRange} from 'vs/editor/common/core/range'; import {IDisposable} from 'vs/base/common/lifecycle'; import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService'; import {Remotable, IThreadService} from 'vs/platform/thread/common/thread'; import * as vscode from 'vscode'; import * as TypeConverters from 'vs/workbench/api/common/pluginHostTypeConverters'; import {Position, Range, SymbolKind, DocumentHighlightKind, Disposable, Diagnostic, DiagnosticSeverity, Location, SignatureHelp, CompletionItemKind} from 'vs/workbench/api/common/pluginHostTypes'; import {IPosition, IRange, ISingleEditOperation} from 'vs/editor/common/editorCommon'; import * as modes from 'vs/editor/common/modes'; import {CancellationTokenSource} from 'vs/base/common/cancellation'; import {PluginHostModelService} from 'vs/workbench/api/common/pluginHostDocuments'; import {IMarkerService, IMarker} from 'vs/platform/markers/common/markers'; import {PluginHostCommands, MainThreadCommands} from 'vs/workbench/api/common/pluginHostCommands'; import {DeclarationRegistry} from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration'; import {ExtraInfoRegistry} from 'vs/editor/contrib/hover/common/hover'; import {OccurrencesRegistry} from 'vs/editor/contrib/wordHighlighter/common/wordHighlighter'; import {ReferenceRegistry} from 'vs/editor/contrib/referenceSearch/common/referenceSearch'; import {QuickFixRegistry} from 'vs/editor/contrib/quickFix/common/quickFix'; import {OutlineRegistry, IOutlineEntry, IOutlineSupport} from 'vs/editor/contrib/quickOpen/common/quickOpen'; import LanguageFeatureRegistry from 'vs/editor/common/modes/languageFeatureRegistry'; import {NavigateTypesSupportRegistry, INavigateTypesSupport, ITypeBearing} from 'vs/workbench/parts/search/common/search' import {RenameRegistry} from 'vs/editor/contrib/rename/common/rename'; import {FormatRegistry, FormatOnTypeRegistry} from 'vs/editor/contrib/format/common/format'; import {CodeLensRegistry} from 'vs/editor/contrib/codelens/common/codelens'; import {ParameterHintsRegistry} from 'vs/editor/contrib/parameterHints/common/parameterHints'; import {SuggestRegistry} from 'vs/editor/contrib/suggest/common/suggest'; function isThenable(obj: any): obj is Thenable { return obj && typeof obj['then'] === 'function'; } function asWinJsPromise(callback: (token: vscode.CancellationToken) => T | Thenable): TPromise { let source = new CancellationTokenSource(); return new TPromise((resolve, reject) => { let item = callback(source.token); if (isThenable(item)) { item.then(resolve, reject); } else { resolve(item); } }, () => { source.cancel(); }); } // --- adapter class OutlineAdapter implements IOutlineSupport { private _documents: PluginHostModelService; private _provider: vscode.DocumentSymbolProvider; constructor(documents: PluginHostModelService, provider: vscode.DocumentSymbolProvider) { this._documents = documents; this._provider = provider; } getOutline(resource: URI): TPromise { let doc = this._documents.getDocument(resource); return asWinJsPromise(token => this._provider.provideDocumentSymbols(doc, token)).then(value => { if (Array.isArray(value)) { return value.map(OutlineAdapter._convertSymbolInfo); } }); } private static _convertSymbolInfo(symbol: vscode.SymbolInformation): IOutlineEntry { return { type: TypeConverters.fromSymbolKind(symbol.kind), range: TypeConverters.fromRange(symbol.location.range), containerLabel: symbol.containerName, label: symbol.name, icon: undefined, }; } } class CodeLensAdapter implements modes.ICodeLensSupport { private _documents: PluginHostModelService; private _provider: vscode.CodeLensProvider; private _cache: { [uri: string]: vscode.CodeLens[] } = Object.create(null); constructor(documents: PluginHostModelService, provider: vscode.CodeLensProvider) { this._documents = documents; this._provider = provider; } findCodeLensSymbols(resource: URI): TPromise { let doc = this._documents.getDocument(resource); let key = resource.toString(); delete this._cache[key]; return asWinJsPromise(token => this._provider.provideCodeLenses(doc, token)).then(value => { if (!Array.isArray(value)) { return; } this._cache[key] = value; return value.map((lens, i) => { return { id: String(i), range: TypeConverters.fromRange(lens.range) } }); }); } resolveCodeLensSymbol(resource: URI, symbol: modes.ICodeLensSymbol): TPromise { let lenses = this._cache[resource.toString()]; if (!lenses) { return; } let lens = lenses[Number(symbol.id)]; if (!lens) { return; } let resolve: TPromise; if (typeof this._provider.resolveCodeLens !== 'function' || lens.isResolved) { resolve = TPromise.as(lens); } else { resolve = asWinJsPromise(token => this._provider.resolveCodeLens(lens, token)); } return resolve.then(newLens => { lens = newLens || lens; let command = lens.command; if (!command) { command = { title: '<>', command: 'missing', } } return { id: command.command, title: command.title, arguments: command.arguments } }); } } class DeclarationAdapter implements modes.IDeclarationSupport { private _documents: PluginHostModelService; private _provider: vscode.DefinitionProvider; constructor(documents: PluginHostModelService, provider: vscode.DefinitionProvider) { this._documents = documents; this._provider = provider; } canFindDeclaration() { return true; } findDeclaration(resource: URI, position: IPosition): TPromise { let doc = this._documents.getDocument(resource); let pos = TypeConverters.toPosition(position); return asWinJsPromise(token => this._provider.provideDefinition(doc, pos, token)).then(value => { if (Array.isArray(value)) { return value.map(DeclarationAdapter._convertLocation); } else if (value) { return DeclarationAdapter._convertLocation(value); } }); } private static _convertLocation(location: vscode.Location): modes.IReference { if (!location) { return; } return { resource: location.uri, range: TypeConverters.fromRange(location.range) }; } } class ExtraInfoAdapter implements modes.IExtraInfoSupport { private _documents: PluginHostModelService; private _provider: vscode.HoverProvider; constructor(documents: PluginHostModelService, provider: vscode.HoverProvider) { this._documents = documents; this._provider = provider; } computeInfo(resource: URI, position: IPosition): TPromise { let doc = this._documents.getDocument(resource); let pos = TypeConverters.toPosition(position); return asWinJsPromise(token => this._provider.provideHover(doc, pos, token)).then(value => { if (!value) { return; } let {range, contents} = value; if (!range) { range = doc.getWordRangeAtPosition(pos); } if (!range) { range = new Range(pos, pos); } return { range: TypeConverters.fromRange(range), htmlContent: contents && contents.map(TypeConverters.fromFormattedString) } }); } } class OccurrencesAdapter implements modes.IOccurrencesSupport { private _documents: PluginHostModelService; private _provider: vscode.DocumentHighlightProvider; constructor(documents: PluginHostModelService, provider: vscode.DocumentHighlightProvider) { this._documents = documents; this._provider = provider; } findOccurrences(resource: URI, position: IPosition): TPromise { let doc = this._documents.getDocument(resource); let pos = TypeConverters.toPosition(position); return asWinJsPromise(token => this._provider.provideDocumentHighlights(doc, pos, token)).then(value => { if (Array.isArray(value)) { return value.map(OccurrencesAdapter._convertDocumentHighlight); } }); } private static _convertDocumentHighlight(documentHighlight: vscode.DocumentHighlight): modes.IOccurence { return { range: TypeConverters.fromRange(documentHighlight.range), kind: DocumentHighlightKind[documentHighlight.kind].toString().toLowerCase() } } } class ReferenceAdapter implements modes.IReferenceSupport { private _documents: PluginHostModelService; private _provider: vscode.ReferenceProvider; constructor(documents: PluginHostModelService, provider: vscode.ReferenceProvider) { this._documents = documents; this._provider = provider; } canFindReferences():boolean { return true } findReferences(resource: URI, position: IPosition, includeDeclaration: boolean): TPromise { let doc = this._documents.getDocument(resource); let pos = TypeConverters.toPosition(position); return asWinJsPromise(token => this._provider.provideReferences(doc, pos, { includeDeclaration }, token)).then(value => { if (Array.isArray(value)) { return value.map(ReferenceAdapter._convertLocation); } }); } private static _convertLocation(location: vscode.Location): modes.IReference { return { resource: location.uri, range: TypeConverters.fromRange(location.range) }; } } class QuickFixAdapter implements modes.IQuickFixSupport { private _documents: PluginHostModelService; private _commands: PluginHostCommands; private _provider: vscode.CodeActionProvider; private _cache: { [key: string]: vscode.Command[] } = Object.create(null); constructor(documents: PluginHostModelService, commands: PluginHostCommands, provider: vscode.CodeActionProvider) { this._documents = documents; this._commands = commands; this._provider = provider; } getQuickFixes(resource: URI, range: IRange, marker?: IMarker[]): TPromise { // return this._executeCommand(resource, range, markers); const key = resource.toString(); delete this._cache[key]; const doc = this._documents.getDocument(resource); const ran = TypeConverters.toRange(range); const diagnostics = marker.map(marker => { const diag = new Diagnostic(TypeConverters.toRange(marker), marker.message); diag.code = marker.code; diag.severity = TypeConverters.toDiagnosticSeverty(marker.severity); return diag; }); return asWinJsPromise(token => this._provider.provideCodeActions(doc, ran, { diagnostics: diagnostics }, token)).then(commands => { if (!Array.isArray(commands)) { return; } this._cache[key] = commands; return commands.map((command, i) => { return { id: String(i), label: command.title, score: 1 }; }); }); } runQuickFixAction(resource: URI, range: IRange, id: string): any { let commands = this._cache[resource.toString()]; if (!commands) { return TPromise.wrapError('no command for ' + resource.toString()); } let command = commands[Number(id)]; if (!command) { return TPromise.wrapError('no command for ' + resource.toString()); } return this._commands.executeCommand(command.command, ...command.arguments); } } class DocumentFormattingAdapter implements modes.IFormattingSupport { private _documents: PluginHostModelService; private _provider: vscode.DocumentFormattingEditProvider; constructor(documents: PluginHostModelService, provider: vscode.DocumentFormattingEditProvider) { this._documents = documents; this._provider = provider; } formatDocument(resource: URI, options: modes.IFormattingOptions): TPromise { let doc = this._documents.getDocument(resource); return asWinJsPromise(token => this._provider.provideDocumentFormattingEdits(doc, options, token)).then(value => { if (Array.isArray(value)) { return value.map(TypeConverters.fromTextEdit); } }); } } class RangeFormattingAdapter implements modes.IFormattingSupport { private _documents: PluginHostModelService; private _provider: vscode.DocumentRangeFormattingEditProvider; constructor(documents: PluginHostModelService, provider: vscode.DocumentRangeFormattingEditProvider) { this._documents = documents; this._provider = provider; } formatRange(resource: URI, range: IRange, options: modes.IFormattingOptions): TPromise { let doc = this._documents.getDocument(resource); let ran = TypeConverters.toRange(range); return asWinJsPromise(token => this._provider.provideDocumentRangeFormattingEdits(doc, ran, options, token)).then(value => { if (Array.isArray(value)) { return value.map(TypeConverters.fromTextEdit); } }); } } class OnTypeFormattingAdapter implements modes.IFormattingSupport { private _documents: PluginHostModelService; private _provider: vscode.OnTypeFormattingEditProvider; constructor(documents: PluginHostModelService, provider: vscode.OnTypeFormattingEditProvider) { this._documents = documents; this._provider = provider; } autoFormatTriggerCharacters = []; // not here formatAfterKeystroke(resource: URI, position: IPosition, ch: string, options: modes.IFormattingOptions): TPromise { let doc = this._documents.getDocument(resource); let pos = TypeConverters.toPosition(position); return asWinJsPromise(token => this._provider.provideOnTypeFormattingEdits(doc, pos, ch, options, token)).then(value => { if (Array.isArray(value)) { return value.map(TypeConverters.fromTextEdit); } }); } } class NavigateTypeAdapter implements INavigateTypesSupport { private _provider: vscode.WorkspaceSymbolProvider; constructor(provider: vscode.WorkspaceSymbolProvider) { this._provider = provider; } getNavigateToItems(search: string): TPromise { return asWinJsPromise(token => this._provider.provideWorkspaceSymbols(search, token)).then(value => { if (Array.isArray(value)) { return value.map(NavigateTypeAdapter._fromSymbolInformation); } }); } private static _fromSymbolInformation(info: vscode.SymbolInformation): ITypeBearing { return { name: info.name, type: SymbolKind[info.kind || SymbolKind.Property].toLowerCase(), range: TypeConverters.fromRange(info.location.range), resourceUri: info.location.uri, containerName: info.containerName, parameters: '', }; } } type Adapter = OutlineAdapter | CodeLensAdapter | DeclarationAdapter | ExtraInfoAdapter | OccurrencesAdapter | ReferenceAdapter | QuickFixAdapter | DocumentFormattingAdapter | RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter; @Remotable.PluginHostContext('ExtHostLanguageFeatures') export class ExtHostLanguageFeatures { private static _handlePool = 0; private _proxy: MainThreadLanguageFeatures; private _documents: PluginHostModelService; private _commands: PluginHostCommands; private _adapter: { [handle: number]: Adapter } = Object.create(null); constructor( @IThreadService threadService: IThreadService) { this._proxy = threadService.getRemotable(MainThreadLanguageFeatures); this._documents = threadService.getRemotable(PluginHostModelService); this._commands = threadService.getRemotable(PluginHostCommands); } private _createDisposable(handle: number): Disposable { return new Disposable(() => { delete this._adapter[handle]; this._proxy.$unregister(handle); }); } private _nextHandle(): number { return ExtHostLanguageFeatures._handlePool++; } private _withAdapter(handle: number, ctor: { new (...args: any[]): A }, callback: (adapter: A) => TPromise): TPromise { let adapter = this._adapter[handle]; if (!(adapter instanceof ctor)) { return TPromise.wrapError(new Error('no adapter found')); } return callback( adapter); } // --- outline registerDocumentSymbolProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentSymbolProvider): vscode.Disposable { const handle = this._nextHandle(); this._adapter[handle] = new OutlineAdapter(this._documents, provider); this._proxy.$registerOutlineSupport(handle, selector); return this._createDisposable(handle); } $getOutline(handle: number, resource: URI): TPromise{ return this._withAdapter(handle, OutlineAdapter, adapter => adapter.getOutline(resource)); } // --- code lens registerCodeLensProvider(selector: vscode.DocumentSelector, provider: vscode.CodeLensProvider): vscode.Disposable { const handle = this._nextHandle(); this._adapter[handle] = new CodeLensAdapter(this._documents, provider); this._proxy.$registerCodeLensSupport(handle, selector); return this._createDisposable(handle); } $findCodeLensSymbols(handle: number, resource: URI): TPromise { return this._withAdapter(handle, CodeLensAdapter, adapter => adapter.findCodeLensSymbols(resource)); } $resolveCodeLensSymbol(handle:number, resource: URI, symbol: modes.ICodeLensSymbol): TPromise { return this._withAdapter(handle, CodeLensAdapter, adapter => adapter.resolveCodeLensSymbol(resource, symbol)); } // --- declaration registerDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.DefinitionProvider): vscode.Disposable { const handle = this._nextHandle(); this._adapter[handle] = new DeclarationAdapter(this._documents, provider); this._proxy.$registerDeclaractionSupport(handle, selector); return this._createDisposable(handle); } $findDeclaration(handle: number, resource: URI, position: IPosition): TPromise { return this._withAdapter(handle, DeclarationAdapter, adapter => adapter.findDeclaration(resource, position)); } // --- extra info registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable { const handle = this._nextHandle(); this._adapter[handle] = new ExtraInfoAdapter(this._documents, provider); this._proxy.$registerExtraInfoSupport(handle, selector); return this._createDisposable(handle); } $computeInfo(handle:number, resource: URI, position: IPosition): TPromise { return this._withAdapter(handle, ExtraInfoAdapter, adpater => adpater.computeInfo(resource, position)); } // --- occurrences registerDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable { const handle = this._nextHandle(); this._adapter[handle] = new OccurrencesAdapter(this._documents, provider); this._proxy.$registerOccurrencesSupport(handle, selector); return this._createDisposable(handle); } $findOccurrences(handle:number, resource: URI, position: IPosition): TPromise { return this._withAdapter(handle, OccurrencesAdapter, adapter => adapter.findOccurrences(resource, position)); } // --- references registerReferenceProvider(selector: vscode.DocumentSelector, provider: vscode.ReferenceProvider): vscode.Disposable { const handle = this._nextHandle(); this._adapter[handle] = new ReferenceAdapter(this._documents, provider); this._proxy.$registerReferenceSupport(handle, selector); return this._createDisposable(handle); } $findReferences(handle: number, resource: URI, position: IPosition, includeDeclaration: boolean): TPromise { return this._withAdapter(handle, ReferenceAdapter, adapter => adapter.findReferences(resource, position, includeDeclaration)); } // --- quick fix registerCodeActionProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider): vscode.Disposable { const handle = this._nextHandle(); this._adapter[handle] = new QuickFixAdapter(this._documents, this._commands, provider); this._proxy.$registerQuickFixSupport(handle, selector); return this._createDisposable(handle); } $getQuickFixes(handle:number, resource: URI, range: IRange, marker: IMarker[]): TPromise { return this._withAdapter(handle, QuickFixAdapter, adapter => adapter.getQuickFixes(resource, range, marker)); } $runQuickFixAction(handle: number, resource: URI, range: IRange, id: string): any { return this._withAdapter(handle, QuickFixAdapter, adapter => adapter.runQuickFixAction(resource, range, id)); } // --- formatting registerDocumentFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentFormattingEditProvider): vscode.Disposable { const handle = this._nextHandle(); this._adapter[handle] = new DocumentFormattingAdapter(this._documents, provider); this._proxy.$registerDocumentFormattingSupport(handle, selector); return this._createDisposable(handle); } $formatDocument(handle: number, resource: URI, options: modes.IFormattingOptions): TPromise{ return this._withAdapter(handle, DocumentFormattingAdapter, adapter => adapter.formatDocument(resource, options)); } registerDocumentRangeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentRangeFormattingEditProvider): vscode.Disposable { const handle = this._nextHandle(); this._adapter[handle] = new RangeFormattingAdapter(this._documents, provider); this._proxy.$registerRangeFormattingSupport(handle, selector); return this._createDisposable(handle); } $formatRange(handle: number, resource: URI, range: IRange, options: modes.IFormattingOptions): TPromise{ return this._withAdapter(handle, RangeFormattingAdapter, adapter => adapter.formatRange(resource, range, options)); } registerOnTypeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.OnTypeFormattingEditProvider, triggerCharacters: string[]): vscode.Disposable { const handle = this._nextHandle(); this._adapter[handle] = new OnTypeFormattingAdapter(this._documents, provider); this._proxy.$registerOnTypeFormattingSupport(handle, selector, triggerCharacters); return this._createDisposable(handle); } $formatAfterKeystroke(handle: number, resource: URI, position: IPosition, ch: string, options: modes.IFormattingOptions): TPromise{ return this._withAdapter(handle, OnTypeFormattingAdapter, adapter => adapter.formatAfterKeystroke(resource, position, ch, options)); } // --- navigate types registerWorkspaceSymbolProvider(provider: vscode.WorkspaceSymbolProvider): vscode.Disposable { const handle = this._nextHandle(); this._adapter[handle] = new NavigateTypeAdapter(provider); this._proxy.$registerNavigateTypeSupport(handle); return this._createDisposable(handle); } $getNavigateToItems(handle: number, search: string): TPromise { return this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.getNavigateToItems(search)); } } @Remotable.MainContext('MainThreadLanguageFeatures') export class MainThreadLanguageFeatures { private _proxy: ExtHostLanguageFeatures; private _markerService: IMarkerService; private _registrations: { [handle: number]: IDisposable; } = Object.create(null); constructor( @IThreadService threadService: IThreadService, @IMarkerService markerService: IMarkerService) { this._proxy = threadService.getRemotable(ExtHostLanguageFeatures); this._markerService = markerService; } $unregister(handle: number): TPromise { let registration = this._registrations[handle]; if (registration) { registration.dispose(); delete this._registrations[handle]; } return undefined; } // --- outline $registerOutlineSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = OutlineRegistry.register(selector, { getOutline: (resource: URI): TPromise => { return this._proxy.$getOutline(handle, resource); } }); return undefined; } // --- code lens $registerCodeLensSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = CodeLensRegistry.register(selector, { findCodeLensSymbols: (resource: URI): TPromise => { return this._proxy.$findCodeLensSymbols(handle, resource); }, resolveCodeLensSymbol: (resource: URI, symbol: modes.ICodeLensSymbol): TPromise => { return this._proxy.$resolveCodeLensSymbol(handle, resource, symbol); } }); return undefined; } // --- declaration $registerDeclaractionSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = DeclarationRegistry.register(selector, { canFindDeclaration() { return true; }, findDeclaration: (resource: URI, position: IPosition): TPromise => { return this._proxy.$findDeclaration(handle, resource, position); } }); return undefined; } // --- extra info $registerExtraInfoSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = ExtraInfoRegistry.register(selector, { computeInfo: (resource: URI, position: IPosition): TPromise => { return this._proxy.$computeInfo(handle, resource, position); } }); return undefined; } // --- occurrences $registerOccurrencesSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = OccurrencesRegistry.register(selector, { findOccurrences: (resource: URI, position: IPosition): TPromise => { return this._proxy.$findOccurrences(handle, resource, position); } }); return undefined; } // --- references $registerReferenceSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = ReferenceRegistry.register(selector, { canFindReferences() { return true; }, findReferences: (resource: URI, position: IPosition, includeDeclaration: boolean): TPromise => { return this._proxy.$findReferences(handle, resource, position, includeDeclaration); } }); return undefined; } // --- quick fix $registerQuickFixSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = QuickFixRegistry.register(selector, { getQuickFixes: (resource: URI, range: IRange): TPromise => { let markers: IMarker[] = []; this._markerService.read({ resource }).forEach(marker => { if (EditorRange.lift(marker).intersectRanges(range)) { markers.push(marker); } }); return this._proxy.$getQuickFixes(handle, resource, range, markers); }, runQuickFixAction: (resource: URI, range: IRange, id: string) => { return this._proxy.$runQuickFixAction(handle, resource, range, id); } }); return undefined; } // --- formatting $registerDocumentFormattingSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = FormatRegistry.register(selector, { formatDocument: (resource: URI, options: modes.IFormattingOptions): TPromise => { return this._proxy.$formatDocument(handle, resource, options); } }); return undefined; } $registerRangeFormattingSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = FormatRegistry.register(selector, { formatRange: (resource: URI, range: IRange, options: modes.IFormattingOptions): TPromise => { return this._proxy.$formatRange(handle, resource, range, options); } }); return undefined; } $registerOnTypeFormattingSupport(handle: number, selector: vscode.DocumentSelector, autoFormatTriggerCharacters: string[]): TPromise { this._registrations[handle] = FormatOnTypeRegistry.register(selector, { autoFormatTriggerCharacters, formatAfterKeystroke: (resource: URI, position: IPosition, ch: string, options: modes.IFormattingOptions): TPromise => { return this._proxy.$formatAfterKeystroke(handle, resource, position, ch, options); } }); return undefined; } // --- navigate type $registerNavigateTypeSupport(handle: number): TPromise { this._registrations[handle] = NavigateTypesSupportRegistry.register({ getNavigateToItems: (search: string): TPromise => { return this._proxy.$getNavigateToItems(handle, search); } }); return undefined; } }