]> Sergey Matveev's repositories - vim-lsp.git/commitdiff
Create custom popup for code action and added a option to enable/disable it
authorD4yvid <kkd4yv1d@gmail.com>
Thu, 27 Oct 2022 00:13:19 +0000 (21:13 -0300)
committerD4yvid <kkd4yv1d@gmail.com>
Thu, 27 Oct 2022 00:13:19 +0000 (21:13 -0300)
autoload/lsp/codeaction.vim
autoload/lsp/options.vim

index 761afb8a8c4b8ecd29a786da290ed1346982dce2..578603f858652eb04aa6112c6f6eb6bf2b47874d 100644 (file)
@@ -4,6 +4,28 @@ vim9script
 
 import './util.vim'
 import './textedit.vim'
+import './options.vim' as opt
+
+export def HandleCodeAction(lspserver: dict<any>, selAction: dict<any>)
+  # textDocument/codeAction can return either Command[] or CodeAction[].
+  # If it is a CodeAction, it can have either an edit, a command or both.
+  # Edits should be executed first.
+  if selAction->has_key('edit') || selAction->has_key('command')
+    if selAction->has_key('edit')
+      # apply edit first
+      textedit.ApplyWorkspaceEdit(selAction.edit)
+    endif
+    if selAction->has_key('command')
+      lspserver.executeCommand(selAction)
+    endif
+  else
+    lspserver.executeCommand(selAction)
+  endif
+enddef
+
+def Print(a: any)
+  echo string(a)
+enddef
 
 export def ApplyCodeAction(lspserver: dict<any>, actions: list<dict<any>>): void
   if actions->empty()
@@ -12,13 +34,13 @@ export def ApplyCodeAction(lspserver: dict<any>, actions: list<dict<any>>): void
     return
   endif
 
-  var prompt: list<string> = ['Code Actions:']
+  var text: list<string> = []
   var act: dict<any>
   for i in range(actions->len())
     act = actions[i]
     var t: string = act.title->substitute('\r\n', '\\r\\n', 'g')
     t = t->substitute('\n', '\\n', 'g')
-    prompt->add(printf("%d. %s", i + 1, t))
+    text->add(printf(" %d. %s ", i + 1, t))
   endfor
 
   var choice: number
@@ -28,28 +50,38 @@ export def ApplyCodeAction(lspserver: dict<any>, actions: list<dict<any>>): void
     # choice set in LSPTest_CodeActionChoice.
     choice = g:LSPTest_CodeActionChoice
   else
-    choice = inputlist(prompt)
+    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: (_, id) => {
+          # Invalid item selected or closed the popup
+          if id <= 0 || id > text->len()
+            return
+          endif
+
+          # Do the code action
+          HandleCodeAction(lspserver, actions[id - 1])
+        },
+        filter: 'popup_filter_menu'
+      })
+    else
+      choice = inputlist(["Code action:"] + text)
+    endif
   endif
 
-  if choice < 1 || choice >= prompt->len()
+  if choice < 1 || choice > text->len()
     return
   endif
-  var selAction = actions[choice - 1]
 
-  # textDocument/codeAction can return either Command[] or CodeAction[].
-  # If it is a CodeAction, it can have either an edit, a command or both.
-  # Edits should be executed first.
-  if selAction->has_key('edit') || selAction->has_key('command')
-    if selAction->has_key('edit')
-      # apply edit first
-      textedit.ApplyWorkspaceEdit(selAction.edit)
-    endif
-    if selAction->has_key('command')
-      lspserver.executeCommand(selAction)
-    endif
-  else
-    lspserver.executeCommand(selAction)
-  endif
+  HandleCodeAction(lspserver, actions[choice - 1])
 enddef
 
 # vim: tabstop=8 shiftwidth=2 softtabstop=2
index e824e740e7957e3e43635002687650ada7a77eb6..5308e83c0482d7754f34c2bcf62da0dd1a193599 100644 (file)
@@ -35,7 +35,9 @@ export var lspOptions: dict<any> = {
   # Make diagnostics show in a popup instead of echoing
   showDiagInPopup: true,
   # Don't print message when a configured language server is missing.
-  ignoreMissingServer: false
+  ignoreMissingServer: false,
+  # Use a floating menu to show the code action menu instead of asking for input
+  usePopupInCodeAction: false
 }
 
 # set LSP options from user provided options