mirror of
https://github.com/neovim/neovim.git
synced 2025-12-16 19:35:37 +00:00
Merge pull request #9586 from bfredl/screencleanup
screen: cleanup allocation and scrolling
This commit is contained in:
@@ -300,7 +300,7 @@ int main(int argc, char **argv)
|
|||||||
assert(p_ch >= 0 && Rows >= p_ch && Rows - p_ch <= INT_MAX);
|
assert(p_ch >= 0 && Rows >= p_ch && Rows - p_ch <= INT_MAX);
|
||||||
cmdline_row = (int)(Rows - p_ch);
|
cmdline_row = (int)(Rows - p_ch);
|
||||||
msg_row = cmdline_row;
|
msg_row = cmdline_row;
|
||||||
screenalloc(false); // allocate screen buffers
|
screenalloc(); // allocate screen buffers
|
||||||
set_init_2(headless_mode);
|
set_init_2(headless_mode);
|
||||||
TIME_MSG("inits 2");
|
TIME_MSG("inits 2");
|
||||||
|
|
||||||
|
|||||||
@@ -946,9 +946,9 @@ void wait_return(int redraw)
|
|||||||
c = CAR; /* no need for a return in ex mode */
|
c = CAR; /* no need for a return in ex mode */
|
||||||
got_int = FALSE;
|
got_int = FALSE;
|
||||||
} else {
|
} else {
|
||||||
/* Make sure the hit-return prompt is on screen when 'guioptions' was
|
// Make sure the hit-return prompt is on screen when 'guioptions' was
|
||||||
* just changed. */
|
// just changed.
|
||||||
screenalloc(false);
|
screenalloc();
|
||||||
|
|
||||||
State = HITRETURN;
|
State = HITRETURN;
|
||||||
setmouse();
|
setmouse();
|
||||||
@@ -2392,9 +2392,8 @@ static int do_more_prompt(int typed_char)
|
|||||||
mp_last = msg_sb_start(mp_last->sb_prev);
|
mp_last = msg_sb_start(mp_last->sb_prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toscroll == -1
|
if (toscroll == -1) {
|
||||||
&& grid_ins_lines(&default_grid, 0, 1, (int)Rows,
|
grid_ins_lines(&default_grid, 0, 1, (int)Rows, 0, (int)Columns);
|
||||||
0, (int)Columns) == OK) {
|
|
||||||
grid_fill(&default_grid, 0, 1, 0, (int)Columns, ' ', ' ', 0);
|
grid_fill(&default_grid, 0, 1, 0, (int)Columns, ' ', ' ', 0);
|
||||||
// display line at top
|
// display line at top
|
||||||
(void)disp_sb_line(0, mp);
|
(void)disp_sb_line(0, mp);
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ void update_topline(void)
|
|||||||
|
|
||||||
// If there is no valid screen and when the window height is zero just use
|
// If there is no valid screen and when the window height is zero just use
|
||||||
// the cursor line.
|
// the cursor line.
|
||||||
if (!screen_valid(true) || curwin->w_height_inner == 0) {
|
if (!default_grid.chars || curwin->w_height_inner == 0) {
|
||||||
curwin->w_topline = curwin->w_cursor.lnum;
|
curwin->w_topline = curwin->w_cursor.lnum;
|
||||||
curwin->w_botline = curwin->w_topline;
|
curwin->w_botline = curwin->w_topline;
|
||||||
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
|
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
|
||||||
@@ -925,12 +925,9 @@ void curs_columns(
|
|||||||
curwin->w_wrow -= extra;
|
curwin->w_wrow -= extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extra could be either positive or negative
|
||||||
extra = ((int)prev_skipcol - (int)curwin->w_skipcol) / width;
|
extra = ((int)prev_skipcol - (int)curwin->w_skipcol) / width;
|
||||||
if (extra > 0) {
|
win_scroll_lines(curwin, 0, extra);
|
||||||
win_ins_lines(curwin, 0, extra);
|
|
||||||
} else if (extra < 0) {
|
|
||||||
win_del_lines(curwin, 0, -extra);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
curwin->w_skipcol = 0;
|
curwin->w_skipcol = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -274,9 +274,10 @@ void update_screen(int type)
|
|||||||
static int did_intro = FALSE;
|
static int did_intro = FALSE;
|
||||||
int did_one;
|
int did_one;
|
||||||
|
|
||||||
/* Don't do anything if the screen structures are (not yet) valid. */
|
// Don't do anything if the screen structures are (not yet) valid.
|
||||||
if (!screen_valid(TRUE))
|
if (!default_grid.chars) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (must_redraw) {
|
if (must_redraw) {
|
||||||
if (type < must_redraw) /* use maximal type */
|
if (type < must_redraw) /* use maximal type */
|
||||||
@@ -335,10 +336,8 @@ void update_screen(int type)
|
|||||||
type = CLEAR;
|
type = CLEAR;
|
||||||
} else if (type != CLEAR) {
|
} else if (type != CLEAR) {
|
||||||
check_for_delay(false);
|
check_for_delay(false);
|
||||||
if (grid_ins_lines(&default_grid, 0, msg_scrolled, (int)Rows,
|
grid_ins_lines(&default_grid, 0, msg_scrolled, (int)Rows,
|
||||||
0, (int)Columns) == FAIL) {
|
0, (int)Columns);
|
||||||
type = CLEAR;
|
|
||||||
}
|
|
||||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||||
if (wp->w_winrow < msg_scrolled) {
|
if (wp->w_winrow < msg_scrolled) {
|
||||||
if (W_ENDROW(wp) > msg_scrolled
|
if (W_ENDROW(wp) > msg_scrolled
|
||||||
@@ -828,15 +827,15 @@ static void win_update(win_T *wp)
|
|||||||
// Try to insert the correct number of lines.
|
// Try to insert the correct number of lines.
|
||||||
// If not the last window, delete the lines at the bottom.
|
// If not the last window, delete the lines at the bottom.
|
||||||
// win_ins_lines may fail when the terminal can't do it.
|
// win_ins_lines may fail when the terminal can't do it.
|
||||||
if (win_ins_lines(wp, 0, i) == OK) {
|
win_scroll_lines(wp, 0, i);
|
||||||
if (wp->w_lines_valid != 0) {
|
if (wp->w_lines_valid != 0) {
|
||||||
/* Need to update rows that are new, stop at the
|
// Need to update rows that are new, stop at the
|
||||||
* first one that scrolled down. */
|
// first one that scrolled down.
|
||||||
top_end = i;
|
top_end = i;
|
||||||
scrolled_down = TRUE;
|
scrolled_down = true;
|
||||||
|
|
||||||
/* Move the entries that were scrolled, disable
|
// Move the entries that were scrolled, disable
|
||||||
* the entries for the lines to be redrawn. */
|
// the entries for the lines to be redrawn.
|
||||||
if ((wp->w_lines_valid += j) > wp->w_grid.Rows) {
|
if ((wp->w_lines_valid += j) > wp->w_grid.Rows) {
|
||||||
wp->w_lines_valid = wp->w_grid.Rows;
|
wp->w_lines_valid = wp->w_grid.Rows;
|
||||||
}
|
}
|
||||||
@@ -847,12 +846,12 @@ static void win_update(win_T *wp)
|
|||||||
wp->w_lines[idx--].wl_valid = false;
|
wp->w_lines[idx--].wl_valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
mid_start = 0; /* redraw all lines */
|
mid_start = 0; // redraw all lines
|
||||||
} else
|
}
|
||||||
mid_start = 0; /* redraw all lines */
|
} else {
|
||||||
} else
|
mid_start = 0; // redraw all lines
|
||||||
mid_start = 0; /* redraw all lines */
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* New topline is at or below old topline: May scroll up.
|
* New topline is at or below old topline: May scroll up.
|
||||||
@@ -889,11 +888,8 @@ static void win_update(win_T *wp)
|
|||||||
/* ... but don't delete new filler lines. */
|
/* ... but don't delete new filler lines. */
|
||||||
row -= wp->w_topfill;
|
row -= wp->w_topfill;
|
||||||
if (row > 0) {
|
if (row > 0) {
|
||||||
if (win_del_lines(wp, 0, row) == OK) {
|
win_scroll_lines(wp, 0, -row);
|
||||||
bot_start = wp->w_grid.Rows - row;
|
bot_start = wp->w_grid.Rows - row;
|
||||||
} else {
|
|
||||||
mid_start = 0; // redraw all lines
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ((row == 0 || bot_start < 999) && wp->w_lines_valid != 0) {
|
if ((row == 0 || bot_start < 999) && wp->w_lines_valid != 0) {
|
||||||
/*
|
/*
|
||||||
@@ -1148,7 +1144,7 @@ static void win_update(win_T *wp)
|
|||||||
// Update a line when it is in an area that needs updating, when it
|
// Update a line when it is in an area that needs updating, when it
|
||||||
// has changes or w_lines[idx] is invalid.
|
// has changes or w_lines[idx] is invalid.
|
||||||
// "bot_start" may be halfway a wrapped line after using
|
// "bot_start" may be halfway a wrapped line after using
|
||||||
// win_del_lines(), check if the current line includes it.
|
// win_scroll_lines(), check if the current line includes it.
|
||||||
// When syntax folding is being used, the saved syntax states will
|
// When syntax folding is being used, the saved syntax states will
|
||||||
// already have been updated, we can't see where the syntax state is
|
// already have been updated, we can't see where the syntax state is
|
||||||
// the same again, just update until the end of the window.
|
// the same again, just update until the end of the window.
|
||||||
@@ -1244,12 +1240,9 @@ static void win_update(win_T *wp)
|
|||||||
if (row - xtra_rows >= wp->w_grid.Rows - 2) {
|
if (row - xtra_rows >= wp->w_grid.Rows - 2) {
|
||||||
mod_bot = MAXLNUM;
|
mod_bot = MAXLNUM;
|
||||||
} else {
|
} else {
|
||||||
if (win_del_lines(wp, row, -xtra_rows) == FAIL) {
|
win_scroll_lines(wp, row, xtra_rows);
|
||||||
mod_bot = MAXLNUM;
|
|
||||||
} else {
|
|
||||||
bot_start = wp->w_grid.Rows + xtra_rows;
|
bot_start = wp->w_grid.Rows + xtra_rows;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if (xtra_rows > 0) {
|
} else if (xtra_rows > 0) {
|
||||||
/* May scroll text down. If there is not enough
|
/* May scroll text down. If there is not enough
|
||||||
* remaining text of scrolling fails, must redraw the
|
* remaining text of scrolling fails, must redraw the
|
||||||
@@ -1257,9 +1250,8 @@ static void win_update(win_T *wp)
|
|||||||
if (row + xtra_rows >= wp->w_grid.Rows - 2) {
|
if (row + xtra_rows >= wp->w_grid.Rows - 2) {
|
||||||
mod_bot = MAXLNUM;
|
mod_bot = MAXLNUM;
|
||||||
} else {
|
} else {
|
||||||
if (win_ins_lines(wp, row + old_rows, xtra_rows) == FAIL) {
|
win_scroll_lines(wp, row + old_rows, xtra_rows);
|
||||||
mod_bot = MAXLNUM;
|
if (top_end > row + old_rows) {
|
||||||
} else if (top_end > row + old_rows) {
|
|
||||||
// Scrolled the part at the top that requires
|
// Scrolled the part at the top that requires
|
||||||
// updating down.
|
// updating down.
|
||||||
top_end += xtra_rows;
|
top_end += xtra_rows;
|
||||||
@@ -5813,7 +5805,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// nothing to do
|
// nothing to do
|
||||||
if (grid->chars == NULL || start_row >= end_row || start_col >= end_col) {
|
if (start_row >= end_row || start_col >= end_col) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5902,18 +5894,6 @@ void check_for_delay(int check_msg_scroll)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* screen_valid - allocate screen buffers if size changed
|
|
||||||
* If "doclear" is TRUE: clear screen if it has been resized.
|
|
||||||
* Returns TRUE if there is a valid screen to write to.
|
|
||||||
* Returns FALSE when starting up and screen not initialized yet.
|
|
||||||
*/
|
|
||||||
int screen_valid(int doclear)
|
|
||||||
{
|
|
||||||
screenalloc(doclear); // allocate screen buffers if size changed
|
|
||||||
return default_grid.chars != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// (Re)allocates a window grid if size changed while in ext_multigrid mode.
|
/// (Re)allocates a window grid if size changed while in ext_multigrid mode.
|
||||||
/// Updates size, offsets and handle for the grid regardless.
|
/// Updates size, offsets and handle for the grid regardless.
|
||||||
///
|
///
|
||||||
@@ -5989,7 +5969,7 @@ void grid_assign_handle(ScreenGrid *grid)
|
|||||||
/// default_grid.Columns to access items in default_grid.chars[]. Use Rows
|
/// default_grid.Columns to access items in default_grid.chars[]. Use Rows
|
||||||
/// and Columns for positioning text etc. where the final size of the shell is
|
/// and Columns for positioning text etc. where the final size of the shell is
|
||||||
/// needed.
|
/// needed.
|
||||||
void screenalloc(bool doclear)
|
void screenalloc(void)
|
||||||
{
|
{
|
||||||
static bool entered = false; // avoid recursiveness
|
static bool entered = false; // avoid recursiveness
|
||||||
int retry_count = 0;
|
int retry_count = 0;
|
||||||
@@ -6041,7 +6021,7 @@ retry:
|
|||||||
// Continuing with the old arrays may result in a crash, because the
|
// Continuing with the old arrays may result in a crash, because the
|
||||||
// size is wrong.
|
// size is wrong.
|
||||||
|
|
||||||
grid_alloc(&default_grid, Rows, Columns, !doclear, true);
|
grid_alloc(&default_grid, Rows, Columns, true, true);
|
||||||
StlClickDefinition *new_tab_page_click_defs = xcalloc(
|
StlClickDefinition *new_tab_page_click_defs = xcalloc(
|
||||||
(size_t)Columns, sizeof(*new_tab_page_click_defs));
|
(size_t)Columns, sizeof(*new_tab_page_click_defs));
|
||||||
|
|
||||||
@@ -6055,10 +6035,7 @@ retry:
|
|||||||
default_grid.col_offset = 0;
|
default_grid.col_offset = 0;
|
||||||
default_grid.handle = DEFAULT_GRID_HANDLE;
|
default_grid.handle = DEFAULT_GRID_HANDLE;
|
||||||
|
|
||||||
must_redraw = CLEAR; /* need to clear the screen later */
|
must_redraw = CLEAR; // need to clear the screen later
|
||||||
if (doclear)
|
|
||||||
screenclear2();
|
|
||||||
|
|
||||||
|
|
||||||
entered = FALSE;
|
entered = FALSE;
|
||||||
--RedrawingDisabled;
|
--RedrawingDisabled;
|
||||||
@@ -6165,13 +6142,9 @@ void clear_tab_page_click_defs(StlClickDefinition *const tpcd,
|
|||||||
|
|
||||||
void screenclear(void)
|
void screenclear(void)
|
||||||
{
|
{
|
||||||
check_for_delay(FALSE);
|
check_for_delay(false);
|
||||||
screenalloc(false); /* allocate screen buffers if size changed */
|
screenalloc(); // allocate screen buffers if size changed
|
||||||
screenclear2(); /* clear the screen */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void screenclear2(void)
|
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (starting == NO_SCREEN || default_grid.chars == NULL) {
|
if (starting == NO_SCREEN || default_grid.chars == NULL) {
|
||||||
@@ -6265,42 +6238,28 @@ void setcursor(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert 'line_count' lines at 'row' in window 'wp'.
|
/// Scroll 'line_count' lines at 'row' in window 'wp'.
|
||||||
/// Returns FAIL if the lines are not inserted, OK for success.
|
///
|
||||||
int win_ins_lines(win_T *wp, int row, int line_count)
|
/// Positive `line_count' means scrolling down, so that more space is available
|
||||||
|
/// at 'row'. Negative `line_count` implies deleting lines at `row`.
|
||||||
|
void win_scroll_lines(win_T *wp, int row, int line_count)
|
||||||
{
|
{
|
||||||
return win_do_lines(wp, row, line_count, false);
|
if (!redrawing() || line_count == 0) {
|
||||||
}
|
return;
|
||||||
|
|
||||||
/// Delete "line_count" window lines at "row" in window "wp".
|
|
||||||
/// Return OK for success, FAIL if the lines are not deleted.
|
|
||||||
int win_del_lines(win_T *wp, int row, int line_count)
|
|
||||||
{
|
|
||||||
return win_do_lines(wp, row, line_count, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Common code for win_ins_lines() and win_del_lines().
|
|
||||||
// Returns OK or FAIL when the work has been done.
|
|
||||||
static int win_do_lines(win_T *wp, int row, int line_count, int del)
|
|
||||||
{
|
|
||||||
if (!redrawing() || line_count <= 0) {
|
|
||||||
return FAIL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No lines are being moved, just draw over the entire area
|
// No lines are being moved, just draw over the entire area
|
||||||
if (row + line_count >= wp->w_grid.Rows) {
|
if (row + abs(line_count) >= wp->w_grid.Rows) {
|
||||||
return OK;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int retval;
|
if (line_count < 0) {
|
||||||
if (del) {
|
grid_del_lines(&wp->w_grid, row, -line_count,
|
||||||
retval = grid_del_lines(&wp->w_grid, row, line_count,
|
|
||||||
wp->w_grid.Rows, 0, wp->w_grid.Columns);
|
wp->w_grid.Rows, 0, wp->w_grid.Columns);
|
||||||
} else {
|
} else {
|
||||||
retval = grid_ins_lines(&wp->w_grid, row, line_count,
|
grid_ins_lines(&wp->w_grid, row, line_count,
|
||||||
wp->w_grid.Rows, 0, wp->w_grid.Columns);
|
wp->w_grid.Rows, 0, wp->w_grid.Columns);
|
||||||
}
|
}
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6320,9 +6279,7 @@ static int win_do_lines(win_T *wp, int row, int line_count, int del)
|
|||||||
/// 'col' is the column from with we start inserting.
|
/// 'col' is the column from with we start inserting.
|
||||||
//
|
//
|
||||||
/// 'row', 'col' and 'end' are relative to the start of the region.
|
/// 'row', 'col' and 'end' are relative to the start of the region.
|
||||||
///
|
void grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
|
||||||
/// @return FAIL for failure, OK for success.
|
|
||||||
int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
|
|
||||||
int width)
|
int width)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -6334,8 +6291,8 @@ int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
|
|||||||
row += row_off;
|
row += row_off;
|
||||||
end += row_off;
|
end += row_off;
|
||||||
|
|
||||||
if (!screen_valid(TRUE) || line_count <= 0) {
|
if (line_count <= 0) {
|
||||||
return FAIL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shift line_offset[] line_count down to reflect the inserted lines.
|
// Shift line_offset[] line_count down to reflect the inserted lines.
|
||||||
@@ -6365,16 +6322,14 @@ int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
|
|||||||
|
|
||||||
ui_call_grid_scroll(grid->handle, row, end, col, col+width, -line_count, 0);
|
ui_call_grid_scroll(grid->handle, row, end, col, col+width, -line_count, 0);
|
||||||
|
|
||||||
return OK;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// delete lines on the screen and move lines up.
|
/// delete lines on the screen and move lines up.
|
||||||
/// 'end' is the line after the scrolled part. Normally it is Rows.
|
/// 'end' is the line after the scrolled part. Normally it is Rows.
|
||||||
/// When scrolling region used 'off' is the offset from the top for the region.
|
/// When scrolling region used 'off' is the offset from the top for the region.
|
||||||
/// 'row' and 'end' are relative to the start of the region.
|
/// 'row' and 'end' are relative to the start of the region.
|
||||||
///
|
void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
|
||||||
/// Return OK for success, FAIL if the lines are not deleted.
|
|
||||||
int grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
|
|
||||||
int width)
|
int width)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
@@ -6386,8 +6341,8 @@ int grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
|
|||||||
row += row_off;
|
row += row_off;
|
||||||
end += row_off;
|
end += row_off;
|
||||||
|
|
||||||
if (!screen_valid(TRUE) || line_count <= 0) {
|
if (line_count <= 0) {
|
||||||
return FAIL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now shift line_offset[] line_count up to reflect the deleted lines.
|
// Now shift line_offset[] line_count up to reflect the deleted lines.
|
||||||
@@ -6418,7 +6373,7 @@ int grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
|
|||||||
|
|
||||||
ui_call_grid_scroll(grid->handle, row, end, col, col+width, line_count, 0);
|
ui_call_grid_scroll(grid->handle, row, end, col, col+width, line_count, 0);
|
||||||
|
|
||||||
return OK;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -7186,7 +7141,7 @@ void screen_resize(int width, int height)
|
|||||||
*/
|
*/
|
||||||
if (State == ASKMORE || State == EXTERNCMD || State == CONFIRM
|
if (State == ASKMORE || State == EXTERNCMD || State == CONFIRM
|
||||||
|| exmode_active) {
|
|| exmode_active) {
|
||||||
screenalloc(false);
|
screenalloc();
|
||||||
repeat_message();
|
repeat_message();
|
||||||
} else {
|
} else {
|
||||||
if (curwin->w_p_scb)
|
if (curwin->w_p_scb)
|
||||||
|
|||||||
Reference in New Issue
Block a user