mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Problem: No autocmd triggered in Insert mode with visible popup menu. Solution: Add TextChangedP. (Prabir Shrestha, Christian Brabandt, closes #2372, closes #1691) Fix that the TextChanged autocommands are not always triggered when sourcing a script.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
*autocmd.txt* For Vim version 8.0. Last change: 2018 Feb 09
|
||||
*autocmd.txt* For Vim version 8.0. Last change: 2018 Feb 10
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -332,6 +332,9 @@ Name triggered by ~
|
||||
|
||||
|TextChanged| after a change was made to the text in Normal mode
|
||||
|TextChangedI| after a change was made to the text in Insert mode
|
||||
when popup menu is not visible
|
||||
|TextChangedP| after a change was made to the text in Insert mode
|
||||
when popup menu visible
|
||||
|TextYankPost| after text is yanked or deleted
|
||||
|
||||
|ColorScheme| after loading a color scheme
|
||||
@@ -976,6 +979,11 @@ TextChangedI After a change was made to the text in the
|
||||
current buffer in Insert mode.
|
||||
Not triggered when the popup menu is visible.
|
||||
Otherwise the same as TextChanged.
|
||||
*TextChangedP*
|
||||
TextChangedP After a change was made to the text in the
|
||||
current buffer in Insert mode, only when the
|
||||
popup menu is visible. Otherwise the same as
|
||||
TextChanged.
|
||||
*TextYankPost*
|
||||
TextYankPost After text has been yanked or deleted in the
|
||||
current buffer. The following values of
|
||||
|
19
src/edit.c
19
src/edit.c
@@ -1682,17 +1682,28 @@ ins_redraw(
|
||||
#ifdef FEAT_AUTOCMD
|
||||
/* Trigger TextChangedI if b_changedtick differs. */
|
||||
if (ready && has_textchangedI()
|
||||
&& last_changedtick != CHANGEDTICK(curbuf)
|
||||
&& curbuf->b_last_changedtick != CHANGEDTICK(curbuf)
|
||||
# ifdef FEAT_INS_EXPAND
|
||||
&& !pum_visible()
|
||||
# endif
|
||||
)
|
||||
{
|
||||
if (last_changedtick_buf == curbuf)
|
||||
apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
|
||||
last_changedtick_buf = curbuf;
|
||||
last_changedtick = CHANGEDTICK(curbuf);
|
||||
curbuf->b_last_changedtick = CHANGEDTICK(curbuf);
|
||||
}
|
||||
|
||||
# ifdef FEAT_INS_EXPAND
|
||||
/* Trigger TextChangedP if b_changedtick differs. When the popupmenu closes
|
||||
* TextChangedI will need to trigger for backwards compatibility, thus use
|
||||
* different b_last_changedtick* variables. */
|
||||
if (ready && has_textchangedP()
|
||||
&& curbuf->b_last_changedtick_pum != CHANGEDTICK(curbuf)
|
||||
&& pum_visible())
|
||||
{
|
||||
apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, FALSE, curbuf);
|
||||
curbuf->b_last_changedtick_pum = CHANGEDTICK(curbuf);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
if (must_redraw)
|
||||
|
15
src/fileio.c
15
src/fileio.c
@@ -5037,9 +5037,8 @@ restore_backup:
|
||||
#ifdef FEAT_AUTOCMD
|
||||
/* b:changedtick is always incremented in unchanged() but that
|
||||
* should not trigger a TextChanged event. */
|
||||
if (last_changedtick + 1 == CHANGEDTICK(buf)
|
||||
&& last_changedtick_buf == buf)
|
||||
last_changedtick = CHANGEDTICK(buf);
|
||||
if (buf->b_last_changedtick + 1 == CHANGEDTICK(buf))
|
||||
buf->b_last_changedtick = CHANGEDTICK(buf);
|
||||
#endif
|
||||
u_unchanged(buf);
|
||||
u_update_save_nr(buf);
|
||||
@@ -7851,6 +7850,7 @@ static struct event_name
|
||||
{"TermResponse", EVENT_TERMRESPONSE},
|
||||
{"TextChanged", EVENT_TEXTCHANGED},
|
||||
{"TextChangedI", EVENT_TEXTCHANGEDI},
|
||||
{"TextChangedP", EVENT_TEXTCHANGEDP},
|
||||
{"User", EVENT_USER},
|
||||
{"VimEnter", EVENT_VIMENTER},
|
||||
{"VimLeave", EVENT_VIMLEAVE},
|
||||
@@ -9376,6 +9376,15 @@ has_textchangedI(void)
|
||||
return (first_autopat[(int)EVENT_TEXTCHANGEDI] != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE when there is a TextChangedP autocommand defined.
|
||||
*/
|
||||
int
|
||||
has_textchangedP(void)
|
||||
{
|
||||
return (first_autopat[(int)EVENT_TEXTCHANGEDP] != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE when there is an InsertCharPre autocommand defined.
|
||||
*/
|
||||
|
@@ -1085,8 +1085,6 @@ EXTERN pos_T last_cursormoved /* for CursorMoved event */
|
||||
= INIT_POS_T(0, 0, 0)
|
||||
# endif
|
||||
;
|
||||
EXTERN varnumber_T last_changedtick INIT(= 0); /* for TextChanged event */
|
||||
EXTERN buf_T *last_changedtick_buf INIT(= NULL);
|
||||
#endif
|
||||
|
||||
EXTERN int postponed_split INIT(= 0); /* for CTRL-W CTRL-] command */
|
||||
|
@@ -1201,13 +1201,10 @@ main_loop(
|
||||
#ifdef FEAT_AUTOCMD
|
||||
/* Trigger TextChanged if b:changedtick differs. */
|
||||
if (!finish_op && has_textchanged()
|
||||
&& last_changedtick != CHANGEDTICK(curbuf))
|
||||
&& curbuf->b_last_changedtick != CHANGEDTICK(curbuf))
|
||||
{
|
||||
if (last_changedtick_buf == curbuf)
|
||||
apply_autocmds(EVENT_TEXTCHANGED, NULL, NULL,
|
||||
FALSE, curbuf);
|
||||
last_changedtick_buf = curbuf;
|
||||
last_changedtick = CHANGEDTICK(curbuf);
|
||||
apply_autocmds(EVENT_TEXTCHANGED, NULL, NULL, FALSE, curbuf);
|
||||
curbuf->b_last_changedtick = CHANGEDTICK(curbuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -48,6 +48,7 @@ int has_cursormoved(void);
|
||||
int has_cursormovedI(void);
|
||||
int has_textchanged(void);
|
||||
int has_textchangedI(void);
|
||||
int has_textchangedP(void);
|
||||
int has_insertcharpre(void);
|
||||
int has_cmdundefined(void);
|
||||
int has_funcundefined(void);
|
||||
|
@@ -1983,6 +1983,15 @@ struct file_buffer
|
||||
incremented for each change, also for undo */
|
||||
#define CHANGEDTICK(buf) ((buf)->b_ct_di.di_tv.vval.v_number)
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
varnumber_T b_last_changedtick; /* b:changedtick when TextChanged or
|
||||
TextChangedI was last triggered. */
|
||||
# ifdef FEAT_INS_EXPAND
|
||||
varnumber_T b_last_changedtick_pum; /* b:changedtick when TextChangedP was
|
||||
last triggered. */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
int b_saving; /* Set to TRUE if we are in the middle of
|
||||
saving the buffer. */
|
||||
|
||||
|
@@ -1249,3 +1249,58 @@ function Test_dirchanged_auto()
|
||||
bwipe!
|
||||
call s:After_test_dirchanged()
|
||||
endfunc
|
||||
|
||||
" Test TextChangedI and TextChangedP
|
||||
func Test_ChangedP()
|
||||
new
|
||||
call setline(1, ['foo', 'bar', 'foobar'])
|
||||
call test_override("char_avail", 1)
|
||||
set complete=. completeopt=menuone
|
||||
|
||||
func! TextChangedAutocmd(char)
|
||||
let g:autocmd .= a:char
|
||||
endfunc
|
||||
|
||||
au! TextChanged <buffer> :call TextChangedAutocmd('N')
|
||||
au! TextChangedI <buffer> :call TextChangedAutocmd('I')
|
||||
au! TextChangedP <buffer> :call TextChangedAutocmd('P')
|
||||
|
||||
call cursor(3, 1)
|
||||
let g:autocmd = ''
|
||||
call feedkeys("o\<esc>", 'tnix')
|
||||
call assert_equal('I', g:autocmd)
|
||||
|
||||
let g:autocmd = ''
|
||||
call feedkeys("Sf", 'tnix')
|
||||
call assert_equal('II', g:autocmd)
|
||||
|
||||
let g:autocmd = ''
|
||||
call feedkeys("Sf\<C-N>", 'tnix')
|
||||
call assert_equal('IIP', g:autocmd)
|
||||
|
||||
let g:autocmd = ''
|
||||
call feedkeys("Sf\<C-N>\<C-N>", 'tnix')
|
||||
call assert_equal('IIPP', g:autocmd)
|
||||
|
||||
let g:autocmd = ''
|
||||
call feedkeys("Sf\<C-N>\<C-N>\<C-N>", 'tnix')
|
||||
call assert_equal('IIPPP', g:autocmd)
|
||||
|
||||
let g:autocmd = ''
|
||||
call feedkeys("Sf\<C-N>\<C-N>\<C-N>\<C-N>", 'tnix')
|
||||
call assert_equal('IIPPPP', g:autocmd)
|
||||
|
||||
call assert_equal(['foo', 'bar', 'foobar', 'foo'], getline(1, '$'))
|
||||
" TODO: how should it handle completeopt=noinsert,noselect?
|
||||
|
||||
" CleanUp
|
||||
call test_override("char_avail", 0)
|
||||
au! TextChanged
|
||||
au! TextChangedI
|
||||
au! TextChangedP
|
||||
delfu TextChangedAutocmd
|
||||
unlet! g:autocmd
|
||||
set complete&vim completeopt&vim
|
||||
|
||||
bw!
|
||||
endfunc
|
||||
|
@@ -771,6 +771,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1494,
|
||||
/**/
|
||||
1493,
|
||||
/**/
|
||||
|
@@ -1337,8 +1337,11 @@ enum auto_event
|
||||
EVENT_TABCLOSED, /* after closing a tab page */
|
||||
EVENT_SHELLCMDPOST, /* after ":!cmd" */
|
||||
EVENT_SHELLFILTERPOST, /* after ":1,2!cmd", ":w !cmd", ":r !cmd". */
|
||||
EVENT_TEXTCHANGED, /* text was modified */
|
||||
EVENT_TEXTCHANGEDI, /* text was modified in Insert mode*/
|
||||
EVENT_TEXTCHANGED, /* text was modified not in Insert mode */
|
||||
EVENT_TEXTCHANGEDI, /* text was modified in Insert mode without
|
||||
popup menu visible */
|
||||
EVENT_TEXTCHANGEDP, /* text was modified in Insert mode with popup
|
||||
menu visible */
|
||||
EVENT_CMDUNDEFINED, /* command undefined */
|
||||
EVENT_OPTIONSET, /* option was set */
|
||||
EVENT_TEXTYANKPOST, /* after some text was yanked */
|
||||
|
Reference in New Issue
Block a user