diff options
Diffstat (limited to 'src/nvim/api/buffer.c')
-rw-r--r-- | src/nvim/api/buffer.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index e79a7a2de2..f84e8c99a4 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -27,6 +27,7 @@ #include "nvim/map_defs.h" #include "nvim/map.h" #include "nvim/mark.h" +#include "nvim/ops.h" #include "nvim/extmark.h" #include "nvim/decoration.h" #include "nvim/fileio.h" @@ -441,6 +442,8 @@ void nvim_buf_set_lines(uint64_t channel_id, goto end; } + bcount_t deleted_bytes = get_region_bytecount(curbuf, start, end, 0, 0); + // If the size of the range is reducing (ie, new_len < old_len) we // need to delete some old_len. We do this at the start, by // repeatedly deleting line "start". @@ -460,6 +463,7 @@ void nvim_buf_set_lines(uint64_t channel_id, // new old_len. This is a more efficient operation, as it requires // less memory allocation and freeing. size_t to_replace = old_len < new_len ? old_len : new_len; + bcount_t inserted_bytes = 0; for (size_t i = 0; i < to_replace; i++) { int64_t lnum = start + (int64_t)i; @@ -472,6 +476,8 @@ void nvim_buf_set_lines(uint64_t channel_id, api_set_error(err, kErrorTypeException, "Failed to replace line"); goto end; } + + inserted_bytes += (bcount_t)strlen(lines[i]) + 1; // Mark lines that haven't been passed to the buffer as they need // to be freed later lines[i] = NULL; @@ -491,6 +497,8 @@ void nvim_buf_set_lines(uint64_t channel_id, goto end; } + inserted_bytes += (bcount_t)strlen(lines[i]) + 1; + // Same as with replacing, but we also need to free lines xfree(lines[i]); lines[i] = NULL; @@ -505,7 +513,11 @@ void nvim_buf_set_lines(uint64_t channel_id, (linenr_T)(end - 1), MAXLNUM, (long)extra, - kExtmarkUndo); + kExtmarkNOOP); + + extmark_splice(curbuf, (int)start-1, 0, (int)(end-start), 0, + deleted_bytes, (int)new_len, 0, inserted_bytes, + kExtmarkUndo); changed_lines((linenr_T)start, 0, (linenr_T)end, (long)extra, true); fix_cursor((linenr_T)start, (linenr_T)end, (linenr_T)extra); @@ -1412,12 +1424,12 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, /// /// @param buffer Buffer handle, or 0 for current buffer /// @param ns_id Namespace id from |nvim_create_namespace()| -/// @param line Line number where to place the mark -/// @param col Column where to place the mark +/// @param line Line where to place the mark, 0-based +/// @param col Column where to place the mark, 0-based /// @param opts Optional parameters. /// - id : id of the extmark to edit. /// - end_line : ending line of the mark, 0-based inclusive. -/// - end_col : ending col of the mark, 0-based inclusive. +/// - end_col : ending col of the mark, 0-based exclusive. /// - hl_group : name of the highlight group used to highlight /// this mark. /// - virt_text : virtual text to link to this mark. @@ -1426,6 +1438,10 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, /// - "eol": right after eol character (default) /// - "overlay": display over the specified column, without /// shifting the underlying text. +/// - "right_align": display right aligned in the window. +/// - virt_text_win_col : position the virtual text at a fixed +/// window column (starting from the first +/// text column) /// - virt_text_hide : hide the virtual text when the background /// text is selected or hidden due to /// horizontal scroll 'nowrap' @@ -1574,11 +1590,22 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, decor.virt_text_pos = kVTEndOfLine; } else if (strequal("overlay", str.data)) { decor.virt_text_pos = kVTOverlay; + } else if (strequal("right_align", str.data)) { + decor.virt_text_pos = kVTRightAlign; } else { api_set_error(err, kErrorTypeValidation, "virt_text_pos: invalid value"); goto error; } + } else if (strequal("virt_text_win_col", k.data)) { + if (v->type != kObjectTypeInteger) { + api_set_error(err, kErrorTypeValidation, + "virt_text_win_col is not a Number of the correct size"); + goto error; + } + + decor.col = (int)v->data.integer; + decor.virt_text_pos = kVTWinCol; } else if (strequal("virt_text_hide", k.data)) { decor.virt_text_hide = api_object_to_bool(*v, "virt_text_hide", false, err); @@ -1673,6 +1700,15 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, col2 = 0; } + if (decor.virt_text_pos == kVTRightAlign) { + decor.col = 0; + for (size_t i = 0; i < kv_size(decor.virt_text); i++) { + decor.col + += (int)mb_string2cells((char_u *)kv_A(decor.virt_text, i).text); + } + } + + Decoration *d = NULL; if (ephemeral) { |