To: vim_dev@googlegroups.com Subject: Patch 8.0.1494 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.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. Files: runtime/doc/autocmd.txt, src/edit.c, src/globals.h, src/structs.h, src/fileio.c, src/proto/fileio.pro, src/vim.h, src/main.c, src/testdir/test_autocmd.vim *** ../vim-8.0.1493/runtime/doc/autocmd.txt 2018-02-03 17:36:22.622091925 +0100 --- runtime/doc/autocmd.txt 2018-02-10 16:42:07.957267702 +0100 *************** *** 316,321 **** --- 332,340 ---- |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 *************** *** 959,965 **** current buffer in Insert mode. Not triggered 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 |v:event| can be used to determine the operation --- 979,990 ---- 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 |v:event| can be used to determine the operation *** ../vim-8.0.1493/src/edit.c 2018-02-10 16:19:09.181521235 +0100 --- src/edit.c 2018-02-10 17:48:59.557814185 +0100 *************** *** 1682,1698 **** #ifdef FEAT_AUTOCMD /* Trigger TextChangedI if b_changedtick differs. */ if (ready && has_textchangedI() ! && 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); } #endif if (must_redraw) --- 1682,1709 ---- #ifdef FEAT_AUTOCMD /* Trigger TextChangedI if b_changedtick differs. */ if (ready && has_textchangedI() ! && curbuf->b_last_changedtick != CHANGEDTICK(curbuf) # ifdef FEAT_INS_EXPAND && !pum_visible() # endif ) { ! 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) *** ../vim-8.0.1493/src/globals.h 2018-02-09 17:50:24.614970413 +0100 --- src/globals.h 2018-02-10 17:50:22.749247057 +0100 *************** *** 1085,1092 **** = 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 */ --- 1085,1090 ---- *** ../vim-8.0.1493/src/structs.h 2018-02-10 16:19:09.181521235 +0100 --- src/structs.h 2018-02-10 17:44:49.051523655 +0100 *************** *** 1983,1988 **** --- 1983,1997 ---- 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. */ *** ../vim-8.0.1493/src/fileio.c 2018-02-03 17:36:22.630091837 +0100 --- src/fileio.c 2018-02-10 17:47:21.134485486 +0100 *************** *** 5037,5045 **** #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); #endif u_unchanged(buf); u_update_save_nr(buf); --- 5037,5044 ---- #ifdef FEAT_AUTOCMD /* b:changedtick is always incremented in unchanged() but that * should not trigger a TextChanged event. */ ! if (buf->b_last_changedtick + 1 == CHANGEDTICK(buf)) ! buf->b_last_changedtick = CHANGEDTICK(buf); #endif u_unchanged(buf); u_update_save_nr(buf); *************** *** 7851,7856 **** --- 7850,7856 ---- {"TermResponse", EVENT_TERMRESPONSE}, {"TextChanged", EVENT_TEXTCHANGED}, {"TextChangedI", EVENT_TEXTCHANGEDI}, + {"TextChangedP", EVENT_TEXTCHANGEDP}, {"User", EVENT_USER}, {"VimEnter", EVENT_VIMENTER}, {"VimLeave", EVENT_VIMLEAVE}, *************** *** 9377,9382 **** --- 9377,9391 ---- } /* + * 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 *** ../vim-8.0.1493/src/proto/fileio.pro 2017-12-16 18:26:56.626992497 +0100 --- src/proto/fileio.pro 2018-02-10 17:16:49.399025678 +0100 *************** *** 48,53 **** --- 48,54 ---- 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); *** ../vim-8.0.1493/src/vim.h 2018-02-06 22:52:45.706103329 +0100 --- src/vim.h 2018-02-10 16:54:45.144300741 +0100 *************** *** 1337,1344 **** 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_CMDUNDEFINED, /* command undefined */ EVENT_OPTIONSET, /* option was set */ EVENT_TEXTYANKPOST, /* after some text was yanked */ --- 1337,1347 ---- 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 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 */ *** ../vim-8.0.1493/src/main.c 2018-02-03 17:36:22.630091837 +0100 --- src/main.c 2018-02-10 17:48:02.798201269 +0100 *************** *** 1201,1213 **** #ifdef FEAT_AUTOCMD /* Trigger TextChanged if b:changedtick differs. */ if (!finish_op && has_textchanged() ! && 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); } #endif --- 1201,1210 ---- #ifdef FEAT_AUTOCMD /* Trigger TextChanged if b:changedtick differs. */ if (!finish_op && has_textchanged() ! && curbuf->b_last_changedtick != CHANGEDTICK(curbuf)) { ! apply_autocmds(EVENT_TEXTCHANGED, NULL, NULL, FALSE, curbuf); ! curbuf->b_last_changedtick = CHANGEDTICK(curbuf); } #endif *** ../vim-8.0.1493/src/testdir/test_autocmd.vim 2018-02-03 20:11:36.416891937 +0100 --- src/testdir/test_autocmd.vim 2018-02-10 18:10:06.756442588 +0100 *************** *** 1249,1251 **** --- 1249,1306 ---- 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 :call TextChangedAutocmd('N') + au! TextChangedI :call TextChangedAutocmd('I') + au! TextChangedP :call TextChangedAutocmd('P') + + call cursor(3, 1) + let g:autocmd = '' + call feedkeys("o\", '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\", 'tnix') + call assert_equal('IIP', g:autocmd) + + let g:autocmd = '' + call feedkeys("Sf\\", 'tnix') + call assert_equal('IIPP', g:autocmd) + + let g:autocmd = '' + call feedkeys("Sf\\\", 'tnix') + call assert_equal('IIPPP', g:autocmd) + + let g:autocmd = '' + call feedkeys("Sf\\\\", '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 *** ../vim-8.0.1493/src/version.c 2018-02-10 16:19:09.181521235 +0100 --- src/version.c 2018-02-10 18:12:44.375167925 +0100 *************** *** 773,774 **** --- 773,776 ---- { /* Add new patch number below this line */ + /**/ + 1494, /**/ -- [clop clop] MORTICIAN: Who's that then? CUSTOMER: I don't know. MORTICIAN: Must be a king. CUSTOMER: Why? MORTICIAN: He hasn't got shit all over him. The Quest for the Holy Grail (Monty Python) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///