memline: cache byte offset of current line

When editing a line in insert mode, this value will be
used for every keypress.
This commit is contained in:
Björn Linse 2020-02-23 20:33:11 +01:00
parent 333bfd5a29
commit 81fa107f59
2 changed files with 22 additions and 5 deletions

View File

@ -262,6 +262,7 @@ int ml_open(buf_T *buf)
buf->b_ml.ml_stack_top = 0; /* nothing in the stack */ buf->b_ml.ml_stack_top = 0; /* nothing in the stack */
buf->b_ml.ml_locked = NULL; /* no cached block */ buf->b_ml.ml_locked = NULL; /* no cached block */
buf->b_ml.ml_line_lnum = 0; /* no cached line */ buf->b_ml.ml_line_lnum = 0; /* no cached line */
buf->b_ml.ml_line_offset = 0;
buf->b_ml.ml_chunksize = NULL; buf->b_ml.ml_chunksize = NULL;
if (cmdmod.noswapfile) { if (cmdmod.noswapfile) {
@ -835,6 +836,7 @@ void ml_recover(bool checkext)
buf->b_ml.ml_stack = NULL; /* 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_stack_top = 0; /* nothing in the stack */
buf->b_ml.ml_line_lnum = 0; /* no cached line */ 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_locked = NULL; /* no locked block */
buf->b_ml.ml_flags = 0; buf->b_ml.ml_flags = 0;
@ -2831,6 +2833,7 @@ static void ml_flush_line(buf_T *buf)
} }
buf->b_ml.ml_line_lnum = 0; buf->b_ml.ml_line_lnum = 0;
buf->b_ml.ml_line_offset = 0;
} }
/* /*
@ -3980,10 +3983,10 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
/// Find offset for line or line with offset. /// Find offset for line or line with offset.
/// ///
/// @param buf buffer to use /// @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 /// if == 0, return line with offset *offp
/// @param offp Location where offset of line is stored, or to read offset to /// @param offp offset to use to find line, store remaining column offset
/// use to find line. In the later case, store remaining offset. /// Should be NULL when getting offset of line
/// @param no_ff ignore 'fileformat' option, always use one byte for NL. /// @param no_ff ignore 'fileformat' option, always use one byte for NL.
/// ///
/// @return -1 if information is not available /// @return -1 if information is not available
@ -4003,8 +4006,17 @@ 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 ffdos = !no_ff && (get_fileformat(buf) == EOL_DOS);
int extra = 0; int extra = 0;
// take care of cached line first // take care of cached line first. Only needed if the cached line is before
ml_flush_line(buf); // 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.
bool can_cache = (lnum != 0 && !ffdos && buf->b_ml.ml_line_lnum == lnum);
if (lnum == 0 || buf->b_ml.ml_line_lnum < lnum) {
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 if (buf->b_ml.ml_usedchunks == -1
|| buf->b_ml.ml_chunksize == NULL || buf->b_ml.ml_chunksize == NULL
@ -4100,6 +4112,10 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
} }
} }
if (can_cache) {
buf->b_ml.ml_line_offset = size;
}
return size; return size;
} }

View File

@ -57,6 +57,7 @@ typedef struct memline {
linenr_T ml_line_lnum; // line number of cached line, 0 if not valid linenr_T ml_line_lnum; // line number of cached line, 0 if not valid
char_u *ml_line_ptr; // pointer to cached line char_u *ml_line_ptr; // pointer to cached line
size_t ml_line_offset; // cached byte offset of ml_line_lnum
bhdr_T *ml_locked; // block used by last ml_get bhdr_T *ml_locked; // block used by last ml_get
linenr_T ml_locked_low; // first line in ml_locked linenr_T ml_locked_low; // first line in ml_locked