1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
--- Manages creating/updating scrollbar gutter and thumb windows
--- @class blink.cmp.ScrollbarWin
--- @field enable_gutter boolean
--- @field thumb_win? number
--- @field gutter_win? number
--- @field buf? number
---
--- @field new fun(opts: blink.cmp.ScrollbarConfig): blink.cmp.ScrollbarWin
--- @field is_visible fun(self: blink.cmp.ScrollbarWin): boolean
--- @field show_thumb fun(self: blink.cmp.ScrollbarWin, geometry: blink.cmp.ScrollbarGeometry)
--- @field show_gutter fun(self: blink.cmp.ScrollbarWin, geometry: blink.cmp.ScrollbarGeometry)
--- @field hide_thumb fun(self: blink.cmp.ScrollbarWin)
--- @field hide_gutter fun(self: blink.cmp.ScrollbarWin)
--- @field hide fun(self: blink.cmp.ScrollbarWin)
--- @field _make_win fun(self: blink.cmp.ScrollbarWin, geometry: blink.cmp.ScrollbarGeometry, hl_group: string): number
--- @field redraw_if_needed fun(self: blink.cmp.ScrollbarWin)
--- @type blink.cmp.ScrollbarWin
--- @diagnostic disable-next-line: missing-fields
local scrollbar_win = {}
function scrollbar_win.new(opts) return setmetatable(opts, { __index = scrollbar_win }) end
function scrollbar_win:is_visible() return self.thumb_win ~= nil and vim.api.nvim_win_is_valid(self.thumb_win) end
function scrollbar_win:show_thumb(geometry)
-- create window if it doesn't exist
if self.thumb_win == nil or not vim.api.nvim_win_is_valid(self.thumb_win) then
self.thumb_win = self:_make_win(geometry, 'BlinkCmpScrollBarThumb')
else
-- update with the geometry
local thumb_existing_config = vim.api.nvim_win_get_config(self.thumb_win)
local thumb_config = vim.tbl_deep_extend('force', thumb_existing_config, geometry)
vim.api.nvim_win_set_config(self.thumb_win, thumb_config)
end
self:redraw_if_needed()
end
function scrollbar_win:show_gutter(geometry)
if not self.enable_gutter then return end
-- create window if it doesn't exist
if self.gutter_win == nil or not vim.api.nvim_win_is_valid(self.gutter_win) then
self.gutter_win = self:_make_win(geometry, 'BlinkCmpScrollBarGutter')
else
-- update with the geometry
local gutter_existing_config = vim.api.nvim_win_get_config(self.gutter_win)
local gutter_config = vim.tbl_deep_extend('force', gutter_existing_config, geometry)
vim.api.nvim_win_set_config(self.gutter_win, gutter_config)
end
self:redraw_if_needed()
end
function scrollbar_win:hide_thumb()
if self.thumb_win and vim.api.nvim_win_is_valid(self.thumb_win) then
vim.api.nvim_win_close(self.thumb_win, true)
self.thumb_win = nil
self:redraw_if_needed()
end
end
function scrollbar_win:hide_gutter()
if self.gutter_win and vim.api.nvim_win_is_valid(self.gutter_win) then
vim.api.nvim_win_close(self.gutter_win, true)
self.gutter_win = nil
self:redraw_if_needed()
end
end
function scrollbar_win:hide()
self:hide_thumb()
self:hide_gutter()
end
function scrollbar_win:_make_win(geometry, hl_group)
if self.buf == nil or not vim.api.nvim_buf_is_valid(self.buf) then self.buf = vim.api.nvim_create_buf(false, true) end
local win_config = vim.tbl_deep_extend('force', geometry, {
style = 'minimal',
focusable = false,
noautocmd = true,
})
local win = vim.api.nvim_open_win(self.buf, false, win_config)
vim.api.nvim_set_option_value('winhighlight', 'Normal:' .. hl_group .. ',EndOfBuffer:' .. hl_group, { win = win })
return win
end
local redraw_queued = false
function scrollbar_win:redraw_if_needed()
if redraw_queued or vim.api.nvim_get_mode().mode ~= 'c' then return end
redraw_queued = true
vim.schedule(function()
redraw_queued = false
if self.gutter_win ~= nil and vim.api.nvim_win_is_valid(self.gutter_win) then
vim.api.nvim__redraw({ win = self.gutter_win, flush = true })
end
if self.thumb_win ~= nil and vim.api.nvim_win_is_valid(self.thumb_win) then
vim.api.nvim__redraw({ win = self.thumb_win, flush = true })
end
end)
end
return scrollbar_win
|