mirror of
https://github.com/neovim/neovim.git
synced 2025-09-13 23:08:16 +00:00
fillchars: adding foldopen, foldsep, foldclose
You can try it with set fillchars+=foldopen:▾,foldsep:│,foldclose:▸
This commit is contained in:
@@ -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
|
stlnc:c ' ' or '=' statusline of the non-current windows
|
||||||
vert:c '│' or '|' vertical separators |:vsplit|
|
vert:c '│' or '|' vertical separators |:vsplit|
|
||||||
fold:c '·' or '-' filling 'foldtext'
|
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
|
diff:c '-' deleted lines of the 'diff' option
|
||||||
msgsep:c ' ' message separator 'display'
|
msgsep:c ' ' message separator 'display'
|
||||||
eob:c '~' empty lines at the end of a buffer
|
eob:c '~' empty lines at the end of a buffer
|
||||||
|
@@ -1126,6 +1126,9 @@ struct window_S {
|
|||||||
int stlnc;
|
int stlnc;
|
||||||
int vert;
|
int vert;
|
||||||
int fold;
|
int fold;
|
||||||
|
int foldopen; ///< when fold is open
|
||||||
|
int foldclosed; ///< when fold is closed
|
||||||
|
int foldsep; ///< continuous fold marker
|
||||||
int diff;
|
int diff;
|
||||||
int msgsep;
|
int msgsep;
|
||||||
int eob;
|
int eob;
|
||||||
|
@@ -350,7 +350,7 @@ retnomove:
|
|||||||
count |= CURSOR_MOVED; // Cursor has moved
|
count |= CURSOR_MOVED; // Cursor has moved
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mouse_char == '+') {
|
if (mouse_char == curwin->w_p_fcs_chars.foldclosed) {
|
||||||
count |= MOUSE_FOLD_OPEN;
|
count |= MOUSE_FOLD_OPEN;
|
||||||
} else if (mouse_char != ' ') {
|
} else if (mouse_char != ' ') {
|
||||||
count |= MOUSE_FOLD_CLOSE;
|
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.stlnc, "stlnc", ' ' },
|
||||||
{ &wp->w_p_fcs_chars.vert, "vert", 9474 }, // │
|
{ &wp->w_p_fcs_chars.vert, "vert", 9474 }, // │
|
||||||
{ &wp->w_p_fcs_chars.fold, "fold", 183 }, // ·
|
{ &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.diff, "diff", '-' },
|
||||||
{ &wp->w_p_fcs_chars.msgsep, "msgsep", ' ' },
|
{ &wp->w_p_fcs_chars.msgsep, "msgsep", ' ' },
|
||||||
{ &wp->w_p_fcs_chars.eob, "eob", '~' },
|
{ &wp->w_p_fcs_chars.eob, "eob", '~' },
|
||||||
|
@@ -126,7 +126,8 @@
|
|||||||
|
|
||||||
|
|
||||||
// temporary buffer for rendering a single screenline, so it can be
|
// 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 size_t linebuf_size = 0;
|
||||||
static schar_T *linebuf_char = NULL;
|
static schar_T *linebuf_char = NULL;
|
||||||
static sattr_T *linebuf_attr = 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++;
|
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) \
|
# define RL_MEMSET(p, v, l) \
|
||||||
do { \
|
do { \
|
||||||
if (wp->w_p_rl) { \
|
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)
|
} 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
|
/* Set all attributes of the 'number' or 'relativenumber' column and the
|
||||||
* text */
|
* text */
|
||||||
RL_MEMSET(col, win_hl_attr(wp, HLF_FL), wp->w_grid.Columns - col);
|
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Fills the foldcolumn at "p" for window "wp".
|
||||||
* Fill the foldcolumn at "p" for window "wp".
|
/// Only to be called when 'foldcolumn' > 0.
|
||||||
* Only to be called when 'foldcolumn' > 0.
|
///
|
||||||
*/
|
/// @param[out] p Char array to write into
|
||||||
static void
|
/// @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(
|
fill_foldcolumn(
|
||||||
char_u *p,
|
char_u *p,
|
||||||
win_T *wp,
|
win_T *wp,
|
||||||
int closed, /* TRUE of FALSE */
|
int closed,
|
||||||
linenr_T lnum /* current line number */
|
linenr_T lnum
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int level;
|
int level;
|
||||||
int first_level;
|
int first_level;
|
||||||
int empty;
|
int fdc = compute_foldcolumn(wp, 0); // available cell width
|
||||||
int fdc = compute_foldcolumn(wp, 0);
|
size_t char_counter = 0;
|
||||||
|
int symbol = 0;
|
||||||
|
int len = 0;
|
||||||
// Init to all spaces.
|
// Init to all spaces.
|
||||||
memset(p, ' ', (size_t)fdc);
|
memset(p, ' ', MAX_MCO * fdc + 1);
|
||||||
|
|
||||||
level = win_foldinfo.fi_level;
|
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
|
// If the column is too narrow, we start at the lowest level that
|
||||||
// fits and use numbers to indicated the depth.
|
// fits and use numbers to indicated the depth.
|
||||||
first_level = level - fdc - closed + 1 + empty;
|
first_level = level - fdc - closed + 1;
|
||||||
if (first_level < 1) {
|
if (first_level < 1) {
|
||||||
first_level = 1;
|
first_level = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i + empty < fdc; i++) {
|
for (i = 0; i < MIN(fdc, level); i++) {
|
||||||
if (win_foldinfo.fi_lnum == lnum
|
if (win_foldinfo.fi_lnum == lnum
|
||||||
&& first_level + i >= win_foldinfo.fi_low_level) {
|
&& first_level + i >= win_foldinfo.fi_low_level) {
|
||||||
p[i] = '-';
|
symbol = wp->w_p_fcs_chars.foldopen;
|
||||||
} else if (first_level == 1) {
|
} else if (first_level == 1) {
|
||||||
p[i] = '|';
|
symbol = wp->w_p_fcs_chars.foldsep;
|
||||||
} else if (first_level + i <= 9) {
|
} else if (first_level + i <= 9) {
|
||||||
p[i] = '0' + first_level + i;
|
symbol = '0' + first_level + i;
|
||||||
} else {
|
} else {
|
||||||
p[i] = '>';
|
symbol = '>';
|
||||||
}
|
}
|
||||||
if (first_level + i == level) {
|
|
||||||
|
len = utf_char2bytes(symbol, &p[char_counter]);
|
||||||
|
char_counter += len;
|
||||||
|
if (first_level + i >= level) {
|
||||||
|
i++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (closed) {
|
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
|
// Draw the 'foldcolumn'. Allocate a buffer, "extra" may
|
||||||
// already be in use.
|
// already be in use.
|
||||||
xfree(p_extra_free);
|
xfree(p_extra_free);
|
||||||
p_extra_free = xmalloc(12 + 1);
|
p_extra_free = xmalloc(MAX_MCO * fdc + 1);
|
||||||
fill_foldcolumn(p_extra_free, wp, false, lnum);
|
n_extra = fill_foldcolumn(p_extra_free, wp, false, lnum);
|
||||||
n_extra = fdc;
|
|
||||||
p_extra_free[n_extra] = NUL;
|
p_extra_free[n_extra] = NUL;
|
||||||
p_extra = p_extra_free;
|
p_extra = p_extra_free;
|
||||||
c_extra = NUL;
|
c_extra = NUL;
|
||||||
|
@@ -60,6 +60,45 @@ describe("folded lines", function()
|
|||||||
]])
|
]])
|
||||||
end)
|
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()
|
it("works with multibyte text", function()
|
||||||
-- Currently the only allowed value of 'maxcombine'
|
-- Currently the only allowed value of 'maxcombine'
|
||||||
eq(6, meths.get_option('maxcombine'))
|
eq(6, meths.get_option('maxcombine'))
|
||||||
|
Reference in New Issue
Block a user