mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-03 00:00:04 +08:00
feat(scrollbar): implement scrollbar in lua
This commit is contained in:
parent
92395fbeae
commit
daf814589b
@ -6,6 +6,21 @@
|
||||
" License: GPLv3
|
||||
"=============================================================================
|
||||
|
||||
if has('nvim-0.9.0')
|
||||
function! SpaceVim#plugins#scrollbar#usable() abort
|
||||
return luaeval('require("spacevim.plugin.scrollbar").usable()')
|
||||
endfunction
|
||||
function! SpaceVim#plugins#scrollbar#show() abort
|
||||
lua require('spacevim.plugin.scrollbar').show()
|
||||
endfunction
|
||||
function! SpaceVim#plugins#scrollbar#clear(...) abort
|
||||
lua require('spacevim.plugin.scrollbar').clear()
|
||||
endfunction
|
||||
finish
|
||||
endif
|
||||
|
||||
|
||||
|
||||
let s:VIM = SpaceVim#api#import('vim')
|
||||
let s:BUF = SpaceVim#api#import('vim#buffer')
|
||||
let s:WIN = SpaceVim#api#import('vim#window')
|
||||
|
161
lua/spacevim/plugin/scrollbar.lua
Normal file
161
lua/spacevim/plugin/scrollbar.lua
Normal file
@ -0,0 +1,161 @@
|
||||
--=============================================================================
|
||||
-- scrollbar.lua --- scrollbar for SpaceVim
|
||||
-- Copyright (c) 2016-2022 Wang Shidong & Contributors
|
||||
-- Author: Wang Shidong < wsdjeg@outlook.com >
|
||||
-- URL: https://spacevim.org
|
||||
-- License: GPLv3
|
||||
--=============================================================================
|
||||
|
||||
local M = {}
|
||||
|
||||
local win = require('spacevim.api.vim.window')
|
||||
|
||||
local default_conf = {
|
||||
max_size = 10,
|
||||
min_size = 3,
|
||||
width = 1,
|
||||
right_offset = 1,
|
||||
excluded_filetypes = {
|
||||
'startify',
|
||||
'git-commit',
|
||||
'leaderf',
|
||||
'NvimTree',
|
||||
'tagbar',
|
||||
'defx',
|
||||
'neo-tree',
|
||||
'qf',
|
||||
},
|
||||
shape = {
|
||||
head = '▲',
|
||||
body = '█',
|
||||
tail = '▼',
|
||||
},
|
||||
highlight = {
|
||||
head = 'Normal',
|
||||
body = 'Normal',
|
||||
tail = 'Normal',
|
||||
},
|
||||
}
|
||||
local function get(opt)
|
||||
|
||||
return default_conf[opt]
|
||||
|
||||
end
|
||||
|
||||
local scrollbar_bufnr = -1
|
||||
local scrollbar_winid = -1
|
||||
local scrollbar_size = -1
|
||||
local ns_id = vim.api.nvim_create_namespace('scrollbar')
|
||||
|
||||
local function add_highlight(bufnr, size)
|
||||
local highlight = get('highlight')
|
||||
vim.api.nvim_buf_add_highlight(bufnr, ns_id, highlight.head, 0, 0, -1)
|
||||
for i = 1, size - 2 do
|
||||
vim.api.nvim_buf_add_highlight(bufnr, ns_id, highlight.body, i, 0, -1)
|
||||
end
|
||||
vim.api.nvim_buf_add_highlight(bufnr, ns_id, highlight.tail, size - 1, 0, -1)
|
||||
end
|
||||
|
||||
local function fix_size(size)
|
||||
return math.max(get('min_size'), math.min(get('max_size'), math.floor(size + 0.5)))
|
||||
end
|
||||
|
||||
local function gen_bar_lines(size)
|
||||
local shape = get('shape')
|
||||
local lines = { shape.head }
|
||||
for _ = 2, size - 1 do
|
||||
table.insert(lines, shape.body)
|
||||
end
|
||||
table.insert(lines, shape.tail)
|
||||
return lines
|
||||
end
|
||||
|
||||
local function create_scrollbar_buffer(size, lines)
|
||||
if not vim.api.nvim_buf_is_valid(scrollbar_bufnr) then
|
||||
scrollbar_bufnr = vim.api.nvim_create_buf(false, true)
|
||||
end
|
||||
vim.api.nvim_buf_set_lines(scrollbar_bufnr, 0, -1, false, lines)
|
||||
add_highlight(scrollbar_bufnr, size)
|
||||
return scrollbar_bufnr
|
||||
end
|
||||
|
||||
function M.show()
|
||||
local saved_ei = vim.o.eventignore
|
||||
vim.o.eventignore = 'all'
|
||||
local winnr = vim.fn.winnr()
|
||||
local bufnr = vim.fn.bufnr()
|
||||
local winid = vim.fn.win_getid()
|
||||
if win.is_float(winid) then
|
||||
M.clear()
|
||||
vim.o.eventignore = saved_ei
|
||||
return
|
||||
end
|
||||
|
||||
local total = vim.api.nvim_buf_line_count(bufnr)
|
||||
local height = vim.fn.winheight(winnr)
|
||||
|
||||
if total <= height then
|
||||
M.clear()
|
||||
vim.o.eventignore = saved_ei
|
||||
return
|
||||
end
|
||||
|
||||
local curr_line = vim.fn.line('w0')
|
||||
local bar_size = fix_size(height * height / total)
|
||||
local width = vim.fn.winwidth(winnr)
|
||||
local col = width - get('width') - get('right_offset')
|
||||
local precision = height - bar_size
|
||||
local each_line = (total - height) * 1.0 / precision
|
||||
local visble_line = vim.fn.min({ curr_line, total - height + 1 })
|
||||
local row
|
||||
if each_line >= 1 then
|
||||
row = vim.fn.float2nr(visble_line / each_line)
|
||||
else
|
||||
row = vim.fn.float2nr(visble_line / each_line - 1 / each_line)
|
||||
end
|
||||
|
||||
local opts = {
|
||||
style = 'minimal',
|
||||
relative = 'win',
|
||||
win = winid,
|
||||
width = get('width'),
|
||||
height = bar_size,
|
||||
row = row,
|
||||
col = vim.fn.float2nr(col),
|
||||
focusable = false,
|
||||
zindex = 10,
|
||||
}
|
||||
|
||||
if win.is_float(scrollbar_winid) then
|
||||
if bar_size ~= scrollbar_size then
|
||||
scrollbar_size = bar_size
|
||||
local bar_lines = gen_bar_lines(bar_size)
|
||||
vim.api.nvim_buf_set_lines(scrollbar_bufnr, 0, -1, false, bar_lines)
|
||||
add_highlight(scrollbar_bufnr, bar_size)
|
||||
end
|
||||
vim.api.nvim_win_set_config(scrollbar_winid, opts)
|
||||
else
|
||||
scrollbar_size = bar_size
|
||||
local bar_lines = gen_bar_lines(bar_size)
|
||||
scrollbar_bufnr = create_scrollbar_buffer(bar_size, bar_lines)
|
||||
scrollbar_winid = vim.api.nvim_open_win(scrollbar_bufnr, false, opts)
|
||||
vim.fn.setwinvar(
|
||||
vim.fn.win_id2win(scrollbar_winid),
|
||||
'&winhighlight',
|
||||
'Normal:ScrollbarWinHighlight'
|
||||
)
|
||||
end
|
||||
vim.o.eventignore = saved_ei
|
||||
end
|
||||
|
||||
function M.clear()
|
||||
if vim.api.nvim_win_is_valid(scrollbar_winid) then
|
||||
vim.api.nvim_win_close(scrollbar_winid, true)
|
||||
end
|
||||
end
|
||||
|
||||
function M.usable()
|
||||
return true
|
||||
end
|
||||
|
||||
return M
|
Loading…
Reference in New Issue
Block a user