fix(buffer): suppress on_bytes during render and fix definition order
Problem: `on_bytes` fired during `render()`'s `nvim_buf_set_lines`, corrupting `_meta` with duplicate entries and causing out-of-range extmark errors. Also, `apply_inline_row` was defined after its first caller `reapply_dirty_inline`. Solution: add `_rendering` guard flag around `nvim_buf_set_lines` in `render()` so `on_bytes` is a no-op during authoritative renders. Move `apply_inline_row` above `reapply_dirty_inline` to satisfy Lua local scoping rules.
This commit is contained in:
parent
e71d6cdff6
commit
27f46ae0dd
1 changed files with 56 additions and 49 deletions
|
|
@ -30,6 +30,8 @@ local _hidden_ids = {}
|
|||
local _dirty_rows = {}
|
||||
---@type boolean
|
||||
local _on_bytes_active = false
|
||||
---@type boolean
|
||||
local _rendering = false
|
||||
|
||||
---@return pending.LineMeta[]
|
||||
function M.meta()
|
||||
|
|
@ -116,6 +118,55 @@ function M.clear_dirty_rows()
|
|||
_dirty_rows = {}
|
||||
end
|
||||
|
||||
---@param bufnr integer
|
||||
---@param row integer
|
||||
---@param m pending.LineMeta
|
||||
---@param icons table
|
||||
local function apply_inline_row(bufnr, row, m, icons)
|
||||
if m.type == 'filter' then
|
||||
local line = vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false)[1] or ''
|
||||
vim.api.nvim_buf_set_extmark(bufnr, ns_inline, row, 0, {
|
||||
end_col = #line,
|
||||
hl_group = 'PendingFilter',
|
||||
})
|
||||
elseif m.type == 'task' then
|
||||
if m.status == 'done' then
|
||||
local line = vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false)[1] or ''
|
||||
local col_start = line:find('/%d+/') and select(2, line:find('/%d+/')) or 0
|
||||
vim.api.nvim_buf_set_extmark(bufnr, ns_inline, row, col_start, {
|
||||
end_col = #line,
|
||||
hl_group = 'PendingDone',
|
||||
})
|
||||
end
|
||||
local line = vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false)[1] or ''
|
||||
local bracket_col = (line:find('%[') or 1) - 1
|
||||
local icon, icon_hl
|
||||
if m.status == 'done' then
|
||||
icon, icon_hl = icons.done, 'PendingDone'
|
||||
elseif m.priority and m.priority > 0 then
|
||||
icon, icon_hl = icons.priority, 'PendingPriority'
|
||||
else
|
||||
icon, icon_hl = icons.pending, 'Normal'
|
||||
end
|
||||
vim.api.nvim_buf_set_extmark(bufnr, ns_inline, row, bracket_col, {
|
||||
virt_text = { { '[' .. icon .. ']', icon_hl } },
|
||||
virt_text_pos = 'overlay',
|
||||
priority = 100,
|
||||
})
|
||||
elseif m.type == 'header' then
|
||||
local line = vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false)[1] or ''
|
||||
vim.api.nvim_buf_set_extmark(bufnr, ns_inline, row, 0, {
|
||||
end_col = #line,
|
||||
hl_group = 'PendingHeader',
|
||||
})
|
||||
vim.api.nvim_buf_set_extmark(bufnr, ns_inline, row, 0, {
|
||||
virt_text = { { icons.category .. ' ', 'PendingHeader' } },
|
||||
virt_text_pos = 'overlay',
|
||||
priority = 100,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
---@param bufnr integer
|
||||
---@return nil
|
||||
function M.reapply_dirty_inline(bufnr)
|
||||
|
|
@ -146,6 +197,9 @@ function M.attach_bytes(bufnr)
|
|||
_on_bytes_active = false
|
||||
return true
|
||||
end
|
||||
if _rendering then
|
||||
return
|
||||
end
|
||||
local delta = new_end_row - old_end_row
|
||||
if delta > 0 then
|
||||
for _ = 1, delta do
|
||||
|
|
@ -298,55 +352,6 @@ function M.get_fold()
|
|||
end
|
||||
end
|
||||
|
||||
---@param bufnr integer
|
||||
---@param row integer
|
||||
---@param m pending.LineMeta
|
||||
---@param icons table
|
||||
local function apply_inline_row(bufnr, row, m, icons)
|
||||
if m.type == 'filter' then
|
||||
local line = vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false)[1] or ''
|
||||
vim.api.nvim_buf_set_extmark(bufnr, ns_inline, row, 0, {
|
||||
end_col = #line,
|
||||
hl_group = 'PendingFilter',
|
||||
})
|
||||
elseif m.type == 'task' then
|
||||
if m.status == 'done' then
|
||||
local line = vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false)[1] or ''
|
||||
local col_start = line:find('/%d+/') and select(2, line:find('/%d+/')) or 0
|
||||
vim.api.nvim_buf_set_extmark(bufnr, ns_inline, row, col_start, {
|
||||
end_col = #line,
|
||||
hl_group = 'PendingDone',
|
||||
})
|
||||
end
|
||||
local line = vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false)[1] or ''
|
||||
local bracket_col = (line:find('%[') or 1) - 1
|
||||
local icon, icon_hl
|
||||
if m.status == 'done' then
|
||||
icon, icon_hl = icons.done, 'PendingDone'
|
||||
elseif m.priority and m.priority > 0 then
|
||||
icon, icon_hl = icons.priority, 'PendingPriority'
|
||||
else
|
||||
icon, icon_hl = icons.pending, 'Normal'
|
||||
end
|
||||
vim.api.nvim_buf_set_extmark(bufnr, ns_inline, row, bracket_col, {
|
||||
virt_text = { { '[' .. icon .. ']', icon_hl } },
|
||||
virt_text_pos = 'overlay',
|
||||
priority = 100,
|
||||
})
|
||||
elseif m.type == 'header' then
|
||||
local line = vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false)[1] or ''
|
||||
vim.api.nvim_buf_set_extmark(bufnr, ns_inline, row, 0, {
|
||||
end_col = #line,
|
||||
hl_group = 'PendingHeader',
|
||||
})
|
||||
vim.api.nvim_buf_set_extmark(bufnr, ns_inline, row, 0, {
|
||||
virt_text = { { icons.category .. ' ', 'PendingHeader' } },
|
||||
virt_text_pos = 'overlay',
|
||||
priority = 100,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
---@param bufnr integer
|
||||
---@param line_meta pending.LineMeta[]
|
||||
local function apply_extmarks(bufnr, line_meta)
|
||||
|
|
@ -537,7 +542,9 @@ function M.render(bufnr)
|
|||
vim.bo[bufnr].modifiable = true
|
||||
local saved = vim.bo[bufnr].undolevels
|
||||
vim.bo[bufnr].undolevels = -1
|
||||
_rendering = true
|
||||
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
|
||||
_rendering = false
|
||||
vim.bo[bufnr].modified = false
|
||||
vim.bo[bufnr].undolevels = saved
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue