To: vim_dev@googlegroups.com Subject: Patch 8.1.0768 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.0768 Problem: Updating completions may cause the popup menu to flicker. Solution: Avoid updating the text below the popup menu before drawing the popup menu. Files: src/popupmnu.c, src/proto/popupmnu.pro, src/edit.c, src/screen.c *** ../vim-8.1.0767/src/popupmnu.c 2019-01-13 23:38:33.407773189 +0100 --- src/popupmnu.c 2019-01-17 21:08:17.890120079 +0100 *************** *** 19,24 **** --- 19,26 ---- static int pum_selected; /* index of selected item or -1 */ static int pum_first = 0; /* index of top item */ + static int call_update_screen = FALSE; + static int pum_height; /* nr of displayed pum items */ static int pum_width; /* width of displayed pum items */ static int pum_base_width; /* width of pum items base */ *************** *** 36,42 **** static int pum_win_wcol; static int pum_win_width; ! static int pum_do_redraw = FALSE; /* do redraw anyway */ static int pum_set_selected(int n, int repeat); --- 38,45 ---- static int pum_win_wcol; static int pum_win_width; ! static int pum_do_redraw = FALSE; // do redraw anyway ! static int pum_skip_redraw = FALSE; // skip redraw static int pum_set_selected(int n, int repeat); *************** *** 354,359 **** --- 357,392 ---- } /* + * Set a flag that when pum_redraw() is called it first calls update_screen(). + * This will avoid clearing and redrawing the popup menu, prevent flicker. + */ + void + pum_call_update_screen() + { + call_update_screen = TRUE; + + // Update the cursor position to be able to compute the popup menu + // position. The cursor line length may have changed because of the + // inserted completion. + curwin->w_valid &= VALID_CROW|VALID_CHEIGHT; + validate_cursor(); + } + + /* + * Return TRUE if we are going to redraw the popup menu and the screen position + * "row"/"col" is under the popup menu. + */ + int + pum_under_menu(int row, int col) + { + return pum_skip_redraw + && row >= pum_row + && row < pum_row + pum_height + && col >= pum_col - 1 + && col < pum_col + pum_width; + } + + /* * Redraw the popup menu, using "pum_first" and "pum_selected". */ void *************** *** 376,382 **** int round; int n; ! /* Never display more than we have */ if (pum_first > pum_size - pum_height) pum_first = pum_size - pum_height; --- 409,423 ---- int round; int n; ! if (call_update_screen) ! { ! call_update_screen = FALSE; ! pum_skip_redraw = TRUE; // do not redraw in pum_may_redraw(). ! update_screen(0); ! pum_skip_redraw = FALSE; ! } ! ! // never display more than we have if (pum_first > pum_size - pum_height) pum_first = pum_size - pum_height; *************** *** 789,794 **** --- 830,836 ---- pum_do_redraw = TRUE; update_screen(0); pum_do_redraw = FALSE; + call_update_screen = FALSE; } } } *************** *** 844,850 **** int len = pum_size; int selected = pum_selected; ! if (!pum_visible()) return; // nothing to do if (pum_window != curwin --- 886,892 ---- int len = pum_size; int selected = pum_selected; ! if (!pum_visible() || pum_skip_redraw) return; // nothing to do if (pum_window != curwin *** ../vim-8.1.0767/src/proto/popupmnu.pro 2018-06-17 14:47:50.649309059 +0200 --- src/proto/popupmnu.pro 2019-01-17 20:18:33.927980786 +0100 *************** *** 1,5 **** --- 1,7 ---- /* popupmnu.c */ void pum_display(pumitem_T *array, int size, int selected); + void pum_call_update_screen(void); + int pum_under_menu(int row, int col); void pum_redraw(void); void pum_undisplay(void); void pum_clear(void); *** ../vim-8.1.0767/src/edit.c 2019-01-13 23:38:33.379773390 +0100 --- src/edit.c 2019-01-17 20:07:30.868052215 +0100 *************** *** 3020,3026 **** if (compl_match_array != NULL) { h = curwin->w_cline_height; ! update_screen(0); if (h != curwin->w_cline_height) ins_compl_del_pum(); } --- 3020,3027 ---- if (compl_match_array != NULL) { h = curwin->w_cline_height; ! // Update the screen later, before drawing the popup menu over it. ! pum_call_update_screen(); if (h != curwin->w_cline_height) ins_compl_del_pum(); } *************** *** 3110,3117 **** do_cmdline_cmd((char_u *)"if exists('g:loaded_matchparen')|3match none|endif"); #endif ! /* Update the screen before drawing the popup menu over it. */ ! update_screen(0); if (compl_match_array == NULL) { --- 3111,3118 ---- do_cmdline_cmd((char_u *)"if exists('g:loaded_matchparen')|3match none|endif"); #endif ! // Update the screen later, before drawing the popup menu over it. ! pum_call_update_screen(); if (compl_match_array == NULL) { *************** *** 3668,3678 **** spell_bad_len = 0; /* need to redetect bad word */ #endif /* ! * Matches were cleared, need to search for them now. First display ! * the changed text before the cursor. Set "compl_restarting" to ! * avoid that the first match is inserted. */ ! update_screen(0); #ifdef FEAT_GUI if (gui.in_use) { --- 3669,3679 ---- spell_bad_len = 0; /* need to redetect bad word */ #endif /* ! * Matches were cleared, need to search for them now. Befor drawing ! * the popup menu display the changed text before the cursor. Set ! * "compl_restarting" to avoid that the first match is inserted. */ ! pum_call_update_screen(); #ifdef FEAT_GUI if (gui.in_use) { *************** *** 5077,5084 **** /* may undisplay the popup menu first */ ins_compl_upd_pum(); ! /* redraw to show the user what was inserted */ ! update_screen(0); /* display the updated popup menu */ ins_compl_show_pum(); --- 5078,5086 ---- /* may undisplay the popup menu first */ ins_compl_upd_pum(); ! // Redraw before showing the popup menu to show the user what was ! // inserted. ! pum_call_update_screen(); /* display the updated popup menu */ ins_compl_show_pum(); *** ../vim-8.1.0767/src/screen.c 2019-01-16 22:41:50.095917784 +0100 --- src/screen.c 2019-01-17 20:17:21.752429872 +0100 *************** *** 183,189 **** /* * Redraw the current window later, with update_screen(type). * Set must_redraw only if not already set to a higher value. ! * e.g. if must_redraw is CLEAR, type NOT_VALID will do nothing. */ void redraw_later(int type) --- 183,189 ---- /* * Redraw the current window later, with update_screen(type). * Set must_redraw only if not already set to a higher value. ! * E.g. if must_redraw is CLEAR, type NOT_VALID will do nothing. */ void redraw_later(int type) *************** *** 8475,8480 **** --- 8475,8484 ---- if (row >= screen_Rows || col >= screen_Columns) return; + #ifdef FEAT_INS_EXPAND + if (pum_under_menu(row, col)) + return; + #endif /* Outputting a character in the last cell on the screen may scroll the * screen up. Only do it when the "xn" termcap property is set, otherwise * mark the character invalid (update it when scrolled up). */ *** ../vim-8.1.0767/src/version.c 2019-01-17 17:36:42.495509219 +0100 --- src/version.c 2019-01-17 21:06:24.227223275 +0100 *************** *** 793,794 **** --- 793,796 ---- { /* Add new patch number below this line */ + /**/ + 768, /**/ -- hundred-and-one symptoms of being an internet addict: 241. You try to look for Net Search even when you're in File Manager. /// 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 ///