0
0
mirror of https://github.com/vim/vim.git synced 2025-10-06 05:44:14 -04:00

patch 8.2.3348: line2byte() returns wrong value after adding textprop

Problem:    line2byte() returns wrong value after adding textprop. (Yuto
            Kimura)
Solution:   Reduce the length by the size of the text property. (closes #8759)
This commit is contained in:
Bram Moolenaar
2021-08-15 14:28:40 +02:00
parent dd9de50f42
commit 14c7530c4f
3 changed files with 30 additions and 4 deletions

View File

@@ -3977,6 +3977,9 @@ ml_flush_line(buf_T *buf)
*/ */
if ((int)dp->db_free >= extra) if ((int)dp->db_free >= extra)
{ {
#ifdef FEAT_BYTEOFF
int old_prop_len = 0;
#endif
// if the length changes and there are following lines // if the length changes and there are following lines
count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1; count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1;
if (extra != 0 && idx < count - 1) if (extra != 0 && idx < count - 1)
@@ -3995,12 +3998,23 @@ ml_flush_line(buf_T *buf)
// adjust free space // adjust free space
dp->db_free -= extra; dp->db_free -= extra;
dp->db_txt_start -= extra; dp->db_txt_start -= extra;
#ifdef FEAT_BYTEOFF
if (buf->b_has_textprop)
old_prop_len = old_len - STRLEN(new_line) - 1;
#endif
// copy new line into the data block // copy new line into the data block
mch_memmove(old_line - extra, new_line, (size_t)new_len); mch_memmove(old_line - extra, new_line, (size_t)new_len);
buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS); buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
#ifdef FEAT_BYTEOFF #ifdef FEAT_BYTEOFF
// The else case is already covered by the insert and delete // The else case is already covered by the insert and delete
if (buf->b_has_textprop)
{
// Do not count the size of any text properties.
extra += old_prop_len;
extra -= new_len - STRLEN(new_line) - 1;
}
if (extra != 0)
ml_updatechunk(buf, lnum, (long)extra, ML_CHNK_UPDLINE); ml_updatechunk(buf, lnum, (long)extra, ML_CHNK_UPDLINE);
#endif #endif
} }
@@ -5734,7 +5748,7 @@ ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
return 1; // Not a "find offset" and offset 0 _must_ be in line 1 return 1; // Not a "find offset" and offset 0 _must_ be in line 1
/* /*
* Find the last chunk before the one containing our line. Last chunk is * Find the last chunk before the one containing our line. Last chunk is
* special because it will never qualify * special because it will never qualify.
*/ */
curline = 1; curline = 1;
curix = size = 0; curix = size = 0;

View File

@@ -809,8 +809,18 @@ func Test_prop_line2byte()
call assert_equal(19, line2byte(3)) call assert_equal(19, line2byte(3))
call prop_add(1, 1, {'end_col': 3, 'type': 'comment'}) call prop_add(1, 1, {'end_col': 3, 'type': 'comment'})
call assert_equal(19, line2byte(3)) call assert_equal(19, line2byte(3))
bwipe! bwipe!
new
call setline(1, range(500))
call assert_equal(1491, line2byte(401))
call prop_add(2, 1, {'type': 'comment'})
call prop_add(222, 1, {'type': 'comment'})
call assert_equal(1491, line2byte(401))
call prop_remove({'type': 'comment'})
call assert_equal(1491, line2byte(401))
bwipe!
call prop_type_delete('comment') call prop_type_delete('comment')
endfunc endfunc

View File

@@ -755,6 +755,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 */
/**/
3348,
/**/ /**/
3347, 3347,
/**/ /**/