summaryrefslogtreecommitdiff
path: root/src/charset.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-08-04 15:03:48 +0100
committerBram Moolenaar <Bram@vim.org>2022-08-04 15:03:48 +0100
commit398649ee44edeb309c77361de697320378104b70 (patch)
tree37c3367373fc9709b219aecc9fd5271ef4a66041 /src/charset.c
parentbc49c5f48f89c2d6f4d88ee77f44a11d68293be3 (diff)
downloadvim-git-398649ee44edeb309c77361de697320378104b70.tar.gz
patch 9.0.0139: truncating virtual text after a line not implementedv9.0.0139
Problem: Truncating virtual text after a line not implemented. Cursor positioning wrong with Newline in the text. Solution: Implement truncating. Disallow control characters in the text. (closes #10842)
Diffstat (limited to 'src/charset.c')
-rw-r--r--src/charset.c76
1 files changed, 61 insertions, 15 deletions
diff --git a/src/charset.c b/src/charset.c
index 37c333622..7ed1fd1bd 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -655,6 +655,9 @@ char2cells(int c)
int
ptr2cells(char_u *p)
{
+ if (!has_mbyte)
+ return byte2cells(*p);
+
// For UTF-8 we need to look at more bytes if the first byte is >= 0x80.
if (enc_utf8 && *p >= 0x80)
return utf_ptr2cells(p);
@@ -682,16 +685,13 @@ vim_strnsize(char_u *s, int len)
int size = 0;
while (*s != NUL && --len >= 0)
- if (has_mbyte)
- {
- int l = (*mb_ptr2len)(s);
+ {
+ int l = (*mb_ptr2len)(s);
- size += ptr2cells(s);
- s += l;
- len -= l - 1;
- }
- else
- size += byte2cells(*s++);
+ size += ptr2cells(s);
+ s += l;
+ len -= l - 1;
+ }
return size;
}
@@ -1026,6 +1026,40 @@ lbr_chartabsize_adv(chartabsize_T *cts)
return retval;
}
+#if defined(FEAT_PROP_POPUP) || defined(PROTO)
+/*
+ * Return the cell size of virtual text after truncation.
+ */
+ int
+textprop_size_after_trunc(
+ win_T *wp,
+ int below,
+ int added,
+ char_u *text,
+ int *n_used_ptr)
+{
+ int space = below ? wp->w_width : added;
+ int len = (int)STRLEN(text);
+ int strsize = 0;
+ int n_used;
+
+ // if the remaining size is to small wrap
+ // anyway and use the next line
+ if (space < PROP_TEXT_MIN_CELLS)
+ space += wp->w_width;
+ for (n_used = 0; n_used < len; n_used += (*mb_ptr2len)(text + n_used))
+ {
+ int clen = ptr2cells(text + n_used);
+
+ if (strsize + clen > space)
+ break;
+ strsize += clen;
+ }
+ *n_used_ptr = n_used;
+ return strsize;
+}
+#endif
+
/*
* Return the screen size of the character indicated by "cts".
* "cts->cts_cur_text_width" is set to the extra size for a text property that
@@ -1110,16 +1144,28 @@ win_lbr_chartabsize(
{
char_u *p = ((char_u **)wp->w_buffer->b_textprop_text.ga_data)[
-tp->tp_id - 1];
- int len = vim_strsize(p);
+ int cells = vim_strsize(p);
+ added = wp->w_width - (vcol + size) % wp->w_width;
if (tp->tp_col == MAXCOL)
{
- // TODO: truncating
- if (tp->tp_flags & TP_FLAG_ALIGN_BELOW)
- len += wp->w_width - (vcol + size) % wp->w_width;
+ int below = (tp->tp_flags & TP_FLAG_ALIGN_BELOW);
+ int wrap = (tp->tp_flags & TP_FLAG_WRAP);
+ int len = (int)STRLEN(p);
+ int n_used = len;
+
+ // Keep in sync with where textprop_size_after_trunc() is
+ // called in win_line().
+ if (!wrap)
+ cells = textprop_size_after_trunc(wp,
+ below, added, p, &n_used);
+ // right-aligned does not really matter here, same as
+ // "after"
+ if (below)
+ cells += wp->w_width - (vcol + size) % wp->w_width;
}
- cts->cts_cur_text_width += len;
- size += len;
+ cts->cts_cur_text_width += cells;
+ size += cells;
}
if (tp->tp_col - 1 > col)
break;