Merge pull request #21768 from luukvbaal/test-virtline

fix(column)!: ensure 'statuscolumn' works with virtual and wrapped lines

BREAKING CHANGE: In 'statuscolumn' evaluation, `v:wrap` has been
replaced by `v:virtnum`. `v:virtnum` is negative when drawing
virtual lines, zero when drawing the actual buffer line, and
positive when drawing the wrapped part of a buffer line.
This commit is contained in:
zeertzjq
2023-01-17 06:24:52 +08:00
committed by GitHub
8 changed files with 139 additions and 83 deletions

View File

@@ -2295,13 +2295,15 @@ v:version Vim version number: major version times 100 plus minor
:if has("nvim-0.2.1") :if has("nvim-0.2.1")
< <
*v:vim_did_enter* *vim_did_enter-variable* *v:virtnum* *virtnum-variable*
v:vim_did_enter 0 during startup, 1 just before |VimEnter|. v:virtnum Virtual line number for the 'statuscolumn' expression.
Negative when drawing the status column for virtual lines, zero
when drawing an actual buffer line, and positive when drawing
the wrapped part of a buffer line.
Read-only. Read-only.
*v:wrap* *wrap-variable* *v:vim_did_enter* *vim_did_enter-variable*
v:wrap Boolean indicating whether 'statuscolumn' is being evaluated v:vim_did_enter 0 during startup, 1 just before |VimEnter|.
for the wrapped part of a line.
Read-only. Read-only.
*v:warningmsg* *warningmsg-variable* *v:warningmsg* *warningmsg-variable*

View File

@@ -6017,12 +6017,15 @@ A jump table for the options with a short description can be found at |Q_op|.
%s sign column for currently drawn line %s sign column for currently drawn line
%C fold column for currently drawn line %C fold column for currently drawn line
To draw the sign and fold columns, they must be included in NOTE: To draw the sign and fold columns, their items must be included in
'statuscolumn'. 'statuscolumn'. Even when they are not included, the status column width
will adapt to the 'signcolumn' and 'foldcolumn' width.
The |v:lnum| variable holds the line number to be drawn. The |v:lnum| variable holds the line number to be drawn.
The |v:relnum| variable holds the relative line number to be drawn. The |v:relnum| variable holds the relative line number to be drawn.
The |v:wrap| variable holds true for the wrapped part of a line. The |v:virtnum| variable is negative when drawing virtual lines, zero
when drawing the actual buffer line, and positive when
drawing the wrapped part of a buffer line.
Examples: >vim Examples: >vim
" Relative number with bar separator and click handlers: " Relative number with bar separator and click handlers:
@@ -6032,7 +6035,7 @@ A jump table for the options with a short description can be found at |Q_op|.
:let &stc='%=%{v:relnum?v:relnum:v:lnum} ' :let &stc='%=%{v:relnum?v:relnum:v:lnum} '
" Line numbers in hexadecimal for non wrapped part of lines: " Line numbers in hexadecimal for non wrapped part of lines:
:let &stc='%=%{v:wrap?"":printf("%x",v:lnum)} ' :let &stc='%=%{v:virtnum>0?"":printf("%x",v:lnum)} '
" Human readable line numbers with thousands separator: " Human readable line numbers with thousands separator:
:let &stc='%{substitute(v:lnum,"\\d\\zs\\ze\\' :let &stc='%{substitute(v:lnum,"\\d\\zs\\ze\\'

View File

