Merge pull request #19098 from zeertzjq/vim-8.1.0822

vim-patch:8.1.{partial:0822,1189,1192},8.2.5109: 'showmode' fixes
This commit is contained in:
zeertzjq 2022-08-15 18:38:46 +08:00 committed by GitHub
commit d334249833
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 217 additions and 20 deletions

View File

@ -4251,7 +4251,7 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
// Otherwise remove the mode message.
if (reg_recording != 0 || restart_edit != NUL) {
showmode();
} else if (p_smd) {
} else if (p_smd && (got_int || !skip_showmode())) {
msg("");
}
// Exit Insert mode

View File

@ -2722,6 +2722,8 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
// getchar(): blocking wait.
// TODO(bfredl): deduplicate shared logic with state_enter ?
if (!char_avail()) {
// flush output before waiting
ui_flush();
(void)os_inchar(NULL, 0, -1, 0, main_loop.events);
if (!multiqueue_empty(main_loop.events)) {
state_handle_k_event();

View File

@ -145,6 +145,7 @@ EXTERN int vgetc_char INIT(= 0);
EXTERN int cmdline_row;
EXTERN bool redraw_cmdline INIT(= false); // cmdline must be redrawn
EXTERN bool redraw_mode INIT(= false); // mode must be redrawn
EXTERN bool clear_cmdline INIT(= false); // cmdline must be cleared
EXTERN bool mode_displayed INIT(= false); // mode is being displayed
EXTERN int cmdline_star INIT(= false); // cmdline is encrypted

View File

@ -1284,7 +1284,7 @@ static void normal_redraw(NormalState *s)
update_screen(INVERTED);
} else if (must_redraw) {
update_screen(0);
} else if (redraw_cmdline || clear_cmdline) {
} else if (redraw_cmdline || clear_cmdline || redraw_mode) {
showmode();
}
@ -6930,6 +6930,10 @@ static void nv_esc(cmdarg_T *cap)
}
}
if (restart_edit != 0) {
redraw_mode = true; // remove "-- (insert) --"
}
restart_edit = 0;
if (cmdwin_type != 0) {

View File

@ -591,7 +591,7 @@ int update_screen(int type)
// Clear or redraw the command line. Done last, because scrolling may
// mess up the command line.
if (clear_cmdline || redraw_cmdline) {
if (clear_cmdline || redraw_cmdline || redraw_mode) {
showmode();
}
@ -5821,12 +5821,26 @@ void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
}
}
// Show the current mode and ruler.
//
// If clear_cmdline is true, clear the rest of the cmdline.
// If clear_cmdline is false there may be a message there that needs to be
// cleared only if a mode is shown.
// Return the length of the message (0 if no message).
/// @return true when postponing displaying the mode message: when not redrawing
/// or inside a mapping.
bool skip_showmode(void)
{
// Call char_avail() only when we are going to show something, because it
// takes a bit of time. redrawing() may also call char_avail().
if (global_busy || msg_silent != 0 || !redrawing() || (char_avail() && !KeyTyped)) {
redraw_mode = true; // show mode later
return true;
}
return false;
}
/// Show the current mode and ruler.
///
/// If clear_cmdline is true, clear the rest of the cmdline.
/// If clear_cmdline is false there may be a message there that needs to be
/// cleared only if a mode is shown.
/// If redraw_mode is true show or clear the mode.
/// @return the length of the message (0 if no message).
int showmode(void)
{
bool need_clear;
@ -5850,12 +5864,8 @@ int showmode(void)
|| restart_edit != NUL
|| VIsual_active));
if (do_mode || reg_recording != 0) {
// Don't show mode right now, when not redrawing or inside a mapping.
// Call char_avail() only when we are going to show something, because
// it takes a bit of time.
if (!redrawing() || (char_avail() && !KeyTyped) || msg_silent != 0) {
redraw_cmdline = true; // show mode later
return 0;
if (skip_showmode()) {
return 0; // show mode later
}
bool nwr_save = need_wait_return;
@ -5989,7 +5999,7 @@ int showmode(void)
}
mode_displayed = true;
if (need_clear || clear_cmdline) {
if (need_clear || clear_cmdline || redraw_mode) {
msg_clr_eos();
}
msg_didout = false; // overwrite this message
@ -6001,6 +6011,9 @@ int showmode(void)
} else if (clear_cmdline && msg_silent == 0) {
// Clear the whole command line. Will reset "clear_cmdline".
msg_clr_cmdline();
} else if (redraw_mode) {
msg_pos_mode();
msg_clr_eos();
}
// NB: also handles clearing the showmode if it was empty or disabled
@ -6018,6 +6031,7 @@ int showmode(void)
win_redr_ruler(last, true);
}
redraw_cmdline = false;
redraw_mode = false;
clear_cmdline = false;
return length;

