vim-patch:9.0.1428: cursor in wrong position when leaving insert mode (#22786)

Problem:    Cursor in wrong position when leaving insert mode.
Solution:   Update the w_valid flags.  Position the cursor also when not
            redrawing. (closes vim/vim#12137)

c174c2e58c

Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
zeertzjq
2023-03-26 09:24:04 +08:00
committed by GitHub
parent e3dab4b326
commit 4eef5ac453
5 changed files with 102 additions and 11 deletions

View File

@@ -3457,6 +3457,7 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
} }
} else { } else {
curwin->w_cursor.col--; curwin->w_cursor.col--;
curwin->w_valid &= ~(VALID_WCOL|VALID_VIRTCOL);
// Correct cursor for multi-byte character. // Correct cursor for multi-byte character.
mb_adjust_cursor(); mb_adjust_cursor();
} }

View File

@@ -1377,6 +1377,7 @@ static int normal_check(VimState *state)
// update cursor and redraw. // update cursor and redraw.
if (skip_redraw || exmode_active) { if (skip_redraw || exmode_active) {
skip_redraw = false; skip_redraw = false;
setcursor();
} else if (do_redraw || stuff_empty()) { } else if (do_redraw || stuff_empty()) {
// Ensure curwin->w_topline and curwin->w_leftcol are up to date // Ensure curwin->w_topline and curwin->w_leftcol are up to date
// before triggering a WinScrolled autocommand. // before triggering a WinScrolled autocommand.

View File

@@ -53,14 +53,13 @@ describe('insert-mode', function()
it('double quote is removed after hit-enter prompt #22609', function() it('double quote is removed after hit-enter prompt #22609', function()
local screen = Screen.new(60, 6) local screen = Screen.new(60, 6)
screen:set_default_attr_ids({ screen:set_default_attr_ids({
[0] = {bold = true, foreground = Screen.colors.Blue}, [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
[1] = {foreground = Screen.colors.Blue}, [1] = {foreground = Screen.colors.Blue}, -- SpecialKey
[2] = {foreground = Screen.colors.SlateBlue}, [2] = {foreground = Screen.colors.SlateBlue},
[3] = {bold = true}, [3] = {bold = true}, -- ModeMsg
[4] = {reverse = true, bold = true}, [4] = {reverse = true, bold = true}, -- MsgSeparator
[5] = {background = Screen.colors.Red, foreground = Screen.colors.Red}, [5] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg
[6] = {background = Screen.colors.Red, foreground = Screen.colors.White}, [6] = {foreground = Screen.colors.SeaGreen, bold = true}, -- MoreMsg
[7] = {foreground = Screen.colors.SeaGreen, bold = true},
}) })
screen:attach() screen:attach()
feed('i<C-R>') feed('i<C-R>')
@@ -72,14 +71,23 @@ describe('insert-mode', function()
{0:~ }| {0:~ }|
{3:-- INSERT --} | {3:-- INSERT --} |
]]) ]])
feed('={}<CR>') feed('={}')
screen:expect([[
{1:"} |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
={2:{}}^ |
]])
feed('<CR>')
screen:expect([[ screen:expect([[
{1:"} | {1:"} |
{0:~ }| {0:~ }|
{4: }| {4: }|
={5:{}{2:}} | ={2:{}} |
{6:E731: using Dictionary as a String} | {5:E731: using Dictionary as a String} |
{7:Press ENTER or type command to continue}^ | {6:Press ENTER or type command to continue}^ |
]]) ]])
feed('<CR>') feed('<CR>')
screen:expect([[ screen:expect([[

View File

@@ -55,4 +55,68 @@ describe('edit', function()
=^ | =^ |
]]) ]])
end) end)
-- oldtest: Test_edit_ctrl_r_failed()
it('positioning cursor after CTRL-R expression failed', function()
local screen = Screen.new(60, 6)
screen:set_default_attr_ids({
[0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
[1] = {foreground = Screen.colors.Blue}, -- SpecialKey
[2] = {foreground = Screen.colors.SlateBlue},
[3] = {bold = true}, -- ModeMsg
[4] = {reverse = true, bold = true}, -- MsgSeparator
[5] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg
[6] = {foreground = Screen.colors.SeaGreen, bold = true}, -- MoreMsg
})
screen:attach()
feed('i<C-R>')
screen:expect([[
{1:^"} |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{3:-- INSERT --} |
]])
feed('={}')
screen:expect([[
{1:"} |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
={2:{}}^ |
]])
-- trying to insert a dictionary produces an error
feed('<CR>')
screen:expect([[
{1:"} |
{0:~ }|
{4: }|
={2:{}} |
{5:E731: using Dictionary as a String} |
{6:Press ENTER or type command to continue}^ |
]])
feed(':')
screen:expect([[
:^ |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{3:-- INSERT --} |
]])
-- ending Insert mode should put the cursor back on the ':'
feed('<Esc>')
screen:expect([[
^: |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
|
]])
end)
end) end)

View File

@@ -5,6 +5,7 @@ if exists("+t_kD")
endif endif
source check.vim source check.vim
source screendump.vim
" Needed for testing basic rightleft: Test_edit_rightleft " Needed for testing basic rightleft: Test_edit_rightleft
source view_util.vim source view_util.vim
@@ -1978,6 +1979,22 @@ func Test_edit_insert_reg()
close! close!
endfunc endfunc
" Test for positioning cursor after CTRL-R expression failed
func Test_edit_ctrl_r_failed()
CheckRunVimInTerminal
let buf = RunVimInTerminal('', #{rows: 6, cols: 60})
" trying to insert a dictionary produces an error
call term_sendkeys(buf, "i\<C-R>={}\<CR>")
" ending Insert mode should put the cursor back on the ':'
call term_sendkeys(buf, ":\<Esc>")
call VerifyScreenDump(buf, 'Test_edit_ctlr_r_failed_1', {})
call StopVimInTerminal(buf)
endfunc
" When a character is inserted at the last position of the last line in a " When a character is inserted at the last position of the last line in a
" window, the window contents should be scrolled one line up. If the top line " window, the window contents should be scrolled one line up. If the top line
" is part of a fold, then the entire fold should be scrolled up. " is part of a fold, then the entire fold should be scrolled up.