endif
enddef
-export def ApplyCodeAction(lspserver: dict<any>, actions: list<dict<any>>): void
+export def ApplyCodeAction(lspserver: dict<any>, actions: list<dict<any>>, query: string): void
if actions->empty()
# no action can be performed
util.WarnMsg('No code action is available')
var choice: number
- if exists('g:LSPTest') && g:LSPTest && exists('g:LSPTest_CodeActionChoice')
- # Running the LSP unit-tests. Instead of prompting the user, use the
- # choice set in LSPTest_CodeActionChoice.
- choice = g:LSPTest_CodeActionChoice
- else
- if opt.lspOptions.usePopupInCodeAction
- # Use a popup menu to show the code action
- popup_create(text, {
- pos: 'botleft',
- line: 'cursor-1',
- col: 'cursor',
- zindex: 1000,
- cursorline: 1,
- mapping: 0,
- wrap: 0,
- title: 'Code action',
- callback: (_, result) => {
- # Invalid item selected or closed the popup
- if result <= 0 || result > text->len()
- return
- endif
+ if query =~ '^\d\+' # digit
+ choice = str2nr(query)
+ elseif query =~ '^/' # regex
+ choice = 1 + util.Indexof(actions, (i, a) => a.title =~ query[1 : ])
+ elseif query != '' # literal string
+ choice = 1 + util.Indexof(actions, (i, a) => a.title[0 : query->len() - 1] == query)
+ elseif opt.lspOptions.usePopupInCodeAction
+ # Use a popup menu to show the code action
+ popup_create(text, {
+ pos: 'botleft',
+ line: 'cursor-1',
+ col: 'cursor',
+ zindex: 1000,
+ cursorline: 1,
+ mapping: 0,
+ wrap: 0,
+ title: 'Code action',
+ callback: (_, result) => {
+ # Invalid item selected or closed the popup
+ if result <= 0 || result > text->len()
+ return
+ endif
- # Do the code action
- HandleCodeAction(lspserver, actions[result - 1])
- },
- filter: (winid, key) => {
- if key == 'h' || key == 'l'
- winid->popup_close(-1)
- elseif key->str2nr() > 0
- # assume less than 10 entries are present
- winid->popup_close(key->str2nr())
- else
- return popup_filter_menu(winid, key)
- endif
- return 1
- },
- })
- else
- choice = inputlist(["Code action:"] + text)
- endif
+ # Do the code action
+ HandleCodeAction(lspserver, actions[result - 1])
+ },
+ filter: (winid, key) => {
+ if key == 'h' || key == 'l'
+ winid->popup_close(-1)
+ elseif key->str2nr() > 0
+ # assume less than 10 entries are present
+ winid->popup_close(key->str2nr())
+ else
+ return popup_filter_menu(winid, key)
+ endif
+ return 1
+ },
+ })
+ else
+ choice = inputlist(["Code action:"] + text)
endif
if choice < 1 || choice > text->len()
# Perform a code action
# Uses LSP "textDocument/codeAction" request
-export def CodeAction(line1: number, line2: number)
+export def CodeAction(line1: number, line2: number, query: string)
var lspserver: dict<any> = buf.CurbufGetServerChecked()
if lspserver->empty()
return
endif
var fname: string = @%
- lspserver.codeAction(fname, line1, line2)
+ lspserver.codeAction(fname, line1, line2, query)
enddef
# Perform a workspace wide symbol lookup
# Request: "textDocument/codeAction"
# Param: CodeActionParams
def CodeAction(lspserver: dict<any>, fname_arg: string, line1: number,
- line2: number)
+ line2: number, query: string)
# Check whether LSP server supports code action operation
if !lspserver.isCodeActionProvider
util.ErrMsg("Error: LSP server does not support code action operation")
return
endif
- codeaction.ApplyCodeAction(lspserver, reply.result)
+ codeaction.ApplyCodeAction(lspserver, reply.result, query)
enddef
# List project-wide symbols matching query string
location.targetSelectionRange.start.character + 1)
enddef
+# 'indexof' is to new to use it, use this instead.
+export def Indexof(list: list<any>, CallbackFn: func(number, any): bool): number
+ var ix = 0
+ for val in list
+ if CallbackFn(ix, val)
+ return ix
+ endif
+ ix += 1
+ endfor
+ return -1
+enddef
+
# vim: tabstop=8 shiftwidth=2 softtabstop=2
can map these commands to keys and make it easier to invoke them.
*:LspCodeAction*
-:LspCodeAction Apply the code action supplied by the language server
+:LspCodeAction [query] Apply the code action supplied by the language server
to the diagnostic in the current line. This works only
if there is a diagnostic message for the current line.
You can use the |:LspDiagCurrent| command to display
- the diagnostic for the current line. You will be
- prompted to select one of the actions supplied by the
- language server.
+ the diagnostic for the current line.
+
+ When [query] is given the code action starting with
+ [query] will be applied. [query] can be a regexp
+ pattern, or a digit corresponding to the index of the
+ code actions in the created prompt.
+
+ When [query] is not given you will be prompted to select
+ one of the actions supplied by the language server.
*:LspDiagCurrent*
:LspDiagCurrent Displays the diagnostic message (if any) for the
# autocmd VimLeavePre * call lsp.StopAllServers()
# LSP commands
-command! -nargs=0 -bar -range LspCodeAction lsp.CodeAction(<line1>, <line2>)
+command! -nargs=? -bar -range LspCodeAction lsp.CodeAction(<line1>, <line2>, <q-args>)
command! -nargs=0 -bar LspDiagCurrent lsp.LspShowCurrentDiag()
command! -nargs=0 -bar LspDiagFirst lsp.JumpToDiag('first')
command! -nargs=0 -bar LspDiagHighlightDisable lsp.DiagHighlightDisable()
sleep 1
cursor(4, 1)
redraw!
- g:LSPTest_CodeActionChoice = 1
- :LspCodeAction
+ :LspCodeAction 1
assert_equal("\tcount = 20;", getline(4))
setline(4, "\tcount = 20:")
cursor(4, 1)
sleep 500m
- g:LSPTest_CodeActionChoice = 0
- :LspCodeAction
+ :LspCodeAction 0
assert_equal("\tcount = 20:", getline(4))
- g:LSPTest_CodeActionChoice = 2
cursor(4, 1)
- :LspCodeAction
+ :LspCodeAction 2
assert_equal("\tcount = 20:", getline(4))
- g:LSPTest_CodeActionChoice = 1
cursor(4, 1)
- :LspCodeAction
+ :LspCodeAction 1
assert_equal("\tcount = 20;", getline(4))
bw!
+ # pattern and string prefix
+ silent! edit Xtest.c
+ sleep 200m
+ var lines2: list<string> =<< trim END
+ void testFunc()
+ {
+ int count;
+ if (count = 1) {
+ }
+ }
+ END
+ setline(1, lines2)
+ sleep 1
+ cursor(4, 1)
+ redraw!
+ :LspCodeAction use
+ assert_equal("\tif (count == 1) {", getline(4))
+
+ setline(4, "\tif (count = 1) {")
+ cursor(4, 1)
+ sleep 500m
+ :LspCodeAction /paren
+ assert_equal("\tif ((count = 1)) {", getline(4))
+
+ setline(4, "\tif (count = 1) {")
+ cursor(4, 1)
+ sleep 500m
+ :LspCodeAction NON_EXISTING_PREFIX
+ assert_equal("\tif (count = 1) {", getline(4))
+
+ cursor(4, 1)
+ :LspCodeAction /NON_EXISTING_REGEX
+ assert_equal("\tif (count = 1) {", getline(4))
+ bw!
+
# empty file
assert_equal('', execute('LspCodeAction'))