comparison src/move.c @ 32387:1ddef52ea786 v9.0.1525

patch 9.0.1525: 'smoothscroll' does not always work properly Commit: https://github.com/vim/vim/commit/3ce8c389155fc1257082cdb0cef7801b49f6aaf9 Author: Luuk van Baal <luukvbaal@gmail.com> Date: Mon May 8 15:51:14 2023 +0100 patch 9.0.1525: 'smoothscroll' does not always work properly Problem: 'smoothscroll' does not always work properly. Solution: Do not reset w_skipcol after it was intentionally set. (Luuk van Baal, closes #12360, closes #12199, closes #12323)
author Bram Moolenaar <Bram@vim.org>
date Mon, 08 May 2023 17:00:04 +0200
parents 9ac987a467d5
children f9d4988a86ef
comparison
equal deleted inserted replaced
32386:1714bba63e87 32387:1ddef52ea786
274 update_topline(void) 274 update_topline(void)
275 { 275 {
276 long line_count; 276 long line_count;
277 int halfheight; 277 int halfheight;
278 int n; 278 int n;
279 linenr_T old_topline;
280 #ifdef FEAT_DIFF
281 int old_topfill;
282 #endif
283 #ifdef FEAT_FOLDING 279 #ifdef FEAT_FOLDING
284 linenr_T lnum; 280 linenr_T lnum;
285 #endif 281 #endif
286 int check_topline = FALSE; 282 int check_topline = FALSE;
287 int check_botline = FALSE; 283 int check_botline = FALSE;
309 305
310 // When dragging with the mouse, don't scroll that quickly 306 // When dragging with the mouse, don't scroll that quickly
311 if (mouse_dragging > 0) 307 if (mouse_dragging > 0)
312 *so_ptr = mouse_dragging - 1; 308 *so_ptr = mouse_dragging - 1;
313 309
314 old_topline = curwin->w_topline; 310 linenr_T old_topline = curwin->w_topline;
315 #ifdef FEAT_DIFF 311 colnr_T old_skipcol = curwin->w_skipcol;
316 old_topfill = curwin->w_topfill; 312 #ifdef FEAT_DIFF
313 int old_topfill = curwin->w_topfill;
317 #endif 314 #endif
318 315
319 /* 316 /*
320 * If the buffer is empty, always set topline to 1. 317 * If the buffer is empty, always set topline to 1.
321 */ 318 */
514 #endif 511 #endif
515 ) 512 )
516 { 513 {
517 dollar_vcol = -1; 514 dollar_vcol = -1;
518 redraw_later(UPD_VALID); 515 redraw_later(UPD_VALID);
519 reset_skipcol(); 516
517 // Only reset w_skipcol if it was not just set to make cursor visible.
518 if (curwin->w_skipcol == old_skipcol)
519 reset_skipcol();
520 520
521 // May need to set w_skipcol when cursor in w_topline. 521 // May need to set w_skipcol when cursor in w_topline.
522 if (curwin->w_cursor.lnum == curwin->w_topline) 522 if (curwin->w_cursor.lnum == curwin->w_topline)
523 validate_cursor(); 523 validate_cursor();
524 } 524 }
2767 scroll_cursor_halfway(int atend, int prefer_above) 2767 scroll_cursor_halfway(int atend, int prefer_above)
2768 { 2768 {
2769 int above = 0; 2769 int above = 0;
2770 linenr_T topline; 2770 linenr_T topline;
2771 colnr_T skipcol = 0; 2771 colnr_T skipcol = 0;
2772 int set_skipcol = FALSE;
2773 #ifdef FEAT_DIFF 2772 #ifdef FEAT_DIFF
2774 int topfill = 0; 2773 int topfill = 0;
2775 #endif 2774 #endif
2776 int below = 0; 2775 int below = 0;
2777 int used; 2776 int used;
2796 #else 2795 #else
2797 used = plines(loff.lnum); 2796 used = plines(loff.lnum);
2798 #endif 2797 #endif
2799 topline = loff.lnum; 2798 topline = loff.lnum;
2800 2799
2801 int half_height = 0; 2800 int want_height;
2802 int smooth_scroll = FALSE; 2801 int smooth_scroll = FALSE;
2803 if (curwin->w_p_sms && curwin->w_p_wrap) 2802 if (curwin->w_p_sms && curwin->w_p_wrap)
2804 { 2803 {
2805 // 'smoothscroll' and 'wrap' are set 2804 // 'smoothscroll' and 'wrap' are set
2806 smooth_scroll = TRUE; 2805 smooth_scroll = TRUE;
2807 half_height = (curwin->w_height - used) / 2; 2806 if (atend)
2808 used = 0; 2807 {
2808 want_height = (curwin->w_height - used) / 2;
2809 used = 0;
2810 }
2811 else
2812 want_height = curwin->w_height;
2809 } 2813 }
2810 2814
2811 while (topline > 1) 2815 while (topline > 1)
2812 { 2816 {
2813 // If using smoothscroll, we can precisely scroll to the 2817 // If using smoothscroll, we can precisely scroll to the
2815 if (smooth_scroll) 2819 if (smooth_scroll)
2816 { 2820 {
2817 topline_back_winheight(&loff, FALSE); 2821 topline_back_winheight(&loff, FALSE);
2818 if (loff.height == MAXCOL) 2822 if (loff.height == MAXCOL)
2819 break; 2823 break;
2820 else 2824 used += loff.height;
2821 used += loff.height; 2825 if (!atend && boff.lnum < curbuf->b_ml.ml_line_count)
2822 if (used > half_height) 2826 {
2823 { 2827 botline_forw(&boff);
2824 if (used - loff.height < half_height) 2828 used += boff.height;
2829 }
2830 if (used > want_height)
2831 {
2832 if (used - loff.height < want_height)
2825 { 2833 {
2826 int plines_offset = used - half_height;
2827 loff.height -= plines_offset;
2828 used = half_height;
2829
2830 topline = loff.lnum; 2834 topline = loff.lnum;
2831 #ifdef FEAT_DIFF 2835 #ifdef FEAT_DIFF
2832 topfill = loff.fill; 2836 topfill = loff.fill;
2833 #endif 2837 #endif
2834 skipcol = skipcol_from_plines(curwin, plines_offset); 2838 skipcol = skipcol_from_plines(curwin, used - want_height);
2835 set_skipcol = TRUE;
2836 } 2839 }
2837 break; 2840 break;
2838 } 2841 }
2839 topline = loff.lnum; 2842 topline = loff.lnum;
2840 #ifdef FEAT_DIFF 2843 #ifdef FEAT_DIFF
2904 #ifdef FEAT_FOLDING 2907 #ifdef FEAT_FOLDING
2905 if (!hasFolding(topline, &curwin->w_topline, NULL)) 2908 if (!hasFolding(topline, &curwin->w_topline, NULL))
2906 #endif 2909 #endif
2907 { 2910 {
2908 if (curwin->w_topline != topline 2911 if (curwin->w_topline != topline
2909 || set_skipcol 2912 || skipcol != 0
2910 || curwin->w_skipcol != 0) 2913 || curwin->w_skipcol != 0)
2911 { 2914 {
2912 curwin->w_topline = topline; 2915 curwin->w_topline = topline;
2913 if (set_skipcol) 2916 if (skipcol != 0)
2914 { 2917 {
2915 curwin->w_skipcol = skipcol; 2918 curwin->w_skipcol = skipcol;
2916 redraw_later(UPD_NOT_VALID); 2919 redraw_later(UPD_NOT_VALID);
2917 } 2920 }
2918 else 2921 else