Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: invalid window id #46

Merged
merged 2 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lua/smear_cursor/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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 ---------------------------------------------------------
Expand Down
58 changes: 32 additions & 26 deletions lua/smear_cursor/draw.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,6 @@ local extmark_id = 999
---@type table<number, {active:number, windows:{window_id:number, buffer_id:number}[]}>
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)
Expand All @@ -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,
Expand All @@ -81,16 +77,14 @@ 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 }
)
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

Expand All @@ -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
Expand All @@ -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

Expand Down
Loading