codemirror-languageserver 1.18.1 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![npm version](https://badge.fury.io/js/codemirror-languageserver.svg)](https://www.npmjs.com/package/codemirror-languageserver)
4
4
 
5
- This plugin enables code completion, hover tooltips, and linter functionality by connecting a CodeMirror 6 editor with a language server over WebSocket.
5
+ This plugin connects a [CodeMirror 6](https://codemirror.net/) editor with a [Language Server](https://microsoft.github.io/language-server-protocol/) over WebSocket, providing IDE-like features in the browser.
6
6
 
7
7
  [How It Works](https://hjr265.me/blog/codemirror-lsp/)
8
8
 
@@ -14,54 +14,229 @@ https://user-images.githubusercontent.com/348107/120141150-c6bb9180-c1fd-11eb-8a
14
14
  - 📚 Hover Documentation
15
15
  - 🩺 Diagnostics
16
16
  - 🔍 Go to Definition, Declaration, and Type Definition
17
+ - 🔦 Document Highlight
18
+ - 🎨 Document Formatting and Range Formatting
19
+ - ✏️ Rename Symbol
17
20
 
18
- ## Usage
21
+ ## Installation
19
22
 
20
23
  ```
21
24
  npm i codemirror-languageserver
22
25
  ```
23
26
 
27
+ **Peer dependencies:** This package requires `@codemirror/autocomplete`, `@codemirror/lint`, `@codemirror/state`, and `@codemirror/view` as peer dependencies. If you're using CodeMirror 6, you likely already have these installed.
28
+
29
+ ## Quick Start
30
+
24
31
  ```js
32
+ import { EditorState } from '@codemirror/state';
33
+ import { EditorView } from '@codemirror/view';
25
34
  import { languageServer } from 'codemirror-languageserver';
26
35
 
27
- const transport = new WebSocketTransport(serverUri);
28
-
29
- var ls = languageServer({
30
- // WebSocket server uri and other client options.
31
- serverUri,
36
+ const ls = languageServer({
37
+ serverUri: 'ws://localhost:8080',
32
38
  rootUri: 'file:///',
33
-
34
- // Alternatively, to share the same client across multiple instances of this plugin.
35
- client: new LanguageServerClient({
36
- serverUri,
37
- rootUri: 'file:///',
38
- }),
39
-
40
39
  documentUri: `file:///${filename}`,
41
40
  languageId: 'cpp', // As defined at https://microsoft.github.io/language-server-protocol/specification#textDocumentItem.
42
41
  });
43
42
 
44
- var view = new EditorView({
43
+ const view = new EditorView({
45
44
  state: EditorState.create({
46
45
  extensions: [
47
- // ...
46
+ // ... other extensions
48
47
  ls,
49
- // ...
50
48
  ],
51
49
  }),
52
50
  });
53
51
  ```
54
52
 
55
- ### Using with Initialization Options
53
+ This sets up all built-in features: completion, hover, diagnostics, go-to-definition, document highlight, and rename support.
54
+
55
+ ## Options
56
+
57
+ | Option | Type | Description |
58
+ |---|---|---|
59
+ | `serverUri` | `ws://...` or `wss://...` | WebSocket server URI |
60
+ | `rootUri` | `string` | Root URI of the workspace |
61
+ | `workspaceFolders` | `WorkspaceFolder[]` | LSP workspace folders |
62
+ | `documentUri` | `string` | URI of the document being edited |
63
+ | `languageId` | `string` | Language identifier ([spec](https://microsoft.github.io/language-server-protocol/specification#textDocumentItem)) |
64
+ | `initializationOptions` | `object` | Server-specific initialization options |
65
+ | `locale` | `string` | Locale for the LSP session (e.g. `'en'`) |
66
+ | `allowHTMLContent` | `boolean` | Trust raw HTML in hover/completion content (default: `false`) |
67
+ | `synchronizationMethod` | `SynchronizationMethod` | `'full'` or `'incremental'` document sync (default: `'full'`) |
68
+ | `client` | `LanguageServerClient` | Share a client across multiple editor instances |
69
+ | `onCapabilities` | `(capabilities) => void` | Called when server capabilities are available |
70
+
71
+ ## Shared Client
72
+
73
+ To share the same language server connection across multiple editor instances:
74
+
75
+ ```js
76
+ import { LanguageServerClient, languageServerWithTransport, WebSocketTransport } from 'codemirror-languageserver';
77
+
78
+ const client = new LanguageServerClient({
79
+ transport: new WebSocketTransport('ws://localhost:8080'),
80
+ rootUri: 'file:///',
81
+ });
82
+
83
+ // Use the same client for multiple editors
84
+ const ls1 = languageServerWithTransport({
85
+ client,
86
+ documentUri: 'file:///main.cpp',
87
+ languageId: 'cpp',
88
+ });
89
+
90
+ const ls2 = languageServerWithTransport({
91
+ client,
92
+ documentUri: 'file:///utils.cpp',
93
+ languageId: 'cpp',
94
+ });
95
+ ```
96
+
97
+ ## Custom Transport
98
+
99
+ Use `languageServerWithTransport` for non-WebSocket connections:
100
+
101
+ ```js
102
+ import { languageServerWithTransport } from 'codemirror-languageserver';
103
+
104
+ const ls = languageServerWithTransport({
105
+ transport: myCustomTransport,
106
+ rootUri: 'file:///',
107
+ documentUri: `file:///${filename}`,
108
+ languageId: 'cpp',
109
+ });
110
+ ```
111
+
112
+ The `Transport` interface:
113
+
114
+ ```ts
115
+ interface Transport {
116
+ send(message: string): void;
117
+ onMessage(callback: (message: string) => void): void;
118
+ onClose(callback: () => void): void;
119
+ onError(callback: (error: Error) => void): void;
120
+ close(): void;
121
+ }
122
+ ```
56
123
 
57
- The plugin includes built-in TypeScript definitions for popular language servers:
124
+ You can import `Transport` and `WebSocketTransport` from the package.
125
+
126
+ ## Document Highlight
127
+
128
+ Enabled by default. When the cursor is on a symbol, all occurrences in the document are highlighted. Style with CSS:
129
+
130
+ ```css
131
+ .cm-lsp-highlight-text,
132
+ .cm-lsp-highlight-read { background-color: rgba(255, 255, 0, 0.2); }
133
+ .cm-lsp-highlight-write { background-color: rgba(255, 165, 0, 0.3); }
134
+ ```
58
135
 
59
- - `PyrightInitializationOptions` - Python (Pyright)
60
- - `RustAnalyzerInitializationOptions` - Rust (rust-analyzer)
61
- - `TypeScriptInitializationOptions` - TypeScript/JavaScript
62
- - `ESLintInitializationOptions` - ESLint
63
- - `ClangdInitializationOptions` - C/C++ (Clangd)
64
- - `GoplsInitializationOptions` - Go (Gopls)
136
+ The three classes correspond to [DocumentHighlightKind](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#documentHighlightKind): general text occurrences, read accesses, and write accesses.
137
+
138
+ ## Formatting
139
+
140
+ `formatDocument` and `formatSelection` are CodeMirror [commands](https://codemirror.net/docs/ref/#view.Command) — bind them to keys:
141
+
142
+ ```js
143
+ import { keymap } from '@codemirror/view';
144
+ import { formatDocument, formatSelection } from 'codemirror-languageserver';
145
+
146
+ const formattingKeymap = keymap.of([
147
+ { key: 'Shift-Alt-f', run: formatDocument },
148
+ { key: 'Ctrl-k Ctrl-f', run: formatSelection },
149
+ ]);
150
+ ```
151
+
152
+ ### Formatting Options
153
+
154
+ Configure formatting with the `formattingOptions` facet. By default, `tabSize` is read from the editor state.
155
+
156
+ ```js
157
+ import { formattingOptions } from 'codemirror-languageserver';
158
+
159
+ // In extensions:
160
+ formattingOptions.of({
161
+ tabSize: 2,
162
+ insertSpaces: true,
163
+ trimTrailingWhitespace: true,
164
+ insertFinalNewline: true,
165
+ trimFinalNewlines: true,
166
+ })
167
+ ```
168
+
169
+ ## Rename Symbol
170
+
171
+ `renameSymbol` is a CodeMirror command that opens a rename prompt at the top of the editor. If the server supports `prepareRename`, the current symbol name is used as the placeholder.
172
+
173
+ ```js
174
+ import { keymap } from '@codemirror/view';
175
+ import { renameSymbol } from 'codemirror-languageserver';
176
+
177
+ const renameKeymap = keymap.of([
178
+ { key: 'F2', run: renameSymbol },
179
+ ]);
180
+ ```
181
+
182
+ Style the panel with CSS:
183
+
184
+ ```css
185
+ .cm-lsp-rename-panel {
186
+ padding: 4px 8px;
187
+ border-bottom: 1px solid #ddd;
188
+ }
189
+ .cm-lsp-rename-input {
190
+ font-family: inherit;
191
+ font-size: inherit;
192
+ }
193
+ ```
194
+
195
+ ## Server Capabilities
196
+
197
+ Use the `onCapabilities` callback to react when the server finishes initializing — e.g. to show or hide toolbar buttons:
198
+
199
+ ```js
200
+ languageServer({
201
+ serverUri: 'ws://localhost:8080',
202
+ rootUri: 'file:///',
203
+ documentUri: `file:///${filename}`,
204
+ languageId: 'cpp',
205
+ onCapabilities(capabilities) {
206
+ // capabilities.documentFormattingProvider
207
+ // capabilities.renameProvider
208
+ // capabilities.completionProvider
209
+ // etc.
210
+ toolbar.update({ capabilities });
211
+ },
212
+ })
213
+ ```
214
+
215
+ ## Initialization Options
216
+
217
+ The package includes TypeScript definitions for popular language servers:
218
+
219
+ - `PyrightInitializationOptions` — Python (Pyright)
220
+ - `RustAnalyzerInitializationOptions` — Rust (rust-analyzer)
221
+ - `TypeScriptInitializationOptions` — TypeScript/JavaScript
222
+ - `ESLintInitializationOptions` — ESLint
223
+ - `ClangdInitializationOptions` — C/C++ (Clangd)
224
+ - `GoplsInitializationOptions` — Go (Gopls)
225
+
226
+ ```ts
227
+ import { languageServer } from 'codemirror-languageserver';
228
+ import type { ClangdInitializationOptions } from 'codemirror-languageserver';
229
+
230
+ const ls = languageServer<ClangdInitializationOptions>({
231
+ serverUri: 'ws://localhost:8080',
232
+ rootUri: 'file:///',
233
+ documentUri: 'file:///main.cpp',
234
+ languageId: 'cpp',
235
+ initializationOptions: {
236
+ // Type-checked options specific to Clangd
237
+ },
238
+ });
239
+ ```
65
240
 
66
241
  ## Contributing
67
242
 
@@ -69,7 +244,7 @@ Contributions are welcome.
69
244
 
70
245
  ## Real World Uses
71
246
 
72
- - [Toph](https://toph.co): Competitive programming platform. Toph uses Language Server Plugin for CodeMirror 6 with its integrated code editor.
247
+ - [Toph](https://toph.co): Competitive programming platform. Toph uses Language Server Plugin for CodeMirror 6 with its integrated code editor.
73
248
 
74
249
  ## License
75
250
 
@@ -1,8 +1,20 @@
1
1
  import { Command, KeyBinding } from '@codemirror/view';
2
+ /** Command: jump to the definition of the symbol at the cursor. */
2
3
  export declare const jumpToDefinition: Command;
4
+ /** Returns a command that jumps to the definition of the symbol at `pos`. */
3
5
  export declare const jumpToDefinitionPos: (pos: number) => Command;
6
+ /** Command: jump to the declaration of the symbol at the cursor. */
4
7
  export declare const jumpToDeclaration: Command;
8
+ /** Returns a command that jumps to the declaration of the symbol at `pos`. */
5
9
  export declare const jumpToDeclarationPos: (pos: number) => Command;
10
+ /** Command: jump to the type definition of the symbol at the cursor. */
6
11
  export declare const jumpToTypeDefinition: Command;
12
+ /** Returns a command that jumps to the type definition of the symbol at `pos`. */
7
13
  export declare const jumpToTypeDefinitionPos: (pos: number) => Command;
14
+ /**
15
+ * Default keymap for go-to-definition commands.
16
+ *
17
+ * - `F12` — jump to definition
18
+ * - `Mod-F12` — jump to type definition
19
+ */
8
20
  export declare const jumpToDefinitionKeymap: readonly KeyBinding[];
@@ -0,0 +1,14 @@
1
+ import { Facet } from '@codemirror/state';
2
+ import type { EditorView } from '@codemirror/view';
3
+ import type * as LSP from 'vscode-languageserver-protocol';
4
+ /**
5
+ * Facet for configuring LSP formatting options (tab size, spaces vs tabs, etc.).
6
+ *
7
+ * Defaults to `{ tabSize: 4, insertSpaces: true }`. The `tabSize` falls back
8
+ * to the editor state's `tabSize` if not explicitly set.
9
+ */
10
+ export declare const formattingOptions: Facet<LSP.FormattingOptions, LSP.FormattingOptions>;
11
+ /** Command: format the entire document using the language server. */
12
+ export declare function formatDocument(view: EditorView): boolean;
13
+ /** Command: format the current selection using the language server. */
14
+ export declare function formatSelection(view: EditorView): boolean;
@@ -0,0 +1,8 @@
1
+ import { Extension } from '@codemirror/state';
2
+ /**
3
+ * Extension that highlights all occurrences of the symbol under the cursor.
4
+ *
5
+ * Applies CSS classes `cm-lsp-highlight-text`, `cm-lsp-highlight-read`, and
6
+ * `cm-lsp-highlight-write` based on the highlight kind returned by the server.
7
+ */
8
+ export declare const documentHighlight: () => Extension;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  export { LanguageServerClient, languageServerPlugin, SynchronizationMethod, } from './plugin';
2
+ export { WebSocketTransport } from './jsonrpc';
3
+ export type { Transport } from './jsonrpc';
2
4
  export { jumpToDefinition, jumpToDefinitionPos, jumpToDefinitionKeymap, } from './definition';
5
+ export { formatDocument, formatSelection, formattingOptions, } from './formatting';
6
+ export { renameSymbol } from './rename';
3
7
  export { PyrightInitializationOptions, RustAnalyzerInitializationOptions, TypeScriptInitializationOptions, ESLintInitializationOptions, ClangdInitializationOptions, GoplsInitializationOptions, } from './initialization';
4
8
  import { LanguageServerClient, SynchronizationMethod } from './plugin';
5
9
  import type { LanguageServerClientOptions, LanguageServerBaseOptions } from './plugin';
@@ -12,5 +16,16 @@ interface LanguageServerWebsocketOptions<InitializationOptions = unknown> extend
12
16
  serverUri: `ws://${string}` | `wss://${string}`;
13
17
  initializationOptions?: InitializationOptions;
14
18
  }
15
- export declare function languageServer<InitializationOptions = unknown>(options: LanguageServerWebsocketOptions<InitializationOptions>): import("@codemirror/state").Extension[];
16
- export declare function languageServerWithTransport<InitializationOptions = unknown>(options: LanguageServerOptions<InitializationOptions>): import("@codemirror/state").Extension[];
19
+ /**
20
+ * Creates a set of CodeMirror extensions that connect to a language server over WebSocket.
21
+ *
22
+ * Includes completion, hover, diagnostics, go-to-definition, document highlight,
23
+ * and rename support. This is the main entry point for most use cases.
24
+ */
25
+ export declare function languageServer<InitializationOptions = unknown>(options: LanguageServerWebsocketOptions<InitializationOptions>): (import("@codemirror/state").Extension | import("@codemirror/state").StateField<string>)[];
26
+ /**
27
+ * Like {@link languageServer}, but accepts a custom {@link Transport} instead of a WebSocket URI.
28
+ *
29
+ * Use this when communicating with the language server over a non-WebSocket channel.
30
+ */
31
+ export declare function languageServerWithTransport<InitializationOptions = unknown>(options: LanguageServerOptions<InitializationOptions>): (import("@codemirror/state").Extension | import("@codemirror/state").StateField<string>)[];