3

As a simple example, let's say I want to show the line number only when :spell is set. I would assume the following would work, but does not.

%{&spell ? %l : ""}

1 Answers1

8

There are 2 ways to change the value of an option, with the :set or :let command.

:set myoption=myvalue
:setlocal mylocaloption=mylocalvalue

Or:

:let &myoption = 'myvalue'
:let &l:mylocaloption = 'mylocalvalue'

When you use the :set command, the value you assign to the option can contain characters which have a special meaning on the command-line. To avoid errors, you should tell Vim they are regular characters, by escaping them. Among these special characters, there are " (beginning of a comment), and Space (separation between 2 option names).

To get back to your issue, you want to display the current line number. I don't think you can use the item %l inside the curly braces, because inside them Vim expects an expression, and %l is not an expression. However, it can be retrieved with the line() function: line('.').

So, to show the current line number in the status line, only when 'spell' is enabled, you could write:

set stl+=%{&spell\ ?\ line(\".\")\ :\ \"\"}

But the backslashes make the expression difficult to read, so you could avoid using spaces and double quotes:

set stl+=%{&spell?line('.'):''}

Or you can use the :let command:

let &stl .= '%{&spell ? line(".") : ""}'

This time, you don't need to escape anything. But to add this value to the 'statusline' option, you have to use the .= operator instead of +=, because you're concatenating strings.


As your last comment says it, with these syntaxes, you lose the ability to include '%' items inside the expression in the curly braces.

In this case, you could consider another syntax, described in :h 'stl:

When the option starts with "%!" then it is used as an expression,
evaluated and the result is used as the option value.  Example: >
    :set statusline=%!MyStatusLine()
The result can contain %{} items that will be evaluated too.

So, maybe you could add something like this in your vimrc:

set statusline=%!MyStatusLine()

fu! MyStatusLine() abort
    if &spell
        " return the items when `'spell'` is enabled
        return '%P %m %l'
    else
        " return the items when `'spell'` is disabled
        return '%P %m'
    endif
endfu

Or shorter:

set statusline=%!MyStatusLine()
fu! MyStatusLine() abort
    return '%P %m ' . (&spell ? '%l ' : '')
endfu
user9433424
  • 6,138
  • 2
  • 21
  • 30
  • Thank you so much. Honestly, I was looking for something that would allow me to use any of the statusline flags, %P, %m, or even colors like %1*. – Oliver Taylor Dec 01 '16 at 02:15