Skip to content

Commit 37423a8

Browse files
committed
init
0 parents  commit 37423a8

File tree

6 files changed

+191
-0
lines changed

6 files changed

+191
-0
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# elevator.vim
2+
3+
Elevator is a scollbar that utilizes VIM popup feature and works across both VIM and GVIM.
4+
5+
[![screenshot](/elevator.png)](https://github.com/noscript/taberian.vim/assets/717109/05af6167-69fa-4f63-8ac1-55479aa4773c)

autoload/elevator.vim

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
vim9script noclear
2+
3+
# defaults:
4+
if !exists('g:elevator#timeout_msec')
5+
g:elevator#timeout_msec = 2000
6+
endif
7+
8+
var s_state = {
9+
scrolloff: -1,
10+
screenrow: -1,
11+
topline: -1,
12+
dragging: false,
13+
scrolled_winid: -1,
14+
popup_id: -1,
15+
timer_id: -1,
16+
}
17+
18+
def S__clamp(value__a: number, min__a: number, max__a: number): number
19+
if value__a < min__a
20+
return min__a
21+
elseif value__a > max__a
22+
return max__a
23+
else
24+
return value__a
25+
endif
26+
enddef
27+
28+
def S__calculate_scale(winid__a: number): float
29+
var winheight = winheight(winid__a)
30+
return 1.0 * winheight / (line('$', winid__a) + winheight)
31+
enddef
32+
33+
export def Show(winid__a: number)
34+
if s_state.dragging
35+
return
36+
endif
37+
38+
S__stop_timer()
39+
40+
if winid__a == 0 # over command line
41+
var mousepos = getmousepos()
42+
# find window above mouse cursor:
43+
for wininfo in getwininfo()
44+
if (
45+
wininfo.winrow + wininfo.height + &cmdheight == &lines &&
46+
wininfo.wincol < mousepos.screencol && wininfo.wincol + wininfo.width > mousepos.screencol
47+
)
48+
s_state.scrolled_winid = wininfo.winid
49+
break
50+
endif
51+
endfor
52+
else
53+
s_state.scrolled_winid = winid__a
54+
endif
55+
56+
if s_state.popup_id == -1
57+
s_state.popup_id = popup_create('', {
58+
pos: 'topleft',
59+
minwidth: 1,
60+
dragall: true,
61+
resize: true,
62+
zindex: 1,
63+
})
64+
65+
endif
66+
67+
S__set_geometry()
68+
S__restart_timer()
69+
enddef
70+
71+
def S__stop_timer()
72+
if s_state.timer_id != -1
73+
timer_stop(s_state.timer_id)
74+
s_state.timer_id = -1
75+
endif
76+
enddef
77+
78+
def S__restart_timer()
79+
S__stop_timer()
80+
s_state.timer_id = timer_start(g:elevator#timeout_msec, (_) => S__close())
81+
enddef
82+
83+
def S__close()
84+
popup_close(s_state.popup_id)
85+
s_state.popup_id = -1
86+
s_state.timer_id = -1
87+
enddef
88+
89+
export def S__set_geometry()
90+
var wininfo = getwininfo(s_state.scrolled_winid)[0]
91+
var scale = S__calculate_scale(s_state.scrolled_winid)
92+
if scale >= 1.0
93+
S__close()
94+
return
95+
endif
96+
97+
var popup_height = S__clamp((wininfo.height * scale)->round()->float2nr(), 1, wininfo.height)
98+
var popup_offset = S__clamp(((wininfo.topline - 1) * scale)->round()->float2nr(), 0, wininfo.height - popup_height)
99+
100+
popup_setoptions(s_state.popup_id, {
101+
col: wininfo.wincol + wininfo.width - 1,
102+
line: wininfo.winrow + wininfo.winbar + popup_offset,
103+
minheight: popup_height,
104+
})
105+
enddef
106+
107+
def S__on_mouse(event__a: string)
108+
var mousepos = getmousepos()
109+
if event__a == 'LeftMouse' && mousepos.winid == s_state.popup_id
110+
s_state.screenrow = mousepos.screenrow
111+
s_state.topline = line('w0')
112+
s_state.dragging = true
113+
s_state.scrolloff = &scrolloff
114+
&scrolloff = 0
115+
S__stop_timer()
116+
win_gotoid(s_state.scrolled_winid)
117+
popup_setoptions(s_state.popup_id, {dragall: false})
118+
elseif event__a == 'LeftDrag' && s_state.dragging
119+
var delta = mousepos.screenrow - s_state.screenrow
120+
var savedview = winsaveview()
121+
var scale = S__calculate_scale(s_state.scrolled_winid)
122+
savedview.topline = S__clamp(s_state.topline + (delta / scale)->round()->float2nr(), 1, line('$'))
123+
savedview.lnum = S__clamp(savedview.lnum, savedview.topline, savedview.topline + line('w$') - line('w0'))
124+
winrestview(savedview)
125+
S__set_geometry()
126+
elseif event__a == 'LeftRelease' && s_state.dragging
127+
s_state.dragging = false
128+
s_state.screenrow = -1
129+
s_state.topline = -1
130+
&scrolloff = s_state.scrolloff
131+
s_state.scrolloff = -1
132+
S__restart_timer()
133+
popup_setoptions(s_state.popup_id, {dragall: true})
134+
endif
135+
enddef
136+
137+
noremap <LeftDrag> <LeftDrag><ScriptCmd>S__on_mouse('LeftDrag')<CR>
138+
noremap <LeftMouse> <LeftMouse><ScriptCmd>S__on_mouse('LeftMouse')<CR>
139+
noremap <LeftRelease> <LeftRelease><ScriptCmd>S__on_mouse('LeftRelease')<CR>

doc/elevator.txt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
*elevator.txt* Clickable tabs per window
2+
3+
Author: Sergey Vlasov <sergey@vlasov.me>
4+
Licence: Vim licence, see |license|
5+
Site: https://github.com/noscript/elevator.vim
6+
Version: 0.1
7+
8+
================================================================================
9+
CONTENTS *elevator-contents*
10+
11+
Intro...................................................|elevator-intro|
12+
Mappings.............................................|elevator-mappings|
13+
Mouse...................................................|elevator-mouse|
14+
Commands.............................................|elevator-commands|
15+
Functions...........................................|elevator-functions|
16+
Variables...........................................|elevator-variables|
17+
18+
================================================================================
19+
INTRO *elevator-intro*
20+
21+
Elevator is a scollbar that utilizes VIM |popup| feature and works across both
22+
VIM and GVIM.
23+
24+
Elevator works out of the box and does not require any configuration.
25+
26+
================================================================================
27+
VARIABLES *elevator-variables*
28+
29+
*g:elevator#timeout_msec* Timeout after which the scrollbar will
30+
hide automatically.
31+
Default value: 2000
32+
Example:
33+
>
34+
g:elevator#timeout_msec = 1000
35+
<

elevator.png

19.2 KB
Loading

elevator.webm

547 KB
Binary file not shown.

plugin/elevator.vim

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
vim9script
2+
3+
if exists('g:elevator_loaded')
4+
finish
5+
endif
6+
g:elevator_loaded = true
7+
8+
import autoload 'elevator.vim'
9+
10+
augroup Elevator
11+
autocmd WinScrolled * elevator#Show(expand('<amatch>')->str2nr())
12+
augroup END

0 commit comments

Comments
 (0)