factor out line-patching into a separate function
Some checks failed
NeoVim tests / plenary-tests (push) Failing after 8s
Some checks failed
NeoVim tests / plenary-tests (push) Failing after 8s
This commit is contained in:
parent
7ad3d941f4
commit
5a6451a85e
@ -132,6 +132,64 @@ end -- }}}
|
|||||||
--- }
|
--- }
|
||||||
function Renderer.markup_to_string(opts) return table.concat(Renderer.markup_to_lines(opts), '\n') end
|
function Renderer.markup_to_string(opts) return table.concat(Renderer.markup_to_lines(opts), '\n') end
|
||||||
|
|
||||||
|
--- @param bufnr number
|
||||||
|
--- @param old_lines string[] | nil
|
||||||
|
--- @param new_lines string[]
|
||||||
|
function Renderer.patch_lines(bufnr, old_lines, new_lines)
|
||||||
|
--
|
||||||
|
-- Helpers:
|
||||||
|
--
|
||||||
|
|
||||||
|
--- @param start integer
|
||||||
|
--- @param end_ integer
|
||||||
|
--- @param strict_indexing boolean
|
||||||
|
--- @param replacement string[]
|
||||||
|
local function _set_lines(start, end_, strict_indexing, replacement)
|
||||||
|
vim.api.nvim_buf_set_lines(bufnr, start, end_, strict_indexing, replacement)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param start_row integer
|
||||||
|
--- @param start_col integer
|
||||||
|
--- @param end_row integer
|
||||||
|
--- @param end_col integer
|
||||||
|
--- @param replacement string[]
|
||||||
|
local function _set_text(start_row, start_col, end_row, end_col, replacement)
|
||||||
|
vim.api.nvim_buf_set_text(bufnr, start_row, start_col, end_row, end_col, replacement)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Morph the text to the desired state:
|
||||||
|
local line_changes =
|
||||||
|
H.levenshtein(old_lines or vim.api.nvim_buf_get_lines(bufnr, 0, -1, false), new_lines)
|
||||||
|
for _, line_change in ipairs(line_changes) do
|
||||||
|
local lnum0 = line_change.index - 1
|
||||||
|
|
||||||
|
if line_change.kind == 'add' then
|
||||||
|
_set_lines(lnum0, lnum0, true, { line_change.item })
|
||||||
|
elseif line_change.kind == 'change' then
|
||||||
|
-- Compute inter-line diff, and apply:
|
||||||
|
local col_changes =
|
||||||
|
H.levenshtein(vim.split(line_change.from, ''), vim.split(line_change.to, ''))
|
||||||
|
|
||||||
|
for _, col_change in ipairs(col_changes) do
|
||||||
|
local cnum0 = col_change.index - 1
|
||||||
|
if col_change.kind == 'add' then
|
||||||
|
_set_text(lnum0, cnum0, lnum0, cnum0, { col_change.item })
|
||||||
|
elseif col_change.kind == 'change' then
|
||||||
|
_set_text(lnum0, cnum0, lnum0, cnum0 + 1, { col_change.to })
|
||||||
|
elseif col_change.kind == 'delete' then
|
||||||
|
_set_text(lnum0, cnum0, lnum0, cnum0 + 1, {})
|
||||||
|
else
|
||||||
|
-- No change
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif line_change.kind == 'delete' then
|
||||||
|
_set_lines(lnum0, lnum0 + 1, true, {})
|
||||||
|
else
|
||||||
|
-- No change
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- @param tree u.renderer.Tree
|
--- @param tree u.renderer.Tree
|
||||||
function Renderer:render(tree) -- {{{
|
function Renderer:render(tree) -- {{{
|
||||||
local changedtick = vim.b[self.bufnr].changedtick
|
local changedtick = vim.b[self.bufnr].changedtick
|
||||||
@ -210,45 +268,16 @@ end
|
|||||||
|
|
||||||
--- @private
|
--- @private
|
||||||
function Renderer:_reconcile() -- {{{
|
function Renderer:_reconcile() -- {{{
|
||||||
local line_changes = H.levenshtein(self.old.lines, self.curr.lines)
|
|
||||||
self.old = self.curr
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Step 1: morph the text to the desired state:
|
-- Step 1: morph the text to the desired state:
|
||||||
--
|
--
|
||||||
for _, line_change in ipairs(line_changes) do
|
Renderer.patch_lines(self.bufnr, self.old.lines, self.curr.lines)
|
||||||
local lnum0 = line_change.index - 1
|
|
||||||
|
|
||||||
if line_change.kind == 'add' then
|
|
||||||
self:_set_lines(lnum0, lnum0, true, { line_change.item })
|
|
||||||
elseif line_change.kind == 'change' then
|
|
||||||
-- Compute inter-line diff, and apply:
|
|
||||||
local col_changes =
|
|
||||||
H.levenshtein(vim.split(line_change.from, ''), vim.split(line_change.to, ''))
|
|
||||||
|
|
||||||
for _, col_change in ipairs(col_changes) do
|
|
||||||
local cnum0 = col_change.index - 1
|
|
||||||
if col_change.kind == 'add' then
|
|
||||||
self:_set_text(lnum0, cnum0, lnum0, cnum0, { col_change.item })
|
|
||||||
elseif col_change.kind == 'change' then
|
|
||||||
self:_set_text(lnum0, cnum0, lnum0, cnum0 + 1, { col_change.to })
|
|
||||||
elseif col_change.kind == 'delete' then
|
|
||||||
self:_set_text(lnum0, cnum0, lnum0, cnum0 + 1, {})
|
|
||||||
else
|
|
||||||
-- No change
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif line_change.kind == 'delete' then
|
|
||||||
self:_set_lines(lnum0, lnum0 + 1, true, {})
|
|
||||||
else
|
|
||||||
-- No change
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self.changedtick = vim.b[self.bufnr].changedtick
|
self.changedtick = vim.b[self.bufnr].changedtick
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Step 2: reconcile extmarks:
|
-- Step 2: reconcile extmarks:
|
||||||
--
|
--
|
||||||
|
|
||||||
-- Clear current extmarks:
|
-- Clear current extmarks:
|
||||||
vim.api.nvim_buf_clear_namespace(self.bufnr, self.ns, 0, -1)
|
vim.api.nvim_buf_clear_namespace(self.bufnr, self.ns, 0, -1)
|
||||||
-- Set current extmarks:
|
-- Set current extmarks:
|
||||||
@ -265,6 +294,8 @@ function Renderer:_reconcile() -- {{{
|
|||||||
}, extmark.opts)
|
}, extmark.opts)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.old = self.curr
|
||||||
end -- }}}
|
end -- }}}
|
||||||
|
|
||||||
--- @private
|
--- @private
|
||||||
|
Loading…
x
Reference in New Issue
Block a user