mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
refactor(grid): unify the two put-text-on-the-screen code paths
The screen grid refactors will continue until morale improves. Jokes aside, this is quite a central installment in the series. Before this refactor, there were two fundamentally distinct codepaths for getting some text on the screen: - the win_line() -> grid_put_linebuf() -> ui_line() call chain used for buffer text, with linebuf_char as a temporary scratch buffer - the grid_line_start/grid_line_puts/grid_line_flush() -> ui_line() path used for every thing else: statuslines, messages and the command line. Here the grid->chars[] array itself doubles as a scratch buffer. With this refactor, the later family of functions still exist, however they now as well render to linebuf_char just like win_line() did, and grid_put_linebuf() is called in the end to calculate delta changes. This means we don't need any duplicate logic for delta calculations anymore. Later down the line, it will be possible to share more logic operating on this scratch buffer, like doing 'rightleft' reversal and arabic shaping as a post-processing step.
This commit is contained in:
parent
af7d317f3f
commit
e33269578b
@ -608,7 +608,7 @@ static void redraw_wildmenu(expand_T *xp, int num_matches, char **matches, int m
|
|||||||
|
|
||||||
grid_line_fill(clen, Columns, fillchar, attr);
|
grid_line_fill(clen, Columns, fillchar, attr);
|
||||||
|
|
||||||
grid_line_flush(false);
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
win_redraw_last_status(topframe);
|
win_redraw_last_status(topframe);
|
||||||
|
@ -1825,7 +1825,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
|||||||
|| (number_only && wlv.draw_state > WL_STC))
|
|| (number_only && wlv.draw_state > WL_STC))
|
||||||
&& wlv.filler_todo <= 0) {
|
&& wlv.filler_todo <= 0) {
|
||||||
draw_virt_text(wp, buf, win_col_offset, &wlv.col, wp->w_p_rl ? -1 : grid->cols, wlv.row);
|
draw_virt_text(wp, buf, win_col_offset, &wlv.col, wp->w_p_rl ? -1 : grid->cols, wlv.row);
|
||||||
grid_put_linebuf(grid, wlv.row, 0, wlv.col, -grid->cols, wp->w_p_rl, wp, bg_attr, false);
|
win_put_linebuf(wp, wlv.row, 0, wlv.col, -grid->cols, bg_attr, false);
|
||||||
// Pretend we have finished updating the window. Except when
|
// Pretend we have finished updating the window. Except when
|
||||||
// 'cursorcolumn' is set.
|
// 'cursorcolumn' is set.
|
||||||
if (wp->w_p_cuc) {
|
if (wp->w_p_cuc) {
|
||||||
@ -2956,7 +2956,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
|||||||
wp->w_p_rl ? -1 : grid->cols, 0, wp->w_p_rl);
|
wp->w_p_rl ? -1 : grid->cols, 0, wp->w_p_rl);
|
||||||
}
|
}
|
||||||
draw_virt_text(wp, buf, win_col_offset, &wlv.col, wp->w_p_rl ? -1 : grid->cols, wlv.row);
|
draw_virt_text(wp, buf, win_col_offset, &wlv.col, wp->w_p_rl ? -1 : grid->cols, wlv.row);
|
||||||
grid_put_linebuf(grid, wlv.row, 0, wlv.col, grid->cols, wp->w_p_rl, wp, bg_attr, false);
|
win_put_linebuf(wp, wlv.row, 0, wlv.col, grid->cols, bg_attr, false);
|
||||||
wlv.row++;
|
wlv.row++;
|
||||||
|
|
||||||
// Update w_cline_height and w_cline_folded if the cursor line was
|
// Update w_cline_height and w_cline_folded if the cursor line was
|
||||||
@ -3229,7 +3229,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
|||||||
draw_virt_text(wp, buf, win_col_offset, &draw_col, wp->w_p_rl ? -1 : grid->cols, wlv.row);
|
draw_virt_text(wp, buf, win_col_offset, &draw_col, wp->w_p_rl ? -1 : grid->cols, wlv.row);
|
||||||
}
|
}
|
||||||
|
|
||||||
grid_put_linebuf(grid, wlv.row, 0, draw_col, grid->cols, wp->w_p_rl, wp, bg_attr, wrap);
|
win_put_linebuf(wp, wlv.row, 0, draw_col, grid->cols, bg_attr, wrap);
|
||||||
if (wrap) {
|
if (wrap) {
|
||||||
ScreenGrid *current_grid = grid;
|
ScreenGrid *current_grid = grid;
|
||||||
int current_row = wlv.row, dummy_col = 0; // dummy_col unused
|
int current_row = wlv.row, dummy_col = 0; // dummy_col unused
|
||||||
@ -3297,3 +3297,37 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
|||||||
xfree(wlv.saved_p_extra_free);
|
xfree(wlv.saved_p_extra_free);
|
||||||
return wlv.row;
|
return wlv.row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void win_put_linebuf(win_T *wp, int row, int coloff, int endcol, int clear_width,
|
||||||
|
int bg_attr, bool wrap)
|
||||||
|
{
|
||||||
|
ScreenGrid *grid = &wp->w_grid;
|
||||||
|
|
||||||
|
// Take care of putting "<<<" on the first line for 'smoothscroll'.
|
||||||
|
if (row == 0 && wp->w_skipcol > 0
|
||||||
|
// do not overwrite the 'showbreak' text with "<<<"
|
||||||
|
&& *get_showbreak_value(wp) == NUL
|
||||||
|
// do not overwrite the 'listchars' "precedes" text with "<<<"
|
||||||
|
&& !(wp->w_p_list && wp->w_p_lcs_chars.prec != 0)) {
|
||||||
|
int off = 0;
|
||||||
|
if (wp->w_p_nu && wp->w_p_rnu) {
|
||||||
|
// do not overwrite the line number, change "123 text" to "123<<<xt".
|
||||||
|
while (off < grid->cols && ascii_isdigit(schar_get_ascii(linebuf_char[off]))) {
|
||||||
|
off++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 3 && off < grid->cols; i++) {
|
||||||
|
if (off + 1 < grid->cols && linebuf_char[off + 1] == NUL) {
|
||||||
|
// When the first half of a double-width character is
|
||||||
|
// overwritten, change the second half to a space.
|
||||||
|
linebuf_char[off + 1] = schar_from_ascii(' ');
|
||||||
|
}
|
||||||
|
linebuf_char[off] = schar_from_ascii('<');
|
||||||
|
linebuf_attr[off] = HL_ATTR(HLF_AT);
|
||||||
|
off++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grid_put_linebuf(grid, row, coloff, 0, endcol, clear_width, wp->w_p_rl, bg_attr, wrap, false);
|
||||||
|
}
|
||||||
|
@ -771,20 +771,20 @@ static void win_redr_border(win_T *wp)
|
|||||||
if (adj[1]) {
|
if (adj[1]) {
|
||||||
grid_line_put_schar(icol + adj[3], chars[2], attrs[2]);
|
grid_line_put_schar(icol + adj[3], chars[2], attrs[2]);
|
||||||
}
|
}
|
||||||
grid_line_flush(false);
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < irow; i++) {
|
for (int i = 0; i < irow; i++) {
|
||||||
if (adj[3]) {
|
if (adj[3]) {
|
||||||
grid_line_start(grid, i + adj[0]);
|
grid_line_start(grid, i + adj[0]);
|
||||||
grid_line_put_schar(0, chars[7], attrs[7]);
|
grid_line_put_schar(0, chars[7], attrs[7]);
|
||||||
grid_line_flush(false);
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
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_line_start(grid, i + adj[0]);
|
grid_line_start(grid, i + adj[0]);
|
||||||
grid_line_put_schar(icol + adj[3], chars[ic], attrs[ic]);
|
grid_line_put_schar(icol + adj[3], chars[ic], attrs[ic]);
|
||||||
grid_line_flush(false);
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -807,7 +807,7 @@ static void win_redr_border(win_T *wp)
|
|||||||
if (adj[1]) {
|
if (adj[1]) {
|
||||||
grid_line_put_schar(icol + adj[3], chars[4], attrs[4]);
|
grid_line_put_schar(icol + adj[3], chars[4], attrs[4]);
|
||||||
}
|
}
|
||||||
grid_line_flush(false);
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1098,7 +1098,7 @@ int showmode(void)
|
|||||||
&& !(p_ch == 0 && !ui_has(kUIMessages))) {
|
&& !(p_ch == 0 && !ui_has(kUIMessages))) {
|
||||||
grid_line_start(&msg_grid_adj, Rows - 1);
|
grid_line_start(&msg_grid_adj, Rows - 1);
|
||||||
win_redr_ruler(ruler_win);
|
win_redr_ruler(ruler_win);
|
||||||
grid_line_flush(false);
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
redraw_cmdline = false;
|
redraw_cmdline = false;
|
||||||
@ -1370,25 +1370,25 @@ static void draw_sep_connectors_win(win_T *wp)
|
|||||||
bool bot_left = !(win_at_bottom || win_at_left);
|
bool bot_left = !(win_at_bottom || win_at_left);
|
||||||
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) {
|
||||||
grid_line_start(&default_grid, wp->w_winrow - 1);
|
grid_line_start(&default_grid, wp->w_winrow - 1);
|
||||||
if (top_left) {
|
grid_line_put_schar(wp->w_wincol - 1, get_corner_sep_connector(wp, WC_TOP_LEFT), hl);
|
||||||
grid_line_put_schar(wp->w_wincol - 1, get_corner_sep_connector(wp, WC_TOP_LEFT), hl);
|
grid_line_flush();
|
||||||
}
|
|
||||||
if (top_right) {
|
|
||||||
grid_line_put_schar(W_ENDCOL(wp), get_corner_sep_connector(wp, WC_TOP_RIGHT), hl);
|
|
||||||
}
|
|
||||||
grid_line_flush(false);
|
|
||||||
}
|
}
|
||||||
if (bot_left || bot_right) {
|
if (top_right) {
|
||||||
|
grid_line_start(&default_grid, wp->w_winrow - 1);
|
||||||
|
grid_line_put_schar(W_ENDCOL(wp), get_corner_sep_connector(wp, WC_TOP_RIGHT), hl);
|
||||||
|
grid_line_flush();
|
||||||
|
}
|
||||||
|
if (bot_left) {
|
||||||
grid_line_start(&default_grid, W_ENDROW(wp));
|
grid_line_start(&default_grid, W_ENDROW(wp));
|
||||||
if (bot_left) {
|
grid_line_put_schar(wp->w_wincol - 1, get_corner_sep_connector(wp, WC_BOTTOM_LEFT), hl);
|
||||||
grid_line_put_schar(wp->w_wincol - 1, get_corner_sep_connector(wp, WC_BOTTOM_LEFT), hl);
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
if (bot_right) {
|
if (bot_right) {
|
||||||
grid_line_put_schar(W_ENDCOL(wp), get_corner_sep_connector(wp, WC_BOTTOM_RIGHT), hl);
|
grid_line_start(&default_grid, W_ENDROW(wp));
|
||||||
}
|
grid_line_put_schar(W_ENDCOL(wp), get_corner_sep_connector(wp, WC_BOTTOM_RIGHT), hl);
|
||||||
grid_line_flush(false);
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2394,8 +2394,11 @@ static void win_update(win_T *wp, DecorProviders *providers)
|
|||||||
int symbol = wp->w_p_fcs_chars.lastline;
|
int symbol = wp->w_p_fcs_chars.lastline;
|
||||||
|
|
||||||
// Last line isn't finished: Display "@@@" at the end.
|
// Last line isn't finished: Display "@@@" at the end.
|
||||||
grid_fill(&wp->w_grid, wp->w_grid.rows - 1, wp->w_grid.rows,
|
// TODO(bfredl): this display ">@@@" when ">" was a left-halve
|
||||||
MAX(start_col, 0), wp->w_grid.cols, symbol, symbol, at_attr);
|
// maybe "@@@@" is preferred when this happens.
|
||||||
|
grid_line_start(&wp->w_grid, wp->w_grid.rows - 1);
|
||||||
|
grid_line_fill(MAX(start_col, 0), wp->w_grid.cols, symbol, at_attr);
|
||||||
|
grid_line_flush();
|
||||||
set_empty_rows(wp, srow);
|
set_empty_rows(wp, srow);
|
||||||
wp->w_botline = lnum;
|
wp->w_botline = lnum;
|
||||||
} else {
|
} else {
|
||||||
|
347
src/nvim/grid.c
347
src/nvim/grid.c
@ -190,21 +190,16 @@ void grid_invalidate(ScreenGrid *grid)
|
|||||||
(void)memset(grid->attrs, -1, sizeof(sattr_T) * (size_t)grid->rows * (size_t)grid->cols);
|
(void)memset(grid->attrs, -1, sizeof(sattr_T) * (size_t)grid->rows * (size_t)grid->cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool grid_invalid_row(ScreenGrid *grid, int row)
|
static bool grid_invalid_row(ScreenGrid *grid, int row)
|
||||||
{
|
{
|
||||||
return grid->attrs[grid->line_offset[row]] < 0;
|
return grid->attrs[grid->line_offset[row]] < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int line_off2cells(schar_T *line, size_t off, size_t max_off)
|
|
||||||
{
|
|
||||||
return (off + 1 < max_off && line[off + 1] == 0) ? 2 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return number of display cells for char at grid->chars[off].
|
/// Return number of display cells for char at grid->chars[off].
|
||||||
/// We make sure that the offset used is less than "max_off".
|
/// We make sure that the offset used is less than "max_off".
|
||||||
static int grid_off2cells(ScreenGrid *grid, size_t off, size_t max_off)
|
static int grid_off2cells(ScreenGrid *grid, size_t off, size_t max_off)
|
||||||
{
|
{
|
||||||
return line_off2cells(grid->chars, off, max_off);
|
return (off + 1 < max_off && grid->chars[off + 1] == 0) ? 2 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return true if the character at "row"/"col" on the screen is the left side
|
/// Return true if the character at "row"/"col" on the screen is the left side
|
||||||
@ -261,18 +256,12 @@ 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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool check_grid(ScreenGrid *grid, int row, int col)
|
static ScreenGrid *grid_line_grid = NULL;
|
||||||
{
|
static int grid_line_row = -1;
|
||||||
grid_adjust(&grid, &row, &col);
|
static int grid_line_coloff = 0;
|
||||||
// Safety check. The check for negative row and column is to fix issue
|
static int grid_line_maxcol = 0;
|
||||||
// vim/vim#4102. TODO(neovim): find out why row/col could be negative.
|
static int grid_line_first = INT_MAX;
|
||||||
if (grid->chars == NULL
|
static int grid_line_last = 0;
|
||||||
|| row >= grid->rows || row < 0
|
|
||||||
|| col >= grid->cols || col < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// put string 'text' on the window grid at position 'row' and 'col', with
|
/// put string 'text' on the window grid at position 'row' and 'col', with
|
||||||
/// attributes 'attr', and update contents of 'grid'
|
/// attributes 'attr', and update contents of 'grid'
|
||||||
@ -280,26 +269,32 @@ static bool check_grid(ScreenGrid *grid, int row, int col)
|
|||||||
/// Note: only outputs within one row!
|
/// Note: only outputs within one row!
|
||||||
int grid_puts(ScreenGrid *grid, const char *text, int textlen, int row, int col, int attr)
|
int grid_puts(ScreenGrid *grid, const char *text, int textlen, int row, int col, int attr)
|
||||||
{
|
{
|
||||||
if (!check_grid(grid, row, col)) {
|
grid_line_start(grid, row);
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
int off_col = grid_line_coloff + col;
|
||||||
|
if (grid_line_grid->chars == NULL
|
||||||
|
|| grid_line_row >= grid_line_grid->rows || grid_line_row < 0
|
||||||
|
|| off_col >= grid_line_grid->cols || off_col < 0) {
|
||||||
if (rdb_flags & RDB_INVALID) {
|
if (rdb_flags & RDB_INVALID) {
|
||||||
abort();
|
abort();
|
||||||
|
} else {
|
||||||
|
grid_line_grid = NULL;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
grid_line_start(grid, row);
|
|
||||||
int len = grid_line_puts(col, text, textlen, attr);
|
int len = grid_line_puts(col, text, textlen, attr);
|
||||||
grid_line_flush(true);
|
if (grid_line_last > grid_line_first) {
|
||||||
|
// TODO(bfredl): this is bullshit. message.c should manage its own cursor movements
|
||||||
|
int col_pos = MIN(grid_line_coloff + grid_line_last, grid_line_grid->cols - 1);
|
||||||
|
ui_grid_cursor_goto(grid_line_grid->handle, grid_line_row, col_pos);
|
||||||
|
}
|
||||||
|
grid_line_flush();
|
||||||
return len;
|
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.
|
/// 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
|
/// Must be matched with a grid_line_flush call before moving to
|
||||||
@ -308,56 +303,46 @@ void grid_line_start(ScreenGrid *grid, int row)
|
|||||||
{
|
{
|
||||||
int col = 0;
|
int col = 0;
|
||||||
grid_adjust(&grid, &row, &col);
|
grid_adjust(&grid, &row, &col);
|
||||||
assert(grid_line_row == -1);
|
assert(grid_line_grid == NULL);
|
||||||
grid_line_row = row;
|
grid_line_row = row;
|
||||||
grid_line_grid = grid;
|
grid_line_grid = grid;
|
||||||
grid_line_coloff = col;
|
grid_line_coloff = col;
|
||||||
// TODO(bfredl): ugly hackaround, will be fixed in STAGE 2
|
grid_line_first = (int)linebuf_size;
|
||||||
grid_line_was_invalid = grid != &default_grid && grid_invalid_row(grid, row);
|
grid_line_maxcol = grid->cols - grid_line_coloff;
|
||||||
|
grid_line_last = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void grid_line_put_schar(int col, schar_T schar, int attr)
|
void grid_line_put_schar(int col, schar_T schar, int attr)
|
||||||
{
|
{
|
||||||
assert(grid_line_row >= 0);
|
assert(grid_line_grid);
|
||||||
ScreenGrid *grid = grid_line_grid;
|
|
||||||
|
|
||||||
size_t off = grid->line_offset[grid_line_row] + (size_t)col;
|
linebuf_char[col] = schar;
|
||||||
if (grid->attrs[off] != attr || grid->chars[off] != schar || rdb_flags & RDB_NODELTA) {
|
linebuf_attr[col] = attr;
|
||||||
grid->chars[off] = schar;
|
|
||||||
grid->attrs[off] = attr;
|
|
||||||
|
|
||||||
grid_line_first = MIN(grid_line_first, col);
|
grid_line_first = MIN(grid_line_first, col);
|
||||||
// TODO(bfredl): Y U NO DOUBLEWIDTH?
|
// TODO(bfredl): Y U NO DOUBLEWIDTH?
|
||||||
grid_line_last = MAX(grid_line_last, col + 1);
|
grid_line_last = MAX(grid_line_last, col + 1);
|
||||||
}
|
linebuf_vcol[col] = -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_line_puts(int col, const char *text, int textlen, int attr)
|
int grid_line_puts(int col, const char *text, int textlen, int attr)
|
||||||
{
|
{
|
||||||
size_t off;
|
|
||||||
const char *ptr = text;
|
const char *ptr = text;
|
||||||
int len = textlen;
|
int len = textlen;
|
||||||
int c;
|
int c;
|
||||||
size_t max_off;
|
|
||||||
int u8cc[MAX_MCO];
|
int u8cc[MAX_MCO];
|
||||||
bool clear_next_cell = false;
|
|
||||||
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];
|
||||||
|
|
||||||
assert(grid_line_row >= 0);
|
assert(grid_line_grid);
|
||||||
ScreenGrid *grid = grid_line_grid;
|
|
||||||
int row = grid_line_row;
|
|
||||||
col += grid_line_coloff;
|
|
||||||
|
|
||||||
off = grid->line_offset[row] + (size_t)col;
|
|
||||||
int start_col = col;
|
int start_col = col;
|
||||||
|
|
||||||
max_off = grid->line_offset[row] + (size_t)grid->cols;
|
int max_col = grid_line_maxcol;
|
||||||
while (col < grid->cols
|
while (col < max_col
|
||||||
&& (len < 0 || (int)(ptr - text) < len)
|
&& (len < 0 || (int)(ptr - text) < len)
|
||||||
&& *ptr != NUL) {
|
&& *ptr != NUL) {
|
||||||
c = (unsigned char)(*ptr);
|
c = (unsigned char)(*ptr);
|
||||||
@ -394,7 +379,7 @@ int grid_line_puts(int col, const char *text, int textlen, int attr)
|
|||||||
} else {
|
} else {
|
||||||
prev_c = u8c;
|
prev_c = u8c;
|
||||||
}
|
}
|
||||||
if (col + mbyte_cells > grid->cols) {
|
if (col + mbyte_cells > max_col) {
|
||||||
// Only 1 cell left, but character requires 2 cells:
|
// Only 1 cell left, but character requires 2 cells:
|
||||||
// display a '>' in the last column to avoid wrapping. */
|
// display a '>' in the last column to avoid wrapping. */
|
||||||
c = '>';
|
c = '>';
|
||||||
@ -408,55 +393,29 @@ int grid_line_puts(int col, const char *text, int textlen, int attr)
|
|||||||
// an edge case, treat it as such..
|
// an edge case, treat it as such..
|
||||||
buf = schar_from_cc(u8c, u8cc);
|
buf = schar_from_cc(u8c, u8cc);
|
||||||
|
|
||||||
int need_redraw = grid->chars[off] != buf
|
// When at the start of the text and overwriting the right half of a
|
||||||
|| (mbyte_cells == 2 && grid->chars[off + 1] != 0)
|
// two-cell character in the same grid, truncate that into a '>'.
|
||||||
|| grid->attrs[off] != attr
|
if (ptr == text && col > grid_line_first && col < grid_line_last
|
||||||
|| exmode_active
|
&& linebuf_char[col] == 0) {
|
||||||
|| rdb_flags & RDB_NODELTA;
|
linebuf_char[col - 1] = schar_from_ascii('>');
|
||||||
|
}
|
||||||
if (need_redraw) {
|
|
||||||
// When at the end of the text and overwriting a two-cell
|
linebuf_char[col] = buf;
|
||||||
// character with a one-cell character, need to clear the next
|
linebuf_attr[col] = attr;
|
||||||
// cell. Also when overwriting the left half of a two-cell char
|
linebuf_vcol[col] = -1;
|
||||||
// with the right half of a two-cell char. Do this only once
|
if (mbyte_cells == 2) {
|
||||||
// (utf8_off2cells() may return 2 on the right half).
|
linebuf_char[col + 1] = 0;
|
||||||
if (clear_next_cell) {
|
linebuf_attr[col + 1] = attr;
|
||||||
clear_next_cell = false;
|
linebuf_vcol[col + 1] = -1;
|
||||||
} else if ((len < 0 ? ptr[mbyte_blen] == NUL : ptr + mbyte_blen >= text + len)
|
|
||||||
&& ((mbyte_cells == 1
|
|
||||||
&& grid_off2cells(grid, off, max_off) > 1)
|
|
||||||
|| (mbyte_cells == 2
|
|
||||||
&& grid_off2cells(grid, off, max_off) == 1
|
|
||||||
&& grid_off2cells(grid, off + 1, max_off) > 1))) {
|
|
||||||
clear_next_cell = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// When at the start of the text and overwriting the right half of a
|
|
||||||
// two-cell character in the same grid, truncate that into a '>'.
|
|
||||||
if (ptr == text && col > 0 && grid->chars[off] == 0) {
|
|
||||||
grid->chars[off - 1] = schar_from_ascii('>');
|
|
||||||
}
|
|
||||||
|
|
||||||
grid->chars[off] = buf;
|
|
||||||
grid->attrs[off] = attr;
|
|
||||||
grid->vcols[off] = -1;
|
|
||||||
if (mbyte_cells == 2) {
|
|
||||||
grid->chars[off + 1] = 0;
|
|
||||||
grid->attrs[off + 1] = attr;
|
|
||||||
grid->vcols[off + 1] = -1;
|
|
||||||
}
|
|
||||||
grid_line_first = MIN(grid_line_first, col);
|
|
||||||
grid_line_last = MAX(grid_line_last, col + mbyte_cells);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
off += (size_t)mbyte_cells;
|
|
||||||
col += mbyte_cells;
|
col += mbyte_cells;
|
||||||
ptr += mbyte_blen;
|
ptr += mbyte_blen;
|
||||||
if (clear_next_cell) {
|
}
|
||||||
// This only happens at the end, display one space next.
|
|
||||||
ptr = " ";
|
if (col > start_col) {
|
||||||
len = -1;
|
grid_line_first = MIN(grid_line_first, start_col);
|
||||||
}
|
grid_line_last = MAX(grid_line_last, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
return col - start_col;
|
return col - start_col;
|
||||||
@ -464,56 +423,30 @@ int grid_line_puts(int col, const char *text, int textlen, int attr)
|
|||||||
|
|
||||||
void grid_line_fill(int start_col, int end_col, int c, int attr)
|
void grid_line_fill(int start_col, int end_col, int c, int attr)
|
||||||
{
|
{
|
||||||
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);
|
schar_T sc = schar_from_char(c);
|
||||||
for (int col = start_col; col < end_col; col++) {
|
for (int col = start_col; col < end_col; col++) {
|
||||||
size_t off = lineoff + (size_t)col;
|
linebuf_char[col] = sc;
|
||||||
if (grid->chars[off] != sc || grid->attrs[off] != attr || rdb_flags & RDB_NODELTA) {
|
linebuf_attr[col] = attr;
|
||||||
grid->chars[off] = sc;
|
linebuf_vcol[col] = -1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
grid_line_first = MIN(grid_line_first, start_col);
|
||||||
|
grid_line_last = MAX(grid_line_last, end_col);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// End a group of grid_line_puts calls and send the screen buffer to the UI layer.
|
/// End a group of grid_line_puts calls and send the screen buffer to the UI layer.
|
||||||
///
|
void grid_line_flush(void)
|
||||||
/// @param set_cursor Move the visible cursor to the end of the changed region.
|
|
||||||
/// This is a workaround for not yet refactored code paths
|
|
||||||
/// and shouldn't be used in new code.
|
|
||||||
void grid_line_flush(bool set_cursor)
|
|
||||||
{
|
{
|
||||||
assert(grid_line_row != -1);
|
ScreenGrid *grid = grid_line_grid;
|
||||||
if (grid_line_first < grid_line_last) {
|
|
||||||
// When drawing over the right half of a double-wide char clear out the
|
|
||||||
// left half. Only needed in a terminal.
|
|
||||||
if (grid_line_was_invalid && grid_line_first == 0) {
|
|
||||||
// redraw the previous cell, make it empty
|
|
||||||
grid_line_first = -1;
|
|
||||||
}
|
|
||||||
if (set_cursor) {
|
|
||||||
ui_grid_cursor_goto(grid_line_grid->handle, grid_line_row,
|
|
||||||
MIN(grid_line_last, grid_line_grid->cols - 1));
|
|
||||||
}
|
|
||||||
if (!grid_line_grid->throttled) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
grid_line_first = INT_MAX;
|
|
||||||
grid_line_last = 0;
|
|
||||||
}
|
|
||||||
grid_line_row = -1;
|
|
||||||
grid_line_grid = NULL;
|
grid_line_grid = NULL;
|
||||||
|
if (!(grid_line_first < grid_line_last)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int row = grid_line_row;
|
||||||
|
|
||||||
|
bool invalid_row = grid != &default_grid && grid_invalid_row(grid, row) && grid_line_first == 0;
|
||||||
|
grid_put_linebuf(grid, row, grid_line_coloff, grid_line_first, grid_line_last, grid_line_last,
|
||||||
|
false, 0, false, invalid_row);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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"
|
||||||
@ -607,13 +540,14 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int
|
|||||||
/// - the attributes are different
|
/// - the attributes are different
|
||||||
/// - the character is multi-byte and the next byte is different
|
/// - the character is multi-byte and the next byte is different
|
||||||
/// - the character is two cells wide and the second cell differs.
|
/// - the character is two cells wide and the second cell differs.
|
||||||
static int grid_char_needs_redraw(ScreenGrid *grid, size_t off_from, size_t off_to, int cols)
|
static int grid_char_needs_redraw(ScreenGrid *grid, int col, size_t off_to, int cols)
|
||||||
{
|
{
|
||||||
return (cols > 0
|
return (cols > 0
|
||||||
&& ((linebuf_char[off_from] != grid->chars[off_to]
|
&& ((linebuf_char[col] != grid->chars[off_to]
|
||||||
|| linebuf_attr[off_from] != grid->attrs[off_to]
|
|| linebuf_attr[col] != grid->attrs[off_to]
|
||||||
|| (line_off2cells(linebuf_char, off_from, off_from + (size_t)cols) > 1
|
|| (cols > 1 && linebuf_char[col + 1] == 0
|
||||||
&& linebuf_char[off_from + 1] != grid->chars[off_to + 1]))
|
&& linebuf_char[col + 1] != grid->chars[off_to + 1]))
|
||||||
|
|| exmode_active // TODO(bfredl): what in the actual fuck
|
||||||
|| rdb_flags & RDB_NODELTA));
|
|| rdb_flags & RDB_NODELTA));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -623,30 +557,27 @@ static int grid_char_needs_redraw(ScreenGrid *grid, size_t off_from, size_t off_
|
|||||||
/// "endcol" gives the columns where valid characters are.
|
/// "endcol" gives the columns where valid characters are.
|
||||||
/// "clear_width" is the width of the window. It's > 0 if the rest of the line
|
/// "clear_width" is the width of the window. It's > 0 if the rest of the line
|
||||||
/// needs to be cleared, negative otherwise.
|
/// needs to be cleared, negative otherwise.
|
||||||
/// "rlflag" is true in a rightleft window:
|
/// "rl" is true for rightleft text, like a window with 'rightleft' option set
|
||||||
/// When true and "clear_width" > 0, clear columns 0 to "endcol"
|
/// When true and "clear_width" > 0, clear columns 0 to "endcol"
|
||||||
/// When false and "clear_width" > 0, clear columns "endcol" to "clear_width"
|
/// When false and "clear_width" > 0, clear columns "endcol" to "clear_width"
|
||||||
/// If "wrap" is true, then hint to the UI that "row" contains a line
|
/// If "wrap" is true, then hint to the UI that "row" contains a line
|
||||||
/// which has wrapped into the next row.
|
/// which has wrapped into the next row.
|
||||||
void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int clear_width,
|
void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol, int clear_width,
|
||||||
int rlflag, win_T *wp, int bg_attr, bool wrap)
|
int rl, int bg_attr, bool wrap, bool invalid_row)
|
||||||
{
|
{
|
||||||
int col = 0;
|
|
||||||
bool redraw_next; // redraw_this for next character
|
bool redraw_next; // redraw_this for next character
|
||||||
bool clear_next = false;
|
bool clear_next = false;
|
||||||
bool topline = row == 0;
|
|
||||||
int char_cells; // 1: normal char
|
int char_cells; // 1: normal char
|
||||||
// 2: occupies two display cells
|
// 2: occupies two display cells
|
||||||
int start_dirty = -1, end_dirty = 0;
|
int start_dirty = -1, end_dirty = 0;
|
||||||
|
|
||||||
assert(row < grid->rows);
|
assert(0 <= row && row < grid->rows);
|
||||||
// TODO(bfredl): check all callsites and eliminate
|
// TODO(bfredl): check all callsites and eliminate
|
||||||
// Check for illegal col, just in case
|
// Check for illegal col, just in case
|
||||||
if (endcol > grid->cols) {
|
if (endcol > grid->cols) {
|
||||||
endcol = grid->cols;
|
endcol = grid->cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t max_off_from = (size_t)grid->cols;
|
|
||||||
grid_adjust(&grid, &row, &coloff);
|
grid_adjust(&grid, &row, &coloff);
|
||||||
|
|
||||||
// Safety check. Avoids clang warnings down the call stack.
|
// Safety check. Avoids clang warnings down the call stack.
|
||||||
@ -655,45 +586,21 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t off_from = 0;
|
|
||||||
size_t off_to = grid->line_offset[row] + (size_t)coloff;
|
size_t off_to = grid->line_offset[row] + (size_t)coloff;
|
||||||
const size_t max_off_to = grid->line_offset[row] + (size_t)grid->cols;
|
const size_t max_off_to = grid->line_offset[row] + (size_t)grid->cols;
|
||||||
|
|
||||||
// Take care of putting "<<<" on the first line for 'smoothscroll'.
|
// When at the start of the text and overwriting the right half of a
|
||||||
if (topline && wp->w_skipcol > 0
|
// two-cell character in the same grid, truncate that into a '>'.
|
||||||
// do not overwrite the 'showbreak' text with "<<<"
|
if (col > 0 && grid->chars[off_to + (size_t)col] == 0) {
|
||||||
&& *get_showbreak_value(wp) == NUL
|
linebuf_char[col - 1] = schar_from_ascii('>');
|
||||||
// do not overwrite the 'listchars' "precedes" text with "<<<"
|
col--;
|
||||||
&& !(wp->w_p_list && wp->w_p_lcs_chars.prec != 0)) {
|
|
||||||
size_t off = 0;
|
|
||||||
size_t skip = 0;
|
|
||||||
if (wp->w_p_nu && wp->w_p_rnu) {
|
|
||||||
// do not overwrite the line number, change "123 text" to
|
|
||||||
// "123<<<xt".
|
|
||||||
while (skip < max_off_from && ascii_isdigit(schar_get_ascii(linebuf_char[off]))) {
|
|
||||||
off++;
|
|
||||||
skip++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < 3 && i + skip < max_off_from; i++) {
|
|
||||||
if (line_off2cells(linebuf_char, off, max_off_from) > 1) {
|
|
||||||
// When the first half of a double-width character is
|
|
||||||
// overwritten, change the second half to a space.
|
|
||||||
linebuf_char[off + 1] = schar_from_ascii(' ');
|
|
||||||
}
|
|
||||||
linebuf_char[off] = schar_from_ascii('<');
|
|
||||||
linebuf_attr[off] = HL_ATTR(HLF_AT);
|
|
||||||
off++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rlflag) {
|
if (rl) {
|
||||||
// Clear rest first, because it's left of the text.
|
// Clear rest first, because it's left of the text.
|
||||||
if (clear_width > 0) {
|
if (clear_width > 0) {
|
||||||
while (col <= endcol && grid->chars[off_to] == schar_from_ascii(' ')
|
while (col <= endcol && grid->chars[off_to + (size_t)col] == schar_from_ascii(' ')
|
||||||
&& grid->attrs[off_to] == bg_attr) {
|
&& grid->attrs[off_to + (size_t)col] == bg_attr) {
|
||||||
off_to++;
|
|
||||||
col++;
|
col++;
|
||||||
}
|
}
|
||||||
if (col <= endcol) {
|
if (col <= endcol) {
|
||||||
@ -701,28 +608,26 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
col = endcol + 1;
|
col = endcol + 1;
|
||||||
off_to = grid->line_offset[row] + (size_t)col + (size_t)coloff;
|
|
||||||
off_from += (size_t)col;
|
|
||||||
endcol = (clear_width > 0 ? clear_width : -clear_width);
|
endcol = (clear_width > 0 ? clear_width : -clear_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bg_attr) {
|
if (bg_attr) {
|
||||||
assert(off_from == (size_t)col);
|
|
||||||
for (int c = col; c < endcol; c++) {
|
for (int c = col; c < endcol; c++) {
|
||||||
linebuf_attr[c] = hl_combine_attr(bg_attr, linebuf_attr[c]);
|
linebuf_attr[c] = hl_combine_attr(bg_attr, linebuf_attr[c]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
redraw_next = grid_char_needs_redraw(grid, off_from, off_to, endcol - col);
|
redraw_next = grid_char_needs_redraw(grid, col, (size_t)col + off_to, endcol - col);
|
||||||
|
|
||||||
while (col < endcol) {
|
while (col < endcol) {
|
||||||
char_cells = 1;
|
char_cells = 1;
|
||||||
if (col + 1 < endcol) {
|
if (col + 1 < endcol && linebuf_char[col + 1] == 0) {
|
||||||
char_cells = line_off2cells(linebuf_char, off_from, max_off_from);
|
char_cells = 2;
|
||||||
}
|
}
|
||||||
bool redraw_this = redraw_next; // Does character need redraw?
|
bool redraw_this = redraw_next; // Does character need redraw?
|
||||||
redraw_next = grid_char_needs_redraw(grid, off_from + (size_t)char_cells,
|
size_t off = (size_t)col + off_to;
|
||||||
off_to + (size_t)char_cells,
|
redraw_next = grid_char_needs_redraw(grid, col + char_cells,
|
||||||
|
off + (size_t)char_cells,
|
||||||
endcol - col - char_cells);
|
endcol - col - char_cells);
|
||||||
|
|
||||||
if (redraw_this) {
|
if (redraw_this) {
|
||||||
@ -737,53 +642,52 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle
|
|||||||
// char over the left half of an existing one
|
// char over the left half of an existing one
|
||||||
if (col + char_cells == endcol
|
if (col + char_cells == endcol
|
||||||
&& ((char_cells == 1
|
&& ((char_cells == 1
|
||||||
&& grid_off2cells(grid, off_to, max_off_to) > 1)
|
&& grid_off2cells(grid, off, max_off_to) > 1)
|
||||||
|| (char_cells == 2
|
|| (char_cells == 2
|
||||||
&& grid_off2cells(grid, off_to, max_off_to) == 1
|
&& grid_off2cells(grid, off, max_off_to) == 1
|
||||||
&& grid_off2cells(grid, off_to + 1, max_off_to) > 1))) {
|
&& grid_off2cells(grid, off + 1, max_off_to) > 1))) {
|
||||||
clear_next = true;
|
clear_next = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
grid->chars[off_to] = linebuf_char[off_from];
|
grid->chars[off] = linebuf_char[col];
|
||||||
if (char_cells == 2) {
|
if (char_cells == 2) {
|
||||||
grid->chars[off_to + 1] = linebuf_char[off_from + 1];
|
grid->chars[off + 1] = linebuf_char[col + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
grid->attrs[off_to] = linebuf_attr[off_from];
|
grid->attrs[off] = linebuf_attr[col];
|
||||||
// For simplicity set the attributes of second half of a
|
// For simplicity set the attributes of second half of a
|
||||||
// double-wide character equal to the first half.
|
// double-wide character equal to the first half.
|
||||||
if (char_cells == 2) {
|
if (char_cells == 2) {
|
||||||
grid->attrs[off_to + 1] = linebuf_attr[off_from];
|
grid->attrs[off + 1] = linebuf_attr[col];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
grid->vcols[off_to] = linebuf_vcol[off_from];
|
grid->vcols[off] = linebuf_vcol[col];
|
||||||
if (char_cells == 2) {
|
if (char_cells == 2) {
|
||||||
grid->vcols[off_to + 1] = linebuf_vcol[off_from + 1];
|
grid->vcols[off + 1] = linebuf_vcol[col + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
off_to += (size_t)char_cells;
|
|
||||||
off_from += (size_t)char_cells;
|
|
||||||
col += char_cells;
|
col += char_cells;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clear_next) {
|
if (clear_next) {
|
||||||
// Clear the second half of a double-wide character of which the left
|
// Clear the second half of a double-wide character of which the left
|
||||||
// half was overwritten with a single-wide character.
|
// half was overwritten with a single-wide character.
|
||||||
grid->chars[off_to] = schar_from_ascii(' ');
|
grid->chars[(size_t)col + off_to] = schar_from_ascii(' ');
|
||||||
end_dirty++;
|
end_dirty++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int clear_end = -1;
|
int clear_end = -1;
|
||||||
if (clear_width > 0 && !rlflag) {
|
if (clear_width > 0 && !rl) {
|
||||||
// blank out the rest of the line
|
// blank out the rest of the line
|
||||||
// TODO(bfredl): we could cache winline widths
|
// TODO(bfredl): we could cache winline widths
|
||||||
while (col < clear_width) {
|
while (col < clear_width) {
|
||||||
if (grid->chars[off_to] != schar_from_ascii(' ')
|
size_t off = (size_t)col + off_to;
|
||||||
|| grid->attrs[off_to] != bg_attr
|
if (grid->chars[off] != schar_from_ascii(' ')
|
||||||
|
|| grid->attrs[off] != bg_attr
|
||||||
|| rdb_flags & RDB_NODELTA) {
|
|| rdb_flags & RDB_NODELTA) {
|
||||||
grid->chars[off_to] = schar_from_ascii(' ');
|
grid->chars[off] = schar_from_ascii(' ');
|
||||||
grid->attrs[off_to] = bg_attr;
|
grid->attrs[off] = bg_attr;
|
||||||
if (start_dirty == -1) {
|
if (start_dirty == -1) {
|
||||||
start_dirty = col;
|
start_dirty = col;
|
||||||
end_dirty = col;
|
end_dirty = col;
|
||||||
@ -792,9 +696,8 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle
|
|||||||
}
|
}
|
||||||
clear_end = col + 1;
|
clear_end = col + 1;
|
||||||
}
|
}
|
||||||
grid->vcols[off_to] = MAXCOL;
|
grid->vcols[off] = MAXCOL;
|
||||||
col++;
|
col++;
|
||||||
off_to++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -805,8 +708,22 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle
|
|||||||
start_dirty = end_dirty;
|
start_dirty = end_dirty;
|
||||||
}
|
}
|
||||||
if (clear_end > start_dirty) {
|
if (clear_end > start_dirty) {
|
||||||
ui_line(grid, row, coloff + start_dirty, coloff + end_dirty, coloff + clear_end,
|
if (!grid->throttled) {
|
||||||
bg_attr, wrap);
|
int start_pos = coloff + start_dirty;
|
||||||
|
// When drawing over the right half of a double-wide char clear out the
|
||||||
|
// left half. Only needed in a terminal.
|
||||||
|
if (invalid_row && start_pos == 0) {
|
||||||
|
start_pos = -1;
|
||||||
|
}
|
||||||
|
ui_line(grid, row, start_pos, coloff + end_dirty, coloff + clear_end,
|
||||||
|
bg_attr, wrap);
|
||||||
|
} else if (grid->dirty_col) {
|
||||||
|
// TODO(bfredl): really get rid of the extra psuedo terminal in message.c
|
||||||
|
// by using a linebuf_char copy for "throttled message line"
|
||||||
|
if (clear_end > grid->dirty_col[row]) {
|
||||||
|
grid->dirty_col[row] = clear_end;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2087,7 +2087,7 @@ static void display_showcmd(void)
|
|||||||
// 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_line_puts(sc_col + len, (char *)" " + len, -1, HL_ATTR(HLF_MSG));
|
grid_line_puts(sc_col + len, (char *)" " + len, -1, HL_ATTR(HLF_MSG));
|
||||||
|
|
||||||
grid_line_flush(false);
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When "check" is false, prepare for commands that scroll the window.
|
/// When "check" is false, prepare for commands that scroll the window.
|
||||||
|
@ -655,7 +655,7 @@ void pum_redraw(void)
|
|||||||
i >= thumb_pos && i < thumb_pos + thumb_height ? attr_thumb : attr_scroll);
|
i >= thumb_pos && i < thumb_pos + thumb_height ? attr_thumb : attr_scroll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
grid_line_flush(false);
|
grid_line_flush();
|
||||||
row++;
|
row++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ void win_redr_status(win_T *wp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
grid_line_flush(false);
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
// May need to draw the character below the vertical separator.
|
// May need to draw the character below the vertical separator.
|
||||||
@ -449,7 +449,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler)
|
|||||||
grid_line_fill(col, maxcol, fillchar, curattr);
|
grid_line_fill(col, maxcol, fillchar, curattr);
|
||||||
|
|
||||||
if (!draw_ruler) {
|
if (!draw_ruler) {
|
||||||
grid_line_flush(false);
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
@ -861,7 +861,7 @@ void draw_tabline(void)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
grid_line_flush(false);
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the flag here again, in case evaluating 'tabline' causes it to be
|
// Reset the flag here again, in case evaluating 'tabline' causes it to be
|
||||||
|
Loading…
Reference in New Issue
Block a user