fix(prompt): prompt mark not placed after text edits correctly #34671

This commit is contained in:
Shadman
2025-06-30 16:19:43 +06:00
committed by GitHub
parent f7c939fa7a
commit ed7ff848a0
4 changed files with 80 additions and 3 deletions

View File

@ -663,7 +663,7 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In
// changed range, and move any in the remainder of the buffer.
// Do not adjust any cursors. need to use column-aware logic (below)
linenr_T adjust = end_row >= start_row ? MAXLNUM : 0;
mark_adjust_buf(buf, (linenr_T)start_row, (linenr_T)end_row, adjust, (linenr_T)extra,
mark_adjust_buf(buf, (linenr_T)start_row, (linenr_T)end_row - 1, adjust, (linenr_T)extra,
true, true, kExtmarkNOOP);
extmark_splice(buf, (int)start_row - 1, (colnr_T)start_col,

View File

@ -1545,6 +1545,7 @@ static void init_prompt(int cmdchar_todo)
ml_replace(curbuf->b_ml.ml_line_count, prompt, true);
} else {
ml_append(curbuf->b_ml.ml_line_count, prompt, 0, false);
curbuf->b_prompt_start.mark.lnum += 1;
}
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
coladvance(curwin, MAXCOL);

View File

@ -8702,6 +8702,7 @@ void prompt_invoke_callback(void)
appended_lines_mark(lnum, 1);
curwin->w_cursor.lnum = lnum + 1;
curwin->w_cursor.col = 0;
curbuf->b_prompt_start.mark.lnum = lnum + 1;
if (curbuf->b_prompt_callback.type == kCallbackNone) {
xfree(user_input);
@ -8720,8 +8721,7 @@ theend:
// clear undo history on submit
u_clearallandblockfree(curbuf);
pos_T next_prompt = { .lnum = curbuf->b_ml.ml_line_count, .col = 1, .coladd = 0 };
RESET_FMARK(&curbuf->b_prompt_start, next_prompt, 0, ((fmarkv_T)INIT_FMARKV));
curbuf->b_prompt_start.mark.lnum = curbuf->b_ml.ml_line_count;
}
/// @return true when the interrupt callback was invoked.

View File

@ -12,6 +12,7 @@ local poke_eventloop = n.poke_eventloop
local api = n.api
local eq = t.eq
local neq = t.neq
local exec_lua = n.exec_lua
describe('prompt buffer', function()
local screen
@ -596,4 +597,79 @@ describe('prompt buffer', function()
eq('', fn('prompt_getinput', bufnr))
end)
end)
it('programmatic (non-user) edits', function()
api.nvim_set_option_value('buftype', 'prompt', { buf = 0 })
-- with nvim_buf_set_lines
exec_lua([[
local buf = vim.api.nvim_get_current_buf()
vim.fn.prompt_setcallback(buf, function(text)
vim.api.nvim_buf_set_lines(buf, -2, -2, true, vim.split(text, '\n'))
end)
]])
feed('iset_lines<cr>')
feed('set_lines2<cr>')
screen:expect([[
% set_lines |
set_lines |
% set_lines2 |
set_lines2 |
% ^ |
{1:~ }|*4
{5:-- INSERT --} |
]])
feed('set_lines3(multi-1)<s-cr>set_lines3(multi-2)<cr>')
screen:expect([[
% set_lines |
set_lines |
% set_lines2 |
set_lines2 |
% set_lines3(multi-1) |
set_lines3(multi-2) |
set_lines3(multi-1) |
set_lines3(multi-2) |
% ^ |
{5:-- INSERT --} |
]])
-- with nvim_buf_set_text
source('bwipeout!')
api.nvim_set_option_value('buftype', 'prompt', { buf = 0 })
exec_lua([[
local buf = vim.api.nvim_get_current_buf()
vim.fn.prompt_setcallback(buf, function(text)
local lines = vim.split(text, '\n')
if lines[#lines] ~= '' then
table.insert(lines, '')
end
vim.api.nvim_buf_set_text(buf, -1, 0, -1, 0, lines)
end)
]])
feed('set_text<cr>')
feed('set_text2<cr>')
screen:expect([[
% set_text |
set_text |
% set_text2 |
set_text2 |
% ^ |
{1:~ }|*4
{5:-- INSERT --} |
]])
feed('set_text3(multi-1)<s-cr>set_text3(multi-2)<cr>')
screen:expect([[
% set_text |
set_text |
% set_text2 |
set_text2 |
% set_text3(multi-1) |
set_text3(multi-2) |
set_text3(multi-1) |
set_text3(multi-2) |
% ^ |
{5:-- INSERT --} |
]])
end)
end)