Merge pull request #25268 from bfredl/grid_line

refactor(grid): properly namespace and separate stateful grid functions
This commit is contained in:
bfredl 2023-09-23 18:29:19 +02:00 committed by GitHub
commit 93d27ea578
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 201 additions and 191 deletions

View File

@ -601,10 +601,10 @@ static void redraw_wildmenu(expand_T *xp, int num_matches, char **matches, int m
ScreenGrid *grid = (wild_menu_showing == WM_SCROLLED) ScreenGrid *grid = (wild_menu_showing == WM_SCROLLED)
? &msg_grid_adj : &default_grid; ? &msg_grid_adj : &default_grid;
grid_puts(grid, buf, row, 0, attr); grid_puts(grid, buf, -1, row, 0, attr);
if (selstart != NULL && highlight) { if (selstart != NULL && highlight) {
*selend = NUL; *selend = NUL;
grid_puts(grid, selstart, row, selstart_col, HL_ATTR(HLF_WM)); grid_puts(grid, selstart, -1, row, selstart_col, HL_ATTR(HLF_WM));
} }
grid_fill(grid, row, row + 1, clen, Columns, grid_fill(grid, row, row + 1, clen, Columns,

View File

@ -709,7 +709,7 @@ void end_search_hl(void)
screen_search_hl.rm.regprog = NULL; screen_search_hl.rm.regprog = NULL;
} }
static void win_redr_bordertext(win_T *wp, ScreenGrid *grid, VirtText vt, int row, int col) static void win_redr_bordertext(win_T *wp, VirtText vt, int col)
{ {
for (size_t i = 0; i < kv_size(vt);) { for (size_t i = 0; i < kv_size(vt);) {
int attr = 0; int attr = 0;
@ -717,9 +717,7 @@ static void win_redr_bordertext(win_T *wp, ScreenGrid *grid, VirtText vt, int ro
if (text == NULL) { if (text == NULL) {
break; break;
} }
int cell = (int)mb_string2cells(text); col += grid_line_puts(col, text, -1, attr);
grid_puts(grid, text, row, col, attr);
col += cell;
} }
} }
@ -756,60 +754,60 @@ static void win_redr_border(win_T *wp)
int irow = wp->w_height_inner + wp->w_winbar_height, icol = wp->w_width_inner; int irow = wp->w_height_inner + wp->w_winbar_height, icol = wp->w_width_inner;
if (adj[0]) { if (adj[0]) {
grid_puts_line_start(grid, 0); grid_line_start(grid, 0);
if (adj[3]) { if (adj[3]) {
grid_put_schar(grid, 0, 0, chars[0], attrs[0]); grid_line_put_schar(0, chars[0], attrs[0]);
} }
for (int i = 0; i < icol; i++) { for (int i = 0; i < icol; i++) {
grid_put_schar(grid, 0, i + adj[3], chars[1], attrs[1]); grid_line_put_schar(i + adj[3], chars[1], attrs[1]);
} }
if (wp->w_float_config.title) { if (wp->w_float_config.title) {
int title_col = win_get_bordertext_col(icol, wp->w_float_config.title_width, int title_col = win_get_bordertext_col(icol, wp->w_float_config.title_width,
wp->w_float_config.title_pos); wp->w_float_config.title_pos);
win_redr_bordertext(wp, grid, wp->w_float_config.title_chunks, 0, title_col); win_redr_bordertext(wp, wp->w_float_config.title_chunks, title_col);
} }
if (adj[1]) { if (adj[1]) {
grid_put_schar(grid, 0, icol + adj[3], chars[2], attrs[2]); grid_line_put_schar(icol + adj[3], chars[2], attrs[2]);
} }
grid_puts_line_flush(false); grid_line_flush(false);
} }
for (int i = 0; i < irow; i++) { for (int i = 0; i < irow; i++) {
if (adj[3]) { if (adj[3]) {
grid_puts_line_start(grid, i + adj[0]); grid_line_start(grid, i + adj[0]);
grid_put_schar(grid, i + adj[0], 0, chars[7], attrs[7]); grid_line_put_schar(0, chars[7], attrs[7]);
grid_puts_line_flush(false); grid_line_flush(false);
} }
if (adj[1]) { if (adj[1]) {
int ic = (i == 0 && !adj[0] && chars[2]) ? 2 : 3; int ic = (i == 0 && !adj[0] && chars[2]) ? 2 : 3;
grid_puts_line_start(grid, i + adj[0]); grid_line_start(grid, i + adj[0]);
grid_put_schar(grid, i + adj[0], icol + adj[3], chars[ic], attrs[ic]); grid_line_put_schar(icol + adj[3], chars[ic], attrs[ic]);
grid_puts_line_flush(false); grid_line_flush(false);
} }
} }
if (adj[2]) { if (adj[2]) {
grid_puts_line_start(grid, irow + adj[0]); grid_line_start(grid, irow + adj[0]);
if (adj[3]) { if (adj[3]) {
grid_put_schar(grid, irow + adj[0], 0, chars[6], attrs[6]); grid_line_put_schar(0, chars[6], attrs[6]);
} }
for (int i = 0; i < icol; i++) { for (int i = 0; i < icol; i++) {
int ic = (i == 0 && !adj[3] && chars[6]) ? 6 : 5; int ic = (i == 0 && !adj[3] && chars[6]) ? 6 : 5;
grid_put_schar(grid, irow + adj[0], i + adj[3], chars[ic], attrs[ic]); grid_line_put_schar(i + adj[3], chars[ic], attrs[ic]);
} }
if (wp->w_float_config.footer) { if (wp->w_float_config.footer) {
int footer_col = win_get_bordertext_col(icol, wp->w_float_config.footer_width, int footer_col = win_get_bordertext_col(icol, wp->w_float_config.footer_width,
wp->w_float_config.footer_pos); wp->w_float_config.footer_pos);
win_redr_bordertext(wp, grid, wp->w_float_config.footer_chunks, grid->rows - 1, footer_col); win_redr_bordertext(wp, wp->w_float_config.footer_chunks, footer_col);
} }
if (adj[1]) { if (adj[1]) {
grid_put_schar(grid, irow + adj[0], icol + adj[3], chars[4], attrs[4]); grid_line_put_schar(icol + adj[3], chars[4], attrs[4]);
} }
grid_puts_line_flush(false); grid_line_flush(false);
} }
} }
@ -932,7 +930,9 @@ int showmode(void)
|| (State & MODE_INSERT) || (State & MODE_INSERT)
|| restart_edit != NUL || restart_edit != NUL
|| VIsual_active)); || VIsual_active));
if (do_mode || reg_recording != 0) {
bool can_show_mode = (p_ch != 0 || ui_has(kUIMessages));
if ((do_mode || reg_recording != 0) && can_show_mode) {
int sub_attr; int sub_attr;
if (skip_showmode()) { if (skip_showmode()) {
return 0; // show mode later return 0; // show mode later
@ -1307,23 +1307,25 @@ static void draw_hsep_win(win_T *wp)
} }
/// Get the separator connector for specified window corner of window "wp" /// Get the separator connector for specified window corner of window "wp"
static int get_corner_sep_connector(win_T *wp, WindowCorner corner) static schar_T get_corner_sep_connector(win_T *wp, WindowCorner corner)
{ {
// It's impossible for windows to be connected neither vertically nor horizontally // It's impossible for windows to be connected neither vertically nor horizontally
// So if they're not vertically connected, assume they're horizontally connected // So if they're not vertically connected, assume they're horizontally connected
int c;
if (vsep_connected(wp, corner)) { if (vsep_connected(wp, corner)) {
if (hsep_connected(wp, corner)) { if (hsep_connected(wp, corner)) {
return wp->w_p_fcs_chars.verthoriz; c = wp->w_p_fcs_chars.verthoriz;
} else if (corner == WC_TOP_LEFT || corner == WC_BOTTOM_LEFT) { } else if (corner == WC_TOP_LEFT || corner == WC_BOTTOM_LEFT) {
return wp->w_p_fcs_chars.vertright; c = wp->w_p_fcs_chars.vertright;
} else { } else {
return wp->w_p_fcs_chars.vertleft; c = wp->w_p_fcs_chars.vertleft;
} }
} else if (corner == WC_TOP_LEFT || corner == WC_TOP_RIGHT) { } else if (corner == WC_TOP_LEFT || corner == WC_TOP_RIGHT) {
return wp->w_p_fcs_chars.horizdown; c = wp->w_p_fcs_chars.horizdown;
} else { } else {
return wp->w_p_fcs_chars.horizup; c = wp->w_p_fcs_chars.horizup;
} }
return schar_from_char(c);
} }
/// Draw separator connecting characters on the corners of window "wp" /// Draw separator connecting characters on the corners of window "wp"
@ -1366,28 +1368,24 @@ static void draw_sep_connectors_win(win_T *wp)
bool bot_right = !(win_at_bottom || win_at_right); bool bot_right = !(win_at_bottom || win_at_right);
if (top_left || top_right) { if (top_left || top_right) {
grid_puts_line_start(&default_grid, wp->w_winrow - 1); grid_line_start(&default_grid, wp->w_winrow - 1);
if (top_left) { if (top_left) {
grid_putchar(&default_grid, get_corner_sep_connector(wp, WC_TOP_LEFT), grid_line_put_schar(wp->w_wincol - 1, get_corner_sep_connector(wp, WC_TOP_LEFT), hl);
wp->w_winrow - 1, wp->w_wincol - 1, hl);
} }
if (top_right) { if (top_right) {
grid_putchar(&default_grid, get_corner_sep_connector(wp, WC_TOP_RIGHT), grid_line_put_schar(W_ENDCOL(wp), get_corner_sep_connector(wp, WC_TOP_RIGHT), hl);
wp->w_winrow - 1, W_ENDCOL(wp), hl);
} }
grid_puts_line_flush(false); grid_line_flush(false);
} }
if (bot_left || bot_right) { if (bot_left || bot_right) {
grid_puts_line_start(&default_grid, W_ENDROW(wp)); grid_line_start(&default_grid, W_ENDROW(wp));
if (bot_left) { if (bot_left) {
grid_putchar(&default_grid, get_corner_sep_connector(wp, WC_BOTTOM_LEFT), grid_line_put_schar(wp->w_wincol - 1, get_corner_sep_connector(wp, WC_BOTTOM_LEFT), hl);
W_ENDROW(wp), wp->w_wincol - 1, hl);
} }
if (bot_right) { if (bot_right) {
grid_putchar(&default_grid, get_corner_sep_connector(wp, WC_BOTTOM_RIGHT), grid_line_put_schar(W_ENDCOL(wp), get_corner_sep_connector(wp, WC_BOTTOM_RIGHT), hl);
W_ENDROW(wp), W_ENDCOL(wp), hl);
} }
grid_puts_line_flush(false); grid_line_flush(false);
} }
} }
@ -2384,7 +2382,7 @@ static void win_update(win_T *wp, DecorProviders *providers)
utf_char2bytes(symbol, &fillbuf[charlen]); utf_char2bytes(symbol, &fillbuf[charlen]);
// Last line isn't finished: Display "@@@" in the last screen line. // Last line isn't finished: Display "@@@" in the last screen line.
grid_puts_len(&wp->w_grid, fillbuf, MIN(wp->w_grid.cols, 2) * charlen, scr_row, 0, at_attr); grid_puts(&wp->w_grid, fillbuf, MIN(wp->w_grid.cols, 2) * charlen, scr_row, 0, at_attr);
grid_fill(&wp->w_grid, scr_row, scr_row + 1, 2, wp->w_grid.cols, symbol, ' ', at_attr); grid_fill(&wp->w_grid, scr_row, scr_row + 1, 2, wp->w_grid.cols, symbol, ' ', at_attr);
set_empty_rows(wp, srow); set_empty_rows(wp, srow);
wp->w_botline = lnum; wp->w_botline = lnum;

