]> Sergey Matveev's repositories - vim-lsp.git/commitdiff
Update the active parameter in the signature popup correctly. Move the functions...
authorYegappan Lakshmanan <yegappan@yahoo.com>
Sat, 5 Feb 2022 16:56:26 +0000 (08:56 -0800)
committerYegappan Lakshmanan <yegappan@yahoo.com>
Sat, 5 Feb 2022 16:56:26 +0000 (08:56 -0800)
autoload/buffer.vim [new file with mode: 0644]
autoload/handlers.vim
autoload/lsp.vim
autoload/lspserver.vim
autoload/signature.vim

diff --git a/autoload/buffer.vim b/autoload/buffer.vim
new file mode 100644 (file)
index 0000000..1b50403
--- /dev/null
@@ -0,0 +1,30 @@
+vim9script
+
+# Functions for managing the per-buffer LSP server information
+
+# Buffer number to LSP server map
+var bufnrToServer: dict<dict<any>> = {}
+
+export def BufLspServerSet(bnr: number, lspserver: dict<any>)
+  bufnrToServer[bnr] = lspserver
+enddef
+
+export def BufLspServerRemove(bnr: number)
+  bufnrToServer->remove(bnr)
+enddef
+
+# Returns the LSP server for the buffer 'bnr'. Returns an empty dict if the
+# server is not found.
+export def BufLspServerGet(bnr: number): dict<any>
+  return bufnrToServer->get(bnr, {})
+enddef
+
+# Returns the LSP server for the current buffer. Returns an empty dict if the
+# server is not found.
+export def CurbufGetServer(): dict<any>
+  return s:BufLspServerGet(bufnr())
+enddef
+
+export def BufHasLspServer(bnr: number): bool
+  return bufnrToServer->has_key(bnr)
+enddef
index 147b26ea78b689bab156b5fde94a7c49706240db..48965fd1c81829b3901d884e3f69eb0ca34c4818 100644 (file)
@@ -43,6 +43,7 @@ if has('patch-8.2.4019')
   callhier.IncomingCalls = callhierarchy_import.IncomingCalls
   callhier.OutgoingCalls = callhierarchy_import.OutgoingCalls
   selection.SelectionStart = selection_import.SelectionStart
+  signature.SignatureInit = signature_import.SignatureInit
   signature.SignatureDisplay = signature_import.SignatureDisplay
 else
   import lspOptions from './lspoptions.vim'
@@ -58,7 +59,7 @@ else
   import ApplyCodeAction from './codeaction.vim'
   import {IncomingCalls, OutgoingCalls} from './callhierarchy.vim'
   import {SelectionStart} from './selection.vim'
-  import {SignatureDisplay} from './signature.vim'
+  import {SignatureInit, SignatureDisplay} from './signature.vim'
 
   opt.lspOptions = lspOptions
   util.WarnMsg = WarnMsg
@@ -76,6 +77,7 @@ else
   callhier.IncomingCalls = IncomingCalls
   callhier.OutgoingCalls = OutgoingCalls
   selection.SelectionStart = SelectionStart
+  signature.SignatureInit = SignatureInit
   signature.SignatureDisplay = SignatureDisplay
 endif
 
