From ba9f86a9cee58dc32ab875da1fd7eac9bc9e88d7 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 19 Jan 2024 11:04:01 +0800 Subject: [PATCH] fix(inccommand): improve preview buffer number handling (#27087) --- src/nvim/ex_getln.c | 9 ++-- test/functional/ui/inccommand_spec.lua | 51 +++++++++++++++++++++ test/functional/ui/inccommand_user_spec.lua | 18 ++++++++ 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index d10214b48f..2c5c291216 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -2277,6 +2277,7 @@ static buf_T *cmdpreview_open_buf(void) /// /// @return Pointer to command preview window if succeeded, NULL if failed. static win_T *cmdpreview_open_win(buf_T *cmdpreview_buf) + FUNC_ATTR_NONNULL_ALL { win_T *save_curwin = curwin; @@ -2548,10 +2549,10 @@ static bool cmdpreview_may_show(CommandLineState *s) cmdpreview_prepare(&cpinfo); // Open preview buffer if inccommand=split. - if (!icm_split) { - cmdpreview_bufnr = 0; - } else if ((cmdpreview_buf = cmdpreview_open_buf()) == NULL) { - abort(); + if (icm_split && (cmdpreview_buf = cmdpreview_open_buf()) == NULL) { + // Failed to create preview buffer, so disable preview. + set_string_option_direct(kOptInccommand, "nosplit", 0, SID_NONE); + icm_split = false; } // Setup preview namespace if it's not already set. if (!cmdpreview_ns) { diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua index f4347a460e..7e79479fc5 100644 --- a/test/functional/ui/inccommand_spec.lua +++ b/test/functional/ui/inccommand_spec.lua @@ -2895,3 +2895,54 @@ it("'inccommand' cannot be changed during preview #23136", function() feed(':%s/foo/bar') assert_alive() end) + +it("'inccommand' value can be changed multiple times #27086", function() + clear() + local screen = Screen.new(30, 20) + common_setup(screen, 'split', 'foo1\nfoo2\nfoo3') + for _ = 1, 3 do + feed(':%s/foo/bar') + screen:expect([[ + {12:bar}1 | + {12:bar}2 | + {12:bar}3 | + {15:~ }|*7 + {11:[No Name] [+] }| + |1| {12:bar}1 | + |2| {12:bar}2 | + |3| {12:bar}3 | + {15:~ }|*4 + {10:[Preview] }| + :%s/foo/bar^ | + ]]) + feed('') + command('set inccommand=nosplit') + feed(':%s/foo/bar') + screen:expect([[ + {12:bar}1 | + {12:bar}2 | + {12:bar}3 | + {15:~ }|*16 + :%s/foo/bar^ | + ]]) + feed('') + command('set inccommand=split') + end +end) + +it("'inccommand' disables preview if preview buffer can't be created #27086", function() + clear() + api.nvim_buf_set_name(0, '[Preview]') + local screen = Screen.new(30, 20) + common_setup(screen, 'split', 'foo1\nfoo2\nfoo3') + eq('split', api.nvim_get_option_value('inccommand', {})) + feed(':%s/foo/bar') + screen:expect([[ + {12:bar}1 | + {12:bar}2 | + {12:bar}3 | + {15:~ }|*16 + :%s/foo/bar^ | + ]]) + eq('nosplit', api.nvim_get_option_value('inccommand', {})) +end) diff --git a/test/functional/ui/inccommand_user_spec.lua b/test/functional/ui/inccommand_user_spec.lua index d30575a9f9..a714df72b7 100644 --- a/test/functional/ui/inccommand_user_spec.lua +++ b/test/functional/ui/inccommand_user_spec.lua @@ -1,6 +1,8 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') +local api = helpers.api local clear = helpers.clear +local eq = helpers.eq local exec_lua = helpers.exec_lua local insert = helpers.insert local feed = helpers.feed @@ -495,6 +497,22 @@ describe("'inccommand' for user commands", function() test_preview_break_undo() end) end) + + it('disables preview if preview buffer cannot be created #27086', function() + command('set inccommand=split') + api.nvim_buf_set_name(0, '[Preview]') + exec_lua([[ + vim.api.nvim_create_user_command('Test', function() end, { + nargs = '*', + preview = function(_, _, _) + return 2 + end + }) + ]]) + eq('split', api.nvim_get_option_value('inccommand', {})) + feed(':Test') + eq('nosplit', api.nvim_get_option_value('inccommand', {})) + end) end) describe("'inccommand' with multiple buffers", function()