diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/buffer.c | 23 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 3 | ||||
-rw-r--r-- | src/nvim/buffer_updates.c | 8 | ||||
-rw-r--r-- | src/nvim/fileio.c | 1 | ||||
-rw-r--r-- | src/nvim/memline.c | 27 | ||||
-rw-r--r-- | src/nvim/misc1.c | 1 |
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)); |