summaryrefslogtreecommitdiff
path: root/src/memline.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2018-12-13 22:20:09 +0100
committerBram Moolenaar <Bram@vim.org>2018-12-13 22:20:09 +0100
commit98aefe7c3250bb5d4153b994f878594d1745424e (patch)
tree262ae31c2dbf4ac0353f5564a2419a79267fa3ae /src/memline.c
parent5c5697f29829fc3b21fc5452fe8f239f6a4cb8e1 (diff)
downloadvim-git-98aefe7c3250bb5d4153b994f878594d1745424e.tar.gz
patch 8.1.0579: cannot attach properties to textv8.1.0579
Problem: Cannot attach properties to text. Solution: First part of adding text properties.
Diffstat (limited to 'src/memline.c')
-rw-r--r--src/memline.c106
1 files changed, 85 insertions, 21 deletions
diff --git a/src/memline.c b/src/memline.c
index 1d65a44d8..59e450260 100644
--- 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, int copy)
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, int copy)
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;
}