fix(prompt): prompt_setprompt cursor col adjustment

Problem: prompt_setprompt adjusted cursor col may be negative (<=0 when
1-based), and doesn't check the col of ':

Solution: avoid negative col and adjust correctly if ': col differs from old
prompt's length.
This commit is contained in:
Sean Dewar
2026-02-17 12:48:19 +00:00
parent 29a46a11aa
commit 602cbbe1d9
2 changed files with 29 additions and 3 deletions

View File

@@ -802,11 +802,12 @@ void f_prompt_setprompt(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
} }
extmark_splice_cols(buf, prompt_lno - 1, 0, buf->b_prompt_start.mark.col, new_prompt_len, extmark_splice_cols(buf, prompt_lno - 1, 0, buf->b_prompt_start.mark.col, new_prompt_len,
kExtmarkUndo); kExtmarkUndo);
cursor_col += new_prompt_len - old_prompt_len; cursor_col += new_prompt_len - buf->b_prompt_start.mark.col;
} }
if (curwin->w_buffer == buf && curwin->w_cursor.lnum == prompt_lno) { if (curwin->w_buffer == buf && curwin->w_cursor.lnum == prompt_lno) {
curwin->w_cursor.col = cursor_col; curwin->w_cursor.col = cursor_col;
check_cursor_col(curwin);
} }
changed_lines(buf, prompt_lno, 0, prompt_lno + 1, 0, true); changed_lines(buf, prompt_lno, 0, prompt_lno + 1, 0, true);
} }

View File

@@ -931,9 +931,34 @@ describe('prompt buffer', function()
{1:~ }|*7 {1:~ }|*7
{5:-- INSERT --} | {5:-- INSERT --} |
]]) ]])
-- Minimum col should be 1. Same event to avoid corrections from the state loop.
feed('<Esc>0')
local colnr = exec_lua(function()
vim.fn.prompt_setprompt('', '')
return vim.fn.col('.')
end)
eq(1, colnr)
-- Correct cursor adjustment when old ': col and old prompt length differs.
set_prompt('foo > ')
fn('setpos', "':", { 0, fn('line', '.'), 10, 0 })
fn('setline', '.', ' foo > hello')
feed('fh')
screen:expect([[
new-prompt > user input |
foo > ^hello |
{1:~ }|*7
|
]])
set_prompt('bar > ')
screen:expect([[
new-prompt > user input |
bar > ^hello |
{1:~ }|*7
|
]])
-- No crash when setting shorter prompt than curbuf's in other buffer. -- No crash when setting shorter prompt than curbuf's in other buffer.
feed('<C-O>zt') feed('ztA')
command('set virtualedit& | new | setlocal buftype=prompt') command('set virtualedit& | new | setlocal buftype=prompt')
set_prompt('looooooooooooooooooooooooooooooooooooooooooooong > ', '') -- curbuf set_prompt('looooooooooooooooooooooooooooooooooooooooooooong > ', '') -- curbuf
set_prompt('foo > ') set_prompt('foo > ')
@@ -943,7 +968,7 @@ describe('prompt buffer', function()
^ | ^ |
{1:~ }| {1:~ }|
{3:[Prompt] [+] }| {3:[Prompt] [+] }|
foo > a b | foo > hello |
{1:~ }|*3 {1:~ }|*3
{5:-- INSERT --} | {5:-- INSERT --} |
]]) ]])