summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-06-17 21:48:05 +0200
committerBram Moolenaar <Bram@vim.org>2019-06-17 21:48:05 +0200
commit394c5d8870b15150fc91a4c058dc571fd5eaa97e (patch)
tree7b94cca5df86c565532c52fa6e5c28b4d4b80645
parent6e5000d493b4f385f901eb97f3ce0c8088373403 (diff)
downloadvim-git-394c5d8870b15150fc91a4c058dc571fd5eaa97e.tar.gz
patch 8.1.1564: sign column takes up spacev8.1.1564
Problem: Sign column takes up space. (Adam Stankiewicz) Solution: Optionally put signs in the number column. (Yegappan Lakshmanan, closes #4555, closes #4515)
-rw-r--r--runtime/doc/options.txt2
-rw-r--r--src/option.c8
-rw-r--r--src/screen.c183
-rw-r--r--src/testdir/test_signs.vim57
-rw-r--r--src/version.c2
5 files changed, 185 insertions, 67 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 949d82f9c..18f6a6774 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -6803,6 +6803,8 @@ A jump table for the options with a short description can be found at |Q_op|.
"auto" only when there is a sign to display
"no" never
"yes" always
+ "number" display signs in the 'number' column. If the number
+ column is not present, then behaves like 'auto'.
*'smartcase'* *'scs'* *'nosmartcase'* *'noscs'*
diff --git a/src/option.c b/src/option.c
index 51d621246..a1cddcf59 100644
--- a/src/option.c
+++ b/src/option.c
@@ -3231,7 +3231,7 @@ static char *(p_fcl_values[]) = {"all", NULL};
static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", "noinsert", "noselect", NULL};
#endif
#ifdef FEAT_SIGNS
-static char *(p_scl_values[]) = {"yes", "no", "auto", NULL};
+static char *(p_scl_values[]) = {"yes", "no", "auto", "number", NULL};
#endif
#if defined(MSWIN) && defined(FEAT_TERMINAL)
static char *(p_twt_values[]) = {"winpty", "conpty", "", NULL};
@@ -13556,6 +13556,12 @@ get_bkc_value(buf_T *buf)
int
signcolumn_on(win_T *wp)
{
+ // If 'signcolumn' is set to 'number', signs are displayed in the 'number'
+ // column (if present). Otherwise signs are to be displayed in the sign
+ // column.
+ if (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u')
+ return wp->w_buffer->b_signlist != NULL && !wp->w_p_nu && !wp->w_p_rnu;
+
if (*wp->w_p_scl == 'n')
return FALSE;
if (*wp->w_p_scl == 'y')
diff --git a/src/screen.c b/src/screen.c
index 988626741..016355e5d 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -3037,6 +3037,91 @@ text_prop_compare(const void *s1, const void *s2)
}
#endif
+#ifdef FEAT_SIGNS
+/*
+ * Get information needed to display the sign in line 'lnum' in window 'wp'.
+ * If 'nrcol' is TRUE, the sign is going to be displayed in the number column.
+ * Otherwise the sign is going to be displayed in the sign column.
+ */
+ static void
+get_sign_display_info(
+ int nrcol,
+ win_T *wp,
+ linenr_T lnum,
+ int wcr_attr,
+ int row,
+ int startrow,
+ int filler_lines,
+ int filler_todo,
+ int *c_extrap,
+ int *c_finalp,
+ char_u *extra,
+ char_u **pp_extra,
+ int *n_extrap,
+ int *char_attrp)
+{
+ int text_sign;
+# ifdef FEAT_SIGN_ICONS
+ int icon_sign;
+# endif
+
+ // Draw two cells with the sign value or blank.
+ *c_extrap = ' ';
+ *c_finalp = NUL;
+ if (nrcol)
+ *n_extrap = number_width(wp) + 1;
+ else
+ {
+ *char_attrp = hl_combine_attr(wcr_attr, HL_ATTR(HLF_SC));
+ *n_extrap = 2;
+ }
+
+ if (row == startrow
+#ifdef FEAT_DIFF
+ + filler_lines && filler_todo <= 0
+#endif
+ )
+ {
+ text_sign = buf_getsigntype(wp->w_buffer, lnum, SIGN_TEXT);
+# ifdef FEAT_SIGN_ICONS
+ icon_sign = buf_getsigntype(wp->w_buffer, lnum, SIGN_ICON);
+ if (gui.in_use && icon_sign != 0)
+ {
+ // Use the image in this position.
+ *c_extrap = SIGN_BYTE;
+ *c_finalp = NUL;
+# ifdef FEAT_NETBEANS_INTG
+ if (buf_signcount(wp->w_buffer, lnum) > 1)
+ {
+ *c_extrap = MULTISIGN_BYTE;
+ *c_finalp = NUL;
+ }
+# endif
+ *char_attrp = icon_sign;
+ }
+ else
+# endif
+ if (text_sign != 0)
+ {
+ *pp_extra = sign_get_text(text_sign);
+ if (*pp_extra != NULL)
+ {
+ if (nrcol)
+ {
+ sprintf((char *)extra, "%-*s ", number_width(wp),
+ *pp_extra);
+ *pp_extra = extra;
+ }
+ *c_extrap = NUL;
+ *c_finalp = NUL;
+ *n_extrap = (int)STRLEN(*pp_extra);
+ }
+ *char_attrp = sign_get_attr(text_sign, FALSE);
+ }
+ }
+}
+#endif
+
/*
* Display line "lnum" of window 'wp' on the screen.
* Start at row "startrow", stop when "endrow" is reached.
@@ -3876,58 +3961,9 @@ win_line(
/* Show the sign column when there are any signs in this
* buffer or when using Netbeans. */
if (signcolumn_on(wp))
- {
- int text_sign;
-# ifdef FEAT_SIGN_ICONS
- int icon_sign;
-# endif
-
- /* Draw two cells with the sign value or blank. */
- c_extra = ' ';
- c_final = NUL;
- char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_SC));
- n_extra = 2;
-
- if (row == startrow
-#ifdef FEAT_DIFF
- + filler_lines && filler_todo <= 0
-#endif
- )
- {
- text_sign = buf_getsigntype(wp->w_buffer, lnum,
- SIGN_TEXT);
-# ifdef FEAT_SIGN_ICONS
- icon_sign = buf_getsigntype(wp->w_buffer, lnum,
- SIGN_ICON);
- if (gui.in_use && icon_sign != 0)
- {
- /* Use the image in this position. */
- c_extra = SIGN_BYTE;
- c_final = NUL;
-# ifdef FEAT_NETBEANS_INTG
- if (buf_signcount(wp->w_buffer, lnum) > 1)
- {
- c_extra = MULTISIGN_BYTE;
- c_final = NUL;
- }
-# endif
- char_attr = icon_sign;
- }
- else
-# endif
- if (text_sign != 0)
- {
- p_extra = sign_get_text(text_sign);
- if (p_extra != NULL)
- {
- c_extra = NUL;
- c_final = NUL;
- n_extra = (int)STRLEN(p_extra);
- }
- char_attr = sign_get_attr(text_sign, FALSE);
- }
- }
- }
+ get_sign_display_info(FALSE, wp, lnum, wcr_attr, row,
+ startrow, filler_lines, filler_todo, &c_extra,
+ &c_final, extra, &p_extra, &n_extra, &char_attr);
}
#endif
@@ -3943,13 +3979,27 @@ win_line(
#endif
|| vim_strchr(p_cpo, CPO_NUMCOL) == NULL))
{
- /* Draw the line number (empty space after wrapping). */
- if (row == startrow
+#ifdef FEAT_SIGNS
+ // 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')
+ && buf_findsign_id(wp->w_buffer, lnum,
+ (char_u *)"*") != 0)
+ get_sign_display_info(TRUE, wp, lnum, wcr_attr, row,
+ startrow, filler_lines, filler_todo, &c_extra,
+ &c_final, extra, &p_extra, &n_extra,
+ &char_attr);
+ else
+#endif
+ {
+ /* Draw the line number (empty space after wrapping). */
+ if (row == startrow
#ifdef FEAT_DIFF
+ filler_lines
#endif
)
- {
+ {
long num;
char *fmt = "%*ld ";
@@ -3992,23 +4042,24 @@ win_line(
p_extra = extra;
c_extra = NUL;
c_final = NUL;
- }
- else
- {
+ }
+ else
+ {
c_extra = ' ';
c_final = NUL;
- }
- n_extra = number_width(wp) + 1;
- char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_N));
+ }
+ n_extra = number_width(wp) + 1;
+ char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_N));
#ifdef FEAT_SYN_HL
- /* When 'cursorline' is set highlight the line number of
- * the current line differently.
- * TODO: Can we use CursorLine instead of CursorLineNr
- * when CursorLineNr isn't set? */
- if ((wp->w_p_cul || wp->w_p_rnu)
+ /* When 'cursorline' is set highlight the line number of
+ * the current line differently.
+ * TODO: Can we use CursorLine instead of CursorLineNr
+ * when CursorLineNr isn't set? */
+ if ((wp->w_p_cul || wp->w_p_rnu)
&& lnum == wp->w_cursor.lnum)
char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_CLN));
#endif
+ }
}
}
diff --git a/src/testdir/test_signs.vim b/src/testdir/test_signs.vim
index 140aa8234..1435e8683 100644
--- a/src/testdir/test_signs.vim
+++ b/src/testdir/test_signs.vim
@@ -1736,3 +1736,60 @@ func Test_sign_cursor_position()
call StopVimInTerminal(buf)
call delete('XtestSigncolumn')
endfunc
+
+" Return the 'len' characters in screen starting from (row,col)
+func s:ScreenLine(row, col, len)
+ let s = ''
+ for i in range(a:len)
+ let s .= nr2char(screenchar(a:row, a:col + i))
+ endfor
+ return s
+endfunc
+
+" Test for 'signcolumn' set to 'number'.
+func Test_sign_numcol()
+ new
+ call append(0, "01234")
+ " With 'signcolumn' set to 'number', make sure sign is displayed in the
+ " number column and line number is not displayed.
+ set numberwidth=2
+ set number
+ set signcolumn=number
+ sign define sign1 text==>
+ sign place 10 line=1 name=sign1
+ redraw!
+ call assert_equal("=> 01234", s:ScreenLine(1, 1, 8))
+
+ " With 'signcolumn' set to 'number', when there is no sign, make sure line
+ " number is displayed in the number column
+ sign unplace 10
+ redraw!
+ call assert_equal("1 01234", s:ScreenLine(1, 1, 7))
+
+ " Disable number column. Check whether sign is displayed in the sign column
+ set numberwidth=4
+ set nonumber
+ sign place 10 line=1 name=sign1
+ redraw!
+ call assert_equal("=>01234", s:ScreenLine(1, 1, 7))
+
+ " Enable number column. Check whether sign is displayed in the number column
+ set number
+ redraw!
+ call assert_equal("=> 01234", s:ScreenLine(1, 1, 9))
+
+ " Disable sign column. Make sure line number is displayed
+ set signcolumn=no
+ redraw!
+ call assert_equal(" 1 01234", s:ScreenLine(1, 1, 9))
+
+ " Enable auto sign column. Make sure both sign and line number are displayed
+ set signcolumn=auto
+ redraw!
+ call assert_equal("=> 1 01234", s:ScreenLine(1, 1, 11))
+
+ sign undefine sign1
+ set signcolumn&
+ set number&
+ enew! | close
+endfunc
diff --git a/src/version.c b/src/version.c
index 7c9a227bb..5831e336d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -778,6 +778,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1564,
+/**/
1563,
/**/
1562,