refactor(ui): separate types for allocated grids and viewports

This commit is contained in:
bfredl
2025-04-15 13:19:08 +02:00
parent ac8ae1596c
commit bd413a2f55
34 changed files with 427 additions and 438 deletions

View File

@@ -181,7 +181,7 @@ static void margin_columns_win(win_T *wp, int *left_col, int *right_col)
static int prev_right_col;
int cur_col_off = win_col_off(wp);
int width1 = wp->w_width_inner - cur_col_off;
int width1 = wp->w_view_width - cur_col_off;
int width2 = width1 + win_col_off2(wp);
if (saved_w_virtcol == wp->w_virtcol && prev_wp == wp
@@ -258,7 +258,7 @@ static int line_putchar(buf_T *buf, const char **pp, schar_T *dest, int maxcells
static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int win_row)
{
DecorState *const state = &decor_state;
int const max_col = wp->w_grid.cols;
int const max_col = wp->w_view_width;
int right_pos = max_col;
bool const do_eol = state->eol_col > -1;
@@ -330,7 +330,7 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int
} else {
updated = false;
}
if (updated && (item->draw_col < 0 || item->draw_col >= wp->w_grid.cols)) {
if (updated && (item->draw_col < 0 || item->draw_col >= wp->w_view_width)) {
// Out of window, don't draw at all.
item->draw_col = INT_MIN;
}
@@ -432,9 +432,9 @@ static void draw_col_buf(win_T *wp, winlinevars_T *wlv, const char *text, size_t
const colnr_T *fold_vcol, bool inc_vcol)
{
const char *ptr = text;
while (ptr < text + len && wlv->off < wp->w_grid.cols) {
while (ptr < text + len && wlv->off < wp->w_view_width) {
int cells = line_putchar(wp->w_buffer, &ptr, &linebuf_char[wlv->off],
wp->w_grid.cols - wlv->off, wlv->off);
wp->w_view_width - wlv->off, wlv->off);
int myattr = attr;
if (inc_vcol) {
advance_color_col(wlv, wlv->vcol);
@@ -788,7 +788,7 @@ static void handle_breakindent(win_T *wp, winlinevars_T *wlv)
static void handle_showbreak_and_filler(win_T *wp, winlinevars_T *wlv)
{
int remaining = wp->w_grid.cols - wlv->off;
int remaining = wp->w_view_width - wlv->off;
if (wlv->filler_todo > wlv->filler_lines - wlv->n_virt_lines) {
// TODO(bfredl): check this doesn't inhibit TUI-style
// clear-to-end-of-line.
@@ -986,7 +986,7 @@ static void win_line_start(win_T *wp, winlinevars_T *wlv)
wlv->col = 0;
wlv->off = 0;
wlv->need_lbr = false;
for (int i = 0; i < wp->w_grid.cols; i++) {
for (int i = 0; i < wp->w_view_width; i++) {
linebuf_char[i] = schar_from_ascii(' ');
linebuf_attr[i] = 0;
linebuf_vcol[i] = -1;
@@ -1041,7 +1041,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
spellvars_T *spv, foldinfo_T foldinfo)
{
colnr_T vcol_prev = -1; // "wlv.vcol" of previous character
ScreenGrid *grid = &wp->w_grid; // grid specific to the window
GridView *grid = &wp->w_grid; // grid specific to the window
const int view_width = wp->w_view_width;
const int view_height = wp->w_view_height;
const bool in_curline = wp == curwin && lnum == curwin->w_cursor.lnum;
const bool has_fold = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0;
@@ -1695,7 +1697,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
// When only updating the columns and that's done, stop here.
if (col_rows > 0) {
wlv_put_linebuf(wp, &wlv, MIN(wlv.off, grid->cols), false, bg_attr, 0);
wlv_put_linebuf(wp, &wlv, MIN(wlv.off, view_width), false, bg_attr, 0);
// Need to update more screen lines if:
// - 'statuscolumn' needs to be drawn, or
// - LineNrAbove or LineNrBelow is used, or
@@ -1740,8 +1742,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
// hide virt_text on text hidden by 'nowrap' or 'smoothscroll'
decor_redraw_col(wp, (colnr_T)(ptr - line) - 1, wlv.off, true, &decor_state);
}
if (wlv.col >= grid->cols) {
wlv.col = wlv.off = grid->cols;
if (wlv.col >= view_width) {
wlv.col = wlv.off = view_width;
goto end_check;
}
}
@@ -1761,7 +1763,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
if (wp->w_p_cuc) {
wlv.row = wp->w_cline_row + wp->w_cline_height;
} else {
wlv.row = grid->rows;
wlv.row = view_height;
}
break;
}
@@ -1944,14 +1946,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
ptr = line + v;
}
if (draw_folded && wlv.n_extra == 0 && wlv.col < grid->cols && (has_foldtext || *ptr == NUL)) {
if (draw_folded && wlv.n_extra == 0 && wlv.col < view_width && (has_foldtext || *ptr == NUL)) {
// Fill rest of line with 'fold'.
wlv.sc_extra = wp->w_p_fcs_chars.fold;
wlv.sc_final = NUL;
wlv.n_extra = grid->cols - wlv.col;
wlv.n_extra = view_width - wlv.col;
}
if (draw_folded && wlv.n_extra != 0 && wlv.col >= grid->cols) {
if (draw_folded && wlv.n_extra != 0 && wlv.col >= view_width) {
// Truncate the folding.
wlv.n_extra = 0;
}
@@ -1981,7 +1983,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
// If a double-width char doesn't fit display a '>' in the last column.
// Don't advance the pointer but put the character at the start of the next line.
if (wlv.col >= grid->cols - 1 && schar_cells(mb_schar) == 2) {
if (wlv.col >= view_width - 1 && schar_cells(mb_schar) == 2) {
mb_c = '>';
mb_l = 1;
mb_schar = schar_from_ascii(mb_c);
@@ -2054,7 +2056,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
// initialize these.
mb_c = ' ';
mb_schar = schar_from_ascii(' ');
} else if (has_foldtext || (has_fold && wlv.col >= grid->cols)) {
} else if (has_foldtext || (has_fold && wlv.col >= view_width)) {
// skip writing the buffer line itself
mb_schar = NUL;
} else {
@@ -2104,7 +2106,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
// If a double-width char doesn't fit display a '>' in the
// last column; the character is displayed at the start of the
// next line.
if (wlv.col >= grid->cols - 1 && schar_cells(mb_schar) == 2) {
if (wlv.col >= view_width - 1 && schar_cells(mb_schar) == 2) {
mb_schar = schar_from_ascii('>');
mb_c = '>';
mb_l = 1;
@@ -2286,7 +2288,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
search_attr = 0;
}
if (mb_c == TAB && wlv.n_extra + wlv.col > grid->cols) {
if (mb_c == TAB && wlv.n_extra + wlv.col > view_width) {
wlv.n_extra = tabstop_padding(wlv.vcol, wp->w_buffer->b_p_ts,
wp->w_buffer->b_p_vts_array) - 1;
}
@@ -2478,7 +2480,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
|| ((wlv.fromcol >= 0 || fromcol_prev >= 0)
&& wlv.tocol > wlv.vcol
&& VIsual_mode != Ctrl_V
&& wlv.col < grid->cols
&& wlv.col < view_width
&& !(noinvcur
&& lnum == wp->w_cursor.lnum
&& wlv.vcol == wp->w_virtcol)))
@@ -2536,7 +2538,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
&& virtual_active(wp)
&& wlv.tocol != MAXCOL
&& wlv.vcol < wlv.tocol
&& wlv.col < grid->cols) {
&& wlv.col < view_width) {
mb_c = ' ';
mb_schar = schar_from_char(mb_c);
ptr--; // put it back at the NUL
@@ -2693,7 +2695,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
|| prevcol_hl_flag)) {
int n = 0;
if (wlv.col >= grid->cols) {
if (wlv.col >= view_width) {
n = -1;
}
if (n != 0) {
@@ -2748,13 +2750,13 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
decor_redraw_eol(wp, &decor_state, &wlv.line_attr, wlv.col + eol_skip);
}
for (int i = wlv.col; i < grid->cols; i++) {
for (int i = wlv.col; i < view_width; i++) {
linebuf_vcol[wlv.off + (i - wlv.col)] = wlv.vcol + (i - wlv.col);
}
if (((wp->w_p_cuc
&& wp->w_virtcol >= vcol_hlc(wlv) - eol_hl_off
&& wp->w_virtcol < grid->cols * (ptrdiff_t)(wlv.row - startrow + 1) + start_col
&& wp->w_virtcol < view_width * (ptrdiff_t)(wlv.row - startrow + 1) + start_col
&& lnum != wp->w_cursor.lnum)
|| wlv.color_cols || wlv.line_attr_lowprio || wlv.line_attr
|| wlv.diff_hlf != 0 || wp->w_buffer->terminal)) {
@@ -2776,7 +2778,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
rightmost_vcol = INT_MAX;
}
while (wlv.col < grid->cols) {
while (wlv.col < view_width) {
linebuf_char[wlv.off] = schar_from_ascii(' ');
advance_color_col(&wlv, vcol_hlc(wlv));
@@ -2809,7 +2811,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
}
if (kv_size(fold_vt) > 0) {
draw_virt_text_item(buf, win_col_offset, fold_vt, kHlModeCombine, grid->cols, 0, 0);
draw_virt_text_item(buf, win_col_offset, fold_vt, kHlModeCombine, view_width, 0, 0);
}
draw_virt_text(wp, buf, win_col_offset, &wlv.col, wlv.row);
// Set increasing virtual columns in grid->vcols[] to set correct curswant
@@ -2837,7 +2839,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
&& wp->w_p_list
&& !wp->w_p_wrap
&& wlv.filler_todo <= 0
&& wlv.col == grid->cols - 1
&& wlv.col == view_width - 1
&& !has_foldtext) {
if (has_decor && *ptr == NUL && lcs_eol == 0 && lcs_eol_todo) {
// Tricky: there might be a virtual text just _after_ the last char
@@ -2999,7 +3001,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
wlv.char_attr = saved_attr2;
}
if (has_decor && wlv.filler_todo <= 0 && wlv.col >= grid->cols) {
if (has_decor && wlv.filler_todo <= 0 && wlv.col >= view_width) {
// At the end of screen line: might need to peek for decorations just after
// this position.
if (is_wrapped && wlv.n_extra == 0) {
@@ -3017,31 +3019,31 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
end_check:
// At end of screen line and there is more to come: Display the line
// so far. If there is no more to display it is caught above.
if (wlv.col >= grid->cols && (!has_foldtext || virt_line_index >= 0)
if (wlv.col >= view_width && (!has_foldtext || virt_line_index >= 0)
&& (wlv.col <= leftcols_width
|| *ptr != NUL
|| wlv.filler_todo > 0
|| (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL && lcs_eol_todo)
|| (wlv.n_extra != 0 && (wlv.sc_extra != NUL || *wlv.p_extra != NUL))
|| (may_have_inline_virt && has_more_inline_virt(&wlv, ptr - line)))) {
const bool wrap = is_wrapped // Wrapping enabled (not a folded line).
&& wlv.filler_todo <= 0 // Not drawing diff filler lines.
&& lcs_eol_todo // Haven't printed the lcs_eol character.
&& wlv.row != endrow - 1 // Not the last line being displayed.
&& (grid->cols == Columns // Window spans the width of the screen,
|| ui_has(kUIMultigrid)) // or has dedicated grid.
&& !wp->w_p_rl; // Not right-to-left.
const bool wrap = is_wrapped // Wrapping enabled (not a folded line).
&& wlv.filler_todo <= 0 // Not drawing diff filler lines.
&& lcs_eol_todo // Haven't printed the lcs_eol character.
&& wlv.row != endrow - 1 // Not the last line being displayed.
&& (view_width == Columns // Window spans the width of the screen,
|| wp->w_grid_alloc.chars) // or has dedicated grid.
&& !wp->w_p_rl; // Not right-to-left.
int draw_col = wlv.col - wlv.boguscols;
for (int i = draw_col; i < grid->cols; i++) {
for (int i = draw_col; i < view_width; i++) {
linebuf_vcol[wlv.off + (i - draw_col)] = wlv.vcol - 1;
}
// Apply 'cursorline' highlight.
if (wlv.boguscols != 0 && (wlv.line_attr_lowprio != 0 || wlv.line_attr != 0)) {
int attr = hl_combine_attr(wlv.line_attr_lowprio, wlv.line_attr);
while (draw_col < grid->cols) {
while (draw_col < view_width) {
linebuf_char[wlv.off] = schar_from_char(' ');
linebuf_attr[wlv.off] = attr;
// linebuf_vcol[] already filled by the for loop above
@@ -3055,7 +3057,7 @@ end_check:
virt_line_flags & kVLLeftcol ? 0 : win_col_offset,
kv_A(virt_lines, virt_line_index).line,
kHlModeReplace,
grid->cols,
view_width,
0,
virt_line_flags & kVLScroll ? wp->w_leftcol : 0);
} else if (wlv.filler_todo <= 0) {
@@ -3064,10 +3066,9 @@ end_check:
wlv_put_linebuf(wp, &wlv, draw_col, true, bg_attr, wrap ? SLF_WRAP : 0);
if (wrap) {
ScreenGrid *current_grid = grid;
int current_row = wlv.row;
int dummy_col = 0; // unused
grid_adjust(&current_grid, &current_row, &dummy_col);
ScreenGrid *current_grid = grid_adjust(grid, &current_row, &dummy_col);
// Force a redraw of the first column of the next line.
current_grid->attrs[current_grid->line_offset[current_row + 1]] = -1;
@@ -3084,7 +3085,7 @@ end_check:
// When the window is too narrow draw all "@" lines.
if (wlv.col <= leftcols_width) {
win_draw_end(wp, schar_from_ascii('@'), true, wlv.row, wp->w_grid.rows, HLF_AT);
win_draw_end(wp, schar_from_ascii('@'), true, wlv.row, wp->w_view_height, HLF_AT);
set_empty_rows(wp, wlv.row);
wlv.row = endrow;
}
@@ -3132,14 +3133,14 @@ end_check:
static void wlv_put_linebuf(win_T *wp, const winlinevars_T *wlv, int endcol, bool clear_end,
int bg_attr, int flags)
{
ScreenGrid *grid = &wp->w_grid;
GridView *grid = &wp->w_grid;
int startcol = 0;
int clear_width = clear_end ? grid->cols : endcol;
int clear_width = clear_end ? wp->w_view_width : endcol;
assert(!(flags & SLF_RIGHTLEFT));
if (wp->w_p_rl) {
linebuf_mirror(&startcol, &endcol, &clear_width, grid->cols);
linebuf_mirror(&startcol, &endcol, &clear_width, wp->w_view_width);
flags |= SLF_RIGHTLEFT;
}
@@ -3152,13 +3153,13 @@ static void wlv_put_linebuf(win_T *wp, const winlinevars_T *wlv, int endcol, boo
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]))) {
while (off < wp->w_view_width && 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) {
for (int i = 0; i < 3 && off < wp->w_view_width; i++) {
if (off + 1 < wp->w_view_width && 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(' ');
@@ -3171,6 +3172,6 @@ static void wlv_put_linebuf(win_T *wp, const winlinevars_T *wlv, int endcol, boo
int row = wlv->row;
int coloff = 0;
grid_adjust(&grid, &row, &coloff);
grid_put_linebuf(grid, row, coloff, startcol, endcol, clear_width, bg_attr, wlv->vcol - 1, flags);
ScreenGrid *g = grid_adjust(grid, &row, &coloff);
grid_put_linebuf(g, row, coloff, startcol, endcol, clear_width, bg_attr, wlv->vcol - 1, flags);
}