feat(extmarks): add "undo_restore" flag to opt out of undo-restoring

It is a design goal of extmarks that they allow precise tracking
of changes across undo/redo, including restore the exact positions
after a do/undo or undo/redo cycle. However this behavior is not useful
for all usecases. Many plugins won't keep marks around for long after
text changes, but uses them more like a cache until some external source
(like LSP semantic highlights) has fully updated to changed text and
then will explicitly readjust/replace extmarks as needed.

Add a "undo_restore" flag which is true by default (matches existing
behavior) but can be set to false to opt-out of this behavior.

Delete dead u_extmark_set() code.
This commit is contained in:
bfredl
2023-11-03 12:26:38 +01:00
parent 92e99bb105
commit 68cb4a7405
10 changed files with 101 additions and 54 deletions

View File

@@ -11,6 +11,7 @@ local meths = helpers.meths
local funcs = helpers.funcs
local curbufmeths = helpers.curbufmeths
local command = helpers.command
local eq = helpers.eq
local assert_alive = helpers.assert_alive
describe('decorations providers', function()
@@ -1997,6 +1998,60 @@ describe('extmark decorations', function()
]]}
end)
local function with_undo_restore(val)
screen:try_resize(50, 5)
insert(example_text)
feed'gg'
meths.buf_set_extmark(0, ns, 0, 6, { end_col=13, hl_group = 'NonText', undo_restore=val})
screen:expect{grid=[[
^for _,{1:item in} ipairs(items) do |
local text, hl_id_cell, count = unpack(item) |
if hl_id_cell ~= nil then |
hl_id = hl_id_cell |
|
]]}
meths.buf_set_text(0, 0, 4, 0, 8, {''})
screen:expect{grid=[[
^for {1:em in} ipairs(items) do |
local text, hl_id_cell, count = unpack(item) |
if hl_id_cell ~= nil then |
hl_id = hl_id_cell |
|
]]}
end
it("highlights do reapply to restored text after delete", function()
with_undo_restore(true) -- also default behavior
feed 'u'
screen:expect{grid=[[
^for _,{1:item in} ipairs(items) do |
local text, hl_id_cell, count = unpack(item) |
if hl_id_cell ~= nil then |
hl_id = hl_id_cell |
1 change; before #2 0 seconds ago |
]]}
end)
it("highlights don't reapply to restored text after delete with no_undo_restore", function()
with_undo_restore(false)
feed 'u'
screen:expect{grid=[[
^for _,it{1:em in} ipairs(items) do |
local text, hl_id_cell, count = unpack(item) |
if hl_id_cell ~= nil then |
hl_id = hl_id_cell |
1 change; before #2 0 seconds ago |
]]}
eq({ { 1, 0, 8, { end_col = 13, end_right_gravity = false, end_row = 0,
hl_eol = false, hl_group = "NonText", undo_restore = false,
ns_id = 1, priority = 4096, right_gravity = true } } },
meths.buf_get_extmarks(0, ns, {0,0}, {0, -1}, {details=true}))
end)
it('virtual text works with rightleft', function()
screen:try_resize(50, 3)
insert('abcdefghijklmn')