Merge pull request #12323 from da-x/orphaned-signs

Handle 'orphaned signs' on line deletion for signcolumn >= 2
This commit is contained in:
Matthieu Coudron
2021-04-18 17:12:41 +02:00
committed by GitHub
5 changed files with 62 additions and 25 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
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' boolean (default off)

View File

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

View File

@@ -18,6 +18,7 @@
#include "nvim/move.h"
#include "nvim/screen.h"
#include "nvim/syntax.h"
#include "nvim/option.h"
/// Struct to hold the sign properties.
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 *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
int is_fixed = 0;
int signcol = win_signcol_configured(curwin, &is_fixed);
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;
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;
}
} 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) {
sign->se_lnum = new_lnum;
}
last = sign;
lastp = &sign->se_next;
}
}

View File

@@ -1628,26 +1628,7 @@ func Test_sign_lnum_adjust()
" Delete the line with the sign
call deletebufline('', 4)
let l = sign_getplaced(bufnr(''))
call assert_equal(4, l[0].signs[0].lnum)
" Undo the delete operation
undo
let l = sign_getplaced(bufnr(''))
call assert_equal(5, l[0].signs[0].lnum)
" Break the undo
let &undolevels=&undolevels
" Delete few lines at the end of the buffer including the line with the sign
" Sign line number should not change (as it is placed outside of the buffer)
call deletebufline('', 3, 6)
let l = sign_getplaced(bufnr(''))
call assert_equal(5, l[0].signs[0].lnum)
" Undo the delete operation. Sign should be restored to the previous line
undo
let l = sign_getplaced(bufnr(''))
call assert_equal(5, l[0].signs[0].lnum)
call assert_equal(0, len(l[0].signs))
sign unplace * group=*
sign undefine sign1

View File

@@ -264,6 +264,24 @@ describe('Signs', function()
{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)
it('auto-resize sign column with minimum size (#13783)', function()