diff options
author | Björn Linse <bjorn.linse@gmail.com> | 2020-02-23 20:33:11 +0100 |
---|---|---|
committer | Björn Linse <bjorn.linse@gmail.com> | 2020-09-09 21:22:21 +0200 |
commit | 81fa107f595ee0392b5f004b86e4e8d41e49cc9e (patch) | |
tree | a8a07aded5e47a17480e855ecd09d842833fa4d4 | |
parent | 333bfd5a29905b0cc4684657f0d0539238b6dbc4 (diff) | |
download | rneovim-81fa107f595ee0392b5f004b86e4e8d41e49cc9e.tar.gz rneovim-81fa107f595ee0392b5f004b86e4e8d41e49cc9e.tar.bz2 rneovim-81fa107f595ee0392b5f004b86e4e8d41e49cc9e.zip |
memline: cache byte offset of current line
When editing a line in insert mode, this value will be
used for every keypress.
-rw-r--r-- | src/nvim/memline.c | 26 | ||||
-rw-r--r-- | src/nvim/memline_defs.h | 1 |
2 files changed, 22 insertions, 5 deletions
diff --git a/src/nvim/memline.c b/src/nvim/memline.c index d5788d96b3..7d84c1cca3 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -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_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) { @@ -835,6 +836,7 @@ void ml_recover(bool checkext) 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; @@ -2831,6 +2833,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 +3983,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 +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 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. + 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 || 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; } diff --git a/src/nvim/memline_defs.h b/src/nvim/memline_defs.h index edd933b2cd..3994632807 100644 --- a/src/nvim/memline_defs.h +++ b/src/nvim/memline_defs.h @@ -57,6 +57,7 @@ typedef struct memline { linenr_T ml_line_lnum; // line number of cached line, 0 if not valid 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 linenr_T ml_locked_low; // first line in ml_locked |