summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sign.c20
-rw-r--r--src/testdir/test_signs.vim42
-rw-r--r--src/version.c2
3 files changed, 57 insertions, 7 deletions
diff --git a/src/sign.c b/src/sign.c
index 6f7ead963..75f41235e 100644
--- a/src/sign.c
+++ b/src/sign.c
@@ -660,18 +660,28 @@ sign_mark_adjust(
long amount_after)
{
signlist_T *sign; // a sign in a b_signlist
+ linenr_T new_lnum;
FOR_ALL_SIGNS_IN_BUF(curbuf, sign)
{
+ // Ignore changes to lines after the sign
+ if (sign->lnum < line1)
+ continue;
+ new_lnum = sign->lnum;
if (sign->lnum >= line1 && sign->lnum <= line2)
{
- if (amount == MAXLNUM)
- sign->lnum = line1;
- else
- sign->lnum += amount;
+ if (amount != MAXLNUM)
+ new_lnum += amount;
}
else if (sign->lnum > line2)
- sign->lnum += amount_after;
+ // Lines inserted or deleted before the sign
+ new_lnum += amount_after;
+
+ // If the new sign line number is past the last line in the buffer,
+ // then don't adjust the line number. Otherwise, it will always be past
+ // the last line and will not be visible.
+ if (new_lnum <= curbuf->b_ml.ml_line_count)
+ sign->lnum = new_lnum;
}
}
diff --git a/src/testdir/test_signs.vim b/src/testdir/test_signs.vim
index 5962ab534..49bd986c3 100644
--- a/src/testdir/test_signs.vim
+++ b/src/testdir/test_signs.vim
@@ -1202,13 +1202,13 @@ func Test_sign_lnum_adjust()
enew! | only!
sign define sign1 text=#> linehl=Comment
- call setline(1, ['A', 'B', 'C', 'D'])
+ call setline(1, ['A', 'B', 'C', 'D', 'E'])
exe 'sign place 5 line=3 name=sign1 buffer=' . bufnr('')
let l = sign_getplaced(bufnr(''))
call assert_equal(3, l[0].signs[0].lnum)
" Add some lines before the sign and check the sign line number
- call append(2, ['AA', 'AB', 'AC'])
+ call append(2, ['BA', 'BB', 'BC'])
let l = sign_getplaced(bufnr(''))
call assert_equal(6, l[0].signs[0].lnum)
@@ -1217,6 +1217,44 @@ func Test_sign_lnum_adjust()
let l = sign_getplaced(bufnr(''))
call assert_equal(4, l[0].signs[0].lnum)
+ " Insert some lines after the sign and check the sign line number
+ call append(5, ['DA', 'DB'])
+ let l = sign_getplaced(bufnr(''))
+ call assert_equal(4, l[0].signs[0].lnum)
+
+ " Delete some lines after the sign and check the sign line number
+ call deletebufline('', 6, 7)
+ let l = sign_getplaced(bufnr(''))
+ call assert_equal(4, l[0].signs[0].lnum)
+
+ " Break the undo. Otherwise the undo operation below will undo all the
+ " changes made by this function.
+ let &undolevels=&undolevels
+
+ " 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)
+
sign unplace * group=*
sign undefine sign1
enew!
diff --git a/src/version.c b/src/version.c
index 4e3c5a20d..719fd0741 100644
--- a/src/version.c
+++ b/src/version.c
@@ -792,6 +792,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 767,
+/**/
766,
/**/
765,