aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/buffer_defs.h2
-rw-r--r--src/nvim/decoration.c6
-rw-r--r--src/nvim/drawline.c2
-rw-r--r--src/nvim/drawscreen.c7
-rw-r--r--src/nvim/option.c45
-rw-r--r--src/nvim/option_vars.h3
-rw-r--r--src/nvim/optionstr.c58
7 files changed, 55 insertions, 68 deletions
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 039484d2e2..21cbefdb90 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -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 ===
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index 48dffea24b..b784d8bea3 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -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);
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index 5813dada28..c1d4e55fe5 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -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).
diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c
index 7a9c5eb588..fee2f288f6 100644
--- a/src/nvim/drawscreen.c
+++ b/src/nvim/drawscreen.c
@@ -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;
}
diff --git a/src/nvim/option.c b/src/nvim/option.c
index a920912452..0fae498b25 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -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;
}
diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h
index 0193e43de7..ce65750d78 100644
--- a/src/nvim/option_vars.h
+++ b/src/nvim/option_vars.h
@@ -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"
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index 000fbaba95..56f44788b0 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -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) {
+ 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;
}
- // 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;
- }
- return OK;
+ if (strncmp(val, "auto:", 5) != 0
+ || strlen(val) != 8
+ || !ascii_isdigit(val[5])
+ || val[6] != '-'
+ || !ascii_isdigit(val[7])) {
+ return FAIL;
}
- 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;