mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge #11568 'fillchars: foldopen, foldsep, foldclose'
This commit is contained in:
commit
b0196586de
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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", '~' },
|
||||
|
@ -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;
|
||||
|
@ -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'))
|
||||
|
Loading…
Reference in New Issue
Block a user