# HG changeset patch # User Bram Moolenaar # Date 1660077903 -7200 # Node ID 57cfb39b784295d841600573064488ea8a57c754 # Parent b766ffb853c0e82ccba4690b40b4ec2b88c8e4f3 patch 9.0.0181: textprop test with line2byte() fails on MS-Windows Commit: https://github.com/vim/vim/commit/e5a0e8c1d781aa3781b4f6167fc2cba1193213f1 Author: Bram Moolenaar Date: Tue Aug 9 21:37:55 2022 +0100 patch 9.0.0181: textprop test with line2byte() fails on MS-Windows Problem: Textprop test with line2byte() fails on MS-Windows. Solution: Fix updating chuncks in ml_delete_int(). diff --git a/src/memline.c b/src/memline.c --- a/src/memline.c +++ b/src/memline.c @@ -3313,7 +3313,7 @@ ml_append_int( (long)text_len # else (long)len -#endif +# endif , ML_CHNK_ADDLINE); #endif @@ -3667,7 +3667,7 @@ ml_delete_int(buf_T *buf, linenr_T lnum, int ret = FAIL; #ifdef FEAT_PROP_POPUP char_u *textprop_save = NULL; - int textprop_save_len = 0; + long textprop_len = 0; #endif if (lowest_marked && lowest_marked > lnum) @@ -3723,18 +3723,17 @@ ml_delete_int(buf_T *buf, linenr_T lnum, netbeans_removed(buf, lnum, 0, line_size); #endif #ifdef FEAT_PROP_POPUP - // If there are text properties, make a copy, so that we can update - // properties in preceding and following lines. - if (buf->b_has_textprop && !(flags & (ML_DEL_UNDO | ML_DEL_NOPROP))) + // If there are text properties compute their byte length. + // if needed make a copy, so that we can update properties in preceding and + // following lines. + if (buf->b_has_textprop) { size_t textlen = STRLEN((char_u *)dp + line_start) + 1; - if ((long)textlen < line_size) - { - textprop_save_len = line_size - (int)textlen; + textprop_len = line_size - (long)textlen; + if (!(flags & (ML_DEL_UNDO | ML_DEL_NOPROP)) && textprop_len > 0) textprop_save = vim_memsave((char_u *)dp + line_start + textlen, - textprop_save_len); - } + textprop_len); } #endif @@ -3820,9 +3819,9 @@ ml_delete_int(buf_T *buf, linenr_T lnum, #ifdef FEAT_BYTEOFF ml_updatechunk(buf, lnum, line_size # ifdef FEAT_PROP_POPUP - - textprop_save_len + - textprop_len # endif - , ML_CHNK_DELLINE); + , ML_CHNK_DELLINE); #endif ret = OK; @@ -3833,10 +3832,10 @@ theend: // Adjust text properties in the line above and below. if (lnum > 1) adjust_text_props_for_delete(buf, lnum - 1, textprop_save, - textprop_save_len, TRUE); + (int)textprop_len, TRUE); if (lnum <= buf->b_ml.ml_line_count) adjust_text_props_for_delete(buf, lnum, textprop_save, - textprop_save_len, FALSE); + (int)textprop_len, FALSE); } vim_free(textprop_save); #endif @@ -5684,7 +5683,8 @@ ml_updatechunk( // the text prop info would also be counted. Go over the // lines. for (i = end_idx; i < idx; ++i) - size += (int)STRLEN((char_u *)dp + (dp->db_index[i] & DB_INDEX_MASK)) + 1; + size += (int)STRLEN((char_u *)dp + + (dp->db_index[i] & DB_INDEX_MASK)) + 1; } else #endif @@ -5693,7 +5693,8 @@ ml_updatechunk( text_end = dp->db_txt_end; else text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK); - size += text_end - ((dp->db_index[end_idx]) & DB_INDEX_MASK); + size += text_end + - ((dp->db_index[end_idx]) & DB_INDEX_MASK); } } buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt; @@ -5749,9 +5750,9 @@ ml_updatechunk( { curchnk->mlcs_numlines--; ml_upd_lastbuf = NULL; // Force recalc of curix & curline - if (curix < (buf->b_ml.ml_usedchunks - 1) - && (curchnk->mlcs_numlines + curchnk[1].mlcs_numlines) - <= MLCS_MINL) + if (curix < buf->b_ml.ml_usedchunks - 1 + && curchnk->mlcs_numlines + curchnk[1].mlcs_numlines + <= MLCS_MINL) { curix++; curchnk = buf->b_ml.ml_chunksize + curix; @@ -5764,8 +5765,8 @@ ml_updatechunk( return; } else if (curix == 0 || (curchnk->mlcs_numlines > 10 - && (curchnk->mlcs_numlines + curchnk[-1].mlcs_numlines) - > MLCS_MINL)) + && curchnk->mlcs_numlines + curchnk[-1].mlcs_numlines + > MLCS_MINL)) { return; } @@ -5775,12 +5776,10 @@ ml_updatechunk( curchnk[-1].mlcs_totalsize += curchnk->mlcs_totalsize; buf->b_ml.ml_usedchunks--; if (curix < buf->b_ml.ml_usedchunks) - { mch_memmove(buf->b_ml.ml_chunksize + curix, buf->b_ml.ml_chunksize + curix + 1, (buf->b_ml.ml_usedchunks - curix) * sizeof(chunksize_T)); - } return; } ml_upd_lastbuf = buf; diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -922,20 +922,22 @@ func Run_test_with_line2byte(add_props) if a:add_props call prop_type_add('textprop', #{highlight: 'Search'}) endif + " Add a text prop to every fourth line and then change every fifth line so + " that it causes a data block split a few times. for nr in range(1, 1000) call setline(nr, 'some longer text here') - if a:add_props && nr % 17 == 0 + if a:add_props && nr % 4 == 0 call prop_add(nr, 13, #{type: 'textprop', length: 4}) endif endfor - call assert_equal(21935, line2byte(998)) - for nr in range(1, 1000, 7) + let expected = 22 * 997 + 1 + call assert_equal(expected, line2byte(998)) + + for nr in range(1, 1000, 5) exe nr .. "s/longer/much more/" + let expected += 3 + call assert_equal(expected, line2byte(998), 'line ' .. nr) endfor - " FIXME: somehow this fails on MS-Windows - if !(a:add_props && has('win32')) - call assert_equal(22364, line2byte(998)) - endif if a:add_props call prop_type_delete('textprop') diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -736,6 +736,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 181, +/**/ 180, /**/ 179,