Repository: neovim/neovim
File: test/functional/lua/buffer_updates_spec.lua (Lua)

Code before:

    exec_lua(function()
      _G.res = {}
      vim.o.foldmethod = 'indent'
      vim.o.softtabstop = -1
      vim.api.nvim_buf_attach(0, false, {
        on_lines = function(_, bufnr, _, row, _, end_row)
          local lines = vim.api.nvim_buf_get_lines(bufnr, row, end_row, true)
          table.insert(_G.res, lines)
        end,
      })
    end)

    feed('i<Tab>')
    eq({ '\ta' }, exec_lua('return _G.res[#_G.res]'))
  end)
end)

describe('lua: nvim_buf_attach on_bytes', function()
  -- verifying the sizes with nvim_buf_get_offset is nice (checks we cannot
  -- assert the wrong thing), but masks errors with unflushed lines (as
  -- nvim_buf_get_offset forces a flush of the memline). To be safe run the
  -- test both ways.
  local function setup_eventcheck(verify, start_txt)
    if start_txt then
      api.nvim_buf_set_lines(0, 0, -1, true, start_txt)
    else
      start_txt = api.nvim_buf_get_lines(0, 0, -1, true)
    end
    local shadowbytes = table.concat(start_txt, '\n') .. '\n'
    -- TODO: while we are brewing the real strong coffee,
    -- verify should check buf_get_offset after every check_events
    if verify then
      local len = api.nvim_buf_get_offset(0, api.nvim_buf_line_count(0))
      eq(len == -1 and 1 or len, string.len(shadowbytes))
    end
    exec_lua('return test_register(...)', 0, 'on_bytes', 'test1', false, false, true)
    api.nvim_buf_get_changedtick(0)

    local verify_name = 'test1'
    local function check_events(expected)
      local events = exec_lua('return get_events(...)')
      expect_events(expected, events, 'byte updates')

      if not verify then
        return
      end

      for _, event in ipairs(events) do
        for _, elem in ipairs(event) do
          if type(elem) == 'number' and elem < 0 then

Review comment (suggestion):
The other tests use `check_events`. Using a different approach makes the tests harder to understand. OTOH, this test is testing both "lines" and "bytes".

Code after:

    exec_lua(function()
      _G.res = {}
      vim.o.foldmethod = 'indent'
      vim.o.softtabstop = -1
      vim.api.nvim_buf_attach(0, false, {
        on_lines = function(_, bufnr, _, row, _, end_row)
          local lines = vim.api.nvim_buf_get_lines(bufnr, row, end_row, true)
          table.insert(_G.res, lines)
        end,
      })
    end)

    feed('i<Tab>')
    eq({ '\ta' }, exec_lua('return _G.res[#_G.res]'))
  end)

  it('quickfix buffer send change', function()
    command('copen')
    exec_lua(function()
      vim.api.nvim_buf_attach(vim.api.nvim_get_current_buf(), false, {
        on_lines = function(...)
          vim.g.qf_on_lines = { ... }
        end,
        on_bytes = function(...)
          vim.g.qf_on_bytes = { ... }
        end,
      })
    end)
    command('caddexpr "foo"')
    eq({ 'bytes', 2, 2, 0, 0, 0, 0, 0, 0, 0, 6, 6 }, api.nvim_get_var('qf_on_bytes'))
    eq({ 'lines', 2, 3, 0, 1, 1, 1 }, api.nvim_get_var('qf_on_lines'))

    command('caddexpr "bar"')
    eq({ 'bytes', 2, 3, 0, 6, 6, 0, 0, 0, 1, 6, 6 }, api.nvim_get_var('qf_on_bytes'))
    eq({ 'lines', 2, 4, 1, 2, 4, 0 }, api.nvim_get_var('qf_on_lines'))

    command('caddexpr ["line1", "line2", "line3"]')
    eq({ 'bytes', 2, 4, 1, 6, 13, 0, 0, 0, 3, 8, 26 }, api.nvim_get_var('qf_on_bytes'))
    eq({ 'lines', 2, 5, 2, 5, 9, 0 }, api.nvim_get_var('qf_on_lines'))

    command('cexpr "replace"')
    eq({ 'bytes', 2, 5, 0, 0, 0, 4, 0, 40, 0, 10, 10 }, api.nvim_get_var('qf_on_bytes'))
    eq({ 'lines', 2, 6, 0, 5, 1, 42 }, api.nvim_get_var('qf_on_lines'))
  end)
end)

describe('lua: nvim_buf_attach on_bytes', function()
  -- verifying the sizes with nvim_buf_get_offset is nice (checks we cannot
  -- assert the wrong thing), but masks errors with unflushed lines (as
  -- nvim_buf_get_offset forces a flush of the memline). To be safe run the