aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/drawline.c
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2023-09-20 10:08:05 +0200
committerbfredl <bjorn.linse@gmail.com>2023-09-29 15:38:25 +0200
commite33269578b5bea2528cc48afc5b009eb8d4ad1d6 (patch)
tree7f96465b64cd638d0b247932e7075a8ea587faf2 /src/nvim/drawline.c
parentaf7d317f3ff31d5ac5d8724b5057a422e1451b54 (diff)
downloadrneovim-e33269578b5bea2528cc48afc5b009eb8d4ad1d6.tar.gz
rneovim-e33269578b5bea2528cc48afc5b009eb8d4ad1d6.tar.bz2
rneovim-e33269578b5bea2528cc48afc5b009eb8d4ad1d6.zip
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.
Diffstat (limited to 'src/nvim/drawline.c')
-rw-r--r--src/nvim/drawline.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index 9da421e79b..5baaa913b3 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -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))
&& wlv.filler_todo <= 0) {
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
// 'cursorcolumn' is set.
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);
}
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++;
// 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);
}
- 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) {
ScreenGrid *current_grid = grid;
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);
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);
+}