functionvimescapingstatusline

Function eats my space characters


I wrote a function

function! BrickWrap(data, icon_align, icon_left, icon_right)
    if empty(a:data)
        return ''
    endif

    let l:brick = (a:icon_align ==# 'left') ? a:icon_left . a:data :
                \ (a:icon_align ==# 'right') ? a:data . a:icon_right :
                \ (a:icon_align ==# 'surround') ? a:icon_left . a:data . a:icon_right :
                \ (a:icon_align ==# 'none') ? a:data :
                \ ''

    if empty(l:brick)
        echom 'BrickWrap(): Argument "icon_align" must be "left", "right", "surround" or "none".'
        return ''
    endif

    return l:brick
endfunction

in order to format some data which gets displayed inside my statusline, e.g.:

set statusline+=%#User2#%{BrickWrap('some_data','surround','\ ','\ ')}

The example above should wrap the data with a space character on each side. But what happens actually is that it only appends a space character to the right but not to the left. In order get a space character displayed to the left I have to pass two escaped space characters ('\ \ '). I have to mention that it only happens in the statusline. If I'd :call the function it works as expected. Why does this happen?


Solution

  • To use backslashes and whitespace with :set, you need additional escaping, see :help option-backslash. So, your backslash in front of the space is already taken by the :set command. (You can check this via :set stl?)

    If coming up with the correct escaping is too hard, an alternative is to use the :let command instead:

    :let &statusline = '...'
    

    However, then you must only use double quotes in your statusline value, or deal with the quote-within-quote escaping then.