aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/screen.c
diff options
context:
space:
mode:
authorYatao Li <yatli@microsoft.com>2021-09-16 07:53:56 +0800
committerYatao Li <yatli@microsoft.com>2022-05-03 22:26:02 +0800
commit29a6cda3ffe981b09d4c59d49d6c97a4ea13ca8b (patch)
treeaef77156a4164f79b004e92bd685d23a40ba6bfb /src/nvim/screen.c
parent8ea84eee570fd1ec560fe149e611d10034d9a223 (diff)
downloadrneovim-29a6cda3ffe981b09d4c59d49d6c97a4ea13ca8b.tar.gz
rneovim-29a6cda3ffe981b09d4c59d49d6c97a4ea13ca8b.tar.bz2
rneovim-29a6cda3ffe981b09d4c59d49d6c97a4ea13ca8b.zip
feat(api/ui): win_extmarks
Diffstat (limited to 'src/nvim/screen.c')
-rw-r--r--src/nvim/screen.c48
1 files changed, 39 insertions, 9 deletions
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 58abc1599a..2c3f8f307b 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -67,6 +67,7 @@
#include "nvim/api/extmark.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/api/ui.h"
#include "nvim/api/vim.h"
#include "nvim/arabic.h"
#include "nvim/ascii.h"
@@ -161,6 +162,14 @@ static bool msg_grid_invalid = false;
static bool resizing = false;
+typedef struct {
+ NS ns_id;
+ uint64_t mark_id;
+ int win_row;
+ int win_col;
+} WinExtmark;
+static kvec_t(WinExtmark) win_extmark_arr INIT(= KV_INITIAL_VALUE);
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "screen.c.generated.h"
@@ -1314,6 +1323,8 @@ static void win_update(win_T *wp, DecorProviders *providers)
srow = 0;
lnum = wp->w_topline; // first line shown in window
+ win_extmark_arr.size = 0;
+
decor_redraw_reset(buf, &decor_state);
DecorProviders line_providers;
@@ -1692,6 +1703,16 @@ static void win_update(win_T *wp, DecorProviders *providers)
wp->w_old_topfill = wp->w_topfill;
wp->w_old_botfill = wp->w_botfill;
+ // Send win_extmarks if needed
+ if (kv_size(win_extmark_arr) > 0) {
+ for (size_t n = 0; n < kv_size(win_extmark_arr); n++) {
+ ui_call_win_extmark(
+ wp->w_grid_alloc.handle, wp->handle,
+ kv_A(win_extmark_arr, n).ns_id, kv_A(win_extmark_arr, n).mark_id,
+ kv_A(win_extmark_arr, n).win_row, kv_A(win_extmark_arr, n).win_col);
+ }
+ }
+
if (dollar_vcol == -1) {
/*
* There is a trick with w_botline. If we invalidate it on each
@@ -1964,7 +1985,7 @@ static inline void provider_err_virt_text(linenr_T lnum, char *err)
((VirtTextChunk){ .text = provider_err,
.hl_id = hl_err }));
err_decor.virt_text_width = mb_string2cells((char_u *)err);
- decor_add_ephemeral(lnum - 1, 0, lnum - 1, 0, &err_decor);
+ decor_add_ephemeral(lnum - 1, 0, lnum - 1, 0, &err_decor, 0, 0);
}
static inline void get_line_number_str(win_T *wp, linenr_T lnum, char_u *buf, size_t buf_len)
@@ -2881,7 +2902,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
&& vcol >= (long)wp->w_virtcol)
|| (number_only && draw_state > WL_NR))
&& filler_todo <= 0) {
- draw_virt_text(buf, win_col_offset, &col, grid->Columns);
+ draw_virt_text(wp, buf, win_col_offset, &col, grid->Columns, row);
grid_put_linebuf(grid, row, 0, col, -grid->Columns, wp->w_p_rl, wp,
wp->w_hl_attr_normal, false);
// Pretend we have finished updating the window. Except when
@@ -3951,7 +3972,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
}
}
- draw_virt_text(buf, win_col_offset, &col, grid->Columns);
+ draw_virt_text(wp, buf, win_col_offset, &col, grid->Columns, row);
grid_put_linebuf(grid, row, 0, col, grid->Columns, wp->w_p_rl, wp,
wp->w_hl_attr_normal, false);
row++;
@@ -4195,7 +4216,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
kHlModeReplace, grid->Columns, offset);
}
} else {
- draw_virt_text(buf, win_col_offset, &draw_col, grid->Columns);
+ draw_virt_text(wp, buf, win_col_offset, &draw_col, grid->Columns, row);
}
grid_put_linebuf(grid, row, 0, draw_col, grid->Columns, wp->w_p_rl,
@@ -4274,14 +4295,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
return row;
}
-void draw_virt_text(buf_T *buf, int col_off, int *end_col, int max_col)
+void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int max_col, int win_row)
{
DecorState *state = &decor_state;
int right_pos = max_col;
bool do_eol = state->eol_col > -1;
for (size_t i = 0; i < kv_size(state->active); i++) {
DecorRange *item = &kv_A(state->active, i);
- if (!(item->start_row == state->row && kv_size(item->decor.virt_text))) {
+ if (!(item->start_row == state->row
+ && (kv_size(item->decor.virt_text) || item->decor.ui_watched))) {
continue;
}
if (item->win_col == -1) {
@@ -4297,9 +4319,17 @@ void draw_virt_text(buf_T *buf, int col_off, int *end_col, int max_col)
if (item->win_col < 0) {
continue;
}
-
- int col = draw_virt_text_item(buf, item->win_col, item->decor.virt_text,
- item->decor.hl_mode, max_col, item->win_col - col_off);
+ int col;
+ if (item->decor.ui_watched) {
+ // send mark position to UI
+ col = item->win_col;
+ WinExtmark m = { item->ns_id, item->mark_id, win_row, col };
+ kv_push(win_extmark_arr, m);
+ }
+ if (kv_size(item->decor.virt_text)) {
+ col = draw_virt_text_item(buf, item->win_col, item->decor.virt_text,
+ item->decor.hl_mode, max_col, item->win_col - col_off);
+ }
item->win_col = -2; // deactivate
if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) {
state->eol_col = col + 1;