diff --git a/src/vs/editor/browser/services/editorWorkerService.ts b/src/vs/editor/browser/services/editorWorkerService.ts index f1ac787f8ab..48389526cff 100644 --- a/src/vs/editor/browser/services/editorWorkerService.ts +++ b/src/vs/editor/browser/services/editorWorkerService.ts @@ -25,6 +25,7 @@ import { StopWatch } from 'vs/base/common/stopwatch'; import { canceled } from 'vs/base/common/errors'; import { UnicodeHighlighterOptions } from 'vs/editor/common/services/unicodeTextModelHighlighter'; import { IEditorWorkerHost } from 'vs/editor/common/services/editorWorkerHost'; +import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; /** * Stop syncing a model to the worker if it was not needed for 1 min. @@ -59,7 +60,8 @@ export class EditorWorkerService extends Disposable implements IEditorWorkerServ @IModelService modelService: IModelService, @ITextResourceConfigurationService configurationService: ITextResourceConfigurationService, @ILogService logService: ILogService, - @ILanguageConfigurationService languageConfigurationService: ILanguageConfigurationService + @ILanguageConfigurationService languageConfigurationService: ILanguageConfigurationService, + @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService, ) { super(); this._modelService = modelService; @@ -67,7 +69,7 @@ export class EditorWorkerService extends Disposable implements IEditorWorkerServ this._logService = logService; // register default link-provider and default completions-provider - this._register(modes.LinkProviderRegistry.register({ language: '*', hasAccessToAllModels: true }, { + this._register(languageFeaturesService.linkProvider.register({ language: '*', hasAccessToAllModels: true }, { provideLinks: (model, token) => { if (!canSyncModel(this._modelService, model.uri)) { return Promise.resolve({ links: [] }); // File too large diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index d21bfd8299c..e18d2db87f0 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -1917,11 +1917,6 @@ export const LinkedEditingRangeProviderRegistry = new LanguageFeatureRegistry
  • (); -/** - * @internal - */ -export const LinkProviderRegistry = new LanguageFeatureRegistry(); - /** * @internal */ diff --git a/src/vs/editor/common/services/languageFeatures.ts b/src/vs/editor/common/services/languageFeatures.ts index 9a9cd7b2407..e3f1c87b391 100644 --- a/src/vs/editor/common/services/languageFeatures.ts +++ b/src/vs/editor/common/services/languageFeatures.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; -import { CodeLensProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentRangeFormattingEditProvider, DocumentSymbolProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages'; +import { CodeLensProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentRangeFormattingEditProvider, DocumentSymbolProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; export const ILanguageFeaturesService = createDecorator('ILanguageFeaturesService'); @@ -56,4 +56,6 @@ export interface ILanguageFeaturesService { readonly selectionRangeProvider: LanguageFeatureRegistry; readonly foldingRangeProvider: LanguageFeatureRegistry; + + readonly linkProvider: LanguageFeatureRegistry; } diff --git a/src/vs/editor/common/services/languageFeaturesService.ts b/src/vs/editor/common/services/languageFeaturesService.ts index 621837d860f..915a7b53f26 100644 --- a/src/vs/editor/common/services/languageFeaturesService.ts +++ b/src/vs/editor/common/services/languageFeaturesService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; -import { CodeLensProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentRangeFormattingEditProvider, DocumentSymbolProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages'; +import { CodeLensProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentRangeFormattingEditProvider, DocumentSymbolProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -47,6 +47,9 @@ export class LanguageFeatureService implements ILanguageFeaturesService { readonly selectionRangeProvider = new LanguageFeatureRegistry(); readonly foldingRangeProvider = new LanguageFeatureRegistry(); + + readonly linkProvider = new LanguageFeatureRegistry(); + } registerSingleton(ILanguageFeaturesService, LanguageFeatureService, true); diff --git a/src/vs/editor/contrib/links/browser/getLinks.ts b/src/vs/editor/contrib/links/browser/getLinks.ts index ebcec2a8776..09e49fea271 100644 --- a/src/vs/editor/contrib/links/browser/getLinks.ts +++ b/src/vs/editor/contrib/links/browser/getLinks.ts @@ -11,9 +11,11 @@ import { assertType } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { IRange, Range } from 'vs/editor/common/core/range'; import { ITextModel } from 'vs/editor/common/model'; -import { ILink, ILinksList, LinkProvider, LinkProviderRegistry } from 'vs/editor/common/languages'; +import { ILink, ILinksList, LinkProvider } from 'vs/editor/common/languages'; import { IModelService } from 'vs/editor/common/services/model'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; +import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; export class Link implements ILink { @@ -135,12 +137,12 @@ export class LinksList { } -export function getLinks(model: ITextModel, token: CancellationToken): Promise { +export function getLinks(providers: LanguageFeatureRegistry, model: ITextModel, token: CancellationToken): Promise { const lists: [ILinksList, LinkProvider][] = []; // ask all providers for links in parallel - const promises = LinkProviderRegistry.ordered(model).reverse().map((provider, i) => { + const promises = providers.ordered(model).reverse().map((provider, i) => { return Promise.resolve(provider.provideLinks(model, token)).then(result => { if (result) { lists[i] = [result, provider]; @@ -167,11 +169,12 @@ CommandsRegistry.registerCommand('_executeLinkProvider', async (accessor, ...arg resolveCount = 0; } + const { linkProvider } = accessor.get(ILanguageFeaturesService); const model = accessor.get(IModelService).getModel(uri); if (!model) { return []; } - const list = await getLinks(model, CancellationToken.None); + const list = await getLinks(linkProvider, model, CancellationToken.None); if (!list) { return []; } diff --git a/src/vs/editor/contrib/links/browser/links.ts b/src/vs/editor/contrib/links/browser/links.ts index 7b99eaf4597..b3ac34f4a2d 100644 --- a/src/vs/editor/contrib/links/browser/links.ts +++ b/src/vs/editor/contrib/links/browser/links.ts @@ -18,9 +18,11 @@ import { EditorAction, registerEditorAction, registerEditorContribution, Service import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { Position } from 'vs/editor/common/core/position'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; +import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; +import { LinkProvider } from 'vs/editor/common/languages'; import { IModelDecorationsChangeAccessor, IModelDeltaDecoration, TrackedRangeStickiness } from 'vs/editor/common/model'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; -import { LinkProviderRegistry } from 'vs/editor/common/languages'; +import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { ClickLinkGesture, ClickLinkKeyboardEvent, ClickLinkMouseEvent } from 'vs/editor/contrib/gotoSymbol/browser/link/clickLinkGesture'; import { getLinks, Link, LinksList } from 'vs/editor/contrib/links/browser/getLinks'; import * as nls from 'vs/nls'; @@ -123,6 +125,7 @@ export class LinkDetector implements IEditorContribution { static readonly RECOMPUTE_TIME = 1000; // ms private readonly editor: ICodeEditor; + private readonly providers: LanguageFeatureRegistry; private enabled: boolean; private readonly listenersToRemove = new DisposableStore(); private readonly timeout: async.TimeoutTimer; @@ -136,9 +139,11 @@ export class LinkDetector implements IEditorContribution { constructor( editor: ICodeEditor, @IOpenerService openerService: IOpenerService, - @INotificationService notificationService: INotificationService + @INotificationService notificationService: INotificationService, + @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService, ) { this.editor = editor; + this.providers = languageFeaturesService.linkProvider; this.openerService = openerService; this.notificationService = notificationService; @@ -175,7 +180,7 @@ export class LinkDetector implements IEditorContribution { this.listenersToRemove.add(editor.onDidChangeModelContent((e) => this.onChange())); this.listenersToRemove.add(editor.onDidChangeModel((e) => this.onModelChanged())); this.listenersToRemove.add(editor.onDidChangeModelLanguage((e) => this.onModelLanguageChanged())); - this.listenersToRemove.add(LinkProviderRegistry.onDidChange((e) => this.onModelLanguageChanged())); + this.listenersToRemove.add(this.providers.onDidChange((e) => this.onModelLanguageChanged())); this.timeout = new async.TimeoutTimer(); this.computePromise = null; @@ -208,7 +213,7 @@ export class LinkDetector implements IEditorContribution { const model = this.editor.getModel(); - if (!LinkProviderRegistry.has(model)) { + if (!this.providers.has(model)) { return; } @@ -217,7 +222,7 @@ export class LinkDetector implements IEditorContribution { this.activeLinksList = null; } - this.computePromise = async.createCancelablePromise(token => getLinks(model, token)); + this.computePromise = async.createCancelablePromise(token => getLinks(this.providers, model, token)); try { this.activeLinksList = await this.computePromise; this.updateDecorations(this.activeLinksList.links); diff --git a/src/vs/editor/contrib/suggest/test/browser/wordDistance.test.ts b/src/vs/editor/contrib/suggest/test/browser/wordDistance.test.ts index 198c4852e83..8caefe114eb 100644 --- a/src/vs/editor/contrib/suggest/test/browser/wordDistance.test.ts +++ b/src/vs/editor/contrib/suggest/test/browser/wordDistance.test.ts @@ -25,6 +25,7 @@ import { createTextModel } from 'vs/editor/test/common/testTextModel'; import { MockMode } from 'vs/editor/test/common/mocks/mockMode'; import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService'; import { NullLogService } from 'vs/platform/log/common/log'; +import { LanguageFeatureService } from 'vs/editor/common/services/languageFeaturesService'; suite('suggest, word distance', function () { @@ -67,7 +68,7 @@ suite('suggest, word distance', function () { private _worker = new EditorSimpleWorker(new class extends mock() { }, null); constructor() { - super(modelService, new class extends mock() { }, new NullLogService(), new TestLanguageConfigurationService()); + super(modelService, new class extends mock() { }, new NullLogService(), new TestLanguageConfigurationService(), new LanguageFeatureService()); this._worker.acceptNewModel({ url: model.uri.toString(), lines: model.getLinesContent(), diff --git a/src/vs/editor/standalone/browser/standaloneLanguages.ts b/src/vs/editor/standalone/browser/standaloneLanguages.ts index e27985843c5..21438c82371 100644 --- a/src/vs/editor/standalone/browser/standaloneLanguages.ts +++ b/src/vs/editor/standalone/browser/standaloneLanguages.ts @@ -558,7 +558,8 @@ export function registerOnTypeFormattingEditProvider(languageId: string, provide * Register a link provider that can find links in text. */ export function registerLinkProvider(languageId: string, provider: languages.LinkProvider): IDisposable { - return languages.LinkProviderRegistry.register(languageId, provider); + const languageFeaturesService = StandaloneServices.get(ILanguageFeaturesService); + return languageFeaturesService.linkProvider.register(languageId, provider); } /** diff --git a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts index 53c49284c82..6314475a4eb 100644 --- a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts @@ -639,7 +639,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha }); }; } - this._registrations.set(handle, modes.LinkProviderRegistry.register(selector, provider)); + this._registrations.set(handle, this._languageFeaturesService.linkProvider.register(selector, provider)); } // --- colors diff --git a/src/vs/workbench/api/test/browser/extHostLanguageFeatures.test.ts b/src/vs/workbench/api/test/browser/extHostLanguageFeatures.test.ts index f50f12352bf..1ebb4f6a3cd 100644 --- a/src/vs/workbench/api/test/browser/extHostLanguageFeatures.test.ts +++ b/src/vs/workbench/api/test/browser/extHostLanguageFeatures.test.ts @@ -1177,7 +1177,7 @@ suite('ExtHostLanguageFeatures', function () { })); await rpcProtocol.sync(); - let { links } = await getLinks(model, CancellationToken.None); + let { links } = await getLinks(languageFeaturesService.linkProvider, model, CancellationToken.None); assert.strictEqual(links.length, 1); let [first] = links; assert.strictEqual(first.url?.toString(), 'foo:bar#3'); @@ -1200,7 +1200,7 @@ suite('ExtHostLanguageFeatures', function () { })); await rpcProtocol.sync(); - let { links } = await getLinks(model, CancellationToken.None); + let { links } = await getLinks(languageFeaturesService.linkProvider, model, CancellationToken.None); assert.strictEqual(links.length, 1); let [first] = links; assert.strictEqual(first.url?.toString(), 'foo:bar#3'); diff --git a/src/vs/workbench/contrib/output/browser/outputLinkProvider.ts b/src/vs/workbench/contrib/output/browser/outputLinkProvider.ts index 148647cd5b8..eb346086655 100644 --- a/src/vs/workbench/contrib/output/browser/outputLinkProvider.ts +++ b/src/vs/workbench/contrib/output/browser/outputLinkProvider.ts @@ -6,13 +6,14 @@ import { URI } from 'vs/base/common/uri'; import { RunOnceScheduler } from 'vs/base/common/async'; import { IModelService } from 'vs/editor/common/services/model'; -import { LinkProviderRegistry, ILink } from 'vs/editor/common/languages'; +import { ILink } from 'vs/editor/common/languages'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { OUTPUT_MODE_ID, LOG_MODE_ID } from 'vs/workbench/contrib/output/common/output'; import { MonacoWebWorker, createWebWorker } from 'vs/editor/browser/services/webWorker'; import { ICreateData, OutputLinkComputer } from 'vs/workbench/contrib/output/common/outputLinkComputer'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; +import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; export class OutputLinkProvider { @@ -25,7 +26,8 @@ export class OutputLinkProvider { constructor( @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @IModelService private readonly modelService: IModelService, - @ILanguageConfigurationService private readonly languageConfigurationService: ILanguageConfigurationService + @ILanguageConfigurationService private readonly languageConfigurationService: ILanguageConfigurationService, + @ILanguageFeaturesService private readonly languageFeaturesService: ILanguageFeaturesService, ) { this.disposeWorkerScheduler = new RunOnceScheduler(() => this.disposeWorker(), OutputLinkProvider.DISPOSE_WORKER_TIME); @@ -43,7 +45,7 @@ export class OutputLinkProvider { const folders = this.contextService.getWorkspace().folders; if (folders.length > 0) { if (!this.linkProviderRegistration) { - this.linkProviderRegistration = LinkProviderRegistry.register([{ language: OUTPUT_MODE_ID, scheme: '*' }, { language: LOG_MODE_ID, scheme: '*' }], { + this.linkProviderRegistration = this.languageFeaturesService.linkProvider.register([{ language: OUTPUT_MODE_ID, scheme: '*' }, { language: LOG_MODE_ID, scheme: '*' }], { provideLinks: async model => { const links = await this.provideLinks(model.uri);