@@ -21,6 +21,7 @@
#include "nvim/decoration_provider.h" #include "nvim/decoration_provider.h"
#include "nvim/diff.h" #include "nvim/diff.h"
#include "nvim/drawline.h" #include "nvim/drawline.h"
#include "nvim/eval.h"
#include "nvim/extmark_defs.h" #include "nvim/extmark_defs.h"
#include "nvim/fold.h" #include "nvim/fold.h"
#include "nvim/garray.h" #include "nvim/garray.h"
@@ -399,40 +400,45 @@ static int get_sign_attrs(buf_T *buf, linenr_T lnum, SignTextAttrs *sattrs, int
/// Prepare and build the 'statuscolumn' string for line "lnum" in window "wp". /// Prepare and build the 'statuscolumn' string for line "lnum" in window "wp".
/// Fill "stcp" with the built status column string and attributes. /// Fill "stcp" with the built status column string and attributes.
/// This can be called three times per win_line(), once for virt_lines, once for
/// the start of the buffer line "lnum" and once for the wrapped lines.
/// ///
/// @param[out] stcp Status column attributes /// @param[out] stcp Status column attributes
static void get_statuscol_str(win_T *wp, linenr_T lnum, int row, int startrow, int filler_lines, static void get_statuscol_str(win_T *wp, linenr_T lnum, int row, int startrow, int filler_lines,
int cul_attr, int sign_num_attr, int sign_cul_attr, char_u *extra, int cul_attr, int sign_num_attr, int sign_cul_attr, statuscol_T *stcp,
foldinfo_T foldinfo, SignTextAttrs *sattrs, statuscol_T *stcp) foldinfo_T foldinfo, SignTextAttrs *sattrs)
{ {
long relnum = 0; long relnum = -1;
bool wrapped = row != startrow + filler_lines;
bool use_cul = use_cursor_line_sign(wp, lnum); bool use_cul = use_cursor_line_sign(wp, lnum);
int virtnum = row - startrow - filler_lines;
// Set num, fold and sign text and attrs, empty when wrapped set_vim_var_nr(VV_VIRTNUM, virtnum);
if (row == startrow) { // When called the first time for line "lnum" set num_attr
relnum = labs(get_cursor_rel_lnum(wp, lnum)); if (stcp->num_attr == 0) {
stcp->num_attr = sign_num_attr ? sign_num_attr stcp->num_attr = sign_num_attr ? sign_num_attr
: get_line_number_attr(wp, lnum, row, startrow, filler_lines); : get_line_number_attr(wp, lnum, row, startrow, filler_lines);
}
// When called for the first non-filler row of line "lnum" set num v:vars and fold column
if (virtnum == 0) {
relnum = labs(get_cursor_rel_lnum(wp, lnum));
if (compute_foldcolumn(wp, 0)) { if (compute_foldcolumn(wp, 0)) {
size_t n = fill_foldcolumn(stcp->fold_text, wp, foldinfo, lnum); size_t n = fill_foldcolumn(stcp->fold_text, wp, foldinfo, lnum);
stcp->fold_text[n] = NUL; stcp->fold_text[n] = NUL;
stcp->fold_attr = win_hl_attr(wp, use_cul ? HLF_CLF : HLF_FC); stcp->fold_attr = win_hl_attr(wp, use_cul ? HLF_CLF : HLF_FC);
} }
} }
// Make sure to clear->set->clear sign column for filler->first->wrapped lines
int i = 0; int i = 0;
for (; i < wp->w_scwidth; i++) { for (; i < wp->w_scwidth; i++) {
SignTextAttrs *sattr = wrapped ? NULL : sign_get_attr(i, sattrs, wp->w_scwidth); SignTextAttrs *sattr = virtnum ? NULL : sign_get_attr(i, sattrs, wp->w_scwidth);
stcp->sign_text[i] = sattr && sattr->text ? sattr->text : " "; stcp->sign_text[i] = sattr && sattr->text ? sattr->text : " ";
stcp->sign_attr[i] = sattr ? (use_cul && sign_cul_attr ? sign_cul_attr : sattr->hl_attr_id) stcp->sign_attr[i] = sattr ? (use_cul && sign_cul_attr ? sign_cul_attr : sattr->hl_attr_id)
: win_hl_attr(wp, use_cul ? HLF_CLS : HLF_SC); : win_hl_attr(wp, use_cul ? HLF_CLS : HLF_SC);
} }
stcp->sign_text[i] = NULL; stcp->sign_text[i] = NULL;
int width = build_statuscol_str(wp, row == startrow, wrapped, lnum, relnum, int width = build_statuscol_str(wp, lnum, relnum, stcp->width,
stcp->width, ' ', stcp->text, &stcp->hlrec, stcp); ' ', stcp->text, &stcp->hlrec, stcp);
// Force a redraw in case of error or when truncated // Force a redraw in case of error or when truncated
if (*wp->w_p_stc == NUL || (stcp->truncate > 0 && wp->w_nrwidth < MAX_NUMBERWIDTH)) { if (*wp->w_p_stc == NUL || (stcp->truncate > 0 && wp->w_nrwidth < MAX_NUMBERWIDTH)) {
if (stcp->truncate) { // Avoid truncating 'statuscolumn' if (stcp->truncate) { // Avoid truncating 'statuscolumn'
@@ -465,9 +471,8 @@ static void get_statuscol_str(win_T *wp, linenr_T lnum, int row, int startrow, i
/// ///
/// @param stcp Status column attributes /// @param stcp Status column attributes
/// @param[out] draw_state Current draw state in win_line() /// @param[out] draw_state Current draw state in win_line()
static void get_statuscol_display_info(LineDrawState *draw_state, int *char_attr, int *n_extrap, static void get_statuscol_display_info(statuscol_T *stcp, LineDrawState *draw_state, int *char_attr,
int *c_extrap, int *c_finalp, char_u *extra, char **pp_extra, int *n_extrap, int *c_extrap, int *c_finalp, char **pp_extra)
statuscol_T *stcp)
{ {
*c_extrap = NUL; *c_extrap = NUL;
*c_finalp = NUL; *c_finalp = NUL;
@@ -1199,6 +1204,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
} }
int sign_idx = 0; int sign_idx = 0;
int virt_line_index;
int virt_line_offset = -1;
// Repeat for the whole displayed line. // Repeat for the whole displayed line.
for (;;) { for (;;) {
int has_match_conc = 0; ///< match wants to conceal int has_match_conc = 0; ///< match wants to conceal
@@ -1225,9 +1232,22 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
} }
} }
// Skip fold, sign and number states if 'statuscolumn' is set. if (draw_state == WL_FOLD - 1 && n_extra == 0) {
if (draw_state == WL_FOLD - 1 && n_extra == 0 && statuscol.draw) { if (filler_todo > 0) {
draw_state = WL_STC - 1; int index = filler_todo - (filler_lines - n_virt_lines);
if (index > 0) {
virt_line_index = (int)kv_size(virt_lines) - index;
assert(virt_line_index >= 0);
virt_line_offset = kv_A(virt_lines, virt_line_index).left_col ? 0 : win_col_off(wp);
}
}
if (!virt_line_offset) {
// Skip the column states if there is a "virt_left_col" line.
draw_state = WL_BRI - 1;
} else if (statuscol.draw) {
// Skip fold, sign and number states if 'statuscolumn' is set.
draw_state = WL_STC - 1;
}
} }
if (draw_state == WL_FOLD - 1 && n_extra == 0) { if (draw_state == WL_FOLD - 1 && n_extra == 0) {
@@ -1326,14 +1346,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
// Draw the 'statuscolumn' if option is set. // Draw the 'statuscolumn' if option is set.
if (statuscol.draw) { if (statuscol.draw) {
if (statuscol.textp == NULL) { if (statuscol.textp == NULL) {
get_statuscol_str(wp, lnum, row, startrow, filler_lines, cul_attr, sign_num_attr, get_statuscol_str(wp, lnum, row, startrow, filler_lines, cul_attr,
sign_cul_attr, extra, foldinfo, sattrs, &statuscol); sign_num_attr, sign_cul_attr, &statuscol, foldinfo, sattrs);
if (wp->w_redr_statuscol) { if (wp->w_redr_statuscol) {
return 0; break;
} }
} }
get_statuscol_display_info(&draw_state, &char_attr, &n_extra, &c_extra, get_statuscol_display_info(&statuscol, &draw_state, &char_attr,
&c_final, extra, &p_extra, &statuscol); &n_extra, &c_extra, &c_final, &p_extra);
} }
} }
@@ -2750,15 +2770,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
&& !wp->w_p_rl; // Not right-to-left. && !wp->w_p_rl; // Not right-to-left.
int draw_col = col - boguscols; int draw_col = col - boguscols;
if (filler_todo > 0) { if (virt_line_offset >= 0) {
int index = filler_todo - (filler_lines - n_virt_lines); draw_virt_text_item(buf, virt_line_offset, kv_A(virt_lines, virt_line_index).line,
if (index > 0) { kHlModeReplace, grid->cols, 0);
int i = (int)kv_size(virt_lines) - index;
assert(i >= 0);
int offset = kv_A(virt_lines, i).left_col ? 0 : win_col_offset;
draw_virt_text_item(buf, offset, kv_A(virt_lines, i).line,
kHlModeReplace, grid->cols, 0);
}
} else { } else {
draw_virt_text(wp, buf, win_col_offset, &draw_col, grid->cols, row); draw_virt_text(wp, buf, win_col_offset, &draw_col, grid->cols, row);
} }
@@ -2818,16 +2832,18 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
need_showbreak = true; need_showbreak = true;
} }
if (statuscol.draw) { if (statuscol.draw) {
if (row == startrow + 1 || row == startrow + filler_lines) { if (row == startrow + filler_lines + 1 || row == startrow + filler_lines) {
// Re-evaluate 'statuscolumn' for the first wrapped row and non filler line // Re-evaluate 'statuscolumn' for the first wrapped row and non filler line
statuscol.textp = NULL; statuscol.textp = NULL;
} else { // Otherwise just reset the text/hlrec pointers } else if (statuscol.textp) {
// Draw the already built 'statuscolumn' on the next wrapped or filler line
statuscol.textp = statuscol.text; statuscol.textp = statuscol.text;
statuscol.hlrecp = statuscol.hlrec; statuscol.hlrecp = statuscol.hlrec;
} // Fall back to default columns if the 'n' flag isn't in 'cpo' } // Fall back to default columns if the 'n' flag isn't in 'cpo'
statuscol.draw = vim_strchr(p_cpo, CPO_NUMCOL) == NULL; statuscol.draw = vim_strchr(p_cpo, CPO_NUMCOL) == NULL;
} }
filler_todo--; filler_todo--;
virt_line_offset = -1;
// When the filler lines are actually below the last line of the // When the filler lines are actually below the last line of the
// file, don't draw the line itself, break here. // file, don't draw the line itself, break here.
if (filler_todo == 0 && (wp->w_botfill || end_fill)) { if (filler_todo == 0 && (wp->w_botfill || end_fill)) {

View File

@@ -268,7 +268,7 @@ static struct vimvar {
VV(VV__NULL_BLOB, "_null_blob", VAR_BLOB, VV_RO), VV(VV__NULL_BLOB, "_null_blob", VAR_BLOB, VV_RO),
VV(VV_LUA, "lua", VAR_PARTIAL, VV_RO), VV(VV_LUA, "lua", VAR_PARTIAL, VV_RO),
VV(VV_RELNUM, "relnum", VAR_NUMBER, VV_RO), VV(VV_RELNUM, "relnum", VAR_NUMBER, VV_RO),
VV(VV_WRAP, "wrap", VAR_BOOL, VV_RO), VV(VV_VIRTNUM, "virtnum", VAR_NUMBER, VV_RO),
}; };
#undef VV #undef VV

View File

@@ -166,7 +166,7 @@ typedef enum {
VV__NULL_BLOB, // Blob with NULL value. For test purposes only. VV__NULL_BLOB, // Blob with NULL value. For test purposes only.
VV_LUA, VV_LUA,
VV_RELNUM, VV_RELNUM,
VV_WRAP, VV_VIRTNUM,
} VimVarIndex; } VimVarIndex;
/// All recognized msgpack types /// All recognized msgpack types

View File

@@ -784,7 +784,7 @@ int number_width(win_T *wp)
if (*wp->w_p_stc != NUL) { if (*wp->w_p_stc != NUL) {
char buf[MAXPATHL]; char buf[MAXPATHL];
wp->w_nrwidth_width = 0; wp->w_nrwidth_width = 0;
n = build_statuscol_str(wp, true, false, lnum, 0, 0, NUL, buf, NULL, NULL); n = build_statuscol_str(wp, lnum, 0, 0, NUL, buf, NULL, NULL);
n = MAX(n, (wp->w_p_nu || wp->w_p_rnu) * (int)wp->w_p_nuw); n = MAX(n, (wp->w_p_nu || wp->w_p_rnu) * (int)wp->w_p_nuw);
wp->w_nrwidth_width = MIN(n, MAX_NUMBERWIDTH); wp->w_nrwidth_width = MIN(n, MAX_NUMBERWIDTH);
return wp->w_nrwidth_width; return wp->w_nrwidth_width;

View File

@@ -876,14 +876,13 @@ void draw_tabline(void)
/// @param hlrec HL attributes (can be NULL) /// @param hlrec HL attributes (can be NULL)
/// @param stcp Status column attributes (can be NULL) /// @param stcp Status column attributes (can be NULL)
/// @return The width of the built status column string for line "lnum" /// @return The width of the built status column string for line "lnum"
int build_statuscol_str(win_T *wp, bool setnum, bool wrap, linenr_T lnum, long relnum, int maxwidth, int build_statuscol_str(win_T *wp, linenr_T lnum, long relnum, int maxwidth, int fillchar,
int fillchar, char *buf, stl_hlrec_t **hlrec, statuscol_T *stcp) char *buf, stl_hlrec_t **hlrec, statuscol_T *stcp)
{ {
if (setnum) { if (relnum >= 0) {
set_vim_var_nr(VV_LNUM, lnum); set_vim_var_nr(VV_LNUM, lnum);
set_vim_var_nr(VV_RELNUM, relnum); set_vim_var_nr(VV_RELNUM, relnum);
} }
set_vim_var_bool(VV_WRAP, wrap);
StlClickRecord *clickrec; StlClickRecord *clickrec;
char *stc = xstrdup(wp->w_p_stc); char *stc = xstrdup(wp->w_p_stc);
@@ -1506,13 +1505,12 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n
case STL_LINE: case STL_LINE:
// Overload %l with v:lnum for 'statuscolumn' // Overload %l with v:lnum for 'statuscolumn'
if (opt_name != NULL && strcmp(opt_name, "statuscolumn") == 0) { if (opt_name != NULL && strcmp(opt_name, "statuscolumn") == 0) {
if (wp->w_p_nu) { if (wp->w_p_nu && !get_vim_var_nr(VV_VIRTNUM)) {
num = get_vim_var_nr(VV_LNUM); num = get_vim_var_nr(VV_LNUM);
} }
} else { } else {
num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) ? 0L : (long)(wp->w_cursor.lnum); num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) ? 0L : (long)(wp->w_cursor.lnum);
} }
break; break;
case STL_NUMLINES: case STL_NUMLINES:
@@ -1612,7 +1610,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n
case STL_ROFLAG_ALT: case STL_ROFLAG_ALT:
// Overload %r with v:relnum for 'statuscolumn' // Overload %r with v:relnum for 'statuscolumn'
if (opt_name != NULL && strcmp(opt_name, "statuscolumn") == 0) { if (opt_name != NULL && strcmp(opt_name, "statuscolumn") == 0) {
if (wp->w_p_rnu) { if (wp->w_p_rnu && !get_vim_var_nr(VV_VIRTNUM)) {
num = get_vim_var_nr(VV_RELNUM); num = get_vim_var_nr(VV_RELNUM);
} }
} else { } else {

View File

@@ -4,6 +4,7 @@ local clear = helpers.clear
local command = helpers.command local command = helpers.command
local eq = helpers.eq local eq = helpers.eq
local eval = helpers.eval local eval = helpers.eval
local exec_lua = helpers.exec_lua
local meths = helpers.meths local meths = helpers.meths
local pcall_err = helpers.pcall_err local pcall_err = helpers.pcall_err
@@ -15,8 +16,8 @@ describe('statuscolumn', function()
screen:attach() screen:attach()
end) end)
it('fails with invalid \'statuscolumn\'', function() it("fails with invalid 'statuscolumn'", function()
command('set stc=%{v:relnum?v:relnum:(v:lnum==5?invalid:v:lnum)}\\ ') command([[set stc=%{v:relnum?v:relnum:(v:lnum==5?invalid:v:lnum)}\ ]])
screen:expect([[ screen:expect([[
4 aaaaa | 4 aaaaa |
3 aaaaa | 3 aaaaa |
@@ -38,8 +39,8 @@ describe('statuscolumn', function()
eq('', eval('&statuscolumn')) eq('', eval('&statuscolumn'))
end) end)
it('widens with irregular \'statuscolumn\' width', function() it("widens with irregular 'statuscolumn' width", function()
command('set stc=%{v:relnum?v:relnum:(v:lnum==5?\'bbbbb\':v:lnum)}') command([[set stc=%{v:relnum?v:relnum:(v:lnum==5?'bbbbb':v:lnum)}]])
command('norm 5G | redraw!') command('norm 5G | redraw!')
screen:expect([[ screen:expect([[
1 aaaaa | 1 aaaaa |
@@ -59,7 +60,7 @@ describe('statuscolumn', function()
]]) ]])
end) end)
it('works with \'statuscolumn\'', function() it("works with 'statuscolumn'", function()
command([[set stc=%{&nu?v:lnum:''}%=%{&rnu?'\ '.v:relnum:''}│]]) command([[set stc=%{&nu?v:lnum:''}%=%{&rnu?'\ '.v:relnum:''}│]])
screen:expect([[ screen:expect([[
4 │aaaaa | 4 │aaaaa |
@@ -122,7 +123,7 @@ describe('statuscolumn', function()
command([[set stc=%{&nu?v:lnum:''}%=%{&rnu?'\ '.v:relnum:''}│]]) command([[set stc=%{&nu?v:lnum:''}%=%{&rnu?'\ '.v:relnum:''}│]])
end) end)
it('works with highlighted \'statuscolumn\'', function() it("works with highlighted 'statuscolumn'", function()
command([[set stc=%#NonText#%{&nu?v:lnum:''}]] .. command([[set stc=%#NonText#%{&nu?v:lnum:''}]] ..
[[%=%{&rnu&&(v:lnum%2)?'\ '.v:relnum:''}]] .. [[%=%{&rnu&&(v:lnum%2)?'\ '.v:relnum:''}]] ..
[[%#LineNr#%{&rnu&&!(v:lnum%2)?'\ '.v:relnum:''}│]]) [[%#LineNr#%{&rnu&&!(v:lnum%2)?'\ '.v:relnum:''}│]])
@@ -183,7 +184,7 @@ describe('statuscolumn', function()
end) end)
it('works with wrapped lines, signs and folds', function() it('works with wrapped lines, signs and folds', function()
command("set stc=%C%s%=%{v:wrap?'':v:lnum}│\\ ") command([[set stc=%C%s%=%{v:virtnum?'':v:lnum}│\ ]])
command("call setline(1,repeat([repeat('aaaaa',10)],16))") command("call setline(1,repeat([repeat('aaaaa',10)],16))")
screen:set_default_attr_ids({ screen:set_default_attr_ids({
[0] = {bold = true, foreground = Screen.colors.Blue}, [0] = {bold = true, foreground = Screen.colors.Blue},
@@ -234,7 +235,7 @@ describe('statuscolumn', function()
]]) ]])
command('norm zf$') command('norm zf$')
-- Check that alignment works properly with signs after %= -- Check that alignment works properly with signs after %=
command("set stc=%C%=%{v:wrap?'':v:lnum}│%s\\ ") command([[set stc=%C%=%{v:virtnum?'':v:lnum}│%s\ ]])
screen:expect([[ screen:expect([[
{2: }{1: 4│>>}{2: }{1: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| {2: }{1: 4│>>}{2: }{1: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
{2: }{1: │}{2: }{1: }aaaaaa | {2: }{1: │}{2: }{1: }aaaaaa |
@@ -269,7 +270,7 @@ describe('statuscolumn', function()
| |
]]) ]])
-- v:lnum is the same value on wrapped lines -- v:lnum is the same value on wrapped lines
command("set stc=%C%=%{v:lnum}│%s\\ ") command([[set stc=%C%=%{v:lnum}│%s\ ]])
screen:expect([[ screen:expect([[
{2: }{1: 4│>>}{2: }{1: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| {2: }{1: 4│>>}{2: }{1: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
{2: }{1: 4│}{2: }{1: }aaaaaa | {2: }{1: 4│}{2: }{1: }aaaaaa |
@@ -287,7 +288,7 @@ describe('statuscolumn', function()
| |
]]) ]])
-- v:relnum is the same value on wrapped lines -- v:relnum is the same value on wrapped lines
command("set stc=%C%=\\ %{v:relnum}│%s\\ ") command([[set stc=%C%=\ %{v:relnum}│%s\ ]])
screen:expect([[ screen:expect([[
{2: }{1: 4│>>}{2: }{1: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| {2: }{1: 4│>>}{2: }{1: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
{2: }{1: 4│}{2: }{1: }aaaaaa | {2: }{1: 4│}{2: }{1: }aaaaaa |
@@ -304,7 +305,7 @@ describe('statuscolumn', function()
{2: }{1: 2│}{2: }{1: }aaaaaa | {2: }{1: 2│}{2: }{1: }aaaaaa |
| |
]]) ]])
command("set stc=%C%=\\ %{v:wrap?'':v:relnum}│%s\\ ") command([[set stc=%C%=\ %{v:virtnum?'':v:relnum}│%s\ ]])
screen:expect([[ screen:expect([[
{2: }{1: 4│>>}{2: }{1: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| {2: }{1: 4│>>}{2: }{1: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
{2: }{1: │}{2: }{1: }aaaaaa | {2: }{1: │}{2: }{1: }aaaaaa |
@@ -346,9 +347,34 @@ describe('statuscolumn', function()
{2: }{1: │}{2: }{1: }aaaaaaaaaaaaaaaaaaaa | {2: }{1: │}{2: }{1: }aaaaaaaaaaaaaaaaaaaa |
| |
]]) ]])
-- Status column is re-evaluated for virt_lines, buffer line, and wrapped line
exec_lua([[
local ns = vim.api.nvim_create_namespace("ns")
vim.api.nvim_buf_set_extmark(0, ns, 5, 0, {
virt_lines_above = true, virt_lines = {{{"virt_line above", ""}}} })
vim.api.nvim_buf_set_extmark(0, ns, 4, 0, { virt_lines = {{{"virt_line", ""}}} })
]])
command('set foldcolumn=0 signcolumn=no')
command([[set stc=%{v:virtnum<0?'virtual':(!v:virtnum?'buffer':'wrapped')}%=%{'\ '.v:virtnum.'\ '.v:lnum}]])
screen:expect([[
{1:buffer 0 4}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
{1:wrapped 1 4}aaaaaaaa |
{1:buffer 0 5}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
{1:wrapped 1 5}aaaaaaaa |
{1:virtual-2 5}virt_line |
{1:virtual-2 5}virt_line above |
{1:buffer 0 6}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
{1:wrapped 1 6}aaaaaaaa |
{1:buffer 0 7}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
{1:wrapped 1 7}aaaaaaaa |
{4:buffer 0 8}{5:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
{1:buffer 0 9}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
{1:wrapped 1 9}aaaaaaaa |
|
]])
end) end)
it('works with \'statuscolumn\' clicks', function() it("works with 'statuscolumn' clicks", function()
command('set mousemodel=extend') command('set mousemodel=extend')
command([[ command([[
function! MyClickFunc(minwid, clicks, button, mods) function! MyClickFunc(minwid, clicks, button, mods)
@@ -385,25 +411,36 @@ describe('statuscolumn', function()
eq('', eval("g:testvar")) eq('', eval("g:testvar"))
end) end)
it('fits maximum multibyte foldcolumn #21759', function() it('works with foldcolumn', function()
command('set stc=%C fdc=9 fillchars=foldsep:𒀀') -- Fits maximum multibyte foldcolumn #21759
command([[set stc=%C%=%l\ fdc=9 fillchars=foldsep:𒀀]])
for _ = 0,8 do command('norm zfjzo') end for _ = 0,8 do command('norm zfjzo') end
-- 'statuscolumn' is not drawn for `virt_lines_leftcol` lines
exec_lua([[
local ns = vim.api.nvim_create_namespace("ns")
vim.api.nvim_buf_set_extmark(0, ns, 6, 0, {
virt_lines_leftcol = true, virt_lines = {{{"virt", ""}}} })
vim.api.nvim_buf_set_extmark(0, ns, 7, 0, {
virt_lines_leftcol = true, virt_lines = {{{"virt", ""}}} })
]])
helpers.feed('lh') -- force update wcol/row
screen:expect([[ screen:expect([[
aaaaa | 4 aaaaa |
aaaaa | 5 aaaaa |
aaaaa | 6 aaaaa |
aaaaa | 7 aaaaa |
--------- ^aaaaa | virt |
𒀀𒀀𒀀𒀀𒀀𒀀𒀀𒀀𒀀 aaaaa | --------- 8 ^aaaaa |
aaaaa | virt |
aaaaa | 𒀀𒀀𒀀𒀀𒀀𒀀𒀀𒀀𒀀 9 aaaaa |
aaaaa | 10 aaaaa |
aaaaa | 11 aaaaa |
aaaaa | 12 aaaaa |
aaaaa | 13 aaaaa |
aaaaa | 14 aaaaa |
| |
]]) ]])
command('set stc=') -- also for the default sign column
screen:expect_unchanged()
end) end)
end) end)