feat(buffer): persist extmarks during editing (#96)
* refactor(buffer): split extmark namespace into `ns_eol` and `ns_inline` Problem: all extmarks shared a single `pending` namespace, making it impossible to selectively clear position-sensitive extmarks (overlays, highlights) while preserving stable EOL virtual text (due dates, recurrence). Solution: introduce `ns_eol` for end-of-line virtual text and `ns_inline` for overlays and highlights. `clear_marks()` and `apply_extmarks()` operate on both namespaces independently. * feat(buffer): track line changes via `on_bytes` to keep `_meta` aligned Problem: `_meta` is a positional array keyed by line number. Line insertions and deletions during editing desync it from actual buffer content, breaking `get_fold()`, cursor-based task lookups, and extmark re-application. Solution: attach an `on_bytes` callback that adjusts `_meta` on line insertions/deletions and tracks dirty rows. Remove the manual `_meta` insert from `open_line()` since `on_bytes` now handles it. Reset dirty rows on each full render. * feat(buffer): clear only inline extmarks on dirty rows during edits Problem: `TextChanged` cleared all extmarks (both namespaces) on every edit, causing EOL virtual text (due dates, recurrence) to vanish while the user types. Solution: replace blanket `clear_marks()` with per-row `clear_inline_row()` that only removes `ns_inline` extmarks on rows flagged dirty by `on_bytes`. EOL virtual text is preserved untouched. * feat(buffer): re-apply inline extmarks after edits Problem: inline extmarks (checkbox overlays, strikethrough, header highlights) were cleared during edits and only restored on `:w`, leaving the buffer visually bare while editing. Solution: extract `apply_inline_row()` from `apply_extmarks()` and call it via `reapply_dirty_inline()` on `InsertLeave` and normal-mode `TextChanged`. Insert-mode `TextChangedI` still only clears inline marks on dirty rows to avoid overlay flicker while typing. * 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
f56de46b4d
commit
5161ef00a0
2 changed files with 162 additions and 48 deletions
|
|
@ -251,12 +251,34 @@ function M._setup_autocmds(bufnr)
|
|||
end
|
||||
end,
|
||||
})
|
||||
vim.api.nvim_create_autocmd({ 'TextChanged', 'TextChangedI' }, {
|
||||
vim.api.nvim_create_autocmd('TextChangedI', {
|
||||
group = group,
|
||||
buffer = bufnr,
|
||||
callback = function()
|
||||
if not vim.bo[bufnr].modified then
|
||||
return
|
||||
end
|
||||
for row in pairs(buffer.dirty_rows()) do
|
||||
buffer.clear_inline_row(bufnr, row)
|
||||
end
|
||||
end,
|
||||
})
|
||||
vim.api.nvim_create_autocmd('TextChanged', {
|
||||
group = group,
|
||||
buffer = bufnr,
|
||||
callback = function()
|
||||
if not vim.bo[bufnr].modified then
|
||||
return
|
||||
end
|
||||
buffer.reapply_dirty_inline(bufnr)
|
||||
end,
|
||||
})
|
||||
vim.api.nvim_create_autocmd('InsertLeave', {
|
||||
group = group,
|
||||
buffer = bufnr,
|
||||
callback = function()
|
||||
if vim.bo[bufnr].modified then
|
||||
buffer.clear_marks(bufnr)
|
||||
buffer.reapply_dirty_inline(bufnr)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue