diff src/memline.c @ 25624:0ef8ef1af478 v8.2.3348

patch 8.2.3348: line2byte() returns wrong value after adding textprop Commit: https://github.com/vim/vim/commit/14c7530c4fca786d3594508e28943f10125827c3 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Aug 15 14:28:40 2021 +0200 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)
author Bram Moolenaar <Bram@vim.org>
date Sun, 15 Aug 2021 14:30:04 +0200
parents 1919361a53da
children 885fba352580
line wrap: on
line diff
--- 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, linen
 	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;