Skip to content

fix: read equation text from the parsed buffer, not the current one - #26

Open
Chiarandini wants to merge 1 commit into
Thiago4532:mainfrom
Chiarandini:fix/parse-reads-wrong-buffer
Open

fix: read equation text from the parsed buffer, not the current one#26
Chiarandini wants to merge 1 commit into
Thiago4532:mainfrom
Chiarandini:fix/parse-reads-wrong-buffer

Conversation

@Chiarandini

Copy link
Copy Markdown

Problem

Buffer:parse passes 0 as the treesitter source to both iter_captures and get_node_text (lua/mdmath/overlay.lua:154,156), so equation text is read from whichever buffer is current, not from self.bufnr — the buffer being parsed.

parse_view runs from the update_interval timer armed by on_lines and WinScrolled, so leaving the markdown buffer inside that window makes the node's range resolve against the wrong buffer. Two failure modes, both reachable from a file containing nothing but $x+y$:

1. Current buffer long enough to cover the node's rowsget_node_text clips to that buffer's line lengths and returns "". An empty equation is rendered at width 0, the processor errors, and Equation:_create takes the error branch, which calls marks.add with a text length of 0. Mark:_init then computes col_end == col and tracker.add asserts:

vim.schedule callback: .../lua/mdmath/tracker.lua:152: assertion failed!
stack traceback:
    [C]: in function 'assert'
    .../lua/mdmath/tracker.lua:152: in function 'add'
    .../lua/mdmath/marks.lua:50: in function '_init'
    .../lua/mdmath/util.lua:13: in function 'new'
    .../lua/mdmath/marks.lua:373: in function 'add'
    .../lua/mdmath/Equation.lua:24: in function <.../lua/mdmath/Equation.lua:22>

2. Current buffer shorter than the node's start rownvim_buf_get_text raises Index out of bounds out of get_node_text instead.

Reproduction

Headless, no terminal or built processor required — the node processor and terminfo.cell_size are stubbed, and the error callback stands in for the render failure:

vim.opt.runtimepath:append("/path/to/mdmath.nvim")
require("mdmath").setup({ filetypes = {}, update_interval = 50 })

require("mdmath.terminfo").cell_size = function() return 10, 20 end
require("mdmath.Processor").from_bufnr = function()
  return { request = function(_, eq, _, _, width, _, _, _, cb)
    vim.schedule(function() cb(nil, "Undefined control sequence") end)
  end }
end

local md = vim.api.nvim_create_buf(true, false)
vim.api.nvim_buf_set_lines(md, 0, -1, false, { "a $x+y$ b", "line2", "line3", "line4" })
vim.bo[md].filetype = "markdown"
vim.api.nvim_set_current_buf(md)
require("mdmath.overlay").enable(md)
vim.wait(400)

-- edit, then leave the buffer before the timer fires
vim.api.nvim_buf_set_lines(md, 1, 2, false, { "line2 edited" })
local small = vim.api.nvim_create_buf(true, false)
vim.api.nvim_buf_set_lines(small, 0, -1, false, { "x" })
vim.api.nvim_set_current_buf(small)
vim.wait(1500, function() return false end)

Before this change the second parse calls Equation.new(buf, 0, 2, "") and asserts. After it, the second parse produces no equation at all and the buffer's existing ones are left alone.

Note

parse_view has the same class of bug in its row range: util.get_current_view() reads line('w0')/line('w$') from the current window rather than a window showing self.bufnr. That one only mis-scopes which rows are parsed, so it is left for a separate change.

Buffer:parse passes 0 as the treesitter source to iter_captures and
get_node_text, so both read whichever buffer happens to be current
rather than self.bufnr.

parse_view runs from the update_interval timer armed by on_lines and
WinScrolled, so leaving the markdown buffer inside that window makes the
node's range resolve against the wrong buffer:

  - a longer current buffer yields an empty string, and rendering "" fails.
    Drawing the resulting error message calls marks.add with length 0,
    which trips assert(col_end > col) in tracker.add.

  - a shorter current buffer raises "Index out of bounds" from
    nvim_buf_get_text.

Both are reachable from a file containing nothing but $x+y$.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant