🌐 AI搜索 & 代理 主页
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
<!--toc:start-->
- [Configuration](#configuration)
- [initializationOptions](#initializationoptions)
- [`plugins` option](#plugins-option)
- [`supportsMoveToFileCodeAction` option](#supportsmovetofilecodeaction-option)
- [`tsserver` options](#tsserver-options)
- [`preferences` options](#preferences-options)
- [workspace/didChangeConfiguration](#workspacedidchangeconfiguration)
Expand All @@ -21,7 +23,8 @@ The language server accepts various settings through the `initializationOptions`
| npmLocation | string | Specifies the path to the NPM executable used for Automatic Type Acquisition. |
| locale | string | The locale to use to show error messages. |
| plugins | object[] | An array of `{ name: string, location: string, languages?: string[] }` objects for registering a Typescript plugins. **Default**: [] |
| preferences | object | Preferences passed to the Typescript (`tsserver`) process. See below for more |
| preferences | object | Preferences passed to the Typescript (`tsserver`) process. See [`preferences` options](#preferences-options) for more details. |
| supportsMoveToFileCodeAction | boolean | Whether the client supports the "Move to file" interactive code action. See [`supportsMoveToFileCodeAction` option](#supportsmovetofilecodeaction-option) for more details. |
| tsserver | object | Options related to the `tsserver` process. See below for more |

### `plugins` option
Expand All @@ -30,6 +33,33 @@ Accepts a list of `tsserver` (typescript) plugins.
The `name` and the `location` are required. The `location` is a path to the package or a directory in which `tsserver` will try to import the plugin `name` using Node's `require` API.
The `languages` property specifies which extra language IDs the language server should accept. This is required when plugin enables support for language IDs that this server does not support by default (so other than `typescript`, `typescriptreact`, `javascript`, `javascriptreact`). It's an optional property and only affects which file types the language server allows to be opened and do not concern the `tsserver` itself.

### `supportsMoveToFileCodeAction` option

The "Move to file" code action is different from other code actions as it is interactive (it needs to ask the user for a file path) and therefore requires custom implementation in the client.

In order to support it, when the user chooses the code action named "Move to file", the client should first ask the user for a file path (via a file picker or equivalent), and then send a `workspace/executeCommand` with parameters as follows:
```json
{
"command": "_typescript.applyRefactoring",
"arguments": [
{
"file": "/path/to/project/currentFile.ts",
"startLine": 1,
"startOffset": 1,
"endLine": 2,
"endOffset": 1,
"refactor": "Move to file",
"action": "Move to file",
"interactiveRefactorArguments": {
"targetFile": "/path/to/project/chosenDestinationFile.ts"
}
}
]
}
```

That is, it should use the arguments provided by the code action (like for other code actions), but also insert an additional `interactiveRefactorArguments` argument containing a `targetFile` field containing the absolute path of the file chosen by the user.

### `tsserver` options

Specifies additional options related to the internal `tsserver` process, like tracing and logging:
Expand Down
11 changes: 9 additions & 2 deletions src/lsp-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ export class LspServer {

// Setup supported features.
this.features.completionDisableFilterText = userInitializationOptions.completionDisableFilterText ?? false;
this.features.moveToFileCodeActionSupport =
userInitializationOptions.supportsMoveToFileCodeAction &&
typescriptVersion.version?.gte(API.v520);
const { textDocument } = clientCapabilities;
if (textDocument) {
const { codeAction, completion, definition, publishDiagnostics } = textDocument;
Expand Down Expand Up @@ -782,7 +785,7 @@ export class LspServer {
actions.push(...provideQuickFix(await this.getCodeFixes(fileRangeArgs, params.context, token), this.tsClient));
}
if (!kinds || kinds.some(kind => kind.contains(CodeActionKind.Refactor))) {
actions.push(...provideRefactors(await this.getRefactors(fileRangeArgs, params.context, token), fileRangeArgs, this.features));
actions.push(...provideRefactors(await this.getRefactors(fileRangeArgs, params.context, this.features, token), fileRangeArgs, this.features));
}

for (const kind of kinds || []) {
Expand Down Expand Up @@ -836,11 +839,12 @@ export class LspServer {
const response = await this.tsClient.execute(CommandTypes.GetCodeFixes, args, token);
return response.type === 'response' ? response : undefined;
}
protected async getRefactors(fileRangeArgs: ts.server.protocol.FileRangeRequestArgs, context: lsp.CodeActionContext, token?: lsp.CancellationToken): Promise<ts.server.protocol.GetApplicableRefactorsResponse | undefined> {
protected async getRefactors(fileRangeArgs: ts.server.protocol.FileRangeRequestArgs, context: lsp.CodeActionContext, features: SupportedFeatures, token?: lsp.CancellationToken): Promise<ts.server.protocol.GetApplicableRefactorsResponse | undefined> {
const args: ts.server.protocol.GetApplicableRefactorsRequestArgs = {
...fileRangeArgs,
triggerReason: context.triggerKind === lsp.CodeActionTriggerKind.Invoked ? 'invoked' : undefined,
kind: context.only?.length === 1 ? context.only[0] : undefined,
includeInteractiveActions: features.moveToFileCodeActionSupport,
};
const response = await this.tsClient.execute(CommandTypes.GetApplicableRefactors, args, token);
return response.type === 'response' ? response : undefined;
Expand All @@ -867,6 +871,9 @@ export class LspServer {
return;
}
const { body } = response;
if (body?.notApplicableReason) {
throw new Error(body.notApplicableReason);
}
if (!body?.edits.length) {
return;
}
Expand Down
12 changes: 9 additions & 3 deletions src/refactor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ export function provideRefactors(response: ts.server.protocol.GetApplicableRefac
if (info.inlineable === false) {
actions.push(asSelectRefactoring(info, args));
} else {
const relevantActions = features.codeActionDisabledSupport
? info.actions
: info.actions.filter(action => !action.notApplicableReason);
const relevantActions = info.actions.filter(action => {
if (action.notApplicableReason && !features.codeActionDisabledSupport) {
return false;
}
if (action.isInteractive && (!features.moveToFileCodeActionSupport || action.name !== 'Move to file')) {
return false;
}
return true;
});
for (const action of relevantActions) {
actions.push(asApplyRefactoring(action, info, args));
}
Expand Down
2 changes: 2 additions & 0 deletions src/ts-protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ export interface SupportedFeatures {
definitionLinkSupport?: boolean;
diagnosticsSupport?: boolean;
diagnosticsTagSupport?: boolean;
moveToFileCodeActionSupport?: boolean;
}

export interface TypeScriptPlugin {
Expand All @@ -369,6 +370,7 @@ export interface TypeScriptInitializationOptions {
npmLocation?: string;
plugins?: TypeScriptPlugin[];
preferences?: ts.server.protocol.UserPreferences;
supportsMoveToFileCodeAction?: boolean;
tsserver?: TsserverOptions;
}

Expand Down
1 change: 1 addition & 0 deletions src/utils/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export default class API {
public static readonly v490 = API.fromSimpleString('4.9.0');
public static readonly v500 = API.fromSimpleString('5.0.0');
public static readonly v510 = API.fromSimpleString('5.1.0');
public static readonly v520 = API.fromSimpleString('5.2.0');
public static readonly v540 = API.fromSimpleString('5.4.0');

public static fromVersionString(versionString: string): API {
Expand Down
Loading