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.
This commit is contained in:
Donatas 2025-01-20 16:40:26 +02:00 committed by GitHub
parent 92556be33d
commit 5b1136a99c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 1 deletions

View File

@ -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

View File

@ -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)) {

View File

@ -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')