From 0fdbb0ea7330aa5fd572f2393ea24ad8acd283d1 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 7 Dec 2023 11:21:41 +0800 Subject: [PATCH] fix(inccommand): save and restore '[ and '] marks Undoing a change moves '[ and '] marks, so it is necessary to save and restore them. (cherry picked from commit 8002176c247ec22087be9e9c9d4a9b2c5882ec84) --- src/nvim/ex_getln.c | 7 +++++++ test/functional/ui/inccommand_spec.lua | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 843854799b..40d294ca25 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -149,6 +149,8 @@ typedef struct cmdpreview_buf_info { buf_T *buf; long save_b_p_ul; int save_b_changed; + pos_T save_b_op_start; + pos_T save_b_op_end; varnumber_T save_changedtick; CpUndoInfo undo_info; } CpBufInfo; @@ -2348,6 +2350,8 @@ static void cmdpreview_prepare(CpInfo *cpinfo) cp_bufinfo.buf = buf; cp_bufinfo.save_b_p_ul = buf->b_p_ul; cp_bufinfo.save_b_changed = buf->b_changed; + cp_bufinfo.save_b_op_start = buf->b_op_start; + cp_bufinfo.save_b_op_end = buf->b_op_end; cp_bufinfo.save_changedtick = buf_get_changedtick(buf); cmdpreview_save_undo(&cp_bufinfo.undo_info, buf); kv_push(cpinfo->buf_info, cp_bufinfo); @@ -2423,6 +2427,9 @@ static void cmdpreview_restore_state(CpInfo *cpinfo) u_blockfree(buf); cmdpreview_restore_undo(&cp_bufinfo.undo_info, buf); + buf->b_op_start = cp_bufinfo.save_b_op_start; + buf->b_op_end = cp_bufinfo.save_b_op_end; + if (cp_bufinfo.save_changedtick != buf_get_changedtick(buf)) { buf_set_changedtick(buf, cp_bufinfo.save_changedtick); } diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua index 217a713c93..e152aeb3ae 100644 --- a/test/functional/ui/inccommand_spec.lua +++ b/test/functional/ui/inccommand_spec.lua @@ -8,6 +8,7 @@ local feed_command = helpers.feed_command local expect = helpers.expect local feed = helpers.feed local insert = helpers.insert +local funcs = helpers.funcs local meths = helpers.meths local neq = helpers.neq local ok = helpers.ok @@ -153,6 +154,29 @@ describe(":substitute, 'inccommand' preserves", function() ]]) end) + it("'[ and '] marks #26439", function() + local screen = Screen.new(30, 10) + common_setup(screen, 'nosplit', ('abc\ndef\n'):rep(50)) + + feed('ggyG') + local X = meths.get_vvar('maxcol') + eq({0, 1, 1, 0}, funcs.getpos("'[")) + eq({0, 101, X, 0}, funcs.getpos("']")) + + feed(":'[,']s/def/") + poke_eventloop() + eq({0, 1, 1, 0}, funcs.getpos("'[")) + eq({0, 101, X, 0}, funcs.getpos("']")) + + feed('DEF/g') + poke_eventloop() + eq({0, 1, 1, 0}, funcs.getpos("'[")) + eq({0, 101, X, 0}, funcs.getpos("']")) + + feed('') + expect(('abc\nDEF\n'):rep(50)) + end) + for _, case in pairs{"", "split", "nosplit"} do it("various delimiters (inccommand="..case..")", function() insert(default_text)