View File

@ -1449,6 +1449,7 @@ void edit_putchar(int c, bool highlight)
// save the character to be able to put it back // save the character to be able to put it back
if (pc_status == PC_STATUS_UNSET) { if (pc_status == PC_STATUS_UNSET) {
// TODO(bfredl): save the schar_T instead
grid_getbytes(&curwin->w_grid, pc_row, pc_col, pc_bytes, &pc_attr); grid_getbytes(&curwin->w_grid, pc_row, pc_col, pc_bytes, &pc_attr);
pc_status = PC_STATUS_SET; pc_status = PC_STATUS_SET;
} }
@ -1532,7 +1533,7 @@ void edit_unputchar(void)
if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT) { if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT) {
redrawWinline(curwin, curwin->w_cursor.lnum); redrawWinline(curwin, curwin->w_cursor.lnum);
} else { } else {
grid_puts(&curwin->w_grid, pc_bytes, pc_row, pc_col, pc_attr); grid_puts(&curwin->w_grid, pc_bytes, -1, pc_row, pc_col, pc_attr);
} }
} }
} }
@ -3485,7 +3486,8 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
// Otherwise remove the mode message. // Otherwise remove the mode message.
if (reg_recording != 0 || restart_edit != NUL) { if (reg_recording != 0 || restart_edit != NUL) {
showmode(); showmode();
} else if (p_smd && (got_int || !skip_showmode())) { } else if (p_smd && (got_int || !skip_showmode())
&& !(p_ch == 0 && !ui_has(kUIMessages))) {
msg(""); msg("");
} }
// Exit Insert mode // Exit Insert mode

