diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-03-03 18:13:53 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2023-03-03 19:28:56 +0800 |
commit | bdde07f60ee452ea598b631be24609134654762a (patch) | |
tree | 8658b69d79c9668350319ca10afa9f4285e4be6a | |
parent | a7dbfec9f3b7385b87588e09aeb20e2bf0b5fccd (diff) | |
download | rneovim-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.c | 189 |
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; |