diff --git a/lua/smear_cursor/config.lua b/lua/smear_cursor/config.lua index 9b1bf11..321720d 100644 --- a/lua/smear_cursor/config.lua +++ b/lua/smear_cursor/config.lua @@ -22,6 +22,9 @@ M.vertical_bar_cursor = false -- Attempt to hide the real cursor by drawing a character below it. M.hide_target_hack = true +-- Number of windows that stay open for rendering. +M.max_kept_windows = 30 + M.time_interval = 17 -- milliseconds -- Smear configuration --------------------------------------------------------- diff --git a/lua/smear_cursor/draw.lua b/lua/smear_cursor/draw.lua index 32367b1..b1cddd5 100644 --- a/lua/smear_cursor/draw.lua +++ b/lua/smear_cursor/draw.lua @@ -19,18 +19,6 @@ local extmark_id = 999 ---@type table local all_tab_windows = {} --- Remove any invalid windows -function M.check_windows() - for _, tab_windows in pairs(all_tab_windows) do - tab_windows.windows = vim.tbl_filter(function(wb) - return wb.window_id - and vim.api.nvim_win_is_valid(wb.window_id) - and wb.buffer_id - and vim.api.nvim_buf_is_valid(wb.buffer_id) - end, tab_windows.windows) - end -end - ---@param window_id number ---@param options vim.wo local function set_window_options(window_id, options) @@ -55,20 +43,28 @@ local function get_window(tab, row, col) all_tab_windows[tab] = all_tab_windows[tab] or { active = 0, windows = {} } local tab_windows = all_tab_windows[tab] + -- Find existing window tab_windows.active = tab_windows.active + 1 - local wb = tab_windows.windows[tab_windows.active] - - if wb then -- Window already exists - ---@type vim.api.keyset.win_config - local window_config = { relative = "editor", row = row - 1, col = col - 1 } - if can_hide then window_config.hide = false end - vim.api.nvim_win_set_config(wb.window_id, window_config) - return wb.window_id, wb.buffer_id + while tab_windows.active <= #tab_windows.windows do + local wb = tab_windows.windows[tab_windows.active] + + if vim.api.nvim_win_is_valid(wb.window_id) and vim.api.nvim_buf_is_valid(wb.buffer_id) then + ---@type vim.api.keyset.win_config + local window_config = { relative = "editor", row = row - 1, col = col - 1 } + if can_hide then window_config.hide = false end + vim.api.nvim_win_set_config(wb.window_id, window_config) + return wb.window_id, wb.buffer_id + end + + -- Remove invalid window + table.remove(tab_windows.windows, tab_windows.active) end -- Create a new window - local buffer_id = vim.api.nvim_create_buf(false, true) + local ei = vim.o.ei -- eventignore + vim.o.ei = "all" -- ignore all events + local buffer_id = vim.api.nvim_create_buf(false, true) local window_id = vim.api.nvim_open_win(buffer_id, false, { relative = "editor", row = row - 1, @@ -81,8 +77,6 @@ local function get_window(tab, row, col) zindex = 300, }) - local ei = vim.o.ei -- eventignore - vim.o.ei = "all" -- ignore all events set_buffer_options( buffer_id, { buftype = "nofile", filetype = "smear-cursor", bufhidden = "wipe", swapfile = false } @@ -90,7 +84,7 @@ local function get_window(tab, row, col) set_window_options(window_id, { winhighlight = "NormalFloat:Normal", winblend = 100 }) vim.o.ei = ei tab_windows.windows[tab_windows.active] = { window_id = window_id, buffer_id = buffer_id } - vim.api.nvim_create_autocmd("BufWipeout", { buffer = buffer_id, callback = vim.schedule_wrap(M.check_windows) }) + return window_id, buffer_id end @@ -107,9 +101,9 @@ M.draw_character = function(row, col, character, hl_group) end M.clear = function() - -- Hide the windows without deleting them for tab, tab_windows in pairs(all_tab_windows) do - for i = 1, tab_windows.active do + -- Hide windows without deleting them + for i = 1, math.min(tab_windows.active, config.max_kept_windows) do local wb = tab_windows.windows[i] if wb and vim.api.nvim_win_is_valid(wb.window_id) then @@ -123,6 +117,18 @@ M.clear = function() end all_tab_windows[tab].active = 0 + + -- Delete supplementary windows + local ei = vim.o.ei -- eventignore + vim.o.ei = "all" -- ignore all events + for i = config.max_kept_windows + 1, #tab_windows.windows do + local wb = tab_windows.windows[i] + + if wb and vim.api.nvim_win_is_valid(wb.window_id) then vim.api.nvim_win_close(wb.window_id, true) end + + tab_windows.windows[i] = nil + end + vim.o.ei = ei end end