View File

@ -239,8 +239,7 @@ void grid_putchar(ScreenGrid *grid, int c, int row, int col, int attr)
{ {
char buf[MB_MAXBYTES + 1]; char buf[MB_MAXBYTES + 1];
buf[utf_char2bytes(c, buf)] = NUL; grid_puts(grid, buf, utf_char2bytes(c, buf), row, col, attr);
grid_puts(grid, buf, row, col, attr);
} }
/// Get a single character directly from grid.chars into "bytes", which must /// Get a single character directly from grid.chars into "bytes", which must
@ -262,51 +261,81 @@ void grid_getbytes(ScreenGrid *grid, int row, int col, char *bytes, int *attrp)
schar_get(bytes, grid->chars[off]); schar_get(bytes, grid->chars[off]);
} }
/// put string '*text' on the window grid at position 'row' and 'col', with static bool check_grid(ScreenGrid *grid, int row, int col)
/// attributes 'attr', and update chars[] and attrs[].
/// Note: only outputs within one row, message is truncated at grid boundary!
/// Note: if grid, row and/or col is invalid, nothing is done.
int grid_puts(ScreenGrid *grid, char *text, int row, int col, int attr)
{ {
return grid_puts_len(grid, text, -1, row, col, attr);
}
static ScreenGrid *put_dirty_grid = NULL;
static int put_dirty_row = -1;
static int put_dirty_first = INT_MAX;
static int put_dirty_last = 0;
/// Start a group of grid_puts_len calls that builds a single grid line.
///
/// Must be matched with a grid_puts_line_flush call before moving to
/// another line.
void grid_puts_line_start(ScreenGrid *grid, int row)
{
int col = 0; // unused
grid_adjust(&grid, &row, &col); grid_adjust(&grid, &row, &col);
assert(put_dirty_row == -1); // Safety check. The check for negative row and column is to fix issue
put_dirty_row = row; // vim/vim#4102. TODO(neovim): find out why row/col could be negative.
put_dirty_grid = grid; if (grid->chars == NULL
|| row >= grid->rows || row < 0
|| col >= grid->cols || col < 0) {
return false;
}
return true;
} }
void grid_put_schar(ScreenGrid *grid, int row, int col, schar_T schar, int attr) /// put string 'text' on the window grid at position 'row' and 'col', with
/// attributes 'attr', and update contents of 'grid'
/// @param textlen length of string or -1 to use strlen(text)
/// Note: only outputs within one row!
int grid_puts(ScreenGrid *grid, const char *text, int textlen, int row, int col, int attr)
{ {
assert(put_dirty_row == row); if (!check_grid(grid, row, col)) {
size_t off = grid->line_offset[row] + (size_t)col; if (rdb_flags & RDB_INVALID) {
abort();
}
return 0;
}
grid_line_start(grid, row);
int len = grid_line_puts(col, text, textlen, attr);
grid_line_flush(true);
return len;
}
static ScreenGrid *grid_line_grid = NULL;
static int grid_line_row = -1;
static int grid_line_coloff = 0;
static int grid_line_first = INT_MAX;
static int grid_line_last = 0;
static bool grid_line_was_invalid = false;
/// Start a group of grid_line_puts calls that builds a single grid line.
///
/// Must be matched with a grid_line_flush call before moving to
/// another line.
void grid_line_start(ScreenGrid *grid, int row)
{
int col = 0;
grid_adjust(&grid, &row, &col);
assert(grid_line_row == -1);
grid_line_row = row;
grid_line_grid = grid;
grid_line_coloff = col;
// TODO(bfredl): ugly hackaround, will be fixed in STAGE 2
grid_line_was_invalid = grid != &default_grid && grid_invalid_row(grid, row);
}
void grid_line_put_schar(int col, schar_T schar, int attr)
{
assert(grid_line_row >= 0);
ScreenGrid *grid = grid_line_grid;
size_t off = grid->line_offset[grid_line_row] + (size_t)col;
if (grid->attrs[off] != attr || grid->chars[off] != schar || rdb_flags & RDB_NODELTA) { if (grid->attrs[off] != attr || grid->chars[off] != schar || rdb_flags & RDB_NODELTA) {
grid->chars[off] = schar; grid->chars[off] = schar;
grid->attrs[off] = attr; grid->attrs[off] = attr;
put_dirty_first = MIN(put_dirty_first, col); grid_line_first = MIN(grid_line_first, col);
// TODO(bfredl): Y U NO DOUBLEWIDTH? // TODO(bfredl): Y U NO DOUBLEWIDTH?
put_dirty_last = MAX(put_dirty_last, col + 1); grid_line_last = MAX(grid_line_last, col + 1);
} }
grid->vcols[off] = -1; grid->vcols[off] = -1;
} }
/// like grid_puts(), but output "text[len]". When "len" is -1 output up to /// like grid_puts(), but output "text[len]". When "len" is -1 output up to
/// a NUL. /// a NUL.
int grid_puts_len(ScreenGrid *grid, const char *text, int textlen, int row, int col, int attr) int grid_line_puts(int col, const char *text, int textlen, int attr)
{ {
size_t off; size_t off;
const char *ptr = text; const char *ptr = text;
@ -318,37 +347,15 @@ int grid_puts_len(ScreenGrid *grid, const char *text, int textlen, int row, int
int prev_c = 0; // previous Arabic character int prev_c = 0; // previous Arabic character
int pc, nc, nc1; int pc, nc, nc1;
int pcc[MAX_MCO]; int pcc[MAX_MCO];
bool do_flush = false;
grid_adjust(&grid, &row, &col); assert(grid_line_row >= 0);
ScreenGrid *grid = grid_line_grid;
int row = grid_line_row;
col += grid_line_coloff;
// Safety check. The check for negative row and column is to fix issue
// vim/vim#4102. TODO(neovim): find out why row/col could be negative.
if (grid->chars == NULL
|| row >= grid->rows || row < 0
|| col >= grid->cols || col < 0) {
return 0;
}
if (put_dirty_row == -1) {
grid_puts_line_start(grid, row);
do_flush = true;
} else {
if (grid != put_dirty_grid || row != put_dirty_row) {
abort();
}
}
off = grid->line_offset[row] + (size_t)col; off = grid->line_offset[row] + (size_t)col;
int start_col = col; int start_col = col;
// When drawing over the right half of a double-wide char clear out the
// left half. Only needed in a terminal.
if (grid != &default_grid && col == 0 && grid_invalid_row(grid, row)) {
// redraw the previous cell, make it empty
put_dirty_first = -1;
put_dirty_last = MAX(put_dirty_last, 1);
}
max_off = grid->line_offset[row] + (size_t)grid->cols; max_off = grid->line_offset[row] + (size_t)grid->cols;
while (col < grid->cols while (col < grid->cols
&& (len < 0 || (int)(ptr - text) < len) && (len < 0 || (int)(ptr - text) < len)
@ -438,8 +445,8 @@ int grid_puts_len(ScreenGrid *grid, const char *text, int textlen, int row, int
grid->attrs[off + 1] = attr; grid->attrs[off + 1] = attr;
grid->vcols[off + 1] = -1; grid->vcols[off + 1] = -1;
} }
put_dirty_first = MIN(put_dirty_first, col); grid_line_first = MIN(grid_line_first, col);
put_dirty_last = MAX(put_dirty_last, col + mbyte_cells); grid_line_last = MAX(grid_line_last, col + mbyte_cells);
} }
off += (size_t)mbyte_cells; off += (size_t)mbyte_cells;
@ -452,39 +459,61 @@ int grid_puts_len(ScreenGrid *grid, const char *text, int textlen, int row, int
} }
} }
if (do_flush) {
grid_puts_line_flush(true);
}
return col - start_col; return col - start_col;
} }
/// End a group of grid_puts_len calls and send the screen buffer to the UI void grid_line_fill(int start_col, int end_col, int c, int attr)
/// layer. {
ScreenGrid *grid = grid_line_grid;
size_t lineoff = grid->line_offset[grid_line_row];
start_col += grid_line_coloff;
end_col += grid_line_coloff;
schar_T sc = schar_from_char(c);
for (int col = start_col; col < end_col; col++) {
size_t off = lineoff + (size_t)col;
if (grid->chars[off] != sc || grid->attrs[off] != attr || rdb_flags & RDB_NODELTA) {
grid->chars[off] = sc;
grid->attrs[off] = attr;
grid_line_first = MIN(grid_line_first, col);
grid_line_last = MAX(grid_line_last, col + 1);
}
grid->vcols[off] = -1;
}
}
/// End a group of grid_line_puts calls and send the screen buffer to the UI layer.
/// ///
/// @param set_cursor Move the visible cursor to the end of the changed region. /// @param set_cursor Move the visible cursor to the end of the changed region.
/// This is a workaround for not yet refactored code paths /// This is a workaround for not yet refactored code paths
/// and shouldn't be used in new code. /// and shouldn't be used in new code.
void grid_puts_line_flush(bool set_cursor) void grid_line_flush(bool set_cursor)
{ {
assert(put_dirty_row != -1); assert(grid_line_row != -1);
if (put_dirty_first < put_dirty_last) { if (grid_line_first < grid_line_last) {
if (set_cursor) { // When drawing over the right half of a double-wide char clear out the
ui_grid_cursor_goto(put_dirty_grid->handle, put_dirty_row, // left half. Only needed in a terminal.
MIN(put_dirty_last, put_dirty_grid->cols - 1)); if (grid_line_was_invalid && grid_line_first == 0) {
// redraw the previous cell, make it empty
grid_line_first = -1;
} }
if (!put_dirty_grid->throttled) { if (set_cursor) {
ui_line(put_dirty_grid, put_dirty_row, put_dirty_first, put_dirty_last, ui_grid_cursor_goto(grid_line_grid->handle, grid_line_row,
put_dirty_last, 0, false); MIN(grid_line_last, grid_line_grid->cols - 1));
} else if (put_dirty_grid->dirty_col) { }
if (put_dirty_last > put_dirty_grid->dirty_col[put_dirty_row]) { if (!grid_line_grid->throttled) {
put_dirty_grid->dirty_col[put_dirty_row] = put_dirty_last; ui_line(grid_line_grid, grid_line_row, grid_line_first, grid_line_last,
grid_line_last, 0, false);
} else if (grid_line_grid->dirty_col) {
if (grid_line_last > grid_line_grid->dirty_col[grid_line_row]) {
grid_line_grid->dirty_col[grid_line_row] = grid_line_last;
} }
} }
put_dirty_first = INT_MAX; grid_line_first = INT_MAX;
put_dirty_last = 0; grid_line_last = 0;
} }
put_dirty_row = -1; grid_line_row = -1;
put_dirty_grid = NULL; grid_line_grid = NULL;
} }
/// Fill the grid from "start_row" to "end_row" (exclusive), from "start_col" /// Fill the grid from "start_row" to "end_row" (exclusive), from "start_col"
@ -521,11 +550,11 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int
// double wide-char clear out the right half. Only needed in a // double wide-char clear out the right half. Only needed in a
// terminal. // terminal.
if (start_col > 0 && grid_fix_col(grid, start_col, row) != start_col) { if (start_col > 0 && grid_fix_col(grid, start_col, row) != start_col) {
grid_puts_len(grid, " ", 1, row, start_col - 1, 0); grid_puts(grid, " ", 1, row, start_col - 1, 0);
} }
if (end_col < grid->cols if (end_col < grid->cols
&& grid_fix_col(grid, end_col, row) != end_col) { && grid_fix_col(grid, end_col, row) != end_col) {
grid_puts_len(grid, " ", 1, row, end_col, 0); grid_puts(grid, " ", 1, row, end_col, 0);
} }
// if grid was resized (in ext_multigrid mode), the UI has no redraw updates // if grid was resized (in ext_multigrid mode), the UI has no redraw updates
@ -553,11 +582,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int
} }
} }
if (dirty_last > dirty_first) { if (dirty_last > dirty_first) {
// TODO(bfredl): support a cleared suffix even with a batched line? if (grid->throttled) {
if (put_dirty_row == row) {
put_dirty_first = MIN(put_dirty_first, dirty_first);
put_dirty_last = MAX(put_dirty_last, dirty_last);
} else if (grid->throttled) {
// Note: assumes msg_grid is the only throttled grid // Note: assumes msg_grid is the only throttled grid
assert(grid == &msg_grid); assert(grid == &msg_grid);
int dirty = 0; int dirty = 0;

View File

@ -2004,7 +2004,7 @@ static const char *screen_puts_mbyte(const char *s, int l, int attr)
return s; return s;
} }
grid_puts_len(&msg_grid_adj, s, l, msg_row, msg_col, attr); grid_puts(&msg_grid_adj, s, l, msg_row, msg_col, attr);
if (cmdmsg_rl) { if (cmdmsg_rl) {
msg_col -= cw; msg_col -= cw;
if (msg_col == 0) { if (msg_col == 0) {
@ -2705,7 +2705,7 @@ static void t_puts(int *t_col, const char *t_s, const char *s, int attr)
attr = hl_combine_attr(HL_ATTR(HLF_MSG), attr); attr = hl_combine_attr(HL_ATTR(HLF_MSG), attr);
// Output postponed text. // Output postponed text.
msg_didout = true; // Remember that line is not empty. msg_didout = true; // Remember that line is not empty.
grid_puts_len(&msg_grid_adj, t_s, (int)(s - t_s), msg_row, msg_col, attr); grid_puts(&msg_grid_adj, t_s, (int)(s - t_s), msg_row, msg_col, attr);
msg_col += *t_col; msg_col += *t_col;
*t_col = 0; *t_col = 0;
// If the string starts with a composing character don't increment the // If the string starts with a composing character don't increment the
@ -3091,9 +3091,9 @@ void msg_moremsg(int full)
char *s = _("-- More --"); char *s = _("-- More --");
attr = hl_combine_attr(HL_ATTR(HLF_MSG), HL_ATTR(HLF_M)); attr = hl_combine_attr(HL_ATTR(HLF_MSG), HL_ATTR(HLF_M));
grid_puts(&msg_grid_adj, s, Rows - 1, 0, attr); grid_puts(&msg_grid_adj, s, -1, Rows - 1, 0, attr);
if (full) { if (full) {
grid_puts(&msg_grid_adj, _(" SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "), grid_puts(&msg_grid_adj, _(" SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "), -1,
Rows - 1, vim_strsize(s), attr); Rows - 1, vim_strsize(s), attr);
} }
} }

View File

@ -2078,18 +2078,16 @@ static void display_showcmd(void)
msg_grid_validate(); msg_grid_validate();
int showcmd_row = Rows - 1; int showcmd_row = Rows - 1;
grid_puts_line_start(&msg_grid_adj, showcmd_row); grid_line_start(&msg_grid_adj, showcmd_row);
if (!showcmd_is_clear) { if (!showcmd_is_clear) {
grid_puts(&msg_grid_adj, showcmd_buf, showcmd_row, sc_col, grid_line_puts(sc_col, showcmd_buf, -1, HL_ATTR(HLF_MSG));
HL_ATTR(HLF_MSG));
} }
// clear the rest of an old message by outputting up to SHOWCMD_COLS spaces // clear the rest of an old message by outputting up to SHOWCMD_COLS spaces
grid_puts(&msg_grid_adj, (char *)" " + len, showcmd_row, grid_line_puts(sc_col + len, (char *)" " + len, -1, HL_ATTR(HLF_MSG));
sc_col + len, HL_ATTR(HLF_MSG));
grid_puts_line_flush(false); grid_line_flush(false);
} }
/// When "check" is false, prepare for commands that scroll the window. /// When "check" is false, prepare for commands that scroll the window.

View File

@ -507,14 +507,14 @@ void pum_redraw(void)
const int *const attrs = (idx == pum_selected) ? attrsSel : attrsNorm; const int *const attrs = (idx == pum_selected) ? attrsSel : attrsNorm;
int attr = attrs[0]; // start with "word" highlight int attr = attrs[0]; // start with "word" highlight
grid_puts_line_start(&pum_grid, row); grid_line_start(&pum_grid, row);
// prepend a space if there is room // prepend a space if there is room
if (extra_space) { if (extra_space) {
if (pum_rl) { if (pum_rl) {
grid_putchar(&pum_grid, ' ', row, col_off + 1, attr); grid_line_puts(col_off + 1, " ", 1, attr);
} else { } else {
grid_putchar(&pum_grid, ' ', row, col_off - 1, attr); grid_line_puts(col_off - 1, " ", 1, attr);
} }
} }
@ -580,13 +580,13 @@ void pum_redraw(void)
size++; size++;
} }
} }
grid_puts_len(&pum_grid, rt, (int)strlen(rt), row, grid_col - size + 1, attr); grid_line_puts(grid_col - size + 1, rt, -1, attr);
xfree(rt_start); xfree(rt_start);
xfree(st); xfree(st);
grid_col -= width; grid_col -= width;
} else { } else {
// use grid_puts_len() to truncate the text // use grid_line_puts() to truncate the text
grid_puts(&pum_grid, st, row, grid_col, attr); grid_line_puts(grid_col, st, -1, attr);
xfree(st); xfree(st);
grid_col += width; grid_col += width;
} }
@ -597,11 +597,10 @@ void pum_redraw(void)
// Display two spaces for a Tab. // Display two spaces for a Tab.
if (pum_rl) { if (pum_rl) {
grid_puts_len(&pum_grid, " ", 2, row, grid_col - 1, grid_line_puts(grid_col - 1, " ", 2, attr);
attr);
grid_col -= 2; grid_col -= 2;
} else { } else {
grid_puts_len(&pum_grid, " ", 2, row, grid_col, attr); grid_line_puts(grid_col, " ", 2, attr);
grid_col += 2; grid_col += 2;
} }
totwidth += 2; totwidth += 2;
@ -632,37 +631,31 @@ void pum_redraw(void)
} }
if (pum_rl) { if (pum_rl) {
grid_fill(&pum_grid, row, row + 1, col_off - pum_base_width - n + 1, grid_line_fill(col_off - pum_base_width - n + 1, grid_col + 1, ' ', attr);
grid_col + 1, ' ', ' ', attr);
grid_col = col_off - pum_base_width - n + 1; grid_col = col_off - pum_base_width - n + 1;
} else { } else {
grid_fill(&pum_grid, row, row + 1, grid_col, grid_line_fill(grid_col, col_off + pum_base_width + n, ' ', attr);
col_off + pum_base_width + n, ' ', ' ', attr);
grid_col = col_off + pum_base_width + n; grid_col = col_off + pum_base_width + n;
} }
totwidth = pum_base_width + n; totwidth = pum_base_width + n;
} }
if (pum_rl) { if (pum_rl) {
grid_fill(&pum_grid, row, row + 1, col_off - pum_width + 1, grid_col + 1, grid_line_fill(col_off - pum_width + 1, grid_col + 1, ' ', attr);
' ', ' ', attr);
} else { } else {
grid_fill(&pum_grid, row, row + 1, grid_col, col_off + pum_width, ' ', ' ', grid_line_fill(grid_col, col_off + pum_width, ' ', attr);
attr);
} }
if (pum_scrollbar > 0) { if (pum_scrollbar > 0) {
if (pum_rl) { if (pum_rl) {
grid_putchar(&pum_grid, ' ', row, col_off - pum_width, grid_line_puts(col_off - pum_width, " ", 1,
i >= thumb_pos && i < thumb_pos + thumb_height i >= thumb_pos && i < thumb_pos + thumb_height ? attr_thumb : attr_scroll);
? attr_thumb : attr_scroll);
} else { } else {
grid_putchar(&pum_grid, ' ', row, col_off + pum_width, grid_line_puts(col_off + pum_width, " ", 1,
i >= thumb_pos && i < thumb_pos + thumb_height i >= thumb_pos && i < thumb_pos + thumb_height ? attr_thumb : attr_scroll);
? attr_thumb : attr_scroll);
} }
} }
grid_puts_line_flush(false); grid_line_flush(false);
row++; row++;
} }
} }

