From 040b4ae05d7bb671002345d4884527a5d5d7dc32 Mon Sep 17 00:00:00 2001 From: Alex Butler Date: Wed, 13 Feb 2019 11:41:32 +0000 Subject: [PATCH 1/2] Use definition to indicate out-of-project files with server support --- lib/auto-languageclient.ts | 30 +++++++++++++++++++++++++++++- lib/server-manager.ts | 14 +++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/lib/auto-languageclient.ts b/lib/auto-languageclient.ts index 0b96204..65d2ac7 100644 --- a/lib/auto-languageclient.ts +++ b/lib/auto-languageclient.ts @@ -313,6 +313,12 @@ export default class AutoLanguageClient { connection, capabilities: initializeResponse.capabilities, disposable: new CompositeDisposable(), + additionalPaths: new Set(), + considerDefinitionPath: (defPath: string): void => { + if (!defPath.startsWith(projectPath)) { + newServer.additionalPaths.add(path.dirname(defPath)); + } + } }; this.postInitialization(newServer); connection.initialized(); @@ -523,13 +529,25 @@ export default class AutoLanguageClient { } this.definitions = this.definitions || new DefinitionAdapter(); - return this.definitions.getDefinition( + const queryPromise = this.definitions.getDefinition( server.connection, server.capabilities, this.getLanguageName(), editor, point, ); + + if (this.serversSupportDefinitionDestinations()) { + queryPromise.then(query => { + if (query) { + for (const def of query.definitions) { + server.considerDefinitionPath(def.path); + } + } + }); + } + + return queryPromise; } // Outline View via LS documentSymbol--------------------------------- @@ -786,6 +804,16 @@ export default class AutoLanguageClient { stderr.split('\n').filter((l) => l).forEach((line) => this.logger.warn(`stderr ${line}`)); } + /** + * Indicates that the language server can support LSP functionality for + * out of project files indicated by `textDocument/definition` responses. + * + * Default: false + */ + protected serversSupportDefinitionDestinations(): boolean { + return false; + } + private getServerAdapter( server: ActiveServer, adapter: T, ): ServerAdapters[T] | undefined { diff --git a/lib/server-manager.ts b/lib/server-manager.ts index a8a0edb..115d5b5 100644 --- a/lib/server-manager.ts +++ b/lib/server-manager.ts @@ -33,6 +33,10 @@ export interface ActiveServer { process: LanguageServerProcess; connection: ls.LanguageClientConnection; capabilities: ls.ServerCapabilities; + // Out of project directories that this server can also support. + additionalPaths: Set; + // Considers a path from `textDocument/definition` for inclusion in `additionalPaths`. + considerDefinitionPath(path: string): void; } interface RestartCounter { @@ -259,7 +263,15 @@ export class ServerManager { if (filePath == null) { return null; } - return this._normalizedProjectPaths.find((d) => filePath.startsWith(d)) || null; + + const projectPath = this._normalizedProjectPaths.find((d) => filePath.startsWith(d)); + if (projectPath) { + return projectPath; + } + + let serverWithClaim = this._activeServers + .find(s => s.additionalPaths.has(path.dirname(filePath))); + return serverWithClaim && this.normalizePath(serverWithClaim.projectPath) || null } public updateNormalizedProjectPaths(): void { From d15610584508d449f390b02fc6aa50c21362c69e Mon Sep 17 00:00:00 2001 From: Alex Butler Date: Wed, 13 Feb 2019 12:02:23 +0000 Subject: [PATCH 2/2] Fix tests after ActiveServer changes --- lib/auto-languageclient.ts | 4 ++-- lib/server-manager.ts | 6 +++--- test/adapters/autocomplete-adapter.test.ts | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/auto-languageclient.ts b/lib/auto-languageclient.ts index 65d2ac7..32b7cca 100644 --- a/lib/auto-languageclient.ts +++ b/lib/auto-languageclient.ts @@ -318,7 +318,7 @@ export default class AutoLanguageClient { if (!defPath.startsWith(projectPath)) { newServer.additionalPaths.add(path.dirname(defPath)); } - } + }, }; this.postInitialization(newServer); connection.initialized(); @@ -538,7 +538,7 @@ export default class AutoLanguageClient { ); if (this.serversSupportDefinitionDestinations()) { - queryPromise.then(query => { + queryPromise.then((query) => { if (query) { for (const def of query.definitions) { server.considerDefinitionPath(def.path); diff --git a/lib/server-manager.ts b/lib/server-manager.ts index 115d5b5..cea9dbc 100644 --- a/lib/server-manager.ts +++ b/lib/server-manager.ts @@ -269,9 +269,9 @@ export class ServerManager { return projectPath; } - let serverWithClaim = this._activeServers - .find(s => s.additionalPaths.has(path.dirname(filePath))); - return serverWithClaim && this.normalizePath(serverWithClaim.projectPath) || null + const serverWithClaim = this._activeServers + .find((s) => s.additionalPaths.has(path.dirname(filePath))); + return serverWithClaim && this.normalizePath(serverWithClaim.projectPath) || null; } public updateNormalizedProjectPaths(): void { diff --git a/test/adapters/autocomplete-adapter.test.ts b/test/adapters/autocomplete-adapter.test.ts index c1531c9..fe1d844 100644 --- a/test/adapters/autocomplete-adapter.test.ts +++ b/test/adapters/autocomplete-adapter.test.ts @@ -20,6 +20,8 @@ describe('AutoCompleteAdapter', () => { disposable: new CompositeDisposable(), process: undefined as any, projectPath: '/', + additionalPaths: new Set(), + considerDefinitionPath: (_: string): void => {}, }; }