View File

@ -19,7 +19,7 @@ func Test_setbufline_getbufline()
let b = bufnr('%')
wincmd w
call assert_equal(1, setbufline(b, 5, ['x']))
call assert_equal(1, setbufline(1234, 1, ['x']))
call assert_equal(1, setbufline(bufnr('$') + 1, 1, ['x']))
call assert_equal(0, setbufline(b, 4, ['d', 'e']))
call assert_equal(['c'], b->getbufline(3))
call assert_equal(['d'], getbufline(b, 4))

View File

@ -95,6 +95,65 @@ func Test_echoerr()
call test_ignore_error('RESET')
endfunc
func Test_mode_message_at_leaving_insert_by_ctrl_c()
if !has('terminal') || has('gui_running')
return
endif
" Set custom statusline built by user-defined function.
let testfile = 'Xtest.vim'
call writefile([
\ 'func StatusLine() abort',
\ ' return ""',
\ 'endfunc',
\ 'set statusline=%!StatusLine()',
\ 'set laststatus=2',
\ ], testfile)
let rows = 10
let buf = term_start([GetVimProg(), '--clean', '-S', testfile], {'term_rows': rows})
call term_wait(buf, 200)
call assert_equal('run', job_status(term_getjob(buf)))
call term_sendkeys(buf, "i")
call WaitForAssert({-> assert_match('^-- INSERT --\s*$', term_getline(buf, rows))})
call term_sendkeys(buf, "\<C-C>")
call WaitForAssert({-> assert_match('^\s*$', term_getline(buf, rows))})
call term_sendkeys(buf, ":qall!\<CR>")
call WaitForAssert({-> assert_equal('dead', job_status(term_getjob(buf)))})
exe buf . 'bwipe!'
call delete(testfile)
endfunc
func Test_mode_message_at_leaving_insert_with_esc_mapped()
if !has('terminal') || has('gui_running')
return
endif
" Set custom statusline built by user-defined function.
let testfile = 'Xtest.vim'
call writefile([
\ 'set laststatus=2',
\ 'inoremap <Esc> <Esc>00',
\ ], testfile)
let rows = 10
let buf = term_start([GetVimProg(), '--clean', '-S', testfile], {'term_rows': rows})
call term_wait(buf, 200)
call assert_equal('run', job_status(term_getjob(buf)))
call term_sendkeys(buf, "i")
call WaitForAssert({-> assert_match('^-- INSERT --\s*$', term_getline(buf, rows))})
call term_sendkeys(buf, "\<Esc>")
call WaitForAssert({-> assert_match('^\s*$', term_getline(buf, rows))})
call term_sendkeys(buf, ":qall!\<CR>")
call WaitForAssert({-> assert_equal('dead', job_status(term_getjob(buf)))})
exe buf . 'bwipe!'
call delete(testfile)
endfunc
func Test_echospace()
set noruler noshowcmd laststatus=1
call assert_equal(&columns - 1, v:echospace)

View File

