aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2021-07-23 18:00:42 +0200
committerBjörn Linse <bjorn.linse@gmail.com>2021-07-29 20:34:20 +0200
commit1495d36d63305862da3c4106455667d51b578707 (patch)
treebf2cabbdb905eff3d3c03be6c67c883fba90a7f2 /src
parent98c4b2cf627bf5156a0d83fe0bf60f3c23af6f1b (diff)
downloadrneovim-1495d36d63305862da3c4106455667d51b578707.tar.gz
rneovim-1495d36d63305862da3c4106455667d51b578707.tar.bz2
rneovim-1495d36d63305862da3c4106455667d51b578707.zip
feat(decorations): allow more than one stacked highlight in a virt_text
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/buffer.c10
-rw-r--r--src/nvim/api/private/helpers.c28
-rw-r--r--src/nvim/screen.c20
3 files changed, 44 insertions, 14 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 78e36e5ef0..47216996b4 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -1433,8 +1433,14 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id,
/// - hl_group : name of the highlight group used to highlight
/// this mark.
/// - virt_text : virtual text to link to this mark.
-/// - virt_text_pos : positioning of virtual text. Possible
-/// values:
+/// A list of [text, highlight] tuples, each representing a
+/// text chunk with specified highlight. `highlight` element
+/// can either be a a single highlight group, or an array of
+/// multiple highlight groups that will be stacked
+/// (highest priority last). A highlight group can be supplied
+/// either as a string or as an integer, the latter which
+/// can be obtained using |nvim_get_hl_id_by_name|.
+/// - virt_text_pos : position of virtual text. Possible values:
/// - "eol": right after eol character (default)
/// - "overlay": display over the specified column, without
/// shifting the underlying text.
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 9f2e94f31e..e78bd2ea9a 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -1603,22 +1603,38 @@ VirtText parse_virt_text(Array chunks, Error *err)
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)) {
+ || chunk.size > 2) {
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 = transstr(str.size > 0 ? str.data : ""); // allocates
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);
+ Object hl = chunk.items[1];
+ if (hl.type == kObjectTypeArray) {
+ Array arr = hl.data.array;
+ for (size_t j = 0; j < arr.size; j++) {
+ hl_id = object_to_hl_id(arr.items[j], "virt_text highlight", err);
+ if (ERROR_SET(err)) {
+ goto free_exit;
+ }
+ if (j < arr.size-1) {
+ kv_push(virt_text, ((VirtTextChunk){ .text = NULL,
+ .hl_id = hl_id }));
+ }
+ }
+ } else {
+ hl_id = object_to_hl_id(hl, "virt_text highlight", err);
+ if (ERROR_SET(err)) {
+ goto free_exit;
+ }
}
}
+
+ char *text = transstr(str.size > 0 ? str.data : ""); // allocates
kv_push(virt_text, ((VirtTextChunk){ .text = text, .hl_id = hl_id }));
}
@@ -1656,7 +1672,7 @@ int object_to_hl_id(Object obj, const char *what, Error *err)
String str = obj.data.string;
return str.size ? syn_check_group((char_u *)str.data, (int)str.size) : 0;
} else if (obj.type == kObjectTypeInteger) {
- return (int)obj.data.integer;
+ return MAX((int)obj.data.integer, 0);
} else {
api_set_error(err, kErrorTypeValidation,
"%s is not a valid highlight", what);
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index ae785132bb..586aeff1e2 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -4021,6 +4021,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
while (wp->w_p_rl ? col >= 0 : col < grid->Columns) {
int cells = -1;
+ // TODO: integrate this whith the other virt_text impl already
if (do_virttext && !delay_virttext) {
if (*s.p == NUL) {
if (virt_pos < virt_text.size) {
@@ -4424,14 +4425,21 @@ void draw_virt_text(buf_T *buf, int col_off, int *end_col, int max_col)
while (col < max_col) {
if (!*s.p) {
- if (virt_pos == kv_size(vt)) {
+ if (virt_pos >= kv_size(vt)) {
+ break;
+ }
+ virt_attr = 0;
+ do {
+ s.p = kv_A(vt, virt_pos).text;
+ int hl_id = kv_A(vt, virt_pos).hl_id;
+ virt_attr = hl_combine_attr(virt_attr,
+ hl_id > 0 ? syn_id2attr(hl_id) : 0);
+ virt_pos++;
+ } while (!s.p && virt_pos < kv_size(vt));
+ // TODO: y w0t m8
+ if (!s.p) {
break;
}
- s.p = kv_A(vt, virt_pos).text;
- int hl_id = kv_A(vt, virt_pos).hl_id;
- virt_attr = hl_id > 0 ? syn_id2attr(hl_id) : 0;
- virt_pos++;
- continue;
}
int attr;
bool through = false;