Merge #11568 'fillchars: foldopen, foldsep, foldclose'

This commit is contained in:
Justin M. Keyes 2019-12-26 07:06:43 +01:00 committed by GitHub
commit b0196586de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 122 additions and 61 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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", '~' },

View File

@ -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;
// 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 = '>';
}
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;
}
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;

View File

@ -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'))