Mercurial > vim
diff src/memline.c @ 15138:9df130fd5e0d v8.1.0579
patch 8.1.0579: cannot attach properties to text
commit https://github.com/vim/vim/commit/98aefe7c3250bb5d4153b994f878594d1745424e
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Dec 13 22:20:09 2018 +0100
patch 8.1.0579: cannot attach properties to text
Problem: Cannot attach properties to text.
Solution: First part of adding text properties.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 13 Dec 2018 22:30:08 +0100 |
parents | c98810dfebaf |
children | 7713ceb8c593 |
line wrap: on
line diff
--- a/src/memline.c +++ b/src/memline.c @@ -2487,7 +2487,6 @@ ml_get_buf( { bhdr_T *hp; DATA_BL *dp; - char_u *ptr; static int recursive = 0; if (lnum > buf->b_ml.ml_line_count) /* invalid line number */ @@ -2518,6 +2517,10 @@ errorret: */ if (buf->b_ml.ml_line_lnum != lnum || mf_dont_release) { + unsigned start, end; + colnr_T len; + int idx; + ml_flush_line(buf); /* @@ -2540,8 +2543,18 @@ errorret: dp = (DATA_BL *)(hp->bh_data); - ptr = (char_u *)dp + ((dp->db_index[lnum - buf->b_ml.ml_locked_low]) & DB_INDEX_MASK); - buf->b_ml.ml_line_ptr = ptr; + idx = lnum - buf->b_ml.ml_locked_low; + start = ((dp->db_index[idx]) & DB_INDEX_MASK); + // The text ends where the previous line starts. The first line ends + // at the end of the block. + if (idx == 0) + end = dp->db_txt_end; + else + end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK); + len = end - start; + + buf->b_ml.ml_line_ptr = (char_u *)dp + start; + buf->b_ml.ml_line_len = len; buf->b_ml.ml_line_lnum = lnum; buf->b_ml.ml_flags &= ~ML_LINE_DIRTY; } @@ -2614,20 +2627,21 @@ ml_append_buf( static int ml_append_int( buf_T *buf, - linenr_T lnum, /* append after this line (can be 0) */ - char_u *line, /* text of the new line */ - colnr_T len, /* length of line, including NUL, or 0 */ - int newfile, /* flag, see above */ - int mark) /* mark the new line */ + linenr_T lnum, // append after this line (can be 0) + char_u *line, // text of the new line + colnr_T len_arg, // length of line, including NUL, or 0 + int newfile, // flag, see above + int mark) // mark the new line { + colnr_T len = len_arg; // length of line, including NUL, or 0 int i; - int line_count; /* number of indexes in current block */ + int line_count; // number of indexes in current block int offset; int from, to; - int space_needed; /* space needed for new line */ + int space_needed; // space needed for new line int page_size; int page_count; - int db_idx; /* index for lnum in data block */ + int db_idx; // index for lnum in data block bhdr_T *hp; memfile_T *mfp; DATA_BL *dp; @@ -2642,8 +2656,8 @@ ml_append_int( lowest_marked = lnum + 1; if (len == 0) - len = (colnr_T)STRLEN(line) + 1; /* space needed for the text */ - space_needed = len + INDEX_SIZE; /* space needed for text + index */ + len = (colnr_T)STRLEN(line) + 1; // space needed for the text + space_needed = len + INDEX_SIZE; // space needed for text + index mfp = buf->b_ml.ml_mfp; page_size = mfp->mf_page_size; @@ -2728,7 +2742,8 @@ ml_append_int( dp->db_index[i + 1] = dp->db_index[i] - len; dp->db_index[db_idx + 1] = offset - len; } - else /* add line at the end */ + else + // add line at the end (which is the start of the text) dp->db_index[db_idx + 1] = dp->db_txt_start; /* @@ -3128,6 +3143,19 @@ ml_append_int( int ml_replace(linenr_T lnum, char_u *line, int copy) { + colnr_T len = -1; + + if (line != NULL) + len = STRLEN(line); + return ml_replace_len(lnum, line, len, copy); +} + + int +ml_replace_len(linenr_T lnum, char_u *line_arg, colnr_T len_arg, int copy) +{ + char_u *line = line_arg; + colnr_T len = len_arg; + if (line == NULL) /* just checking... */ return FAIL; @@ -3135,7 +3163,7 @@ ml_replace(linenr_T lnum, char_u *line, if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL) return FAIL; - if (copy && (line = vim_strsave(line)) == NULL) /* allocate memory */ + if (copy && (line = vim_strnsave(line, len)) == NULL) /* allocate memory */ return FAIL; #ifdef FEAT_NETBEANS_INTG if (netbeans_active()) @@ -3144,11 +3172,48 @@ ml_replace(linenr_T lnum, char_u *line, netbeans_inserted(curbuf, lnum, 0, line, (int)STRLEN(line)); } #endif - if (curbuf->b_ml.ml_line_lnum != lnum) /* other line buffered */ - ml_flush_line(curbuf); /* flush it */ - else if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) /* same line allocated */ + if (curbuf->b_ml.ml_line_lnum != lnum) + { + // another line is buffered, flush it + ml_flush_line(curbuf); + +#ifdef FEAT_TEXT_PROP + curbuf->b_ml.ml_flags &= ~ML_LINE_DIRTY; + if (has_any_text_properties(curbuf)) + // Need to fetch the old line to copy over any text properties. + ml_get_buf(curbuf, lnum, TRUE); +#endif + } + +#ifdef FEAT_TEXT_PROP + if (has_any_text_properties(curbuf)) + { + size_t oldtextlen = STRLEN(curbuf->b_ml.ml_line_ptr) + 1; + + if (oldtextlen < (size_t)curbuf->b_ml.ml_line_len) + { + char_u *newline; + size_t textproplen = curbuf->b_ml.ml_line_len - oldtextlen; + + // Need to copy over text properties, stored after the text. + newline = alloc(len + 1 + textproplen); + if (newline != NULL) + { + mch_memmove(newline, line, len + 1); + mch_memmove(newline + len + 1, curbuf->b_ml.ml_line_ptr + oldtextlen, textproplen); + vim_free(line); + line = newline; + len += textproplen; + } + } + } +#endif + + if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) /* same line allocated */ vim_free(curbuf->b_ml.ml_line_ptr); /* free it */ + curbuf->b_ml.ml_line_ptr = line; + curbuf->b_ml.ml_line_len = len + 1; curbuf->b_ml.ml_line_lnum = lnum; curbuf->b_ml.ml_flags = (curbuf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY; @@ -3490,7 +3555,7 @@ ml_flush_line(buf_T *buf) old_len = dp->db_txt_end - start; else /* text of previous line follows */ old_len = (dp->db_index[idx - 1] & DB_INDEX_MASK) - start; - new_len = (colnr_T)STRLEN(new_line) + 1; + new_len = buf->b_ml.ml_line_len; extra = new_len - old_len; /* negative if lines gets smaller */ /* @@ -5009,8 +5074,7 @@ ml_updatechunk( */ buf->b_ml.ml_usedchunks = 1; buf->b_ml.ml_chunksize[0].mlcs_numlines = 1; - buf->b_ml.ml_chunksize[0].mlcs_totalsize = - (long)STRLEN(buf->b_ml.ml_line_ptr) + 1; + buf->b_ml.ml_chunksize[0].mlcs_totalsize = (long)buf->b_ml.ml_line_len; return; }