aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/buffer.c23
-rw-r--r--src/nvim/buffer_defs.h3
-rw-r--r--src/nvim/buffer_updates.c8
-rw-r--r--src/nvim/fileio.c1
-rw-r--r--src/nvim/memline.c27
-rw-r--r--src/nvim/misc1.c1
6 files changed, 59 insertions, 4 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index b0b65545ab..497b4ae9a4 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -1176,6 +1176,29 @@ free_exit:
return 0;
}
+Dictionary nvim__buf_stats(Buffer buffer, Error *err)
+{
+ Dictionary rv = ARRAY_DICT_INIT;
+
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+ if (!buf) {
+ return rv;
+ }
+
+ // Number of times the cached line was flushed.
+ // This should generally not increase while editing the same
+ // line in the same mode.
+ PUT(rv, "flush_count", INTEGER_OBJ(buf->flush_count));
+ // lnum of current line
+ PUT(rv, "current_lnum", INTEGER_OBJ(buf->b_ml.ml_line_lnum));
+ // whether the line has unflushed changes.
+ PUT(rv, "line_dirty", BOOLEAN_OBJ(buf->b_ml.ml_flags & ML_LINE_DIRTY));
+ // NB: this should be zero at any time API functions are called,
+ // this exists to debug issues
+ PUT(rv, "dirty_bytes", INTEGER_OBJ((Integer)buf->deleted_bytes));
+ return rv;
+}
+
// Check if deleting lines made the cursor position invalid.
// Changed lines from `lo` to `hi`; added `extra` lines (negative if deleted).
static void fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 143737b478..eb26e4ad8e 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -807,6 +807,9 @@ struct file_buffer {
kvec_t(uint64_t) update_channels;
kvec_t(BufUpdateCallbacks) update_callbacks;
+ size_t deleted_bytes;
+ int flush_count;
+
int b_diff_failed; // internal diff failed for this buffer
};
diff --git a/src/nvim/buffer_updates.c b/src/nvim/buffer_updates.c
index 21efda9fd9..7dea8bfac5 100644
--- a/src/nvim/buffer_updates.c
+++ b/src/nvim/buffer_updates.c
@@ -169,6 +169,8 @@ void buf_updates_send_changes(buf_T *buf,
int64_t num_removed,
bool send_tick)
{
+ size_t deleted_bytes = ml_flush_deleted_bytes(buf);
+
if (!buf_updates_active(buf)) {
return;
}
@@ -231,8 +233,8 @@ void buf_updates_send_changes(buf_T *buf,
bool keep = true;
if (cb.on_lines != LUA_NOREF) {
Array args = ARRAY_DICT_INIT;
- Object items[5];
- args.size = 5;
+ Object items[6];
+ args.size = 6;
args.items = items;
// the first argument is always the buffer handle
@@ -250,6 +252,8 @@ void buf_updates_send_changes(buf_T *buf,
// the last line in the updated range
args.items[4] = INTEGER_OBJ(firstline - 1 + num_added);
+ // byte count of previous contents
+ args.items[5] = INTEGER_OBJ((Integer)deleted_bytes);
textlock++;
Object res = executor_exec_lua_cb(cb.on_lines, "lines", args, true);
textlock--;
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index a164cf47d5..2232de8c1e 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -1755,6 +1755,7 @@ failed:
ml_delete(curbuf->b_ml.ml_line_count, false);
linecnt--;
}
+ curbuf->deleted_bytes = 0;
linecnt = curbuf->b_ml.ml_line_count - linecnt;
if (filesize == 0)
linecnt = 0;
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index b027459706..0b16f86416 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -2403,13 +2403,26 @@ int ml_replace(linenr_T lnum, char_u *line, bool copy)
if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
return FAIL;
+ bool readlen = true;
+
if (copy) {
line = vim_strsave(line);
}
- if (curbuf->b_ml.ml_line_lnum != lnum) /* other line buffered */
+ 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 */
+ } else if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) { /* same line allocated */
+ // TODO FIXME: see other "TODO FIXME"
+ curbuf->deleted_bytes += STRLEN(curbuf->b_ml.ml_line_ptr)+1;
xfree(curbuf->b_ml.ml_line_ptr); /* free it */
+ readlen = false; // already read it.
+ }
+
+ if (readlen) {
+ if (true) { // TODO: buffer updates active
+ curbuf->deleted_bytes += STRLEN(ml_get_buf(curbuf, lnum, false))+1;
+ }
+ }
+
curbuf->b_ml.ml_line_ptr = line;
curbuf->b_ml.ml_line_lnum = lnum;
curbuf->b_ml.ml_flags = (curbuf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY;
@@ -2491,6 +2504,7 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
else
line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start;
+ buf->deleted_bytes += line_size;
/*
* special case: If there is only one line in the data block it becomes empty.
@@ -2676,6 +2690,13 @@ void ml_clearmarked(void)
return;
}
+size_t ml_flush_deleted_bytes(buf_T *buf)
+{
+ size_t ret = buf->deleted_bytes;
+ buf->deleted_bytes = 0;
+ return ret;
+}
+
/*
* flush ml_line if necessary
*/
@@ -2704,6 +2725,8 @@ static void ml_flush_line(buf_T *buf)
return;
entered = TRUE;
+ buf->flush_count++;
+
lnum = buf->b_ml.ml_line_lnum;
new_line = buf->b_ml.ml_line_ptr;
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index db0d56b5fd..112ca6f287 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -1685,6 +1685,7 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine)
bool was_alloced = ml_line_alloced(); // check if oldp was allocated
char_u *newp;
if (was_alloced) {
+ curbuf->deleted_bytes += (size_t)oldlen+1;
newp = oldp; // use same allocated memory
} else { // need to allocate a new line
newp = xmalloc((size_t)(oldlen + 1 - count));