typescript-language-server 0.6.3 → 0.7.1
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/CHANGELOG.md +76 -0
- package/README.md +216 -31
- package/lib/cli.js +4 -9
- package/lib/cli.js.map +1 -1
- package/lib/commands.d.ts +4 -1
- package/lib/commands.d.ts.map +1 -1
- package/lib/commands.js +5 -2
- package/lib/commands.js.map +1 -1
- package/lib/completion.d.ts.map +1 -1
- package/lib/completion.js +55 -29
- package/lib/completion.js.map +1 -1
- package/lib/file-lsp-server.spec.js +22 -0
- package/lib/file-lsp-server.spec.js.map +1 -1
- package/lib/lsp-connection.d.ts.map +1 -1
- package/lib/lsp-connection.js +1 -0
- package/lib/lsp-connection.js.map +1 -1
- package/lib/lsp-protocol.calls.proposed.d.ts.map +1 -1
- package/lib/lsp-protocol.calls.proposed.js.map +1 -1
- package/lib/lsp-protocol.inlayHints.proposed.d.ts +9 -0
- package/lib/lsp-protocol.inlayHints.proposed.d.ts.map +1 -1
- package/lib/lsp-server.d.ts +8 -2
- package/lib/lsp-server.d.ts.map +1 -1
- package/lib/lsp-server.js +144 -62
- package/lib/lsp-server.js.map +1 -1
- package/lib/lsp-server.spec.js +218 -8
- package/lib/lsp-server.spec.js.map +1 -1
- package/lib/organize-imports.d.ts +2 -1
- package/lib/organize-imports.d.ts.map +1 -1
- package/lib/organize-imports.js +7 -5
- package/lib/organize-imports.js.map +1 -1
- package/lib/organize-imports.spec.js +14 -7
- package/lib/organize-imports.spec.js.map +1 -1
- package/lib/protocol-translation.d.ts +7 -3
- package/lib/protocol-translation.d.ts.map +1 -1
- package/lib/protocol-translation.js +21 -10
- package/lib/protocol-translation.js.map +1 -1
- package/lib/test-utils.js +1 -1
- package/lib/test-utils.js.map +1 -1
- package/lib/ts-protocol.d.ts +11 -1
- package/lib/ts-protocol.d.ts.map +1 -1
- package/lib/ts-protocol.js.map +1 -1
- package/lib/tsp-client.d.ts +1 -0
- package/lib/tsp-client.d.ts.map +1 -1
- package/lib/tsp-client.js +20 -11
- package/lib/tsp-client.js.map +1 -1
- package/lib/tsp-command-types.d.ts +12 -0
- package/lib/tsp-command-types.d.ts.map +1 -1
- package/lib/tsp-command-types.js +21 -1
- package/lib/tsp-command-types.js.map +1 -1
- package/lib/utils/api.d.ts +45 -0
- package/lib/utils/api.d.ts.map +1 -0
- package/lib/utils/api.js +95 -0
- package/lib/utils/api.js.map +1 -0
- package/package.json +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,82 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
|
3
3
|
|
|
4
|
+
## [0.7.1] - 2021-11-10
|
|
5
|
+
|
|
6
|
+
- fix: add missing `semver` dependency (#288)
|
|
7
|
+
|
|
8
|
+
## [0.7.0] - 2021-11-09
|
|
9
|
+
|
|
10
|
+
### Breaking
|
|
11
|
+
|
|
12
|
+
Changes to default options sent to tsserver could affect behavior (hopefully for the better). Read changes below for more details.
|
|
13
|
+
|
|
14
|
+
### Changes
|
|
15
|
+
|
|
16
|
+
- **feat**: include import specifier for import completions (#281)
|
|
17
|
+
For completions that import from another package, the completions will include a "detail" field with the name of the module.
|
|
18
|
+
|
|
19
|
+
Also aligned some other logic with the typescript language services used in VSCode:
|
|
20
|
+
* annotate the completions with the local name of the import when completing a path in import foo from '...'
|
|
21
|
+
* update completion "sortText" regardless if the completion "isRecommended"
|
|
22
|
+
|
|
23
|
+
- **feat**: allow skip destructive actions on running OrganizeImports (#228)
|
|
24
|
+
Add support for the new skipDestructiveCodeActions argument to TypeScript's organize imports feature - [1] to support [2].
|
|
25
|
+
|
|
26
|
+
Support is added in two places:
|
|
27
|
+
* Automatically inferring the proper value based on diagnostics for the file when returning code actions.
|
|
28
|
+
* Supporting sending it when manually executing the organize imports action.
|
|
29
|
+
|
|
30
|
+
Also added documentation to the readme about the supported commands that can be manually executed.
|
|
31
|
+
|
|
32
|
+
[1] https://github.com/microsoft/TypeScript/issues/43051
|
|
33
|
+
[2] https://github.com/apexskier/nova-typescript/issues/273
|
|
34
|
+
|
|
35
|
+
- **feat**: support running server on files without root workspace (#286)
|
|
36
|
+
The tsserver seems to be good at inferring the project configuration when opening single files without a workspace so don't crash on missing `rootPath`.
|
|
37
|
+
|
|
38
|
+
- **feat**: add `disableAutomaticTypingAcquisition` option to disable automatic type acquisition (#285)
|
|
39
|
+
- **feat**: update default tsserver options (#284)
|
|
40
|
+
Set the following additional options by default:
|
|
41
|
+
```
|
|
42
|
+
allowRenameOfImportPath: true,
|
|
43
|
+
displayPartsForJSDoc: true,
|
|
44
|
+
generateReturnInDocTemplate: true,
|
|
45
|
+
includeAutomaticOptionalChainCompletions: true,
|
|
46
|
+
includeCompletionsForImportStatements: true,
|
|
47
|
+
includeCompletionsWithSnippetText: true,
|
|
48
|
+
```
|
|
49
|
+
This aligns more with the default options of the typescript language services in VSCode.
|
|
50
|
+
- **feat**: announce support for "source.organizeImports.ts-ls" action (#283)
|
|
51
|
+
Announcing support for that code action allows editors that support
|
|
52
|
+
running code actions on save to automatically run the code action if
|
|
53
|
+
the user has configured the editor with settings like
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
"codeActionsOnSave": {
|
|
57
|
+
"source.organizeImports": true,
|
|
58
|
+
// or
|
|
59
|
+
"source.organizeImports.ts-ls": true,
|
|
60
|
+
},
|
|
61
|
+
```
|
|
62
|
+
- **chore**: change default log level from "warn" to "info" (#287)
|
|
63
|
+
|
|
64
|
+
## [0.6.5] - 2021-11-03
|
|
65
|
+
|
|
66
|
+
- fix: normalize client and tsserver paths (#275)
|
|
67
|
+
This should ensure consistent behavior regradless of the platform. Previously some functionality could be malfunctioning on Windows depending on the LSP client used due to using non-normalized file paths.
|
|
68
|
+
- Handle the `APPLY_COMPLETION_CODE_ACTION` command internally (#270)
|
|
69
|
+
This means that the clients that have implemented a custom handling for the `_typescript.applyCompletionCodeAction` command can remove that code.
|
|
70
|
+
Without removing the custom handling everything should work as before but some edge cases might work better when custom handling is removed.
|
|
71
|
+
- fix: ignore empty code blocks in content returned from `textDocument/hover` (#276)
|
|
72
|
+
- fix: remove unsupported --node-ipc and --socket options (#278)
|
|
73
|
+
|
|
74
|
+
## [0.6.4] - 2021-10-12
|
|
75
|
+
|
|
76
|
+
- Fix broken logging (#267)
|
|
77
|
+
- Add support for `workspace/didChangeConfiguration` and setting formatting options per language (#268)
|
|
78
|
+
- Add option to set inlayHints preferences by language (#266)
|
|
79
|
+
|
|
4
80
|
## [0.6.3] - 2021-10-27
|
|
5
81
|
|
|
6
82
|
- Implement experimental inlay hints (#259) ([documentation](https://github.com/typescript-language-server/typescript-language-server#typescriptinlayhints-experimental-supported-from-typescript-v442))
|
package/README.md
CHANGED
|
@@ -11,13 +11,13 @@ Based on concepts and ideas from https://github.com/prabirshrestha/typescript-la
|
|
|
11
11
|
|
|
12
12
|
Maintained by a [community of contributors](https://github.com/typescript-language-server/typescript-language-server/graphs/contributors) like you
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
## Installing
|
|
15
15
|
|
|
16
16
|
```sh
|
|
17
17
|
npm install -g typescript-language-server
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
## Running the language server
|
|
21
21
|
|
|
22
22
|
```
|
|
23
23
|
typescript-language-server --stdio
|
|
@@ -32,10 +32,8 @@ typescript-language-server --stdio
|
|
|
32
32
|
Options:
|
|
33
33
|
|
|
34
34
|
-V, --version output the version number
|
|
35
|
-
--stdio use stdio
|
|
36
|
-
--
|
|
37
|
-
--log-level <log-level> A number indicating the log level (4 = log, 3 = info, 2 = warn, 1 = error). Defaults to `2`.
|
|
38
|
-
--socket <port> use socket. example: --socket=5000
|
|
35
|
+
--stdio use stdio (required option)
|
|
36
|
+
--log-level <log-level> A number indicating the log level (4 = log, 3 = info, 2 = warn, 1 = error). Defaults to `3`.
|
|
39
37
|
--tsserver-log-file <tsServerLogFile> Specify a tsserver log file. example: --tsserver-log-file=ts-logs.txt
|
|
40
38
|
--tsserver-log-verbosity <verbosity> Specify tsserver log verbosity (off, terse, normal, verbose). Defaults to `normal`. example: --tsserver-log-verbosity=verbose
|
|
41
39
|
--tsserver-path <path> Specify path to tsserver. example: --tsserver-path=tsserver
|
|
@@ -49,6 +47,7 @@ The language server accepts various settings through the `initializationOptions`
|
|
|
49
47
|
| Setting | Type | Description |
|
|
50
48
|
|:------------------|:---------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
51
49
|
| hostInfo | string | Information about the host, for example `"Emacs 24.4"` or `"Sublime Text v3075"`. **Default**: `undefined` |
|
|
50
|
+
| disableAutomaticTypingAcquisition | boolean | Disables tsserver from automatically fetching missing type definitions (`@types` packages) for external modules. |
|
|
52
51
|
| logVerbosity | string | The verbosity level of the information printed in the log by `tsserver`. Accepts values: `"off"`, `"terse"`, `"normal"`, `"requesttime"`, `"verbose"`. **Default**: `undefined` (`"off"`). |
|
|
53
52
|
| maxTsServerMemory | number | The maximum size of the V8's old memory section in megabytes (for example `4096` means 4GB). The default value is dynamically configured by Node so can differ per system. Increase for very big projects that exceed allowed memory usage. **Default**: `undefined` |
|
|
54
53
|
| plugins | object[] | An array of `{ name: string, location: string }` objects for registering a Typescript plugins. **Default**: [] |
|
|
@@ -85,6 +84,10 @@ interface UserPreferences {
|
|
|
85
84
|
* values, with insertion text to replace preceding `.` tokens with `?.`.
|
|
86
85
|
*/
|
|
87
86
|
includeAutomaticOptionalChainCompletions: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Allows import module names to be resolved in the initial completions request.
|
|
89
|
+
* @default false
|
|
90
|
+
*/
|
|
88
91
|
allowIncompleteCompletions: boolean;
|
|
89
92
|
importModuleSpecifierPreference: "shortest" | "project-relative" | "relative" | "non-relative";
|
|
90
93
|
/** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */
|
|
@@ -104,33 +107,107 @@ From the `preferences` options listed above, this server explicilty sets the fol
|
|
|
104
107
|
|
|
105
108
|
```js
|
|
106
109
|
{
|
|
107
|
-
|
|
108
|
-
|
|
110
|
+
allowIncompleteCompletions: true,
|
|
111
|
+
allowRenameOfImportPath: true,
|
|
112
|
+
allowTextChangesInNewFiles: true,
|
|
113
|
+
displayPartsForJSDoc: true,
|
|
114
|
+
generateReturnInDocTemplate: true,
|
|
115
|
+
includeAutomaticOptionalChainCompletions: true,
|
|
116
|
+
includeCompletionsForImportStatements: true,
|
|
117
|
+
includeCompletionsForModuleExports: true,
|
|
118
|
+
includeCompletionsWithInsertText: true,
|
|
119
|
+
includeCompletionsWithSnippetText: true,
|
|
109
120
|
}
|
|
110
121
|
```
|
|
111
122
|
|
|
112
|
-
|
|
123
|
+
## workspace/didChangeConfiguration
|
|
113
124
|
|
|
114
|
-
|
|
115
|
-
- [x] textDocument/didClose
|
|
116
|
-
- [x] textDocument/didOpen
|
|
117
|
-
- [x] textDocument/didSave
|
|
125
|
+
Some of the preferences can be controlled through the `workspace/didChangeConfiguration` notification. Below is a list of supported options that can be passed. Note that the settings are specified separately for the typescript and javascript files so `[language]` can be either `javascript` or `typescript`.
|
|
118
126
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
127
|
+
```ts
|
|
128
|
+
// Formatting preferences
|
|
129
|
+
[language].format.baseIndentSize: number;
|
|
130
|
+
[language].format.convertTabsToSpaces: boolean;
|
|
131
|
+
[language].format.indentSize: number;
|
|
132
|
+
[language].format.indentStyle: 'None' | 'Block' | 'Smart';
|
|
133
|
+
[language].format.insertSpaceAfterCommaDelimiter: boolean;
|
|
134
|
+
[language].format.insertSpaceAfterConstructor: boolean;
|
|
135
|
+
[language].format.insertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean;
|
|
136
|
+
[language].format.insertSpaceAfterKeywordsInControlFlowStatements: boolean;
|
|
137
|
+
[language].format.insertSpaceAfterOpeningAndBeforeClosingEmptyBraces: boolean;
|
|
138
|
+
[language].format.insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: boolean;
|
|
139
|
+
[language].format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: boolean;
|
|
140
|
+
[language].format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean;
|
|
141
|
+
[language].format.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean;
|
|
142
|
+
[language].format.insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean;
|
|
143
|
+
[language].format.insertSpaceAfterSemicolonInForStatements: boolean;
|
|
144
|
+
[language].format.insertSpaceAfterTypeAssertion: boolean;
|
|
145
|
+
[language].format.insertSpaceBeforeAndAfterBinaryOperators: boolean;
|
|
146
|
+
[language].format.insertSpaceBeforeFunctionParenthesis: boolean;
|
|
147
|
+
[language].format.insertSpaceBeforeTypeAnnotation: boolean;
|
|
148
|
+
[language].format.newLineCharacter: string;
|
|
149
|
+
[language].format.placeOpenBraceOnNewLineForControlBlocks: boolean;
|
|
150
|
+
[language].format.placeOpenBraceOnNewLineForFunctions: boolean;
|
|
151
|
+
[language].format.semicolons: 'ignore' | 'insert' | 'remove';
|
|
152
|
+
[language].format.tabSize: number;
|
|
153
|
+
[language].format.trimTrailingWhitespace: boolean;
|
|
154
|
+
// Inlay Hints preferences
|
|
155
|
+
[language].inlayHints.includeInlayEnumMemberValueHints: boolean;
|
|
156
|
+
[language].inlayHints.includeInlayFunctionLikeReturnTypeHints: boolean;
|
|
157
|
+
[language].inlayHints.includeInlayFunctionParameterTypeHints: boolean;
|
|
158
|
+
[language].inlayHints.includeInlayParameterNameHints: 'none' | 'literals' | 'all';
|
|
159
|
+
[language].inlayHints.includeInlayParameterNameHintsWhenArgumentMatchesName: boolean;
|
|
160
|
+
[language].inlayHints.includeInlayPropertyDeclarationTypeHints: boolean;
|
|
161
|
+
[language].inlayHints.includeInlayVariableTypeHints: boolean;
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Code actions on save
|
|
165
|
+
|
|
166
|
+
Server announces support for the `source.organizeImports.ts-ls` code action which allows editors that support running code actions on save to automatically organize imports on saving. The user can enable it with a setting similar to (can vary per-editor):
|
|
167
|
+
|
|
168
|
+
```js
|
|
169
|
+
"codeActionsOnSave": {
|
|
170
|
+
"source.organizeImports": true,
|
|
171
|
+
// or
|
|
172
|
+
"source.organizeImports.ts-ls": true,
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Workspace commands (`workspace/executeCommand`)
|
|
177
|
+
|
|
178
|
+
See [LSP specification](https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#workspace_executeCommand).
|
|
179
|
+
|
|
180
|
+
Most of the time, you'll execute commands with arguments retrieved from another request like `textDocument/codeAction`. There are some use cases for calling them manually.
|
|
132
181
|
|
|
133
|
-
|
|
182
|
+
Supported commands:
|
|
183
|
+
|
|
184
|
+
`lsp` refers to the language server protocol, `tsp` refers to the typescript server protocol.
|
|
185
|
+
|
|
186
|
+
* `_typescript.applyWorkspaceEdit`
|
|
187
|
+
```ts
|
|
188
|
+
type Arguments = [lsp.WorkspaceEdit]
|
|
189
|
+
```
|
|
190
|
+
* `_typescript.applyCodeAction`
|
|
191
|
+
```ts
|
|
192
|
+
type Arguments = [tsp.CodeAction]
|
|
193
|
+
```
|
|
194
|
+
* `_typescript.applyRefactoring`
|
|
195
|
+
```ts
|
|
196
|
+
type Arguments = [tsp.GetEditsForRefactorRequestArgs]
|
|
197
|
+
```
|
|
198
|
+
* `_typescript.organizeImports`
|
|
199
|
+
```ts
|
|
200
|
+
// The "skipDestructiveCodeActions" argument is supported from Typescript 4.4+
|
|
201
|
+
type Arguments = [string] | [string, { skipDestructiveCodeActions?: boolean }]
|
|
202
|
+
```
|
|
203
|
+
* `_typescript.applyRenameFile`
|
|
204
|
+
```ts
|
|
205
|
+
type Arguments = [{ sourceUri: string; targetUri: string; }]
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Inlay hints (`typescript/inlayHints`) (experimental)
|
|
209
|
+
|
|
210
|
+
Supports experimental inline hints.
|
|
134
211
|
|
|
135
212
|
```ts
|
|
136
213
|
type Request = {
|
|
@@ -156,9 +233,9 @@ For the request to return any results, some or all of the following options need
|
|
|
156
233
|
```ts
|
|
157
234
|
// Not officially part of UserPreferences yet but you can send them along with the UserPreferences just fine:
|
|
158
235
|
export interface InlayHintsOptions extends UserPreferences {
|
|
159
|
-
includeInlayParameterNameHints:
|
|
236
|
+
includeInlayParameterNameHints: 'none' | 'literals' | 'all';
|
|
160
237
|
includeInlayParameterNameHintsWhenArgumentMatchesName: boolean;
|
|
161
|
-
includeInlayFunctionParameterTypeHints: boolean
|
|
238
|
+
includeInlayFunctionParameterTypeHints: boolean;
|
|
162
239
|
includeInlayVariableTypeHints: boolean;
|
|
163
240
|
includeInlayPropertyDeclarationTypeHints: boolean;
|
|
164
241
|
includeInlayFunctionLikeReturnTypeHints: boolean;
|
|
@@ -166,7 +243,115 @@ export interface InlayHintsOptions extends UserPreferences {
|
|
|
166
243
|
}
|
|
167
244
|
```
|
|
168
245
|
|
|
169
|
-
|
|
246
|
+
## Callers and callees (`textDocument/calls`) (experimental)
|
|
247
|
+
|
|
248
|
+
Supports showing callers and calles for a given symbol. If the editor has support for appropriate UI, it can generate a tree of callers and calles for a document.
|
|
249
|
+
|
|
250
|
+
```ts
|
|
251
|
+
type Request = {
|
|
252
|
+
/**
|
|
253
|
+
* The text document.
|
|
254
|
+
*/
|
|
255
|
+
textDocument: TextDocumentIdentifier;
|
|
256
|
+
/**
|
|
257
|
+
* The position inside the text document.
|
|
258
|
+
*/
|
|
259
|
+
position: Position;
|
|
260
|
+
/**
|
|
261
|
+
* Outgoing direction for callees.
|
|
262
|
+
* The default is incoming for callers.
|
|
263
|
+
*/
|
|
264
|
+
direction?: CallDirection;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export enum CallDirection {
|
|
268
|
+
/**
|
|
269
|
+
* Incoming calls aka. callers
|
|
270
|
+
*/
|
|
271
|
+
Incoming = 'incoming',
|
|
272
|
+
/**
|
|
273
|
+
* Outgoing calls aka. callees
|
|
274
|
+
*/
|
|
275
|
+
Outgoing = 'outgoing',
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
type Result = {
|
|
279
|
+
/**
|
|
280
|
+
* The symbol of a definition for which the request was made.
|
|
281
|
+
*
|
|
282
|
+
* If no definition is found at a given text document position, the symbol is undefined.
|
|
283
|
+
*/
|
|
284
|
+
symbol?: DefinitionSymbol;
|
|
285
|
+
/**
|
|
286
|
+
* List of calls.
|
|
287
|
+
*/
|
|
288
|
+
calls: Call[];
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
interface Call {
|
|
292
|
+
/**
|
|
293
|
+
* Actual location of a call to a definition.
|
|
294
|
+
*/
|
|
295
|
+
location: Location;
|
|
296
|
+
/**
|
|
297
|
+
* Symbol refered to by this call. For outgoing calls this is a callee,
|
|
298
|
+
* otherwise a caller.
|
|
299
|
+
*/
|
|
300
|
+
symbol: DefinitionSymbol;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
interface DefinitionSymbol {
|
|
304
|
+
/**
|
|
305
|
+
* The name of this symbol.
|
|
306
|
+
*/
|
|
307
|
+
name: string;
|
|
308
|
+
/**
|
|
309
|
+
* More detail for this symbol, e.g the signature of a function.
|
|
310
|
+
*/
|
|
311
|
+
detail?: string;
|
|
312
|
+
/**
|
|
313
|
+
* The kind of this symbol.
|
|
314
|
+
*/
|
|
315
|
+
kind: SymbolKind;
|
|
316
|
+
/**
|
|
317
|
+
* The range enclosing this symbol not including leading/trailing whitespace but everything else
|
|
318
|
+
* like comments. This information is typically used to determine if the the clients cursor is
|
|
319
|
+
* inside the symbol to reveal in the symbol in the UI.
|
|
320
|
+
*/
|
|
321
|
+
location: Location;
|
|
322
|
+
/**
|
|
323
|
+
* The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
|
|
324
|
+
* Must be contained by the the `range`.
|
|
325
|
+
*/
|
|
326
|
+
selectionRange: Range;
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Supported Protocol features
|
|
331
|
+
|
|
332
|
+
- [x] textDocument/didChange (incremental)
|
|
333
|
+
- [x] textDocument/didClose
|
|
334
|
+
- [x] textDocument/didOpen
|
|
335
|
+
- [x] textDocument/didSave
|
|
336
|
+
- [x] textDocument/codeAction
|
|
337
|
+
- [x] textDocument/completion (incl. completion/resolve)
|
|
338
|
+
- [x] textDocument/definition
|
|
339
|
+
- [x] textDocument/documentHighlight
|
|
340
|
+
- [x] textDocument/documentSymbol
|
|
341
|
+
- [x] textDocument/executeCommand
|
|
342
|
+
- [x] textDocument/formatting
|
|
343
|
+
- [x] textDocument/rangeFormatting
|
|
344
|
+
- [x] textDocument/hover
|
|
345
|
+
- [x] textDocument/rename
|
|
346
|
+
- [x] textDocument/references
|
|
347
|
+
- [x] textDocument/signatureHelp
|
|
348
|
+
- [x] textDocument/calls (experimental)
|
|
349
|
+
- [x] typescript/inlayHints (experimental, supported from Typescript v4.4.2)
|
|
350
|
+
- [x] workspace/symbol
|
|
351
|
+
- [x] workspace/didChangeConfiguration
|
|
352
|
+
- [x] workspace/executeCommand
|
|
353
|
+
|
|
354
|
+
## Development
|
|
170
355
|
|
|
171
356
|
### Build
|
|
172
357
|
|
|
@@ -174,7 +359,7 @@ export interface InlayHintsOptions extends UserPreferences {
|
|
|
174
359
|
yarn
|
|
175
360
|
```
|
|
176
361
|
|
|
177
|
-
|
|
362
|
+
### Test
|
|
178
363
|
|
|
179
364
|
```sh
|
|
180
365
|
yarn test
|
package/lib/cli.js
CHANGED
|
@@ -30,32 +30,27 @@ const commander_1 = require("commander");
|
|
|
30
30
|
const utils_1 = require("./utils");
|
|
31
31
|
const lsp_connection_1 = require("./lsp-connection");
|
|
32
32
|
const lsp = __importStar(require("vscode-languageserver/node"));
|
|
33
|
+
const DEFAULT_LOG_LEVEL = lsp.MessageType.Info;
|
|
33
34
|
const program = new commander_1.Command('typescript-language-server')
|
|
34
35
|
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
|
|
35
36
|
.version(require('../package.json').version)
|
|
36
|
-
.
|
|
37
|
-
.option('--node-ipc', 'use node-ipc')
|
|
37
|
+
.requiredOption('--stdio', 'use stdio')
|
|
38
38
|
.option('--log-level <logLevel>', 'A number indicating the log level (4 = log, 3 = info, 2 = warn, 1 = error). Defaults to `2`.')
|
|
39
|
-
.option('--socket <port>', 'use socket. example: --socket=5000')
|
|
40
39
|
.option('--tsserver-log-file <tsserverLogFile>', 'Specify a tsserver log file. example: --tsserver-log-file ts-logs.txt')
|
|
41
40
|
.option('--tsserver-log-verbosity <tsserverLogVerbosity>', 'Specify a tsserver log verbosity (terse, normal, verbose). Defaults to `normal`.' +
|
|
42
41
|
' example: --tsserver-log-verbosity verbose')
|
|
43
42
|
.option('--tsserver-path <path>', `Specify path to tsserver. example: --tsserver-path=${(0, utils_1.getTsserverExecutable)()}`)
|
|
44
43
|
.parse(process.argv);
|
|
45
44
|
const options = program.opts();
|
|
46
|
-
if (!(options.stdio || options.socket || options.nodeIpc)) {
|
|
47
|
-
console.error('Connection type required (stdio, node-ipc, socket). Refer to --help for more details.');
|
|
48
|
-
process.exit(1);
|
|
49
|
-
}
|
|
50
45
|
if (options.tsserverLogFile && !options.tsserverLogVerbosity) {
|
|
51
46
|
options.tsserverLogVerbosity = 'normal';
|
|
52
47
|
}
|
|
53
|
-
let logLevel =
|
|
48
|
+
let logLevel = DEFAULT_LOG_LEVEL;
|
|
54
49
|
if (options.logLevel) {
|
|
55
50
|
logLevel = parseInt(options.logLevel, 10);
|
|
56
51
|
if (logLevel && (logLevel < 1 || logLevel > 4)) {
|
|
57
52
|
console.error(`Invalid '--log-level ${logLevel}'. Falling back to 'info' level.`);
|
|
58
|
-
logLevel =
|
|
53
|
+
logLevel = DEFAULT_LOG_LEVEL;
|
|
59
54
|
}
|
|
60
55
|
}
|
|
61
56
|
(0, lsp_connection_1.createLspConnection)({
|
package/lib/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;AACA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;AAEH,yCAAoC;AACpC,mCAAgD;AAChD,qDAAuD;AACvD,gEAAkD;AAElD,MAAM,OAAO,GAAG,IAAI,mBAAO,CAAC,4BAA4B,CAAC;IACrD,qGAAqG;KACpG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC;KAC3C,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;AACA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;AAEH,yCAAoC;AACpC,mCAAgD;AAChD,qDAAuD;AACvD,gEAAkD;AAElD,MAAM,iBAAiB,GAAG,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC;AAE/C,MAAM,OAAO,GAAG,IAAI,mBAAO,CAAC,4BAA4B,CAAC;IACrD,qGAAqG;KACpG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC;KAC3C,cAAc,CAAC,SAAS,EAAE,WAAW,CAAC;KACtC,MAAM,CAAC,wBAAwB,EAAE,8FAA8F,CAAC;KAChI,MAAM,CAAC,uCAAuC,EAAE,uEAAuE,CAAC;KACxH,MAAM,CAAC,iDAAiD,EAAE,kFAAkF;IAC3I,4CAA4C,CAAC;KAC9C,MAAM,CAAC,wBAAwB,EAAE,sDAAsD,IAAA,6BAAqB,GAAE,EAAE,CAAC;KACjH,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;AAE/B,IAAI,OAAO,CAAC,eAAe,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE;IAC1D,OAAO,CAAC,oBAAoB,GAAG,QAAQ,CAAC;CAC3C;AAED,IAAI,QAAQ,GAAG,iBAAiB,CAAC;AACjC,IAAI,OAAO,CAAC,QAAQ,EAAE;IAClB,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC1C,IAAI,QAAQ,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,EAAE;QAC5C,OAAO,CAAC,KAAK,CAAC,wBAAwB,QAAQ,kCAAkC,CAAC,CAAC;QAClF,QAAQ,GAAG,iBAAiB,CAAC;KAChC;CACJ;AAED,IAAA,oCAAmB,EAAC;IAChB,YAAY,EAAE,OAAO,CAAC,YAAsB;IAC5C,eAAe,EAAE,OAAO,CAAC,eAAyB;IAClD,oBAAoB,EAAE,OAAO,CAAC,oBAA8B;IAC5D,gBAAgB,EAAE,QAA2B;CAChD,CAAC,CAAC,MAAM,EAAE,CAAC"}
|
package/lib/commands.d.ts
CHANGED
|
@@ -4,8 +4,11 @@ export declare const Commands: {
|
|
|
4
4
|
APPLY_REFACTORING: string;
|
|
5
5
|
ORGANIZE_IMPORTS: string;
|
|
6
6
|
APPLY_RENAME_FILE: string;
|
|
7
|
-
/** Commands below should be implemented by the client */
|
|
8
7
|
APPLY_COMPLETION_CODE_ACTION: string;
|
|
8
|
+
/** Commands below should be implemented by the client */
|
|
9
9
|
SELECT_REFACTORING: string;
|
|
10
10
|
};
|
|
11
|
+
export declare const CodeActions: {
|
|
12
|
+
SourceOrganizeImportsTsLs: string;
|
|
13
|
+
};
|
|
11
14
|
//# sourceMappingURL=commands.d.ts.map
|
package/lib/commands.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,QAAQ
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,QAAQ;;;;;;;IAOjB,yDAAyD;;CAE5D,CAAC;AAEF,eAAO,MAAM,WAAW;;CAEvB,CAAC"}
|
package/lib/commands.js
CHANGED
|
@@ -6,15 +6,18 @@
|
|
|
6
6
|
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.Commands = void 0;
|
|
9
|
+
exports.CodeActions = exports.Commands = void 0;
|
|
10
10
|
exports.Commands = {
|
|
11
11
|
APPLY_WORKSPACE_EDIT: '_typescript.applyWorkspaceEdit',
|
|
12
12
|
APPLY_CODE_ACTION: '_typescript.applyCodeAction',
|
|
13
13
|
APPLY_REFACTORING: '_typescript.applyRefactoring',
|
|
14
14
|
ORGANIZE_IMPORTS: '_typescript.organizeImports',
|
|
15
15
|
APPLY_RENAME_FILE: '_typescript.applyRenameFile',
|
|
16
|
-
/** Commands below should be implemented by the client */
|
|
17
16
|
APPLY_COMPLETION_CODE_ACTION: '_typescript.applyCompletionCodeAction',
|
|
17
|
+
/** Commands below should be implemented by the client */
|
|
18
18
|
SELECT_REFACTORING: '_typescript.selectRefactoring'
|
|
19
19
|
};
|
|
20
|
+
exports.CodeActions = {
|
|
21
|
+
SourceOrganizeImportsTsLs: 'source.organizeImports.ts-ls'
|
|
22
|
+
};
|
|
20
23
|
//# sourceMappingURL=commands.js.map
|
package/lib/commands.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,QAAQ,GAAG;IACpB,oBAAoB,EAAE,gCAAgC;IACtD,iBAAiB,EAAE,6BAA6B;IAChD,iBAAiB,EAAE,8BAA8B;IACjD,gBAAgB,EAAE,6BAA6B;IAC/C,iBAAiB,EAAE,6BAA6B;IAChD,
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,QAAQ,GAAG;IACpB,oBAAoB,EAAE,gCAAgC;IACtD,iBAAiB,EAAE,6BAA6B;IAChD,iBAAiB,EAAE,8BAA8B;IACjD,gBAAgB,EAAE,6BAA6B;IAC/C,iBAAiB,EAAE,6BAA6B;IAChD,4BAA4B,EAAE,uCAAuC;IACrE,yDAAyD;IACzD,kBAAkB,EAAE,+BAA+B;CACtD,CAAC;AAEW,QAAA,WAAW,GAAG;IACvB,yBAAyB,EAAE,8BAA8B;CAC5D,CAAC"}
|
package/lib/completion.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../src/completion.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,GAAG,MAAM,4BAA4B,CAAC;AAClD,OAAO,KAAK,GAAG,MAAM,yBAAyB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAKzC,UAAU,gBAAiB,SAAQ,GAAG,CAAC,cAAc;IACjD,IAAI,EAAE,GAAG,CAAC,4BAA4B,CAAC;CAC1C;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,GAAG,gBAAgB,
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../src/completion.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,GAAG,MAAM,4BAA4B,CAAC;AAClD,OAAO,KAAK,GAAG,MAAM,yBAAyB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAKzC,UAAU,gBAAiB,SAAQ,GAAG,CAAC,cAAc;IACjD,IAAI,EAAE,GAAG,CAAC,4BAA4B,CAAC;CAC1C;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,GAAG,gBAAgB,CAoF1I;AA6ED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,GAAG,CAAC,cAAc,EAAE,OAAO,EAAE,GAAG,CAAC,sBAAsB,GAAG,GAAG,CAAC,cAAc,CAS1H"}
|
package/lib/completion.js
CHANGED
|
@@ -36,25 +36,29 @@ function asCompletionItem(entry, file, position, document) {
|
|
|
36
36
|
kind: asCompletionItemKind(entry.kind),
|
|
37
37
|
sortText: entry.sortText,
|
|
38
38
|
commitCharacters: asCommitCharacters(entry.kind),
|
|
39
|
+
preselect: entry.isRecommended,
|
|
39
40
|
data: {
|
|
40
41
|
file,
|
|
41
42
|
line: position.line + 1,
|
|
42
43
|
offset: position.character + 1,
|
|
43
44
|
entryNames: [
|
|
44
|
-
entry.source
|
|
45
|
+
entry.source || entry.data ? {
|
|
46
|
+
name: entry.name,
|
|
47
|
+
source: entry.source,
|
|
48
|
+
data: entry.data
|
|
49
|
+
} : entry.name
|
|
45
50
|
]
|
|
46
51
|
}
|
|
47
52
|
};
|
|
48
|
-
if (entry.
|
|
49
|
-
// Make sure isRecommended property always comes first
|
|
50
|
-
// https://github.com/Microsoft/vscode/issues/40325
|
|
51
|
-
item.preselect = true;
|
|
52
|
-
}
|
|
53
|
-
else if (entry.source) {
|
|
53
|
+
if (entry.source && entry.hasAction) {
|
|
54
54
|
// De-prioritze auto-imports
|
|
55
55
|
// https://github.com/Microsoft/vscode/issues/40311
|
|
56
56
|
item.sortText = '\uffff' + entry.sortText;
|
|
57
57
|
}
|
|
58
|
+
const { sourceDisplay } = entry;
|
|
59
|
+
if (sourceDisplay) {
|
|
60
|
+
item.detail = (0, protocol_translation_1.asPlainText)(sourceDisplay);
|
|
61
|
+
}
|
|
58
62
|
if (item.kind === lsp.CompletionItemKind.Function || item.kind === lsp.CompletionItemKind.Method) {
|
|
59
63
|
item.insertTextFormat = lsp.InsertTextFormat.Snippet;
|
|
60
64
|
}
|
|
@@ -69,7 +73,7 @@ function asCompletionItem(entry, file, position, document) {
|
|
|
69
73
|
}
|
|
70
74
|
if (entry.kindModifiers) {
|
|
71
75
|
const kindModifiers = new Set(entry.kindModifiers.split(/,|\s+/g));
|
|
72
|
-
if (kindModifiers.has(
|
|
76
|
+
if (kindModifiers.has(tsp_command_types_1.KindModifiers.optional)) {
|
|
73
77
|
if (!insertText) {
|
|
74
78
|
insertText = item.label;
|
|
75
79
|
}
|
|
@@ -78,9 +82,25 @@ function asCompletionItem(entry, file, position, document) {
|
|
|
78
82
|
}
|
|
79
83
|
item.label += '?';
|
|
80
84
|
}
|
|
81
|
-
if (kindModifiers.has(
|
|
85
|
+
if (kindModifiers.has(tsp_command_types_1.KindModifiers.deprecated)) {
|
|
82
86
|
item.tags = [lsp.CompletionItemTag.Deprecated];
|
|
83
87
|
}
|
|
88
|
+
if (kindModifiers.has(tsp_command_types_1.KindModifiers.color)) {
|
|
89
|
+
item.kind = lsp.CompletionItemKind.Color;
|
|
90
|
+
}
|
|
91
|
+
if (entry.kind === tsp_command_types_1.ScriptElementKind.scriptElement) {
|
|
92
|
+
for (const extModifier of tsp_command_types_1.KindModifiers.fileExtensionKindModifiers) {
|
|
93
|
+
if (kindModifiers.has(extModifier)) {
|
|
94
|
+
if (entry.name.toLowerCase().endsWith(extModifier)) {
|
|
95
|
+
item.detail = entry.name;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
item.detail = entry.name + extModifier;
|
|
99
|
+
}
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
84
104
|
}
|
|
85
105
|
if (insertText && replacementRange) {
|
|
86
106
|
item.textEdit = lsp.TextEdit.replace(replacementRange, insertText);
|
|
@@ -163,25 +183,21 @@ function asCommitCharacters(kind) {
|
|
|
163
183
|
return commitCharacters.length === 0 ? undefined : commitCharacters;
|
|
164
184
|
}
|
|
165
185
|
function asResolvedCompletionItem(item, details) {
|
|
186
|
+
var _a;
|
|
166
187
|
item.detail = asDetail(details);
|
|
167
188
|
item.documentation = (0, protocol_translation_1.asDocumentation)(details);
|
|
168
|
-
|
|
189
|
+
if ((_a = details.codeActions) === null || _a === void 0 ? void 0 : _a.length) {
|
|
190
|
+
const filepath = (0, protocol_translation_1.normalizePath)(item.data.file);
|
|
191
|
+
item.additionalTextEdits = asAdditionalTextEdits(details.codeActions, filepath);
|
|
192
|
+
item.command = asCommand(details.codeActions, item.data.file);
|
|
193
|
+
}
|
|
169
194
|
return item;
|
|
170
195
|
}
|
|
171
196
|
exports.asResolvedCompletionItem = asResolvedCompletionItem;
|
|
172
|
-
function
|
|
173
|
-
if (!details.codeActions || !details.codeActions.length) {
|
|
174
|
-
return {};
|
|
175
|
-
}
|
|
197
|
+
function asAdditionalTextEdits(codeActions, filepath) {
|
|
176
198
|
// Try to extract out the additionalTextEdits for the current file.
|
|
177
|
-
// Also check if we still have to apply other workspace edits and commands
|
|
178
|
-
// using a vscode command
|
|
179
199
|
const additionalTextEdits = [];
|
|
180
|
-
|
|
181
|
-
for (const tsAction of details.codeActions) {
|
|
182
|
-
if (tsAction.commands) {
|
|
183
|
-
hasRemainingCommandsOrEdits = true;
|
|
184
|
-
}
|
|
200
|
+
for (const tsAction of codeActions) {
|
|
185
201
|
// Apply all edits in the current file using `additionalTextEdits`
|
|
186
202
|
if (tsAction.changes) {
|
|
187
203
|
for (const change of tsAction.changes) {
|
|
@@ -190,29 +206,39 @@ function asCodeActions(details, filepath) {
|
|
|
190
206
|
additionalTextEdits.push((0, protocol_translation_1.toTextEdit)(textChange));
|
|
191
207
|
}
|
|
192
208
|
}
|
|
193
|
-
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return additionalTextEdits.length ? additionalTextEdits : undefined;
|
|
213
|
+
}
|
|
214
|
+
function asCommand(codeActions, filepath) {
|
|
215
|
+
let hasRemainingCommandsOrEdits = false;
|
|
216
|
+
for (const tsAction of codeActions) {
|
|
217
|
+
if (tsAction.commands) {
|
|
218
|
+
hasRemainingCommandsOrEdits = true;
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
if (tsAction.changes) {
|
|
222
|
+
for (const change of tsAction.changes) {
|
|
223
|
+
if (change.fileName !== filepath) {
|
|
194
224
|
hasRemainingCommandsOrEdits = true;
|
|
225
|
+
break;
|
|
195
226
|
}
|
|
196
227
|
}
|
|
197
228
|
}
|
|
198
229
|
}
|
|
199
|
-
let command = undefined;
|
|
200
230
|
if (hasRemainingCommandsOrEdits) {
|
|
201
231
|
// Create command that applies all edits not in the current file.
|
|
202
|
-
|
|
232
|
+
return {
|
|
203
233
|
title: '',
|
|
204
234
|
command: commands_1.Commands.APPLY_COMPLETION_CODE_ACTION,
|
|
205
|
-
arguments: [filepath,
|
|
235
|
+
arguments: [filepath, codeActions.map(codeAction => ({
|
|
206
236
|
commands: codeAction.commands,
|
|
207
237
|
description: codeAction.description,
|
|
208
238
|
changes: codeAction.changes.filter(x => x.fileName !== filepath)
|
|
209
239
|
}))]
|
|
210
240
|
};
|
|
211
241
|
}
|
|
212
|
-
return {
|
|
213
|
-
command,
|
|
214
|
-
additionalTextEdits: additionalTextEdits.length ? additionalTextEdits : undefined
|
|
215
|
-
};
|
|
216
242
|
}
|
|
217
243
|
function asDetail({ displayParts, sourceDisplay, source: deprecatedSource }) {
|
|
218
244
|
const result = [];
|