mirror of
https://github.com/zoriya/virtcolumn.nvim.git
synced 2026-08-16 02:44:44 +00:00
improve: remove unnecessary caches, use timer for TextChanged
This commit is contained in:
+39
-41
@@ -1,7 +1,6 @@
|
|||||||
--- vim.g.virtcolumn_char: ▕ by default
|
--- vim.g.virtcolumn_char: ▕ by default
|
||||||
|
|
||||||
local api = vim.api
|
local api = vim.api
|
||||||
local fn = vim.fn
|
|
||||||
local ffi = require "ffi"
|
local ffi = require "ffi"
|
||||||
|
|
||||||
ffi.cdef "int curwin_col_off(void);"
|
ffi.cdef "int curwin_col_off(void);"
|
||||||
@@ -10,35 +9,20 @@ local curwin_col_off = ffi.C.curwin_col_off
|
|||||||
|
|
||||||
local NS = api.nvim_create_namespace "virt-column"
|
local NS = api.nvim_create_namespace "virt-column"
|
||||||
|
|
||||||
local function _refresh()
|
---@param cc string
|
||||||
local bufnr = api.nvim_get_current_buf()
|
---@return number[]
|
||||||
if not api.nvim_buf_is_loaded(bufnr) then
|
local function parse_items(cc)
|
||||||
return
|
local textwidth = vim.o.textwidth
|
||||||
end
|
|
||||||
|
|
||||||
local virtcolumn = vim.b.virtcolumn or vim.w.virtcolumn
|
|
||||||
|
|
||||||
local local_cc = vim.wo.cc
|
|
||||||
if not virtcolumn or local_cc ~= "" then
|
|
||||||
virtcolumn = local_cc
|
|
||||||
vim.wo.cc = ""
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.b.virtcolumn = virtcolumn
|
|
||||||
vim.w.virtcolumn = virtcolumn
|
|
||||||
|
|
||||||
---@type number[]
|
---@type number[]
|
||||||
local items = {}
|
local items = {}
|
||||||
|
for _, c in ipairs(vim.split(cc, ",")) do
|
||||||
local textwidth = vim.opt.textwidth:get()
|
|
||||||
for _, c in ipairs(vim.split(virtcolumn, ",")) do
|
|
||||||
local item
|
local item
|
||||||
if c and c ~= "" then
|
if c and c ~= "" then
|
||||||
if vim.startswith(c, "+") then
|
if vim.startswith(c, "+") then
|
||||||
if textwidth ~= 0 then
|
if textwidth ~= 0 then
|
||||||
item = textwidth + tonumber(c:sub(2))
|
item = textwidth + tonumber(c:sub(2))
|
||||||
end
|
end
|
||||||
elseif vim.startswith(virtcolumn, "-") then
|
elseif vim.startswith(cc, "-") then
|
||||||
if textwidth ~= 0 then
|
if textwidth ~= 0 then
|
||||||
item = textwidth - tonumber(c:sub(2))
|
item = textwidth - tonumber(c:sub(2))
|
||||||
end
|
end
|
||||||
@@ -53,21 +37,38 @@ local function _refresh()
|
|||||||
table.sort(items, function(a, b)
|
table.sort(items, function(a, b)
|
||||||
return a > b
|
return a > b
|
||||||
end)
|
end)
|
||||||
|
return items
|
||||||
|
end
|
||||||
|
|
||||||
api.nvim_buf_clear_namespace(bufnr, NS, 0, -1)
|
local function _refresh()
|
||||||
|
local curbuf = api.nvim_get_current_buf()
|
||||||
|
if not api.nvim_buf_is_loaded(curbuf) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local items = vim.b.virtcolumn_items or vim.w.virtcolumn_items
|
||||||
|
local local_cc = vim.wo.cc
|
||||||
|
if not items or local_cc ~= "" then
|
||||||
|
items = parse_items(local_cc)
|
||||||
|
vim.wo.cc = ""
|
||||||
|
end
|
||||||
|
vim.b.virtcolumn_items = items
|
||||||
|
vim.w.virtcolumn_items = items
|
||||||
|
|
||||||
|
api.nvim_buf_clear_namespace(curbuf, NS, 0, -1)
|
||||||
|
|
||||||
if #items == 0 then
|
if #items == 0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local win_lines = vim.o.lines
|
local debounce = math.floor(api.nvim_win_get_height(0) * 0.6)
|
||||||
local offset = vim.fn.line "w0"
|
local offset = vim.fn.line "w0"
|
||||||
-- Avoid flickering caused by winscrolled_timer
|
-- Avoid flickering caused by winscrolled_timer
|
||||||
offset = offset <= win_lines and 1 or offset - win_lines
|
offset = (offset <= debounce and 1 or offset - debounce) - 1 -- convert to 0-based
|
||||||
|
|
||||||
-- Avoid flickering caused by winscrolled_timer
|
-- Avoid flickering caused by winscrolled_timer
|
||||||
-- ↓↓↓↓↓↓↓↓↓↓↓
|
-- ↓↓↓↓↓↓↓↓↓↓↓
|
||||||
local lines = api.nvim_buf_get_lines(bufnr, offset - 1, vim.fn.line "w$" + win_lines, false)
|
local lines = api.nvim_buf_get_lines(curbuf, offset, vim.fn.line "w$" + debounce, false)
|
||||||
local width = api.nvim_win_get_width(0) - curwin_col_off()
|
local width = api.nvim_win_get_width(0) - curwin_col_off()
|
||||||
local tabstop = vim.opt.tabstop:get()
|
local tabstop = vim.opt.tabstop:get()
|
||||||
local char = vim.g.virtcolumn_char or "▕"
|
local char = vim.g.virtcolumn_char or "▕"
|
||||||
@@ -76,7 +77,7 @@ local function _refresh()
|
|||||||
for _, item in ipairs(items) do
|
for _, item in ipairs(items) do
|
||||||
local line = lines[i]:gsub("\t", string.rep(" ", tabstop))
|
local line = lines[i]:gsub("\t", string.rep(" ", tabstop))
|
||||||
if width > item and api.nvim_strwidth(line) < item then
|
if width > item and api.nvim_strwidth(line) < item then
|
||||||
api.nvim_buf_set_extmark(bufnr, NS, i + offset - 2, 0, {
|
api.nvim_buf_set_extmark(curbuf, NS, i + offset - 1, 0, {
|
||||||
virt_text = { { char, "VirtColumn" } },
|
virt_text = { { char, "VirtColumn" } },
|
||||||
virt_text_pos = "overlay",
|
virt_text_pos = "overlay",
|
||||||
hl_mode = "combine",
|
hl_mode = "combine",
|
||||||
@@ -88,8 +89,9 @@ local function _refresh()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Avoid unnecessary refreshing as much as possible
|
-- Avoid unnecessary refreshing as much as possible lcoallfdafffadf
|
||||||
local winscrolled_timer
|
local winscrolled_timer
|
||||||
|
local textchanged_timer
|
||||||
local function refresh(args)
|
local function refresh(args)
|
||||||
---@type string
|
---@type string
|
||||||
local event = args.event or ""
|
local event = args.event or ""
|
||||||
@@ -98,14 +100,13 @@ local function refresh(args)
|
|||||||
winscrolled_timer:stop()
|
winscrolled_timer:stop()
|
||||||
winscrolled_timer:close()
|
winscrolled_timer:close()
|
||||||
end
|
end
|
||||||
winscrolled_timer = vim.defer_fn(_refresh, 100)
|
winscrolled_timer = vim.defer_fn(_refresh, 150)
|
||||||
elseif event:match "TextChanged" then
|
elseif event:match "TextChanged" then
|
||||||
local lines_count = fn.line "$"
|
if textchanged_timer and textchanged_timer:is_active() then
|
||||||
local need_refresh = vim.b.virtcolumn_lines_count ~= lines_count
|
textchanged_timer:stop()
|
||||||
vim.b.virtcolumn_lines_count = lines_count
|
textchanged_timer:close()
|
||||||
if need_refresh then
|
|
||||||
_refresh()
|
|
||||||
end
|
end
|
||||||
|
textchanged_timer = vim.defer_fn(_refresh, 500)
|
||||||
else
|
else
|
||||||
_refresh()
|
_refresh()
|
||||||
end
|
end
|
||||||
@@ -119,7 +120,6 @@ local function set_hl()
|
|||||||
vim.cmd [[hi default link VirtColumn NonText]]
|
vim.cmd [[hi default link VirtColumn NonText]]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
set_hl()
|
|
||||||
|
|
||||||
local group = api.nvim_create_augroup("virtcolumn", {})
|
local group = api.nvim_create_augroup("virtcolumn", {})
|
||||||
api.nvim_create_autocmd({
|
api.nvim_create_autocmd({
|
||||||
@@ -130,11 +130,9 @@ api.nvim_create_autocmd({
|
|||||||
"InsertLeave",
|
"InsertLeave",
|
||||||
"InsertEnter",
|
"InsertEnter",
|
||||||
"FileChangedShellPost",
|
"FileChangedShellPost",
|
||||||
}, {
|
}, { group = group, callback = refresh })
|
||||||
group = group,
|
|
||||||
callback = refresh,
|
|
||||||
})
|
|
||||||
api.nvim_create_autocmd("OptionSet", { group = group, callback = refresh, pattern = "colorcolumn" })
|
api.nvim_create_autocmd("OptionSet", { group = group, callback = refresh, pattern = "colorcolumn" })
|
||||||
api.nvim_create_autocmd("ColorScheme", { group = group, callback = set_hl })
|
api.nvim_create_autocmd("ColorScheme", { group = group, callback = set_hl })
|
||||||
|
|
||||||
|
pcall(set_hl)
|
||||||
pcall(_refresh)
|
pcall(_refresh)
|
||||||
|
|||||||
Reference in New Issue
Block a user