add command: tsserver.executeAutofix
This commit is contained in:
parent
9da6ce8838
commit
b1fcf886cc
4 changed files with 64 additions and 5 deletions
|
@ -59,6 +59,11 @@
|
|||
"title": "Run `tsc --watch` for current project in terminal buffer.",
|
||||
"category": "TSServer",
|
||||
"command": "tsserver.watchBuild"
|
||||
},
|
||||
{
|
||||
"title": "Fix autofixable problems of current document.",
|
||||
"category": "TSServer",
|
||||
"command": "tsserver.executeAutofix"
|
||||
}
|
||||
],
|
||||
"configuration": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { commands, ExtensionContext, services, workspace } from 'coc.nvim'
|
||||
import TsserverService from './server'
|
||||
import { Command, OpenTsServerLogCommand, ReloadProjectsCommand, TypeScriptGoToProjectConfigCommand } from './server/commands'
|
||||
import { Command, OpenTsServerLogCommand, AutoFixCommand, ReloadProjectsCommand, TypeScriptGoToProjectConfigCommand } from './server/commands'
|
||||
import OrganizeImportsCommand from './server/organizeImports'
|
||||
|
||||
export async function activate(context: ExtensionContext): Promise<void> {
|
||||
|
@ -22,6 +22,7 @@ export async function activate(context: ExtensionContext): Promise<void> {
|
|||
subscriptions.push(commands.registerCommand(id as string, execute, cmd))
|
||||
}
|
||||
|
||||
registCommand(new AutoFixCommand(service.clientHost))
|
||||
registCommand(new ReloadProjectsCommand(service.clientHost))
|
||||
registCommand(new OpenTsServerLogCommand(service.clientHost))
|
||||
registCommand(new TypeScriptGoToProjectConfigCommand(service.clientHost))
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { diagnosticManager, workspace } from 'coc.nvim'
|
||||
import { CancellationToken } from 'vscode-languageserver-protocol'
|
||||
import URI from 'vscode-uri'
|
||||
import { workspace } from 'coc.nvim'
|
||||
import { ProjectInfoResponse } from './protocol'
|
||||
import * as Proto from './protocol'
|
||||
import TypeScriptServiceClientHost from './typescriptServiceClientHost'
|
||||
import * as typeConverters from './utils/typeConverters'
|
||||
import { WorkspaceEdit, TextEdit } from 'vscode-languageserver-types'
|
||||
|
||||
export interface Command {
|
||||
readonly id: string | string[]
|
||||
|
@ -54,7 +56,7 @@ async function goToProjectConfig(clientHost: TypeScriptServiceClientHost, uri: s
|
|||
}
|
||||
const client = clientHost.serviceClient
|
||||
const file = client.toPath(uri)
|
||||
let res: ProjectInfoResponse | undefined
|
||||
let res: Proto.ProjectInfoResponse | undefined
|
||||
try {
|
||||
res = await client.execute('projectInfo', { file, needFileNameList: false }, CancellationToken.None)
|
||||
} catch {
|
||||
|
@ -77,3 +79,54 @@ async function goToProjectConfig(clientHost: TypeScriptServiceClientHost, uri: s
|
|||
function isImplicitProjectConfigFile(configFileName: string): boolean {
|
||||
return configFileName.indexOf('/dev/null/') === 0
|
||||
}
|
||||
|
||||
const autoFixableDiagnosticCodes = new Set<number>([
|
||||
2420, // Incorrectly implemented interface
|
||||
2552, // Cannot find name
|
||||
2304, // Cannot find name
|
||||
])
|
||||
|
||||
export class AutoFixCommand implements Command {
|
||||
public readonly id = 'tsserver.executeAutofix'
|
||||
|
||||
constructor(private client: TypeScriptServiceClientHost) {
|
||||
}
|
||||
|
||||
public async execute(): Promise<void> {
|
||||
let document = await workspace.document
|
||||
if (!this.client.handles(document.uri)) {
|
||||
workspace.showMessage('Document is not handled by tsserver.', 'warning')
|
||||
return
|
||||
}
|
||||
let file = this.client.serviceClient.toPath(document.uri)
|
||||
let diagnostics = diagnosticManager.getDiagnostics(document.uri)
|
||||
diagnostics = diagnostics.filter(x => autoFixableDiagnosticCodes.has(x.code as number))
|
||||
if (diagnostics.length == 0) {
|
||||
workspace.showMessage('No autofixable diagnostics found', 'warning')
|
||||
}
|
||||
let client = this.client.serviceClient
|
||||
let edits: TextEdit[] = []
|
||||
for (let diagnostic of diagnostics) {
|
||||
const args: Proto.CodeFixRequestArgs = {
|
||||
...typeConverters.Range.toFileRangeRequestArgs(file, diagnostic.range),
|
||||
errorCodes: [+(diagnostic.code!)]
|
||||
}
|
||||
const response: Proto.GetCodeFixesResponse = await client.execute('getCodeFixes', args)
|
||||
if (response.type !== 'response' || !response.body || response.body.length < 1) {
|
||||
continue
|
||||
}
|
||||
const fix = response.body[0]
|
||||
for (let change of fix.changes) {
|
||||
if (change.fileName != file) continue
|
||||
// change.fileName
|
||||
for (let ch of change.textChanges) {
|
||||
edits.push({
|
||||
range: typeConverters.Range.fromTextSpan(ch),
|
||||
newText: ch.newText
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
if (edits.length) await document.applyEdits(workspace.nvim, edits)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -815,7 +815,7 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
|
|||
public getProjectRootPath(uri: string): string {
|
||||
let u = Uri.parse(uri)
|
||||
if (u.scheme != 'file') return workspace.root
|
||||
let res = findUp.sync(['tsconfig.json', 'jsconfig.json', 'package.json'], { cwd: path.dirname(u.fsPath) })
|
||||
let res = findUp.sync(['package.json', 'tsconfig.json', 'jsconfig.json'], { cwd: path.dirname(u.fsPath) })
|
||||
return res ? path.dirname(res) : workspace.rootPath
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue