typescript-language-server 0.6.5 → 0.8.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.
Files changed (95) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/README.md +105 -30
  3. package/lib/cli.js +4 -4
  4. package/lib/cli.js.map +1 -1
  5. package/lib/commands.d.ts +3 -0
  6. package/lib/commands.d.ts.map +1 -1
  7. package/lib/commands.js +4 -1
  8. package/lib/commands.js.map +1 -1
  9. package/lib/completion.d.ts +4 -1
  10. package/lib/completion.d.ts.map +1 -1
  11. package/lib/completion.js +171 -19
  12. package/lib/completion.js.map +1 -1
  13. package/lib/diagnostic-queue.d.ts +3 -0
  14. package/lib/diagnostic-queue.d.ts.map +1 -1
  15. package/lib/diagnostic-queue.js +14 -3
  16. package/lib/diagnostic-queue.js.map +1 -1
  17. package/lib/logger.d.ts.map +1 -1
  18. package/lib/logger.js +1 -0
  19. package/lib/logger.js.map +1 -1
  20. package/lib/lsp-connection.d.ts.map +1 -1
  21. package/lib/lsp-connection.js +2 -0
  22. package/lib/lsp-connection.js.map +1 -1
  23. package/lib/lsp-server.d.ts +7 -12
  24. package/lib/lsp-server.d.ts.map +1 -1
  25. package/lib/lsp-server.js +174 -52
  26. package/lib/lsp-server.js.map +1 -1
  27. package/lib/lsp-server.spec.js +213 -10
  28. package/lib/lsp-server.spec.js.map +1 -1
  29. package/lib/organize-imports.d.ts +2 -1
  30. package/lib/organize-imports.d.ts.map +1 -1
  31. package/lib/organize-imports.js +7 -5
  32. package/lib/organize-imports.js.map +1 -1
  33. package/lib/organize-imports.spec.js +14 -7
  34. package/lib/organize-imports.spec.js.map +1 -1
  35. package/lib/protocol-translation.js +7 -10
  36. package/lib/protocol-translation.js.map +1 -1
  37. package/lib/semantic-tokens.d.ts +9 -0
  38. package/lib/semantic-tokens.d.ts.map +1 -0
  39. package/lib/semantic-tokens.js +47 -0
  40. package/lib/semantic-tokens.js.map +1 -0
  41. package/lib/test-utils.d.ts.map +1 -1
  42. package/lib/test-utils.js +4 -2
  43. package/lib/test-utils.js.map +1 -1
  44. package/lib/ts-protocol.d.ts +19 -0
  45. package/lib/ts-protocol.d.ts.map +1 -1
  46. package/lib/ts-protocol.js +10 -1
  47. package/lib/ts-protocol.js.map +1 -1
  48. package/lib/tsp-client.d.ts +7 -1
  49. package/lib/tsp-client.d.ts.map +1 -1
  50. package/lib/tsp-client.js +24 -14
  51. package/lib/tsp-client.js.map +1 -1
  52. package/lib/tsp-client.spec.js +74 -82
  53. package/lib/tsp-client.spec.js.map +1 -1
  54. package/lib/tsp-command-types.d.ts +14 -1
  55. package/lib/tsp-command-types.d.ts.map +1 -1
  56. package/lib/tsp-command-types.js +21 -1
  57. package/lib/tsp-command-types.js.map +1 -1
  58. package/lib/utils/SnippetString.d.ts +12 -0
  59. package/lib/utils/SnippetString.d.ts.map +1 -0
  60. package/lib/utils/SnippetString.js +69 -0
  61. package/lib/utils/SnippetString.js.map +1 -0
  62. package/lib/utils/api.d.ts +45 -0
  63. package/lib/utils/api.d.ts.map +1 -0
  64. package/lib/utils/api.js +95 -0
  65. package/lib/utils/api.js.map +1 -0
  66. package/lib/utils/configuration.d.ts +10 -0
  67. package/lib/utils/configuration.d.ts.map +1 -0
  68. package/lib/utils/configuration.js +3 -0
  69. package/lib/utils/configuration.js.map +1 -0
  70. package/lib/utils/modules-resolver.d.ts +2 -0
  71. package/lib/utils/modules-resolver.d.ts.map +1 -0
  72. package/lib/{modules-resolver.js → utils/modules-resolver.js} +8 -22
  73. package/lib/utils/modules-resolver.js.map +1 -0
  74. package/lib/{modules-resolver.spec.d.ts → utils/modules-resolver.spec.d.ts} +0 -0
  75. package/lib/utils/modules-resolver.spec.d.ts.map +1 -0
  76. package/lib/{modules-resolver.spec.js → utils/modules-resolver.spec.js} +9 -9
  77. package/lib/utils/modules-resolver.spec.js.map +1 -0
  78. package/lib/utils/typeConverters.d.ts +11 -0
  79. package/lib/utils/typeConverters.d.ts.map +1 -0
  80. package/lib/utils/typeConverters.js +22 -0
  81. package/lib/utils/typeConverters.js.map +1 -0
  82. package/lib/utils/versionProvider.d.ts +30 -0
  83. package/lib/utils/versionProvider.d.ts.map +1 -0
  84. package/lib/utils/versionProvider.js +147 -0
  85. package/lib/utils/versionProvider.js.map +1 -0
  86. package/lib/utils.d.ts +0 -1
  87. package/lib/utils.d.ts.map +1 -1
  88. package/lib/utils.js +1 -8
  89. package/lib/utils.js.map +1 -1
  90. package/package.json +31 -17
  91. package/lib/modules-resolver.d.ts +0 -3
  92. package/lib/modules-resolver.d.ts.map +0 -1
  93. package/lib/modules-resolver.js.map +0 -1
  94. package/lib/modules-resolver.spec.d.ts.map +0 -1
  95. package/lib/modules-resolver.spec.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,6 +1,90 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [0.8.0] - 2021-11-21
