Patch 8.1.1751
Problem: When redrawing popups plines_win() may be called often.
Solution: Pass a cache to mouse_comp_pos().
Files: src/ui.c, src/proto/
ui.pro, src/beval.c, src/evalfunc.c,
src/popupwin.c
*** ../vim-8.1.1750/src/ui.c 2019-06-30 22:16:06.931821750 +0200
--- src/ui.c 2019-07-26 20:34:06.193125274 +0200
***************
*** 3381,3387 ****
#endif
/* compute the position in the buffer line from the posn on the screen */
! if (mouse_comp_pos(curwin, &row, &col, &curwin->w_cursor.lnum))
mouse_past_bottom = TRUE;
/* Start Visual mode before coladvance(), for when 'sel' != "old" */
--- 3381,3387 ----
#endif
/* compute the position in the buffer line from the posn on the screen */
! if (mouse_comp_pos(curwin, &row, &col, &curwin->w_cursor.lnum, NULL))
mouse_past_bottom = TRUE;
/* Start Visual mode before coladvance(), for when 'sel' != "old" */
***************
*** 3429,3436 ****
#if defined(FEAT_MOUSE) || defined(FEAT_TEXT_PROP) || defined(PROTO)
/*
! * Compute the position in the buffer line from the posn on the screen in
* window "win".
* Returns TRUE if the position is below the last line.
*/
int
--- 3429,3440 ----
#if defined(FEAT_MOUSE) || defined(FEAT_TEXT_PROP) || defined(PROTO)
/*
! * Compute the buffer line position from the screen position "rowp" / "colp" in
* window "win".
+ * "plines_cache" can be NULL (no cache) or an array with "win->w_height"
+ * entries that caches the plines_win() result from a previous call. Entry is
+ * zero if not computed yet. There must be no text or setting changes since
+ * the entry is put in the cache.
* Returns TRUE if the position is below the last line.
*/
int
***************
*** 3438,3444 ****
win_T *win,
int *rowp,
int *colp,
! linenr_T *lnump)
{
int col = *colp;
int row = *rowp;
--- 3442,3449 ----
win_T *win,
int *rowp,
int *colp,
! linenr_T *lnump,
! int *plines_cache)
{
int col = *colp;
int row = *rowp;
***************
*** 3456,3478 ****
while (row > 0)
{
#ifdef FEAT_DIFF
! /* Don't include filler lines in "count" */
! if (win->w_p_diff
# ifdef FEAT_FOLDING
! && !hasFoldingWin(win, lnum, NULL, NULL, TRUE, NULL)
# endif
! )
! {
! if (lnum == win->w_topline)
! row -= win->w_topfill;
else
- row -= diff_check_fill(win, lnum);
- count = plines_win_nofill(win, lnum, TRUE);
- }
- else
#endif
! count = plines_win(win, lnum, TRUE);
if (count > row)
break; /* Position is in this buffer line. */
#ifdef FEAT_FOLDING
--- 3461,3492 ----
while (row > 0)
{
+ int cache_idx = lnum - win->w_topline;
+
+ if (plines_cache != NULL && plines_cache[cache_idx] > 0)
+ count = plines_cache[cache_idx];
+ else
+ {
#ifdef FEAT_DIFF
! /* Don't include filler lines in "count" */
! if (win->w_p_diff
# ifdef FEAT_FOLDING
! && !hasFoldingWin(win, lnum, NULL, NULL, TRUE, NULL)
# endif
! )
! {
! if (lnum == win->w_topline)
! row -= win->w_topfill;
! else
! row -= diff_check_fill(win, lnum);
! count = plines_win_nofill(win, lnum, TRUE);
! }
else
#endif
! count = plines_win(win, lnum, TRUE);
! if (plines_cache != NULL)
! plines_cache[cache_idx] = count;
! }
if (count > row)
break; /* Position is in this buffer line. */
#ifdef FEAT_FOLDING
***************
*** 3626,3632 ****
return IN_UNKNOWN;
/* compute the position in the buffer line from the posn on the screen */
! if (mouse_comp_pos(curwin, &row, &col, &mpos->lnum))
return IN_STATUS_LINE; /* past bottom */
mpos->col = vcol2col(wp, mpos->lnum, col);
--- 3640,3646 ----
return IN_UNKNOWN;
/* compute the position in the buffer line from the posn on the screen */
! if (mouse_comp_pos(curwin, &row, &col, &mpos->lnum, NULL))
return IN_STATUS_LINE; /* past bottom */
mpos->col = vcol2col(wp, mpos->lnum, col);
*** ../vim-8.1.1750/src/proto/
ui.pro 2019-06-14 21:36:51.018437479 +0200
--- src/proto/
ui.pro 2019-07-26 20:29:05.302990868 +0200
***************
*** 64,70 ****
int clip_x11_owner_exists(Clipboard_T *cbd);
void yank_cut_buffer0(Display *dpy, Clipboard_T *cbd);
int jump_to_mouse(int flags, int *inclusive, int which_button);
! int mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump);
win_T *mouse_find_win(int *rowp, int *colp, mouse_find_T popup);
int get_fpos_of_mouse(pos_T *mpos);
int vcol2col(win_T *wp, linenr_T lnum, int vcol);
--- 64,70 ----
int clip_x11_owner_exists(Clipboard_T *cbd);
void yank_cut_buffer0(Display *dpy, Clipboard_T *cbd);
int jump_to_mouse(int flags, int *inclusive, int which_button);
! int mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump, int *plines_cache);
win_T *mouse_find_win(int *rowp, int *colp, mouse_find_T popup);
int get_fpos_of_mouse(pos_T *mpos);
int vcol2col(win_T *wp, linenr_T lnum, int vcol);
*** ../vim-8.1.1750/src/beval.c 2019-07-17 21:32:10.717608653 +0200
--- src/beval.c 2019-07-26 20:29:13.590940017 +0200
***************
*** 43,49 ****
{
// Found a window and the cursor is in the text. Now find the line
// number.
! if (!mouse_comp_pos(wp, &row, &col, &lnum))
{
// Not past end of the file.
lbuf = ml_get_buf(wp->w_buffer, lnum, FALSE);
--- 43,49 ----
{
// Found a window and the cursor is in the text. Now find the line
// number.
! if (!mouse_comp_pos(wp, &row, &col, &lnum, NULL))
{
// Not past end of the file.
lbuf = ml_get_buf(wp->w_buffer, lnum, FALSE);
*** ../vim-8.1.1750/src/evalfunc.c 2019-07-24 16:00:34.922180377 +0200
--- src/evalfunc.c 2019-07-26 20:29:31.006833066 +0200
***************
*** 4738,4744 ****
win = mouse_find_win(&row, &col, FIND_POPUP);
if (win == NULL)
return;
! (void)mouse_comp_pos(win, &row, &col, &lnum);
# ifdef FEAT_TEXT_PROP
if (WIN_IS_POPUP(win))
winnr = 0;
--- 4738,4744 ----
win = mouse_find_win(&row, &col, FIND_POPUP);
if (win == NULL)
return;
! (void)mouse_comp_pos(win, &row, &col, &lnum, NULL);
# ifdef FEAT_TEXT_PROP
if (WIN_IS_POPUP(win))
winnr = 0;
*** ../vim-8.1.1750/src/popupwin.c 2019-07-20 17:45:45.552285965 +0200
--- src/popupwin.c 2019-07-26 20:59:43.474154575 +0200
***************
*** 2593,2598 ****
--- 2593,2602 ----
// Only check which lines are to be updated if not already
// updating all lines.
if (mask == popup_mask_next)
+ {
+ int *plines_cache = ALLOC_CLEAR_MULT(int, Rows);
+ win_T *prev_wp = NULL;
+
for (line = 0; line < screen_Rows; ++line)
{
int col_done = 0;
***************
*** 2625,2637 ****
wp = mouse_find_win(&line_cp, &col_cp, IGNORE_POPUP);
if (wp != NULL)
{
if (line_cp >= wp->w_height)
// In (or below) status line
wp->w_redr_status = TRUE;
// compute the position in the buffer line from the
// position on the screen
else if (mouse_comp_pos(wp, &line_cp, &col_cp,
! &lnum))
// past bottom
wp->w_redr_status = TRUE;
else
--- 2629,2647 ----
wp = mouse_find_win(&line_cp, &col_cp, IGNORE_POPUP);
if (wp != NULL)
{
+ if (wp != prev_wp)
+ {
+ vim_memset(plines_cache, 0, sizeof(int) * Rows);
+ prev_wp = wp;
+ }
+
if (line_cp >= wp->w_height)
// In (or below) status line
wp->w_redr_status = TRUE;
// compute the position in the buffer line from the
// position on the screen
else if (mouse_comp_pos(wp, &line_cp, &col_cp,
! &lnum, plines_cache))
// past bottom
wp->w_redr_status = TRUE;
else
***************
*** 2645,2650 ****
--- 2655,2663 ----
}
}
}
+
+ vim_free(plines_cache);
+ }
}
/*
*** ../vim-8.1.1750/src/version.c 2019-07-26 19:48:15.811405918 +0200
--- src/version.c 2019-07-26 20:28:46.767104434 +0200
***************
*** 779,780 ****
--- 779,782 ----
{ /* Add new patch number below this line */
+ /**/
+ 1751,
/**/
--
ARTHUR: Now stand aside worthy adversary.
BLACK KNIGHT: (Glancing at his shoulder) 'Tis but a scratch.
ARTHUR: A scratch? Your arm's off.
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
/// Bram Moolenaar -- Br...@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 ///