]> granicus.if.org Git - vim/commitdiff
patch 8.2.3348: line2byte() returns wrong value after adding textprop v8.2.3348
authorBram Moolenaar <Bram@vim.org>
Sun, 15 Aug 2021 12:28:40 +0000 (14:28 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 15 Aug 2021 12:28:40 +0000 (14:28 +0200)
Problem:    line2byte() returns wrong value after adding textprop. (Yuto
            Kimura)
Solution:   Reduce the length by the size of the text property. (closes #8759)

src/memline.c
src/testdir/test_textprop.vim
src/version.c

index 75c17d2ed7e6e5895c45500214c30bb076476c62..40eecea6ce5cb4998f4b9c89df8a552c3b4171ef 100644 (file)
@@ -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;
index acdbf48493f8c17f48509fc1a6c900512acc4ea2..847968c07588aa43e6584484de6c301a2b5e71ba 100644 (file)
@@ -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
 
index 34793f11efc2e5bb0239e04d8fb442438da9b980..21efafcef4262dd60194476d73c53046ca6cf6e1 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3348,
 /**/
     3347,
 /**/