]> Sergey Matveev's repositories - vim-lsp.git/commitdiff
Make it possible to specify a name, pattern or number directly to "LspCodeAction"
authorAndreas Louv <andreas@louv.dk>
Sat, 11 Mar 2023 09:32:57 +0000 (10:32 +0100)
committerAndreas Louv <andreas@louv.dk>
Sat, 11 Mar 2023 10:13:51 +0000 (11:13 +0100)
autoload/lsp/codeaction.vim
autoload/lsp/lsp.vim
autoload/lsp/lspserver.vim
autoload/lsp/util.vim
doc/lsp.txt
plugin/lsp.vim
test/unit_tests.vim

index 5a34d908c7c2d8303434200c4ecd2b0d123875da..229523039a59fe73108d1885ed29e397a9f08517 100644 (file)
@@ -43,7 +43,7 @@ export def HandleCodeAction(lspserver: dict<any>, selAction: dict<any>)
   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')
@@ -61,46 +61,46 @@ export def ApplyCodeAction(lspserver: dict<any>, actions: list<dict<any>>): void
 
   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()
index e42b12a12cd354be40e40c224ccd89296cab0be2..24f41bb6dbaea429a5a1f90f3423fd11057d4ab0 100644 (file)
@@ -707,14 +707,14 @@ enddef
 
 # 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
index 16d98380013aea065742b806e47983cba9abb75e..0f6385b919ab2a8171626b0e5a587a20a9457ed3 100644 (file)
@@ -1335,7 +1335,7 @@ enddef
 # 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")
@@ -1368,7 +1368,7 @@ def CodeAction(lspserver: dict<any>, fname_arg: string, line1: number,
     return
   endif
 
-  codeaction.ApplyCodeAction(lspserver, reply.result)
+  codeaction.ApplyCodeAction(lspserver, reply.result, query)
 enddef
 
 # List project-wide symbols matching query string
index 11b160655c7344e7f40b2f675b0256f1ef06835c..091c8d221dfff36249ef2ba0896318a38ffee8a3 100644 (file)
@@ -206,4 +206,16 @@ export def JumpToLspLocation(location: dict<any>, cmdmods: 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
index f25181de71680a476a9409eeb778650fe9ebafad..0cecbe75adf154e6b119841e2a2b0dd91ce30d68 100644 (file)
@@ -330,13 +330,19 @@ A description of the various commands provided by this plugin is below.  You
 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
index c983f56cf0bf8da2a2ee24b6076d3aa7fea8d71b..8bf146b8b2244f77be7a0f010d03ac7b549e2223 100644 (file)
@@ -80,7 +80,7 @@ augroup END
 # 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()
index dd16bfde1259391b11bf47e9860bd7b73a514b2c..777649a6d8c48c7b6a257c0253219fae2bc7d090 100644 (file)
@@ -343,28 +343,59 @@ def Test_LspCodeAction()
   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'))