Skip to content

Commit

Permalink
feat: add support for workspace folders
Browse files Browse the repository at this point in the history
More information
https://bit.ly/3uou37n
  • Loading branch information
aminya committed May 6, 2021
1 parent bc4cb7e commit 8320bc8
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 3 deletions.
41 changes: 41 additions & 0 deletions lib/adapters/workspace-folders-adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { LanguageClientConnection, WorkspaceFolder } from "../languageclient"
import Convert from "../convert"
import { basename } from "path"

/** Public: Adapts the window/workspaceFolders command to Atom. */
const WorkspaceFoldersAdapter = {
/** {@inheritDoc attach} */
attach,
/** {@inheritDoc getWorkspaceFolders} */
getWorkspaceFolders,
}
export default WorkspaceFoldersAdapter

/**
* Public: Attach to a {LanguageClientConnection} to fetch the current open list of workspace folders.
*
* @param connection The {LanguageClientConnection}
* @param getProjectPaths A method that returns the open atom projects. This is passed from {ServerManager.getProjectPaths}
*/
export function attach(connection: LanguageClientConnection, getProjectPaths: () => string[]): void {
connection.onWorkspaceFolders(() => getWorkspaceFolders(getProjectPaths))
}

/**
* Public: fetch the current open list of workspace folders
*
* @param getProjectPaths A method that returns the open atom projects. This is passed from {ServerManager.getProjectPaths}
* @returns A {Promise} containing an {Array} of {lsp.WorkspaceFolder[]} or {null} if only a single file is open in the tool.
*/
export async function getWorkspaceFolders(getProjectPaths: () => string[]): Promise<WorkspaceFolder[] | null> {
const projectPaths = getProjectPaths()
if (projectPaths.length === 0) {
// only a single file is open
return null
} else {
return projectPaths.map((projectPath) => ({
uri: Convert.pathToUri(projectPath),
name: basename(projectPath),
}))
}
}
11 changes: 8 additions & 3 deletions lib/auto-languageclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ import OutlineViewAdapter from "./adapters/outline-view-adapter"
import RenameAdapter from "./adapters/rename-adapter"
import SignatureHelpAdapter from "./adapters/signature-help-adapter"
import * as ShowDocumentAdapter from "./adapters/show-document-adapter"
import * as WorkspaceFoldersAdapter from "./adapters/workspace-folders-adapter"
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 { Disposable, CompositeDisposable, Point, Range, TextEditor } from "atom"
import * as ac from "atom/autocomplete-plus"
import { basename } from "path"

export { ActiveServer, LanguageClientConnection, LanguageServerProcess }
export type ConnectionType = "stdio" | "socket" | "ipc"
Expand Down Expand Up @@ -106,12 +108,13 @@ export default class AutoLanguageClient {

/** (Optional) Return the parameters used to initialize a client - you may want to extend capabilities */
protected getInitializeParams(projectPath: string, lsProcess: LanguageServerProcess): ls.InitializeParams {
const rootUri = Convert.pathToUri(projectPath)
return {
processId: lsProcess.pid,
rootPath: projectPath,
rootUri: Convert.pathToUri(projectPath),
rootUri,
locale: atom.config.get("atom-i18n.locale") || "en",
workspaceFolders: null,
workspaceFolders: [{ uri: rootUri, name: basename(projectPath) }],
// The capabilities supported.
// TODO the capabilities set to false/undefined are TODO. See {ls.ServerCapabilities} for a full list.
capabilities: {
Expand All @@ -124,7 +127,7 @@ export default class AutoLanguageClient {
changeAnnotationSupport: undefined,
resourceOperations: ["create", "rename", "delete"],
},
workspaceFolders: false,
workspaceFolders: true,
didChangeConfiguration: {
dynamicRegistration: false,
},
Expand Down Expand Up @@ -570,6 +573,8 @@ export default class AutoLanguageClient {
})

ShowDocumentAdapter.attach(server.connection)

WorkspaceFoldersAdapter.attach(server.connection, this._serverManager.getProjectPaths)
}

public shouldSyncForEditor(editor: TextEditor, projectPath: string): boolean {
Expand Down
11 changes: 11 additions & 0 deletions lib/languageclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,17 @@ export class LanguageClientConnection extends EventEmitter {
this._sendNotification(lsp.DidChangeWatchedFilesNotification.type, params)
}

/**
* Public: Register a callback for the `workspace.workspaceFolders` request. This request is sent from the server to
* Atom to fetch the current open list of workspace folders
*
* @param A Callback which returns a {Promise} containing an {Array} of {lsp.WorkspaceFolder[]} or {null} if only a
* single file is open in the tool.
*/
public onWorkspaceFolders(callback: () => Promise<lsp.WorkspaceFolder[] | null>): void {
return this._onRequest(lsp.WorkspaceFoldersRequest.type, callback)
}

/**
* Public: Register a callback for the `textDocument/publishDiagnostics` message.
*
Expand Down
4 changes: 4 additions & 0 deletions lib/server-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ export class ServerManager {
this._normalizedProjectPaths = atom.project.getDirectories().map((d) => this.normalizePath(d.getPath()))
}

public getProjectPaths(): string[] {
return this._normalizedProjectPaths
}

public normalizePath(projectPath: string): string {
return !projectPath.endsWith(path.sep) ? path.join(projectPath, path.sep) : projectPath
}
Expand Down

0 comments on commit 8320bc8

Please sign in to comment.