Skip to content

Commit

Permalink
feat(handler): support only as title for codeAction
Browse files Browse the repository at this point in the history
  • Loading branch information
chemzqm committed Jun 6, 2019
1 parent 7d63e28 commit e88b86e
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 70 deletions.
9 changes: 6 additions & 3 deletions doc/coc.cnx
Original file line number Diff line number Diff line change
Expand Up @@ -780,12 +780,14 @@ CocActionAsync({action}, [...{args}, [{callback}]])
如果不提供 {mode}, 该函数必须设置为 |formatexpr| 使用。


"codeAction" [{mode}] *coc-action-codeAction*
"codeAction" [{mode}] [{only}] *coc-action-codeAction*

执行 codeAction。

{mode} 为 visualmode() 返回结果。

{only} 可以是莫个 codeAction 的 title,或者是 CodeActionKind 列表

"codeLensAction" *coc-action-codeLensAction*

执行 codeLens 给出的 codeAction。
Expand Down Expand Up @@ -868,9 +870,10 @@ CocActionAsync({action}, [...{args}, [{callback}]])

推荐安装 coc-highlight 插件在所有文件中支持该功能。

"quickfixes" *coc-action-quickfixes*
"quickfixes" [{visualmode}] *coc-action-quickfixes*

获取当前缓冲区的 quickfix codeActions。
获取当前行的 quickfix codeActions,指定 {visualmode}
获取上一次选择区间的中的 quickfixes.

"doCodeAction" {codeAction} *coc-action-doCodeAction*

Expand Down
16 changes: 8 additions & 8 deletions doc/coc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1305,12 +1305,14 @@ Available Actions ~
When {mode} is omitted, it should be called using |formatexpr|.


"codeAction" [{mode}] *coc-action-codeAction*
"codeAction" [{mode}] [{only}] *coc-action-codeAction*

Prompt for a code action and do it.

{mode} should be result of visualmode(), when used in visualmode,
could be empty string for none visualmode.
could be empty string or v:null for none visualmode.

{only} can be title of a codeAction or list of CodeActionKind.


"codeLensAction" *coc-action-codeLensAction*
Expand Down Expand Up @@ -1391,17 +1393,15 @@ Available Actions ~

Change the color presentation at the current color position.

Requires a language server that supports color representation
Requires a language server that supports color representation
requests.

"quickfixes" [{lnum}] *coc-action-quickfixes*
"quickfixes" [{visualmode}] *coc-action-quickfixes*

Get quickfix codeActions of current buffer.

Add {lnum} as second argument fi get codeActions of that line.

Could be used with |CocDiagnosticChange| autocmd to get available fix
actions.
Add {visualmode} as second argument get quickfix actions with range of
latest |visualmode()|

"doCodeAction" {codeAction} *coc-action-doCodeAction*

Expand Down
2 changes: 1 addition & 1 deletion plugin/coc.vim
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,10 @@ call s:Enable()
nnoremap <Plug>(coc-codelens-action) :<C-u>call CocActionAsync('codeLensAction')<CR>
vnoremap <Plug>(coc-format-selected) :<C-u>call CocActionAsync('formatSelected', visualmode())<CR>
vnoremap <Plug>(coc-codeaction-selected) :<C-u>call CocActionAsync('codeAction', visualmode())<CR>
nnoremap <Plug>(coc-codeaction-selected) :<C-u>set operatorfunc=<SID>CodeActionFromSelected<CR>g@
nnoremap <Plug>(coc-codeaction) :<C-u>call CocActionAsync('codeAction', '')<CR>
nnoremap <Plug>(coc-rename) :<C-u>call CocActionAsync('rename')<CR>
nnoremap <Plug>(coc-format-selected) :<C-u>set operatorfunc=<SID>FormatFromSelected<CR>g@
nnoremap <Plug>(coc-codeaction-selected) :<C-u>set operatorfunc=<SID>CodeActionFromSelected<CR>g@
nnoremap <Plug>(coc-format) :<C-u>call CocActionAsync('format')<CR>
nnoremap <Plug>(coc-diagnostic-info) :<C-u>call CocActionAsync('diagnosticInfo')<CR>
nnoremap <Plug>(coc-diagnostic-next) :<C-u>call CocActionAsync('diagnosticNext')<CR>
Expand Down
84 changes: 37 additions & 47 deletions src/handler/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NeovimClient as Neovim } from '@chemzqm/neovim'
import binarySearch from 'binary-search'
import { CancellationTokenSource, CodeActionContext, CodeActionKind, Definition, Disposable, DocumentLink, DocumentSymbol, ExecuteCommandParams, ExecuteCommandRequest, Hover, Location, LocationLink, MarkedString, MarkupContent, Position, Range, SymbolInformation, TextEdit } from 'vscode-languageserver-protocol'
import { CancellationTokenSource, CodeActionContext, CodeActionKind, Definition, Disposable, DocumentLink, DocumentSymbol, ExecuteCommandParams, ExecuteCommandRequest, Hover, Location, LocationLink, MarkedString, MarkupContent, Position, Range, SymbolInformation, TextEdit, TextDocument } from 'vscode-languageserver-protocol'
import { SelectionRange } from 'vscode-languageserver-protocol/lib/protocol.selectionRange.proposed'
import { Document } from '..'
import commandManager from '../commands'
Expand Down Expand Up @@ -442,13 +442,10 @@ export default class Handler {
}
}

