To: vim_dev@googlegroups.com Subject: Patch 9.0.0751 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.0751 Problem: 'scrolloff' does not work well with 'smoothscroll'. Solution: Make positioning the cursor a bit better. Rename functions. Files: src/move.c, src/charset.c, src/proto/charset.pro, src/edit.c, src/ex_cmds.c, src/misc2.c, src/normal.c, src/ops.c, src/popupwin.c *** ../vim-9.0.0750/src/move.c 2022-10-13 21:54:23.962227932 +0100 --- src/move.c 2022-10-14 19:26:23.502782783 +0100 *************** *** 1633,1639 **** if (curwin->w_cursor.lnum == curwin->w_topline && do_sms) { ! long so = curwin->w_p_so >= 0 ? curwin->w_p_so : p_so; int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2; // make sure the cursor is in the visible text --- 1633,1639 ---- if (curwin->w_cursor.lnum == curwin->w_topline && do_sms) { ! long so = get_scrolloff_value(); int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2; // make sure the cursor is in the visible text *************** *** 1684,1691 **** linenr_T prev_topline = curwin->w_topline; if (do_sms) ! size = win_linetabsize(curwin, curwin->w_topline, ! ml_get(curwin->w_topline), (colnr_T)MAXCOL); // diff mode: first consume "topfill" // 'smoothscroll': increase "w_skipcol" until it goes over the end of --- 1684,1690 ---- linenr_T prev_topline = curwin->w_topline; if (do_sms) ! size = linetabsize(curwin, curwin->w_topline); // diff mode: first consume "topfill" // 'smoothscroll': increase "w_skipcol" until it goes over the end of *************** *** 1740,1747 **** # endif curwin->w_skipcol = 0; if (todo > 1 && do_sms) ! size = win_linetabsize(curwin, curwin->w_topline, ! ml_get(curwin->w_topline), (colnr_T)MAXCOL); } } } --- 1739,1745 ---- # endif curwin->w_skipcol = 0; if (todo > 1 && do_sms) ! size = linetabsize(curwin, curwin->w_topline); } } } *************** *** 1784,1794 **** { int width1 = curwin->w_width - curwin_col_off(); int width2 = width1 + curwin_col_off2(); ! long so = curwin->w_p_so >= 0 ? curwin->w_p_so : p_so; int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2; // Make sure the cursor is in a visible part of the line, taking // 'scrolloff' into account, but using screen lines. validate_virtcol(); if (curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols) { --- 1782,1796 ---- { int width1 = curwin->w_width - curwin_col_off(); int width2 = width1 + curwin_col_off2(); ! long so = get_scrolloff_value(); int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2; + int space_cols = (curwin->w_height - 1) * width2; // Make sure the cursor is in a visible part of the line, taking // 'scrolloff' into account, but using screen lines. + // If there are not enough screen lines put the cursor in the middle. + if (scrolloff_cols > space_cols / 2) + scrolloff_cols = space_cols / 2; validate_virtcol(); if (curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols) { *************** *** 1823,1833 **** int width1 = curwin->w_width - curwin_col_off(); int width2 = width1 + curwin_col_off2(); ! long so = curwin->w_p_so >= 0 ? curwin->w_p_so : p_so; int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2; int scrolled = FALSE; validate_virtcol(); while (curwin->w_skipcol > 0 && curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols) { --- 1825,1846 ---- int width1 = curwin->w_width - curwin_col_off(); int width2 = width1 + curwin_col_off2(); ! long so = get_scrolloff_value(); int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2; int scrolled = FALSE; validate_virtcol(); + if (curwin->w_cline_height == curwin->w_height) + { + // the line just fits in the window, don't scroll + if (curwin->w_skipcol != 0) + { + curwin->w_skipcol = 0; + redraw_later(UPD_NOT_VALID); + } + return; + } + while (curwin->w_skipcol > 0 && curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols) { *************** *** 2691,2696 **** --- 2704,2722 ---- ) return; + if (curwin->w_p_sms && !curwin->w_p_wrap) + { + // 'smoothscroll is active + if (curwin->w_cline_height == curwin->w_height) + { + // The cursor line just fits in the window, don't scroll. + curwin->w_skipcol = 0; + return; + } + // TODO: If the cursor line doesn't fit in the window then only adjust + // w_skipcol. + } + /* * Narrow down the area where the cursor can be put by taking lines from * the top and the bottom until: *** ../vim-9.0.0750/src/charset.c 2022-10-13 22:12:07.160673838 +0100 --- src/charset.c 2022-10-14 14:48:29.506975353 +0100 *************** *** 743,755 **** * Does not handle text properties, since "s" is not a buffer line. */ int ! linetabsize(char_u *s) { return linetabsize_col(0, s); } /* ! * Like linetabsize(), but "s" starts at column "startcol". */ int linetabsize_col(int startcol, char_u *s) --- 743,755 ---- * Does not handle text properties, since "s" is not a buffer line. */ int ! linetabsize_str(char_u *s) { return linetabsize_col(0, s); } /* ! * Like linetabsize_str(), but "s" starts at column "startcol". */ int linetabsize_col(int startcol, char_u *s) *************** *** 772,778 **** } /* ! * Like linetabsize(), but for a given window instead of the current one. */ int win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len) --- 772,778 ---- } /* ! * Like linetabsize_str(), but for a given window instead of the current one. */ int win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len) *************** *** 785,790 **** --- 785,801 ---- return (int)cts.cts_vcol; } + /* + * Return the number of cells line "lnum" of window "wp" will take on the + * screen, taking into account the size of a tab and text properties. + */ + int + linetabsize(win_T *wp, linenr_T lnum) + { + return win_linetabsize(wp, lnum, + ml_get_buf(wp->w_buffer, lnum, FALSE), (colnr_T)MAXCOL); + } + void win_linetabsize_cts(chartabsize_T *cts, colnr_T len) { *** ../vim-9.0.0750/src/proto/charset.pro 2022-09-10 20:00:31.121468657 +0100 --- src/proto/charset.pro 2022-10-14 14:44:22.646987951 +0100 *************** *** 15,23 **** int vim_strsize(char_u *s); int vim_strnsize(char_u *s, int len); int chartabsize(char_u *p, colnr_T col); ! int linetabsize(char_u *s); int linetabsize_col(int startcol, char_u *s); int win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len); void win_linetabsize_cts(chartabsize_T *cts, colnr_T len); int vim_isIDc(int c); int vim_isNormalIDc(int c); --- 15,24 ---- int vim_strsize(char_u *s); int vim_strnsize(char_u *s, int len); int chartabsize(char_u *p, colnr_T col); ! int linetabsize_str(char_u *s); int linetabsize_col(int startcol, char_u *s); int win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len); + int linetabsize(win_T *wp, linenr_T lnum); void win_linetabsize_cts(chartabsize_T *cts, colnr_T len); int vim_isIDc(int c); int vim_isNormalIDc(int c); *** ../vim-9.0.0750/src/edit.c 2022-10-13 22:12:07.164673822 +0100 --- src/edit.c 2022-10-14 14:45:07.154983652 +0100 *************** *** 237,243 **** if (startln) Insstart.col = 0; } ! Insstart_textlen = (colnr_T)linetabsize(ml_get_curline()); Insstart_blank_vcol = MAXCOL; if (!did_ai) ai_col = 0; --- 237,243 ---- if (startln) Insstart.col = 0; } ! Insstart_textlen = (colnr_T)linetabsize_str(ml_get_curline()); Insstart_blank_vcol = MAXCOL; if (!did_ai) ai_col = 0; *************** *** 2372,2378 **** // Don't update the original insert position when moved to the // right, except when nothing was inserted yet. update_Insstart_orig = FALSE; ! Insstart_textlen = (colnr_T)linetabsize(ml_get_curline()); if (u_save_cursor() == OK) { --- 2372,2378 ---- // Don't update the original insert position when moved to the // right, except when nothing was inserted yet. update_Insstart_orig = FALSE; ! Insstart_textlen = (colnr_T)linetabsize_str(ml_get_curline()); if (u_save_cursor() == OK) { *** ../vim-9.0.0750/src/ex_cmds.c 2022-10-04 16:23:39.010042185 +0100 --- src/ex_cmds.c 2022-10-14 14:45:29.902981847 +0100 *************** *** 256,262 **** ; save = *last; *last = NUL; ! len = linetabsize(line); // get line length if (has_tab != NULL) // check for embedded TAB *has_tab = (vim_strchr(first, TAB) != NULL); *last = save; --- 256,262 ---- ; save = *last; *last = NUL; ! len = linetabsize_str(line); // get line length on screen if (has_tab != NULL) // check for embedded TAB *has_tab = (vim_strchr(first, TAB) != NULL); *last = save; *** ../vim-9.0.0750/src/misc2.c 2022-09-26 19:50:07.463112932 +0100 --- src/misc2.c 2022-10-14 14:45:57.334979979 +0100 *************** *** 150,156 **** if ((addspaces || finetune) && !VIsual_active) { ! curwin->w_curswant = linetabsize(line) + one_more; if (curwin->w_curswant > 0) --curwin->w_curswant; } --- 150,156 ---- if ((addspaces || finetune) && !VIsual_active) { ! curwin->w_curswant = linetabsize_str(line) + one_more; if (curwin->w_curswant > 0) --curwin->w_curswant; } *************** *** 166,172 **** && wcol >= (colnr_T)width && width > 0) { ! csize = linetabsize(line); if (csize > 0) csize--; --- 166,172 ---- && wcol >= (colnr_T)width && width > 0) { ! csize = linetabsize_str(line); if (csize > 0) csize--; *** ../vim-9.0.0750/src/normal.c 2022-10-13 22:12:07.168673806 +0100 --- src/normal.c 2022-10-14 14:46:25.242978430 +0100 *************** *** 2266,2272 **** static int nv_screengo(oparg_T *oap, int dir, long dist) { ! int linelen = linetabsize(ml_get_curline()); int retval = OK; int atend = FALSE; int n; --- 2266,2272 ---- static int nv_screengo(oparg_T *oap, int dir, long dist) { ! int linelen = linetabsize_str(ml_get_curline()); int retval = OK; int atend = FALSE; int n; *************** *** 2343,2349 **** } --curwin->w_cursor.lnum; ! linelen = linetabsize(ml_get_curline()); if (linelen > width1) curwin->w_curswant += (((linelen - width1 - 1) / width2) + 1) * width2; --- 2343,2349 ---- } --curwin->w_cursor.lnum; ! linelen = linetabsize_str(ml_get_curline()); if (linelen > width1) curwin->w_curswant += (((linelen - width1 - 1) / width2) + 1) * width2; *************** *** 2383,2389 **** // clipped to column 0. if (curwin->w_curswant >= width1) curwin->w_curswant -= width2; ! linelen = linetabsize(ml_get_curline()); } } } --- 2383,2389 ---- // clipped to column 0. if (curwin->w_curswant >= width1) curwin->w_curswant -= width2; ! linelen = linetabsize_str(ml_get_curline()); } } } *************** *** 6005,6011 **** { oap->motion_type = MCHAR; oap->inclusive = FALSE; ! i = linetabsize(ml_get_curline()); if (cap->count0 > 0 && cap->count0 <= 100) coladvance((colnr_T)(i * cap->count0 / 100)); else --- 6005,6011 ---- { oap->motion_type = MCHAR; oap->inclusive = FALSE; ! i = linetabsize_str(ml_get_curline()); if (cap->count0 > 0 && cap->count0 <= 100) coladvance((colnr_T)(i * cap->count0 / 100)); else *** ../vim-9.0.0750/src/ops.c 2022-10-08 17:55:29.231208875 +0100 --- src/ops.c 2022-10-14 14:46:33.474978034 +0100 *************** *** 3261,3267 **** col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1, (int)curwin->w_virtcol + 1); col_print(buf2, sizeof(buf2), (int)STRLEN(p), ! linetabsize(p)); if (char_count_cursor == byte_count_cursor && char_count == byte_count) --- 3261,3267 ---- col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1, (int)curwin->w_virtcol + 1); col_print(buf2, sizeof(buf2), (int)STRLEN(p), ! linetabsize_str(p)); if (char_count_cursor == byte_count_cursor && char_count == byte_count) *** ../vim-9.0.0750/src/popupwin.c 2022-10-07 14:31:04.320852668 +0100 --- src/popupwin.c 2022-10-14 14:49:47.334976190 +0100 *************** *** 1403,1410 **** // "margin_width" is added to "len" where it matters. if (wp->w_width < maxwidth) wp->w_width = maxwidth; ! len = win_linetabsize(wp, lnum, ml_get_buf(wp->w_buffer, lnum, FALSE), ! (colnr_T)MAXCOL); wp->w_width = w_width; if (wp->w_p_wrap) --- 1403,1409 ---- // "margin_width" is added to "len" where it matters. if (wp->w_width < maxwidth) wp->w_width = maxwidth; ! len = linetabsize(wp, lnum); wp->w_width = w_width; if (wp->w_p_wrap) *** ../vim-9.0.0750/src/version.c 2022-10-14 17:04:05.891675444 +0100 --- src/version.c 2022-10-14 20:07:07.147512335 +0100 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 751, /**/ -- ARTHUR: Go on, Bors, chop its head off. BORS: Right. Silly little bleeder. One rabbit stew coming up. "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/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///