mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
tui: eliminate scrolling region data structure
The scrolling region is always local to a single grid_scroll event, use local variables and parameters instead. The invocation of reset_scroll_region in grid_resize is cargo-culted to use margin reset under exactly the same circumstances, not sure if it is necessary though.
This commit is contained in:
parent
1b8939d233
commit
edb26f2c65
@ -765,43 +765,31 @@ static void clear_region(UI *ui, int top, int bot, int left, int right,
|
|||||||
cursor_goto(ui, data->row, data->col);
|
cursor_goto(ui, data->row, data->col);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool can_use_scroll(UI * ui)
|
static void set_scroll_region(UI *ui, int top, int bot, int left, int right)
|
||||||
{
|
{
|
||||||
TUIData *data = ui->data;
|
TUIData *data = ui->data;
|
||||||
UGrid *grid = &data->grid;
|
UGrid *grid = &data->grid;
|
||||||
|
|
||||||
return data->scroll_region_is_full_screen
|
UNIBI_SET_NUM_VAR(data->params[0], top);
|
||||||
|| (data->can_change_scroll_region
|
UNIBI_SET_NUM_VAR(data->params[1], bot);
|
||||||
&& ((grid->left == 0 && grid->right == ui->width - 1)
|
|
||||||
|| data->can_set_lr_margin
|
|
||||||
|| data->can_set_left_right_margin));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_scroll_region(UI *ui)
|
|
||||||
{
|
|
||||||
TUIData *data = ui->data;
|
|
||||||
UGrid *grid = &data->grid;
|
|
||||||
|
|
||||||
UNIBI_SET_NUM_VAR(data->params[0], grid->top);
|
|
||||||
UNIBI_SET_NUM_VAR(data->params[1], grid->bot);
|
|
||||||
unibi_out(ui, unibi_change_scroll_region);
|
unibi_out(ui, unibi_change_scroll_region);
|
||||||
if (grid->left != 0 || grid->right != ui->width - 1) {
|
if (left != 0 || right != ui->width - 1) {
|
||||||
unibi_out_ext(ui, data->unibi_ext.enable_lr_margin);
|
unibi_out_ext(ui, data->unibi_ext.enable_lr_margin);
|
||||||
if (data->can_set_lr_margin) {
|
if (data->can_set_lr_margin) {
|
||||||
UNIBI_SET_NUM_VAR(data->params[0], grid->left);
|
UNIBI_SET_NUM_VAR(data->params[0], left);
|
||||||
UNIBI_SET_NUM_VAR(data->params[1], grid->right);
|
UNIBI_SET_NUM_VAR(data->params[1], right);
|
||||||
unibi_out(ui, unibi_set_lr_margin);
|
unibi_out(ui, unibi_set_lr_margin);
|
||||||
} else {
|
} else {
|
||||||
UNIBI_SET_NUM_VAR(data->params[0], grid->left);
|
UNIBI_SET_NUM_VAR(data->params[0], left);
|
||||||
unibi_out(ui, unibi_set_left_margin_parm);
|
unibi_out(ui, unibi_set_left_margin_parm);
|
||||||
UNIBI_SET_NUM_VAR(data->params[0], grid->right);
|
UNIBI_SET_NUM_VAR(data->params[0], right);
|
||||||
unibi_out(ui, unibi_set_right_margin_parm);
|
unibi_out(ui, unibi_set_right_margin_parm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unibi_goto(ui, grid->row, grid->col);
|
unibi_goto(ui, grid->row, grid->col);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reset_scroll_region(UI *ui)
|
static void reset_scroll_region(UI *ui, bool fullwidth)
|
||||||
{
|
{
|
||||||
TUIData *data = ui->data;
|
TUIData *data = ui->data;
|
||||||
UGrid *grid = &data->grid;
|
UGrid *grid = &data->grid;
|
||||||
@ -813,7 +801,7 @@ static void reset_scroll_region(UI *ui)
|
|||||||
UNIBI_SET_NUM_VAR(data->params[1], ui->height - 1);
|
UNIBI_SET_NUM_VAR(data->params[1], ui->height - 1);
|
||||||
unibi_out(ui, unibi_change_scroll_region);
|
unibi_out(ui, unibi_change_scroll_region);
|
||||||
}
|
}
|
||||||
if (grid->left != 0 || grid->right != ui->width - 1) {
|
if (!fullwidth) {
|
||||||
if (data->can_set_lr_margin) {
|
if (data->can_set_lr_margin) {
|
||||||
UNIBI_SET_NUM_VAR(data->params[0], 0);
|
UNIBI_SET_NUM_VAR(data->params[0], 0);
|
||||||
UNIBI_SET_NUM_VAR(data->params[1], ui->width - 1);
|
UNIBI_SET_NUM_VAR(data->params[1], ui->width - 1);
|
||||||
@ -850,7 +838,7 @@ static void tui_grid_resize(UI *ui, Integer g, Integer width, Integer height)
|
|||||||
unibi_out_ext(ui, data->unibi_ext.resize_screen);
|
unibi_out_ext(ui, data->unibi_ext.resize_screen);
|
||||||
// DECSLPP does not reset the scroll region.
|
// DECSLPP does not reset the scroll region.
|
||||||
if (data->scroll_region_is_full_screen) {
|
if (data->scroll_region_is_full_screen) {
|
||||||
reset_scroll_region(ui);
|
reset_scroll_region(ui, ui->width == grid->width);
|
||||||
}
|
}
|
||||||
} else { // Already handled the SIGWINCH signal; avoid double-resize.
|
} else { // Already handled the SIGWINCH signal; avoid double-resize.
|
||||||
got_winch = false;
|
got_winch = false;
|
||||||
@ -1008,28 +996,35 @@ static void tui_mode_change(UI *ui, String mode, Integer mode_idx)
|
|||||||
data->showing_mode = (ModeShape)mode_idx;
|
data->showing_mode = (ModeShape)mode_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tui_grid_scroll(UI *ui, Integer g, Integer top, Integer bot,
|
static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, Integer endrow,
|
||||||
Integer left, Integer right,
|
Integer startcol, Integer endcol,
|
||||||
Integer rows, Integer cols)
|
Integer rows, Integer cols)
|
||||||
{
|
{
|
||||||
TUIData *data = ui->data;
|
TUIData *data = ui->data;
|
||||||
UGrid *grid = &data->grid;
|
UGrid *grid = &data->grid;
|
||||||
ugrid_set_scroll_region(&data->grid, (int)top, (int)bot-1,
|
int top = (int)startrow, bot = (int)endrow-1;
|
||||||
(int)left, (int)right-1);
|
int left = (int)startcol, right = (int)endcol-1;
|
||||||
|
|
||||||
data->scroll_region_is_full_screen =
|
bool fullwidth = left == 0 && right == ui->width-1;
|
||||||
left == 0 && right == ui->width
|
data->scroll_region_is_full_screen = fullwidth
|
||||||
&& top == 0 && bot == ui->height;
|
&& top == 0 && bot == ui->height-1;
|
||||||
|
|
||||||
int clear_top, clear_bot;
|
int clear_top, clear_bot;
|
||||||
ugrid_scroll(grid, (int)rows, &clear_top, &clear_bot);
|
ugrid_scroll(grid, top, bot, left, right, (int)rows,
|
||||||
|
&clear_top, &clear_bot);
|
||||||
|
|
||||||
if (can_use_scroll(ui)) {
|
bool can_scroll = data->scroll_region_is_full_screen
|
||||||
|
|| (data->can_change_scroll_region
|
||||||
|
&& ((left == 0 && right == ui->width - 1)
|
||||||
|
|| data->can_set_lr_margin
|
||||||
|
|| data->can_set_left_right_margin));
|
||||||
|
|
||||||
|
if (can_scroll) {
|
||||||
// Change terminal scroll region and move cursor to the top
|
// Change terminal scroll region and move cursor to the top
|
||||||
if (!data->scroll_region_is_full_screen) {
|
if (!data->scroll_region_is_full_screen) {
|
||||||
set_scroll_region(ui);
|
set_scroll_region(ui, top, bot, left, right);
|
||||||
}
|
}
|
||||||
cursor_goto(ui, grid->top, grid->left);
|
cursor_goto(ui, top, left);
|
||||||
// also set default color attributes or some terminals can become funny
|
// also set default color attributes or some terminals can become funny
|
||||||
update_attrs(ui, data->clear_attrs);
|
update_attrs(ui, data->clear_attrs);
|
||||||
|
|
||||||
@ -1051,19 +1046,19 @@ static void tui_grid_scroll(UI *ui, Integer g, Integer top, Integer bot,
|
|||||||
|
|
||||||
// Restore terminal scroll region and cursor
|
// Restore terminal scroll region and cursor
|
||||||
if (!data->scroll_region_is_full_screen) {
|
if (!data->scroll_region_is_full_screen) {
|
||||||
reset_scroll_region(ui);
|
reset_scroll_region(ui, fullwidth);
|
||||||
}
|
}
|
||||||
cursor_goto(ui, data->row, data->col);
|
cursor_goto(ui, data->row, data->col);
|
||||||
|
|
||||||
if (!(data->bce || no_bg(ui, data->clear_attrs))) {
|
if (!(data->bce || no_bg(ui, data->clear_attrs))) {
|
||||||
// Scrolling will leave wrong background in the cleared area on non-BCE
|
// Scrolling will leave wrong background in the cleared area on non-BCE
|
||||||
// terminals. Update the cleared area.
|
// terminals. Update the cleared area.
|
||||||
clear_region(ui, clear_top, clear_bot, grid->left, grid->right,
|
clear_region(ui, clear_top, clear_bot, left, right,
|
||||||
data->clear_attrs);
|
data->clear_attrs);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Mark the entire scroll region as invalid for redrawing later
|
// Mark the entire scroll region as invalid for redrawing later
|
||||||
invalidate(ui, grid->top, grid->bot, grid->left, grid->right);
|
invalidate(ui, top, bot, left, right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,10 +32,6 @@ void ugrid_resize(UGrid *grid, int width, int height)
|
|||||||
grid->cells[i] = xcalloc((size_t)width, sizeof(UCell));
|
grid->cells[i] = xcalloc((size_t)width, sizeof(UCell));
|
||||||
}
|
}
|
||||||
|
|
||||||
grid->top = 0;
|
|
||||||
grid->bot = height - 1;
|
|
||||||
grid->left = 0;
|
|
||||||
grid->right = width - 1;
|
|
||||||
grid->row = grid->col = 0;
|
grid->row = grid->col = 0;
|
||||||
grid->width = width;
|
grid->width = width;
|
||||||
grid->height = height;
|
grid->height = height;
|
||||||
@ -57,25 +53,18 @@ void ugrid_goto(UGrid *grid, int row, int col)
|
|||||||
grid->col = col;
|
grid->col = col;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ugrid_set_scroll_region(UGrid *grid, int top, int bot, int left, int right)
|
void ugrid_scroll(UGrid *grid, int top, int bot, int left, int right,
|
||||||
{
|
int count, int *clear_top, int *clear_bot)
|
||||||
grid->top = top;
|
|
||||||
grid->bot = bot;
|
|
||||||
grid->left = left;
|
|
||||||
grid->right = right;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ugrid_scroll(UGrid *grid, int count, int *clear_top, int *clear_bot)
|
|
||||||
{
|
{
|
||||||
// Compute start/stop/step for the loop below
|
// Compute start/stop/step for the loop below
|
||||||
int start, stop, step;
|
int start, stop, step;
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
start = grid->top;
|
start = top;
|
||||||
stop = grid->bot - count + 1;
|
stop = bot - count + 1;
|
||||||
step = 1;
|
step = 1;
|
||||||
} else {
|
} else {
|
||||||
start = grid->bot;
|
start = bot;
|
||||||
stop = grid->top - count - 1;
|
stop = top - count - 1;
|
||||||
step = -1;
|
step = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,10 +72,10 @@ void ugrid_scroll(UGrid *grid, int count, int *clear_top, int *clear_bot)
|
|||||||
|
|
||||||
// Copy cell data
|
// Copy cell data
|
||||||
for (i = start; i != stop; i += step) {
|
for (i = start; i != stop; i += step) {
|
||||||
UCell *target_row = grid->cells[i] + grid->left;
|
UCell *target_row = grid->cells[i] + left;
|
||||||
UCell *source_row = grid->cells[i + count] + grid->left;
|
UCell *source_row = grid->cells[i + count] + left;
|
||||||
memcpy(target_row, source_row,
|
memcpy(target_row, source_row,
|
||||||
sizeof(UCell) * (size_t)(grid->right - grid->left + 1));
|
sizeof(UCell) * (size_t)(right - left + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear cells in the emptied region,
|
// clear cells in the emptied region,
|
||||||
@ -97,7 +86,7 @@ void ugrid_scroll(UGrid *grid, int count, int *clear_top, int *clear_bot)
|
|||||||
*clear_bot = stop;
|
*clear_bot = stop;
|
||||||
*clear_top = stop + count + 1;
|
*clear_top = stop + count + 1;
|
||||||
}
|
}
|
||||||
clear_region(grid, *clear_top, *clear_bot, grid->left, grid->right, 0);
|
clear_region(grid, *clear_top, *clear_bot, left, right, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_region(UGrid *grid, int top, int bot, int left, int right,
|
static void clear_region(UGrid *grid, int top, int bot, int left, int right,
|
||||||
|
@ -15,7 +15,6 @@ struct ucell {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ugrid {
|
struct ugrid {
|
||||||
int top, bot, left, right;
|
|
||||||
int row, col;
|
int row, col;
|
||||||
int width, height;
|
int width, height;
|
||||||
UCell **cells;
|
UCell **cells;
|
||||||
|
Loading…
Reference in New Issue
Block a user