aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/api/buffer.c
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2018-03-24 14:26:20 +0100
committerBjörn Linse <bjorn.linse@gmail.com>2018-09-17 10:41:29 +0200
commit45f53b370b11626468c35b58b939dfd2f0aa9de0 (patch)
treea1487b7201dc53b0658f8df9a7534f685f48a39c /src/nvim/api/buffer.c
parentb2d7b70f4ddd043a7f0f905c74f7d7e2e2a81ebb (diff)
downloadrneovim-45f53b370b11626468c35b58b939dfd2f0aa9de0.tar.gz
rneovim-45f53b370b11626468c35b58b939dfd2f0aa9de0.tar.bz2
rneovim-45f53b370b11626468c35b58b939dfd2f0aa9de0.zip
buffer: add support for virtual text annotations
Diffstat (limited to 'src/nvim/api/buffer.c')
-rw-r--r--src/nvim/api/buffer.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 67a4b70c9e..16196ec910 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -967,6 +967,85 @@ void nvim_buf_clear_highlight(Buffer buffer,
bufhl_clear_line_range(buf, (int)src_id, (int)line_start+1, (int)line_end);
}
+
+/// Set the virtual text (annotation) for a buffer line.
+///
+/// By default (and currently the only option) the text will be placed after
+/// the buffer text. Virtual text will never cause reflow, rather virtual
+/// text will be truncated at the end of the screen line. The virtual text will
+/// begin after one cell to the right of the ordinary text, this will contain
+/// the |lcs-eol| char if set, otherwise just be a space.
+///
+/// @param buffer Buffer handle
+/// @param src_id Source group to use or 0 to use a new group,
+/// or -1 for a ungrouped annotation
+/// @param line Line to annotate with virtual text (zero-indexed)
+/// @param chunks A list of [text, hl_group] arrays, each representing a
+/// text chunk with specified highlight. `hl_group` element
+/// can be omitted for no highlight.
+/// @param opts Optional parameters. Currently not used.
+/// @param[out] err Error details, if any
+/// @return The src_id that was used
+Integer nvim_buf_set_virtual_text(Buffer buffer,
+ Integer src_id,
+ Integer line,
+ Array chunks,
+ Dictionary opts,
+ Error *err)
+ FUNC_API_SINCE(5)
+{
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+ if (!buf) {
+ return 0;
+ }
+
+ if (line < 0 || line >= MAXLNUM) {
+ api_set_error(err, kErrorTypeValidation, "Line number outside range");
+ return 0;
+ }
+
+ if (opts.size > 0) {
+ api_set_error(err, kErrorTypeValidation, "opts dict isn't empty");
+ return 0;
+ }
+
+ VirtText virt_text = KV_INITIAL_VALUE;
+ for (size_t i = 0; i < chunks.size; i++) {
+ if (chunks.items[i].type != kObjectTypeArray) {
+ api_set_error(err, kErrorTypeValidation, "Chunk is not an array");
+ goto free_exit;
+ }
+ Array chunk = chunks.items[i].data.array;
+ if (chunk.size == 0 || chunk.size > 2
+ || chunk.items[0].type != kObjectTypeString
+ || (chunk.size == 2 && chunk.items[1].type != kObjectTypeString)) {
+ api_set_error(err, kErrorTypeValidation,
+ "Chunk is not an array with one or two strings");
+ goto free_exit;
+ }
+
+ String str = chunk.items[0].data.string;
+ char *text = xstrdup(str.size > 0 ? str.data : "");
+
+ int hl_id = 0;
+ if (chunk.size == 2) {
+ String hl = chunk.items[1].data.string;
+ if (hl.size > 0) {
+ hl_id = syn_check_group((char_u *)hl.data, (int)hl.size);
+ }
+ }
+ kv_push(virt_text, ((VirtTextChunk){ .text = text, .hl_id = hl_id }));
+ }
+
+ src_id = bufhl_add_virt_text(buf, (int)src_id, (linenr_T)line+1,
+ virt_text);
+ return src_id;
+
+free_exit:
+ kv_destroy(virt_text);
+ return 0;
+}
+
// Check if deleting lines made the cursor position invalid.
// Changed the lines from "lo" to "hi" and added "extra" lines (negative if
// deleted).