To: vim_dev@googlegroups.com Subject: Patch 8.1.1751 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- 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 ///