comparison src/screen.c @ 15502:bc17a9d37810 v8.1.0759

patch 8.1.0759: showing two characters for tab is limited commit https://github.com/vim/vim/commit/83a52171ba00b2b9fd2d1d22a07e38fc9fc69c1e Author: Bram Moolenaar <Bram@vim.org> Date: Wed Jan 16 22:41:54 2019 +0100 patch 8.1.0759: showing two characters for tab is limited Problem: Showing two characters for tab is limited. Solution: Allow for a third character for "tab:" in 'listchars'. (Nathaniel Braun, Ken Takata, closes #3810)
author Bram Moolenaar <Bram@vim.org>
date Wed, 16 Jan 2019 22:45:07 +0100
parents 29f3d59bb6f0
children 6d949e552e99
comparison
equal deleted inserted replaced
15501:f1ba08812cf2 15502:bc17a9d37810
3047 char_u extra[18]; /* "%ld" and 'fdc' must fit in here */ 3047 char_u extra[18]; /* "%ld" and 'fdc' must fit in here */
3048 int n_extra = 0; /* number of extra chars */ 3048 int n_extra = 0; /* number of extra chars */
3049 char_u *p_extra = NULL; /* string of extra chars, plus NUL */ 3049 char_u *p_extra = NULL; /* string of extra chars, plus NUL */
3050 char_u *p_extra_free = NULL; /* p_extra needs to be freed */ 3050 char_u *p_extra_free = NULL; /* p_extra needs to be freed */
3051 int c_extra = NUL; /* extra chars, all the same */ 3051 int c_extra = NUL; /* extra chars, all the same */
3052 int c_final = NUL; /* final char, mandatory if set */
3052 int extra_attr = 0; /* attributes when n_extra != 0 */ 3053 int extra_attr = 0; /* attributes when n_extra != 0 */
3053 static char_u *at_end_str = (char_u *)""; /* used for p_extra when 3054 static char_u *at_end_str = (char_u *)""; /* used for p_extra when
3054 displaying lcs_eol at end-of-line */ 3055 displaying lcs_eol at end-of-line */
3055 int lcs_eol_one = lcs_eol; /* lcs_eol until it's been used */ 3056 int lcs_eol_one = lcs_eol; /* lcs_eol until it's been used */
3056 int lcs_prec_todo = lcs_prec; /* lcs_prec until it's been used */ 3057 int lcs_prec_todo = lcs_prec; /* lcs_prec until it's been used */
3057 3058
3058 /* saved "extra" items for when draw_state becomes WL_LINE (again) */ 3059 /* saved "extra" items for when draw_state becomes WL_LINE (again) */
3059 int saved_n_extra = 0; 3060 int saved_n_extra = 0;
3060 char_u *saved_p_extra = NULL; 3061 char_u *saved_p_extra = NULL;
3061 int saved_c_extra = 0; 3062 int saved_c_extra = 0;
3063 int saved_c_final = 0;
3062 int saved_char_attr = 0; 3064 int saved_char_attr = 0;
3063 3065
3064 int n_attr = 0; /* chars with special attr */ 3066 int n_attr = 0; /* chars with special attr */
3065 int saved_attr2 = 0; /* char_attr saved for n_attr */ 3067 int saved_attr2 = 0; /* char_attr saved for n_attr */
3066 int n_attr3 = 0; /* chars with overruling special attr */ 3068 int n_attr3 = 0; /* chars with overruling special attr */
3812 if (cmdwin_type != 0 && wp == curwin) 3814 if (cmdwin_type != 0 && wp == curwin)
3813 { 3815 {
3814 /* Draw the cmdline character. */ 3816 /* Draw the cmdline character. */
3815 n_extra = 1; 3817 n_extra = 1;
3816 c_extra = cmdwin_type; 3818 c_extra = cmdwin_type;
3819 c_final = NUL;
3817 char_attr = HL_ATTR(HLF_AT); 3820 char_attr = HL_ATTR(HLF_AT);
3818 } 3821 }
3819 } 3822 }
3820 #endif 3823 #endif
3821 3824
3837 fill_foldcolumn(p_extra_free, wp, FALSE, lnum); 3840 fill_foldcolumn(p_extra_free, wp, FALSE, lnum);
3838 n_extra = fdc; 3841 n_extra = fdc;
3839 p_extra_free[n_extra] = NUL; 3842 p_extra_free[n_extra] = NUL;
3840 p_extra = p_extra_free; 3843 p_extra = p_extra_free;
3841 c_extra = NUL; 3844 c_extra = NUL;
3845 c_final = NUL;
3842 char_attr = HL_ATTR(HLF_FC); 3846 char_attr = HL_ATTR(HLF_FC);
3843 } 3847 }
3844 } 3848 }
3845 } 3849 }
3846 #endif 3850 #endif
3858 int icon_sign; 3862 int icon_sign;
3859 # endif 3863 # endif
3860 3864
3861 /* Draw two cells with the sign value or blank. */ 3865 /* Draw two cells with the sign value or blank. */
3862 c_extra = ' '; 3866 c_extra = ' ';
3867 c_final = NUL;
3863 char_attr = HL_ATTR(HLF_SC); 3868 char_attr = HL_ATTR(HLF_SC);
3864 n_extra = 2; 3869 n_extra = 2;
3865 3870
3866 if (row == startrow 3871 if (row == startrow
3867 #ifdef FEAT_DIFF 3872 #ifdef FEAT_DIFF
3876 SIGN_ICON); 3881 SIGN_ICON);
3877 if (gui.in_use && icon_sign != 0) 3882 if (gui.in_use && icon_sign != 0)
3878 { 3883 {
3879 /* Use the image in this position. */ 3884 /* Use the image in this position. */
3880 c_extra = SIGN_BYTE; 3885 c_extra = SIGN_BYTE;
3886 c_final = NUL;
3881 # ifdef FEAT_NETBEANS_INTG 3887 # ifdef FEAT_NETBEANS_INTG
3882 if (buf_signcount(wp->w_buffer, lnum) > 1) 3888 if (buf_signcount(wp->w_buffer, lnum) > 1)
3889 {
3883 c_extra = MULTISIGN_BYTE; 3890 c_extra = MULTISIGN_BYTE;
3891 c_final = NUL;
3892 }
3884 # endif 3893 # endif
3885 char_attr = icon_sign; 3894 char_attr = icon_sign;
3886 } 3895 }
3887 else 3896 else
3888 # endif 3897 # endif
3890 { 3899 {
3891 p_extra = sign_get_text(text_sign); 3900 p_extra = sign_get_text(text_sign);
3892 if (p_extra != NULL) 3901 if (p_extra != NULL)
3893 { 3902 {
3894 c_extra = NUL; 3903 c_extra = NUL;
3904 c_final = NUL;
3895 n_extra = (int)STRLEN(p_extra); 3905 n_extra = (int)STRLEN(p_extra);
3896 } 3906 }
3897 char_attr = sign_get_attr(text_sign, FALSE); 3907 char_attr = sign_get_attr(text_sign, FALSE);
3898 } 3908 }
3899 } 3909 }
3947 if (wp->w_p_rl) /* reverse line numbers */ 3957 if (wp->w_p_rl) /* reverse line numbers */
3948 rl_mirror(extra); 3958 rl_mirror(extra);
3949 #endif 3959 #endif
3950 p_extra = extra; 3960 p_extra = extra;
3951 c_extra = NUL; 3961 c_extra = NUL;
3962 c_final = NUL;
3952 } 3963 }
3953 else 3964 else
3965 {
3954 c_extra = ' '; 3966 c_extra = ' ';
3967 c_final = NUL;
3968 }
3955 n_extra = number_width(wp) + 1; 3969 n_extra = number_width(wp) + 1;
3956 char_attr = HL_ATTR(HLF_N); 3970 char_attr = HL_ATTR(HLF_N);
3957 #ifdef FEAT_SYN_HL 3971 #ifdef FEAT_SYN_HL
3958 /* When 'cursorline' is set highlight the line number of 3972 /* When 'cursorline' is set highlight the line number of
3959 * the current line differently. 3973 * the current line differently.
4018 # ifdef FEAT_DIFF 4032 # ifdef FEAT_DIFF
4019 if (filler_todo > 0) 4033 if (filler_todo > 0)
4020 { 4034 {
4021 /* Draw "deleted" diff line(s). */ 4035 /* Draw "deleted" diff line(s). */
4022 if (char2cells(fill_diff) > 1) 4036 if (char2cells(fill_diff) > 1)
4037 {
4023 c_extra = '-'; 4038 c_extra = '-';
4039 c_final = NUL;
4040 }
4024 else 4041 else
4042 {
4025 c_extra = fill_diff; 4043 c_extra = fill_diff;
4044 c_final = NUL;
4045 }
4026 # ifdef FEAT_RIGHTLEFT 4046 # ifdef FEAT_RIGHTLEFT
4027 if (wp->w_p_rl) 4047 if (wp->w_p_rl)
4028 n_extra = col + 1; 4048 n_extra = col + 1;
4029 else 4049 else
4030 # endif 4050 # endif
4036 if (*p_sbr != NUL && need_showbreak) 4056 if (*p_sbr != NUL && need_showbreak)
4037 { 4057 {
4038 /* Draw 'showbreak' at the start of each broken line. */ 4058 /* Draw 'showbreak' at the start of each broken line. */
4039 p_extra = p_sbr; 4059 p_extra = p_sbr;
4040 c_extra = NUL; 4060 c_extra = NUL;
4061 c_final = NUL;
4041 n_extra = (int)STRLEN(p_sbr); 4062 n_extra = (int)STRLEN(p_sbr);
4042 char_attr = HL_ATTR(HLF_AT); 4063 char_attr = HL_ATTR(HLF_AT);
4043 need_showbreak = FALSE; 4064 need_showbreak = FALSE;
4044 vcol_sbr = vcol + MB_CHARLEN(p_sbr); 4065 vcol_sbr = vcol + MB_CHARLEN(p_sbr);
4045 /* Correct end of highlighted area for 'showbreak', 4066 /* Correct end of highlighted area for 'showbreak',
4063 if (saved_n_extra) 4084 if (saved_n_extra)
4064 { 4085 {
4065 /* Continue item from end of wrapped line. */ 4086 /* Continue item from end of wrapped line. */
4066 n_extra = saved_n_extra; 4087 n_extra = saved_n_extra;
4067 c_extra = saved_c_extra; 4088 c_extra = saved_c_extra;
4089 c_final = saved_c_final;
4068 p_extra = saved_p_extra; 4090 p_extra = saved_p_extra;
4069 char_attr = saved_char_attr; 4091 char_attr = saved_char_attr;
4070 } 4092 }
4071 else 4093 else
4072 char_attr = 0; 4094 char_attr = 0;
4362 */ 4384 */
4363 /* 4385 /*
4364 * The "p_extra" points to the extra stuff that is inserted to 4386 * The "p_extra" points to the extra stuff that is inserted to
4365 * represent special characters (non-printable stuff) and other 4387 * represent special characters (non-printable stuff) and other
4366 * things. When all characters are the same, c_extra is used. 4388 * things. When all characters are the same, c_extra is used.
4389 * If c_final is set, it will compulsorily be used at the end.
4367 * "p_extra" must end in a NUL to avoid mb_ptr2len() reads past 4390 * "p_extra" must end in a NUL to avoid mb_ptr2len() reads past
4368 * "p_extra[n_extra]". 4391 * "p_extra[n_extra]".
4369 * For the '$' of the 'list' option, n_extra == 1, p_extra == "". 4392 * For the '$' of the 'list' option, n_extra == 1, p_extra == "".
4370 */ 4393 */
4371 if (n_extra > 0) 4394 if (n_extra > 0)
4372 { 4395 {
4373 if (c_extra != NUL) 4396 if (c_extra != NUL || (n_extra == 1 && c_final != NUL))
4374 { 4397 {
4375 c = c_extra; 4398 c = (n_extra == 1 && c_final != NUL) ? c_final : c_extra;
4376 #ifdef FEAT_MBYTE 4399 #ifdef FEAT_MBYTE
4377 mb_c = c; /* doesn't handle non-utf-8 multi-byte! */ 4400 mb_c = c; /* doesn't handle non-utf-8 multi-byte! */
4378 if (enc_utf8 && utf_char2len(c) > 1) 4401 if (enc_utf8 && utf_char2len(c) > 1)
4379 { 4402 {
4380 mb_utf8 = TRUE; 4403 mb_utf8 = TRUE;
4535 c = *p_extra; 4558 c = *p_extra;
4536 mb_c = mb_ptr2char_adv(&p_extra); 4559 mb_c = mb_ptr2char_adv(&p_extra);
4537 mb_utf8 = (c >= 0x80); 4560 mb_utf8 = (c >= 0x80);
4538 n_extra = (int)STRLEN(p_extra); 4561 n_extra = (int)STRLEN(p_extra);
4539 c_extra = NUL; 4562 c_extra = NUL;
4563 c_final = NUL;
4540 if (area_attr == 0 && search_attr == 0) 4564 if (area_attr == 0 && search_attr == 0)
4541 { 4565 {
4542 n_attr = n_extra + 1; 4566 n_attr = n_extra + 1;
4543 extra_attr = HL_ATTR(HLF_8); 4567 extra_attr = HL_ATTR(HLF_8);
4544 saved_attr2 = char_attr; /* save current attr */ 4568 saved_attr2 = char_attr; /* save current attr */
4603 STRCPY(extra, "XX"); 4627 STRCPY(extra, "XX");
4604 } 4628 }
4605 p_extra = extra; 4629 p_extra = extra;
4606 n_extra = (int)STRLEN(extra) - 1; 4630 n_extra = (int)STRLEN(extra) - 1;
4607 c_extra = NUL; 4631 c_extra = NUL;
4632 c_final = NUL;
4608 c = *p_extra++; 4633 c = *p_extra++;
4609 if (area_attr == 0 && search_attr == 0) 4634 if (area_attr == 0 && search_attr == 0)
4610 { 4635 {
4611 n_attr = n_extra + 1; 4636 n_attr = n_extra + 1;
4612 extra_attr = HL_ATTR(HLF_8); 4637 extra_attr = HL_ATTR(HLF_8);
4643 * characters. */ 4668 * characters. */
4644 if (n_skip > 0 && mb_l > 1 && n_extra == 0) 4669 if (n_skip > 0 && mb_l > 1 && n_extra == 0)
4645 { 4670 {
4646 n_extra = 1; 4671 n_extra = 1;
4647 c_extra = MB_FILLER_CHAR; 4672 c_extra = MB_FILLER_CHAR;
4673 c_final = NUL;
4648 c = ' '; 4674 c = ' ';
4649 if (area_attr == 0 && search_attr == 0) 4675 if (area_attr == 0 && search_attr == 0)
4650 { 4676 {
4651 n_attr = n_extra + 1; 4677 n_attr = n_extra + 1;
4652 extra_attr = HL_ATTR(HLF_AT); 4678 extra_attr = HL_ATTR(HLF_AT);
4854 # ifdef FEAT_MBYTE 4880 # ifdef FEAT_MBYTE
4855 c_extra = mb_off > 0 ? MB_FILLER_CHAR : ' '; 4881 c_extra = mb_off > 0 ? MB_FILLER_CHAR : ' ';
4856 # else 4882 # else
4857 c_extra = ' '; 4883 c_extra = ' ';
4858 # endif 4884 # endif
4885 c_final = NUL;
4859 if (VIM_ISWHITE(c)) 4886 if (VIM_ISWHITE(c))
4860 { 4887 {
4861 #ifdef FEAT_CONCEAL 4888 #ifdef FEAT_CONCEAL
4862 if (c == TAB) 4889 if (c == TAB)
4863 /* See "Tab alignment" below. */ 4890 /* See "Tab alignment" below. */
5038 #ifdef FEAT_MBYTE 5065 #ifdef FEAT_MBYTE
5039 mb_utf8 = FALSE; /* don't draw as UTF-8 */ 5066 mb_utf8 = FALSE; /* don't draw as UTF-8 */
5040 #endif 5067 #endif
5041 if (wp->w_p_list) 5068 if (wp->w_p_list)
5042 { 5069 {
5043 c = lcs_tab1; 5070 c = (n_extra == 0 && lcs_tab3) ? lcs_tab3 : lcs_tab1;
5044 #ifdef FEAT_LINEBREAK 5071 #ifdef FEAT_LINEBREAK
5045 if (wp->w_p_lbr) 5072 if (wp->w_p_lbr)
5046 c_extra = NUL; /* using p_extra from above */ 5073 c_extra = NUL; /* using p_extra from above */
5047 else 5074 else
5048 #endif 5075 #endif
5049 c_extra = lcs_tab2; 5076 c_extra = lcs_tab2;
5077 c_final = lcs_tab3;
5050 n_attr = tab_len + 1; 5078 n_attr = tab_len + 1;
5051 extra_attr = HL_ATTR(HLF_8); 5079 extra_attr = HL_ATTR(HLF_8);
5052 saved_attr2 = char_attr; /* save current attr */ 5080 saved_attr2 = char_attr; /* save current attr */
5053 #ifdef FEAT_MBYTE 5081 #ifdef FEAT_MBYTE
5054 mb_c = c; 5082 mb_c = c;
5060 } 5088 }
5061 #endif 5089 #endif
5062 } 5090 }
5063 else 5091 else
5064 { 5092 {
5093 c_final = NUL;
5065 c_extra = ' '; 5094 c_extra = ' ';
5066 c = ' '; 5095 c = ' ';
5067 } 5096 }
5068 } 5097 }
5069 else if (c == NUL 5098 else if (c == NUL
5109 #endif 5138 #endif
5110 { 5139 {
5111 p_extra = at_end_str; 5140 p_extra = at_end_str;
5112 n_extra = 1; 5141 n_extra = 1;
5113 c_extra = NUL; 5142 c_extra = NUL;
5143 c_final = NUL;
5114 } 5144 }
5115 } 5145 }
5116 if (wp->w_p_list && lcs_eol > 0) 5146 if (wp->w_p_list && lcs_eol > 0)
5117 c = lcs_eol; 5147 c = lcs_eol;
5118 else 5148 else
5144 #ifdef FEAT_RIGHTLEFT 5174 #ifdef FEAT_RIGHTLEFT
5145 if ((dy_flags & DY_UHEX) && wp->w_p_rl) 5175 if ((dy_flags & DY_UHEX) && wp->w_p_rl)
5146 rl_mirror(p_extra); /* reverse "<12>" */ 5176 rl_mirror(p_extra); /* reverse "<12>" */
5147 #endif 5177 #endif
5148 c_extra = NUL; 5178 c_extra = NUL;
5179 c_final = NUL;
5149 #ifdef FEAT_LINEBREAK 5180 #ifdef FEAT_LINEBREAK
5150 if (wp->w_p_lbr) 5181 if (wp->w_p_lbr)
5151 { 5182 {
5152 char_u *p; 5183 char_u *p;
5153 5184
5405 if (has_mbyte && (*mb_char2cells)(mb_c) > 1) 5436 if (has_mbyte && (*mb_char2cells)(mb_c) > 1)
5406 { 5437 {
5407 /* Double-width character being overwritten by the "precedes" 5438 /* Double-width character being overwritten by the "precedes"
5408 * character, need to fill up half the character. */ 5439 * character, need to fill up half the character. */
5409 c_extra = MB_FILLER_CHAR; 5440 c_extra = MB_FILLER_CHAR;
5441 c_final = NUL;
5410 n_extra = 1; 5442 n_extra = 1;
5411 n_attr = 2; 5443 n_attr = 2;
5412 extra_attr = HL_ATTR(HLF_AT); 5444 extra_attr = HL_ATTR(HLF_AT);
5413 } 5445 }
5414 mb_c = c; 5446 mb_c = c;
6062 /* reset the drawing state for the start of a wrapped line */ 6094 /* reset the drawing state for the start of a wrapped line */
6063 draw_state = WL_START; 6095 draw_state = WL_START;
6064 saved_n_extra = n_extra; 6096 saved_n_extra = n_extra;
6065 saved_p_extra = p_extra; 6097 saved_p_extra = p_extra;
6066 saved_c_extra = c_extra; 6098 saved_c_extra = c_extra;
6099 saved_c_final = c_final;
6067 saved_char_attr = char_attr; 6100 saved_char_attr = char_attr;
6068 n_extra = 0; 6101 n_extra = 0;
6069 lcs_prec_todo = lcs_prec; 6102 lcs_prec_todo = lcs_prec;
6070 #ifdef FEAT_LINEBREAK 6103 #ifdef FEAT_LINEBREAK
6071 # ifdef FEAT_DIFF 6104 # ifdef FEAT_DIFF