diff options
author | Björn Linse <bjorn.linse@gmail.com> | 2020-09-21 14:50:24 +0200 |
---|---|---|
committer | Björn Linse <bjorn.linse@gmail.com> | 2020-09-24 19:31:58 +0200 |
commit | a958039f0ad7cd4f6a139fde18795c88c623a30e (patch) | |
tree | ad295c6bd9680e69132bba6f3575aa1ee8a702cf | |
parent | f8134f2fd1e2effe79d011b1ff12ebb8719c3ffe (diff) | |
download | rneovim-a958039f0ad7cd4f6a139fde18795c88c623a30e.tar.gz rneovim-a958039f0ad7cd4f6a139fde18795c88c623a30e.tar.bz2 rneovim-a958039f0ad7cd4f6a139fde18795c88c623a30e.zip |
screen: more work on fold_line replacement
-rw-r--r-- | src/nvim/eval/funcs.c | 9 | ||||
-rw-r--r-- | src/nvim/fold.c | 44 | ||||
-rw-r--r-- | src/nvim/fold.h | 1 | ||||
-rw-r--r-- | src/nvim/screen.c | 67 | ||||
-rw-r--r-- | test/functional/ui/fold_spec.lua | 24 |
5 files changed, 67 insertions, 78 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 3a4b4f2a50..bd77a3b7e2 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -2584,8 +2584,6 @@ static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr) { char_u *text; char_u buf[FOLD_TEXT_LEN]; - foldinfo_T foldinfo; - int fold_count; static bool entered = false; rettv->v_type = VAR_STRING; @@ -2599,9 +2597,10 @@ static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (lnum < 0) { lnum = 0; } - fold_count = foldedCount(curwin, lnum, &foldinfo); - if (fold_count > 0) { - text = get_foldtext(curwin, lnum, lnum + fold_count - 1, &foldinfo, buf); + + foldinfo_T info = fold_info(curwin, lnum); + if (info.fi_lines > 0) { + text = get_foldtext(curwin, lnum, lnum + info.fi_lines - 1, info, buf); if (text == buf) { text = vim_strsave(text); } diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 9994ad3ea8..9188ae6571 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -280,26 +280,31 @@ int foldLevel(linenr_T lnum) // Return false if line is not folded. bool lineFolded(win_T *const win, const linenr_T lnum) { - return foldedCount(win, lnum, NULL) != 0; + return fold_info(win, lnum).fi_lines != 0; } -/* foldedCount() {{{2 */ -/* - * Count the number of lines that are folded at line number "lnum". - * Normally "lnum" is the first line of a possible fold, and the returned - * number is the number of lines in the fold. - * Doesn't use caching from the displayed window. - * Returns number of folded lines from "lnum", or 0 if line is not folded. - * When "infop" is not NULL, fills *infop with the fold level info. - */ -long foldedCount(win_T *win, linenr_T lnum, foldinfo_T *infop) +/// fold_info() {{{2 +/// +/// Count the number of lines that are folded at line number "lnum". +/// Normally "lnum" is the first line of a possible fold, and the returned +/// number is the number of lines in the fold. +/// Doesn't use caching from the displayed window. +/// +/// @return with the fold level info. +/// fi_lines = number of folded lines from "lnum", +/// or 0 if line is not folded. +foldinfo_T fold_info(win_T *win, linenr_T lnum) { + foldinfo_T info; linenr_T last; - if (hasFoldingWin(win, lnum, NULL, &last, false, infop)) { - return (long)(last - lnum + 1); + if (hasFoldingWin(win, lnum, NULL, &last, false, &info)) { + info.fi_lines = (long)(last - lnum + 1); + } else { + info.fi_lines = 0; } - return 0; + + return info; } /* foldmethodIsManual() {{{2 */ @@ -1755,7 +1760,7 @@ static void foldDelMarker( /// When 'foldtext' isn't set puts the result in "buf[FOLD_TEXT_LEN]". /// Otherwise the result is in allocated memory. char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, - foldinfo_T *foldinfo, char_u *buf) + foldinfo_T foldinfo, char_u *buf) FUNC_ATTR_NONNULL_ARG(1) { char_u *text = NULL; @@ -1783,11 +1788,12 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, set_vim_var_nr(VV_FOLDSTART, (varnumber_T) lnum); set_vim_var_nr(VV_FOLDEND, (varnumber_T) lnume); - /* Set "v:folddashes" to a string of "level" dashes. */ - /* Set "v:foldlevel" to "level". */ - level = foldinfo->fi_level; - if (level > (int)sizeof(dashes) - 1) + // Set "v:folddashes" to a string of "level" dashes. + // Set "v:foldlevel" to "level". + level = foldinfo.fi_level; + if (level > (int)sizeof(dashes) - 1) { level = (int)sizeof(dashes) - 1; + } memset(dashes, '-', (size_t)level); dashes[level] = NUL; set_vim_var_string(VV_FOLDDASHES, dashes, -1); diff --git a/src/nvim/fold.h b/src/nvim/fold.h index f35b328fb1..95c4b0c1dc 100644 --- a/src/nvim/fold.h +++ b/src/nvim/fold.h @@ -18,6 +18,7 @@ typedef struct foldinfo { other fields are invalid */ int fi_low_level; /* lowest fold level that starts in the same line */ + long fi_lines; } foldinfo_T; diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 9dc5774e86..f3fdafcc70 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -133,8 +133,6 @@ static sattr_T *linebuf_attr = NULL; static match_T search_hl; /* used for 'hlsearch' highlight matching */ -static foldinfo_T win_foldinfo; /* info for 'foldcolumn' */ - StlClickDefinition *tab_page_click_defs = NULL; long tab_page_click_defs_size = 0; @@ -702,7 +700,6 @@ static void win_update(win_T *wp) long j; static int recursive = FALSE; /* being called recursively */ int old_botline = wp->w_botline; - long folded_lines; // rename to folded_lines instead // Remember what happened to the previous line. #define DID_NONE 1 // didn't update a line #define DID_LINE 2 // updated a normal line @@ -713,6 +710,7 @@ static void win_update(win_T *wp) linenr_T mod_bot = 0; int save_got_int; + // If we can compute a change in the automatic sizing of the sign column // under 'signcolumn=auto:X' and signs currently placed in the buffer, better // figuring it out here so we can redraw the entire screen for it. @@ -1229,7 +1227,6 @@ static void win_update(win_T *wp) // Set the time limit to 'redrawtime'. proftime_T syntax_tm = profile_setlimit(p_rdt); syn_set_timeout(&syntax_tm); - win_foldinfo.fi_level = 0; /* * Update all the window rows. @@ -1459,9 +1456,9 @@ static void win_update(win_T *wp) * Otherwise, display normally (can be several display lines when * 'wrap' is on). */ - folded_lines = foldedCount(wp, lnum, &win_foldinfo); + foldinfo_T foldinfo = fold_info(wp, lnum); - if (folded_lines == 0 + if (foldinfo.fi_lines == 0 && idx < wp->w_lines_valid && wp->w_lines[idx].wl_valid && wp->w_lines[idx].wl_lnum == lnum @@ -1482,18 +1479,17 @@ static void win_update(win_T *wp) // Display one line row = win_line(wp, lnum, srow, - folded_lines ? srow : wp->w_grid.Rows, - mod_top == 0, false, - &win_foldinfo, folded_lines); + foldinfo.fi_lines ? srow : wp->w_grid.Rows, + mod_top == 0, false, foldinfo); - wp->w_lines[idx].wl_folded = folded_lines != 0; + wp->w_lines[idx].wl_folded = foldinfo.fi_lines != 0; wp->w_lines[idx].wl_lastlnum = lnum; did_update = DID_LINE; - if (folded_lines > 0) { + if (foldinfo.fi_lines > 0) { did_update = DID_FOLD; - folded_lines--; - wp->w_lines[idx].wl_lastlnum = lnum + folded_lines; + foldinfo.fi_lines--; + wp->w_lines[idx].wl_lastlnum = lnum + foldinfo.fi_lines; } syntax_last_parsed = lnum; @@ -1514,14 +1510,13 @@ static void win_update(win_T *wp) wp->w_lines[idx].wl_size = row - srow; } idx++; - lnum += folded_lines + 1; + lnum += foldinfo.fi_lines + 1; } else { if (wp->w_p_rnu) { // 'relativenumber' set: The text doesn't need to be drawn, but // the number column nearly always does. - folded_lines = foldedCount(wp, lnum, &win_foldinfo); - (void)win_line(wp, lnum, srow, wp->w_grid.Rows, true, true, - &win_foldinfo, folded_lines); + foldinfo_T info = fold_info(wp, lnum); + (void)win_line(wp, lnum, srow, wp->w_grid.Rows, true, true, info); } // This line does not need to be drawn, advance to the next one. @@ -1831,7 +1826,7 @@ static size_t fill_foldcolumn( char_u *p, win_T *wp, - int closed, + foldinfo_T foldinfo, linenr_T lnum ) { @@ -1842,10 +1837,11 @@ fill_foldcolumn( size_t char_counter = 0; int symbol = 0; int len = 0; + bool closed = foldinfo.fi_lines > 0; // Init to all spaces. memset(p, ' ', MAX_MCO * fdc + 1); - level = win_foldinfo.fi_level; + level = foldinfo.fi_level; // If the column is too narrow, we start at the lowest level that // fits and use numbers to indicated the depth. @@ -1855,8 +1851,8 @@ fill_foldcolumn( } for (i = 0; i < MIN(fdc, level); i++) { - if (win_foldinfo.fi_lnum == lnum - && first_level + i >= win_foldinfo.fi_low_level) { + if (foldinfo.fi_lnum == lnum + && first_level + i >= foldinfo.fi_low_level) { symbol = wp->w_p_fcs_chars.foldopen; } else if (first_level == 1) { symbol = wp->w_p_fcs_chars.foldsep; @@ -1896,8 +1892,7 @@ fill_foldcolumn( /// @param endrow stop drawing once reaching this row /// @param nochange not updating for changed text /// @param number_only only update the number column -/// @param[in] foldinfo fold info for this line -/// @param folded_lines Number returned by \ref foldedCount +/// @param foldinfo fold info for this line /// /// @return the number of last row the line occupies. static int @@ -1908,8 +1903,7 @@ win_line ( int endrow, bool nochange, bool number_only, - foldinfo_T *foldinfo, - long folded_lines + foldinfo_T foldinfo ) { int c = 0; // init for GCC @@ -2567,7 +2561,7 @@ win_line ( // already be in use. xfree(p_extra_free); p_extra_free = xmalloc(MAX_MCO * fdc + 1); - n_extra = fill_foldcolumn(p_extra_free, wp, folded_lines > 0, lnum); + n_extra = fill_foldcolumn(p_extra_free, wp, foldinfo, lnum); p_extra_free[n_extra] = NUL; p_extra = p_extra_free; c_extra = NUL; @@ -2794,22 +2788,21 @@ win_line ( } if (draw_state == WL_LINE - && foldinfo->fi_level != 0 - && folded_lines > 0 + && foldinfo.fi_level != 0 + && foldinfo.fi_lines > 0 && vcol == 0 && n_extra == 0 && row == startrow) { char_attr = win_hl_attr(wp, HLF_FL); - linenr_T lnume = lnum + folded_lines - 1; + linenr_T lnume = lnum + foldinfo.fi_lines - 1; memset(buf_fold, ' ', FOLD_TEXT_LEN); p_extra = get_foldtext(wp, lnum, lnume, foldinfo, buf_fold); n_extra = STRLEN(p_extra); if (p_extra != buf_fold) { xfree(p_extra_free); - p_extra_free = vim_strsave(p_extra); - p_extra = p_extra_free; + p_extra_free = p_extra; } c_extra = NUL; c_final = NUL; @@ -2817,8 +2810,8 @@ win_line ( } if (draw_state == WL_LINE - && foldinfo->fi_level != 0 - && folded_lines > 0 + && foldinfo.fi_level != 0 + && foldinfo.fi_lines > 0 && col < grid->Columns && n_extra == 0 && row == startrow) { @@ -2826,7 +2819,7 @@ win_line ( c_extra = wp->w_p_fcs_chars.fold; c_final = NUL; - n_extra = grid->Columns - col; + n_extra = wp->w_p_rl ? (col + 1) : (grid->Columns - col); } if (draw_state == WL_LINE && (area_highlighting || has_spell)) { @@ -3057,7 +3050,7 @@ win_line ( p_extra++; } n_extra--; - } else if (folded_lines > 0) { + } else if (foldinfo.fi_lines > 0) { // skip writing the buffer line itself c = NUL; XFREE_CLEAR(p_extra_free); @@ -3939,7 +3932,7 @@ win_line ( if (wp == curwin && lnum == curwin->w_cursor.lnum) { curwin->w_cline_row = startrow; curwin->w_cline_height = row - startrow; - curwin->w_cline_folded = folded_lines > 0; + curwin->w_cline_folded = foldinfo.fi_lines > 0; curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW); conceal_cursor_used = conceal_cursor_line(curwin); } @@ -4131,7 +4124,7 @@ win_line ( * so far. If there is no more to display it is caught above. */ if ((wp->w_p_rl ? (col < 0) : (col >= grid->Columns)) - && folded_lines == 0 + && foldinfo.fi_lines == 0 && (*ptr != NUL || filler_todo > 0 || (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL diff --git a/test/functional/ui/fold_spec.lua b/test/functional/ui/fold_spec.lua index 9fe4b2580f..fe67b9f6b0 100644 --- a/test/functional/ui/fold_spec.lua +++ b/test/functional/ui/fold_spec.lua @@ -132,27 +132,17 @@ describe("folded lines", function() ]]) feed('vkzf') - -- screen:snapshot_util() - -- screen:expect([[ - -- {5:^+-- 2 lines: å 语 x̎͛ العَرَبِيَّة········ - -- {1:~ }| - -- {1:~ }| - -- {1:~ }| - -- {1:~ }| - -- {1:~ }| - -- {1:~ }| - -- | - -- ]]) screen:expect{grid=[[ - {5:^+-- 2 lines: å 语 x̎͛ العَرَبِيَّة·················}| + {5:^+-- 2 lines: å 语 x̎͂̀̂͛͛ العَرَبِيَّة·················}| {1:~ }| {1:~ }| {1:~ }| {1:~ }| {1:~ }| {1:~ }| - | + | ]]} + feed_command("set noarabicshape") screen:expect([[ {5:^+-- 2 lines: å 语 x̎͂̀̂͛͛ العَرَبِيَّة·················}| @@ -167,7 +157,7 @@ describe("folded lines", function() feed_command("set number foldcolumn=2") screen:expect([[ - {7:+ }{5: 1 ^+-- 2 lines: å 语 x̎͂̀̂͛͛ العَرَبِيَّة···········}| + {7:+ }{8: 1 }{5:^+-- 2 lines: å 语 x̎͂̀̂͛͛ العَرَبِيَّة···········}| {1:~ }| {1:~ }| {1:~ }| @@ -180,7 +170,7 @@ describe("folded lines", function() -- Note: too much of the folded line gets cut off.This is a vim bug. feed_command("set rightleft") screen:expect([[ - {5:+-- 2 lines: å ······················^· 1 }{7: +}| + {5:···········ةيَّبِرَعَلا x̎͂̀̂͛͛ 语 å :senil 2 --^+}{8: 1 }{7: +}| {1: ~}| {1: ~}| {1: ~}| @@ -192,7 +182,7 @@ describe("folded lines", function() feed_command("set nonumber foldcolumn=0") screen:expect([[ - {5:+-- 2 lines: å 语 x̎͂̀̂͛͛ ال·····················^·}| + {5:·················ةيَّبِرَعَلا x̎͂̀̂͛͛ 语 å :senil 2 --^+}| {1: ~}| {1: ~}| {1: ~}| @@ -204,7 +194,7 @@ describe("folded lines", function() feed_command("set arabicshape") screen:expect([[ - {5:+-- 2 lines: å 语 x̎͂̀̂͛͛ ﺍﻟ·····················^·}| + {5:·················ةيَّبِرَعَلا x̎͂̀̂͛͛ 语 å :senil 2 --^+}| {1: ~}| {1: ~}| {1: ~}| |