public async doCodeAction(mode: string | null, only?: CodeActionKind[]): Promise<void> {
let document = await workspace.document
if (!document) return
let range: Range
if (mode) {
range = await workspace.getSelectedRange(mode, document.textDocument)
} else {
public async getCodeActions(bufnr: number, range?: Range, only?: CodeActionKind[]): Promise<CodeAction[]> {
let document = workspace.getDocument(bufnr)
if (!document) return []
if (!range) {
let lnum = await this.nvim.call('line', ['.'])
range = {
start: { line: lnum - 1, character: 0 },
Expand All @@ -457,9 +454,9 @@ export default class Handler {
}
let diagnostics = diagnosticManager.getDiagnosticsInRange(document.textDocument, range)
let context: CodeActionContext = { diagnostics }
if (only) context.only = only
if (only && Array.isArray(only)) context.only = only
let codeActionsMap = await languages.getCodeActions(document.textDocument, range, context)
if (!codeActionsMap) return workspace.showMessage('No action available', 'warning')
if (!codeActionsMap) return []
let codeActions: CodeAction[] = []
for (let clientId of codeActionsMap.keys()) {
let actions = codeActionsMap.get(clientId)
Expand All @@ -476,10 +473,28 @@ export default class Handler {
}
return 0
})
let idx = await workspace.showQuickpick(codeActions.map(o => o.title))
if (idx == -1) return
let action = codeActions[idx]
if (action) await this.applyCodeAction(action)
return codeActions
}

public async doCodeAction(mode: string | null, only?: CodeActionKind[] | string): Promise<void> {
let bufnr = await this.nvim.call('bufnr', '%')
let range: Range
if (mode) range = await workspace.getSelectedRange(mode, workspace.getDocument(bufnr).textDocument)
let codeActions = await this.getCodeActions(bufnr, range, Array.isArray(only) ? only : null)
if (!codeActions || codeActions.length == 0) {
workspace.showMessage('No action available', 'warning')
return
}
if (only && typeof only == 'string') {
let action = codeActions.find(o => o.title == only || (o.command && o.command.title == only))
if (!action) return workspace.showMessage(`action "${only}" not found.`, 'warning')
await this.applyCodeAction(action)
} else {
let idx = await workspace.showQuickpick(codeActions.map(o => o.title))
if (idx == -1) return
let action = codeActions[idx]
if (action) await this.applyCodeAction(action)
}
}

/**
Expand All @@ -488,44 +503,19 @@ export default class Handler {
* @public
* @returns {Promise<CodeAction[]>}
*/
public async getQuickfixActions(range?: Range): Promise<CodeAction[]> {
let document = await workspace.document
public async getQuickfixActions(mode?: string): Promise<CodeAction[]> {
let bufnr = await this.nvim.call('bufnr', '%') as number
let document = workspace.getDocument(bufnr)
if (!document) return []
range = range || Range.create(0, 0, document.lineCount, 0)
let diagnostics = diagnosticManager.getDiagnosticsInRange(document.textDocument, range)
let context: CodeActionContext = { diagnostics, only: [CodeActionKind.QuickFix] }
let codeActionsMap = await languages.getCodeActions(document.textDocument, range, context, true)
if (!codeActionsMap) return []
let codeActions: CodeAction[] = []
for (let clientId of codeActionsMap.keys()) {
let actions = codeActionsMap.get(clientId)
for (let action of actions) {
if (action.kind !== CodeActionKind.QuickFix) continue
codeActions.push({ clientId, ...action })
}
}
codeActions.sort((a, b) => {
if (a.isPrefered && !b.isPrefered) {
return -1
}
if (b.isPrefered && !a.isPrefered) {
return 1
}
return 0
})
logger.debug('actions:', codeActions)
return codeActions
let range: Range
if (mode) range = await workspace.getSelectedRange(mode, workspace.getDocument(bufnr).textDocument)
return await this.getCodeActions(bufnr, range, [CodeActionKind.QuickFix])
}

public async doQuickfix(): Promise<void> {
let lnum = await this.nvim.call('line', ['.'])
let range: Range = {
start: { line: lnum - 1, character: 0 },
end: { line: lnum, character: 0 }
}
let actions = await this.getQuickfixActions(range)
let actions = await this.getQuickfixActions()
if (!actions || actions.length == 0) {
return workspace.showMessage('No action available', 'warning')
return workspace.showMessage('No quickfix action available', 'warning')
}
await this.applyCodeAction(actions[0])
await this.nvim.command(`silent! call repeat#set("\\<Plug>(coc-fix-current)", -1)`)
Expand Down
15 changes: 4 additions & 11 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -406,26 +406,19 @@ export default class Plugin extends EventEmitter {
case 'toggleService':
return services.toggle(args[1])
case 'codeAction':
return handler.doCodeAction(args[1])
return handler.doCodeAction(args[1], args[2])
case 'doCodeAction':
return await handler.applyCodeAction(args[1])
case 'codeLensAction':
return handler.doCodeLensAction()
case 'runCommand':
return await handler.runCommand(...args.slice(1))
case 'quickfixes':
let range
if (args[1]) {
range = {
start: { line: args[1] - 1, character: 0 },
end: { line: args[1], character: 0 }
}
}
return await handler.getQuickfixActions(range)
return await handler.getQuickfixActions(args[1])
case 'doQuickfix':
return await handler.doQuickfix()
case 'repeatCommand':
return await commandManager.repeatCommand()
case 'doCodeAction':
return await handler.applyCodeAction(args[1])
case 'extensionStats':
return await extensions.getExtensionStates()
case 'activeExtension':
Expand Down

0 comments on commit e88b86e

Please sign in to comment.