@@ -92,13 +94,8 @@ def s:processInitializeReply(lspserver: dict<any>, req: dict<any>, reply: dict<a
   # TODO: Check all the buffers with filetype corresponding to this LSP server
   # and then setup the below mapping for those buffers.
 
-  # map characters that trigger signature help
-  if opt.lspOptions.showSignature && caps->has_key('signatureHelpProvider')
-    var triggers = caps.signatureHelpProvider.triggerCharacters
-    for ch in triggers
-      exe 'inoremap <buffer> <silent> ' .. ch .. ' ' .. ch .. "<C-R>=LspShowSignature()<CR>"
-    endfor
-  endif
+  # initialize signature help
+  signature.SignatureInit(lspserver)
 
   if opt.lspOptions.autoComplete && caps->has_key('completionProvider')
     var triggers = caps.completionProvider.triggerCharacters
index e7411ac59fca56be0455a8013923b7b4afa8b9b7..7a37b6a7430a86a323857fa11d5a33dd648af279 100644 (file)
@@ -13,14 +13,18 @@ var util = {}
 var diag = {}
 var symbol = {}
 var outline = {}
+var signature = {}
+var buf = {}
 
 if has('patch-8.2.4019')
   import './lspoptions.vim' as opt_import
   import './lspserver.vim' as server_import
   import './util.vim' as util_import
+  import './buffer.vim' as buf_import
   import './diag.vim' as diag_import
   import './symbol.vim' as symbol_import
   import './outline.vim' as outline_import
+  import './signature.vim' as signature_import
 
   opt.lspOptions = opt_import.lspOptions
   lserver.NewLspServer = server_import.NewLspServer
@@ -31,6 +35,11 @@ if has('patch-8.2.4019')
   util.GetLineByteFromPos = util_import.GetLineByteFromPos
   util.PushCursorToTagStack = util_import.PushCursorToTagStack
   util.LspUriRemote = util_import.LspUriRemote
+  buf.BufLspServerSet = buf_import.BufLspServerSet
+  buf.BufLspServerRemove = buf_import.BufLspServerRemove
+  buf.BufHasLspServer = buf_import.BufHasLspServer
+  buf.BufLspServerGet = buf_import.BufLspServerGet
+  buf.CurbufGetServer = buf_import.CurbufGetServer
   diag.UpdateDiags = diag_import.UpdateDiags
   diag.DiagsGetErrorCount = diag_import.DiagsGetErrorCount
   diag.ShowAllDiags = diag_import.ShowAllDiags
@@ -43,6 +52,7 @@ if has('patch-8.2.4019')
   symbol.ShowSymbolMenu = symbol_import.ShowSymbolMenu
   outline.OpenOutlineWindow = outline_import.OpenOutlineWindow
   outline.SkipOutlineRefresh = outline_import.SkipOutlineRefresh
+  signature.SignatureInit = signature_import.SignatureInit
 else
   import {lspOptions} from './lspoptions.vim'
   import NewLspServer from './lspserver.vim'
@@ -53,6 +63,11 @@ else
         GetLineByteFromPos,
         PushCursorToTagStack,
        LspUriRemote} from './util.vim'
+  import {BufLspServerSet,
+         BufLspServerRemove,
+         BufHasLspServer,
+         BufLspServerGet,
+         CurbufGetServer} from './buffer.vim'
   import {DiagRemoveFile,
        UpdateDiags,
        DiagsGetErrorCount,
@@ -64,6 +79,7 @@ else
        DiagsHighlightDisable} from './diag.vim'
   import ShowSymbolMenu from './symbol.vim'
   import {OpenOutlineWindow, SkipOutlineRefresh} from './outline.vim'
+  import {SignatureInit} from './signature.vim'
 
   opt.lspOptions = lspOptions
   lserver.NewLspServer = NewLspServer
@@ -74,6 +90,11 @@ else
   util.GetLineByteFromPos = GetLineByteFromPos
   util.PushCursorToTagStack = PushCursorToTagStack
   util.LspUriRemote = LspUriRemote
+  buf.BufLspServerSet = BufLspServerSet
+  buf.BufLspServerRemove = BufLspServerRemove
+  buf.BufHasLspServer = BufHasLspServer
+  buf.BufLspServerGet = BufLspServerGet
+  buf.CurbufGetServer = CurbufGetServer
   diag.DiagRemoveFile = DiagRemoveFile
   diag.UpdateDiags = UpdateDiags
   diag.DiagsGetErrorCount = DiagsGetErrorCount
@@ -86,6 +107,7 @@ else
   symbol.ShowSymbolMenu = ShowSymbolMenu
   outline.OpenOutlineWindow = OpenOutlineWindow
   outline.SkipOutlineRefresh = SkipOutlineRefresh
+  signature.SignatureInit = SignatureInit
 endif
 
 # LSP server information