5
+
6
+ - **feat**: implement semantic tokens support (#290)
7
+
8
+ - **feat**: add support for snippet completions for methods/functions (#303)
9
+
10
+ - **feat**: ability to ignore diagnostics by code (#272)
11
+ Adds new `diagnostics.ignoredCodes` workspace setting to ignore specific diagnostics.
12
+
13
+ - **feat**: add `npmLocation` option to specify NPM location (#293)
14
+
15
+ - **fix**: don't announce support for codeActionKinds (#289)
16
+
17
+ - **fix**: mark import completions as snippets (#291)
18
+
19
+ - **fix**: specify minimum node version to be v12 (#301)
20
+
21
+ - **fix**: ensure that the `tsserver` subprocess uses forked node instance (#292)
22
+ Potentially **BREAKING**. The lookup of `tsserver` was refactored to never use `spawn` logic but instead always `fork` the current node instance. See more info in the PR.
23
+
24
+ - **fix**: exit the server if tsserver process crashes (#305)
25
+
26
+ - **fix**: respect "includeDeclaration" for references request (#306)
27
+
28
+ ## [0.7.1] - 2021-11-10
29
+
30
+ - fix: add missing `semver` dependency (#288)
31
+
32
+ ## [0.7.0] - 2021-11-09
33
+
34
+ ### Breaking
35
+
36
+ Changes to default options sent to tsserver could affect behavior (hopefully for the better). Read changes below for more details.
37
+
38
+ ### Changes
39
+
40
+ - **feat**: include import specifier for import completions (#281)
41
+ For completions that import from another package, the completions will include a "detail" field with the name of the module.
42
+
43
+ Also aligned some other logic with the typescript language services used in VSCode:
44
+ * annotate the completions with the local name of the import when completing a path in import foo from '...'
45
+ * update completion "sortText" regardless if the completion "isRecommended"
46
+
47
+ - **feat**: allow skip destructive actions on running OrganizeImports (#228)
48
+ Add support for the new skipDestructiveCodeActions argument to TypeScript's organize imports feature - [1] to support [2].
49
+
50
+ Support is added in two places:
51
+ * Automatically inferring the proper value based on diagnostics for the file when returning code actions.
52
+ * Supporting sending it when manually executing the organize imports action.
53
+
54
+ Also added documentation to the readme about the supported commands that can be manually executed.
55
+
56
+ [1] https://github.com/microsoft/TypeScript/issues/43051
57
+ [2] https://github.com/apexskier/nova-typescript/issues/273
58
+
59
+ - **feat**: support running server on files without root workspace (#286)
60
+ 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`.
61
+
62
+ - **feat**: add `disableAutomaticTypingAcquisition` option to disable automatic type acquisition (#285)
63
+ - **feat**: update default tsserver options (#284)
64
+ Set the following additional options by default:
65
+ ```
66
+ allowRenameOfImportPath: true,
67
+ displayPartsForJSDoc: true,
68
+ generateReturnInDocTemplate: true,
69
+ includeAutomaticOptionalChainCompletions: true,
70
+ includeCompletionsForImportStatements: true,
71
+ includeCompletionsWithSnippetText: true,
72
+ ```
73
+ This aligns more with the default options of the typescript language services in VSCode.
74
+ - **feat**: announce support for "source.organizeImports.ts-ls" action (#283)
75
+ Announcing support for that code action allows editors that support
76
+ running code actions on save to automatically run the code action if
77
+ the user has configured the editor with settings like
78
+
79
+ ```js
80
+ "codeActionsOnSave": {
81
+ "source.organizeImports": true,
82
+ // or
83
+ "source.organizeImports.ts-ls": true,
84
+ },
85
+ ```
86
+ - **chore**: change default log level from "warn" to "info" (#287)
87
+
4
88
  ## [0.6.5] - 2021-11-03
5
89
 
6
90
  - fix: normalize client and tsserver paths (#275)
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
- # Installing
14
+ ## Installing
15
15
 
16
16
  ```sh
17
17
  npm install -g typescript-language-server
18
18
  ```
19
19
 
20
- # Running the language server
20
+ ## Running the language server
21
21
 
22
22
  ```
23
23
  typescript-language-server --stdio
@@ -32,14 +32,16 @@ typescript-language-server --stdio
32
32
  Options:
33
33
 
34
34
  -V, --version output the version number
35
- --stdio use stdio (the only supported and required option)
36
- --log-level <log-level> A number indicating the log level (4 = log, 3 = info, 2 = warn, 1 = error). Defaults to `2`.
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`.
37
37
  --tsserver-log-file <tsServerLogFile> Specify a tsserver log file. example: --tsserver-log-file=ts-logs.txt
38
38
  --tsserver-log-verbosity <verbosity> Specify tsserver log verbosity (off, terse, normal, verbose). Defaults to `normal`. example: --tsserver-log-verbosity=verbose
39
- --tsserver-path <path> Specify path to tsserver. example: --tsserver-path=tsserver
39
+ --tsserver-path <path> Specify path to tsserver directory. example: --tsserver-path=/Users/me/typescript/lib/
40
40
  -h, --help output usage information
41
41
  ```
42
42
 
43
+ > Note: The path passed to `--tsserver-path` should ideally be a path to the `/.../typescript/lib/` directory and not to the shell script `/.../node_modules/.bin/tsserver` or `tsserver`. Though for backward-compatibility reasons, the server will try to do the right thing even when passed a path to the shell script.
44
+
43
45
  ## initializationOptions
44
46
 
45
47
  The language server accepts various settings through the `initializationOptions` object passed through the `initialize` request. Refer to your LSP client's documentation on how to set these. Here is the list of supported options:
@@ -47,8 +49,10 @@ The language server accepts various settings through the `initializationOptions`
47
49
  | Setting | Type | Description |
48
50
  |:------------------|:---------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
49
51
  | hostInfo | string | Information about the host, for example `"Emacs 24.4"` or `"Sublime Text v3075"`. **Default**: `undefined` |
52
+ | disableAutomaticTypingAcquisition | boolean | Disables tsserver from automatically fetching missing type definitions (`@types` packages) for external modules. |
50
53
  | logVerbosity | string | The verbosity level of the information printed in the log by `tsserver`. Accepts values: `"off"`, `"terse"`, `"normal"`, `"requesttime"`, `"verbose"`. **Default**: `undefined` (`"off"`). |
51
54
  | 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` |
55
+ | npmLocation | string | Specifies the path to the NPM executable used for Automatic Type Acquisition. |
52
56
  | plugins | object[] | An array of `{ name: string, location: string }` objects for registering a Typescript plugins. **Default**: [] |
53
57
  | preferences | object | Preferences passed to the Typescript (`tsserver`) process. See below for more info. |
54
58
 
@@ -83,6 +87,10 @@ interface UserPreferences {
83
87
  * values, with insertion text to replace preceding `.` tokens with `?.`.
84
88
  */
85
89
  includeAutomaticOptionalChainCompletions: boolean;
90
+ /**
91
+ * Allows import module names to be resolved in the initial completions request.
92
+ * @default false
93
+ */
86
94
  allowIncompleteCompletions: boolean;
87
95
  importModuleSpecifierPreference: "shortest" | "project-relative" | "relative" | "non-relative";
88
96
  /** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */
@@ -102,8 +110,16 @@ From the `preferences` options listed above, this server explicilty sets the fol
102
110
 
103
111
  ```js
104
112
  {
105
- includeCompletionsForModuleExports: true,
106
- includeCompletionsWithInsertText: true,
113
+ allowIncompleteCompletions: true,
114
+ allowRenameOfImportPath: true,
115
+ allowTextChangesInNewFiles: true,
116
+ displayPartsForJSDoc: true,
117
+ generateReturnInDocTemplate: true,
118
+ includeAutomaticOptionalChainCompletions: true,
119
+ includeCompletionsForImportStatements: true,
120
+ includeCompletionsForModuleExports: true,
121
+ includeCompletionsWithInsertText: true,
122
+ includeCompletionsWithSnippetText: true,
107
123
  }
108
124
  ```
109
125
 
@@ -146,31 +162,64 @@ Some of the preferences can be controlled through the `workspace/didChangeConfig
146
162
  [language].inlayHints.includeInlayParameterNameHintsWhenArgumentMatchesName: boolean;
147
163
  [language].inlayHints.includeInlayPropertyDeclarationTypeHints: boolean;
148
164
  [language].inlayHints.includeInlayVariableTypeHints: boolean;
165
+ /**
166
+ * Complete functions with their parameter signature.
167
+ * @default false
168
+ */
169
+ completions.completeFunctionCalls: boolean;
170
+ // Diagnostics code to be omitted when reporting diagnostics.
171
+ // See https://github.com/microsoft/TypeScript/blob/master/src/compiler/diagnosticMessages.json for a full list of valid codes.
172
+ diagnostics.ignoredCodes: number[];
173
+
149
174
  ```
150
175
 
151
- # Supported Protocol features
176
+ ## Code actions on save
152
177
 
153
- - [x] textDocument/didChange (incremental)
154
- - [x] textDocument/didClose
155
- - [x] textDocument/didOpen
156
- - [x] textDocument/didSave
178
+ 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):
157
179
 
158
- - [x] textDocument/codeAction
159
- - [x] textDocument/completion (incl. completion/resolve)
160
- - [x] textDocument/definition
161
- - [x] textDocument/documentHighlight
162
- - [x] textDocument/documentSymbol
163
- - [x] textDocument/executeCommand
164
- - [x] textDocument/formatting
165
- - [x] textDocument/rangeFormatting
166
- - [x] textDocument/hover
167
- - [x] textDocument/rename
168
- - [x] textDocument/references
169
- - [x] textDocument/signatureHelp
170
- - [x] workspace/symbol
171
- - [x] workspace/didChangeConfiguration
180
+ ```js
181
+ "codeActionsOnSave": {
182
+ "source.organizeImports": true,
183
+ // or
184
+ "source.organizeImports.ts-ls": true,
185
+ }
186
+ ```
187
+
188
+ ## Workspace commands (`workspace/executeCommand`)
189
+
190
+ See [LSP specification](https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#workspace_executeCommand).
172
191
 
173
- ## `typescript/inlayHints` (experimental, supported from Typescript v4.4.2)
192
+ 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.
193
+
194
+ Supported commands:
195
+
196
+ `lsp` refers to the language server protocol, `tsp` refers to the typescript server protocol.
197
+
198
+ * `_typescript.applyWorkspaceEdit`
199
+ ```ts
200
+ type Arguments = [lsp.WorkspaceEdit]
201
+ ```
202
+ * `_typescript.applyCodeAction`
203
+ ```ts
204
+ type Arguments = [tsp.CodeAction]
205
+ ```
206
+ * `_typescript.applyRefactoring`
207
+ ```ts
208
+ type Arguments = [tsp.GetEditsForRefactorRequestArgs]
209
+ ```
210
+ * `_typescript.organizeImports`
211
+ ```ts
212
+ // The "skipDestructiveCodeActions" argument is supported from Typescript 4.4+
213
+ type Arguments = [string] | [string, { skipDestructiveCodeActions?: boolean }]
214
+ ```
215
+ * `_typescript.applyRenameFile`
216
+ ```ts
217
+ type Arguments = [{ sourceUri: string; targetUri: string; }]
218
+ ```
219
+
220
+ ## Inlay hints (`typescript/inlayHints`) (experimental)
221
+
222
+ Supports experimental inline hints.
174
223
 
175
224
  ```ts
176
225
  type Request = {
@@ -206,7 +255,9 @@ export interface InlayHintsOptions extends UserPreferences {
206
255
  }
207
256
  ```
208
257
 
209
- ## `textDocument/calls` (experimental)
258
+ ## Callers and callees (`textDocument/calls`) (experimental)
259
+
260
+ 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.
210
261
 
211
262
  ```ts
212
263
  type Request = {
@@ -288,7 +339,31 @@ interface DefinitionSymbol {
288
339
  }
289
340
  ```
290
341
 
291
- # Development
342
+ ## Supported Protocol features
343
+
344
+ - [x] textDocument/didChange (incremental)
345
+ - [x] textDocument/didClose
346
+ - [x] textDocument/didOpen
347
+ - [x] textDocument/didSave
348
+ - [x] textDocument/codeAction
349
+ - [x] textDocument/completion (incl. completion/resolve)
350
+ - [x] textDocument/definition
351
+ - [x] textDocument/documentHighlight
352
+ - [x] textDocument/documentSymbol
353
+ - [x] textDocument/executeCommand
354
+ - [x] textDocument/formatting
355
+ - [x] textDocument/rangeFormatting
356
+ - [x] textDocument/hover
357
+ - [x] textDocument/rename
358
+ - [x] textDocument/references
359
+ - [x] textDocument/signatureHelp
360
+ - [x] textDocument/calls (experimental)
361
+ - [x] typescript/inlayHints (experimental, supported from Typescript v4.4.2)
362
+ - [x] workspace/symbol
363
+ - [x] workspace/didChangeConfiguration
364
+ - [x] workspace/executeCommand
365
+
366
+ ## Development
292
367
 
293
368
  ### Build
294
369
 
@@ -296,7 +371,7 @@ interface DefinitionSymbol {
296
371
  yarn
297
372
  ```
298
373
 
299
- ## Test
374
+ ### Test
300
375
 
301
376
  ```sh
302
377
  yarn test
package/lib/cli.js CHANGED
@@ -27,9 +27,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const commander_1 = require("commander");
30
- const utils_1 = require("./utils");
31
30
  const lsp_connection_1 = require("./lsp-connection");
32
31
  const lsp = __importStar(require("vscode-languageserver/node"));
32
+ const DEFAULT_LOG_LEVEL = lsp.MessageType.Info;
33
33
  const program = new commander_1.Command('typescript-language-server')
34
34
  // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
35
35
  .version(require('../package.json').version)
@@ -38,18 +38,18 @@ const program = new commander_1.Command('typescript-language-server')
38
38
  .option('--tsserver-log-file <tsserverLogFile>', 'Specify a tsserver log file. example: --tsserver-log-file ts-logs.txt')
39
39
  .option('--tsserver-log-verbosity <tsserverLogVerbosity>', 'Specify a tsserver log verbosity (terse, normal, verbose). Defaults to `normal`.' +
40
40
  ' example: --tsserver-log-verbosity verbose')
41
- .option('--tsserver-path <path>', `Specify path to tsserver. example: --tsserver-path=${(0, utils_1.getTsserverExecutable)()}`)
41
+ .option('--tsserver-path <path>', 'Specify path to tsserver directory. example: --tsserver-path=/Users/me/typescript/lib/')
42
42
  .parse(process.argv);
43
43
  const options = program.opts();
44
44
  if (options.tsserverLogFile && !options.tsserverLogVerbosity) {
45
45
  options.tsserverLogVerbosity = 'normal';
46
46
  }
47
- let logLevel = lsp.MessageType.Warning;
47
+ let logLevel = DEFAULT_LOG_LEVEL;
48
48
  if (options.logLevel) {
49
49
  logLevel = parseInt(options.logLevel, 10);
50
50
  if (logLevel && (logLevel < 1 || logLevel > 4)) {
51
51
  console.error(`Invalid '--log-level ${logLevel}'. Falling back to 'info' level.`);
52
- logLevel = lsp.MessageType.Warning;
52
+ logLevel = DEFAULT_LOG_LEVEL;
53
53
  }
54
54
  }
55
55
  (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,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,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC;AACvC,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,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC;KACtC;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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;AACA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;AAEH,yCAAoC;AACpC,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,wFAAwF,CAAC;KAC1H,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
@@ -8,4 +8,7 @@ export declare const Commands: {
8
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
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,QAAQ;;;;;;;IAOjB,yDAAyD;;CAE5D,CAAC"}
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,7 +6,7 @@
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',
@@ -17,4 +17,7 @@ exports.Commands = {
17
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
@@ -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,4BAA4B,EAAE,uCAAuC;IACrE,yDAAyD;IACzD,kBAAkB,EAAE,+BAA+B;CACtD,CAAC"}
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"}
@@ -1,10 +1,13 @@
1
1
  import * as lsp from 'vscode-languageserver/node';
2
2
  import type tsp from 'typescript/lib/protocol';
3
3
  import { LspDocument } from './document';
4
+ import { TspClient } from './tsp-client';
5
+ import { CompletionOptions } from './ts-protocol';
4
6
  interface TSCompletionItem extends lsp.CompletionItem {
5
7
  data: tsp.CompletionDetailsRequestArgs;
6
8
  }
7
9
  export declare function asCompletionItem(entry: tsp.CompletionEntry, file: string, position: lsp.Position, document: LspDocument): TSCompletionItem;
8
- export declare function asResolvedCompletionItem(item: lsp.CompletionItem, details: tsp.CompletionEntryDetails): lsp.CompletionItem;
10
+ export declare function asResolvedCompletionItem(item: lsp.CompletionItem, details: tsp.CompletionEntryDetails, client: TspClient, options: CompletionOptions): Promise<lsp.CompletionItem>;
11
+ export declare function isValidFunctionCompletionContext(filepath: string, position: lsp.Position, client: TspClient): Promise<boolean>;
9
12
  export {};
10
13
  //# sourceMappingURL=completion.d.ts.map
@@ -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,CA2D1I;AA6ED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,GAAG,CAAC,cAAc,EAAE,OAAO,EAAE,GAAG,CAAC,sBAAsB,GAAG,GAAG,CAAC,cAAc,CAS1H"}
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;AAIzC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAmB,MAAM,eAAe,CAAC;AAInE,UAAU,gBAAiB,SAAQ,GAAG,CAAC,cAAc;IACjD,IAAI,EAAE,GAAG,CAAC,4BAA4B,CAAC;CAC1C;AAOD,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,wBAAsB,wBAAwB,CAC1C,IAAI,EAAE,GAAG,CAAC,cAAc,EAAE,OAAO,EAAE,GAAG,CAAC,sBAAsB,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,iBAAiB,GAC7G,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAmB7B;AAED,wBAAsB,gCAAgC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAuBpI"}
package/lib/completion.js CHANGED
@@ -24,38 +24,57 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  __setModuleDefault(result, mod);
25
25
  return result;
26
26
  };
27
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
28
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
29
+ return new (P || (P = Promise))(function (resolve, reject) {
30
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
31
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
32
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
33
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
34
+ });
35
+ };
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
27
39
  Object.defineProperty(exports, "__esModule", { value: true });
28
- exports.asResolvedCompletionItem = exports.asCompletionItem = void 0;
40
+ exports.isValidFunctionCompletionContext = exports.asResolvedCompletionItem = exports.asCompletionItem = void 0;
29
41
  const lsp = __importStar(require("vscode-languageserver/node"));
30
42
  const tsp_command_types_1 = require("./tsp-command-types");
31
43
  const protocol_translation_1 = require("./protocol-translation");
32
44
  const commands_1 = require("./commands");
45
+ const ts_protocol_1 = require("./ts-protocol");
46
+ const SnippetString_1 = __importDefault(require("./utils/SnippetString"));
47
+ const typeConverters = __importStar(require("./utils/typeConverters"));
33
48
  function asCompletionItem(entry, file, position, document) {
34
49
  const item = {
35
50
  label: entry.name,
36
51
  kind: asCompletionItemKind(entry.kind),
37
52
  sortText: entry.sortText,
38
53
  commitCharacters: asCommitCharacters(entry.kind),
54
+ preselect: entry.isRecommended,
39
55
  data: {
40
56
  file,
41
57
  line: position.line + 1,
42
58
  offset: position.character + 1,
43
59
  entryNames: [
44
- entry.source ? { name: entry.name, source: entry.source } : entry.name
60
+ entry.source || entry.data ? {
61
+ name: entry.name,
62
+ source: entry.source,
63
+ data: entry.data
64
+ } : entry.name
45
65
  ]
46
66
  }
47
67
  };
48
- if (entry.isRecommended) {
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) {
68
+ if (entry.source && entry.hasAction) {
54
69
  // De-prioritze auto-imports
55
70
  // https://github.com/Microsoft/vscode/issues/40311
56
71
  item.sortText = '\uffff' + entry.sortText;
57
72
  }
58
- if (item.kind === lsp.CompletionItemKind.Function || item.kind === lsp.CompletionItemKind.Method) {
73
+ const { sourceDisplay } = entry;
74
+ if (sourceDisplay) {
75
+ item.detail = (0, protocol_translation_1.asPlainText)(sourceDisplay);
76
+ }
77
+ if (entry.isImportStatementCompletion || item.kind === lsp.CompletionItemKind.Function || item.kind === lsp.CompletionItemKind.Method) {
59
78
  item.insertTextFormat = lsp.InsertTextFormat.Snippet;
60
79
  }
61
80
  let insertText = entry.insertText;
@@ -69,7 +88,7 @@ function asCompletionItem(entry, file, position, document) {
69
88
  }
70
89
  if (entry.kindModifiers) {
71
90
  const kindModifiers = new Set(entry.kindModifiers.split(/,|\s+/g));
72
- if (kindModifiers.has('optional')) {
91
+ if (kindModifiers.has(tsp_command_types_1.KindModifiers.optional)) {
73
92
  if (!insertText) {
74
93
  insertText = item.label;
75
94
  }
@@ -78,9 +97,25 @@ function asCompletionItem(entry, file, position, document) {
78
97
  }
79
98
  item.label += '?';
80
99
  }
81
- if (kindModifiers.has('deprecated')) {
100
+ if (kindModifiers.has(tsp_command_types_1.KindModifiers.deprecated)) {
82
101
  item.tags = [lsp.CompletionItemTag.Deprecated];
83
102
  }
103
+ if (kindModifiers.has(tsp_command_types_1.KindModifiers.color)) {
104
+ item.kind = lsp.CompletionItemKind.Color;
105
+ }
106
+ if (entry.kind === tsp_command_types_1.ScriptElementKind.scriptElement) {
107
+ for (const extModifier of tsp_command_types_1.KindModifiers.fileExtensionKindModifiers) {
108
+ if (kindModifiers.has(extModifier)) {
109
+ if (entry.name.toLowerCase().endsWith(extModifier)) {
110
+ item.detail = entry.name;
111
+ }
112
+ else {
113
+ item.detail = entry.name + extModifier;
114
+ }
115
+ break;
116
+ }
117
+ }
118
+ }
84
119
  }
85
120
  if (insertText && replacementRange) {
86
121
  item.textEdit = lsp.TextEdit.replace(replacementRange, insertText);
@@ -162,18 +197,135 @@ function asCommitCharacters(kind) {
162
197
  }
163
198
  return commitCharacters.length === 0 ? undefined : commitCharacters;
164
199
  }
165
- function asResolvedCompletionItem(item, details) {
200
+ function asResolvedCompletionItem(item, details, client, options) {
166
201
  var _a;
167
- item.detail = asDetail(details);
168
- item.documentation = (0, protocol_translation_1.asDocumentation)(details);
169
- if ((_a = details.codeActions) === null || _a === void 0 ? void 0 : _a.length) {
202
+ return __awaiter(this, void 0, void 0, function* () {
203
+ item.detail = asDetail(details);
204
+ item.documentation = (0, protocol_translation_1.asDocumentation)(details);
170
205
  const filepath = (0, protocol_translation_1.normalizePath)(item.data.file);
171
- item.additionalTextEdits = asAdditionalTextEdits(details.codeActions, filepath);
172
- item.command = asCommand(details.codeActions, item.data.file);
173
- }
174
- return item;
206
+ if ((_a = details.codeActions) === null || _a === void 0 ? void 0 : _a.length) {
207
+ item.additionalTextEdits = asAdditionalTextEdits(details.codeActions, filepath);
208
+ item.command = asCommand(details.codeActions, item.data.file);
209
+ }
210
+ if (options.completeFunctionCalls && item.insertTextFormat === lsp.InsertTextFormat.Snippet
211
+ && (item.kind === lsp.CompletionItemKind.Function || item.kind === lsp.CompletionItemKind.Method)) {
212
+ const { line, offset } = item.data;
213
+ const position = typeConverters.Position.fromLocation({ line, offset });
214
+ const shouldCompleteFunction = yield isValidFunctionCompletionContext(filepath, position, client);
215
+ if (shouldCompleteFunction) {
216
+ createSnippetOfFunctionCall(item, details);
217
+ }
218
+ }
219
+ return item;
220
+ });
175
221
  }
176
222
  exports.asResolvedCompletionItem = asResolvedCompletionItem;
223
+ function isValidFunctionCompletionContext(filepath, position, client) {
224
+ return __awaiter(this, void 0, void 0, function* () {
225
+ // Workaround for https://github.com/Microsoft/TypeScript/issues/12677
226
+ // Don't complete function calls inside of destructive assigments or imports
227
+ try {
228
+ const args = typeConverters.Position.toFileLocationRequestArgs(filepath, position);
229
+ const response = yield client.request("quickinfo" /* Quickinfo */, args);
230
+ if (response.type !== 'response') {
231
+ return true;
232
+ }
233
+ const { body } = response;
234
+ switch (body === null || body === void 0 ? void 0 : body.kind) {
235
+ case 'var':
236
+ case 'let':
237
+ case 'const':
238
+ case 'alias':
239
+ return false;
240
+ default:
241
+ return true;
242
+ }
243
+ }
244
+ catch (_a) {
245
+ return true;
246
+ }
247
+ });
248
+ }
249
+ exports.isValidFunctionCompletionContext = isValidFunctionCompletionContext;
250
+ function createSnippetOfFunctionCall(item, detail) {
251
+ const { displayParts } = detail;
252
+ const parameterListParts = getParameterListParts(displayParts);
253
+ const snippet = new SnippetString_1.default();
254
+ snippet.appendText(`${item.insertText || item.label}(`);
255
+ appendJoinedPlaceholders(snippet, parameterListParts.parts, ', ');
256
+ if (parameterListParts.hasOptionalParameters) {
257
+ snippet.appendTabstop();
258
+ }
259
+ snippet.appendText(')');
260
+ snippet.appendTabstop(0);
261
+ item.insertText = snippet.value;
262
+ }
263
+ function getParameterListParts(displayParts) {
264
+ const parts = [];
265
+ let isInMethod = false;
266
+ let hasOptionalParameters = false;
267
+ let parenCount = 0;
268
+ let braceCount = 0;
269
+ outer: for (let i = 0; i < displayParts.length; ++i) {
270
+ const part = displayParts[i];
271
+ switch (part.kind) {
272
+ case ts_protocol_1.DisplayPartKind.methodName:
273
+ case ts_protocol_1.DisplayPartKind.functionName:
274
+ case ts_protocol_1.DisplayPartKind.text:
275
+ case ts_protocol_1.DisplayPartKind.propertyName:
276
+ if (parenCount === 0 && braceCount === 0) {
277
+ isInMethod = true;
278
+ }
279
+ break;
280
+ case ts_protocol_1.DisplayPartKind.parameterName:
281
+ if (parenCount === 1 && braceCount === 0 && isInMethod) {
282
+ // Only take top level paren names
283
+ const next = displayParts[i + 1];
284
+ // Skip optional parameters
285
+ const nameIsFollowedByOptionalIndicator = next && next.text === '?';
286
+ // Skip this parameter
287
+ const nameIsThis = part.text === 'this';
288
+ if (!nameIsFollowedByOptionalIndicator && !nameIsThis) {
289
+ parts.push(part);
290
+ }
291
+ hasOptionalParameters = hasOptionalParameters || nameIsFollowedByOptionalIndicator;
292
+ }
293
+ break;
294
+ case ts_protocol_1.DisplayPartKind.punctuation:
295
+ if (part.text === '(') {
296
+ ++parenCount;
297
+ }
298
+ else if (part.text === ')') {
299
+ --parenCount;
300
+ if (parenCount <= 0 && isInMethod) {
301
+ break outer;
302
+ }
303
+ }
304
+ else if (part.text === '...' && parenCount === 1) {
305
+ // Found rest parmeter. Do not fill in any further arguments
306
+ hasOptionalParameters = true;
307
+ break outer;
308
+ }
309
+ else if (part.text === '{') {
310
+ ++braceCount;
311
+ }
312
+ else if (part.text === '}') {
313
+ --braceCount;
314
+ }
315
+ break;
316
+ }
317
+ }
318
+ return { hasOptionalParameters, parts };
319
+ }
320
+ function appendJoinedPlaceholders(snippet, parts, joiner) {
321
+ for (let i = 0; i < parts.length; ++i) {
322
+ const paramterPart = parts[i];
323
+ snippet.appendPlaceholder(paramterPart.text);
324
+ if (i !== parts.length - 1) {
325
+ snippet.appendText(joiner);
326
+ }
327
+ }
328
+ }
177
329
  function asAdditionalTextEdits(codeActions, filepath) {
178
330
  // Try to extract out the additionalTextEdits for the current file.
179
331
  const additionalTextEdits = [];