diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-01-13 20:40:51 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-01-13 20:40:51 +0100 |
commit | 9df53b62de86f544b41bef5e964b7fc8ae5231e3 (patch) | |
tree | 873b31c1157f80f91ee004d2011077c81b114845 /src | |
parent | 7ebcba61b20d25d23109fff73d0346ad44ba1b3b (diff) | |
download | vim-git-9df53b62de86f544b41bef5e964b7fc8ae5231e3.tar.gz |
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)
Diffstat (limited to 'src')
-rw-r--r-- | src/memline.c | 36 | ||||
-rw-r--r-- | src/testdir/test_textprop.vim | 18 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 50 insertions, 6 deletions
diff --git a/src/memline.c b/src/memline.c index 860438cfc..2ac47af11 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 ca6fd746e..32001b362 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 0dac41e7c..2d502beac 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, |