@@ -97,9 +119,6 @@ var ftypeServerMap: dict<dict<any>> = {}
 # per-filetype omni-completion enabled/disabled table
 var ftypeOmniCtrlMap: dict<bool> = {}
 
-# Buffer number to LSP server map
-var bufnrToServer: dict<dict<any>> = {}
-
 var lspInitializedOnce = false
 
 def s:lspInitOnce()
@@ -126,18 +145,6 @@ def s:lspGetServer(ftype: string): dict<any>
   return ftypeServerMap->get(ftype, {})
 enddef
 
-# Returns the LSP server for the buffer 'bnr'. Returns an empty dict if the
-# server is not found.
-def s:bufGetServer(bnr: number): dict<any>
-  return bufnrToServer->get(bnr, {})
-enddef
-
-# Returns the LSP server for the current buffer. Returns an empty dict if the
-# server is not found.
-def s:curbufGetServer(): dict<any>
-  return s:bufGetServer(bufnr())
-enddef
-
 # Returns the LSP server for the current buffer if it is running and is ready.
 # Returns an empty dict if the server is not found or is not ready.
 def s:curbufGetServerChecked(): dict<any>
@@ -146,7 +153,7 @@ def s:curbufGetServerChecked(): dict<any>
     return {}
   endif
 
-  var lspserver: dict<any> = s:curbufGetServer()
+  var lspserver: dict<any> = buf.CurbufGetServer()
   if lspserver->empty()
     util.ErrMsg('Error: LSP server for "' .. fname .. '" is not found')
     return {}
@@ -254,7 +261,7 @@ enddef
 
 # buffer change notification listener
 def s:bufchange_listener(bnr: number, start: number, end: number, added: number, changes: list<dict<number>>)
-  var lspserver: dict<any> = s:curbufGetServer()
+  var lspserver: dict<any> = buf.CurbufGetServer()
   if lspserver->empty() || !lspserver.running
     return
   endif
@@ -265,7 +272,7 @@ enddef
 # A buffer is saved. Send the "textDocument/didSave" LSP notification
 def s:lspSavedFile()
   var bnr: number = expand('<abuf>')->str2nr()
-  var lspserver: dict<any> = s:bufGetServer(bnr)
+  var lspserver: dict<any> = buf.BufLspServerGet(bnr)
   if lspserver->empty() || !lspserver.running
     return
   endif
@@ -278,7 +285,7 @@ enddef
 var lspDiagPopupID: number = 0
 var lspDiagPopupInfo: dict<any> = {}
 def g:LspDiagExpr(): string
-  var lspserver: dict<any> = s:bufGetServer(v:beval_bufnr)
+  var lspserver: dict<any> = buf.BufLspServerGet(v:beval_bufnr)
   if lspserver->empty() || !lspserver.running
     return ''
   endif
@@ -309,7 +316,7 @@ def g:LspLeftInsertMode()
   :unlet b:LspDiagsUpdatePending
 
   var bnr: number = bufnr()
-  var lspserver: dict<any> = s:curbufGetServer()
+  var lspserver: dict<any> = buf.CurbufGetServer()
   if lspserver->empty() || !lspserver.running
     return
   endif
@@ -318,7 +325,7 @@ enddef
 
 # A new buffer is opened. If LSP is supported for this buffer, then add it
 export def AddFile(bnr: number): void
-  if bufnrToServer->has_key(bnr)
+  if buf.BufHasLspServer(bnr)
     # LSP server for this buffer is already initialized and running
     return
   endif
@@ -363,15 +370,8 @@ export def AddFile(bnr: number): void
 
   setbufvar(bnr, '&balloonexpr', 'g:LspDiagExpr()')
 
-  # map characters that trigger signature help
-  if opt.lspOptions.showSignature &&
-                       lspserver.caps->has_key('signatureHelpProvider')
-    var triggers = lspserver.caps.signatureHelpProvider.triggerCharacters
-    for ch in triggers
-      exe 'inoremap <buffer> <silent> ' .. ch .. ' ' .. ch
-                               .. "<C-R>=LspShowSignature()<CR>"
-    endfor
-  endif
+  # initialize signature help
+  signature.SignatureInit(lspserver)
 
   # Set buffer local autocmds
   augroup LSPBufferAutocmds
