aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2020-02-23 20:33:11 +0100
committerBjörn Linse <bjorn.linse@gmail.com>2020-09-09 21:22:21 +0200
commit81fa107f595ee0392b5f004b86e4e8d41e49cc9e (patch)
treea8a07aded5e47a17480e855ecd09d842833fa4d4
parent333bfd5a29905b0cc4684657f0d0539238b6dbc4 (diff)
downloadrneovim-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.c26
-rw-r--r--src/nvim/memline_defs.h1
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