Handle 'orphaned signs' on line deletion for signcolumn >= 2

This commit is contained in:
Dan Aloni 2020-05-15 19:22:44 +03:00
parent a6504ec339
commit f2ed7605da
4 changed files with 61 additions and 5 deletions

View File

@ -5555,6 +5555,12 @@ A jump table for the options with a short description can be found at |Q_op|.
"number" display signs in the 'number' column. If the number "number" display signs in the 'number' column. If the number
column is not present, then behaves like 'auto'. column is not present, then behaves like 'auto'.
Note regarding 'orphaned signs': with signcolumn numbers higher than
1, deleting lines will also remove the associated signs automatically,
in contrast to the default Vim behavior of keeping and grouping them.
This is done in order for the signcolumn appearence not appear weird
during line deletion.
*'smartcase'* *'scs'* *'nosmartcase'* *'noscs'* *'smartcase'* *'scs'* *'nosmartcase'* *'noscs'*
'smartcase' 'scs' boolean (default off) 'smartcase' 'scs' boolean (default off)

View File

@ -7582,10 +7582,20 @@ int csh_like_shell(void)
/// Return the number of requested sign columns, based on current /// Return the number of requested sign columns, based on current
/// buffer signs and on user configuration. /// buffer signs and on user configuration.
int win_signcol_count(win_T *wp) int win_signcol_count(win_T *wp)
{
return win_signcol_configured(wp, NULL);
}
/// Return the number of requested sign columns, based on user / configuration.
int win_signcol_configured(win_T *wp, int *is_fixed)
{ {
int minimum = 0, maximum = 1, needed_signcols; int minimum = 0, maximum = 1, needed_signcols;
const char *scl = (const char *)wp->w_p_scl; const char *scl = (const char *)wp->w_p_scl;
if (is_fixed) {
*is_fixed = 1;
}
// Note: It checks "no" or "number" in 'signcolumn' option // Note: It checks "no" or "number" in 'signcolumn' option
if (*scl == 'n' if (*scl == 'n'
&& (*(scl + 1) == 'o' || (*(scl + 1) == 'u' && (*(scl + 1) == 'o' || (*(scl + 1) == 'u'
@ -7603,7 +7613,11 @@ int win_signcol_count(win_T *wp)
return 1; return 1;
} }
if (is_fixed) {
// auto or auto:<NUM> // auto or auto:<NUM>
*is_fixed = 0;
}
if (!strncmp(scl, "auto:", 5)) { if (!strncmp(scl, "auto:", 5)) {
// Variable depending on a configuration // Variable depending on a configuration
maximum = scl[5] - '0'; maximum = scl[5] - '0';

View File

@ -18,6 +18,7 @@
#include "nvim/move.h" #include "nvim/move.h"
#include "nvim/screen.h" #include "nvim/screen.h"
#include "nvim/syntax.h" #include "nvim/syntax.h"
#include "nvim/option.h"
/// Struct to hold the sign properties. /// Struct to hold the sign properties.
typedef struct sign sign_T; typedef struct sign sign_T;
@ -727,14 +728,28 @@ void sign_mark_adjust(
) )
{ {
sign_entry_T *sign; // a sign in a b_signlist sign_entry_T *sign; // a sign in a b_signlist
sign_entry_T *next; // the next sign in a b_signlist
sign_entry_T *last = NULL; // pointer to pointer to current sign
sign_entry_T **lastp = NULL; // pointer to pointer to current sign
linenr_T new_lnum; // new line number to assign to sign linenr_T new_lnum; // new line number to assign to sign
int is_fixed = 0;
int signcol = win_signcol_configured(curwin, &is_fixed);
curbuf->b_signcols_max = -1; curbuf->b_signcols_max = -1;
lastp = &curbuf->b_signlist;
FOR_ALL_SIGNS_IN_BUF(curbuf, sign) { for (sign = curbuf->b_signlist; sign != NULL; sign = next) {
next = sign->se_next;
new_lnum = sign->se_lnum; new_lnum = sign->se_lnum;
if (sign->se_lnum >= line1 && sign->se_lnum <= line2) { if (sign->se_lnum >= line1 && sign->se_lnum <= line2) {
if (amount != MAXLNUM) { if (amount == MAXLNUM && (!is_fixed || signcol >= 2)) {
*lastp = next;
if (next) {
next->se_prev = last;
}
xfree(sign);
continue;
} else {
new_lnum += amount; new_lnum += amount;
} }
} else if (sign->se_lnum > line2) { } else if (sign->se_lnum > line2) {
@ -746,6 +761,9 @@ void sign_mark_adjust(
if (sign->se_lnum >= line1 && new_lnum <= curbuf->b_ml.ml_line_count) { if (sign->se_lnum >= line1 && new_lnum <= curbuf->b_ml.ml_line_count) {
sign->se_lnum = new_lnum; sign->se_lnum = new_lnum;
} }
last = sign;
lastp = &sign->se_next;
} }
} }

View File

@ -264,6 +264,24 @@ describe('Signs', function()
{0:~ }| {0:~ }|
| |
]]} ]]}
-- line deletion deletes signs.
command('2d')
screen:expect([[
{1:>>}XX{2: }{6: 1 }a |
XX{1:>>}WW{6: 2 }^c |
{2: }{6: 3 } |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
|
]])
end) end)
it('auto-resize sign column with minimum size (#13783)', function() it('auto-resize sign column with minimum size (#13783)', function()