aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-03-03 18:13:53 +0800
committerzeertzjq <zeertzjq@outlook.com>2023-03-03 19:28:56 +0800
commitbdde07f60ee452ea598b631be24609134654762a (patch)
tree8658b69d79c9668350319ca10afa9f4285e4be6a
parenta7dbfec9f3b7385b87588e09aeb20e2bf0b5fccd (diff)
downloadrneovim-bdde07f60ee452ea598b631be24609134654762a.tar.gz
rneovim-bdde07f60ee452ea598b631be24609134654762a.tar.bz2
rneovim-bdde07f60ee452ea598b631be24609134654762a.zip
vim-patch:9.0.0533: the win_line() function is much too long
Problem: The win_line() function is much too long. Solution: Move code to separate functions. https://github.com/vim/vim/commit/e49f9acecc03755db850410b2590ad7312c5224b Co-authored-by: Bram Moolenaar <Bram@vim.org>
-rw-r--r--src/nvim/drawline.c189
1 files changed, 103 insertions, 86 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index 1a4f718c11..dbbeabbba2 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -92,6 +92,7 @@ typedef struct {
int fromcol; ///< start of inverting
int tocol; ///< end of inverting
+ long vcol_sbr; ///< virtual column after showbreak
bool need_showbreak; ///< overlong line, skipping first x chars
int char_attr; ///< attributes for next character
@@ -104,10 +105,18 @@ typedef struct {
int c_extra; ///< extra chars, all the same
int c_final; ///< final char, mandatory if set
+ // saved "extra" items for when draw_state becomes WL_LINE (again)
+ int saved_n_extra;
+ char *saved_p_extra;
+ int saved_c_extra;
+ int saved_c_final;
+ int saved_char_attr;
+
char extra[57]; ///< sign, line number and 'fdc' must fit in here
hlf_T diff_hlf; ///< type of diff highlighting
+ int n_virt_lines; ///< nr of virtual lines
int filler_lines; ///< nr of filler lines to be drawn
int filler_todo; ///< nr of filler lines still to do + 1
SignTextAttrs sattrs[SIGN_SHOW_MAX]; ///< sign attributes for the sign column
@@ -689,6 +698,60 @@ static void handle_breakindent(win_T *wp, winlinevars_T *wlv)
}
}
+static void handle_showbreak_and_filler(win_T *wp, winlinevars_T *wlv)
+{
+ 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.
+ wlv->c_extra = ' ';
+ wlv->c_final = NUL;
+ if (wp->w_p_rl) {
+ wlv->n_extra = wlv->col + 1;
+ } else {
+ wlv->n_extra = wp->w_grid.cols - wlv->col;
+ }
+ wlv->char_attr = 0;
+ } else if (wlv->filler_todo > 0) {
+ // Draw "deleted" diff line(s)
+ if (char2cells(wp->w_p_fcs_chars.diff) > 1) {
+ wlv->c_extra = '-';
+ wlv->c_final = NUL;
+ } else {
+ wlv->c_extra = wp->w_p_fcs_chars.diff;
+ wlv->c_final = NUL;
+ }
+ if (wp->w_p_rl) {
+ wlv->n_extra = wlv->col + 1;
+ } else {
+ wlv->n_extra = wp->w_grid.cols - wlv->col;
+ }
+ wlv->char_attr = win_hl_attr(wp, HLF_DED);
+ }
+
+ char *const sbr = get_showbreak_value(wp);
+ if (*sbr != NUL && wlv->need_showbreak) {
+ // Draw 'showbreak' at the start of each broken line.
+ wlv->p_extra = sbr;
+ wlv->c_extra = NUL;
+ wlv->c_final = NUL;
+ wlv->n_extra = (int)strlen(sbr);
+ wlv->char_attr = win_hl_attr(wp, HLF_AT);
+ if (wp->w_skipcol == 0 || !wp->w_p_wrap) {
+ wlv->need_showbreak = false;
+ }
+ wlv->vcol_sbr = wlv->vcol + mb_charlen(sbr);
+ // Correct end of highlighted area for 'showbreak',
+ // required when 'linebreak' is also set.
+ if (wlv->tocol == wlv->vcol) {
+ wlv->tocol += wlv->n_extra;
+ }
+ // Combine 'showbreak' with 'cursorline', prioritizing 'showbreak'.
+ if (wlv->cul_attr) {
+ wlv->char_attr = hl_combine_attr(wlv->cul_attr, wlv->char_attr);
+ }
+ }
+}
+
static void apply_cursorline_highlight(win_T *wp, winlinevars_T *wlv)
{
wlv->cul_attr = win_hl_attr(wp, HLF_CUL);
@@ -756,10 +819,11 @@ static colnr_T get_leadcol(win_T *wp, const char *ptr, const char *line)
}
/// Start a screen line at column zero.
-static void win_line_start(win_T *wp, winlinevars_T *wlv)
+static void win_line_start(win_T *wp, winlinevars_T *wlv, bool save_extra)
{
wlv->col = 0;
wlv->off = 0;
+
if (wp->w_p_rl) {
// Rightleft window: process the text in the normal direction, but put
// it in linebuf_char[wlv.off] from right to left. Start at the
@@ -767,6 +831,33 @@ static void win_line_start(win_T *wp, winlinevars_T *wlv)
wlv->col = wp->w_grid.cols - 1;
wlv->off += wlv->col;
}
+
+ if (save_extra) {
+ // reset the drawing state for the start of a wrapped line
+ wlv->draw_state = WL_START;
+ wlv->saved_n_extra = wlv->n_extra;
+ wlv->saved_p_extra = wlv->p_extra;
+ wlv->saved_c_extra = wlv->c_extra;
+ wlv->saved_c_final = wlv->c_final;
+ wlv->saved_char_attr = wlv->char_attr;
+
+ wlv->n_extra = 0;
+ }
+}
+
+/// Called when wlv->draw_state is set to WL_LINE.
+static void win_line_continue(winlinevars_T *wlv)
+{
+ if (wlv->saved_n_extra > 0) {
+ // Continue item from end of wrapped line.
+ wlv->n_extra = wlv->saved_n_extra;
+ wlv->c_extra = wlv->saved_c_extra;
+ wlv->c_final = wlv->saved_c_final;
+ wlv->p_extra = wlv->saved_p_extra;
+ wlv->char_attr = wlv->saved_char_attr;
+ } else {
+ wlv->char_attr = 0;
+ }
}
/// Display line "lnum" of window 'wp' on the screen.
@@ -789,7 +880,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
winlinevars_T wlv; // variables passed between functions
int c = 0; // init for GCC
- long vcol_sbr = -1; // virtual column after showbreak
long vcol_prev = -1; // "wlv.vcol" of previous character
char *line; // current line
char *ptr; // current position in "line"
@@ -799,13 +889,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
// at end-of-line
bool has_fold = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0;
- // saved "extra" items for when draw_state becomes WL_LINE (again)
- int saved_n_extra = 0;
- char *saved_p_extra = NULL;
- int saved_c_extra = 0;
- int saved_c_final = 0;
- int saved_char_attr = 0;
-
int n_attr = 0; // chars with special attr
int saved_attr2 = 0; // char_attr saved for n_attr
int n_attr3 = 0; // chars with overruling special attr
@@ -907,6 +990,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
wlv.row = startrow;
wlv.fromcol = -10;
wlv.tocol = MAXCOL;
+ wlv.vcol_sbr = -1;
buf_T *buf = wp->w_buffer;
bool end_fill = (lnum == buf->b_ml.ml_line_count + 1);
@@ -1103,11 +1187,11 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
area_highlighting = true;
}
VirtLines virt_lines = KV_INITIAL_VALUE;
- int n_virt_lines = decor_virt_lines(wp, lnum, &virt_lines, has_fold);
- wlv.filler_lines += n_virt_lines;
+ wlv.n_virt_lines = decor_virt_lines(wp, lnum, &virt_lines, has_fold);
+ wlv.filler_lines += wlv.n_virt_lines;
if (lnum == wp->w_topline) {
wlv.filler_lines = wp->w_topfill;
- n_virt_lines = MIN(n_virt_lines, wlv.filler_lines);
+ wlv.n_virt_lines = MIN(wlv.n_virt_lines, wlv.filler_lines);
}
wlv.filler_todo = wlv.filler_lines;
@@ -1323,7 +1407,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
ptr = line + v; // "line" may have been updated
}
- win_line_start(wp, &wlv);
+ win_line_start(wp, &wlv, false);
// won't highlight after TERM_ATTRS_MAX columns
int term_attrs[TERM_ATTRS_MAX] = { 0 };
@@ -1375,7 +1459,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
if (wlv.draw_state == WL_FOLD - 1 && wlv.n_extra == 0) {
if (wlv.filler_todo > 0) {
- int index = wlv.filler_todo - (wlv.filler_lines - n_virt_lines);
+ int index = wlv.filler_todo - (wlv.filler_lines - wlv.n_virt_lines);
if (index > 0) {
virt_line_index = (int)kv_size(virt_lines) - index;
assert(virt_line_index >= 0);
@@ -1443,76 +1527,17 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
if (wlv.draw_state == WL_SBR - 1 && wlv.n_extra == 0) {
wlv.draw_state = WL_SBR;
- if (wlv.filler_todo > wlv.filler_lines - n_virt_lines) {
- // TODO(bfredl): check this doesn't inhibit TUI-style
- // clear-to-end-of-line.
- wlv.c_extra = ' ';
- wlv.c_final = NUL;
- if (wp->w_p_rl) {
- wlv.n_extra = wlv.col + 1;
- } else {
- wlv.n_extra = grid->cols - wlv.col;
- }
- wlv.char_attr = 0;
- } else if (wlv.filler_todo > 0) {
- // Draw "deleted" diff line(s)
- if (char2cells(wp->w_p_fcs_chars.diff) > 1) {
- wlv.c_extra = '-';
- wlv.c_final = NUL;
- } else {
- wlv.c_extra = wp->w_p_fcs_chars.diff;
- wlv.c_final = NUL;
- }
- if (wp->w_p_rl) {
- wlv.n_extra = wlv.col + 1;
- } else {
- wlv.n_extra = grid->cols - wlv.col;
- }
- wlv.char_attr = win_hl_attr(wp, HLF_DED);
- }
- char *const sbr = get_showbreak_value(wp);
- if (*sbr != NUL && wlv.need_showbreak) {
- // Draw 'showbreak' at the start of each broken line.
- wlv.p_extra = sbr;
- wlv.c_extra = NUL;
- wlv.c_final = NUL;
- wlv.n_extra = (int)strlen(sbr);
- wlv.char_attr = win_hl_attr(wp, HLF_AT);
- if (wp->w_skipcol == 0 || !wp->w_p_wrap) {
- wlv.need_showbreak = false;
- }
- vcol_sbr = wlv.vcol + mb_charlen(sbr);
- // Correct end of highlighted area for 'showbreak',
- // required when 'linebreak' is also set.
- if (wlv.tocol == wlv.vcol) {
- wlv.tocol += wlv.n_extra;
- }
- // Combine 'showbreak' with 'cursorline', prioritizing 'showbreak'.
- if (wlv.cul_attr) {
- wlv.char_attr = hl_combine_attr(wlv.cul_attr, wlv.char_attr);
- }
- }
+ handle_showbreak_and_filler(wp, &wlv);
}
if (wlv.draw_state == WL_LINE - 1 && wlv.n_extra == 0) {
sign_idx = 0;
wlv.draw_state = WL_LINE;
-
if (has_decor && wlv.row == startrow + wlv.filler_lines) {
// hide virt_text on text hidden by 'nowrap'
decor_redraw_col(wp->w_buffer, wlv.vcol, wlv.off, true, &decor_state);
}
-
- if (saved_n_extra) {
- // Continue item from end of wrapped line.
- wlv.n_extra = saved_n_extra;
- wlv.c_extra = saved_c_extra;
- wlv.c_final = saved_c_final;
- wlv.p_extra = saved_p_extra;
- wlv.char_attr = saved_char_attr;
- } else {
- wlv.char_attr = 0;
- }
+ win_line_continue(&wlv); // use wlv.saved_ values
}
}
@@ -2011,7 +2036,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
// We have just drawn the showbreak value, no need to add
// space for it again.
- if (wlv.vcol == vcol_sbr) {
+ if (wlv.vcol == wlv.vcol_sbr) {
wlv.n_extra -= mb_charlen(get_showbreak_value(wp));
if (wlv.n_extra < 0) {
wlv.n_extra = 0;
@@ -2112,7 +2137,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
// Only adjust the tab_len, when at the first column after the
// showbreak value was drawn.
- if (*sbr != NUL && wlv.vcol == vcol_sbr && wp->w_p_wrap) {
+ if (*sbr != NUL && wlv.vcol == wlv.vcol_sbr && wp->w_p_wrap) {
vcol_adjusted = wlv.vcol - mb_charlen(sbr);
}
// tab amount depends on current column
@@ -2850,16 +2875,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
break;
}
- win_line_start(wp, &wlv);
+ win_line_start(wp, &wlv, true);
- // reset the drawing state for the start of a wrapped line
- wlv.draw_state = WL_START;
- saved_n_extra = wlv.n_extra;
- saved_p_extra = wlv.p_extra;
- saved_c_extra = wlv.c_extra;
- saved_c_final = wlv.c_final;
- saved_char_attr = wlv.char_attr;
- wlv.n_extra = 0;
lcs_prec_todo = wp->w_p_lcs_chars.prec;
if (wlv.filler_todo <= 0) {
wlv.need_showbreak = true;