(renderer) add more tests; fix bugs in text-change
All checks were successful
NeoVim tests / code-quality (push) Successful in 1m21s
All checks were successful
NeoVim tests / code-quality (push) Successful in 1m21s
This commit is contained in:
parent
06e6b88391
commit
2ea6c02c69
@ -68,7 +68,7 @@ function Buffer:motion(motion, opts)
|
||||
return Range.from_motion(motion, opts)
|
||||
end
|
||||
|
||||
--- @param event string|string[]
|
||||
--- @param event vim.api.keyset.events|vim.api.keyset.events[]
|
||||
--- @diagnostic disable-next-line: undefined-doc-name
|
||||
--- @param opts vim.api.keyset.create_autocmd
|
||||
function Buffer:autocmd(event, opts)
|
||||
|
@ -1,5 +1,15 @@
|
||||
function _G.URendererOpFuncSwallow() end
|
||||
|
||||
local ENABLE_LOG = false
|
||||
|
||||
local function log(...)
|
||||
if not ENABLE_LOG then return end
|
||||
|
||||
local f = assert(io.open(vim.fs.joinpath(vim.fn.stdpath 'log', 'u.renderer.log'), 'a+'))
|
||||
f:write(os.date() .. '\t' .. vim.inspect { ... } .. '\n')
|
||||
f:close()
|
||||
end
|
||||
|
||||
local M = {}
|
||||
local H = {}
|
||||
|
||||
@ -251,8 +261,12 @@ function Renderer:render(tree) -- {{{
|
||||
-- to do that, forwarding the event to an operatorfunc that does
|
||||
-- nothing:
|
||||
if result == '' then
|
||||
vim.go.operatorfunc = 'v:lua.URendererOpFuncSwallow'
|
||||
return 'g@ '
|
||||
if mode == 'i' then
|
||||
return ''
|
||||
else
|
||||
vim.go.operatorfunc = 'v:lua.URendererOpFuncSwallow'
|
||||
return 'g@ '
|
||||
end
|
||||
end
|
||||
return result
|
||||
end, { buffer = self.bufnr, expr = true, replace_keycodes = true })
|
||||
@ -272,6 +286,7 @@ function Renderer:render(tree) -- {{{
|
||||
self.old = self.curr
|
||||
self.curr = { lines = lines, extmarks = extmarks }
|
||||
self:_reconcile()
|
||||
vim.cmd.doautocmd { args = { 'User', 'Renderer:' .. tostring(self.bufnr) .. ':render' } }
|
||||
end -- }}}
|
||||
|
||||
--- @private
|
||||
@ -362,6 +377,7 @@ function Renderer:_on_text_changed() -- {{{
|
||||
local l, c = unpack(vim.api.nvim_win_get_cursor(0))
|
||||
l = l - 1 -- make it actually 0-based
|
||||
local pos_infos = self:get_tags_at({ l, c }, 'i')
|
||||
log('_on_text_changed', { cursor_0_0 = { l, c }, pos_infos = pos_infos })
|
||||
for _, pos_info in ipairs(pos_infos) do
|
||||
local extmark_inf = pos_info.extmark
|
||||
local tag = pos_info.tag
|
||||
@ -374,6 +390,21 @@ function Renderer:_on_text_changed() -- {{{
|
||||
--- @type integer, integer, vim.api.keyset.extmark_details
|
||||
local start_row0, start_col0, details = unpack(extmark)
|
||||
local end_row0, end_col0 = details.end_row, details.end_col
|
||||
log('_on_text_changed: fetched current extmark for pos_info', {
|
||||
pos_info = pos_info,
|
||||
curr_extmark = {
|
||||
start_row0 = start_row0,
|
||||
start_col0 = start_col0,
|
||||
end_row0 = end_row0,
|
||||
end_col0 = end_col0,
|
||||
details = details,
|
||||
},
|
||||
})
|
||||
|
||||
if start_row0 == end_row0 and start_col0 == end_col0 then
|
||||
on_change ''
|
||||
return
|
||||
end
|
||||
|
||||
local buf_max_line0 = math.max(1, vim.api.nvim_buf_line_count(self.bufnr) - 1)
|
||||
if end_row0 > buf_max_line0 then
|
||||
@ -388,25 +419,37 @@ function Renderer:_on_text_changed() -- {{{
|
||||
or ''
|
||||
end_col0 = last_line:len()
|
||||
end
|
||||
log('_on_text_changed: after position correction', {
|
||||
curr_extmark = {
|
||||
start_row0 = start_row0,
|
||||
start_col0 = start_col0,
|
||||
end_row0 = end_row0,
|
||||
end_col0 = end_col0,
|
||||
},
|
||||
})
|
||||
|
||||
if start_row0 == end_row0 and start_col0 == end_col0 then
|
||||
on_change ''
|
||||
else
|
||||
local pos1 = { self.bufnr, start_row0 + 1, start_col0 + 1 }
|
||||
local pos2 = { self.bufnr, end_row0 + 1, end_col0 }
|
||||
local ok, lines = pcall(vim.fn.getregion, pos1, pos2, { type = 'v' })
|
||||
if not ok then
|
||||
vim.api.nvim_echo({
|
||||
{ '(u.nvim:getregion:invalid-pos) ', 'ErrorMsg' },
|
||||
{
|
||||
'{ start, end } = ' .. vim.inspect({ pos1, pos2 }, { newline = ' ', indent = '' }),
|
||||
},
|
||||
}, true, {})
|
||||
error(lines)
|
||||
end
|
||||
local text = table.concat(lines, '\n')
|
||||
on_change(text)
|
||||
return
|
||||
end
|
||||
|
||||
local pos1 = { self.bufnr, start_row0 + 1, start_col0 + 1 }
|
||||
local pos2 = { self.bufnr, end_row0 + 1, end_col0 }
|
||||
local ok, lines = pcall(vim.fn.getregion, pos1, pos2, { type = 'v' })
|
||||
if not ok then
|
||||
log('_on_text_changed: getregion: invalid-pos ', {
|
||||
{ pos1, pos2 },
|
||||
})
|
||||
vim.api.nvim_echo({
|
||||
{ '(u.nvim:getregion:invalid-pos) ', 'ErrorMsg' },
|
||||
{
|
||||
'{ start, end } = ' .. vim.inspect({ pos1, pos2 }, { newline = ' ', indent = '' }),
|
||||
},
|
||||
}, true, {})
|
||||
error(lines)
|
||||
end
|
||||
local text = table.concat(lines, '\n')
|
||||
on_change(text)
|
||||
end
|
||||
end
|
||||
end -- }}}
|
||||
@ -428,33 +471,42 @@ function Renderer:_debug() -- {{{
|
||||
vim.api.nvim_buf_delete(info_bufnr, { force = true })
|
||||
end
|
||||
|
||||
local function autocmd_callback()
|
||||
if vim.api.nvim_get_current_win() ~= prev_w then return end
|
||||
|
||||
local l, c = unpack(vim.api.nvim_win_get_cursor(0))
|
||||
l = l - 1 -- make it actually 0-based
|
||||
|
||||
local info = {
|
||||
cursor = {
|
||||
pos = { l, c },
|
||||
tags = self:get_tags_at { l, c },
|
||||
extmarks = vim.api.nvim_buf_get_extmarks(
|
||||
self.bufnr,
|
||||
self.ns,
|
||||
{ l, c },
|
||||
{ l, c },
|
||||
{ details = true, overlap = true }
|
||||
),
|
||||
},
|
||||
computed = {
|
||||
extmarks = self.curr.extmarks,
|
||||
},
|
||||
}
|
||||
vim.api.nvim_buf_set_lines(info_bufnr, 0, -1, true, vim.split(vim.inspect(info), '\n'))
|
||||
end
|
||||
|
||||
table.insert(
|
||||
ids,
|
||||
vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, {
|
||||
callback = function()
|
||||
if vim.api.nvim_get_current_win() ~= prev_w then return end
|
||||
|
||||
local l, c = unpack(vim.api.nvim_win_get_cursor(0))
|
||||
l = l - 1 -- make it actually 0-based
|
||||
|
||||
local info = {
|
||||
cursor = {
|
||||
pos = { l, c },
|
||||
tags = self:get_tags_at { l, c },
|
||||
extmarks = vim.api.nvim_buf_get_extmarks(
|
||||
self.bufnr,
|
||||
self.ns,
|
||||
{ l, c },
|
||||
{ l, c },
|
||||
{ details = true, overlap = true }
|
||||
),
|
||||
},
|
||||
computed = {
|
||||
extmarks = self.curr.extmarks,
|
||||
},
|
||||
}
|
||||
vim.api.nvim_buf_set_lines(info_bufnr, 0, -1, true, vim.split(vim.inspect(info), '\n'))
|
||||
end,
|
||||
callback = autocmd_callback,
|
||||
})
|
||||
)
|
||||
table.insert(
|
||||
ids,
|
||||
vim.api.nvim_create_autocmd({ 'User' }, {
|
||||
pattern = 'Renderer:' .. tostring(self.bufnr) .. ':render',
|
||||
callback = autocmd_callback,
|
||||
})
|
||||
)
|
||||
table.insert(
|
||||
|
@ -201,6 +201,41 @@ describe('Renderer', function()
|
||||
|
||||
assert.are.same(buf:all():text(), 'bleh')
|
||||
assert.are.same(captured_changed_text, 'bleh')
|
||||
|
||||
vim.fn.setreg('"', '')
|
||||
vim.cmd [[normal! ggdG]]
|
||||
-- We'll call the handler ourselves:
|
||||
r:_on_text_changed()
|
||||
|
||||
assert.are.same(buf:all():text(), '')
|
||||
assert.are.same(captured_changed_text, '')
|
||||
end)
|
||||
|
||||
withbuf({}, function()
|
||||
local Buffer = require 'u.buffer'
|
||||
local buf = Buffer.current()
|
||||
local r = R.Renderer.new(0)
|
||||
--- @type string?
|
||||
local captured_changed_text = nil
|
||||
r:render {
|
||||
'prefix:',
|
||||
R.h('text', {
|
||||
on_change = function(txt) captured_changed_text = txt end,
|
||||
}, {
|
||||
'one',
|
||||
}),
|
||||
'suffix',
|
||||
}
|
||||
|
||||
vim.fn.setreg('"', 'bleh')
|
||||
vim.api.nvim_win_set_cursor(0, { 1, 9 })
|
||||
vim.cmd [[normal! vhhd]]
|
||||
-- For some reason, the autocmd does not fire in the busted environment.
|
||||
-- We'll call the handler ourselves:
|
||||
r:_on_text_changed()
|
||||
|
||||
assert.are.same(buf:all():text(), 'prefix:suffix')
|
||||
assert.are.same(captured_changed_text, '')
|
||||
end)
|
||||
end)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user