From afaad416580476a979208d68e7a87cd8183ea3a4 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 20 May 2016 11:51:25 +0200 Subject: [PATCH] Remove IMode.linkSupport and convert to provider --- src/vs/editor/common/modes.ts | 23 +++--------- .../hover/browser/modesContentHover.ts | 4 +- src/vs/editor/contrib/hover/common/hover.ts | 4 +- src/vs/editor/contrib/links/browser/links.ts | 13 ++----- src/vs/editor/contrib/links/common/links.ts | 37 +++++++++++++++++++ .../languages/handlebars/common/handlebars.ts | 6 +++ src/vs/languages/html/common/html.ts | 14 ++++--- src/vs/languages/html/common/htmlWorker.ts | 6 +-- src/vs/languages/razor/common/razor.ts | 6 +++ .../parts/output/common/outputMode.ts | 22 ++++++----- .../parts/output/common/outputWorker.ts | 2 +- .../node/api/extHostLanguageFeatures.test.ts | 10 ++--- 12 files changed, 93 insertions(+), 54 deletions(-) create mode 100644 src/vs/editor/contrib/links/common/links.ts diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index 11e5851bd69..18a5dc7f4d1 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -211,11 +211,6 @@ export interface IMode { */ emitOutputSupport?:IEmitOutputSupport; - /** - * Optional adapter to support detecting links. - */ - linkSupport?:ILinkSupport; - /** * Optional adapter to support configuring this mode. */ @@ -584,26 +579,16 @@ export interface IEmitOutput { content:string; } -/** - * Interface used to detect links. - */ -export interface ILink { +export interface ILink { range: editorCommon.IRange; - - /** - * The url of the link. - * The url should be absolute and will not get any special treatment. - */ url: string; - - extraInlineClassName?: string; } - export interface ILinkSupport { - computeLinks(resource:URI):TPromise; + provideLinks(model: editorCommon.IReadOnlyModel, token: CancellationToken): ILink[] | Thenable; } + /** * Interface used to define a configurable editor mode. */ @@ -781,3 +766,5 @@ export const DocumentFormattingEditProviderRegistry = new LanguageFeatureRegistr export const DocumentRangeFormattingEditProviderRegistry = new LanguageFeatureRegistry(); export const OnTypeFormattingEditProviderRegistry = new LanguageFeatureRegistry(); + +export const LinksProviderRegistry = new LanguageFeatureRegistry(); diff --git a/src/vs/editor/contrib/hover/browser/modesContentHover.ts b/src/vs/editor/contrib/hover/browser/modesContentHover.ts index 47ebde79a3f..6d5b3712e01 100644 --- a/src/vs/editor/contrib/hover/browser/modesContentHover.ts +++ b/src/vs/editor/contrib/hover/browser/modesContentHover.ts @@ -16,7 +16,7 @@ import {IEditorRange, IRange} from 'vs/editor/common/editorCommon'; import {HoverProviderRegistry, Hover, IMode} from 'vs/editor/common/modes'; import {tokenizeToString} from 'vs/editor/common/modes/textToHtmlTokenizer'; import {ICodeEditor} from 'vs/editor/browser/editorBrowser'; -import {provideHover} from '../common/hover'; +import {getHover} from '../common/hover'; import {HoverOperation, IHoverComputer} from './hoverOperation'; import {ContentHoverWidget} from './hoverWidgets'; @@ -47,7 +47,7 @@ class ModesContentComputer implements IHoverComputer { return TPromise.as(null); } - return provideHover(model, new Position( + return getHover(model, new Position( this._range.startLineNumber, this._range.startColumn )); diff --git a/src/vs/editor/contrib/hover/common/hover.ts b/src/vs/editor/contrib/hover/common/hover.ts index 073117e6393..51766df859a 100644 --- a/src/vs/editor/contrib/hover/common/hover.ts +++ b/src/vs/editor/contrib/hover/common/hover.ts @@ -13,7 +13,7 @@ import {CommonEditorRegistry} from 'vs/editor/common/editorCommonExtensions'; import {Hover, HoverProviderRegistry} from 'vs/editor/common/modes'; import {asWinJsPromise} from 'vs/base/common/async'; -export function provideHover(model: IReadOnlyModel, position: IEditorPosition): TPromise { +export function getHover(model: IReadOnlyModel, position: IEditorPosition): TPromise { const supports = HoverProviderRegistry.ordered(model); const values: Hover[] = []; @@ -37,4 +37,4 @@ export function provideHover(model: IReadOnlyModel, position: IEditorPosition): return TPromise.join(promises).then(() => coalesce(values)); } -CommonEditorRegistry.registerDefaultLanguageCommand('_executeHoverProvider', provideHover); \ No newline at end of file +CommonEditorRegistry.registerDefaultLanguageCommand('_executeHoverProvider', getHover); \ No newline at end of file diff --git a/src/vs/editor/contrib/links/browser/links.ts b/src/vs/editor/contrib/links/browser/links.ts index 0b04f430229..39c4515c3e1 100644 --- a/src/vs/editor/contrib/links/browser/links.ts +++ b/src/vs/editor/contrib/links/browser/links.ts @@ -22,9 +22,10 @@ import {EditorAction} from 'vs/editor/common/editorAction'; import {Behaviour} from 'vs/editor/common/editorActionEnablement'; import * as editorCommon from 'vs/editor/common/editorCommon'; import {CommonEditorRegistry, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions'; -import {ILink} from 'vs/editor/common/modes'; +import {ILink, LinksProviderRegistry} from 'vs/editor/common/modes'; import {IEditorWorkerService} from 'vs/editor/common/services/editorWorkerService'; import {IEditorMouseEvent} from 'vs/editor/browser/editorBrowser'; +import {getLinks} from 'vs/editor/contrib/links/common/links'; class LinkOccurence { @@ -42,9 +43,6 @@ class LinkOccurence { private static _getOptions(link:ILink, isActive:boolean):editorCommon.IModelDecorationOptions { var result = ''; - if (link.extraInlineClassName) { - result = link.extraInlineClassName + ' '; - } if (isActive) { result += LinkDetector.CLASS_NAME_ACTIVE; @@ -79,12 +77,10 @@ class LinkOccurence { class Link { range: editorCommon.IEditorRange; url: string; - extraInlineClassName: string; constructor(source:ILink) { this.range = new Range(source.range.startLineNumber, source.range.startColumn, source.range.endLineNumber, source.range.endColumn); this.url = source.url; - this.extraInlineClassName = source.extraInlineClassName || null; } } @@ -165,9 +161,8 @@ class LinkDetector { } let modePromise:TPromise = TPromise.as(null); - let mode = this.editor.getModel().getMode(); - if (mode.linkSupport) { - modePromise = mode.linkSupport.computeLinks(this.editor.getModel().getAssociatedResource()); + if (LinksProviderRegistry.has(this.editor.getModel())) { + modePromise = getLinks(this.editor.getModel()); } let standardPromise:TPromise = this.editorWorkerService.computeLinks(this.editor.getModel().getAssociatedResource()); diff --git a/src/vs/editor/contrib/links/common/links.ts b/src/vs/editor/contrib/links/common/links.ts new file mode 100644 index 00000000000..f5e33b95898 --- /dev/null +++ b/src/vs/editor/contrib/links/common/links.ts @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * 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 {onUnexpectedError} from 'vs/base/common/errors'; +import {TPromise} from 'vs/base/common/winjs.base'; +import {IReadOnlyModel} from 'vs/editor/common/editorCommon'; +import {ILink, LinksProviderRegistry} from 'vs/editor/common/modes'; +import {asWinJsPromise} from 'vs/base/common/async'; + +export function getLinks(model: IReadOnlyModel): TPromise { + + const promises = LinksProviderRegistry.ordered(model).map((support) => { + return asWinJsPromise((token) => { + return support.provideLinks(model, token); + }).then((result) => { + if (Array.isArray(result)) { + return result; + } + }, err => { + onUnexpectedError(err); + }); + }); + + return TPromise.join(promises).then(manyLinks => { + let result: ILink[] = []; + for (let links of manyLinks) { + if (links) { + result = result.concat(links); + } + } + return result; + }); +} diff --git a/src/vs/languages/handlebars/common/handlebars.ts b/src/vs/languages/handlebars/common/handlebars.ts index c4cde291ed6..84531338ceb 100644 --- a/src/vs/languages/handlebars/common/handlebars.ts +++ b/src/vs/languages/handlebars/common/handlebars.ts @@ -142,6 +142,12 @@ export class HandlebarsMode extends htmlMode.HTMLMode { return wireCancellationToken(token, this._provideDocumentHighlights(model.getAssociatedResource(), position)); } }); + + modes.LinksProviderRegistry.register(this.getId(), { + provideLinks: (model, token): Thenable => { + return wireCancellationToken(token, this._provideLinks(model.getAssociatedResource())); + } + }); } protected _createRichEditSupport(): modes.IRichEditSupport { diff --git a/src/vs/languages/html/common/html.ts b/src/vs/languages/html/common/html.ts index a54d2e38db2..ca894676fef 100644 --- a/src/vs/languages/html/common/html.ts +++ b/src/vs/languages/html/common/html.ts @@ -287,7 +287,6 @@ export class HTMLMode extends AbstractMode impl public tokenizationSupport: modes.ITokenizationSupport; public richEditSupport: modes.IRichEditSupport; - public linkSupport:modes.ILinkSupport; public configSupport: modes.IConfigurationSupport; private modeService:IModeService; @@ -307,7 +306,6 @@ export class HTMLMode extends AbstractMode impl this.threadService = threadService; this.tokenizationSupport = new TokenizationSupport(this, this, true, true); - this.linkSupport = this; this.configSupport = this; this.richEditSupport = this._createRichEditSupport(); @@ -358,6 +356,12 @@ export class HTMLMode extends AbstractMode impl return wireCancellationToken(token, this._provideDocumentRangeFormattingEdits(model.getAssociatedResource(), range, options)); } }); + + modes.LinksProviderRegistry.register(this.getId(), { + provideLinks: (model, token): Thenable => { + return wireCancellationToken(token, this._provideLinks(model.getAssociatedResource())); + } + }); } protected _createModeWorkerManager(descriptor:modes.IModeDescriptor, instantiationService: IInstantiationService): ModeWorkerManager { @@ -484,9 +488,9 @@ export class HTMLMode extends AbstractMode impl return this._worker((w) => w._doConfigure(options)); } - static $computeLinks = OneWorkerAttr(HTMLMode, HTMLMode.prototype.computeLinks); - public computeLinks(resource:URI):winjs.TPromise { - return this._worker((w) => w.computeLinks(resource)); + static $_provideLinks = OneWorkerAttr(HTMLMode, HTMLMode.prototype._provideLinks); + protected _provideLinks(resource:URI):winjs.TPromise { + return this._worker((w) => w.provideLinks(resource)); } static $_provideDocumentRangeFormattingEdits = OneWorkerAttr(HTMLMode, HTMLMode.prototype._provideDocumentRangeFormattingEdits); diff --git a/src/vs/languages/html/common/htmlWorker.ts b/src/vs/languages/html/common/htmlWorker.ts index c519a3f49b9..50665096613 100644 --- a/src/vs/languages/html/common/htmlWorker.ts +++ b/src/vs/languages/html/common/htmlWorker.ts @@ -21,7 +21,7 @@ import {isTag, DELIM_END, DELIM_START, DELIM_ASSIGN, ATTRIB_NAME, ATTRIB_VALUE} import {isEmptyElement} from 'vs/languages/html/common/htmlEmptyTagsShared'; import {filterSuggestions} from 'vs/editor/common/modes/supports/suggestSupport'; import paths = require('vs/base/common/paths'); -import {provideHover} from 'vs/editor/contrib/hover/common/hover'; +import {getHover} from 'vs/editor/contrib/hover/common/hover'; import {provideReferences} from 'vs/editor/contrib/referenceSearch/common/referenceSearch'; import {provideCompletionItems} from 'vs/editor/contrib/suggest/common/suggest'; @@ -150,7 +150,7 @@ export class HTMLWorker { public provideHover(resource:URI, position:editorCommon.IPosition): winjs.TPromise { return this._delegateToModeAtPosition(resource, position, (isEmbeddedMode, model) => { if (isEmbeddedMode) { - return provideHover(model, Position.lift(position)).then((r) => { + return getHover(model, Position.lift(position)).then((r) => { return (r.length > 0 ? r[0] : null); }); } @@ -659,7 +659,7 @@ export class HTMLWorker { return newLinks; } - public computeLinks(resource: URI): winjs.TPromise { + public provideLinks(resource: URI): winjs.TPromise { let model = this.resourceService.get(resource); return winjs.TPromise.as(this._computeHTMLLinks(model)); } diff --git a/src/vs/languages/razor/common/razor.ts b/src/vs/languages/razor/common/razor.ts index b0d464ee00b..2ead75369f2 100644 --- a/src/vs/languages/razor/common/razor.ts +++ b/src/vs/languages/razor/common/razor.ts @@ -91,6 +91,12 @@ export class RAZORMode extends htmlMode.HTMLMode { return wireCancellationToken(token, this._provideDocumentHighlights(model.getAssociatedResource(), position)); } }); + + modes.LinksProviderRegistry.register(this.getId(), { + provideLinks: (model, token): Thenable => { + return wireCancellationToken(token, this._provideLinks(model.getAssociatedResource())); + } + }); } protected _createModeWorkerManager(descriptor:modes.IModeDescriptor, instantiationService: IInstantiationService): ModeWorkerManager { diff --git a/src/vs/workbench/parts/output/common/outputMode.ts b/src/vs/workbench/parts/output/common/outputMode.ts index 6f11b68355e..88acead3001 100644 --- a/src/vs/workbench/parts/output/common/outputMode.ts +++ b/src/vs/workbench/parts/output/common/outputMode.ts @@ -14,12 +14,13 @@ import {OutputWorker} from 'vs/workbench/parts/output/common/outputWorker'; import winjs = require('vs/base/common/winjs.base'); import {OneWorkerAttr} from 'vs/platform/thread/common/threadService'; import URI from 'vs/base/common/uri'; -import Modes = require('vs/editor/common/modes'); +import * as modes from 'vs/editor/common/modes'; import {IEditorWorkerService} from 'vs/editor/common/services/editorWorkerService'; import {AbstractMode, ModeWorkerManager} from 'vs/editor/common/modes/abstractMode'; import {createRichEditSupport} from 'vs/editor/common/modes/monarch/monarchDefinition'; import {createTokenizationSupport} from 'vs/editor/common/modes/monarch/monarchLexer'; import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport'; +import {wireCancellationToken} from 'vs/base/common/async'; export const language: types.ILanguage = { displayName: 'Log', @@ -47,9 +48,8 @@ export const language: types.ILanguage = { export class OutputMode extends AbstractMode { - public linkSupport:Modes.ILinkSupport; - public tokenizationSupport: Modes.ITokenizationSupport; - public richEditSupport: Modes.IRichEditSupport; + public tokenizationSupport: modes.ITokenizationSupport; + public richEditSupport: modes.IRichEditSupport; private _modeWorkerManager: ModeWorkerManager; @@ -64,19 +64,23 @@ export class OutputMode extends AbstractMode { let lexer = compile(language); this._modeWorkerManager = new ModeWorkerManager(descriptor, 'vs/workbench/parts/output/common/outputWorker', 'OutputWorker', null, instantiationService); - this.linkSupport = this; - this.tokenizationSupport = createTokenizationSupport(modeService, this, lexer); this.richEditSupport = new RichEditSupport(this.getId(), null, createRichEditSupport(lexer)); + + modes.LinksProviderRegistry.register(this.getId(), { + provideLinks: (model, token): Thenable => { + return wireCancellationToken(token, this._provideLinks(model.getAssociatedResource())); + } + }); } private _worker(runner:(worker:OutputWorker)=>winjs.TPromise): winjs.TPromise { return this._modeWorkerManager.worker(runner); } - static $computeLinks = OneWorkerAttr(OutputMode, OutputMode.prototype.computeLinks); - public computeLinks(resource:URI):winjs.TPromise { - return this._worker((w) => w.computeLinks(resource)); + static $_provideLinks = OneWorkerAttr(OutputMode, OutputMode.prototype._provideLinks); + private _provideLinks(resource:URI):winjs.TPromise { + return this._worker((w) => w.provideLinks(resource)); } } diff --git a/src/vs/workbench/parts/output/common/outputWorker.ts b/src/vs/workbench/parts/output/common/outputWorker.ts index 8dfd8d2ee13..6bebdb8a13a 100644 --- a/src/vs/workbench/parts/output/common/outputWorker.ts +++ b/src/vs/workbench/parts/output/common/outputWorker.ts @@ -44,7 +44,7 @@ export class OutputWorker { return this._contextService; } - public computeLinks(resource: URI): TPromise { + public provideLinks(resource: URI): TPromise { let links: ILink[] = []; if (!this.patterns.length) { return TPromise.as(links); diff --git a/src/vs/workbench/test/node/api/extHostLanguageFeatures.test.ts b/src/vs/workbench/test/node/api/extHostLanguageFeatures.test.ts index 9c21caf3d21..5a618f5f67e 100644 --- a/src/vs/workbench/test/node/api/extHostLanguageFeatures.test.ts +++ b/src/vs/workbench/test/node/api/extHostLanguageFeatures.test.ts @@ -26,7 +26,7 @@ import {getDocumentSymbols} from 'vs/editor/contrib/quickOpen/common/quickOpen'; import {DocumentSymbolProviderRegistry, DocumentHighlightKind} from 'vs/editor/common/modes'; import {getCodeLensData} from 'vs/editor/contrib/codelens/common/codelens'; import {getDeclarationsAtPosition} from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration'; -import {provideHover} from 'vs/editor/contrib/hover/common/hover'; +import {getHover} from 'vs/editor/contrib/hover/common/hover'; import {getOccurrencesAtPosition} from 'vs/editor/contrib/wordHighlighter/common/wordHighlighter'; import {provideReferences} from 'vs/editor/contrib/referenceSearch/common/referenceSearch'; import {getCodeActions} from 'vs/editor/contrib/quickFix/common/quickFix'; @@ -337,7 +337,7 @@ suite('ExtHostLanguageFeatures', function() { })); return threadService.sync().then(() => { - provideHover(model, new EditorPosition(1, 1)).then(value => { + getHover(model, new EditorPosition(1, 1)).then(value => { assert.equal(value.length, 1); let [entry] = value; assert.deepEqual(entry.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 5 }); @@ -356,7 +356,7 @@ suite('ExtHostLanguageFeatures', function() { return threadService.sync().then(() => { - provideHover(model, new EditorPosition(1, 1)).then(value => { + getHover(model, new EditorPosition(1, 1)).then(value => { assert.equal(value.length, 1); let [entry] = value; assert.deepEqual(entry.range, { startLineNumber: 4, startColumn: 1, endLineNumber: 9, endColumn: 8 }); @@ -380,7 +380,7 @@ suite('ExtHostLanguageFeatures', function() { })); return threadService.sync().then(() => { - return provideHover(model, new EditorPosition(1, 1)).then(value => { + return getHover(model, new EditorPosition(1, 1)).then(value => { assert.equal(value.length, 2); let [first, second] = value; assert.equal(first.htmlContent[0].markdown, 'registered second'); @@ -405,7 +405,7 @@ suite('ExtHostLanguageFeatures', function() { return threadService.sync().then(() => { - provideHover(model, new EditorPosition(1, 1)).then(value => { + getHover(model, new EditorPosition(1, 1)).then(value => { assert.equal(value.length, 1); }); -- GitLab