comparison src/charset.c @ 29597:f2d7f20d83c3 v9.0.0139

patch 9.0.0139: truncating virtual text after a line not implemented Commit: https://github.com/vim/vim/commit/398649ee44edeb309c77361de697320378104b70 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Aug 4 15:03:48 2022 +0100 patch 9.0.0139: truncating virtual text after a line not implemented 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)
author Bram Moolenaar <Bram@vim.org>
date Thu, 04 Aug 2022 16:15:08 +0200
parents 5233acfa06f1
children 8f01d250793a
comparison
equal deleted inserted replaced
29596:aea558552904 29597:f2d7f20d83c3
653 * A TAB is counted as two cells: "^I" or four: "<09>". 653 * A TAB is counted as two cells: "^I" or four: "<09>".
654 */ 654 */
655 int 655 int
656 ptr2cells(char_u *p) 656 ptr2cells(char_u *p)
657 { 657 {
658 if (!has_mbyte)
659 return byte2cells(*p);
660
658 // For UTF-8 we need to look at more bytes if the first byte is >= 0x80. 661 // For UTF-8 we need to look at more bytes if the first byte is >= 0x80.
659 if (enc_utf8 && *p >= 0x80) 662 if (enc_utf8 && *p >= 0x80)
660 return utf_ptr2cells(p); 663 return utf_ptr2cells(p);
661 // For DBCS we can tell the cell count from the first byte. 664 // For DBCS we can tell the cell count from the first byte.
662 return (g_chartab[*p] & CT_CELL_MASK); 665 return (g_chartab[*p] & CT_CELL_MASK);
680 vim_strnsize(char_u *s, int len) 683 vim_strnsize(char_u *s, int len)
681 { 684 {
682 int size = 0; 685 int size = 0;
683 686
684 while (*s != NUL && --len >= 0) 687 while (*s != NUL && --len >= 0)
685 if (has_mbyte) 688 {
686 { 689 int l = (*mb_ptr2len)(s);
687 int l = (*mb_ptr2len)(s); 690
688 691 size += ptr2cells(s);
689 size += ptr2cells(s); 692 s += l;
690 s += l; 693 len -= l - 1;
691 len -= l - 1; 694 }
692 }
693 else
694 size += byte2cells(*s++);
695 695
696 return size; 696 return size;
697 } 697 }
698 698
699 /* 699 /*
1024 retval = lbr_chartabsize(cts); 1024 retval = lbr_chartabsize(cts);
1025 MB_PTR_ADV(cts->cts_ptr); 1025 MB_PTR_ADV(cts->cts_ptr);
1026 return retval; 1026 return retval;
1027 } 1027 }
1028 1028
1029 #if defined(FEAT_PROP_POPUP) || defined(PROTO)
1030 /*
1031 * Return the cell size of virtual text after truncation.
1032 */
1033 int
1034 textprop_size_after_trunc(
1035 win_T *wp,
1036 int below,
1037 int added,
1038 char_u *text,
1039 int *n_used_ptr)
1040 {
1041 int space = below ? wp->w_width : added;
1042 int len = (int)STRLEN(text);
1043 int strsize = 0;
1044 int n_used;
1045
1046 // if the remaining size is to small wrap
1047 // anyway and use the next line
1048 if (space < PROP_TEXT_MIN_CELLS)
1049 space += wp->w_width;
1050 for (n_used = 0; n_used < len; n_used += (*mb_ptr2len)(text + n_used))
1051 {
1052 int clen = ptr2cells(text + n_used);
1053
1054 if (strsize + clen > space)
1055 break;
1056 strsize += clen;
1057 }
1058 *n_used_ptr = n_used;
1059 return strsize;
1060 }
1061 #endif
1062
1029 /* 1063 /*
1030 * Return the screen size of the character indicated by "cts". 1064 * Return the screen size of the character indicated by "cts".
1031 * "cts->cts_cur_text_width" is set to the extra size for a text property that 1065 * "cts->cts_cur_text_width" is set to the extra size for a text property that
1032 * inserts text. 1066 * inserts text.
1033 * This function is used very often, keep it fast!!!! 1067 * This function is used very often, keep it fast!!!!
1108 || (tp->tp_col == MAXCOL && (s[0] == NUL || s[1] == NUL) 1142 || (tp->tp_col == MAXCOL && (s[0] == NUL || s[1] == NUL)
1109 && cts->cts_with_trailing))) 1143 && cts->cts_with_trailing)))
1110 { 1144 {
1111 char_u *p = ((char_u **)wp->w_buffer->b_textprop_text.ga_data)[ 1145 char_u *p = ((char_u **)wp->w_buffer->b_textprop_text.ga_data)[
1112 -tp->tp_id - 1]; 1146 -tp->tp_id - 1];
1113 int len = vim_strsize(p); 1147 int cells = vim_strsize(p);
1114 1148
1149 added = wp->w_width - (vcol + size) % wp->w_width;
1115 if (tp->tp_col == MAXCOL) 1150 if (tp->tp_col == MAXCOL)
1116 { 1151 {
1117 // TODO: truncating 1152 int below = (tp->tp_flags & TP_FLAG_ALIGN_BELOW);
1118 if (tp->tp_flags & TP_FLAG_ALIGN_BELOW) 1153 int wrap = (tp->tp_flags & TP_FLAG_WRAP);
1119 len += wp->w_width - (vcol + size) % wp->w_width; 1154 int len = (int)STRLEN(p);
1155 int n_used = len;
1156
1157 // Keep in sync with where textprop_size_after_trunc() is
1158 // called in win_line().
1159 if (!wrap)
1160 cells = textprop_size_after_trunc(wp,
1161 below, added, p, &n_used);
1162 // right-aligned does not really matter here, same as
1163 // "after"
1164 if (below)
1165 cells += wp->w_width - (vcol + size) % wp->w_width;
1120 } 1166 }
1121 cts->cts_cur_text_width += len; 1167 cts->cts_cur_text_width += cells;
1122 size += len; 1168 size += cells;
1123 } 1169 }
1124 if (tp->tp_col - 1 > col) 1170 if (tp->tp_col - 1 > col)
1125 break; 1171 break;
1126 } 1172 }
1127 } 1173 }