aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/drawline.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/drawline.c')
-rw-r--r--src/nvim/drawline.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index 4a7bc9170a..37a42917b0 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -263,6 +263,9 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int
int *const indices = state->ranges_i.items;
DecorRangeSlot *const slots = state->slots.items;
+ /// Total width of all virtual text with "eol_right_align" alignment
+ int totalWidthOfEolRightAlignedVirtText = 0;
+
for (int i = 0; i < end; i++) {
DecorRange *item = &slots[indices[i]].range;
if (!(item->start_row == state->row && decor_virt_pos(item))) {
@@ -277,7 +280,44 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int
if (decor_virt_pos(item) && item->draw_col == -1) {
bool updated = true;
VirtTextPos pos = decor_virt_pos_kind(item);
- if (pos == kVPosRightAlign) {
+
+ if (do_eol && pos == kVPosEndOfLineRightAlign) {
+ int eolOffset = 0;
+ if (totalWidthOfEolRightAlignedVirtText == 0) {
+ // Look ahead to the remaining decor items
+ for (int j = i; j < end; j++) {
+ /// A future decor to be handled in this function's call
+ DecorRange *lookaheadItem = &slots[indices[j]].range;
+
+ if (lookaheadItem->start_row != state->row
+ || !decor_virt_pos(lookaheadItem)
+ || lookaheadItem->draw_col != -1) {
+ continue;
+ }
+
+ /// The Virtual Text of the decor item we're looking ahead to
+ DecorVirtText *lookaheadVt = NULL;
+ if (item->kind == kDecorKindVirtText) {
+ assert(item->data.vt);
+ lookaheadVt = item->data.vt;
+ }
+
+ if (decor_virt_pos_kind(lookaheadItem) == kVPosEndOfLineRightAlign) {
+ // An extra space is added for single character spacing in EOL alignment
+ totalWidthOfEolRightAlignedVirtText += (lookaheadVt->width + 1);
+ }
+ }
+
+ // Remove one space from the total width since there's no single space after the last entry
+ totalWidthOfEolRightAlignedVirtText--;
+
+ if (totalWidthOfEolRightAlignedVirtText <= (right_pos - state->eol_col)) {
+ eolOffset = right_pos - totalWidthOfEolRightAlignedVirtText - state->eol_col;
+ }
+ }
+
+ item->draw_col = state->eol_col + eolOffset;
+ } else if (pos == kVPosRightAlign) {
right_pos -= vt->width;
item->draw_col = right_pos;
} else if (pos == kVPosEndOfLine && do_eol) {
@@ -304,7 +344,7 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int
int vcol = item->draw_col - col_off;
int col = draw_virt_text_item(buf, item->draw_col, vt->data.virt_text,
vt->hl_mode, max_col, vcol);
- if (vt->pos == kVPosEndOfLine && do_eol) {
+ if (do_eol && ((vt->pos == kVPosEndOfLine) || (vt->pos == kVPosEndOfLineRightAlign))) {
state->eol_col = col + 1;
}
*end_col = MAX(*end_col, col);