patch 9.2.0538: Cannot keep leading whitespace in %{} statusline expr

Problem:  A leading space in the result of a %{} item is sometimes
          stripped, and an all-digit result is converted to a number.
Solution: Add %0{} atom which inserts the expression result verbatim
          (glepnir)

fixes:  #3898
closes: #20315

Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
glepnir
2026-05-25 17:30:22 +00:00
committed by Christian Brabandt
parent c175ce86fa
commit e8d7a40b98
6 changed files with 22 additions and 3 deletions
+4 -1
View File
@@ -8670,7 +8670,8 @@ A jump table for the options with a short description can be found at |Q_op|.
{ NF Evaluate expression between '%{' and '}' and substitute result.
Note that there is no '%' before the closing '}'. The
expression cannot contain a '}' character, call a function to
work around that. See |stl-%{| below.
work around that. See |stl-%{| below. Use '%0{' to insert the
result verbatim.
{% - This is almost same as { except the result of the expression is
re-evaluated as a statusline format string. Thus if the
return value of expr contains % items they will get expanded.
@@ -8797,6 +8798,8 @@ A jump table for the options with a short description can be found at |Q_op|.
A result of all digits is regarded a number for display purposes.
Otherwise the result is taken as flag text and applied to the rules
described above.
*stl-%0{*
With %0{ neither applies: the result is inserted as a literal string.
Watch out for errors in expressions. They may render Vim unusable!
If you are stuck, hold down ':' or 'Q' to get a prompt, then quit and
+1
View File
@@ -10562,6 +10562,7 @@ static-tag tagsrch.txt /*static-tag*
status-line windows.txt /*status-line*
statusmsg-variable eval.txt /*statusmsg-variable*
stl-%! options.txt /*stl-%!*
stl-%0{ options.txt /*stl-%0{*
stl-%@ options.txt /*stl-%@*
stl-%[FuncName] options.txt /*stl-%[FuncName]*
stl-%{ options.txt /*stl-%{*
+2
View File
@@ -52640,6 +52640,8 @@ Other ~
well.
- New argument handling for user commands |:command-nargs| using the "-nars=_"
attribute to handle completion of single arguments with spaces as expected.
- Support %0{} in 'statusline' to insert the expression result verbatim and
not drop leading spaces |stl-%0{|.
Platform specific ~
-----------------
+3 -2
View File
@@ -5041,7 +5041,8 @@ build_stl_str_hl_local(
if (reevaluate)
s++;
itemisflag = TRUE;
// %0{} keeps the result verbatim
itemisflag = zeropad ? FALSE : TRUE;
t = p;
while ((*s != '}' || (reevaluate && s[-1] != '%'))
&& *s != NUL && p + 1 < out + outlen)
@@ -5078,7 +5079,7 @@ build_stl_str_hl_local(
do_unlet((char_u *)"g:actual_curbuf", TRUE);
do_unlet((char_u *)"g:actual_curwin", TRUE);
if (str != NULL && *str != NUL)
if (!zeropad && str != NULL && *str != NUL)
{
if (*skipdigits(str) == NUL)
{
+10
View File
@@ -282,6 +282,16 @@ func Test_statusline()
call assert_match('^vimLineComment\s*$', s:get_statusline())
syntax off
" %0{: result of expression is inserted verbatim
set statusline=%{'\ x'}
call assert_match('^x\s*$', s:get_statusline())
set statusline=%0{'\ x'}
call assert_match('^ x\s*$', s:get_statusline())
set statusline=%{'000'}
call assert_match('^0\s*$', s:get_statusline())
set statusline=%0{'000'}
call assert_match('^000\s*$', s:get_statusline())
"%{%expr%}: evaluates expressions present in result of expr
func! Inner_eval()
return '%n some other text'
+2
View File
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
538,
/**/
537,
/**/