Skip to content

Commit 06456d0

Browse files
add FloatingWindow support from vim-vital-vs
1 parent 90d61f1 commit 06456d0

File tree

6 files changed

+906
-0
lines changed

6 files changed

+906
-0
lines changed

autoload/vital/_lsp.vim

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
let s:_plugin_name = expand('<sfile>:t:r')
2+
3+
function! vital#{s:_plugin_name}#new() abort
4+
return vital#{s:_plugin_name[1:]}#new()
5+
endfunction
6+
7+
function! vital#{s:_plugin_name}#function(funcname) abort
8+
silent! return function(a:funcname)
9+
endfunction
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
" ___vital___
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$')
6+
endfunction
7+
execute join(['function! vital#_lsp#VS#Vim#Buffer#import() abort', printf("return map({'get_line_count': '', 'do': '', 'create': '', 'load': ''}, \"vital#_lsp#function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
8+
delfunction s:_SID
9+
" ___vital___
10+
let s:Do = { -> {} }
11+
12+
let g:___VS_Vim_Buffer_id = get(g:, '___VS_Vim_Buffer_id', 0)
13+
14+
"
15+
" get_line_count
16+
"
17+
if exists('*nvim_buf_line_count')
18+
function! s:get_line_count(bufnr) abort
19+
return nvim_buf_line_count(a:bufnr)
20+
endfunction
21+
elseif has('patch-8.2.0019')
22+
function! s:get_line_count(bufnr) abort
23+
return getbufinfo(a:bufnr)[0].linecount
24+
endfunction
25+
else
26+
function! s:get_line_count(bufnr) abort
27+
if bufnr('%') == bufnr(a:bufnr)
28+
return line('$')
29+
endif
30+
return len(getbufline(a:bufnr, '^', '$'))
31+
endfunction
32+
endif
33+
34+
"
35+
" create
36+
"
37+
function! s:create(...) abort
38+
let g:___VS_Vim_Buffer_id += 1
39+
let l:bufnr = bufnr(printf('VS.Vim.Buffer: %s: %s',
40+
\ g:___VS_Vim_Buffer_id,
41+
\ get(a:000, 0, 'VS.Vim.Buffer.Default')
42+
\ ), v:true)
43+
call s:load(l:bufnr)
44+
return l:bufnr
45+
endfunction
46+
47+
"
48+
" load
49+
"
50+
if exists('*bufload')
51+
function! s:load(bufnr_or_path) abort
52+
call bufload(bufnr(a:bufnr_or_path, v:true))
53+
endfunction
54+
else
55+
function! s:load(bufnr_or_path) abort
56+
call s:do(bufnr(a:bufnr_or_path, v:true), { -> {} })
57+
endfunction
58+
endif
59+
60+
"
61+
" do
62+
"
63+
function! s:do(bufnr, func) abort
64+
let l:curr_bufnr = bufnr('%')
65+
if l:curr_bufnr == a:bufnr
66+
call a:func()
67+
return
68+
endif
69+
70+
try
71+
execute printf('noautocmd keepalt keepjumps %sbuffer', a:bufnr)
72+
call a:func()
73+
catch /.*/
74+
echomsg string({ 'exception': v:exception, 'throwpoint': v:throwpoint })
75+
finally
76+
execute printf('noautocmd keepalt keepjumps %sbuffer', l:curr_bufnr)
77+
endtry
78+
endfunction
79+
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
" ___vital___
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$')
6+
endfunction
7+
execute join(['function! vital#_lsp#VS#Vim#Window#import() abort', printf("return map({'info': '', 'do': '', 'find': '', 'scroll': '', 'screenpos': ''}, \"vital#_lsp#function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
8+
delfunction s:_SID
9+
" ___vital___
10+
let s:Do = { -> {} }
11+
12+
"
13+
" do
14+
"
15+
function! s:do(winid, func) abort
16+
let l:curr_winid = win_getid()
17+
if l:curr_winid == a:winid
18+
call a:func()
19+
return
20+
endif
21+
22+
if exists('*win_execute')
23+
let s:Do = a:func
24+
try
25+
noautocmd keepalt keepjumps call win_execute(a:winid, 'call s:Do()')
26+
catch /.*/
27+
echomsg string({ 'exception': v:exception, 'throwpoint': v:throwpoint })
28+
endtry
29+
unlet s:Do
30+
return
31+
endif
32+
33+
noautocmd keepalt keepjumps call win_gotoid(a:winid)
34+
try
35+
call a:func()
36+
catch /.*/
37+
echomsg string({ 'exception': v:exception, 'throwpoint': v:throwpoint })
38+
endtry
39+
noautocmd keepalt keepjumps call win_gotoid(l:curr_winid)
40+
endfunction
41+
42+
"
43+
" info
44+
"
45+
if has('nvim')
46+
function! s:info(win) abort
47+
let l:info = getwininfo(a:win)[0]
48+
return {
49+
\ 'width': l:info.width,
50+
\ 'height': l:info.height,
51+
\ 'topline': l:info.topline,
52+
\ }
53+
endfunction
54+
else
55+
function! s:info(win) abort
56+
if index(s:_get_visible_popup_winids(), a:win) >= 0
57+
let l:info = popup_getpos(a:win)
58+
return {
59+
\ 'width': l:info.width,
60+
\ 'height': l:info.height,
61+
\ 'topline': l:info.firstline
62+
\ }
63+
endif
64+
65+
let l:ctx = {}
66+
let l:ctx.info = {}
67+
function! l:ctx.callback() abort
68+
let self.info.width = winwidth(0)
69+
let self.info.height = winheight(0)
70+
let self.info.topline = line('w0')
71+
endfunction
72+
call s:do(a:win, { -> l:ctx.callback() })
73+
return l:ctx.info
74+
endfunction
75+
endif
76+
77+
"
78+
" find
79+
"
80+
function! s:find(callback) abort
81+
let l:winids = []
82+
let l:winids += map(range(1, tabpagewinnr(tabpagenr(), '$')), 'win_getid(v:val)')
83+
let l:winids += s:_get_visible_popup_winids()
84+
return filter(l:winids, 'a:callback(v:val)')
85+
endfunction
86+
87+
"
88+
" scroll
89+
"
90+
function! s:scroll(winid, topline) abort
91+
let l:ctx = {}
92+
function! l:ctx.callback(winid, topline) abort
93+
let l:wininfo = s:info(a:winid)
94+
let l:topline = a:topline
95+
let l:topline = max([l:topline, 1])
96+
let l:topline = min([l:topline, line('$') - l:wininfo.height + 1])
97+
98+
if l:topline == l:wininfo.topline
99+
return
100+
endif
101+
102+
if index(s:_get_visible_popup_winids(), a:winid) >= 0
103+
call popup_setoptions(a:winid, {
104+
\ 'firstline': l:topline,
105+
\ })
106+
else
107+
let l:delta = l:topline - l:wininfo.topline
108+
let l:key = l:delta > 0 ? "\<C-e>" : "\<C-y>"
109+
execute printf('noautocmd silent normal! %s', repeat(l:key, abs(l:delta)))
110+
endif
111+
endfunction
112+
call s:do(a:winid, { -> l:ctx.callback(a:winid, a:topline) })
113+
endfunction
114+
115+
"
116+
" screenpos
117+
"
118+
" @param {[number, number]} pos - position on the current buffer.
119+
"
120+
function! s:screenpos(pos) abort
121+
let l:ui_x = wincol() - col('.')
122+
let l:view = winsaveview()
123+
let l:scroll_x = l:view.leftcol
124+
let l:scroll_y = l:view.topline - 1
125+
let l:winpos = win_screenpos(win_getid())
126+
let l:origin1 = [l:winpos[0] + (a:pos[0] - l:scroll_y) - 1, l:winpos[1] + (a:pos[1] + a:pos[2] + l:ui_x - l:scroll_x) - 1]
127+
return [l:origin1[0] - 1, l:origin1[1] - 1]
128+
endfunction
129+
130+
"
131+
" _get_visible_popup_winids
132+
"
133+
function! s:_get_visible_popup_winids() abort
134+
if !exists('*popup_list')
135+
return []
136+
endif
137+
return filter(popup_list(), 'popup_getpos(v:val).visible')
138+
endfunction
139+

0 commit comments

Comments
 (0)