Skip to content

Commit

Permalink
feat(watcher): detach buffers on BufDelete and BufWipeout
Browse files Browse the repository at this point in the history
  • Loading branch information
Goose97 committed Nov 21, 2024
1 parent 72e169d commit 78aba1c
Show file tree
Hide file tree
Showing 4 changed files with 267 additions and 122 deletions.
111 changes: 91 additions & 20 deletions lua/neolog/buffers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,26 @@ local function render_placeholder_snippet(log_placeholder)
end
end

---@param log_placeholder LogPlaceholder
local function remove_placeholder_snippet(log_placeholder)
local is_loaded = vim.api.nvim_buf_is_loaded(log_placeholder.bufnr)
if not is_loaded then
return
end

local mark =
vim.api.nvim_buf_get_extmark_by_id(log_placeholder.bufnr, M.log_placeholder_ns, log_placeholder.extmark_id, {})

if mark and #mark > 0 then
---@type integer, integer
local row, col = unpack(mark, 1, 2)

vim.api.nvim_buf_set_extmark(log_placeholder.bufnr, M.log_placeholder_ns, row, col, {
id = log_placeholder.extmark_id,
})
end
end

---@param bufnr number
---@return boolean found_any_placeholders
local function process_buffer(bufnr)
Expand All @@ -120,18 +140,47 @@ local function process_buffer(bufnr)
return found_any
end

local function detach_buffer(bufnr)
local index = utils.array_find_index(M.attached_buffers, function(v)
return v == bufnr
end)

-- There's no API to detach a buffer. We will return false in the next on_lines callback
if index then
table.remove(M.attached_buffers, index)
end
end

---@param extmark_id integer
---@param bufnr integer
local function delete_placeholder_by_extmark_id(extmark_id, bufnr)
local buf_remain_placeholders = 0

for placeholder_id, placeholder in pairs(M.log_placeholders) do
if placeholder.extmark_id == extmark_id and placeholder.bufnr == bufnr then
M.log_placeholders[placeholder_id] = nil
break
if placeholder.bufnr == bufnr then
if placeholder.extmark_id == extmark_id then
M.log_placeholders[placeholder_id] = nil
else
buf_remain_placeholders = buf_remain_placeholders + 1
end
end
end

if buf_remain_placeholders == 0 then
detach_buffer(bufnr)
end
end

local function on_lines(_, bufnr, _, first_line, last_line, new_last_line, _)
-- local index = utils.array_find_index(M.attached_buffers, function(v)
-- return v == bufnr
-- end)
--
-- if not index then
-- -- Detach the buffer
-- return true
-- end

-- Process each line in the changed region
for lnum = first_line, new_last_line - 1 do
local line = vim.api.nvim_buf_get_lines(bufnr, lnum, lnum + 1, false)[1]
Expand Down Expand Up @@ -175,6 +224,21 @@ local function on_lines(_, bufnr, _, first_line, last_line, new_last_line, _)
end
end

local function attach_buffer(bufnr)
if vim.list_contains(M.attached_buffers, bufnr) then
return
end

vim.api.nvim_buf_attach(bufnr, false, {
on_lines = on_lines,
on_reload = function()
process_buffer(bufnr)
end,
})

table.insert(M.attached_buffers, bufnr)
end

---Callback for log entry received
--- @param entry WatcherLogEntry
function M.on_log_entry_received(entry)
Expand All @@ -195,21 +259,6 @@ function M.on_log_entry_received(entry)
end
end

local function attach_buffer(bufnr)
if vim.list_contains(M.attached_buffers, bufnr) then
return
end

vim.api.nvim_buf_attach(bufnr, false, {
on_lines = on_lines,
on_reload = function()
process_buffer(bufnr)
end,
})

table.insert(M.attached_buffers, bufnr)
end

---@param log_placeholder LogPlaceholder
function M.new_log_placeholder(log_placeholder)
if M.log_placeholders[log_placeholder.id] then
Expand Down Expand Up @@ -258,8 +307,10 @@ local function prepare_floating_window_content(contents)
local separators = {}
local line_count = 0

local total_entries_line
if has_total_entries then
table.insert(buf_content, utils.string_left_pad(string.format("Total entries: %d", #contents), max_width))
total_entries_line = utils.string_left_pad(string.format("%d entries", #contents), max_width)
table.insert(buf_content, total_entries_line)
line_count = line_count + 1
end

Expand All @@ -268,7 +319,8 @@ local function prepare_floating_window_content(contents)
line_count = line_count + #lines

if i < #contents then
table.insert(buf_content, string.rep("", max_width))
local separator_width = math.max(max_width, #total_entries_line)
table.insert(buf_content, string.rep("", separator_width))
table.insert(separators, line_count)
line_count = line_count + 1
end
Expand Down Expand Up @@ -344,6 +396,13 @@ local function update_placeholders_snippet()
end
end

function M.clear_logs()
for _, log_placeholder in pairs(M.log_placeholders) do
log_placeholder.contents = {}
remove_placeholder_snippet(log_placeholder)
end
end

function M.setup()
vim.api.nvim_set_hl(0, "Neolog.LogPlaceholderSnippet", { link = "DiagnosticVirtualTextInfo", default = true })
vim.api.nvim_set_hl(0, "Neolog.LogPlaceholderTime", { italic = true })
Expand All @@ -369,6 +428,18 @@ function M.setup()
end,
})

vim.api.nvim_create_autocmd("BufDelete", {
callback = function(args)
detach_buffer(args.buf)
end,
})

vim.api.nvim_create_autocmd("BufWipeout", {
callback = function(args)
detach_buffer(args.buf)
end,
})

-- Timer loop to keep updating the placeholder snippets
M.placeholder_render_timer = vim.uv.new_timer()
M.placeholder_render_timer:start(0, 10000, vim.schedule_wrap(update_placeholders_snippet))
Expand Down
10 changes: 10 additions & 0 deletions lua/neolog/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ function M.array_find(array, predicate)
return nil
end

function M.array_find_index(array, predicate)
for i, v in ipairs(array) do
if predicate(v, i) then
return i
end
end

return nil
end

function M.array_map(array, mapper)
local result = {}

Expand Down
1 change: 0 additions & 1 deletion tests/neolog/helper.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ local function setup_buffer(lines, cursor, filetype)
vim.api.nvim_set_option_value("shiftwidth", 2, { buf = buf })

vim.api.nvim_buf_set_lines(buf, 0, -1, true, lines)
-- vim.api.nvim_command("buffer " .. buf)
vim.api.nvim_set_current_buf(buf)
vim.api.nvim_exec_autocmds("BufRead", { buffer = buf })
if cursor then
Expand Down
Loading

0 comments on commit 78aba1c

Please sign in to comment.