From c0278341edcb6d831d24b5da3e854c6189829b12 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 15 Jan 2018 17:36:00 -0800 Subject: [PATCH] link detection for remote file systems, #41482 --- src/vs/workbench/api/node/extHost.api.impl.ts | 42 ++++++++-------- .../workbench/api/node/extHostFileSystem.ts | 49 ++++++++++++++++++- 2 files changed, 69 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 54deff05595..4d6eb312357 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -106,8 +106,8 @@ export function createApiFactory( const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(rpcProtocol, extHostWorkspace)); rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration); const extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol)); - const languageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, extHostDocuments, extHostCommands, extHostHeapService, extHostDiagnostics)); - const extHostFileSystem = rpcProtocol.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(rpcProtocol)); + const extHostLanguageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, extHostDocuments, extHostCommands, extHostHeapService, extHostDiagnostics)); + const extHostFileSystem = rpcProtocol.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(rpcProtocol, extHostLanguageFeatures)); const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService()); const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands)); const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol)); @@ -236,61 +236,61 @@ export function createApiFactory( return score(toLanguageSelector(selector), document.uri, document.languageId); }, registerCodeActionsProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider): vscode.Disposable { - return languageFeatures.registerCodeActionProvider(selector, provider); + return extHostLanguageFeatures.registerCodeActionProvider(selector, provider); }, registerCodeLensProvider(selector: vscode.DocumentSelector, provider: vscode.CodeLensProvider): vscode.Disposable { - return languageFeatures.registerCodeLensProvider(selector, provider); + return extHostLanguageFeatures.registerCodeLensProvider(selector, provider); }, registerDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.DefinitionProvider): vscode.Disposable { - return languageFeatures.registerDefinitionProvider(selector, provider); + return extHostLanguageFeatures.registerDefinitionProvider(selector, provider); }, registerImplementationProvider(selector: vscode.DocumentSelector, provider: vscode.ImplementationProvider): vscode.Disposable { - return languageFeatures.registerImplementationProvider(selector, provider); + return extHostLanguageFeatures.registerImplementationProvider(selector, provider); }, registerTypeDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.TypeDefinitionProvider): vscode.Disposable { - return languageFeatures.registerTypeDefinitionProvider(selector, provider); + return extHostLanguageFeatures.registerTypeDefinitionProvider(selector, provider); }, registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable { - return languageFeatures.registerHoverProvider(selector, provider, extension.id); + return extHostLanguageFeatures.registerHoverProvider(selector, provider, extension.id); }, registerDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable { - return languageFeatures.registerDocumentHighlightProvider(selector, provider); + return extHostLanguageFeatures.registerDocumentHighlightProvider(selector, provider); }, registerReferenceProvider(selector: vscode.DocumentSelector, provider: vscode.ReferenceProvider): vscode.Disposable { - return languageFeatures.registerReferenceProvider(selector, provider); + return extHostLanguageFeatures.registerReferenceProvider(selector, provider); }, registerRenameProvider(selector: vscode.DocumentSelector, provider: vscode.RenameProvider): vscode.Disposable { - return languageFeatures.registerRenameProvider(selector, provider); + return extHostLanguageFeatures.registerRenameProvider(selector, provider); }, registerDocumentSymbolProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentSymbolProvider): vscode.Disposable { - return languageFeatures.registerDocumentSymbolProvider(selector, provider); + return extHostLanguageFeatures.registerDocumentSymbolProvider(selector, provider); }, registerWorkspaceSymbolProvider(provider: vscode.WorkspaceSymbolProvider): vscode.Disposable { - return languageFeatures.registerWorkspaceSymbolProvider(provider); + return extHostLanguageFeatures.registerWorkspaceSymbolProvider(provider); }, registerDocumentFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentFormattingEditProvider): vscode.Disposable { - return languageFeatures.registerDocumentFormattingEditProvider(selector, provider); + return extHostLanguageFeatures.registerDocumentFormattingEditProvider(selector, provider); }, registerDocumentRangeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentRangeFormattingEditProvider): vscode.Disposable { - return languageFeatures.registerDocumentRangeFormattingEditProvider(selector, provider); + return extHostLanguageFeatures.registerDocumentRangeFormattingEditProvider(selector, provider); }, registerOnTypeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.OnTypeFormattingEditProvider, firstTriggerCharacter: string, ...moreTriggerCharacters: string[]): vscode.Disposable { - return languageFeatures.registerOnTypeFormattingEditProvider(selector, provider, [firstTriggerCharacter].concat(moreTriggerCharacters)); + return extHostLanguageFeatures.registerOnTypeFormattingEditProvider(selector, provider, [firstTriggerCharacter].concat(moreTriggerCharacters)); }, registerSignatureHelpProvider(selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, ...triggerCharacters: string[]): vscode.Disposable { - return languageFeatures.registerSignatureHelpProvider(selector, provider, triggerCharacters); + return extHostLanguageFeatures.registerSignatureHelpProvider(selector, provider, triggerCharacters); }, registerCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, ...triggerCharacters: string[]): vscode.Disposable { - return languageFeatures.registerCompletionItemProvider(selector, provider, triggerCharacters); + return extHostLanguageFeatures.registerCompletionItemProvider(selector, provider, triggerCharacters); }, registerDocumentLinkProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentLinkProvider): vscode.Disposable { - return languageFeatures.registerDocumentLinkProvider(selector, provider); + return extHostLanguageFeatures.registerDocumentLinkProvider(selector, provider); }, registerColorProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentColorProvider): vscode.Disposable { - return languageFeatures.registerColorProvider(selector, provider); + return extHostLanguageFeatures.registerColorProvider(selector, provider); }, setLanguageConfiguration: (language: string, configuration: vscode.LanguageConfiguration): vscode.Disposable => { - return languageFeatures.setLanguageConfiguration(language, configuration); + return extHostLanguageFeatures.setLanguageConfiguration(language, configuration); } }; diff --git a/src/vs/workbench/api/node/extHostFileSystem.ts b/src/vs/workbench/api/node/extHostFileSystem.ts index c89a461d1cc..62dbf9b67fe 100644 --- a/src/vs/workbench/api/node/extHostFileSystem.ts +++ b/src/vs/workbench/api/node/extHostFileSystem.ts @@ -12,19 +12,65 @@ import { IStat } from 'vs/platform/files/common/files'; import { IDisposable } from 'vs/base/common/lifecycle'; import { asWinJsPromise } from 'vs/base/common/async'; import { IPatternInfo } from 'vs/platform/search/common/search'; +import { values } from 'vs/base/common/map'; +import { Range } from 'vs/workbench/api/node/extHostTypes'; +import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures'; + +class FsLinkProvider implements vscode.DocumentLinkProvider { + + private _schemes = new Set(); + private _regex: RegExp; + + add(scheme: string): void { + this._regex = undefined; + this._schemes.add(scheme); + } + + delete(scheme: string): void { + if (this._schemes.delete(scheme)) { + this._regex = undefined; + } + } + + provideDocumentLinks(document: vscode.TextDocument, token: vscode.CancellationToken): vscode.ProviderResult { + if (this._schemes.size === 0) { + return undefined; + } + if (!this._regex) { + this._regex = new RegExp(`(${(values(this._schemes).join('|'))}):[^\\s]+`, 'gi'); + } + let result: vscode.DocumentLink[] = []; + let max = Math.min(document.lineCount, 2500); + for (let line = 0; line < max; line++) { + this._regex.lastIndex = 0; + let textLine = document.lineAt(line); + let m: RegExpMatchArray; + while (m = this._regex.exec(textLine.text)) { + const target = URI.parse(m[0]); + const range = new Range(line, this._regex.lastIndex - m[0].length, line, this._regex.lastIndex); + result.push({ target, range }); + } + } + return result; + } +} export class ExtHostFileSystem implements ExtHostFileSystemShape { private readonly _proxy: MainThreadFileSystemShape; private readonly _provider = new Map(); + private readonly _linkProvider = new FsLinkProvider(); + private _handlePool: number = 0; - constructor(mainContext: IMainContext) { + constructor(mainContext: IMainContext, extHostLanguageFeatures: ExtHostLanguageFeatures) { this._proxy = mainContext.getProxy(MainContext.MainThreadFileSystem); + extHostLanguageFeatures.registerDocumentLinkProvider('*', this._linkProvider); } registerFileSystemProvider(scheme: string, provider: vscode.FileSystemProvider) { const handle = this._handlePool++; + this._linkProvider.add(scheme); this._provider.set(handle, provider); this._proxy.$registerFileSystemProvider(handle, scheme); if (provider.root) { @@ -40,6 +86,7 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { if (reg) { reg.dispose(); } + this._linkProvider.delete(scheme); this._provider.delete(handle); this._proxy.$unregisterFileSystemProvider(handle); } -- GitLab