@ -3,6 +3,7 @@
source shared.vim
source check.vim
source view_util.vim
source screendump.vim
func Setup_NewWindow()
10new
@ -2038,9 +2039,9 @@ func Test_normal33_g_cmd2()
call assert_equal(2, line('.'))
call assert_fails(':norm! g;', 'E662')
call assert_fails(':norm! g,', 'E663')
let &ul=&ul
let &ul = &ul
call append('$', ['a', 'b', 'c', 'd'])
let &ul=&ul
let &ul = &ul
call append('$', ['Z', 'Y', 'X', 'W'])
let a = execute(':changes')
call assert_match('2\s\+0\s\+2', a)
@ -2889,6 +2890,20 @@ func Test_message_when_using_ctrl_c()
bwipe!
endfunc
func Test_mode_updated_after_ctrl_c()
CheckScreendump
let buf = RunVimInTerminal('', {'rows': 5})
call term_sendkeys(buf, "i")
call term_sendkeys(buf, "\<C-O>")
" wait a moment so that the "-- (insert) --" message is displayed
call TermWait(buf, 50)
call term_sendkeys(buf, "\<C-C>")
call VerifyScreenDump(buf, 'Test_mode_updated_1', {})
call StopVimInTerminal(buf)
endfunc
" Test for '[m', ']m', '[M' and ']M'
" Jumping to beginning and end of methods in Java-like languages
func Test_java_motion()

View File

@ -337,6 +337,95 @@ describe('messages', function()
end)
end)
describe('mode is cleared when', function()
before_each(function()
screen = Screen.new(40, 6)
screen:set_default_attr_ids({
[1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
[2] = {bold = true}, -- ModeMsg
[3] = {bold = true, reverse=true}, -- StatusLine
})
screen:attach()
end)
-- oldtest: Test_mode_message_at_leaving_insert_by_ctrl_c()
it('leaving Insert mode with Ctrl-C vim-patch:8.1.1189', function()
exec([[
func StatusLine() abort
return ""
endfunc
set statusline=%!StatusLine()
set laststatus=2
]])
feed('i')
screen:expect([[
^ |
{1:~ }|
{1:~ }|
{1:~ }|
{3: }|
{2:-- INSERT --} |
]])
feed('<C-C>')
screen:expect([[
^ |
{1:~ }|
{1:~ }|
{1:~ }|
{3: }|
|
]])
end)
-- oldtest: Test_mode_message_at_leaving_insert_with_esc_mapped()
it('leaving Insert mode with ESC in the middle of a mapping vim-patch:8.1.1192', function()
exec([[
set laststatus=2
inoremap <Esc> <Esc>00
]])
feed('i')
screen:expect([[
^ |
{1:~ }|
{1:~ }|
{1:~ }|
{3:[No Name] }|
{2:-- INSERT --} |
]])
feed('<Esc>')
screen:expect([[
^ |
{1:~ }|
{1:~ }|
{1:~ }|
{3:[No Name] }|
|
]])
end)
-- oldtest: Test_mode_updated_after_ctrl_c()
it('pressing Ctrl-C in i_CTRL-O', function()
feed('i<C-O>')
screen:expect([[
^ |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{2:-- (insert) --} |
]])
feed('<C-C>')
screen:expect([[
^ |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
|
]])
end)
end)
-- oldtest: Test_ask_yesno()
it('y/n prompt works', function()
screen = Screen.new(75, 6)

View File

@ -1243,6 +1243,19 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim
|
]])
end)
it('echo messages are shown correctly when getchar() immediately follows', function()
feed([[:echo 'foo' | echo 'bar' | call getchar()<CR>]])
screen:expect([[
|
{1:~ }|
{1:~ }|
{1:~ }|
{3: }|
foo |
bar^ |
]])
end)
end)
describe('ui/ext_messages', function()

View File

@ -135,7 +135,7 @@ describe('NULL', function()
null_test('does not make Neovim crash when v:oldfiles gets assigned to that', ':let v:oldfiles = L|oldfiles', 0)
null_expr_test('does not make complete() crash or error out',
'execute(":normal i\\<C-r>=complete(1, L)[-1]\\n")',
'', '\n', function()
0, '', function()
eq({''}, curbufmeths.get_lines(0, -1, false))
end)
null_expr_test('is accepted by setmatches()', 'setmatches(L)', 0, 0)