├── .gitignore ├── LICENSE ├── README.md ├── autoload └── popup_signature.vim ├── plugin └── popup_signature.vim ├── popup_signature.gif └── syntax └── popup_signature.vim /.gitignore: -------------------------------------------------------------------------------- 1 | .popup_signature 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Naruhiko Nishino 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # vim-popup_signature 3 | 4 | vim-popup\_signature provides to show a signature of a vim's build-in function under the cursor and uses `+textprop` feature. 5 | 6 | ![](https://raw.githubusercontent.com/rbtnn/vim-popup_signature/master/popup_signature.gif) 7 | 8 | ## License 9 | 10 | Distributed under MIT License. See LICENSE. 11 | -------------------------------------------------------------------------------- /autoload/popup_signature.vim: -------------------------------------------------------------------------------- 1 | 2 | if has('vimscript-3') && has('textprop') && exists('*popup_atcursor') 3 | scriptversion 3 4 | else 5 | finish 6 | endif 7 | 8 | let s:__version__ = 6 9 | let s:cachepath = fnamemodify(expand(''), ':h:h') .. '/.popup_signature' 10 | 11 | function! popup_signature#build() abort 12 | call s:message('Building cache ...') 13 | let s:dict = {} 14 | let paths = [ 15 | \ expand('$VIMRUNTIME/doc/usr_41.txt'), 16 | \ expand('$VIMRUNTIME/doc/popup.txt'), 17 | \ expand('$VIMRUNTIME/doc/channel.txt'), 18 | \ expand('$VIMRUNTIME/doc/terminal.txt'), 19 | \ expand('$VIMRUNTIME/doc/eval.txt'), 20 | \ ] 21 | let obsoletes = ['buffer_exists', 'buffer_name', 'buffer_number', 'file_readable', 'highlight_exists'] 22 | let lines = [] 23 | for path in paths 24 | if filereadable(path) 25 | let lines += readfile(path) 26 | endif 27 | endfor 28 | call filter(lines, { i,x -> 29 | \ (x =~# '^\s\+|\?[a-zA-Z0-9_]\+()|\?') || 30 | \ (x =~# '^[a-zA-Z0-9_]\+(') || 31 | \ (x =~# '\*$') 32 | \ }) 33 | for x in getcompletion('*', 'function') 34 | let funcname = matchstr(x, '^.*\ze(') 35 | if (funcname =~# '^[a-zA-Z0-9_]\+$') && (-1 == index(obsoletes, funcname)) 36 | let summary = '' 37 | let signature = '' 38 | for y in range(0, len(lines) - 1) 39 | if lines[y] =~# ('^\s\+|\?' .. funcname .. '()|\?') 40 | let summary = matchstr(lines[y], ')|\?\s\+\zs.*$') 41 | break 42 | endif 43 | endfor 44 | for y in range(0, len(lines) - 1) 45 | if lines[y] =~# escape(('*' .. funcname .. '()*'), '*') 46 | for z in range(y, y + 3) 47 | if lines[z] =~# ('^' .. funcname .. '(') 48 | let signature = matchstr(lines[z], '^[^)]*)') 49 | break 50 | endif 51 | endfor 52 | break 53 | endif 54 | endfor 55 | if !empty(summary) && !empty(signature) 56 | let s:dict[funcname] = { 57 | \ 'summary' : summary, 58 | \ 'signature' : signature, 59 | \ } 60 | endif 61 | endif 62 | endfor 63 | let s:dict.__version__ = s:__version__ 64 | call writefile([json_encode(s:dict)], s:cachepath) 65 | call s:message('Has builded cache.') 66 | endfunction 67 | 68 | function! popup_signature#close_popup() abort 69 | let s:popup_id = get(s:, 'popup_id', -1) 70 | if -1 != s:popup_id 71 | call popup_close(s:popup_id) 72 | endif 73 | endfunction 74 | 75 | function! popup_signature#show_popup() abort 76 | let funcname = expand('') 77 | if !get(g:, 'popup_signature_enable', 1) 78 | return 79 | endif 80 | if -1 == index(split(&filetype, '\.'), 'vim') 81 | return 82 | endif 83 | if '__version__' == funcname 84 | return 85 | endif 86 | if -1 == stridx(getline('.'), funcname .. '(') 87 | return 88 | endif 89 | let s:dict = get(s:, 'dict', {}) 90 | if empty(s:dict) && filereadable(s:cachepath) 91 | let s:dict = json_decode(readfile(s:cachepath)[0]) 92 | endif 93 | if get(s:dict, '__version__', 0) < s:__version__ 94 | call popup_signature#build() 95 | endif 96 | if !has_key(s:dict, funcname) 97 | return 98 | endif 99 | " delay the popup window. 100 | if -1 != get(s:, 'timer_id', -1) 101 | call timer_stop(s:timer_id) 102 | endif 103 | let s:timer_id = timer_start(&timeoutlen, function('s:delay_popup', [funcname])) 104 | endfunction 105 | 106 | function! s:delay_popup(funcname, timer) abort 107 | try 108 | call popup_signature#close_popup() 109 | let lines = [get(s:dict[a:funcname], 'signature', '')] 110 | if !empty(get(s:dict[a:funcname], 'summary', '')) 111 | let lines += [printf(' %-' .. len(lines[0]) .. 's', get(s:dict[a:funcname], 'summary', ''))] 112 | endif 113 | let s:popup_id = popup_atcursor(lines, { 114 | \ 'padding' : [1, 1, 1, 1], 115 | \ }) 116 | if has('win32') 117 | if has('gui_running') 118 | call win_execute(s:popup_id, 'setfiletype popup_signature') 119 | else 120 | if has('vcon') && has('termguicolors') 121 | if &termguicolors 122 | call win_execute(s:popup_id, 'setfiletype popup_signature') 123 | endif 124 | endif 125 | endif 126 | else 127 | if 256 <= &t_Co 128 | call win_execute(s:popup_id, 'setfiletype popup_signature') 129 | endif 130 | endif 131 | catch 132 | finally 133 | let s:timer_id = -1 134 | endtry 135 | endfunction 136 | 137 | function! s:message(text) abort 138 | echohl Title 139 | echomsg printf('[popup_signature] %s', a:text) 140 | echohl None 141 | endfunction 142 | 143 | -------------------------------------------------------------------------------- /plugin/popup_signature.vim: -------------------------------------------------------------------------------- 1 | 2 | if has('vimscript-3') && has('textprop') && exists('*popup_atcursor') 3 | scriptversion 3 4 | else 5 | finish 6 | endif 7 | 8 | let g:loaded_popup_signature = 1 9 | 10 | augroup popup_signature 11 | autocmd! 12 | autocmd CursorMoved * :call popup_signature#show_popup() 13 | augroup END 14 | 15 | -------------------------------------------------------------------------------- /popup_signature.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbtnn/vim-popup_signature/28b5f447da7281801413cd5083e8da3d3e7d95fe/popup_signature.gif -------------------------------------------------------------------------------- /syntax/popup_signature.vim: -------------------------------------------------------------------------------- 1 | 2 | if has('vimscript-3') && has('textprop') && exists('*popup_atcursor') 3 | scriptversion 3 4 | else 5 | finish 6 | endif 7 | 8 | syntax match PopupSignatureFuncName /^[a-zA-Z0-9_]\+/ 9 | syntax region PopupSignatureFuncArgs start='{' end='}' 10 | syntax match PopupSignatureFuncSummay /\%2l/ 11 | 12 | function! s:group_name2synIDattr(group_name, what) abort 13 | let syn_id = 1 14 | while a:group_name != synIDattr(syn_id, 'name') 15 | let syn_id += 1 16 | endwhile 17 | return synIDattr(synIDtrans(syn_id), a:what) 18 | endfunction 19 | 20 | let s:bg = s:group_name2synIDattr('Pmenu', 'bg#') 21 | let s:fg_name = s:group_name2synIDattr('Function', 'fg#') 22 | let s:fg_args = s:group_name2synIDattr('Special', 'fg#') 23 | let s:fg_summary = s:group_name2synIDattr('Normal', 'fg#') 24 | 25 | let s:mode = (s:bg =~# '^#') ? 'gui' : 'cterm' 26 | 27 | execute printf('highlight PopupSignatureFuncName %sfg=%s %sbg=%s', s:mode, s:fg_name, s:mode, s:bg) 28 | execute printf('highlight PopupSignatureFuncArgs %sfg=%s %sbg=%s', s:mode, s:fg_args, s:mode, s:bg) 29 | execute printf('highlight PopupSignatureFuncSummay %sfg=%s %sbg=%s', s:mode, s:fg_summary, s:mode, s:bg) 30 | --------------------------------------------------------------------------------