@@ -395,18 +395,18 @@ export def AddFile(bnr: number): void
     endif
   augroup END
 
-  bufnrToServer[bnr] = lspserver
+  buf.BufLspServerSet(bnr, lspserver)
 enddef
 
 # Notify LSP server to remove a file
 export def RemoveFile(bnr: number): void
-  var lspserver: dict<any> = s:bufGetServer(bnr)
+  var lspserver: dict<any> = buf.BufLspServerGet(bnr)
   if lspserver->empty() || !lspserver.running
     return
   endif
   lspserver.textdocDidClose(bnr)
   diag.DiagRemoveFile(lspserver, bnr)
-  bufnrToServer->remove(bnr)
+  buf.BufLspServerRemove(bnr)
 enddef
 
 # Stop all the LSP servers
@@ -477,7 +477,7 @@ export def ServerReady(): bool
     return false
   endif
 
-  var lspserver: dict<any> = s:curbufGetServer()
+  var lspserver: dict<any> = buf.CurbufGetServer()
   if lspserver->empty()
     return false
   endif
@@ -528,7 +528,7 @@ export def LspShowCurrentDiagInStatusLine()
     return
   endif
 
-  var lspserver: dict<any> = s:curbufGetServer()
+  var lspserver: dict<any> = buf.CurbufGetServer()
   if lspserver->empty() || !lspserver.running
     return
   endif
@@ -544,7 +544,7 @@ export def ErrorCount(): dict<number>
     return res
   endif
 
-  var lspserver: dict<any> = s:curbufGetServer()
+  var lspserver: dict<any> = buf.CurbufGetServer()
   if lspserver->empty() || !lspserver.running
     return res
   endif
@@ -565,7 +565,7 @@ enddef
 # Insert mode completion handler. Used when 24x7 completion is enabled
 # (default).
 def g:LspComplete()
-  var lspserver: dict<any> = s:curbufGetServer()
+  var lspserver: dict<any> = buf.CurbufGetServer()
   if lspserver->empty() || !lspserver.running || !lspserver.ready
     return
   endif
@@ -644,7 +644,7 @@ enddef
 # Display the hover message from the LSP server for the current cursor
 # location
 export def Hover()
-  var lspserver: dict<any> = s:curbufGetServer()
+  var lspserver: dict<any> = buf.CurbufGetServer()
   if lspserver->empty() || !lspserver.running || !lspserver.ready
     return
   endif
@@ -689,7 +689,7 @@ def g:LspRequestDocSymbols()
     return
   endif
 
-  var lspserver: dict<any> = s:curbufGetServer()
+  var lspserver: dict<any> = buf.CurbufGetServer()
   if lspserver->empty() || !lspserver.running || !lspserver.ready
     return
   endif
index e59b40a334c061e0c0f34c5489f1f769e819dbe7..3da52394370fe7855f18af95b840dd245b70fc46 100644 (file)
@@ -100,6 +100,7 @@ def s:startServer(lspserver: dict<any>): number
   lspserver.requests = {}
   lspserver.completePending = false
   lspserver.completionTriggerChars = []
+  lspserver.signaturePopup = -1
   lspserver.workspaceFolders = [getcwd()]
 
   var job = job_start(cmd, opts)
@@ -954,6 +955,7 @@ export def NewLspServer(path: string, args: list<string>): dict<any>
     requests: {},
     completePending: false,
     completionTriggerChars: [],
+    signaturePopup: -1,
     diagsMap: {},
     workspaceSymbolPopup: 0,
     workspaceSymbolQuery: '',
index dd58acbeb1b4097786d77590d81c10e79ddc72ab..9459a2cee61d2ee3737996198604d81120a2152b 100644 (file)
@@ -4,29 +4,68 @@ vim9script
 
 var opt = {}
 var util = {}
