summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-01-13 20:40:51 +0100
committerBram Moolenaar <Bram@vim.org>2020-01-13 20:40:51 +0100
commit9df53b62de86f544b41bef5e964b7fc8ae5231e3 (patch)
tree873b31c1157f80f91ee004d2011077c81b114845
parent7ebcba61b20d25d23109fff73d0346ad44ba1b3b (diff)
patch 8.2.0115: byte2line() does not work correctly with text propertiesv8.2.0115
Problem: Byte2line() does not work correctly with text properties. (Billie Cleek) Solution: Take the bytes of the text properties into account. (closes #5334)
-rw-r--r--src/memline.c36
-rw-r--r--src/testdir/test_textprop.vim18
-rw-r--r--src/version.c2
3 files changed, 50 insertions, 6 deletions
diff --git a/src/memline.c b/src/memline.c
index 860438cfcd..2ac47af117 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -5738,7 +5738,7 @@ ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
count = (long)(buf->b_ml.ml_locked_high) -
(long)(buf->b_ml.ml_locked_low) + 1;
start_idx = idx = curline - buf->b_ml.ml_locked_low;
- 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);
@@ -5752,13 +5752,38 @@ ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
}
else
{
+#ifdef FEAT_PROP_POPUP
+ long textprop_total = 0;
+ long textprop_size = 0;
+ char_u *l1, *l2;
+#endif
+
extra = 0;
- while (offset >= size
- + text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK)
- + ffdos)
+ for (;;)
{
+#ifdef FEAT_PROP_POPUP
+ if (buf->b_has_textprop)
+ {
+ // compensate for the extra bytes taken by textprops
+ l1 = (char_u *)dp + ((dp->db_index[idx]) & DB_INDEX_MASK);
+ l2 = (char_u *)dp + (idx == 0 ? dp->db_txt_end
+ : ((dp->db_index[idx - 1]) & DB_INDEX_MASK));
+ textprop_size = (l2 - l1) - (STRLEN(l1) + 1);
+ }
+#endif
+ if (!(offset >= size
+ + text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK)
+#ifdef FEAT_PROP_POPUP
+ - textprop_total - textprop_size
+#endif
+ + ffdos))
+ break;
+
if (ffdos)
size++;
+#ifdef FEAT_PROP_POPUP
+ textprop_total += textprop_size;
+#endif
if (idx == count - 1)
{
extra = 1;
@@ -5776,7 +5801,8 @@ ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
// lengths.
len = 0;
for (i = start_idx; i <= idx; ++i)
- len += (int)STRLEN((char_u *)dp + ((dp->db_index[i]) & DB_INDEX_MASK)) + 1;
+ len += (int)STRLEN((char_u *)dp
+ + ((dp->db_index[i]) & DB_INDEX_MASK)) + 1;
}
else
#endif
diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim
index ca6fd746e6..32001b3622 100644
--- a/src/testdir/test_textprop.vim
+++ b/src/testdir/test_textprop.vim
@@ -664,7 +664,7 @@ func Test_prop_multiline()
call prop_type_delete('comment')
endfunc
-func Test_prop_byteoff()
+func Test_prop_line2byte()
call prop_type_add('comment', {'highlight': 'Directory'})
new
call setline(1, ['line1', 'second line', ''])
@@ -677,6 +677,22 @@ func Test_prop_byteoff()
call prop_type_delete('comment')
endfunc
+func Test_prop_byte2line()
+ new
+ set ff=unix
+ call setline(1, ['one one', 'two two', 'three three', 'four four', 'five'])
+ call assert_equal(4, byte2line(line2byte(4)))
+ call assert_equal(5, byte2line(line2byte(5)))
+
+ call prop_type_add('prop', {'highlight': 'Directory'})
+ call prop_add(3, 1, {'length': 5, 'type': 'prop'})
+ call assert_equal(4, byte2line(line2byte(4)))
+ call assert_equal(5, byte2line(line2byte(5)))
+
+ bwipe!
+ call prop_type_delete('prop')
+endfunc
+
func Test_prop_undo()
new
call prop_type_add('comment', {'highlight': 'Directory'})
diff --git a/src/version.c b/src/version.c
index 0dac41e7cf..2d502beac6 100644
--- a/src/version.c
+++ b/src/version.c
@@ -743,6 +743,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 115,
+/**/
114,
/**/
113,