mirror of
https://github.com/neovim/neovim.git
synced 2024-12-24 21:25:04 -07:00
feat(fold): transparent foldtext
'foldtext' can be set to an empty string to disable and render the line with: - extmark highlight - syntax highlighting - search highlighting - no line wrapping - spelling - conceal - inline virtual text - respects `fillchars:fold` Currently normal virtual text is not displayed Co-authored-by: zeertzjq <zeertzjq@outlook.com>
This commit is contained in:
parent
21b36c7d7f
commit
1233ac467d
@ -154,6 +154,9 @@ The following new APIs and features were added.
|
|||||||
|
|
||||||
• 'foldtext' now supports virtual text format. |fold-foldtext|
|
• 'foldtext' now supports virtual text format. |fold-foldtext|
|
||||||
|
|
||||||
|
• |'foldtext'| can be set to an empty string to disable and render the line:
|
||||||
|
as normal with regular highlighting and no line wrapping.
|
||||||
|
|
||||||
• The terminal buffer now supports reflow (wrapped lines adapt when the buffer
|
• The terminal buffer now supports reflow (wrapped lines adapt when the buffer
|
||||||
is resized horizontally). Note: Lines that are not visible and kept in
|
is resized horizontally). Note: Lines that are not visible and kept in
|
||||||
|'scrollback'| are not reflown.
|
|'scrollback'| are not reflown.
|
||||||
|
@ -2714,6 +2714,9 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
It is not allowed to change text or jump to another window while
|
It is not allowed to change text or jump to another window while
|
||||||
evaluating 'foldtext' |textlock|.
|
evaluating 'foldtext' |textlock|.
|
||||||
|
|
||||||
|
When set to an empty string, foldtext is disabled, and the line
|
||||||
|
is displayed normally with highlighting and no line wrapping.
|
||||||
|
|
||||||
*'formatexpr'* *'fex'*
|
*'formatexpr'* *'fex'*
|
||||||
'formatexpr' 'fex' string (default "")
|
'formatexpr' 'fex' string (default "")
|
||||||
local to buffer
|
local to buffer
|
||||||
|
3
runtime/lua/vim/_meta/options.lua
generated
3
runtime/lua/vim/_meta/options.lua
generated
@ -2473,6 +2473,9 @@ vim.go.fdo = vim.go.foldopen
|
|||||||
--- It is not allowed to change text or jump to another window while
|
--- It is not allowed to change text or jump to another window while
|
||||||
--- evaluating 'foldtext' `textlock`.
|
--- evaluating 'foldtext' `textlock`.
|
||||||
---
|
---
|
||||||
|
--- When set to an empty string, foldtext is disabled, and the line
|
||||||
|
--- is displayed normally with highlighting and no line wrapping.
|
||||||
|
---
|
||||||
--- @type string
|
--- @type string
|
||||||
vim.o.foldtext = "foldtext()"
|
vim.o.foldtext = "foldtext()"
|
||||||
vim.o.fdt = vim.o.foldtext
|
vim.o.fdt = vim.o.foldtext
|
||||||
|
@ -944,6 +944,10 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
static char *at_end_str = ""; // used for p_extra when displaying curwin->w_p_lcs_chars.eol
|
static char *at_end_str = ""; // used for p_extra when displaying curwin->w_p_lcs_chars.eol
|
||||||
// at end-of-line
|
// at end-of-line
|
||||||
const bool has_fold = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0;
|
const bool has_fold = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0;
|
||||||
|
const bool has_foldtext = has_fold && *wp->w_p_fdt != NUL;
|
||||||
|
|
||||||
|
const bool is_wrapped = wp->w_p_wrap
|
||||||
|
&& !has_fold; // Never wrap folded lines
|
||||||
|
|
||||||
int saved_attr2 = 0; // char_attr saved for n_attr
|
int saved_attr2 = 0; // char_attr saved for n_attr
|
||||||
int n_attr3 = 0; // chars with overruling special attr
|
int n_attr3 = 0; // chars with overruling special attr
|
||||||
@ -1036,7 +1040,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
// trailing white space and/or syntax processing to be done.
|
// trailing white space and/or syntax processing to be done.
|
||||||
extra_check = wp->w_p_lbr;
|
extra_check = wp->w_p_lbr;
|
||||||
if (syntax_present(wp) && !wp->w_s->b_syn_error && !wp->w_s->b_syn_slow
|
if (syntax_present(wp) && !wp->w_s->b_syn_error && !wp->w_s->b_syn_slow
|
||||||
&& !has_fold && !end_fill) {
|
&& !has_foldtext && !end_fill) {
|
||||||
// Prepare for syntax highlighting in this line. When there is an
|
// Prepare for syntax highlighting in this line. When there is an
|
||||||
// error, stop syntax highlighting.
|
// error, stop syntax highlighting.
|
||||||
int save_did_emsg = did_emsg;
|
int save_did_emsg = did_emsg;
|
||||||
@ -1132,7 +1136,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
// handle 'incsearch' and ":s///c" highlighting
|
// handle 'incsearch' and ":s///c" highlighting
|
||||||
} else if (highlight_match
|
} else if (highlight_match
|
||||||
&& wp == curwin
|
&& wp == curwin
|
||||||
&& !has_fold
|
&& !has_foldtext
|
||||||
&& lnum >= curwin->w_cursor.lnum
|
&& lnum >= curwin->w_cursor.lnum
|
||||||
&& lnum <= curwin->w_cursor.lnum + search_match_lines) {
|
&& lnum <= curwin->w_cursor.lnum + search_match_lines) {
|
||||||
if (lnum == curwin->w_cursor.lnum) {
|
if (lnum == curwin->w_cursor.lnum) {
|
||||||
@ -1192,7 +1196,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
// Do not show the cursor line in the text when Visual mode is active,
|
// Do not show the cursor line in the text when Visual mode is active,
|
||||||
// because it's not clear what is selected then.
|
// because it's not clear what is selected then.
|
||||||
&& !(wp == curwin && VIsual_active)) {
|
&& !(wp == curwin && VIsual_active)) {
|
||||||
cul_screenline = (wp->w_p_wrap && (wp->w_p_culopt_flags & CULOPT_SCRLINE));
|
cul_screenline = (is_wrapped && (wp->w_p_culopt_flags & CULOPT_SCRLINE));
|
||||||
if (!cul_screenline) {
|
if (!cul_screenline) {
|
||||||
apply_cursorline_highlight(wp, &wlv);
|
apply_cursorline_highlight(wp, &wlv);
|
||||||
} else {
|
} else {
|
||||||
@ -1315,7 +1319,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
const schar_T lcs_eol = wp->w_p_lcs_chars.eol; // 'eol' value
|
const schar_T lcs_eol = wp->w_p_lcs_chars.eol; // 'eol' value
|
||||||
schar_T lcs_prec_todo = wp->w_p_lcs_chars.prec; // 'prec' until it's been used, then NUL
|
schar_T lcs_prec_todo = wp->w_p_lcs_chars.prec; // 'prec' until it's been used, then NUL
|
||||||
|
|
||||||
if (wp->w_p_list && !has_fold && !end_fill) {
|
if (wp->w_p_list && !has_foldtext && !end_fill) {
|
||||||
if (wp->w_p_lcs_chars.space
|
if (wp->w_p_lcs_chars.space
|
||||||
|| wp->w_p_lcs_chars.multispace != NULL
|
|| wp->w_p_lcs_chars.multispace != NULL
|
||||||
|| wp->w_p_lcs_chars.leadmultispace != NULL
|
|| wp->w_p_lcs_chars.leadmultispace != NULL
|
||||||
@ -1467,7 +1471,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (col_rows == 0 && !has_fold && !end_fill) {
|
if (col_rows == 0 && !has_foldtext && !end_fill) {
|
||||||
const int v = (int)(ptr - line);
|
const int v = (int)(ptr - line);
|
||||||
area_highlighting |= prepare_search_hl_line(wp, lnum, v,
|
area_highlighting |= prepare_search_hl_line(wp, lnum, v,
|
||||||
&line, &screen_search_hl, &search_attr,
|
&line, &screen_search_hl, &search_attr,
|
||||||
@ -1605,6 +1609,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
const bool draw_folded = has_fold && wlv.row == startrow + wlv.filler_lines;
|
const bool draw_folded = has_fold && wlv.row == startrow + wlv.filler_lines;
|
||||||
if (draw_folded && wlv.n_extra == 0) {
|
if (draw_folded && wlv.n_extra == 0) {
|
||||||
wlv.char_attr = folded_attr = win_hl_attr(wp, HLF_FL);
|
wlv.char_attr = folded_attr = win_hl_attr(wp, HLF_FL);
|
||||||
|
decor_attr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int extmark_attr = 0;
|
int extmark_attr = 0;
|
||||||
@ -1640,7 +1645,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
&decor_state);
|
&decor_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_fold && wp->w_buffer->b_virt_text_inline > 0) {
|
if (!has_foldtext && wp->w_buffer->b_virt_text_inline > 0) {
|
||||||
handle_inline_virtual_text(wp, &wlv, ptr - line);
|
handle_inline_virtual_text(wp, &wlv, ptr - line);
|
||||||
if (wlv.n_extra > 0 && wlv.virt_inline_hl_mode <= kHlModeReplace) {
|
if (wlv.n_extra > 0 && wlv.virt_inline_hl_mode <= kHlModeReplace) {
|
||||||
// restore search_attr and area_attr when n_extra is down to zero
|
// restore search_attr and area_attr when n_extra is down to zero
|
||||||
@ -1679,7 +1684,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
area_active = false;
|
area_active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_fold && wlv.n_extra == 0) {
|
if (!has_foldtext && wlv.n_extra == 0) {
|
||||||
// Check for start/end of 'hlsearch' and other matches.
|
// Check for start/end of 'hlsearch' and other matches.
|
||||||
// After end, check for start/end of next match.
|
// After end, check for start/end of next match.
|
||||||
// When another match, have to check for start again.
|
// When another match, have to check for start again.
|
||||||
@ -1746,7 +1751,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draw_folded && wlv.n_extra == 0 && wlv.col == win_col_offset) {
|
if (draw_folded && has_foldtext && wlv.n_extra == 0 && wlv.col == win_col_offset) {
|
||||||
const int v = (int)(ptr - line);
|
const int v = (int)(ptr - line);
|
||||||
linenr_T lnume = lnum + foldinfo.fi_lines - 1;
|
linenr_T lnume = lnum + foldinfo.fi_lines - 1;
|
||||||
memset(buf_fold, ' ', FOLD_TEXT_LEN);
|
memset(buf_fold, ' ', FOLD_TEXT_LEN);
|
||||||
@ -1765,7 +1770,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
ptr = line + v;
|
ptr = line + v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draw_folded && wlv.n_extra == 0 && wlv.col < grid->cols) {
|
if (draw_folded && wlv.n_extra == 0 && wlv.col < grid->cols && (has_foldtext || *ptr == NUL)) {
|
||||||
// Fill rest of line with 'fold'.
|
// Fill rest of line with 'fold'.
|
||||||
wlv.sc_extra = wp->w_p_fcs_chars.fold;
|
wlv.sc_extra = wp->w_p_fcs_chars.fold;
|
||||||
wlv.sc_final = NUL;
|
wlv.sc_final = NUL;
|
||||||
@ -1848,7 +1853,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
// initialize these.
|
// initialize these.
|
||||||
mb_c = ' ';
|
mb_c = ' ';
|
||||||
mb_schar = schar_from_ascii(' ');
|
mb_schar = schar_from_ascii(' ');
|
||||||
} else if (has_fold) {
|
} else if (has_foldtext || (has_fold && wlv.col >= grid->cols)) {
|
||||||
// skip writing the buffer line itself
|
// skip writing the buffer line itself
|
||||||
mb_schar = NUL;
|
mb_schar = NUL;
|
||||||
} else {
|
} else {
|
||||||
@ -1974,6 +1979,10 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
can_spell = TRISTATE_TO_BOOL(decor_state.spell, can_spell);
|
can_spell = TRISTATE_TO_BOOL(decor_state.spell, can_spell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (folded_attr) {
|
||||||
|
decor_attr = hl_combine_attr(folded_attr, decor_attr);
|
||||||
|
}
|
||||||
|
|
||||||
if (decor_attr) {
|
if (decor_attr) {
|
||||||
if (!attr_pri) {
|
if (!attr_pri) {
|
||||||
if (wlv.cul_attr) {
|
if (wlv.cul_attr) {
|
||||||
@ -2388,7 +2397,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
wlv.vcol_off += wlv.n_extra;
|
wlv.vcol_off += wlv.n_extra;
|
||||||
}
|
}
|
||||||
wlv.vcol += wlv.n_extra;
|
wlv.vcol += wlv.n_extra;
|
||||||
if (wp->w_p_wrap && wlv.n_extra > 0) {
|
if (is_wrapped && wlv.n_extra > 0) {
|
||||||
wlv.boguscols += wlv.n_extra;
|
wlv.boguscols += wlv.n_extra;
|
||||||
wlv.col += wlv.n_extra;
|
wlv.col += wlv.n_extra;
|
||||||
}
|
}
|
||||||
@ -2489,7 +2498,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
// Add a blank character to highlight.
|
// Add a blank character to highlight.
|
||||||
linebuf_char[wlv.off] = schar_from_ascii(' ');
|
linebuf_char[wlv.off] = schar_from_ascii(' ');
|
||||||
}
|
}
|
||||||
if (area_attr == 0 && !has_fold) {
|
if (area_attr == 0 && !has_foldtext) {
|
||||||
// Use attributes from match with highest priority among
|
// Use attributes from match with highest priority among
|
||||||
// 'search_hl' and the match list.
|
// 'search_hl' and the match list.
|
||||||
get_search_match_hl(wp,
|
get_search_match_hl(wp,
|
||||||
@ -2616,7 +2625,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// When the window is too narrow draw all "@" lines.
|
// When the window is too narrow draw all "@" lines.
|
||||||
if (leftcols_width >= wp->w_grid.cols && wp->w_p_wrap) {
|
if (leftcols_width >= wp->w_grid.cols && is_wrapped) {
|
||||||
win_draw_end(wp, schar_from_ascii('@'), true, wlv.row, wp->w_grid.rows, HLF_AT);
|
win_draw_end(wp, schar_from_ascii('@'), true, wlv.row, wp->w_grid.rows, HLF_AT);
|
||||||
set_empty_rows(wp, wlv.row);
|
set_empty_rows(wp, wlv.row);
|
||||||
wlv.row = endrow;
|
wlv.row = endrow;
|
||||||
@ -2627,12 +2636,13 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
|
|
||||||
// Show "extends" character from 'listchars' if beyond the line end and
|
// Show "extends" character from 'listchars' if beyond the line end and
|
||||||
// 'list' is set.
|
// 'list' is set.
|
||||||
|
// Don't show this with 'wrap' as the line can't be scrolled horizontally.
|
||||||
if (wp->w_p_lcs_chars.ext != NUL
|
if (wp->w_p_lcs_chars.ext != NUL
|
||||||
&& wp->w_p_list
|
&& wp->w_p_list
|
||||||
&& !wp->w_p_wrap
|
&& !wp->w_p_wrap
|
||||||
&& wlv.filler_todo <= 0
|
&& wlv.filler_todo <= 0
|
||||||
&& wlv.col == grid->cols - 1
|
&& wlv.col == grid->cols - 1
|
||||||
&& !has_fold) {
|
&& !has_foldtext) {
|
||||||
if (has_decor && *ptr == NUL && lcs_eol == 0 && lcs_eol_todo) {
|
if (has_decor && *ptr == NUL && lcs_eol == 0 && lcs_eol_todo) {
|
||||||
// Tricky: there might be a virtual text just _after_ the last char
|
// Tricky: there might be a virtual text just _after_ the last char
|
||||||
decor_redraw_col(wp, (colnr_T)(ptr - line), wlv.off, false, &decor_state);
|
decor_redraw_col(wp, (colnr_T)(ptr - line), wlv.off, false, &decor_state);
|
||||||
@ -2714,7 +2724,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
if (wlv.n_extra > 0) {
|
if (wlv.n_extra > 0) {
|
||||||
wlv.vcol_off += wlv.n_extra;
|
wlv.vcol_off += wlv.n_extra;
|
||||||
}
|
}
|
||||||
if (wp->w_p_wrap) {
|
if (is_wrapped) {
|
||||||
// Special voodoo required if 'wrap' is on.
|
// Special voodoo required if 'wrap' is on.
|
||||||
//
|
//
|
||||||
// Advance the column indicator to force the line
|
// Advance the column indicator to force the line
|
||||||
@ -2782,11 +2792,11 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
if (has_decor && wlv.filler_todo <= 0 && wlv.col >= grid->cols) {
|
if (has_decor && wlv.filler_todo <= 0 && wlv.col >= grid->cols) {
|
||||||
// At the end of screen line: might need to peek for decorations just after
|
// At the end of screen line: might need to peek for decorations just after
|
||||||
// this position.
|
// this position.
|
||||||
if (!has_fold && wp->w_p_wrap && wlv.n_extra == 0) {
|
if (is_wrapped && wlv.n_extra == 0) {
|
||||||
decor_redraw_col(wp, (colnr_T)(ptr - line), -3, false, &decor_state);
|
decor_redraw_col(wp, (colnr_T)(ptr - line), -3, false, &decor_state);
|
||||||
// Check position/hiding of virtual text again on next screen line.
|
// Check position/hiding of virtual text again on next screen line.
|
||||||
decor_need_recheck = true;
|
decor_need_recheck = true;
|
||||||
} else if (has_fold || !wp->w_p_wrap) {
|
} else if (!is_wrapped) {
|
||||||
// Without wrapping, we might need to display right_align and win_col
|
// Without wrapping, we might need to display right_align and win_col
|
||||||
// virt_text for the entire text line.
|
// virt_text for the entire text line.
|
||||||
decor_redraw_col(wp, MAXCOL, -1, true, &decor_state);
|
decor_redraw_col(wp, MAXCOL, -1, true, &decor_state);
|
||||||
@ -2795,14 +2805,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
|
|
||||||
// At end of screen line and there is more to come: Display the line
|
// At end of screen line and there is more to come: Display the line
|
||||||
// so far. If there is no more to display it is caught above.
|
// so far. If there is no more to display it is caught above.
|
||||||
if (wlv.col >= grid->cols && (!has_fold || virt_line_offset >= 0)
|
if (wlv.col >= grid->cols && (!has_foldtext || virt_line_offset >= 0)
|
||||||
&& (*ptr != NUL
|
&& (*ptr != NUL
|
||||||
|| wlv.filler_todo > 0
|
|| wlv.filler_todo > 0
|
||||||
|| (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL
|
|| (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL
|
||||||
&& wlv.p_extra != at_end_str)
|
&& wlv.p_extra != at_end_str)
|
||||||
|| (wlv.n_extra != 0 && (wlv.sc_extra != NUL || *wlv.p_extra != NUL))
|
|| (wlv.n_extra != 0 && (wlv.sc_extra != NUL || *wlv.p_extra != NUL))
|
||||||
|| has_more_inline_virt(&wlv, ptr - line))) {
|
|| has_more_inline_virt(&wlv, ptr - line))) {
|
||||||
const bool wrap = wp->w_p_wrap // Wrapping enabled.
|
const bool wrap = is_wrapped // Wrapping enabled (not a folded line).
|
||||||
&& wlv.filler_todo <= 0 // Not drawing diff filler lines.
|
&& wlv.filler_todo <= 0 // Not drawing diff filler lines.
|
||||||
&& lcs_eol_todo // Haven't printed the lcs_eol character.
|
&& lcs_eol_todo // Haven't printed the lcs_eol character.
|
||||||
&& wlv.row != endrow - 1 // Not the last line being displayed.
|
&& wlv.row != endrow - 1 // Not the last line being displayed.
|
||||||
@ -2835,7 +2845,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
|
|
||||||
// When not wrapping and finished diff lines, or when displayed
|
// When not wrapping and finished diff lines, or when displayed
|
||||||
// '$' and highlighting until last column, break here.
|
// '$' and highlighting until last column, break here.
|
||||||
if ((!wp->w_p_wrap && wlv.filler_todo <= 0) || !lcs_eol_todo) {
|
if ((!is_wrapped && wlv.filler_todo <= 0) || !lcs_eol_todo) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2283,22 +2283,28 @@ static void win_update(win_T *wp)
|
|||||||
syntax_end_parsing(wp, syntax_last_parsed + 1);
|
syntax_end_parsing(wp, syntax_last_parsed + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool display_buf_line = (foldinfo.fi_lines == 0 || *wp->w_p_fdt == NUL);
|
||||||
|
|
||||||
// Display one line
|
// Display one line
|
||||||
spellvars_T zero_spv = { 0 };
|
spellvars_T zero_spv = { 0 };
|
||||||
row = win_line(wp, lnum, srow, wp->w_grid.rows, 0,
|
row = win_line(wp, lnum, srow, wp->w_grid.rows, 0,
|
||||||
foldinfo.fi_lines > 0 ? &zero_spv : &spv, foldinfo);
|
display_buf_line ? &spv : &zero_spv, foldinfo);
|
||||||
|
|
||||||
|
if (display_buf_line) {
|
||||||
|
syntax_last_parsed = lnum;
|
||||||
|
} else {
|
||||||
|
spv.spv_capcol_lnum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (foldinfo.fi_lines == 0) {
|
if (foldinfo.fi_lines == 0) {
|
||||||
wp->w_lines[idx].wl_folded = false;
|
wp->w_lines[idx].wl_folded = false;
|
||||||
wp->w_lines[idx].wl_lastlnum = lnum;
|
wp->w_lines[idx].wl_lastlnum = lnum;
|
||||||
did_update = DID_LINE;
|
did_update = DID_LINE;
|
||||||
syntax_last_parsed = lnum;
|
|
||||||
} else {
|
} else {
|
||||||
foldinfo.fi_lines--;
|
foldinfo.fi_lines--;
|
||||||
wp->w_lines[idx].wl_folded = true;
|
wp->w_lines[idx].wl_folded = true;
|
||||||
wp->w_lines[idx].wl_lastlnum = lnum + foldinfo.fi_lines;
|
wp->w_lines[idx].wl_lastlnum = lnum + foldinfo.fi_lines;
|
||||||
did_update = DID_FOLD;
|
did_update = DID_FOLD;
|
||||||
spv.spv_capcol_lnum = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3181,6 +3181,9 @@ return {
|
|||||||
|
|
||||||
It is not allowed to change text or jump to another window while
|
It is not allowed to change text or jump to another window while
|
||||||
evaluating 'foldtext' |textlock|.
|
evaluating 'foldtext' |textlock|.
|
||||||
|
|
||||||
|
When set to an empty string, foldtext is disabled, and the line
|
||||||
|
is displayed normally with highlighting and no line wrapping.
|
||||||
]=],
|
]=],
|
||||||
full_name = 'foldtext',
|
full_name = 'foldtext',
|
||||||
modelineexpr = true,
|
modelineexpr = true,
|
||||||
|
@ -80,56 +80,113 @@ describe('folded lines', function()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local function test_folded_cursorline()
|
local function test_folded_cursorline(foldtext)
|
||||||
|
if not foldtext then
|
||||||
|
command('set foldtext=')
|
||||||
|
end
|
||||||
command('set number cursorline foldcolumn=2')
|
command('set number cursorline foldcolumn=2')
|
||||||
command('hi link CursorLineFold Search')
|
command('hi link CursorLineFold Search')
|
||||||
insert(content1)
|
insert(content1)
|
||||||
feed('ggzf3jj')
|
feed('ggzf3jj')
|
||||||
|
|
||||||
if multigrid then
|
if multigrid then
|
||||||
screen:expect([[
|
if foldtext then
|
||||||
## grid 1
|
screen:expect([[
|
||||||
[2:---------------------------------------------]|*7
|
## grid 1
|
||||||
[3:---------------------------------------------]|
|
[2:---------------------------------------------]|*7
|
||||||
## grid 2
|
[3:---------------------------------------------]|
|
||||||
{7:+ }{8: 1 }{5:+-- 4 lines: This is a················}|
|
## grid 2
|
||||||
{6: }{9: 5 }{12:^in his cave. }|
|
{7:+ }{8: 1 }{5:+-- 4 lines: This is a················}|
|
||||||
{7: }{8: 6 } |
|
{6: }{9: 5 }{12:^in his cave. }|
|
||||||
{1:~ }|*4
|
{7: }{8: 6 } |
|
||||||
## grid 3
|
{1:~ }|*4
|
||||||
|
|
## grid 3
|
||||||
]])
|
|
|
||||||
|
]])
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
## grid 1
|
||||||
|
[2:---------------------------------------------]|*7
|
||||||
|
[3:---------------------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
{7:+ }{8: 1 }{5:This is a······························}|
|
||||||
|
{6: }{9: 5 }{12:^in his cave. }|
|
||||||
|
{7: }{8: 6 } |
|
||||||
|
{1:~ }|*4
|
||||||
|
## grid 3
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
end
|
||||||
else
|
else
|
||||||
screen:expect([[
|
if foldtext then
|
||||||
{7:+ }{8: 1 }{5:+-- 4 lines: This is a················}|
|
screen:expect([[
|
||||||
{6: }{9: 5 }{12:^in his cave. }|
|
{7:+ }{8: 1 }{5:+-- 4 lines: This is a················}|
|
||||||
{7: }{8: 6 } |
|
{6: }{9: 5 }{12:^in his cave. }|
|
||||||
{1:~ }|*4
|
{7: }{8: 6 } |
|
||||||
|
|
{1:~ }|*4
|
||||||
]])
|
|
|
||||||
|
]])
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
{7:+ }{8: 1 }{5:This is a······························}|
|
||||||
|
{6: }{9: 5 }{12:^in his cave. }|
|
||||||
|
{7: }{8: 6 } |
|
||||||
|
{1:~ }|*4
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feed('k')
|
feed('k')
|
||||||
|
|
||||||
if multigrid then
|
if multigrid then
|
||||||
screen:expect([[
|
if foldtext then
|
||||||
## grid 1
|
screen:expect([[
|
||||||
[2:---------------------------------------------]|*7
|
## grid 1
|
||||||
[3:---------------------------------------------]|
|
[2:---------------------------------------------]|*7
|
||||||
## grid 2
|
[3:---------------------------------------------]|
|
||||||
{6:+ }{9: 1 }{13:^+-- 4 lines: This is a················}|
|
## grid 2
|
||||||
{7: }{8: 5 }in his cave. |
|
{6:+ }{9: 1 }{13:^+-- 4 lines: This is a················}|
|
||||||
{7: }{8: 6 } |
|
{7: }{8: 5 }in his cave. |
|
||||||
{1:~ }|*4
|
{7: }{8: 6 } |
|
||||||
## grid 3
|
{1:~ }|*4
|
||||||
|
|
## grid 3
|
||||||
]])
|
|
|
||||||
|
]])
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
## grid 1
|
||||||
|
[2:---------------------------------------------]|*7
|
||||||
|
[3:---------------------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
{6:+ }{9: 1 }{13:^This is a······························}|
|
||||||
|
{7: }{8: 5 }in his cave. |
|
||||||
|
{7: }{8: 6 } |
|
||||||
|
{1:~ }|*4
|
||||||
|
## grid 3
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
end
|
||||||
else
|
else
|
||||||
screen:expect([[
|
if foldtext then
|
||||||
{6:+ }{9: 1 }{13:^+-- 4 lines: This is a················}|
|
screen:expect([[
|
||||||
{7: }{8: 5 }in his cave. |
|
{6:+ }{9: 1 }{13:^+-- 4 lines: This is a················}|
|
||||||
{7: }{8: 6 } |
|
{7: }{8: 5 }in his cave. |
|
||||||
{1:~ }|*4
|
{7: }{8: 6 } |
|
||||||
|
|
{1:~ }|*4
|
||||||
]])
|
|
|
||||||
|
]])
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
{6:+ }{9: 1 }{13:^This is a······························}|
|
||||||
|
{7: }{8: 5 }in his cave. |
|
||||||
|
{7: }{8: 6 } |
|
||||||
|
{1:~ }|*4
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- CursorLine is applied correctly with screenrow motions #22232
|
-- CursorLine is applied correctly with screenrow motions #22232
|
||||||
feed('jgk')
|
feed('jgk')
|
||||||
screen:expect_unchanged()
|
screen:expect_unchanged()
|
||||||
@ -137,71 +194,130 @@ describe('folded lines', function()
|
|||||||
feed('zo4Gzc')
|
feed('zo4Gzc')
|
||||||
screen:expect_unchanged()
|
screen:expect_unchanged()
|
||||||
command('set cursorlineopt=line')
|
command('set cursorlineopt=line')
|
||||||
|
|
||||||
if multigrid then
|
if multigrid then
|
||||||
screen:expect([[
|
if foldtext then
|
||||||
## grid 1
|
screen:expect([[
|
||||||
[2:---------------------------------------------]|*7
|
## grid 1
|
||||||
[3:---------------------------------------------]|
|
[2:---------------------------------------------]|*7
|
||||||
## grid 2
|
[3:---------------------------------------------]|
|
||||||
{7:+ }{8: 1 }{13:^+-- 4 lines: This is a················}|
|
## grid 2
|
||||||
{7: }{8: 5 }in his cave. |
|
{7:+ }{8: 1 }{13:^+-- 4 lines: This is a················}|
|
||||||
{7: }{8: 6 } |
|
{7: }{8: 5 }in his cave. |
|
||||||
{1:~ }|*4
|
{7: }{8: 6 } |
|
||||||
## grid 3
|
{1:~ }|*4
|
||||||
|
|
## grid 3
|
||||||
]])
|
|
|
||||||
|
]])
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
## grid 1
|
||||||
|
[2:---------------------------------------------]|*7
|
||||||
|
[3:---------------------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
{7:+ }{8: 1 }{13:^This is a······························}|
|
||||||
|
{7: }{8: 5 }in his cave. |
|
||||||
|
{7: }{8: 6 } |
|
||||||
|
{1:~ }|*4
|
||||||
|
## grid 3
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
end
|
||||||
else
|
else
|
||||||
screen:expect([[
|
if foldtext then
|
||||||
{7:+ }{8: 1 }{13:^+-- 4 lines: This is a················}|
|
screen:expect([[
|
||||||
{7: }{8: 5 }in his cave. |
|
{7:+ }{8: 1 }{13:^+-- 4 lines: This is a················}|
|
||||||
{7: }{8: 6 } |
|
{7: }{8: 5 }in his cave. |
|
||||||
{1:~ }|*4
|
{7: }{8: 6 } |
|
||||||
|
|
{1:~ }|*4
|
||||||
]])
|
|
|
||||||
|
]])
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
{7:+ }{8: 1 }{13:^This is a······························}|
|
||||||
|
{7: }{8: 5 }in his cave. |
|
||||||
|
{7: }{8: 6 } |
|
||||||
|
{1:~ }|*4
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
command('set relativenumber cursorlineopt=number')
|
command('set relativenumber cursorlineopt=number')
|
||||||
|
|
||||||
if multigrid then
|
if multigrid then
|
||||||
screen:expect([[
|
if foldtext then
|
||||||
## grid 1
|
screen:expect([[
|
||||||
[2:---------------------------------------------]|*7
|
## grid 1
|
||||||
[3:---------------------------------------------]|
|
[2:---------------------------------------------]|*7
|
||||||
## grid 2
|
[3:---------------------------------------------]|
|
||||||
{6:+ }{9:1 }{5:^+-- 4 lines: This is a················}|
|
## grid 2
|
||||||
{7: }{8: 1 }in his cave. |
|
{6:+ }{9:1 }{5:^+-- 4 lines: This is a················}|
|
||||||
{7: }{8: 2 } |
|
{7: }{8: 1 }in his cave. |
|
||||||
{1:~ }|*4
|
{7: }{8: 2 } |
|
||||||
## grid 3
|
{1:~ }|*4
|
||||||
|
|
## grid 3
|
||||||
]])
|
|
|
||||||
|
]])
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
## grid 1
|
||||||
|
[2:---------------------------------------------]|*7
|
||||||
|
[3:---------------------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
{6:+ }{9:1 }{5:^This is a······························}|
|
||||||
|
{7: }{8: 1 }in his cave. |
|
||||||
|
{7: }{8: 2 } |
|
||||||
|
{1:~ }|*4
|
||||||
|
## grid 3
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
end
|
||||||
else
|
else
|
||||||
screen:expect([[
|
if foldtext then
|
||||||
{6:+ }{9:1 }{5:^+-- 4 lines: This is a················}|
|
screen:expect([[
|
||||||
{7: }{8: 1 }in his cave. |
|
{6:+ }{9:1 }{5:^+-- 4 lines: This is a················}|
|
||||||
{7: }{8: 2 } |
|
{7: }{8: 1 }in his cave. |
|
||||||
{1:~ }|*4
|
{7: }{8: 2 } |
|
||||||
|
|
{1:~ }|*4
|
||||||
]])
|
|
|
||||||
|
]])
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
{6:+ }{9:1 }{5:^This is a······························}|
|
||||||
|
{7: }{8: 1 }in his cave. |
|
||||||
|
{7: }{8: 2 } |
|
||||||
|
{1:~ }|*4
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe("when 'cursorline' is set", function()
|
describe("when 'cursorline' is set", function()
|
||||||
it('with high-priority CursorLine', function()
|
local function cursorline_tests(foldtext)
|
||||||
command('hi! CursorLine guibg=NONE guifg=Red gui=NONE')
|
local sfx = not foldtext and ' (disabled foldtext)' or ''
|
||||||
test_folded_cursorline()
|
it('with high-priority CursorLine' .. sfx, function()
|
||||||
end)
|
command('hi! CursorLine guibg=NONE guifg=Red gui=NONE')
|
||||||
|
test_folded_cursorline(foldtext)
|
||||||
|
end)
|
||||||
|
|
||||||
it('with low-priority CursorLine', function()
|
it('with low-priority CursorLine' .. sfx, function()
|
||||||
command('hi! CursorLine guibg=NONE guifg=NONE gui=underline')
|
command('hi! CursorLine guibg=NONE guifg=NONE gui=underline')
|
||||||
local attrs = screen:get_default_attr_ids()
|
local attrs = screen:get_default_attr_ids()
|
||||||
attrs[12] = { underline = true }
|
attrs[12] = { underline = true }
|
||||||
attrs[13] = {
|
attrs[13] = {
|
||||||
foreground = Screen.colors.DarkBlue,
|
foreground = Screen.colors.DarkBlue,
|
||||||
background = Screen.colors.LightGrey,
|
background = Screen.colors.LightGrey,
|
||||||
underline = true,
|
underline = true,
|
||||||
}
|
}
|
||||||
screen:set_default_attr_ids(attrs)
|
screen:set_default_attr_ids(attrs)
|
||||||
test_folded_cursorline()
|
test_folded_cursorline(foldtext)
|
||||||
end)
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
cursorline_tests(true)
|
||||||
|
cursorline_tests(false)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('work with spell', function()
|
it('work with spell', function()
|
||||||
@ -2549,6 +2665,120 @@ describe('folded lines', function()
|
|||||||
]])
|
]])
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('supports disabled foldtext', function()
|
||||||
|
screen:try_resize(30, 7)
|
||||||
|
insert(content1)
|
||||||
|
command('hi! CursorLine guibg=NONE guifg=Red gui=NONE')
|
||||||
|
command('hi F0 guibg=Red guifg=Black')
|
||||||
|
command('hi F1 guifg=White')
|
||||||
|
api.nvim_set_option_value('cursorline', true, {})
|
||||||
|
api.nvim_set_option_value('foldcolumn', '4', {})
|
||||||
|
api.nvim_set_option_value('foldtext', '', {})
|
||||||
|
|
||||||
|
command('3,4fold')
|
||||||
|
command('5,6fold')
|
||||||
|
command('2,6fold')
|
||||||
|
if multigrid then
|
||||||
|
screen:expect([[
|
||||||
|
## grid 1
|
||||||
|
[2:------------------------------]|*6
|
||||||
|
[3:------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
{7: }This is a |
|
||||||
|
{7:+ }{13:^valid English·············}|
|
||||||
|
{1:~ }|*4
|
||||||
|
## grid 3
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
{7: }This is a |
|
||||||
|
{7:+ }{13:^valid English·············}|
|
||||||
|
{1:~ }|*4
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
end
|
||||||
|
|
||||||
|
feed('zo')
|
||||||
|
if multigrid then
|
||||||
|
screen:expect([[
|
||||||
|
## grid 1
|
||||||
|
[2:------------------------------]|*6
|
||||||
|
[3:------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
{7: }This is a |
|
||||||
|
{7:- }valid English |
|
||||||
|
{7:│+ }{5:sentence composed by······}|
|
||||||
|
{7:│+ }{13:^in his cave.··············}|
|
||||||
|
{1:~ }|*2
|
||||||
|
## grid 3
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
{7: }This is a |
|
||||||
|
{7:- }valid English |
|
||||||
|
{7:│+ }{5:sentence composed by······}|
|
||||||
|
{7:│+ }{13:^in his cave.··············}|
|
||||||
|
{1:~ }|*2
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
end
|
||||||
|
|
||||||
|
command('hi! Visual guibg=Red')
|
||||||
|
feed('V2k')
|
||||||
|
if multigrid then
|
||||||
|
screen:expect([[
|
||||||
|
## grid 1
|
||||||
|
[2:------------------------------]|*6
|
||||||
|
[3:------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
{7: }This is a |
|
||||||
|
{7:- }^v{14:alid English} |
|
||||||
|
{7:│+ }{15:sentence composed by······}|
|
||||||
|
{7:│+ }{15:in his cave.··············}|
|
||||||
|
{1:~ }|*2
|
||||||
|
## grid 3
|
||||||
|
{11:-- VISUAL LINE --} |
|
||||||
|
]])
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
{7: }This is a |
|
||||||
|
{7:- }^v{14:alid English} |
|
||||||
|
{7:│+ }{15:sentence composed by······}|
|
||||||
|
{7:│+ }{15:in his cave.··············}|
|
||||||
|
{1:~ }|*2
|
||||||
|
{11:-- VISUAL LINE --} |
|
||||||
|
]])
|
||||||
|
end
|
||||||
|
|
||||||
|
api.nvim_set_option_value('rightleft', true, {})
|
||||||
|
if multigrid then
|
||||||
|
screen:expect([[
|
||||||
|
## grid 1
|
||||||
|
[2:------------------------------]|*6
|
||||||
|
[3:------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
a si sihT{7: }|
|
||||||
|
{14:hsilgnE dila}^v{7: -}|
|
||||||
|
{15:······yb desopmoc ecnetnes}{7: +│}|
|
||||||
|
{15:··············.evac sih ni}{7: +│}|
|
||||||
|
{1: ~}|*2
|
||||||
|
## grid 3
|
||||||
|
{11:-- VISUAL LINE --} |
|
||||||
|
]])
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
a si sihT{7: }|
|
||||||
|
{14:hsilgnE dila}^v{7: -}|
|
||||||
|
{15:······yb desopmoc ecnetnes}{7: +│}|
|
||||||
|
{15:··············.evac sih ni}{7: +│}|
|
||||||
|
{1: ~}|*2
|
||||||
|
{11:-- VISUAL LINE --} |
|
||||||
|
]])
|
||||||
|
end
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe('with ext_multigrid', function()
|
describe('with ext_multigrid', function()
|
||||||
|
Loading…
Reference in New Issue
Block a user