View File

@ -153,13 +153,13 @@ void win_redr_status(win_T *wp)
row = is_stl_global ? (Rows - (int)p_ch - 1) : W_ENDROW(wp); row = is_stl_global ? (Rows - (int)p_ch - 1) : W_ENDROW(wp);
col = is_stl_global ? 0 : wp->w_wincol; col = is_stl_global ? 0 : wp->w_wincol;
int width = grid_puts(&default_grid, p, row, col, attr); int width = grid_puts(&default_grid, p, -1, row, col, attr);
grid_fill(&default_grid, row, row + 1, width + col, grid_fill(&default_grid, row, row + 1, width + col,
this_ru_col + col, fillchar, fillchar, attr); this_ru_col + col, fillchar, fillchar, attr);
if (get_keymap_str(wp, "<%s>", NameBuff, MAXPATHL) if (get_keymap_str(wp, "<%s>", NameBuff, MAXPATHL)
&& this_ru_col - len > (int)(strlen(NameBuff) + 1)) { && this_ru_col - len > (int)(strlen(NameBuff) + 1)) {
grid_puts(&default_grid, NameBuff, row, grid_puts(&default_grid, NameBuff, -1, row,
(int)((size_t)this_ru_col - strlen(NameBuff) - 1), attr); (int)((size_t)this_ru_col - strlen(NameBuff) - 1), attr);
} }
@ -170,8 +170,8 @@ void win_redr_status(win_T *wp)
const int sc_width = MIN(10, this_ru_col - len - 2); const int sc_width = MIN(10, this_ru_col - len - 2);
if (sc_width > 0) { if (sc_width > 0) {
grid_puts_len(&default_grid, showcmd_buf, sc_width, row, grid_puts(&default_grid, showcmd_buf, sc_width, row,
wp->w_wincol + this_ru_col - sc_width - 1, attr); wp->w_wincol + this_ru_col - sc_width - 1, attr);
} }
} }
} }
@ -419,7 +419,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler)
int start_col = col; int start_col = col;
// Draw each snippet with the specified highlighting. // Draw each snippet with the specified highlighting.
grid_puts_line_start(grid, row); grid_line_start(grid, row);
int curattr = attr; int curattr = attr;
char *p = buf; char *p = buf;
@ -427,7 +427,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler)
int textlen = (int)(hltab[n].start - p); int textlen = (int)(hltab[n].start - p);
// Make all characters printable. // Make all characters printable.
size_t tsize = transstr_buf(p, textlen, transbuf, sizeof transbuf, true); size_t tsize = transstr_buf(p, textlen, transbuf, sizeof transbuf, true);
col += grid_puts_len(grid, transbuf, (int)tsize, row, col, curattr); col += grid_line_puts(col, transbuf, (int)tsize, curattr);
p = hltab[n].start; p = hltab[n].start;
if (hltab[n].userhl == 0) { if (hltab[n].userhl == 0) {
@ -442,13 +442,13 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler)
} }
// Make sure to use an empty string instead of p, if p is beyond buf + len. // Make sure to use an empty string instead of p, if p is beyond buf + len.
size_t tsize = transstr_buf(p >= buf + len ? "" : p, -1, transbuf, sizeof transbuf, true); size_t tsize = transstr_buf(p >= buf + len ? "" : p, -1, transbuf, sizeof transbuf, true);
col += grid_puts_len(grid, transbuf, (int)tsize, row, col, curattr); col += grid_line_puts(col, transbuf, (int)tsize, curattr);
int maxcol = start_col + maxwidth; int maxcol = start_col + maxwidth;
// fill up with "fillchar" // fill up with "fillchar"
grid_fill(grid, row, row + 1, col, maxcol, fillchar, fillchar, curattr); grid_line_fill(col, maxcol, fillchar, curattr);
grid_puts_line_flush(false); grid_line_flush(false);
// Fill the tab_page_click_defs, w_status_click_defs or w_winbar_click_defs array for clicking // Fill the tab_page_click_defs, w_status_click_defs or w_winbar_click_defs array for clicking
// in the tab page line, status line or window bar // in the tab page line, status line or window bar
@ -618,7 +618,7 @@ void win_redr_ruler(win_T *wp)
} }
ScreenGrid *grid = part_of_status ? &default_grid : &msg_grid_adj; ScreenGrid *grid = part_of_status ? &default_grid : &msg_grid_adj;
grid_puts(grid, buffer, row, this_ru_col + off, attr); grid_puts(grid, buffer, -1, row, this_ru_col + off, attr);
grid_fill(grid, row, row + 1, grid_fill(grid, row, row + 1,
this_ru_col + off + (int)strlen(buffer), off + width, fillchar, this_ru_col + off + (int)strlen(buffer), off + width, fillchar,
fillchar, attr); fillchar, attr);
@ -810,12 +810,12 @@ void draw_tabline(void)
if (col + len >= Columns - 3) { if (col + len >= Columns - 3) {
break; break;
} }
grid_puts_len(&default_grid, NameBuff, len, 0, col, grid_puts(&default_grid, NameBuff, len, 0, col,
hl_combine_attr(attr, win_hl_attr(cwp, HLF_T))); hl_combine_attr(attr, win_hl_attr(cwp, HLF_T)));
col += len; col += len;
} }
if (modified) { if (modified) {
grid_puts_len(&default_grid, "+", 1, 0, col++, attr); grid_puts(&default_grid, "+", 1, 0, col++, attr);
} }
grid_putchar(&default_grid, ' ', 0, col++, attr); grid_putchar(&default_grid, ' ', 0, col++, attr);
} }
@ -835,7 +835,7 @@ void draw_tabline(void)
len = Columns - col - 1; len = Columns - col - 1;
} }
grid_puts_len(&default_grid, p, (int)strlen(p), 0, col, attr); grid_puts(&default_grid, p, (int)strlen(p), 0, col, attr);
col += len; col += len;
} }
grid_putchar(&default_grid, ' ', 0, col++, attr); grid_putchar(&default_grid, ' ', 0, col++, attr);
@ -864,8 +864,8 @@ void draw_tabline(void)
const int sc_width = MIN(10, (int)Columns - col - (tabcount > 1) * 3); const int sc_width = MIN(10, (int)Columns - col - (tabcount > 1) * 3);
if (sc_width > 0) { if (sc_width > 0) {
grid_puts_len(&default_grid, showcmd_buf, sc_width, 0, grid_puts(&default_grid, showcmd_buf, sc_width, 0,
Columns - sc_width - (tabcount > 1) * 2, attr_nosel); Columns - sc_width - (tabcount > 1) * 2, attr_nosel);
} }
} }

View File

@ -2837,12 +2837,6 @@ void intro_message(int colon)
} }
} }
} }
// Make the wait-return message appear just below the text.
if (colon) {
assert(row <= INT_MAX);
msg_row = (int)row;
}
} }
static void do_intro_line(long row, char *mesg, int attr) static void do_intro_line(long row, char *mesg, int attr)
@ -2871,8 +2865,8 @@ static void do_intro_line(long row, char *mesg, int attr)
l += utfc_ptr2len(p + l) - 1; l += utfc_ptr2len(p + l) - 1;
} }
assert(row <= INT_MAX && col <= INT_MAX); assert(row <= INT_MAX && col <= INT_MAX);
grid_puts_len(&default_grid, p, l, (int)row, (int)col, grid_puts(&default_grid, p, l, (int)row, (int)col,
*p == '<' ? HL_ATTR(HLF_8) : attr); *p == '<' ? HL_ATTR(HLF_8) : attr);
col += clen; col += clen;
} }
} }