summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-08-15 14:28:40 +0200
committerBram Moolenaar <Bram@vim.org>2021-08-15 14:28:40 +0200
commit14c7530c4fca786d3594508e28943f10125827c3 (patch)
treeab8ac44d9993a366a363f799d7beefcd92bcf4da
parentdd9de50f4262898384be6ea7694d05507c7cb260 (diff)
downloadvim-git-14c7530c4fca786d3594508e28943f10125827c3.tar.gz
patch 8.2.3348: line2byte() returns wrong value after adding textpropv8.2.3348
Problem: line2byte() returns wrong value after adding textprop. (Yuto Kimura) Solution: Reduce the length by the size of the text property. (closes #8759)
-rw-r--r--src/memline.c20
-rw-r--r--src/testdir/test_textprop.vim10
-rw-r--r--src/version.c2
3 files changed, 29 insertions, 3 deletions
diff --git a/src/memline.c b/src/memline.c
index 75c17d2ed..40eecea6c 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -3977,6 +3977,9 @@ ml_flush_line(buf_T *buf)
*/
if ((int)dp->db_free >= extra)
{
+#ifdef FEAT_BYTEOFF
+ int old_prop_len = 0;
+#endif
// if the length changes and there are following lines
count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1;
if (extra != 0 && idx < count - 1)
@@ -3995,13 +3998,24 @@ ml_flush_line(buf_T *buf)
// adjust free space
dp->db_free -= 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
mch_memmove(old_line - extra, new_line, (size_t)new_len);
buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
#ifdef FEAT_BYTEOFF
// The else case is already covered by the insert and delete
- ml_updatechunk(buf, lnum, (long)extra, ML_CHNK_UPDLINE);
+ 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);
#endif
}
else
@@ -5595,7 +5609,7 @@ ml_updatechunk(
else
#endif
{
- if (idx == 0)// first line in block, text at the end
+ if (idx == 0) // first line in block, text at the end
text_end = dp->db_txt_end;
else
text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
@@ -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
/*
* 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;
curix = size = 0;
diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim
index acdbf4849..847968c07 100644
--- a/src/testdir/test_textprop.vim
+++ b/src/testdir/test_textprop.vim
@@ -809,8 +809,18 @@ func Test_prop_line2byte()
call assert_equal(19, line2byte(3))
call prop_add(1, 1, {'end_col': 3, 'type': 'comment'})
call assert_equal(19, line2byte(3))
+ 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')
endfunc
diff --git a/src/version.c b/src/version.c
index 34793f11e..21efafcef 100644
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3348,
+/**/
3347,
/**/
3346,