From ce9dbd398b4ad31d8febde004cb7799964ecb009 Mon Sep 17 00:00:00 2001 From: Sean Dewar <6256228+seandewar@users.noreply.github.com> Date: Tue, 17 Feb 2026 00:06:03 +0000 Subject: [PATCH] fix(undo): u_savecommon uses wrong buffer Problem: u_savecommon with reload = true wrongly uses curbuf. Solution: use buf. Fix comments. --- src/nvim/undo.c | 6 +++--- test/functional/editor/undo_spec.lua | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/nvim/undo.c b/src/nvim/undo.c index e1e2238a36..67c2921a8f 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -382,7 +382,7 @@ int u_savecommon(buf_T *buf, linenr_T top, linenr_T bot, linenr_T newbot, bool r u_entry_T *prev_uep; linenr_T size = bot - top - 1; - // If curbuf->b_u_synced == true make a new header. + // If buf->b_u_synced == true make a new header. if (buf->b_u_synced) { // Need to create new entry in b_changelist. buf->b_new_change = true; @@ -401,7 +401,7 @@ int u_savecommon(buf_T *buf, linenr_T top, linenr_T bot, linenr_T newbot, bool r } // If we undid more than we redid, move the entry lists before and - // including curbuf->b_u_curhead to an alternate branch. + // including buf->b_u_curhead to an alternate branch. u_header_T *old_curhead = buf->b_u_curhead; if (old_curhead != NULL) { buf->b_u_newhead = old_curhead->uh_next.ptr; @@ -608,7 +608,7 @@ int u_savecommon(buf_T *buf, linenr_T top, linenr_T bot, linenr_T newbot, bool r buf->b_u_newhead->uh_entry = uep; if (reload) { // buffer was reloaded, notify text change subscribers - curbuf->b_u_newhead->uh_flags |= UH_RELOAD; + buf->b_u_newhead->uh_flags |= UH_RELOAD; } buf->b_u_synced = false; undo_undoes = false; diff --git a/test/functional/editor/undo_spec.lua b/test/functional/editor/undo_spec.lua index 2d4b79cc8c..0d75e072c3 100644 --- a/test/functional/editor/undo_spec.lua +++ b/test/functional/editor/undo_spec.lua @@ -225,3 +225,22 @@ describe(':undo! command', function() ) end) end) + +describe('undo', function() + before_each(clear) + + it('u_savecommon uses correct buffer with reload = true', function() + -- Easiest to repro in a prompt buffer. prompt_setprompt's buffer must not yet have an undo + -- header to trigger this. Will crash if it wrongly uses the unloaded curbuf in nvim_buf_call, + -- as that has no undo buffer. + eq(0, #fn.undotree().entries) + exec_lua(function() + local buf = vim.api.nvim_get_current_buf() + vim.bo.buftype = 'prompt' + vim.api.nvim_buf_call(vim.fn.bufadd(''), function() + vim.fn.prompt_setprompt(buf, 'hej > ') + end) + end) + eq('hej > ', fn.prompt_getprompt('')) + end) +end)