Mercurial > vim
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 |