# HG changeset patch # User Bram Moolenaar # Date 1603276206 -7200 # Node ID fba5ccf33794c96deb2fe24a6480254ea4108f8f # Parent c78e309dc10f5172a3a7b21e5f2748ce738f1571 patch 8.2.1874: can't do something just before leaving Insert mode Commit: https://github.com/vim/vim/commit/b53e13a91ab2fc9d52bd044715daa84972f4ce47 Author: Bram Moolenaar Date: Wed Oct 21 12:19:53 2020 +0200 patch 8.2.1874: can't do something just before leaving Insert mode Problem: Can't do something just before leaving Insert mode. Solution: Add the InsertLeavePre autocommand event. (closes https://github.com/vim/vim/issues/7177) diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -881,9 +881,14 @@ InsertEnter Just before starting Inser The cursor is restored afterwards. If you do not want that set |v:char| to a non-empty string. + *InsertLeavePre* +InsertLeavePre Just before leaving Insert mode. Also when + using CTRL-O |i_CTRL-O|. Be caseful not to + change mode or use `:normal`, it will likely + cause trouble. *InsertLeave* -InsertLeave When leaving Insert mode. Also when using - CTRL-O |i_CTRL-O|. But not for |i_CTRL-C|. +InsertLeave Just after leaving Insert mode. Also when + using CTRL-O |i_CTRL-O|. But not for |i_CTRL-C|. *MenuPopup* MenuPopup Just before showing the popup menu (under the right mouse button). Useful for adjusting the diff --git a/src/autocmd.c b/src/autocmd.c --- a/src/autocmd.c +++ b/src/autocmd.c @@ -149,6 +149,7 @@ static struct event_name {"InsertChange", EVENT_INSERTCHANGE}, {"InsertEnter", EVENT_INSERTENTER}, {"InsertLeave", EVENT_INSERTLEAVE}, + {"InsertLeavePre", EVENT_INSERTLEAVEPRE}, {"InsertCharPre", EVENT_INSERTCHARPRE}, {"MenuPopup", EVENT_MENUPOPUP}, {"OptionSet", EVENT_OPTIONSET}, diff --git a/src/edit.c b/src/edit.c --- a/src/edit.c +++ b/src/edit.c @@ -3607,6 +3607,9 @@ ins_esc( undisplay_dollar(); } + if (cmdchar != 'r' && cmdchar != 'v') + ins_apply_autocmds(EVENT_INSERTLEAVEPRE); + // When an autoindent was removed, curswant stays after the // indent if (restart_edit == NUL && (colnr_T)temp == curwin->w_cursor.col) diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim --- a/src/testdir/test_edit.vim +++ b/src/testdir/test_edit.vim @@ -1446,31 +1446,40 @@ endfunc func Test_edit_InsertLeave() new + au InsertLeavePre * let g:did_au_pre = 1 au InsertLeave * let g:did_au = 1 + let g:did_au_pre = 0 let g:did_au = 0 call feedkeys("afoo\", 'tx') + call assert_equal(1, g:did_au_pre) call assert_equal(1, g:did_au) call assert_equal('foo', getline(1)) + let g:did_au_pre = 0 let g:did_au = 0 call feedkeys("Sbar\", 'tx') + call assert_equal(1, g:did_au_pre) call assert_equal(0, g:did_au) call assert_equal('bar', getline(1)) inoremap x xx + let g:did_au_pre = 0 let g:did_au = 0 call feedkeys("Saax", 'tx') + call assert_equal(1, g:did_au_pre) call assert_equal(1, g:did_au) call assert_equal('aaxx', getline(1)) inoremap x xx + let g:did_au_pre = 0 let g:did_au = 0 call feedkeys("Sbbx", 'tx') + call assert_equal(1, g:did_au_pre) call assert_equal(0, g:did_au) call assert_equal('bbxx', getline(1)) bwipe! - au! InsertLeave + au! InsertLeave InsertLeavePre iunmap x endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1874, +/**/ 1873, /**/ 1872, diff --git a/src/vim.h b/src/vim.h --- a/src/vim.h +++ b/src/vim.h @@ -1298,7 +1298,8 @@ enum auto_event EVENT_INSERTCHANGE, // when changing Insert/Replace mode EVENT_INSERTCHARPRE, // before inserting a char EVENT_INSERTENTER, // when entering Insert mode - EVENT_INSERTLEAVE, // when leaving Insert mode + EVENT_INSERTLEAVEPRE, // just before leaving Insert mode + EVENT_INSERTLEAVE, // just after leaving Insert mode EVENT_MENUPOPUP, // just before popup menu is displayed EVENT_OPTIONSET, // option was set EVENT_QUICKFIXCMDPOST, // after :make, :grep etc. @@ -1325,7 +1326,8 @@ enum auto_event EVENT_TABNEW, // when entering a new tab page EVENT_TERMCHANGED, // after changing 'term' EVENT_TERMINALOPEN, // after a terminal buffer was created - EVENT_TERMINALWINOPEN, // after a terminal buffer was created and entering its window + EVENT_TERMINALWINOPEN, // after a terminal buffer was created and + // entering its window EVENT_TERMRESPONSE, // after setting "v:termresponse" EVENT_TEXTCHANGED, // text was modified not in Insert mode EVENT_TEXTCHANGEDI, // text was modified in Insert mode