diff options
author | Bram Moolenaar <Bram@vim.org> | 2018-02-10 18:15:19 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2018-02-10 18:15:19 +0100 |
commit | 5a093437199001a0d60d8e18e2b9539b99a7757c (patch) | |
tree | 4897a21d58c38ac3adc0c3b309381a58f4bbde45 /src | |
parent | 9b56a57cdae31f7a2c85d440392bf63d3253a158 (diff) |
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menuv8.0.1494
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/edit.c | 21 | ||||
-rw-r--r-- | src/fileio.c | 15 | ||||
-rw-r--r-- | src/globals.h | 2 | ||||
-rw-r--r-- | src/main.c | 9 | ||||
-rw-r--r-- | src/proto/fileio.pro | 1 | ||||
-rw-r--r-- | src/structs.h | 9 | ||||
-rw-r--r-- | src/testdir/test_autocmd.vim | 55 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim.h | 7 |
9 files changed, 103 insertions, 18 deletions
diff --git a/src/edit.c b/src/edit.c index a9e6343a80..7074f26486 100644 --- a/src/edit.c +++ b/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); + apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, 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) diff --git a/src/fileio.c b/src/fileio.c index ab216abbf6..d4735f344e 100644 --- a/src/fileio.c +++ b/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}, @@ -9377,6 +9377,15 @@ has_textchangedI(void) } /* + * 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. */ int diff --git a/src/globals.h b/src/globals.h index 943bb3130a..1b2b1e8bf1 100644 --- a/src/globals.h +++ b/src/globals.h @@ -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 */ diff --git a/src/main.c b/src/main.c index 9f443aef25..971590aab6 100644 --- a/src/main.c +++ b/src/main.c @@ -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 diff --git a/src/proto/fileio.pro b/src/proto/fileio.pro index 757963113f..12d5c14ff3 100644 --- a/src/proto/fileio.pro +++ b/src/proto/fileio.pro @@ -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); diff --git a/src/structs.h b/src/structs.h index abfb73176f..3efd6ab3d9 100644 --- a/src/structs.h +++ b/src/structs.h @@ -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. */ diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index 065ac4e29d..d1ce561973 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -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 diff --git a/src/version.c b/src/version.c index 261e3d7c69..f5772a8c26 100644 --- a/src/version.c +++ b/src/version.c @@ -772,6 +772,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1494, +/**/ 1493, /**/ 1492, @@ -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 */ |