+var buf = {}
 
 if has('patch-8.2.4019')
   import './lspoptions.vim' as opt_import
   import './util.vim' as util_import
+  import './buffer.vim' as buf_import
 
   opt.lspOptions = opt_import.lspOptions
   util.WarnMsg = util_import.WarnMsg
+  buf.CurbufGetServer = buf_import.CurbufGetServer
 else
   import lspOptions from './lspoptions.vim'
   import {WarnMsg} from './util.vim'
+  import {CurbufGetServer} from './buffer.vim'
 
   opt.lspOptions = lspOptions
   util.WarnMsg = WarnMsg
+  buf.CurbufGetServer = CurbufGetServer
 endif
 
+# close the signature popup window
+def s:closeSignaturePopup(lspserver: dict<any>)
+  lspserver.signaturePopup->popup_close()
+  lspserver.signaturePopup = -1
+enddef
+
+def s:closeCurBufSignaturePopup()
+  var lspserver: dict<any> = buf.CurbufGetServer()
+  if lspserver->empty()
+    return
+  endif
+
+  s:closeSignaturePopup(lspserver)
+enddef
+
+# Initialize the signature triggers for the current buffer
+export def SignatureInit(lspserver: dict<any>)
+  if !opt.lspOptions.showSignature ||
+                       !lspserver.caps->has_key('signatureHelpProvider')
+    # no support for signature help
+    return
+  endif
+
+  # map characters that trigger signature help
+  for ch in lspserver.caps.signatureHelpProvider.triggerCharacters
+    exe 'inoremap <buffer> <silent> ' .. ch .. ' ' .. ch
+                                       .. "<C-R>=LspShowSignature()<CR>"
+  endfor
+  # close the signature popup when leaving insert mode
+  autocmd InsertLeave <buffer> call s:closeCurBufSignaturePopup()
+enddef
+
 # Display the symbol signature help
 export def SignatureDisplay(lspserver: dict<any>, sighelp: dict<any>): void
   if sighelp->empty()
+    s:closeSignaturePopup(lspserver)
     return
   endif
 
   if sighelp.signatures->len() <= 0
     util.WarnMsg('No signature help available')
+    s:closeSignaturePopup(lspserver)
     return
   endif
 
@@ -36,13 +75,13 @@ export def SignatureDisplay(lspserver: dict<any>, sighelp: dict<any>): void
   endif
 
   var sig: dict<any> = sighelp.signatures[sigidx]
-  var text = sig.label
-  var hllen = 0
-  var startcol = 0
+  var text: string = sig.label
+  var hllen: number = 0
+  var startcol: number = 0
   if sig->has_key('parameters') && sighelp->has_key('activeParameter')
     var params_len = sig.parameters->len()
     if params_len > 0 && sighelp.activeParameter < params_len
-      var label = sig.parameters[sighelp.activeParameter].label
+      var label: string = sig.parameters[sighelp.activeParameter].label
       hllen = label->len()
       startcol = text->stridx(label)
     endif
@@ -56,11 +95,16 @@ export def SignatureDisplay(lspserver: dict<any>, sighelp: dict<any>): void
     echoh None
     echon strpart(text, startcol + hllen)
   else
-    var popupID = text->popup_atcursor({moved: 'any'})
-    prop_type_add('signature', {bufnr: popupID->winbufnr(), highlight: 'LineNr'})
+    # Close the previous signature popup and open a new one
+    lspserver.signaturePopup->popup_close()
+
+    var popupID = text->popup_atcursor({moved: [col('.') - 1, 9999999]})
+    var bnum: number = popupID->winbufnr()
+    prop_type_add('signature', {bufnr: bnum, highlight: 'LineNr'})
     if hllen > 0
-      prop_add(1, startcol + 1, {bufnr: popupID->winbufnr(), length: hllen, type: 'signature'})
+      prop_add(1, startcol + 1, {bufnr: bnum, length: hllen, type: 'signature'})
     endif
+    lspserver.signaturePopup = popupID
   endif
 enddef