]> Sergey Matveev's repositories - vim-lsp.git/blob - autoload/lsp/signature.vim
4764c784e4a395014ee92e78ac0f17545f19855d
[vim-lsp.git] / autoload / lsp / signature.vim
1 vim9script
2
3 # Functions related to handling LSP symbol signature help.
4
5 import './options.vim' as opt
6 import './util.vim'
7 import './buffer.vim' as buf
8
9 # close the signature popup window
10 def CloseSignaturePopup(lspserver: dict<any>)
11   if lspserver.signaturePopup != -1
12     lspserver.signaturePopup->popup_close()
13   endif
14   lspserver.signaturePopup = -1
15 enddef
16
17 def CloseCurBufSignaturePopup()
18   var lspserver: dict<any> = buf.CurbufGetServer('signatureHelp')
19   if lspserver->empty()
20     return
21   endif
22
23   CloseSignaturePopup(lspserver)
24 enddef
25
26 export def InitOnce()
27   hlset([{name: 'LspSigActiveParameter', default: true, linksto: 'LineNr'}])
28 enddef
29
30 # Initialize the signature triggers for the current buffer
31 export def BufferInit(lspserver: dict<any>)
32   if !lspserver.isSignatureHelpProvider
33         || !lspserver.caps.signatureHelpProvider->has_key('triggerCharacters')
34     # no support for signature help
35     return
36   endif
37
38   if !opt.lspOptions.showSignature
39       || !lspserver.featureEnabled('signatureHelp')
40     # Show signature support is disabled
41     return
42   endif
43
44   # map characters that trigger signature help
45   for ch in lspserver.caps.signatureHelpProvider.triggerCharacters
46     exe $"inoremap <buffer> <silent> {ch} {ch}<C-R>=LspShowSignature()<CR>"
47   endfor
48
49   # close the signature popup when leaving insert mode
50   autocmd_add([{bufnr: bufnr(),
51                 event: 'InsertLeave',
52                 cmd: 'CloseCurBufSignaturePopup()'}])
53 enddef
54
55 # process the 'textDocument/signatureHelp' reply from the LSP server and
56 # display the symbol signature help.
57 # Result: SignatureHelp | null
58 export def SignatureHelp(lspserver: dict<any>, sighelp: any): void
59   if sighelp->empty()
60     CloseSignaturePopup(lspserver)
61     return
62   endif
63
64   if sighelp.signatures->len() <= 0
65     CloseSignaturePopup(lspserver)
66     return
67   endif
68
69   var sigidx: number = 0
70   if sighelp->has_key('activeSignature')
71     sigidx = sighelp.activeSignature
72   endif
73
74   var sig: dict<any> = sighelp.signatures[sigidx]
75   var text: string = sig.label
76   var hllen: number = 0
77   var startcol: number = 0
78   if sig->has_key('parameters') && sighelp->has_key('activeParameter')
79     var params_len = sig.parameters->len()
80     if params_len > 0 && sighelp.activeParameter < params_len
81       var label: string = sig.parameters[sighelp.activeParameter].label
82       hllen = label->len()
83       startcol = text->stridx(label)
84     endif
85   endif
86   if opt.lspOptions.echoSignature
87     :echon "\r\r"
88     :echon ''
89     :echon text->strpart(0, startcol)
90     :echoh LspSigActiveParameter
91     :echon text->strpart(startcol, hllen)
92     :echoh None
93     :echon text->strpart(startcol + hllen)
94   else
95     # Close the previous signature popup and open a new one
96     lspserver.signaturePopup->popup_close()
97
98     var popupID = text->popup_atcursor({moved: [col('.') - 1, 9999999]})
99     var bnr: number = popupID->winbufnr()
100     prop_type_add('signature', {bufnr: bnr, highlight: 'LspSigActiveParameter'})
101     if hllen > 0
102       prop_add(1, startcol + 1, {bufnr: bnr, length: hllen, type: 'signature'})
103     endif
104     lspserver.signaturePopup = popupID
105   endif
106 enddef
107
108 # vim: tabstop=8 shiftwidth=2 softtabstop=2