mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-07 15:37:14 +02:00
patch 9.2.0572: lines disappear with wrapping virtual text after a double-width char
Problem: With 'nowrap', when a line ends with a double-width character
exactly at the window width and has wrapping "after" virtual
text, the lines below disappear and "@@@" is shown.
Solution: Detect that the last character fills the rightmost column using
its displayed width (win_chartabsize(), so a <Tab> or double-width
character is handled like a single-width one), and also when it
overflows the last column. Also clarify in the help that "wrap"
only takes effect with the 'wrap' option set.
fixes: #20384
related: #12213
closes: #20395
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
37089793b8
commit
09f7fc60d3
@@ -1,4 +1,4 @@
|
||||
*textprop.txt* For Vim version 9.2. Last change: 2026 Apr 07
|
||||
*textprop.txt* For Vim version 9.2. Last change: 2026 May 31
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -177,7 +177,9 @@ prop_add({lnum}, {col}, {props})
|
||||
When omitted "truncate" is used.
|
||||
Note that this applies to the individual text
|
||||
property, the 'wrap' option sets the overall
|
||||
behavior
|
||||
behavior. "wrap" only takes effect when the
|
||||
'wrap' option is set; with 'nowrap' the text
|
||||
is truncated at the right edge of the window.
|
||||
All fields except "type" are optional.
|
||||
|
||||
It is an error when both "length" and "end_lnum" or "end_col"
|
||||
|
||||
+5
-1
@@ -2479,7 +2479,11 @@ win_line(
|
||||
// displaying that character.
|
||||
// Or when not wrapping and at the rightmost column.
|
||||
|
||||
int only_below_follows = !wp->w_p_wrap && wlv.col == wp->w_width - 1;
|
||||
// Use the displayed width so a double-width or <Tab> last
|
||||
// character filling the rightmost column is detected too.
|
||||
int only_below_follows = !wp->w_p_wrap
|
||||
&& wlv.col + win_chartabsize(wp, ptr, wlv.vcol)
|
||||
>= wp->w_width;
|
||||
int suffix_flags = text_prop_suffix_flags[text_prop_next];
|
||||
|
||||
text_prop_follows = (suffix_flags
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
>x+0&#ffffff0@42|口*&
|
||||
|s+&|e|c|o|n|d| |l|i|n|e| @33
|
||||
|t|h|i|r|d| |l|i|n|e| @34
|
||||
|~+0#4040ff13&| @43
|
||||
|~| @43
|
||||
|~| @43
|
||||
|~| @43
|
||||
| +0#0000000&@26|1|,|1| @10|A|l@1|
|
||||
@@ -0,0 +1,8 @@
|
||||
>x+0&#ffffff0@38|>+0#4040ff13&
|
||||
|b+0#0000000&|e|t|w|e@1|n| |l|i|n|e| @27
|
||||
|x@31| @7
|
||||
|l|a|s|t| |l|i|n|e| @30
|
||||
|~+0#4040ff13&| @38
|
||||
|~| @38
|
||||
|~| @38
|
||||
| +0#0000000&@21|1|,|1| @10|A|l@1|
|
||||
@@ -3574,6 +3574,56 @@ func Test_props_with_text_after_nowrap()
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
func Test_props_with_text_after_wide_char_at_end()
|
||||
CheckScreendump
|
||||
CheckRunVimInTerminal
|
||||
|
||||
" The buffer line ends with a double-width character exactly at the window
|
||||
" width and has wrapping "after" virtual text. This must not leave blank
|
||||
" lines or "@@@", see issue #20384.
|
||||
let lines =<< trim END
|
||||
vim9script
|
||||
set nowrap
|
||||
setline(1, [repeat('x', 43) .. '口', 'second line', 'third line'])
|
||||
prop_type_add('errtype', {highlight: 'WarningMsg', text_wrap: 'wrap'})
|
||||
prop_add(1, 0, {type: 'errtype', text_padding_left: 3, text: 'E>'})
|
||||
END
|
||||
call writefile(lines, 'XscriptPropsAfterWideChar', 'D')
|
||||
let buf = RunVimInTerminal('-S XscriptPropsAfterWideChar', #{rows: 8, cols: 45})
|
||||
call VerifyScreenDump(buf, 'Test_prop_with_text_after_wide_char_1', {})
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
func Test_props_with_text_after_wide_char_overflow()
|
||||
CheckScreendump
|
||||
CheckRunVimInTerminal
|
||||
|
||||
" Like above, but the last character reaches the rightmost column without
|
||||
" starting on it: a double-width character that does not fit in the last
|
||||
" column, and a <Tab> that expands up to the window width. Both must be
|
||||
" detected as filling the line so the wrapping "after" text does not cause
|
||||
" blank lines, "@@@" or a spurious wrap with 'nowrap'.
|
||||
let lines =<< trim END
|
||||
vim9script
|
||||
set nowrap tabstop=8 noexpandtab
|
||||
setline(1, [
|
||||
repeat('x', 39) .. '口',
|
||||
'between line',
|
||||
repeat('x', 32) .. "\t",
|
||||
'last line',
|
||||
])
|
||||
prop_type_add('errtype', {highlight: 'WarningMsg', text_wrap: 'wrap'})
|
||||
prop_add(1, 0, {type: 'errtype', text_padding_left: 3, text: 'E>'})
|
||||
prop_add(3, 0, {type: 'errtype', text_padding_left: 3, text: 'E>'})
|
||||
END
|
||||
call writefile(lines, 'XscriptPropsAfterWideOverflow', 'D')
|
||||
let buf = RunVimInTerminal('-S XscriptPropsAfterWideOverflow', #{rows: 8, cols: 40})
|
||||
call VerifyScreenDump(buf, 'Test_prop_with_text_after_wide_char_2', {})
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
func Test_prop_with_text_below_cul()
|
||||
CheckScreendump
|
||||
CheckRunVimInTerminal
|
||||
|
||||
@@ -2157,4 +2157,25 @@ def Test_map_legacy_expr()
|
||||
v9.CheckDefAndScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" :call on a funcref stored in a dict member used to fail with E1017 in Vim9
|
||||
" script because get_lval() treated the subscript as a re-declaration.
|
||||
def Test_call_dict_funcref()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
var d: dict<any> = {}
|
||||
var marker = ''
|
||||
def F()
|
||||
marker = 'called'
|
||||
enddef
|
||||
d.key = F
|
||||
d['k2'] = F
|
||||
call d.key()
|
||||
assert_equal('called', marker)
|
||||
marker = ''
|
||||
call d['k2']()
|
||||
assert_equal('called', marker)
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||
|
||||
+2
-2
@@ -6273,7 +6273,7 @@ ex_delfunction(exarg_T *eap)
|
||||
int is_global = FALSE;
|
||||
|
||||
p = eap->arg;
|
||||
name = trans_function_name_ext(&p, &is_global, eap->skip, 0, &fudi,
|
||||
name = trans_function_name_ext(&p, &is_global, eap->skip, TFN_NO_DECL, &fudi,
|
||||
NULL, NULL, NULL);
|
||||
vim_free(fudi.fd_newkey);
|
||||
if (name == NULL)
|
||||
@@ -6823,7 +6823,7 @@ ex_call(exarg_T *eap)
|
||||
return;
|
||||
}
|
||||
|
||||
tofree = trans_function_name_ext(&arg, NULL, FALSE, TFN_INT,
|
||||
tofree = trans_function_name_ext(&arg, NULL, FALSE, TFN_INT | TFN_NO_DECL,
|
||||
&fudi, &partial, vim9script ? &type : NULL, &ufunc);
|
||||
if (fudi.fd_newkey != NULL)
|
||||
{
|
||||
|
||||
@@ -729,6 +729,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
572,
|
||||
/**/
|
||||
571,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user