aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonatas <contactdonatas@gmail.com>2025-01-20 16:40:26 +0200
committerGitHub <noreply@github.com>2025-01-20 06:40:26 -0800
commit5b1136a99c7fc6db4cfe6865b72c069a4697c1a5 (patch)
tree2f8699149e1b377c4d52849c9128c6079d8284c2
parent92556be33d04668c58a37794de5562af6297b3ac (diff)
downloadrneovim-5b1136a99c7fc6db4cfe6865b72c069a4697c1a5.tar.gz
rneovim-5b1136a99c7fc6db4cfe6865b72c069a4697c1a5.tar.bz2
rneovim-5b1136a99c7fc6db4cfe6865b72c069a4697c1a5.zip
feat(inccommand): preview 'nomodifiable' buffers #32034
Problem: Incremental preview is not allowed on 'nomodifiable' buffers. Solution: - Allow preview on 'nomodifiable' buffers. - Restore the 'modifiable' option in case the preview function changes it.
-rw-r--r--runtime/doc/news.txt2
-rw-r--r--src/nvim/ex_getln.c4
-rw-r--r--test/functional/ui/inccommand_user_spec.lua44
3 files changed, 49 insertions, 1 deletions
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index 58902abb87..58dab586d9 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -319,6 +319,8 @@ PLUGINS
• EditorConfig
• spelling_language property is now supported.
+• 'inccommand' incremental preview can run on 'nomodifiable' buffers and
+ restores their 'modifiable' state
STARTUP
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 423b50cd32..1eecee2a38 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -163,6 +163,7 @@ typedef struct {
typedef struct {
buf_T *buf;
OptInt save_b_p_ul;
+ int save_b_p_ma;
int save_b_changed;
pos_T save_b_op_start;
pos_T save_b_op_end;
@@ -2419,6 +2420,7 @@ static void cmdpreview_prepare(CpInfo *cpinfo)
if (!set_has(ptr_t, &saved_bufs, buf)) {
CpBufInfo cp_bufinfo;
cp_bufinfo.buf = buf;
+ cp_bufinfo.save_b_p_ma = buf->b_p_ma;
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;
@@ -2509,6 +2511,7 @@ static void cmdpreview_restore_state(CpInfo *cpinfo)
}
buf->b_p_ul = cp_bufinfo.save_b_p_ul; // Restore 'undolevels'
+ buf->b_p_ma = cp_bufinfo.save_b_p_ma; // Restore 'modifiable'
}
for (size_t i = 0; i < cpinfo->win_info.size; i++) {
@@ -2704,7 +2707,6 @@ static int command_line_changed(CommandLineState *s)
&& current_sctx.sc_sid == 0 // only if interactive
&& *p_icm != NUL // 'inccommand' is set
&& !exmode_active // not in ex mode
- && curbuf->b_p_ma // buffer is modifiable
&& cmdline_star == 0 // not typing a password
&& !vpeekc_any()
&& cmdpreview_may_show(s)) {
diff --git a/test/functional/ui/inccommand_user_spec.lua b/test/functional/ui/inccommand_user_spec.lua
index 2d26d2c5e0..3eee9a6e07 100644
--- a/test/functional/ui/inccommand_user_spec.lua
+++ b/test/functional/ui/inccommand_user_spec.lua
@@ -253,6 +253,50 @@ describe("'inccommand' for user commands", function()
]]
end)
+ it("can preview 'nomodifiable' buffer", function()
+ exec_lua([[
+ vim.api.nvim_create_user_command("PreviewTest", function() end, {
+ preview = function(ev)
+ vim.bo.modifiable = true
+ vim.api.nvim_buf_set_lines(0, 0, -1, false, {"cats"})
+ return 2
+ end,
+ })
+ ]])
+ command('set inccommand=split')
+
+ command('set nomodifiable')
+ eq(false, api.nvim_get_option_value('modifiable', { buf = 0 }))
+
+ feed(':PreviewTest')
+
+ screen:expect([[
+ cats |
+ {1:~ }|*8
+ {3:[No Name] [+] }|
+ |
+ {1:~ }|*4
+ {2:[Preview] }|
+ :PreviewTest^ |
+ ]])
+ feed('<Esc>')
+ screen:expect([[
+ text on line 1 |
+ more text on line 2 |
+ oh no, even more text |
+ will the text ever stop |
+ oh well |
+ did the text stop |
+ why won't it stop |
+ make the text stop |
+ ^ |
+ {1:~ }|*7
+ |
+ ]])
+
+ eq(false, api.nvim_get_option_value('modifiable', { buf = 0 }))
+ end)
+
it('works with inccommand=nosplit', function()
command('set inccommand=nosplit')
feed(':Replace text cats')