aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/memline.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/memline.c')
-rw-r--r--src/nvim/memline.c64
1 files changed, 43 insertions, 21 deletions
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index d5788d96b3..f9390bcb88 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -257,11 +257,12 @@ int ml_open(buf_T *buf)
/*
* init fields in memline struct
*/
- buf->b_ml.ml_stack_size = 0; /* no stack yet */
- buf->b_ml.ml_stack = NULL; /* no stack yet */
- buf->b_ml.ml_stack_top = 0; /* nothing in the stack */
- buf->b_ml.ml_locked = NULL; /* no cached block */
- buf->b_ml.ml_line_lnum = 0; /* no cached line */
+ buf->b_ml.ml_stack_size = 0; // no stack yet
+ buf->b_ml.ml_stack = NULL; // no stack yet
+ buf->b_ml.ml_stack_top = 0; // nothing in the stack
+ buf->b_ml.ml_locked = NULL; // no cached block
+ buf->b_ml.ml_line_lnum = 0; // no cached line
+ buf->b_ml.ml_line_offset = 0;
buf->b_ml.ml_chunksize = NULL;
if (cmdmod.noswapfile) {
@@ -831,11 +832,12 @@ void ml_recover(bool checkext)
/*
* init fields in memline struct
*/
- buf->b_ml.ml_stack_size = 0; /* no stack yet */
- buf->b_ml.ml_stack = NULL; /* no stack yet */
- buf->b_ml.ml_stack_top = 0; /* nothing in the stack */
- buf->b_ml.ml_line_lnum = 0; /* no cached line */
- buf->b_ml.ml_locked = NULL; /* no locked block */
+ buf->b_ml.ml_stack_size = 0; // no stack yet
+ buf->b_ml.ml_stack = NULL; // no stack yet
+ buf->b_ml.ml_stack_top = 0; // nothing in the stack
+ buf->b_ml.ml_line_lnum = 0; // no cached line
+ buf->b_ml.ml_line_offset = 0;
+ buf->b_ml.ml_locked = NULL; // no locked block
buf->b_ml.ml_flags = 0;
/*
@@ -2403,12 +2405,13 @@ void ml_add_deleted_len_buf(buf_T *buf, char_u *ptr, ssize_t len)
if (len == -1) {
len = STRLEN(ptr);
}
- buf->deleted_bytes += len+1;
- if (buf->update_need_codepoints) {
- mb_utflen(ptr, len, &buf->deleted_codepoints,
- &buf->deleted_codeunits);
- buf->deleted_codepoints++; // NL char
- buf->deleted_codeunits++;
+ curbuf->deleted_bytes += len+1;
+ curbuf->deleted_bytes2 += len+1;
+ if (curbuf->update_need_codepoints) {
+ mb_utflen(ptr, len, &curbuf->deleted_codepoints,
+ &curbuf->deleted_codeunits);
+ curbuf->deleted_codepoints++; // NL char
+ curbuf->deleted_codeunits++;
}
}
@@ -2831,6 +2834,7 @@ static void ml_flush_line(buf_T *buf)
}
buf->b_ml.ml_line_lnum = 0;
+ buf->b_ml.ml_line_offset = 0;
}
/*
@@ -3980,10 +3984,10 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
/// Find offset for line or line with offset.
///
/// @param buf buffer to use
-/// @param lnum if > 0, find offset of lnum, store offset in offp
+/// @param lnum if > 0, find offset of lnum, return offset
/// if == 0, return line with offset *offp
-/// @param offp Location where offset of line is stored, or to read offset to
-/// use to find line. In the later case, store remaining offset.
+/// @param offp offset to use to find line, store remaining column offset
+/// Should be NULL when getting offset of line
/// @param no_ff ignore 'fileformat' option, always use one byte for NL.
///
/// @return -1 if information is not available
@@ -4003,8 +4007,22 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
int ffdos = !no_ff && (get_fileformat(buf) == EOL_DOS);
int extra = 0;
- // take care of cached line first
- ml_flush_line(buf);
+ // take care of cached line first. Only needed if the cached line is before
+ // the requested line. Additionally cache the value for the cached line.
+ // This is used by the extmark code which needs the byte offset of the edited
+ // line. So when doing multiple small edits on the same line the value is
+ // only calculated once.
+ //
+ // NB: caching doesn't work with 'fileformat'. This is not a problem for
+ // bytetracking, as bytetracking ignores 'fileformat' option. But calling
+ // line2byte() will invalidate the cache for the time being (this function
+ // was never cached to start with anyway).
+ bool can_cache = (lnum != 0 && !ffdos && buf->b_ml.ml_line_lnum == lnum);
+ if (lnum == 0 || buf->b_ml.ml_line_lnum < lnum || !no_ff) {
+ ml_flush_line(curbuf);
+ } else if (can_cache && buf->b_ml.ml_line_offset > 0) {
+ return buf->b_ml.ml_line_offset;
+ }
if (buf->b_ml.ml_usedchunks == -1
|| buf->b_ml.ml_chunksize == NULL
@@ -4100,6 +4118,10 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
}
}
+ if (can_cache && size > 0) {
+ buf->b_ml.ml_line_offset = size;
+ }
+
return size;
}