diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 84c555b890..d1aa32be48 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -895,8 +895,16 @@ bool buf_freeall(buf_T *buf, int flags) unblock_autocmds(); } + linenr_T count = buf->b_ml.ml_line_count; ml_close(buf, true); // close and delete the memline/memfile buf->b_ml.ml_line_count = 0; // no lines in buffer + + // Ensure marks are adjusted for cleared buffer in case buffer not on disk: + // if it is reloaded the buffer will be empty. + if (bt_nofilename(buf) && !exiting) { + mark_adjust_buf(buf, 1, count, MAXLNUM, -count, false, kMarkAdjustNormal, kExtmarkNoUndo); + } + if ((flags & BFA_KEEP_UNDO) == 0) { // free the memory allocated for undo // and reset all undo information diff --git a/test/functional/api/extmark_spec.lua b/test/functional/api/extmark_spec.lua index 3245eba80c..911d9fb0bf 100644 --- a/test/functional/api/extmark_spec.lua +++ b/test/functional/api/extmark_spec.lua @@ -1959,6 +1959,16 @@ describe('API/extmarks', function() }, } end) + + it('are invalidated when "nofile" buffer is unloaded', function() + local buf = api.nvim_create_buf(false, true) + api.nvim_buf_set_name(buf, 'foo') + api.nvim_buf_set_lines(buf, 0, 0, false, { 'foo', 'bar' }) + local id = api.nvim_buf_set_extmark(buf, ns, 1, 0, { invalidate = true }) + api.nvim_buf_delete(buf, { unload = true }) + local mark = { 0, 0, { invalid = true, invalidate = true, ns_id = 3, right_gravity = true } } + eq(mark, api.nvim_buf_get_extmark_by_id(buf, ns, id, { details = true })) + end) end) describe('Extmarks buffer api with many marks', function()