Mercurial > vim
comparison src/memline.c @ 15255:19e79a1ed6b6 v8.1.0636
patch 8.1.0636: line2byte() gives wrong values with text properties
commit https://github.com/vim/vim/commit/b413d2e6a8cc7b1611a41bfa9462b986393ca5fe
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Dec 25 23:15:46 2018 +0100
patch 8.1.0636: line2byte() gives wrong values with text properties
Problem: line2byte() gives wrong values with text properties. (Bjorn Linse)
Solution: Compute byte offsets differently when text properties were added.
(closes #3718)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 25 Dec 2018 23:30:07 +0100 |
parents | 4b2de998ebd6 |
children | 762fccd84b7c |
comparison
equal
deleted
inserted
replaced
15254:7790044a7348 | 15255:19e79a1ed6b6 |
---|---|
3177 // another line is buffered, flush it | 3177 // another line is buffered, flush it |
3178 ml_flush_line(curbuf); | 3178 ml_flush_line(curbuf); |
3179 curbuf->b_ml.ml_flags &= ~ML_LINE_DIRTY; | 3179 curbuf->b_ml.ml_flags &= ~ML_LINE_DIRTY; |
3180 | 3180 |
3181 #ifdef FEAT_TEXT_PROP | 3181 #ifdef FEAT_TEXT_PROP |
3182 if (has_any_text_properties(curbuf)) | 3182 if (curbuf->b_has_textprop) |
3183 // Need to fetch the old line to copy over any text properties. | 3183 // Need to fetch the old line to copy over any text properties. |
3184 ml_get_buf(curbuf, lnum, TRUE); | 3184 ml_get_buf(curbuf, lnum, TRUE); |
3185 #endif | 3185 #endif |
3186 } | 3186 } |
3187 | 3187 |
3188 #ifdef FEAT_TEXT_PROP | 3188 #ifdef FEAT_TEXT_PROP |
3189 if (has_any_text_properties(curbuf)) | 3189 if (curbuf->b_has_textprop) |
3190 { | 3190 { |
3191 size_t oldtextlen = STRLEN(curbuf->b_ml.ml_line_ptr) + 1; | 3191 size_t oldtextlen = STRLEN(curbuf->b_ml.ml_line_ptr) + 1; |
3192 | 3192 |
3193 if (oldtextlen < (size_t)curbuf->b_ml.ml_line_len) | 3193 if (oldtextlen < (size_t)curbuf->b_ml.ml_line_len) |
3194 { | 3194 { |
5129 | 5129 |
5130 if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL) | 5130 if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL) |
5131 { | 5131 { |
5132 int count; /* number of entries in block */ | 5132 int count; /* number of entries in block */ |
5133 int idx; | 5133 int idx; |
5134 int end_idx; | |
5134 int text_end; | 5135 int text_end; |
5135 int linecnt; | 5136 int linecnt; |
5136 | 5137 |
5137 mch_memmove(buf->b_ml.ml_chunksize + curix + 1, | 5138 mch_memmove(buf->b_ml.ml_chunksize + curix + 1, |
5138 buf->b_ml.ml_chunksize + curix, | 5139 buf->b_ml.ml_chunksize + curix, |
5152 dp = (DATA_BL *)(hp->bh_data); | 5153 dp = (DATA_BL *)(hp->bh_data); |
5153 count = (long)(buf->b_ml.ml_locked_high) - | 5154 count = (long)(buf->b_ml.ml_locked_high) - |
5154 (long)(buf->b_ml.ml_locked_low) + 1; | 5155 (long)(buf->b_ml.ml_locked_low) + 1; |
5155 idx = curline - buf->b_ml.ml_locked_low; | 5156 idx = curline - buf->b_ml.ml_locked_low; |
5156 curline = buf->b_ml.ml_locked_high + 1; | 5157 curline = buf->b_ml.ml_locked_high + 1; |
5157 if (idx == 0)/* first line in block, text at the end */ | 5158 |
5158 text_end = dp->db_txt_end; | 5159 // compute index of last line to use in this MEMLINE |
5159 else | |
5160 text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK); | |
5161 /* Compute index of last line to use in this MEMLINE */ | |
5162 rest = count - idx; | 5160 rest = count - idx; |
5163 if (linecnt + rest > MLCS_MINL) | 5161 if (linecnt + rest > MLCS_MINL) |
5164 { | 5162 { |
5165 idx += MLCS_MINL - linecnt - 1; | 5163 end_idx = idx + MLCS_MINL - linecnt - 1; |
5166 linecnt = MLCS_MINL; | 5164 linecnt = MLCS_MINL; |
5167 } | 5165 } |
5168 else | 5166 else |
5169 { | 5167 { |
5170 idx = count - 1; | 5168 end_idx = count - 1; |
5171 linecnt += rest; | 5169 linecnt += rest; |
5172 } | 5170 } |
5173 size += text_end - ((dp->db_index[idx]) & DB_INDEX_MASK); | 5171 #ifdef FEAT_TEXT_PROP |
5172 if (buf->b_has_textprop) | |
5173 { | |
5174 int i; | |
5175 | |
5176 // We cannot use the text pointers to get the text length, | |
5177 // the text prop info would also be counted. Go over the | |
5178 // lines. | |
5179 for (i = end_idx; i < idx; ++i) | |
5180 size += STRLEN((char_u *)dp + (dp->db_index[i] & DB_INDEX_MASK)) + 1; | |
5181 } | |
5182 else | |
5183 #endif | |
5184 { | |
5185 if (idx == 0)/* first line in block, text at the end */ | |
5186 text_end = dp->db_txt_end; | |
5187 else | |
5188 text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK); | |
5189 size += text_end - ((dp->db_index[end_idx]) & DB_INDEX_MASK); | |
5190 } | |
5174 } | 5191 } |
5175 buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt; | 5192 buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt; |
5176 buf->b_ml.ml_chunksize[curix + 1].mlcs_numlines -= linecnt; | 5193 buf->b_ml.ml_chunksize[curix + 1].mlcs_numlines -= linecnt; |
5177 buf->b_ml.ml_chunksize[curix].mlcs_totalsize = size; | 5194 buf->b_ml.ml_chunksize[curix].mlcs_totalsize = size; |
5178 buf->b_ml.ml_chunksize[curix + 1].mlcs_totalsize -= size; | 5195 buf->b_ml.ml_chunksize[curix + 1].mlcs_totalsize -= size; |
5358 break; | 5375 break; |
5359 } | 5376 } |
5360 idx++; | 5377 idx++; |
5361 } | 5378 } |
5362 } | 5379 } |
5363 len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK); | 5380 #ifdef FEAT_TEXT_PROP |
5381 if (buf->b_has_textprop) | |
5382 { | |
5383 int i; | |
5384 | |
5385 // cannot use the db_index pointer, need to get the actual text | |
5386 // lengths. | |
5387 len = 0; | |
5388 for (i = start_idx; i <= idx; ++i) | |
5389 len += STRLEN((char_u *)dp + ((dp->db_index[idx]) & DB_INDEX_MASK)) + 1; | |
5390 } | |
5391 else | |
5392 #endif | |
5393 len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK); | |
5364 size += len; | 5394 size += len; |
5365 if (offset != 0 && size >= offset) | 5395 if (offset != 0 && size >= offset) |
5366 { | 5396 { |
5367 if (size + ffdos == offset) | 5397 if (size + ffdos == offset) |
5368 *offp = 0; | 5398 *offp = 0; |