6c3e92e48a
subrepo: subdir: "dotfiles/.vim/plugged/coc.nvim" merged: "7ca7cb915" upstream: origin: "https://github.com/neoclide/coc.nvim.git" branch: "master" commit: "7ca7cb915" git-subrepo: version: "0.4.3" origin: "???" commit: "???"
158 lines
5.7 KiB
TypeScript
158 lines
5.7 KiB
TypeScript
'use strict'
|
|
import { CancellationToken, ClientCapabilities, CodeAction, CodeActionContext, CodeActionKind, CodeActionOptions, CodeActionParams, CodeActionRegistrationOptions, CodeActionRequest, CodeActionResolveRequest, Command, Disposable, DocumentSelector, ExecuteCommandParams, ExecuteCommandRequest, Range, ServerCapabilities } from 'vscode-languageserver-protocol'
|
|
import { TextDocument } from "vscode-languageserver-textdocument"
|
|
import commands from '../commands'
|
|
import languages from '../languages'
|
|
import { CodeActionProvider, ProviderResult } from '../provider'
|
|
import { ExecuteCommandMiddleware, ExecuteCommandSignature } from './executeCommand'
|
|
import { ensure, FeatureClient, TextDocumentLanguageFeature } from './features'
|
|
import * as UUID from './utils/uuid'
|
|
|
|
export interface ProvideCodeActionsSignature {
|
|
(
|
|
this: void,
|
|
document: TextDocument,
|
|
range: Range,
|
|
context: CodeActionContext,
|
|
token: CancellationToken
|
|
): ProviderResult<(Command | CodeAction)[]>
|
|
}
|
|
|
|
export interface ResolveCodeActionSignature {
|
|
(this: void, item: CodeAction, token: CancellationToken): ProviderResult<CodeAction>
|
|
}
|
|
|
|
export interface CodeActionMiddleware {
|
|
provideCodeActions?: (
|
|
this: void,
|
|
document: TextDocument,
|
|
range: Range,
|
|
context: CodeActionContext,
|
|
token: CancellationToken,
|
|
next: ProvideCodeActionsSignature
|
|
) => ProviderResult<(Command | CodeAction)[]>
|
|
resolveCodeAction?: (
|
|
this: void,
|
|
item: CodeAction,
|
|
token: CancellationToken,
|
|
next: ResolveCodeActionSignature
|
|
) => ProviderResult<CodeAction>
|
|
}
|
|
|
|
export class CodeActionFeature extends TextDocumentLanguageFeature<boolean | CodeActionOptions, CodeActionRegistrationOptions, CodeActionProvider, CodeActionMiddleware & ExecuteCommandMiddleware> {
|
|
private disposables: Disposable[] = []
|
|
constructor(client: FeatureClient<CodeActionMiddleware>) {
|
|
super(client, CodeActionRequest.type)
|
|
}
|
|
|
|
public fillClientCapabilities(capabilities: ClientCapabilities): void {
|
|
const cap = ensure(ensure(capabilities, 'textDocument')!, 'codeAction')!
|
|
cap.dynamicRegistration = true
|
|
cap.isPreferredSupport = true
|
|
cap.disabledSupport = true
|
|
cap.dataSupport = true
|
|
cap.honorsChangeAnnotations = false
|
|
cap.resolveSupport = {
|
|
properties: ['edit']
|
|
}
|
|
cap.codeActionLiteralSupport = {
|
|
codeActionKind: {
|
|
valueSet: [
|
|
CodeActionKind.Empty,
|
|
CodeActionKind.QuickFix,
|
|
CodeActionKind.Refactor,
|
|
CodeActionKind.RefactorExtract,
|
|
CodeActionKind.RefactorInline,
|
|
CodeActionKind.RefactorRewrite,
|
|
CodeActionKind.Source,
|
|
CodeActionKind.SourceOrganizeImports
|
|
]
|
|
}
|
|
}
|
|
}
|
|
|
|
public initialize(
|
|
capabilities: ServerCapabilities,
|
|
documentSelector: DocumentSelector
|
|
): void {
|
|
const options = this.getRegistrationOptions(documentSelector, capabilities.codeActionProvider)
|
|
if (!options) {
|
|
return
|
|
}
|
|
|
|
this.register({
|
|
id: UUID.generateUuid(),
|
|
registerOptions: options
|
|
})
|
|
}
|
|
|
|
protected registerLanguageProvider(
|
|
options: CodeActionRegistrationOptions
|
|
): [Disposable, CodeActionProvider] {
|
|
const registerCommand = (id: string) => {
|
|
const client = this._client
|
|
const executeCommand: ExecuteCommandSignature = (command: string, args: any[]): any => {
|
|
const params: ExecuteCommandParams = {
|
|
command,
|
|
arguments: args
|
|
}
|
|
return client.sendRequest(ExecuteCommandRequest.type, params)
|
|
}
|
|
const middleware = client.middleware!
|
|
this.disposables.push(commands.registerCommand(id, (...args: any[]) => {
|
|
return middleware.executeCommand
|
|
? middleware.executeCommand(id, args, executeCommand)
|
|
: executeCommand(id, args)
|
|
}, null, true))
|
|
}
|
|
const provider: CodeActionProvider = {
|
|
provideCodeActions: (document, range, context, token) => {
|
|
const client = this._client
|
|
const _provideCodeActions: ProvideCodeActionsSignature = (document, range, context, token) => {
|
|
const params: CodeActionParams = {
|
|
textDocument: {
|
|
uri: document.uri
|
|
},
|
|
range,
|
|
context,
|
|
}
|
|
return this.sendRequest(CodeActionRequest.type, params, token).then(
|
|
values => {
|
|
if (!values) return undefined
|
|
// some server may not registered commands to client.
|
|
values.forEach(val => {
|
|
let cmd = Command.is(val) ? val.command : val.command?.command
|
|
if (cmd && !commands.has(cmd)) registerCommand(cmd)
|
|
})
|
|
return values
|
|
}
|
|
)
|
|
}
|
|
const middleware = client.middleware!
|
|
return middleware.provideCodeActions
|
|
? middleware.provideCodeActions(document, range, context, token, _provideCodeActions)
|
|
: _provideCodeActions(document, range, context, token)
|
|
},
|
|
resolveCodeAction: options.resolveProvider
|
|
? (item: CodeAction, token: CancellationToken) => {
|
|
const middleware = this._client.middleware!
|
|
const resolveCodeAction: ResolveCodeActionSignature = (item, token) => {
|
|
return this.sendRequest(CodeActionResolveRequest.type, item, token, item)
|
|
}
|
|
return middleware.resolveCodeAction
|
|
? middleware.resolveCodeAction(item, token, resolveCodeAction)
|
|
: resolveCodeAction(item, token)
|
|
}
|
|
: undefined
|
|
}
|
|
return [languages.registerCodeActionProvider(options.documentSelector, provider, this._client.id, options.codeActionKinds), provider]
|
|
}
|
|
|
|
public dispose(): void {
|
|
this.disposables.forEach(o => {
|
|
o.dispose()
|
|
})
|
|
this.disposables = []
|
|
super.dispose()
|
|
}
|
|
}
|