forked from aniani/vim
patch 8.1.0767: when deleting lines at the bottom signs are misplaced
Problem: When deleting lines at the bottom signs are misplaced. Solution: Properly update the line number of signs at the end of a buffer after a delete/undo operation. (Yegappan Lakshmanan, closes #3798)
This commit is contained in:
20
src/sign.c
20
src/sign.c
@@ -660,18 +660,28 @@ sign_mark_adjust(
|
|||||||
long amount_after)
|
long amount_after)
|
||||||
{
|
{
|
||||||
signlist_T *sign; // a sign in a b_signlist
|
signlist_T *sign; // a sign in a b_signlist
|
||||||
|
linenr_T new_lnum;
|
||||||
|
|
||||||
FOR_ALL_SIGNS_IN_BUF(curbuf, sign)
|
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 (sign->lnum >= line1 && sign->lnum <= line2)
|
||||||
{
|
{
|
||||||
if (amount == MAXLNUM)
|
if (amount != MAXLNUM)
|
||||||
sign->lnum = line1;
|
new_lnum += amount;
|
||||||
else
|
|
||||||
sign->lnum += amount;
|
|
||||||
}
|
}
|
||||||
else if (sign->lnum > line2)
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1202,13 +1202,13 @@ func Test_sign_lnum_adjust()
|
|||||||
enew! | only!
|
enew! | only!
|
||||||
|
|
||||||
sign define sign1 text=#> linehl=Comment
|
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('')
|
exe 'sign place 5 line=3 name=sign1 buffer=' . bufnr('')
|
||||||
let l = sign_getplaced(bufnr(''))
|
let l = sign_getplaced(bufnr(''))
|
||||||
call assert_equal(3, l[0].signs[0].lnum)
|
call assert_equal(3, l[0].signs[0].lnum)
|
||||||
|
|
||||||
" Add some lines before the sign and check the sign line number
|
" 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(''))
|
let l = sign_getplaced(bufnr(''))
|
||||||
call assert_equal(6, l[0].signs[0].lnum)
|
call assert_equal(6, l[0].signs[0].lnum)
|
||||||
|
|
||||||
@@ -1217,6 +1217,44 @@ func Test_sign_lnum_adjust()
|
|||||||
let l = sign_getplaced(bufnr(''))
|
let l = sign_getplaced(bufnr(''))
|
||||||
call assert_equal(4, l[0].signs[0].lnum)
|
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 unplace * group=*
|
||||||
sign undefine sign1
|
sign undefine sign1
|
||||||
enew!
|
enew!
|
||||||
|
@@ -791,6 +791,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
767,
|
||||||
/**/
|
/**/
|
||||||
766,
|
766,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user