add organizeImports codeAction
This commit is contained in:
parent
e316d80577
commit
26bb4b4872
5 changed files with 58 additions and 34 deletions
|
@ -115,11 +115,6 @@
|
||||||
"default": "",
|
"default": "",
|
||||||
"description": "Folder path for cache typings"
|
"description": "Folder path for cache typings"
|
||||||
},
|
},
|
||||||
"tsserver.orgnizeImportOnSave": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false,
|
|
||||||
"description": "Orgnize import on buffer will save"
|
|
||||||
},
|
|
||||||
"tsserver.formatOnType": {
|
"tsserver.formatOnType": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true,
|
"default": true,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { commands, ExtensionContext, services, workspace } from 'coc.nvim'
|
import { commands, ExtensionContext, services, workspace } from 'coc.nvim'
|
||||||
import TsserverService from './server'
|
import TsserverService from './server'
|
||||||
import { AutoFixCommand, Command, ConfigurePluginCommand, OpenTsServerLogCommand, ReloadProjectsCommand, TypeScriptGoToProjectConfigCommand } from './server/commands'
|
import { AutoFixCommand, Command, ConfigurePluginCommand, OpenTsServerLogCommand, ReloadProjectsCommand, TypeScriptGoToProjectConfigCommand } from './server/commands'
|
||||||
import OrganizeImportsCommand from './server/organizeImports'
|
import { OrganizeImportsCommand } from './server/organizeImports'
|
||||||
import { PluginManager } from './utils/plugins'
|
import { PluginManager } from './utils/plugins'
|
||||||
|
|
||||||
interface API {
|
interface API {
|
||||||
|
@ -30,7 +30,7 @@ export async function activate(context: ExtensionContext): Promise<API> {
|
||||||
registCommand(new ReloadProjectsCommand(service.clientHost))
|
registCommand(new ReloadProjectsCommand(service.clientHost))
|
||||||
registCommand(new OpenTsServerLogCommand(service.clientHost))
|
registCommand(new OpenTsServerLogCommand(service.clientHost))
|
||||||
registCommand(new TypeScriptGoToProjectConfigCommand(service.clientHost))
|
registCommand(new TypeScriptGoToProjectConfigCommand(service.clientHost))
|
||||||
registCommand(new OrganizeImportsCommand(service.clientHost))
|
registCommand(new OrganizeImportsCommand(service.clientHost.serviceClient))
|
||||||
registCommand(new ConfigurePluginCommand(pluginManager))
|
registCommand(new ConfigurePluginCommand(pluginManager))
|
||||||
registCommand(commands.register({
|
registCommand(commands.register({
|
||||||
id: 'tsserver.restart',
|
id: 'tsserver.restart',
|
||||||
|
|
|
@ -300,7 +300,7 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
|
||||||
if (additionalTextEdits.length && this.noSemicolons) {
|
if (additionalTextEdits.length && this.noSemicolons) {
|
||||||
// remove comma
|
// remove comma
|
||||||
additionalTextEdits.forEach(o => {
|
additionalTextEdits.forEach(o => {
|
||||||
o.newText = o.newText.replace(/;/g, '')
|
o.newText = o.newText.replace(/;(?:(\n|$))/g, '')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -34,6 +34,7 @@ import InstallModuleProvider from './features/moduleInstall'
|
||||||
import API from './utils/api'
|
import API from './utils/api'
|
||||||
import { LanguageDescription } from './utils/languageDescription'
|
import { LanguageDescription } from './utils/languageDescription'
|
||||||
import TypingsStatus from './utils/typingsStatus'
|
import TypingsStatus from './utils/typingsStatus'
|
||||||
|
import { OrganizeImportsCodeActionProvider } from './organizeImports'
|
||||||
|
|
||||||
const validateSetting = 'validate.enable'
|
const validateSetting = 'validate.enable'
|
||||||
const suggestionSetting = 'suggestionActions.enabled'
|
const suggestionSetting = 'suggestionActions.enabled'
|
||||||
|
@ -220,6 +221,11 @@ export default class LanguageProvider {
|
||||||
this.disposables.push(
|
this.disposables.push(
|
||||||
languages.registerFoldingRangeProvider(languageIds, new Folding(this.client))
|
languages.registerFoldingRangeProvider(languageIds, new Folding(this.client))
|
||||||
)
|
)
|
||||||
|
this.disposables.push(
|
||||||
|
languages.registerCodeActionProvider(languageIds,
|
||||||
|
new OrganizeImportsCodeActionProvider(this.client, this.fileConfigurationManager),
|
||||||
|
`tsserver-${this.description.id}`, [CodeActionKind.SourceOrganizeImports])
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let { fileConfigurationManager } = this
|
let { fileConfigurationManager } = this
|
||||||
|
|
|
@ -2,40 +2,26 @@
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
import { TextDocumentWillSaveEvent, workspace } from 'coc.nvim'
|
import { workspace, CodeActionProvider, CodeActionProviderMetadata } from 'coc.nvim'
|
||||||
import { TextDocument, TextEdit, WorkspaceEdit, CancellationToken } from 'vscode-languageserver-protocol'
|
import { CancellationToken, Range, TextDocument, CodeActionContext, WorkspaceEdit, CodeActionKind, CodeAction } from 'vscode-languageserver-protocol'
|
||||||
import { Command } from './commands'
|
import { Command } from './commands'
|
||||||
import Proto from './protocol'
|
import Proto from './protocol'
|
||||||
import TypeScriptServiceClientHost from './typescriptServiceClientHost'
|
|
||||||
import { standardLanguageDescriptions } from './utils/languageDescription'
|
import { standardLanguageDescriptions } from './utils/languageDescription'
|
||||||
import { languageIds } from './utils/languageModeIds'
|
import { languageIds } from './utils/languageModeIds'
|
||||||
import * as typeconverts from './utils/typeConverters'
|
import * as typeconverts from './utils/typeConverters'
|
||||||
|
import FileConfigurationManager from './features/fileConfigurationManager'
|
||||||
|
import TypeScriptServiceClient from './typescriptServiceClient'
|
||||||
|
|
||||||
export default class OrganizeImportsCommand implements Command {
|
export class OrganizeImportsCommand implements Command {
|
||||||
public readonly id: string = 'tsserver.organizeImports'
|
public readonly id: string = 'tsserver.organizeImports'
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly client: TypeScriptServiceClientHost
|
private readonly client: TypeScriptServiceClient
|
||||||
) {
|
) {
|
||||||
workspace.onWillSaveUntil(this.onWillSaveUntil, this, 'tsserver')
|
|
||||||
}
|
|
||||||
|
|
||||||
private onWillSaveUntil(event: TextDocumentWillSaveEvent): void {
|
|
||||||
let config = workspace.getConfiguration('tsserver')
|
|
||||||
let format = config.get('orgnizeImportOnSave', false)
|
|
||||||
if (!format) return
|
|
||||||
let { document } = event
|
|
||||||
if (languageIds.indexOf(document.languageId) == -1) return
|
|
||||||
let willSaveWaitUntil = async (): Promise<TextEdit[]> => {
|
|
||||||
let edit = await this.getTextEdits(document)
|
|
||||||
if (!edit) return []
|
|
||||||
return edit.changes ? edit.changes[document.uri] : []
|
|
||||||
}
|
|
||||||
event.waitUntil(willSaveWaitUntil())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getTextEdits(document: TextDocument): Promise<WorkspaceEdit | null> {
|
private async getTextEdits(document: TextDocument): Promise<WorkspaceEdit | null> {
|
||||||
let client = this.client.serviceClient
|
let client = this.client
|
||||||
let file = client.toPath(document.uri)
|
let file = client.toPath(document.uri)
|
||||||
const args: Proto.OrganizeImportsRequestArgs = {
|
const args: Proto.OrganizeImportsRequestArgs = {
|
||||||
scope: {
|
scope: {
|
||||||
|
@ -64,7 +50,7 @@ export default class OrganizeImportsCommand implements Command {
|
||||||
if (changes) {
|
if (changes) {
|
||||||
for (let c of Object.keys(changes)) {
|
for (let c of Object.keys(changes)) {
|
||||||
for (let textEdit of changes[c]) {
|
for (let textEdit of changes[c]) {
|
||||||
textEdit.newText = textEdit.newText.replace(/;/g, '')
|
textEdit.newText = textEdit.newText.replace(/;(?:(\n|$))/g, '')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,11 +58,48 @@ export default class OrganizeImportsCommand implements Command {
|
||||||
return edit
|
return edit
|
||||||
}
|
}
|
||||||
|
|
||||||
public async execute(): Promise<void> {
|
public async execute(document?: TextDocument): Promise<void> {
|
||||||
let document = await workspace.document
|
if (!document) {
|
||||||
if (languageIds.indexOf(document.filetype) == -1) return
|
let doc = await workspace.document
|
||||||
let edit = await this.getTextEdits(document.textDocument)
|
if (languageIds.indexOf(doc.filetype) == -1) return
|
||||||
|
document = doc.textDocument
|
||||||
|
}
|
||||||
|
let edit = await this.getTextEdits(document)
|
||||||
if (edit) await workspace.applyEdit(edit)
|
if (edit) await workspace.applyEdit(edit)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class OrganizeImportsCodeActionProvider implements CodeActionProvider {
|
||||||
|
// public static readonly minVersion = API.v280
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
private readonly client: TypeScriptServiceClient,
|
||||||
|
private readonly fileConfigManager: FileConfigurationManager,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly metadata: CodeActionProviderMetadata = {
|
||||||
|
providedCodeActionKinds: [CodeActionKind.SourceOrganizeImports]
|
||||||
|
}
|
||||||
|
|
||||||
|
public provideCodeActions(
|
||||||
|
document: TextDocument,
|
||||||
|
_range: Range,
|
||||||
|
context: CodeActionContext,
|
||||||
|
_token: CancellationToken
|
||||||
|
): CodeAction[] {
|
||||||
|
if (languageIds.indexOf(document.languageId) == -1) return
|
||||||
|
|
||||||
|
if (!context.only || !context.only.includes(CodeActionKind.SourceOrganizeImports)) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const action = CodeAction.create('Organize Imports', {
|
||||||
|
title: '',
|
||||||
|
command: 'tsserver.organizeImports',
|
||||||
|
arguments: [document]
|
||||||
|
}, CodeActionKind.SourceOrganizeImports)
|
||||||
|
return [action]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue