aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/decoration.c29
-rw-r--r--src/nvim/decoration.h6
-rw-r--r--src/nvim/drawline.c25
3 files changed, 36 insertions, 24 deletions
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index ce1af290c1..81e1cb617c 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -81,7 +81,7 @@ void decor_redraw(buf_T *buf, int row1, int row2, Decoration *decor)
}
}
- if (decor && decor_virt_pos(*decor)) {
+ if (decor && decor_virt_pos(decor)) {
redraw_buf_line_later(buf, row1 + 1, false);
if (decor->virt_text_pos == kVTInline) {
changed_line_display_buf(buf);
@@ -202,9 +202,9 @@ Decoration get_decor(mtkey_t mark)
}
/// @return true if decor has a virtual position (virtual text or ui_watched)
-static bool decor_virt_pos(Decoration decor)
+bool decor_virt_pos(const Decoration *const decor)
{
- return kv_size(decor.virt_text) || decor.ui_watched;
+ return kv_size(decor->virt_text) || decor->ui_watched;
}
bool decor_redraw_start(win_T *wp, int top_row, DecorState *state)
@@ -232,7 +232,7 @@ bool decor_redraw_start(win_T *wp, int top_row, DecorState *state)
// Exclude start marks if the end mark position is above the top row
// Exclude end marks if we have already added the start mark
- if ((mt_start(mark) && altpos.row < top_row && !decor_virt_pos(decor))
+ if ((mt_start(mark) && altpos.row < top_row && !decor_virt_pos(&decor))
|| (mt_end(mark) && altpos.row >= top_row)) {
goto next_mark;
}
@@ -342,7 +342,7 @@ next_mark:
bool active = false, keep = true;
if (item.end_row < state->row
|| (item.end_row == state->row && item.end_col <= col)) {
- if (!(item.start_row >= state->row && decor_virt_pos(item.decor))) {
+ if (!(item.start_row >= state->row && decor_virt_pos(&item.decor))) {
keep = false;
}
} else {
@@ -372,10 +372,19 @@ next_mark:
if (active && item.decor.spell != kNone) {
spell = item.decor.spell;
}
- if ((item.start_row == state->row && item.start_col <= col)
- && decor_virt_pos(item.decor)
- && item.decor.virt_text_pos == kVTOverlay && item.win_col == -1) {
- item.win_col = (item.decor.virt_text_hide && hidden) ? -2 : win_col;
+ if (item.start_row == state->row && decor_virt_pos(&item.decor)
+ && item.draw_col != INT_MIN) {
+ if (item.start_col <= col) {
+ if (item.decor.virt_text_pos == kVTOverlay && item.draw_col == -1) {
+ item.draw_col = (item.decor.virt_text_hide && hidden) ? INT_MIN : win_col;
+ } else if (item.draw_col == -3) {
+ item.draw_col = -1;
+ }
+ } else if (wp->w_p_wrap
+ && (item.decor.virt_text_pos == kVTRightAlign
+ || item.decor.virt_text_pos == kVTWinCol)) {
+ item.draw_col = -3;
+ }
}
if (keep) {
kv_A(state->active, j++) = item;
@@ -550,7 +559,7 @@ bool decor_redraw_eol(win_T *wp, DecorState *state, int *eol_attr, int eol_col)
bool has_virttext = false;
for (size_t i = 0; i < kv_size(state->active); i++) {
DecorRange item = kv_A(state->active, i);
- if (item.start_row == state->row && decor_virt_pos(item.decor)) {
+ if (item.start_row == state->row && decor_virt_pos(&item.decor)) {
has_virttext = true;
}
diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h
index 95c9655742..565279b21b 100644
--- a/src/nvim/decoration.h
+++ b/src/nvim/decoration.h
@@ -82,7 +82,11 @@ typedef struct {
Decoration decor;
int attr_id; // cached lookup of decor.hl_id
bool virt_text_owned;
- int win_col;
+ /// Screen column to draw the virtual text.
+ /// When -1, the virtual text may be drawn after deciding where.
+ /// When -3, the virtual text should be drawn on a later screen line.
+ /// When INT_MIN, the virtual text should no longer be drawn.
+ int draw_col;
uint64_t ns_id;
uint64_t mark_id;
} DecorRange;
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index c9a27ceedf..723c3e1c2b 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -277,35 +277,34 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int
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) || item->decor.ui_watched))) {
+ if (!(item->start_row == state->row && decor_virt_pos(&item->decor))) {
continue;
}
- if (item->win_col == -1) {
+ if (item->draw_col == -1) {
if (item->decor.virt_text_pos == kVTRightAlign) {
right_pos -= item->decor.virt_text_width;
- item->win_col = right_pos;
+ item->draw_col = right_pos;
} else if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) {
- item->win_col = state->eol_col;
+ item->draw_col = state->eol_col;
} else if (item->decor.virt_text_pos == kVTWinCol) {
- item->win_col = MAX(item->decor.col + col_off, 0);
+ item->draw_col = MAX(item->decor.col + col_off, 0);
}
}
- if (item->win_col < 0) {
+ if (item->draw_col < 0) {
continue;
}
int col = 0;
if (item->decor.ui_watched) {
// send mark position to UI
- col = item->win_col;
+ col = item->draw_col;
WinExtmark m = { (NS)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);
+ col = draw_virt_text_item(buf, item->draw_col, item->decor.virt_text,
+ item->decor.hl_mode, max_col, item->draw_col - col_off);
}
- item->win_col = -2; // deactivate
+ item->draw_col = INT_MIN; // deactivate
if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) {
state->eol_col = col + 1;
}
@@ -876,10 +875,10 @@ static void handle_inline_virtual_text(win_T *wp, winlinevars_T *wlv, ptrdiff_t
|| item->decor.virt_text_pos != kVTInline) {
continue;
}
- if (item->win_col >= -1 && item->start_col == v) {
+ if (item->draw_col >= -1 && item->start_col == v) {
wlv->virt_inline = item->decor.virt_text;
wlv->virt_inline_i = 0;
- item->win_col = -2;
+ item->draw_col = INT_MIN;
break;
}
}