comparison src/window.c @ 30624:f2f35161d75a v9.0.0647

patch 9.0.0647: the 'splitscroll' option is not a good name Commit: https://github.com/vim/vim/commit/13ece2ae1d09009d3fb8acf858c288e7848ecdac Author: Luuk van Baal <luukvbaal@gmail.com> Date: Mon Oct 3 15:28:08 2022 +0100 patch 9.0.0647: the 'splitscroll' option is not a good name Problem: The 'splitscroll' option is not a good name. Solution: Rename 'splitscroll' to 'splitkeep' and make it a string option, also supporting "topline". (Luuk van Baal, closes #11258)
author Bram Moolenaar <Bram@vim.org>
date Mon, 03 Oct 2022 16:30:04 +0200
parents 66de6909e102
children 101f08b49ed3
comparison
equal deleted inserted replaced
30623:22b985817601 30624:f2f35161d75a
1323 */ 1323 */
1324 if (do_equal || dir != 0) 1324 if (do_equal || dir != 0)
1325 win_equal(wp, TRUE, 1325 win_equal(wp, TRUE,
1326 (flags & WSP_VERT) ? (dir == 'v' ? 'b' : 'h') 1326 (flags & WSP_VERT) ? (dir == 'v' ? 'b' : 'h')
1327 : dir == 'h' ? 'b' : 'v'); 1327 : dir == 'h' ? 'b' : 'v');
1328 else if (!p_spsc && wp != aucmd_win) 1328 else if (*p_spk != 'c' && wp != aucmd_win)
1329 win_fix_scroll(FALSE); 1329 win_fix_scroll(FALSE);
1330 1330
1331 // Don't change the window height/width to 'winheight' / 'winwidth' if a 1331 // Don't change the window height/width to 'winheight' / 'winwidth' if a
1332 // size was given. 1332 // size was given.
1333 if (flags & WSP_VERT) 1333 if (flags & WSP_VERT)
1409 newp->w_localdir = (oldp->w_localdir == NULL) 1409 newp->w_localdir = (oldp->w_localdir == NULL)
1410 ? NULL : vim_strsave(oldp->w_localdir); 1410 ? NULL : vim_strsave(oldp->w_localdir);
1411 newp->w_prevdir = (oldp->w_prevdir == NULL) 1411 newp->w_prevdir = (oldp->w_prevdir == NULL)
1412 ? NULL : vim_strsave(oldp->w_prevdir); 1412 ? NULL : vim_strsave(oldp->w_prevdir);
1413 1413
1414 if (!p_spsc) 1414 if (*p_spk != 'c')
1415 { 1415 {
1416 newp->w_botline = oldp->w_botline; 1416 newp->w_botline = oldp->w_botline;
1417 newp->w_prev_height = oldp->w_height - WINBAR_HEIGHT(oldp); 1417 newp->w_prev_height = oldp->w_height - WINBAR_HEIGHT(oldp);
1418 newp->w_prev_winrow = oldp->w_winrow + 2 * WINBAR_HEIGHT(oldp); 1418 newp->w_prev_winrow = oldp->w_winrow + 2 * WINBAR_HEIGHT(oldp);
1419 } 1419 }
1923 if (dir == 0) 1923 if (dir == 0)
1924 dir = *p_ead; 1924 dir = *p_ead;
1925 win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current, 1925 win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current,
1926 topframe, dir, 0, tabline_height(), 1926 topframe, dir, 0, tabline_height(),
1927 (int)Columns, topframe->fr_height); 1927 (int)Columns, topframe->fr_height);
1928 if (!p_spsc && next_curwin != aucmd_win) 1928 if (*p_spk != 'c' && next_curwin != aucmd_win)
1929 win_fix_scroll(TRUE); 1929 win_fix_scroll(TRUE);
1930 } 1930 }
1931 1931
1932 /* 1932 /*
1933 * Set a frame to a new position and height, spreading the available room 1933 * Set a frame to a new position and height, spreading the available room
2731 // only resize that frame. Otherwise resize all windows. 2731 // only resize that frame. Otherwise resize all windows.
2732 win_equal(curwin, curwin->w_frame->fr_parent == win_frame, dir); 2732 win_equal(curwin, curwin->w_frame->fr_parent == win_frame, dir);
2733 else 2733 else
2734 { 2734 {
2735 win_comp_pos(); 2735 win_comp_pos();
2736 if (!p_spsc) 2736 if (*p_spk != 'c')
2737 win_fix_scroll(FALSE); 2737 win_fix_scroll(FALSE);
2738 } 2738 }
2739 if (close_curwin) 2739 if (close_curwin)
2740 { 2740 {
2741 // Pass WEE_ALLOW_PARSE_MESSAGES to decrement dont_parse_messages 2741 // Pass WEE_ALLOW_PARSE_MESSAGES to decrement dont_parse_messages
4929 if ((flags & WEE_UNDO_SYNC) && curbuf != wp->w_buffer) 4929 if ((flags & WEE_UNDO_SYNC) && curbuf != wp->w_buffer)
4930 u_sync(FALSE); 4930 u_sync(FALSE);
4931 4931
4932 // Might need to scroll the old window before switching, e.g., when the 4932 // Might need to scroll the old window before switching, e.g., when the
4933 // cursor was moved. 4933 // cursor was moved.
4934 if (p_spsc) 4934 if (*p_spk == 'c')
4935 update_topline(); 4935 update_topline();
4936 4936
4937 // may have to copy the buffer options when 'cpo' contains 'S' 4937 // may have to copy the buffer options when 'cpo' contains 'S'
4938 if (wp->w_buffer != curbuf) 4938 if (wp->w_buffer != curbuf)
4939 buf_copy_options(wp->w_buffer, BCO_ENTER | BCO_NOHELP); 4939 buf_copy_options(wp->w_buffer, BCO_ENTER | BCO_NOHELP);
4945 curwin = wp; 4945 curwin = wp;
4946 curbuf = wp->w_buffer; 4946 curbuf = wp->w_buffer;
4947 check_cursor(); 4947 check_cursor();
4948 if (!virtual_active()) 4948 if (!virtual_active())
4949 curwin->w_cursor.coladd = 0; 4949 curwin->w_cursor.coladd = 0;
4950 if (p_spsc) // assume cursor position needs updating. 4950 if (*p_spk == 'c') // assume cursor position needs updating
4951 changed_line_abv_curs(); 4951 changed_line_abv_curs();
4952 else 4952 else
4953 win_fix_cursor(TRUE); 4953 win_fix_cursor(TRUE);
4954 4954
4955 // Now it is OK to parse messages again, which may be needed in 4955 // Now it is OK to parse messages again, which may be needed in
5066 /* 5066 /*
5067 * Allocate a window structure and link it in the window list when "hidden" is 5067 * Allocate a window structure and link it in the window list when "hidden" is
5068 * FALSE. 5068 * FALSE.
5069 */ 5069 */
5070 static win_T * 5070 static win_T *
5071 win_alloc(win_T *after UNUSED, int hidden UNUSED) 5071 win_alloc(win_T *after, int hidden)
5072 { 5072 {
5073 win_T *new_wp; 5073 win_T *new_wp;
5074 5074
5075 /* 5075 /*
5076 * allocate window structure and linesizes arrays 5076 * allocate window structure and linesizes arrays
5478 5478
5479 (void)win_comp_pos(); // recompute w_winrow and w_wincol 5479 (void)win_comp_pos(); // recompute w_winrow and w_wincol
5480 compute_cmdrow(); 5480 compute_cmdrow();
5481 curtab->tp_ch_used = p_ch; 5481 curtab->tp_ch_used = p_ch;
5482 5482
5483 if (!p_spsc && !skip_win_fix_scroll) 5483 if (*p_spk != 'c' && !skip_win_fix_scroll)
5484 win_fix_scroll(TRUE); 5484 win_fix_scroll(TRUE);
5485 5485
5486 #if 0 5486 #if 0
5487 // Disabled: don't want making the screen smaller make a window larger. 5487 // Disabled: don't want making the screen smaller make a window larger.
5488 if (p_ea) 5488 if (p_ea)
5685 screen_fill(row, cmdline_row, 0, (int)Columns, ' ', ' ', 0); 5685 screen_fill(row, cmdline_row, 0, (int)Columns, ' ', ' ', 0);
5686 cmdline_row = row; 5686 cmdline_row = row;
5687 msg_row = row; 5687 msg_row = row;
5688 msg_col = 0; 5688 msg_col = 0;
5689 5689
5690 if (!p_spsc) 5690 if (*p_spk != 'c')
5691 win_fix_scroll(TRUE); 5691 win_fix_scroll(TRUE);
5692 5692
5693 redraw_all_later(UPD_NOT_VALID); 5693 redraw_all_later(UPD_NOT_VALID);
5694 } 5694 }
5695 5695
6216 screen_fill(row, cmdline_row, 0, (int)Columns, ' ', ' ', 0); 6216 screen_fill(row, cmdline_row, 0, (int)Columns, ' ', ' ', 0);
6217 cmdline_row = row; 6217 cmdline_row = row;
6218 p_ch = MAX(Rows - cmdline_row, 1); 6218 p_ch = MAX(Rows - cmdline_row, 1);
6219 curtab->tp_ch_used = p_ch; 6219 curtab->tp_ch_used = p_ch;
6220 6220
6221 if (!p_spsc) 6221 if (*p_spk != 'c')
6222 win_fix_scroll(TRUE); 6222 win_fix_scroll(TRUE);
6223 6223
6224 redraw_all_later(UPD_SOME_VALID); 6224 redraw_all_later(UPD_SOME_VALID);
6225 showmode(); 6225 showmode();
6226 } 6226 }
6346 wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT 6346 wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT
6347 + FRACTION_MULT / 2) / (long)wp->w_height; 6347 + FRACTION_MULT / 2) / (long)wp->w_height;
6348 } 6348 }
6349 6349
6350 /* 6350 /*
6351 * Handle scroll position for 'nosplitscroll'. Replaces scroll_to_fraction() 6351 * Handle scroll position for 'splitkeep'. Replaces scroll_to_fraction()
6352 * call from win_new_height(). Instead we iterate over all windows in a 6352 * call from win_new_height(). Instead we iterate over all windows in a
6353 * tabpage and calculate the new scroll position. 6353 * tabpage and calculate the new scroll position.
6354 * TODO: Ensure this also works with wrapped lines. 6354 * TODO: Ensure this also works with wrapped lines.
6355 * Requires topline to be able to be set to a bufferline with some 6355 * Requires topline to be able to be set to a bufferline with some
6356 * offset(row-wise scrolling/smoothscroll). 6356 * offset(row-wise scrolling/smoothscroll).
6360 { 6360 {
6361 int diff; 6361 int diff;
6362 win_T *wp; 6362 win_T *wp;
6363 linenr_T lnum; 6363 linenr_T lnum;
6364 6364
6365 skip_update_topline = TRUE; // avoid scrolling in curs_columns() 6365 skip_update_topline = TRUE;
6366 FOR_ALL_WINDOWS(wp) 6366 FOR_ALL_WINDOWS(wp)
6367 { 6367 {
6368 // Skip when window height has not changed. 6368 // Skip when window height has not changed.
6369 if (wp->w_height != wp->w_prev_height) 6369 if (wp->w_height != wp->w_prev_height)
6370 { 6370 {
6371 // If window has moved update botline to keep the same screenlines. 6371 // If window has moved update botline to keep the same screenlines.
6372 if (wp->w_winrow != wp->w_prev_winrow) 6372 if (*p_spk == 's' && wp->w_winrow != wp->w_prev_winrow)
6373 { 6373 {
6374 lnum = wp->w_cursor.lnum; 6374 lnum = wp->w_cursor.lnum;
6375 diff = (wp->w_winrow - wp->w_prev_winrow) 6375 diff = (wp->w_winrow - wp->w_prev_winrow)
6376 + (wp->w_height - wp->w_prev_height); 6376 + (wp->w_height - wp->w_prev_height);
6377 wp->w_cursor.lnum = wp->w_botline - 1; 6377 wp->w_cursor.lnum = wp->w_botline - 1;
6401 else if (resize) 6401 else if (resize)
6402 win_fix_cursor(TRUE); 6402 win_fix_cursor(TRUE);
6403 } 6403 }
6404 6404
6405 /* 6405 /*
6406 * Make sure the cursor position is valid for 'nosplitscroll'. 6406 * Make sure the cursor position is valid for 'splitkeep'.
6407 * If it is not, put the cursor position in the jumplist and move it. 6407 * If it is not, put the cursor position in the jumplist and move it.
6408 * If we are not in normal mode, scroll to make valid instead. 6408 * If we are not in normal mode, scroll to make valid instead.
6409 */ 6409 */
6410 static void 6410 static void
6411 win_fix_cursor(int normal) 6411 win_fix_cursor(int normal)
6412 { 6412 {
6413 long so = get_scrolloff_value(); 6413 long so = get_scrolloff_value();
6414 win_T *wp = curwin; 6414 win_T *wp = curwin;
6415 linenr_T nlnum = 0; 6415 linenr_T nlnum = 0;
6416 linenr_T lnum = wp->w_cursor.lnum; 6416 linenr_T lnum = wp->w_cursor.lnum;
6417 linenr_T bot; 6417 linenr_T bot;
6418 linenr_T top; 6418 linenr_T top;
6419 6419
6420 if (wp->w_buffer->b_ml.ml_line_count < wp->w_height) 6420 if (wp->w_buffer->b_ml.ml_line_count < wp->w_height)
6421 return; 6421 return;
6422 #ifdef FEAT_CMDWIN 6422 #ifdef FEAT_CMDWIN
6423 if (skip_win_fix_cursor) 6423 if (skip_win_fix_cursor)
6427 so = MIN(wp->w_height / 2, so); 6427 so = MIN(wp->w_height / 2, so);
6428 wp->w_cursor.lnum = wp->w_topline; 6428 wp->w_cursor.lnum = wp->w_topline;
6429 top = cursor_down_inner(wp, so); 6429 top = cursor_down_inner(wp, so);
6430 wp->w_cursor.lnum = wp->w_botline - 1; 6430 wp->w_cursor.lnum = wp->w_botline - 1;
6431 bot = cursor_up_inner(wp, so); 6431 bot = cursor_up_inner(wp, so);
6432 wp->w_cursor.lnum = lnum;
6432 // Check if cursor position is above or below valid cursor range. 6433 // Check if cursor position is above or below valid cursor range.
6433 if (lnum > bot && (wp->w_botline - wp->w_buffer->b_ml.ml_line_count) != 1) 6434 if (lnum > bot && (wp->w_botline - wp->w_buffer->b_ml.ml_line_count) != 1)
6434 nlnum = bot; 6435 nlnum = bot;
6435 else if (lnum < top && wp->w_topline != 1) 6436 else if (lnum < top && wp->w_topline != 1)
6436 nlnum = (so == wp->w_height / 2) ? bot : top; 6437 nlnum = (so == wp->w_height / 2) ? bot : top;
6437 6438
6438 wp->w_cursor.lnum = lnum;
6439
6440 if (nlnum) // Cursor is invalid for current scroll position. 6439 if (nlnum) // Cursor is invalid for current scroll position.
6441 { 6440 {
6442 if (normal) // Save to jumplist and set cursor to avoid scrolling. 6441 if (normal) // Save to jumplist and set cursor to avoid scrolling.
6443 { 6442 {
6444 setmark('\''); 6443 setmark('\'');
6445 wp->w_cursor.lnum = nlnum; 6444 wp->w_cursor.lnum = nlnum;
6446 curs_columns(TRUE); // validate w_wrow
6447 } 6445 }
6448 else // Scroll instead when not in normal mode. 6446 else // Scroll instead when not in normal mode.
6449 { 6447 {
6450 wp->w_fraction = 0.5 * FRACTION_MULT; 6448 wp->w_fraction = (nlnum == bot) ? FRACTION_MULT : 0;
6451 scroll_to_fraction(wp, wp->w_prev_height); 6449 scroll_to_fraction(wp, wp->w_prev_height);
6452 validate_botline_win(curwin); 6450 validate_botline_win(curwin);
6453 } 6451 }
6454 } 6452 }
6455 } 6453 }
6472 if (wp->w_height == height) 6470 if (wp->w_height == height)
6473 return; // nothing to do 6471 return; // nothing to do
6474 6472
6475 if (wp->w_height > 0) 6473 if (wp->w_height > 0)
6476 { 6474 {
6477 if (wp == curwin && p_spsc) 6475 if (wp == curwin && *p_spk == 'c')
6478 // w_wrow needs to be valid. When setting 'laststatus' this may 6476 // w_wrow needs to be valid. When setting 'laststatus' this may
6479 // call win_new_height() recursively. 6477 // call win_new_height() recursively.
6480 validate_cursor(); 6478 validate_cursor();
6481 if (wp->w_height != prev_height) 6479 if (wp->w_height != prev_height)
6482 return; // Recursive call already changed the size, bail out here 6480 return; // Recursive call already changed the size, bail out here
6488 wp->w_height = height; 6486 wp->w_height = height;
6489 wp->w_skipcol = 0; 6487 wp->w_skipcol = 0;
6490 6488
6491 // There is no point in adjusting the scroll position when exiting. Some 6489 // There is no point in adjusting the scroll position when exiting. Some
6492 // values might be invalid. 6490 // values might be invalid.
6493 if (!exiting && p_spsc) 6491 if (!exiting && *p_spk == 'c')
6494 scroll_to_fraction(wp, prev_height); 6492 scroll_to_fraction(wp, prev_height);
6495 } 6493 }
6496 6494
6497 void 6495 void
6498 scroll_to_fraction(win_T *wp, int prev_height) 6496 scroll_to_fraction(win_T *wp, int prev_height)
6602 set_topline(wp, lnum); 6600 set_topline(wp, lnum);
6603 } 6601 }
6604 6602
6605 if (wp == curwin) 6603 if (wp == curwin)
6606 { 6604 {
6607 if (p_spsc && get_scrolloff_value()) 6605 if (get_scrolloff_value())
6608 update_topline(); 6606 update_topline();
6609 curs_columns(FALSE); // validate w_wrow 6607 curs_columns(FALSE); // validate w_wrow
6610 } 6608 }
6611 if (prev_height > 0) 6609 if (prev_height > 0)
6612 wp->w_prev_fraction_row = wp->w_wrow; 6610 wp->w_prev_fraction_row = wp->w_wrow;
6625 { 6623 {
6626 // Should we give an error if width < 0? 6624 // Should we give an error if width < 0?
6627 wp->w_width = width < 0 ? 0 : width; 6625 wp->w_width = width < 0 ? 0 : width;
6628 wp->w_lines_valid = 0; 6626 wp->w_lines_valid = 0;
6629 changed_line_abv_curs_win(wp); 6627 changed_line_abv_curs_win(wp);
6630 // Handled in win_fix_scroll() 6628 invalidate_botline_win(wp);
6631 if (p_spsc) 6629 if (wp == curwin)
6632 { 6630 {
6633 invalidate_botline_win(wp); 6631 skip_update_topline = (*p_spk != 'c');
6634 if (wp == curwin) 6632 update_topline();
6635 { 6633 curs_columns(TRUE); // validate w_wrow
6636 update_topline(); 6634 skip_update_topline = FALSE;
6637 curs_columns(TRUE); // validate w_wrow
6638 }
6639 } 6635 }
6640 redraw_win_later(wp, UPD_NOT_VALID); 6636 redraw_win_later(wp, UPD_NOT_VALID);
6641 wp->w_redr_status = TRUE; 6637 wp->w_redr_status = TRUE;
6642 } 6638 }
6643 6639