diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-08-04 15:03:48 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-08-04 15:03:48 +0100 |
commit | 398649ee44edeb309c77361de697320378104b70 (patch) | |
tree | 37c3367373fc9709b219aecc9fd5271ef4a66041 /src/charset.c | |
parent | bc49c5f48f89c2d6f4d88ee77f44a11d68293be3 (diff) | |
download | vim-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.c | 76 |
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; |