All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
2 " NOTE: lines between '" ___vital___' is generated by :Vitalize.
3 " Do not modify the code nor insert new lines before '" ___vital___'
4 function! s:_SID() abort
5 return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
7 execute join(['function! vital#_lsp#VS#Vim#Window#import() abort', printf("return map({'info': '', 'do': '', 'is_floating': '', 'find': '', 'scroll': '', 'screenpos': ''}, \"vital#_lsp#function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
15 function! s:do(winid, func) abort
16 let l:curr_winid = win_getid()
17 if l:curr_winid == a:winid
22 if !has('nvim') && exists('*win_execute')
25 noautocmd keepalt keepjumps call win_execute(a:winid, 'call s:Do()')
27 echomsg string({ 'exception': v:exception, 'throwpoint': v:throwpoint })
33 noautocmd keepalt keepjumps call win_gotoid(a:winid)
37 echomsg string({ 'exception': v:exception, 'throwpoint': v:throwpoint })
39 noautocmd keepalt keepjumps call win_gotoid(l:curr_winid)
46 function! s:info(winid) abort
47 let l:info = getwininfo(a:winid)[0]
49 if s:is_floating(a:winid)
50 let l:config = nvim_win_get_config(a:winid)
51 let l:config.border = get(l:config, 'border', 'none')
52 if type(l:config.border) !=# type([])
53 if index(['rounded', 'single', 'double', 'solid'], l:config.border) >= 0
56 elseif l:config.border ==# 'shadow'
64 let l:has_top = v:false
65 let l:has_top = l:has_top || get(l:config.border, 0, '') !=# ''
66 let l:has_top = l:has_top || get(l:config.border, 1, '') !=# ''
67 let l:has_top = l:has_top || get(l:config.border, 2, '') !=# ''
68 let l:has_right = v:false
69 let l:has_right = l:has_right || get(l:config.border, 2, '') !=# ''
70 let l:has_right = l:has_right || get(l:config.border, 3, '') !=# ''
71 let l:has_right = l:has_right || get(l:config.border, 4, '') !=# ''
72 let l:has_bottom = v:false
73 let l:has_bottom = l:has_bottom || get(l:config.border, 4, '') !=# ''
74 let l:has_bottom = l:has_bottom || get(l:config.border, 5, '') !=# ''
75 let l:has_bottom = l:has_bottom || get(l:config.border, 6, '') !=# ''
76 let l:has_left = v:false
77 let l:has_left = l:has_left || get(l:config.border, 6, '') !=# ''
78 let l:has_left = l:has_left || get(l:config.border, 7, '') !=# ''
79 let l:has_left = l:has_left || get(l:config.border, 0, '') !=# ''
81 let l:width_off = (l:has_left ? 1 : 0) + (l:has_right ? 1 : 0)
82 let l:height_off = (l:has_top ? 1 : 0) + (l:has_bottom ? 1 : 0)
84 let l:left = get(l:config, '')
85 let l:info.core_width = l:config.width - l:width_off
86 let l:info.core_height = l:config.height - l:height_off
88 let l:info.core_width = l:info.width
89 let l:info.core_height = l:info.height
93 \ 'width': l:info.width,
94 \ 'height': l:info.height,
95 \ 'core_width': l:info.core_width,
96 \ 'core_height': l:info.core_height,
97 \ 'topline': l:info.topline,
101 function! s:info(winid) abort
102 if s:is_floating(a:winid)
103 let l:info = popup_getpos(a:winid)
105 \ 'width': l:info.width,
106 \ 'height': l:info.height,
107 \ 'core_width': l:info.core_width,
108 \ 'core_height': l:info.core_height,
109 \ 'topline': l:info.firstline
115 function! l:ctx.callback() abort
116 let self.info.width = winwidth(0)
117 let self.info.height = winheight(0)
118 let self.info.core_width = self.info.width
119 let self.info.core_height = self.info.height
120 let self.info.topline = line('w0')
122 call s:do(a:winid, { -> l:ctx.callback() })
130 function! s:find(callback) abort
132 let l:winids += map(range(1, tabpagewinnr(tabpagenr(), '$')), 'win_getid(v:val)')
133 let l:winids += s:_get_visible_popup_winids()
134 return filter(l:winids, 'a:callback(v:val)')
141 function! s:is_floating(winid) abort
142 let l:config = nvim_win_get_config(a:winid)
143 return empty(l:config) || !empty(get(l:config, 'relative', ''))
146 function! s:is_floating(winid) abort
147 return winheight(a:winid) != -1 && win_id2win(a:winid) == 0
154 function! s:scroll(winid, topline) abort
156 function! l:ctx.callback(winid, topline) abort
157 let l:wininfo = s:info(a:winid)
158 let l:topline = a:topline
159 let l:topline = min([l:topline, line('$') - l:wininfo.core_height + 1])
160 let l:topline = max([l:topline, 1])
162 if l:topline == l:wininfo.topline
166 if !has('nvim') && s:is_floating(a:winid)
167 call popup_setoptions(a:winid, {
168 \ 'firstline': l:topline,
171 let l:delta = l:topline - l:wininfo.topline
172 let l:key = l:delta > 0 ? "\<C-e>" : "\<C-y>"
173 execute printf('noautocmd silent normal! %s', repeat(l:key, abs(l:delta)))
176 call s:do(a:winid, { -> l:ctx.callback(a:winid, a:topline) })
182 " @param {[number, number]} pos - position on the current buffer.
184 function! s:screenpos(pos) abort
186 let l:x = a:pos[1] + get(a:pos, 2, 0)
188 let l:view = winsaveview()
189 let l:scroll_x = l:view.leftcol
190 let l:scroll_y = l:view.topline
192 let l:winpos = win_screenpos(win_getid())
193 let l:y = l:winpos[0] + l:y - l:scroll_y
194 let l:x = l:winpos[1] + l:x - l:scroll_x
195 return [l:y, l:x + (wincol() - virtcol('.')) - 1]
199 " _get_visible_popup_winids
201 function! s:_get_visible_popup_winids() abort
202 if !exists('*popup_list')
205 return filter(popup_list(), 'popup_getpos(v:val).visible')