mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
refactor(sign): store 'signcolumn' width range when it is set
Problem: Minimum and maximum signcolumn width is determined each redraw. Solution: Determine and store 'signcolumn' range when option is set.
This commit is contained in:
parent
fec5e3ab24
commit
585eeacb24
@ -1206,6 +1206,8 @@ struct window_S {
|
||||
int w_nrwidth; // width of 'number' and 'relativenumber'
|
||||
// column being used
|
||||
int w_scwidth; // width of 'signcolumn'
|
||||
int w_minscwidth; // minimum width or SCL_NO/SCL_NUM
|
||||
int w_maxscwidth; // maximum width or SCL_NO/SCL_NUM
|
||||
|
||||
// === end of cached values ===
|
||||
|
||||
|
@ -442,7 +442,9 @@ void decor_redraw_signs(win_T *wp, buf_T *buf, int row, SignTextAttrs sattrs[],
|
||||
int *cul_id, int *num_id)
|
||||
{
|
||||
MarkTreeIter itr[1];
|
||||
if (!buf->b_signs || !marktree_itr_get_overlap(buf->b_marktree, row, 0, itr)) {
|
||||
if (!buf->b_signs
|
||||
|| wp->w_minscwidth == SCL_NO
|
||||
|| !marktree_itr_get_overlap(buf->b_marktree, row, 0, itr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -471,7 +473,7 @@ void decor_redraw_signs(win_T *wp, buf_T *buf, int row, SignTextAttrs sattrs[],
|
||||
}
|
||||
|
||||
if (kv_size(signs)) {
|
||||
int width = (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u') ? 1 : wp->w_scwidth;
|
||||
int width = wp->w_minscwidth == SCL_NUM ? 1 : wp->w_scwidth;
|
||||
int idx = MIN(width, num_text) - 1;
|
||||
qsort((void *)&kv_A(signs, 0), kv_size(signs), sizeof(MTKey), sign_cmp);
|
||||
|
||||
|
@ -561,7 +561,7 @@ static void handle_lnum_col(win_T *wp, winlinevars_T *wlv, int sign_num_attr, in
|
||||
&& !((has_cpo_n && !wp->w_p_bri) && wp->w_skipcol > 0 && wlv->lnum == wp->w_topline)) {
|
||||
// If 'signcolumn' is set to 'number' and a sign is present in "lnum",
|
||||
// then display the sign instead of the line number.
|
||||
if (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u' && wlv->sattrs[0].text) {
|
||||
if (wp->w_minscwidth == SCL_NUM && wlv->sattrs[0].text) {
|
||||
get_sign_display_info(true, wp, wlv, 0, sign_cul_attr);
|
||||
} else {
|
||||
// Draw the line number (empty space after wrapping).
|
||||
|
@ -606,7 +606,7 @@ int update_screen(void)
|
||||
}
|
||||
|
||||
// Reset 'statuscolumn' if there is no dedicated signcolumn but it is invalid.
|
||||
if (*wp->w_p_stc != NUL && !wp->w_buffer->b_signcols.valid && win_no_signcol(wp)) {
|
||||
if (*wp->w_p_stc != NUL && !wp->w_buffer->b_signcols.valid && wp->w_minscwidth <= SCL_NO) {
|
||||
wp->w_nrwidth_line_count = 0;
|
||||
wp->w_valid &= ~VALID_WCOL;
|
||||
wp->w_redr_type = UPD_NOT_VALID;
|
||||
@ -619,7 +619,7 @@ int update_screen(void)
|
||||
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||
// Validate b_signcols if there is no dedicated signcolumn but 'statuscolumn' is set.
|
||||
if (*wp->w_p_stc != NUL && win_no_signcol(wp)) {
|
||||
if (*wp->w_p_stc != NUL && wp->w_minscwidth <= SCL_NO) {
|
||||
buf_signcols(wp->w_buffer, 0);
|
||||
}
|
||||
|
||||
@ -2632,8 +2632,7 @@ int number_width(win_T *wp)
|
||||
|
||||
// If 'signcolumn' is set to 'number' and there is a sign to display, then
|
||||
// the minimal width for the number column is 2.
|
||||
if (n < 2 && wp->w_buffer->b_signs_with_text
|
||||
&& (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u')) {
|
||||
if (n < 2 && wp->w_buffer->b_signs_with_text && wp->w_minscwidth == SCL_NUM) {
|
||||
n = 2;
|
||||
}
|
||||
|
||||
|
@ -2245,6 +2245,7 @@ static const char *did_set_number_relativenumber(optset_T *args)
|
||||
// When 'relativenumber'/'number' is changed and 'statuscolumn' is set, reset width.
|
||||
win->w_nrwidth_line_count = 0;
|
||||
}
|
||||
check_signcolumn(win);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -4861,6 +4862,7 @@ void didset_window_options(win_T *wp, bool valid_cursor)
|
||||
parse_winhl_opt(wp); // sets w_hl_needs_update also for w_p_winbl
|
||||
check_blending(wp);
|
||||
set_winbar_win(wp, false, valid_cursor);
|
||||
check_signcolumn(wp);
|
||||
wp->w_grid_alloc.blending = wp->w_p_winbl > 0;
|
||||
}
|
||||
|
||||
@ -6170,49 +6172,12 @@ bool fish_like_shell(void)
|
||||
/// buffer signs and on user configuration.
|
||||
int win_signcol_count(win_T *wp)
|
||||
{
|
||||
return win_signcol_configured(wp);
|
||||
}
|
||||
|
||||
/// Return true when window "wp" has no sign column.
|
||||
bool win_no_signcol(win_T *wp)
|
||||
{
|
||||
const char *scl = wp->w_p_scl;
|
||||
return (*scl == 'n' && (*(scl + 1) == 'o' || (*(scl + 1) == 'u'
|
||||
&& (wp->w_p_nu || wp->w_p_rnu))));
|
||||
}
|
||||
|
||||
/// Return the number of requested sign columns, based on user / configuration.
|
||||
int win_signcol_configured(win_T *wp)
|
||||
{
|
||||
const char *scl = wp->w_p_scl;
|
||||
|
||||
if (win_no_signcol(wp)) {
|
||||
if (wp->w_minscwidth <= SCL_NO) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// yes or yes
|
||||
if (!strncmp(scl, "yes:", 4)) {
|
||||
// Fixed amount of columns
|
||||
return scl[4] - '0';
|
||||
}
|
||||
if (*scl == 'y') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int minimum = 0, maximum = 1;
|
||||
|
||||
if (!strncmp(scl, "auto:", 5)) {
|
||||
// Variable depending on a configuration
|
||||
maximum = scl[5] - '0';
|
||||
// auto:<NUM>-<NUM>
|
||||
if (strlen(scl) == 8 && *(scl + 6) == '-') {
|
||||
minimum = maximum;
|
||||
maximum = scl[7] - '0';
|
||||
}
|
||||
}
|
||||
|
||||
int needed_signcols = buf_signcols(wp->w_buffer, maximum);
|
||||
int ret = MAX(minimum, MIN(maximum, needed_signcols));
|
||||
int needed_signcols = buf_signcols(wp->w_buffer, wp->w_maxscwidth);
|
||||
int ret = MAX(wp->w_minscwidth, MIN(wp->w_maxscwidth, needed_signcols));
|
||||
assert(ret <= SIGN_SHOW_MAX);
|
||||
return ret;
|
||||
}
|
||||
|
@ -947,3 +947,6 @@ enum {
|
||||
#define MAX_NUMBERWIDTH 20 // used for 'numberwidth' and 'statuscolumn'
|
||||
|
||||
#define TABSTOP_MAX 9999
|
||||
|
||||
#define SCL_NO -1 // 'signcolumn' set to "no"
|
||||
#define SCL_NUM -2 // 'signcolumn' set to "number"
|
||||
|
@ -388,34 +388,53 @@ static bool valid_filetype(const char *val)
|
||||
return valid_name(val, ".-_");
|
||||
}
|
||||
|
||||
/// Handle setting 'signcolumn' for value 'val'
|
||||
/// Handle setting 'signcolumn' for value 'val'. Store minimum and maximum width.
|
||||
///
|
||||
/// @return OK when the value is valid, FAIL otherwise
|
||||
static int check_signcolumn(char *val)
|
||||
int check_signcolumn(win_T *wp)
|
||||
{
|
||||
char *val = wp->w_p_scl;
|
||||
if (*val == NUL) {
|
||||
return FAIL;
|
||||
}
|
||||
// check for basic match
|
||||
if (check_opt_strings(val, p_scl_values, false) == OK) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
// check for 'auto:<NUMBER>-<NUMBER>'
|
||||
if (strlen(val) == 8
|
||||
&& !strncmp(val, "auto:", 5)
|
||||
&& ascii_isdigit(val[5])
|
||||
&& val[6] == '-'
|
||||
&& ascii_isdigit(val[7])) {
|
||||
int min = val[5] - '0';
|
||||
int max = val[7] - '0';
|
||||
if (min < 1 || max < 2 || min > 8 || max > 9 || min >= max) {
|
||||
return FAIL;
|
||||
if (check_opt_strings(val, p_scl_values, false) == OK) {
|
||||
if (!strncmp(val, "no", 2)) { // no
|
||||
wp->w_minscwidth = wp->w_maxscwidth = SCL_NO;
|
||||
} else if (!strncmp(val, "nu", 2) && (wp->w_p_nu || wp->w_p_rnu)) { // number
|
||||
wp->w_minscwidth = wp->w_maxscwidth = SCL_NUM;
|
||||
} else if (!strncmp(val, "yes:", 4)) { // yes:<NUM>
|
||||
wp->w_minscwidth = wp->w_maxscwidth = val[4] - '0';
|
||||
} else if (*val == 'y') { // yes
|
||||
wp->w_minscwidth = wp->w_maxscwidth = 1;
|
||||
} else if (!strncmp(val, "auto:", 5)) { // auto:<NUM>
|
||||
wp->w_minscwidth = 0;
|
||||
wp->w_maxscwidth = val[5] - '0';
|
||||
} else { // auto
|
||||
wp->w_minscwidth = 0;
|
||||
wp->w_maxscwidth = 1;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
return FAIL;
|
||||
if (strncmp(val, "auto:", 5) != 0
|
||||
|| strlen(val) != 8
|
||||
|| !ascii_isdigit(val[5])
|
||||
|| val[6] != '-'
|
||||
|| !ascii_isdigit(val[7])) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// auto:<NUM>-<NUM>
|
||||
int min = val[5] - '0';
|
||||
int max = val[7] - '0';
|
||||
if (min < 1 || max < 2 || min > 8 || min >= max) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
wp->w_minscwidth = min;
|
||||
wp->w_maxscwidth = max;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/// Check validity of options with the 'statusline' format.
|
||||
@ -2072,16 +2091,13 @@ int expand_set_showcmdloc(optexpand_T *args, int *numMatches, char ***matches)
|
||||
const char *did_set_signcolumn(optset_T *args)
|
||||
{
|
||||
win_T *win = (win_T *)args->os_win;
|
||||
char **varp = (char **)args->os_varp;
|
||||
const char *oldval = args->os_oldval.string.data;
|
||||
if (check_signcolumn(*varp) != OK) {
|
||||
if (check_signcolumn(win) != OK) {
|
||||
return e_invarg;
|
||||
}
|
||||
// When changing the 'signcolumn' to or from 'number', recompute the
|
||||
// width of the number column if 'number' or 'relativenumber' is set.
|
||||
if (((*oldval == 'n' && *(oldval + 1) == 'u')
|
||||
|| (*win->w_p_scl == 'n' && *(win->w_p_scl + 1) == 'u'))
|
||||
&& (win->w_p_nu || win->w_p_rnu)) {
|
||||
if ((*oldval == 'n' && *(oldval + 1) == 'u') || win->w_minscwidth == SCL_NUM) {
|
||||
win->w_nrwidth_line_count = 0;
|
||||
}
|
||||
return NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user