diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2019-12-26 07:06:43 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-26 07:06:43 +0100 |
commit | b0196586debd55b9b8be62966084eee12bf0e4ad (patch) | |
tree | 738e9c21a57e31950420cb0533b8a8b2a8838eb0 | |
parent | 927a4f24e09e879ae1006aab32ead81985c61865 (diff) | |
parent | bbad324b175f1bd35201f0ba73fba1b11af7093d (diff) | |
download | rneovim-b0196586debd55b9b8be62966084eee12bf0e4ad.tar.gz rneovim-b0196586debd55b9b8be62966084eee12bf0e4ad.tar.bz2 rneovim-b0196586debd55b9b8be62966084eee12bf0e4ad.zip |
Merge #11568 'fillchars: foldopen, foldsep, foldclose'
-rw-r--r-- | runtime/doc/options.txt | 3 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 3 | ||||
-rw-r--r-- | src/nvim/mouse.c | 2 | ||||
-rw-r--r-- | src/nvim/option.c | 3 | ||||
-rw-r--r-- | src/nvim/screen.c | 139 | ||||
-rw-r--r-- | test/functional/ui/fold_spec.lua | 39 |
6 files changed, 125 insertions, 64 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 4b8740c5d2..519cbf66b1 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -2371,6 +2371,9 @@ A jump table for the options with a short description can be found at |Q_op|. stlnc:c ' ' or '=' statusline of the non-current windows vert:c '│' or '|' vertical separators |:vsplit| fold:c '·' or '-' filling 'foldtext' + foldopen:c '-' mark the beginning of a fold + foldclose:c '+' show a closed fold + foldsep:c '|' open fold middle marker diff:c '-' deleted lines of the 'diff' option msgsep:c ' ' message separator 'display' eob:c '~' empty lines at the end of a buffer diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index bc4fb2997d..265fc05f67 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -1126,6 +1126,9 @@ struct window_S { int stlnc; int vert; int fold; + int foldopen; ///< when fold is open + int foldclosed; ///< when fold is closed + int foldsep; ///< continuous fold marker int diff; int msgsep; int eob; diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index de2db63651..dab2e44890 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -350,7 +350,7 @@ retnomove: count |= CURSOR_MOVED; // Cursor has moved } - if (mouse_char == '+') { + if (mouse_char == curwin->w_p_fcs_chars.foldclosed) { count |= MOUSE_FOLD_OPEN; } else if (mouse_char != ' ') { count |= MOUSE_FOLD_CLOSE; diff --git a/src/nvim/option.c b/src/nvim/option.c index e48ed201e8..de25ee3218 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -3542,6 +3542,9 @@ static char_u *set_chars_option(win_T *wp, char_u **varp, bool set) { &wp->w_p_fcs_chars.stlnc, "stlnc", ' ' }, { &wp->w_p_fcs_chars.vert, "vert", 9474 }, // │ { &wp->w_p_fcs_chars.fold, "fold", 183 }, // · + { &wp->w_p_fcs_chars.foldopen, "foldopen", '-' }, + { &wp->w_p_fcs_chars.foldclosed, "foldclose", '+' }, + { &wp->w_p_fcs_chars.foldsep, "foldsep", '|' }, { &wp->w_p_fcs_chars.diff, "diff", '-' }, { &wp->w_p_fcs_chars.msgsep, "msgsep", ' ' }, { &wp->w_p_fcs_chars.eob, "eob", '~' }, diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 4082208dd4..1b7eeeecb8 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -126,7 +126,8 @@ // temporary buffer for rendering a single screenline, so it can be -// comparared with previous contents to calculate smallest delta. +// compared with previous contents to calculate smallest delta. +// Per-cell attributes static size_t linebuf_size = 0; static schar_T *linebuf_char = NULL; static sattr_T *linebuf_attr = NULL; @@ -1814,27 +1815,6 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T col++; } - // 2. Add the 'foldcolumn' - // Reduce the width when there is not enough space. - fdc = compute_foldcolumn(wp, col); - if (fdc > 0) { - fill_foldcolumn(buf, wp, TRUE, lnum); - if (wp->w_p_rl) { - int i; - - copy_text_attr(off + wp->w_grid.Columns - fdc - col, buf, fdc, - win_hl_attr(wp, HLF_FC)); - // reverse the fold column - for (i = 0; i < fdc; i++) { - schar_from_ascii(linebuf_char[off + wp->w_grid.Columns - i - 1 - col], - buf[i]); - } - } else { - copy_text_attr(off + col, buf, fdc, win_hl_attr(wp, HLF_FC)); - } - col += fdc; - } - # define RL_MEMSET(p, v, l) \ do { \ if (wp->w_p_rl) { \ @@ -1848,6 +1828,25 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T } \ } while (0) + // 2. Add the 'foldcolumn' + // Reduce the width when there is not enough space. + fdc = compute_foldcolumn(wp, col); + if (fdc > 0) { + fill_foldcolumn(buf, wp, true, lnum); + const char_u *it = &buf[0]; + for (int i = 0; i < fdc; i++) { + int mb_c = mb_ptr2char_adv(&it); + if (wp->w_p_rl) { + schar_from_char(linebuf_char[off + wp->w_grid.Columns - i - 1 - col], + mb_c); + } else { + schar_from_char(linebuf_char[off + col + i], mb_c); + } + } + RL_MEMSET(col, win_hl_attr(wp, HLF_FC), fdc); + col += fdc; + } + /* Set all attributes of the 'number' or 'relativenumber' column and the * text */ RL_MEMSET(col, win_hl_attr(wp, HLF_FL), wp->w_grid.Columns - col); @@ -2068,58 +2067,73 @@ static void copy_text_attr(int off, char_u *buf, int len, int attr) } } -/* - * Fill the foldcolumn at "p" for window "wp". - * Only to be called when 'foldcolumn' > 0. - */ -static void -fill_foldcolumn ( +/// Fills the foldcolumn at "p" for window "wp". +/// Only to be called when 'foldcolumn' > 0. +/// +/// @param[out] p Char array to write into +/// @param lnum Absolute current line number +/// @param closed Whether it is in 'foldcolumn' mode +/// +/// Assume monocell characters +/// @return number of chars added to \param p +static size_t +fill_foldcolumn( char_u *p, win_T *wp, - int closed, /* TRUE of FALSE */ - linenr_T lnum /* current line number */ + int closed, + linenr_T lnum ) { int i = 0; int level; int first_level; - int empty; - int fdc = compute_foldcolumn(wp, 0); - + int fdc = compute_foldcolumn(wp, 0); // available cell width + size_t char_counter = 0; + int symbol = 0; + int len = 0; // Init to all spaces. - memset(p, ' ', (size_t)fdc); + memset(p, ' ', MAX_MCO * fdc + 1); level = win_foldinfo.fi_level; - if (level > 0) { - // If there is only one column put more info in it. - empty = (fdc == 1) ? 0 : 1; - - // If the column is too narrow, we start at the lowest level that - // fits and use numbers to indicated the depth. - first_level = level - fdc - closed + 1 + empty; - if (first_level < 1) { - first_level = 1; - } - - for (i = 0; i + empty < fdc; i++) { - if (win_foldinfo.fi_lnum == lnum - && first_level + i >= win_foldinfo.fi_low_level) { - p[i] = '-'; - } else if (first_level == 1) { - p[i] = '|'; - } else if (first_level + i <= 9) { - p[i] = '0' + first_level + i; - } else { - p[i] = '>'; - } - if (first_level + i == level) { - break; - } + + // If the column is too narrow, we start at the lowest level that + // fits and use numbers to indicated the depth. + first_level = level - fdc - closed + 1; + if (first_level < 1) { + first_level = 1; + } + + for (i = 0; i < MIN(fdc, level); i++) { + if (win_foldinfo.fi_lnum == lnum + && first_level + i >= win_foldinfo.fi_low_level) { + symbol = wp->w_p_fcs_chars.foldopen; + } else if (first_level == 1) { + symbol = wp->w_p_fcs_chars.foldsep; + } else if (first_level + i <= 9) { + symbol = '0' + first_level + i; + } else { + symbol = '>'; + } + + len = utf_char2bytes(symbol, &p[char_counter]); + char_counter += len; + if (first_level + i >= level) { + i++; + break; } } + if (closed) { - p[i >= fdc ? i - 1 : i] = '+'; + if (symbol != 0) { + // rollback length + char_counter -= len; + } + symbol = wp->w_p_fcs_chars.foldclosed; + len = utf_char2bytes(symbol, &p[char_counter]); + char_counter += len; } + + return MAX(char_counter + (fdc-i), (size_t)fdc); } /* @@ -2807,9 +2821,8 @@ win_line ( // Draw the 'foldcolumn'. Allocate a buffer, "extra" may // already be in use. xfree(p_extra_free); - p_extra_free = xmalloc(12 + 1); - fill_foldcolumn(p_extra_free, wp, false, lnum); - n_extra = fdc; + p_extra_free = xmalloc(MAX_MCO * fdc + 1); + n_extra = fill_foldcolumn(p_extra_free, wp, false, lnum); p_extra_free[n_extra] = NUL; p_extra = p_extra_free; c_extra = NUL; diff --git a/test/functional/ui/fold_spec.lua b/test/functional/ui/fold_spec.lua index eb81aba131..0b788e7afb 100644 --- a/test/functional/ui/fold_spec.lua +++ b/test/functional/ui/fold_spec.lua @@ -60,6 +60,45 @@ describe("folded lines", function() ]]) end) + it("works with multibyte fillchars", function() + insert([[ + aa + bb + cc + dd + ee + ff]]) + command("set fillchars+=foldopen:▾,foldsep:│,foldclose:▸") + feed_command('1') + command("set foldcolumn=2") + feed('zf4j') + feed('zf2j') + feed('zO') + screen:expect{grid=[[ + {7:▾▾}^aa | + {7:││}bb | + {7:││}cc | + {7:││}dd | + {7:││}ee | + {7:│ }ff | + {1:~ }| + :1 | + ]]} + + feed_command("set rightleft") + screen:expect{grid=[[ + a^a{7:▾▾}| + bb{7:││}| + cc{7:││}| + dd{7:││}| + ee{7:││}| + ff{7: │}| + {1: ~}| + :set rightleft | + ]]} + end) + + it("works with multibyte text", function() -- Currently the only allowed value of 'maxcombine' eq(6, meths.get_option('maxcombine')) |