Skip to content

Commit

Permalink
feat: definitions for out-of-project files
Browse files Browse the repository at this point in the history
  • Loading branch information
alexheretic authored and aminya committed Jun 10, 2021
1 parent d3f213f commit e471c23
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 4 deletions.
51 changes: 47 additions & 4 deletions lib/auto-languageclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@ import * as Utils from "./utils"
import { Socket } from "net"
import { LanguageClientConnection } from "./languageclient"
import { ConsoleLogger, FilteredLogger, Logger } from "./logger"
import { LanguageServerProcess, ServerManager, ActiveServer } from "./server-manager.js"
import {
LanguageServerProcess,
ServerManager,
ActiveServer,
normalizePath,
considerDefinitionPath,
} from "./server-manager.js"
import { Disposable, CompositeDisposable, Point, Range, TextEditor } from "atom"
import * as ac from "atom/autocomplete-plus"
import { basename } from "path"
Expand Down Expand Up @@ -391,6 +397,7 @@ export default class AutoLanguageClient {
connection,
capabilities: initializeResponse.capabilities,
disposable: new CompositeDisposable(),
additionalPaths: new Set<string>(),
}
this.postInitialization(newServer)
connection.initialized()
Expand Down Expand Up @@ -481,10 +488,22 @@ export default class AutoLanguageClient {
/** (Optional) Finds the project path. If there is a custom logic for finding projects override this method. */
protected determineProjectPath(textEditor: TextEditor): string | null {
const filePath = textEditor.getPath()
if (filePath == null) {
// TODO can filePath be null
if (filePath === null || filePath === undefined) {
return null
}
return this._serverManager.getNormalizedProjectPaths().find((d) => filePath.startsWith(d)) || null
const projectPath = this._serverManager.getNormalizedProjectPaths().find((d) => filePath.startsWith(d))
if (projectPath !== undefined) {
return projectPath
}

const serverWithClaim = this._serverManager
.getActiveServers()
.find((server) => server.additionalPaths?.has(path.dirname(filePath)))
if (serverWithClaim !== undefined) {
return normalizePath(serverWithClaim.projectPath)
}
return null
}

/**
Expand Down Expand Up @@ -678,7 +697,21 @@ export default class AutoLanguageClient {
}

this.definitions = this.definitions || new DefinitionAdapter()
return this.definitions.getDefinition(server.connection, server.capabilities, this.getLanguageName(), editor, point)
const query = await this.definitions.getDefinition(
server.connection,
server.capabilities,
this.getLanguageName(),
editor,
point
)

if (query !== null && this.serversSupportDefinitionDestinations() && server.additionalPaths !== undefined) {
for (const def of query.definitions) {
considerDefinitionPath(server as ActiveServer & { additionalPaths: Set<string> }, def.path)
}
}

return query
}

// Outline View via LS documentSymbol---------------------------------
Expand Down Expand Up @@ -965,6 +998,16 @@ export default class AutoLanguageClient {
.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<T extends keyof ServerAdapters>(
server: ActiveServer,
adapter: T
Expand Down
9 changes: 9 additions & 0 deletions lib/server-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export interface ActiveServer {
process: LanguageServerProcess
connection: ls.LanguageClientConnection
capabilities: ls.ServerCapabilities
/** Out of project directories that this server can also support. */
additionalPaths?: Set<string>
}

interface RestartCounter {
Expand Down Expand Up @@ -343,3 +345,10 @@ export function normalizedProjectPathToWorkspaceFolder(normalizedProjectPath: st
export function normalizePath(projectPath: string): string {
return !projectPath.endsWith(path.sep) ? path.join(projectPath, path.sep) : projectPath
}

/** Considers a path from `textDocument/definition` for inclusion in `additionalPaths`. */
export function considerDefinitionPath(server: ActiveServer & { additionalPaths: Set<string> }, defPath: string): void {
if (!defPath.startsWith(server.projectPath)) {
server.additionalPaths.add(path.dirname(defPath))
}
}

0 comments on commit e471c23

Please sign in to comment.