diff --git a/README.md b/README.md index ab556ac..0d7a1b4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![npm version](https://badge.fury.io/js/codemirror-languageserver.svg)](https://www.npmjs.com/package/codemirror-languageserver) -This plugin enables code completion, hover tooltips, and linter functionality by connecting a CodeMirror 6 editor with a language server over WebSocket. +This plugin enables code completion, hover tooltips, and linter functionality by connecting a CodeMirror 6 editor with a language server over WebSocket or any compatible transport. [How It Works](https://hjr265.me/blog/codemirror-lsp/) @@ -12,35 +12,91 @@ This plugin enables code completion, hover tooltips, and linter functionality by npm i codemirror-languageserver ``` +### WebSockets transport ``` js import { languageServer } from 'codemirror-languageserver'; -const transport = new WebSocketTransport(serverUri) - -var ls = languageServer({ - // WebSocket server uri and other client options. - serverUri, +const lsPlugin = languageServer({ + serverUri, // WebSocket server uri. rootUri: 'file:///', - - // Alternatively, to share the same client across multiple instances of this plugin. - client: new LanguageServerClient({ - serverUri, - rootUri: 'file:///' - }), - documentUri: `file:///${filename}`, languageId: 'cpp' // As defined at https://microsoft.github.io/language-server-protocol/specification#textDocumentItem. }); -var view = new EditorView({ +const view = new EditorView({ + state: EditorState.create({ + extensions: [ + // ... + lsPlugin, + // ... + ] + }) +}); +``` + +### Re using the same client +``` js +import { languageServer } from 'codemirror-languageserver'; + +const client = new LanguageServerClient({ + transport: new WebSocketTransport(serverUri), + rootUri: 'file:///' +}) + +const firstView = new EditorView({ + state: EditorState.create({ + extensions: [ + // ... + languageServerWithClient({ + client, + documentUri: `file:///${secondFileName}`, + languageId: 'cpp' + }), + // ... + ] + }) +}); + +const secondView = new EditorView({ + state: EditorState.create({ + extensions: [ + // ... + languageServerWithClient({ + client, + documentUri: `file:///${firstFileName}`, + languageId: 'cpp' + }), + // ... + ] + }) +}); +``` + +### Custom transport +``` js +import { languageServer } from 'codemirror-languageserver'; + +const client = new LanguageServerClient({ + transport: new AwesomeCustomTransport(), + rootUri: 'file:///' +}) + +const lsPlugin = languageServerWithClient({ + client, + documentUri: `file:///${filename}`, + languageId: 'cpp' +}) + +const view = new EditorView({ state: EditorState.create({ extensions: [ // ... - ls, + lsPlugin, // ... ] }) }); + ``` ## Contributing diff --git a/src/index.ts b/src/index.ts index 8c0ba0e..2bda578 100644 --- a/src/index.ts +++ b/src/index.ts @@ -456,40 +456,43 @@ class LanguageServerPlugin implements PluginValue { } } -interface LanguageServerBaseOptions { - rootUri: string | null; - workspaceFolders: LSP.WorkspaceFolder[] | null; - documentUri: string; - languageId: string; +type ServerUri = `ws://${string}` | `wss://${string}`; +interface LanguageServerOptions { + rootUri?: string; + workspaceFolders?: LSP.WorkspaceFolder[]; } - -interface LanguageServerClientOptions extends LanguageServerBaseOptions { - transport: Transport, +interface LanguageServerClientOptions extends LanguageServerOptions { + transport?: Transport; autoClose?: boolean; } - -interface LanguageServerOptions extends LanguageServerClientOptions { - client?: LanguageServerClient; +interface LanguageServerWithClientOptions { + documentUri: string; + client: LanguageServerClient; + languageId: string; } - -interface LanguageServerWebsocketOptions extends LanguageServerBaseOptions { - serverUri: `ws://${string}` | `wss://${string}`; +interface LanguageServerWebsocketOptions extends LanguageServerOptions { + documentUri: string; + serverUri: ServerUri; + languageId: string; } export function languageServer(options: LanguageServerWebsocketOptions){ const serverUri = options.serverUri; delete options.serverUri; - return languageServerWithTransport({ + return languageServerWithClient({ ...options, - transport: new WebSocketTransport(serverUri) + client: new LanguageServerClient({ + ...options, + transport: new WebSocketTransport(serverUri) + }) }) } -export function languageServerWithTransport(options: LanguageServerOptions) { +export function languageServerWithClient(options: LanguageServerWithClientOptions) { let plugin: LanguageServerPlugin | null = null; return [ - client.of(options.client || new LanguageServerClient({...options, autoClose: true})), + client.of(options.client), documentUri.of(options.documentUri), languageId.of(options.languageId), ViewPlugin.define((view) => (plugin = new LanguageServerPlugin(view))),