From: D4yvid <kkd4yv1d@gmail.com>
Date: Thu, 27 Oct 2022 00:13:19 +0000 (-0300)
Subject: Create custom popup for code action and added a option to enable/disable it
X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=ee9a73cbfaa723e101ffafca37b99eea84114f01;p=vim-lsp.git

Create custom popup for code action and added a option to enable/disable it
---

diff --git a/autoload/lsp/codeaction.vim b/autoload/lsp/codeaction.vim
index 761afb8..578603f 100644
--- a/autoload/lsp/codeaction.vim
+++ b/autoload/lsp/codeaction.vim
@@ -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
diff --git a/autoload/lsp/options.vim b/autoload/lsp/options.vim
index e824e74..5308e83 100644
--- a/autoload/lsp/options.vim
+++ b/autoload/lsp/options.vim
@@ -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