aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIbby <33922797+SleepySwords@users.noreply.github.com>2023-04-12 18:21:46 +1000
committerbfredl <bjorn.linse@gmail.com>2023-05-22 13:49:42 +0200
commit5d7afb2e9f222c32dd18c9c2bca49cab8bf751bc (patch)
treeeec2b15afbb46844c718c51c0e4c7c2af7ae00d1 /src
parent7423d3479d95e875e2d261d6e404ad19a631e530 (diff)
downloadrneovim-5d7afb2e9f222c32dd18c9c2bca49cab8bf751bc.tar.gz
rneovim-5d7afb2e9f222c32dd18c9c2bca49cab8bf751bc.tar.bz2
rneovim-5d7afb2e9f222c32dd18c9c2bca49cab8bf751bc.zip
fix(ui): fix tabs not being spaced properly after virtual text with no wrap
also fixes incorrect skipping of multibyte characters
Diffstat (limited to 'src')
-rw-r--r--src/nvim/drawline.c26
-rw-r--r--src/nvim/mbyte.c18
2 files changed, 38 insertions, 6 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index 0ad03f940a..fddf1362a3 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -969,8 +969,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
int n_skip = 0; // nr of chars to skip for 'nowrap' or
// concealing
int skip_cells = 0; // nr of cells to skip for virtual text
- // after the line, when w_skipcol is
- // larger than the text length
+ int skipped_cells = 0; // nr of skipped virtual text cells
int fromcol_prev = -2; // start of inverting after cursor
bool noinvcur = false; // don't invert the cursor
@@ -1786,14 +1785,22 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
// If the text didn't reach until the first window
// column we need to skip cells.
if (skip_cells > 0) {
- if (wlv.n_extra > skip_cells) {
- wlv.n_extra -= skip_cells;
- wlv.p_extra += skip_cells;
+ int virt_text_len = n_attr;
+ if (virt_text_len > skip_cells) {
+ int len = mb_charlen2bytelen(wlv.p_extra, skip_cells);
+ wlv.n_extra -= len;
+ wlv.p_extra += len;
+ n_attr -= skip_cells;
+ // Skipped cells needed to be accounted for in vcol.
+ skipped_cells += skip_cells;
skip_cells = 0;
} else {
// the whole text is left of the window, drop
// it and advance to the next one
- skip_cells -= wlv.n_extra;
+ skip_cells -= virt_text_len;
+ // Skipped cells needed to be accounted for in vcol.
+ skipped_cells += virt_text_len;
+ n_attr = 0;
wlv.n_extra = 0;
}
}
@@ -2969,6 +2976,13 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
n_skip--;
}
+ // The skipped cells need to be accounted for in vcol.
+ if (wlv.draw_state > WL_STC
+ && skipped_cells > 0) {
+ wlv.vcol += skipped_cells;
+ skipped_cells = 0;
+ }
+
// Only advance the "wlv.vcol" when after the 'number' or
// 'relativenumber' column.
if (wlv.draw_state > WL_STC
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 7d61b918d2..66c26275f1 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -2024,6 +2024,24 @@ int mb_charlen(const char *str)
return count;
}
+int mb_charlen2bytelen(const char *str, int charlen)
+{
+ const char *p = str;
+ int count = 0;
+
+ if (p == NULL) {
+ return 0;
+ }
+
+ for (int i = 0; *p != NUL && i < charlen; i++) {
+ int b = utfc_ptr2len(p);
+ p += b;
+ count += b;
+ }
+
+ return count;
+}
+
/// Like mb_charlen() but for a string with specified length.
int mb_charlen_len(const char *str, int len)
{