summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-07-26 21:01:29 +0200
committerBram Moolenaar <Bram@vim.org>2019-07-26 21:01:29 +0200
commit9d5ffceb3fea247a88d4d3936e97b7f488aab6ff (patch)
tree24a015797538750c4e362f9c976db8749c3c0c50 /src
parent8a5c29aee978345132ad7f318b8a84633c33905c (diff)
downloadvim-git-9d5ffceb3fea247a88d4d3936e97b7f488aab6ff.tar.gz
patch 8.1.1751: when redrawing popups plines_win() may be called oftenv8.1.1751
Problem: When redrawing popups plines_win() may be called often. Solution: Pass a cache to mouse_comp_pos().
Diffstat (limited to 'src')
-rw-r--r--src/beval.c2
-rw-r--r--src/evalfunc.c2
-rw-r--r--src/popupwin.c15
-rw-r--r--src/proto/ui.pro2
-rw-r--r--src/ui.c46
-rw-r--r--src/version.c2
6 files changed, 49 insertions, 20 deletions
diff --git a/src/beval.c b/src/beval.c
index 3dd9b6770..69e667d63 100644
--- a/src/beval.c
+++ b/src/beval.c
@@ -43,7 +43,7 @@ find_word_under_cursor(
{
// Found a window and the cursor is in the text. Now find the line
// number.
- if (!mouse_comp_pos(wp, &row, &col, &lnum))
+ if (!mouse_comp_pos(wp, &row, &col, &lnum, NULL))
{
// Not past end of the file.
lbuf = ml_get_buf(wp->w_buffer, lnum, FALSE);
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 73efa79f2..685e2f1e4 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -4738,7 +4738,7 @@ f_getchar(typval_T *argvars, typval_T *rettv)
win = mouse_find_win(&row, &col, FIND_POPUP);
if (win == NULL)
return;
- (void)mouse_comp_pos(win, &row, &col, &lnum);
+ (void)mouse_comp_pos(win, &row, &col, &lnum, NULL);
# ifdef FEAT_TEXT_PROP
if (WIN_IS_POPUP(win))
winnr = 0;
diff --git a/src/popupwin.c b/src/popupwin.c
index a303582be..d0f6156ad 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -2593,6 +2593,10 @@ may_update_popup_mask(int type)
// 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,13 +2629,19 @@ may_update_popup_mask(int type)
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))
+ &lnum, plines_cache))
// past bottom
wp->w_redr_status = TRUE;
else
@@ -2645,6 +2655,9 @@ may_update_popup_mask(int type)
}
}
}
+
+ vim_free(plines_cache);
+ }
}
/*
diff --git a/src/proto/ui.pro b/src/proto/ui.pro
index 7b28a32a2..472da3601 100644
--- a/src/proto/ui.pro
+++ b/src/proto/ui.pro
@@ -64,7 +64,7 @@ void clip_x11_set_selection(Clipboard_T *cbd);
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 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);
diff --git a/src/ui.c b/src/ui.c
index 1e6c1464a..5d04e1b97 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -3381,7 +3381,7 @@ retnomove:
#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))
+ 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,8 +3429,12 @@ retnomove:
#if defined(FEAT_MOUSE) || defined(FEAT_TEXT_PROP) || defined(PROTO)
/*
- * Compute the position in the buffer line from the posn on the screen in
+ * 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,7 +3442,8 @@ mouse_comp_pos(
win_T *win,
int *rowp,
int *colp,
- linenr_T *lnump)
+ linenr_T *lnump,
+ int *plines_cache)
{
int col = *colp;
int row = *rowp;
@@ -3456,23 +3461,32 @@ mouse_comp_pos(
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
+ /* Don't include filler lines in "count" */
+ if (win->w_p_diff
# ifdef FEAT_FOLDING
- && !hasFoldingWin(win, lnum, NULL, NULL, TRUE, NULL)
+ && !hasFoldingWin(win, lnum, NULL, NULL, TRUE, NULL)
# endif
- )
- {
- if (lnum == win->w_topline)
- row -= win->w_topfill;
+ )
+ {
+ if (lnum == win->w_topline)
+ row -= win->w_topfill;
+ else
+ row -= diff_check_fill(win, lnum);
+ count = plines_win_nofill(win, lnum, TRUE);
+ }
else
- row -= diff_check_fill(win, lnum);
- count = plines_win_nofill(win, lnum, TRUE);
- }
- else
#endif
- count = plines_win(win, lnum, TRUE);
+ 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,7 +3640,7 @@ get_fpos_of_mouse(pos_T *mpos)
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))
+ if (mouse_comp_pos(curwin, &row, &col, &mpos->lnum, NULL))
return IN_STATUS_LINE; /* past bottom */
mpos->col = vcol2col(wp, mpos->lnum, col);
diff --git a/src/version.c b/src/version.c
index 5c7507845..5104f6a99 100644
--- a/src/version.c
+++ b/src/version.c
@@ -778,6 +778,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1751,
+/**/
1750,
/**/
1749,