I am trying to write my (first) function which is (eventually to be) a toggle on my colorscheme. What I have now is as follows:

nnoremap <expr> <leader>3 ToggleColors()
func ToggleColors()
    let x = ":colorscheme"
    echom '111' + x
    x = x += "TextMate"
    echom '222' + x
    return x

Here is what I am trying to do:

  • Set a variable x to be the string :colorscheme
  • Print it, which should give me the output message 111 :colorscheme
  • Append to the variable x, so now it should be :colorscheme TextMate
  • Print it again, so now it should print 222: colorscheme

However, it seems like the echom '111' + x only prints 111, and the string-concatenation is giving me an error.

What would be the proper way to write this? Finally, is there any way to debug functions in vim? Or do you just have to check messages? All the error messages (stacktraces) I get give almost zero information...less than even SQL would.

1 Answer 1


String concatination in Vim is done with a . (dot).


func ToggleColor()
    let x = ":colorscheme"
    echom '111' . x
    let x .= " TextMate"
    echom '222' . x
    return x

In your scenario I would not use map-expression. (Guess you want to use a function, because you are learning Vim)

nnoremap <leader>3 :call ToggleColors()<cr>
function ToggleColors()
    let x = "colorscheme"
    let x .= " TextMate"
    call execute(x)

And the simplest solution would be:

nnoremap <leader>3 :colorscheme TextMate<cr>

When to use a map-expression?

Normally a mapping is fixed. Like

nnoremap A  B

So whenever you type A you will get B.

With a map-expression you are able to create a dynamic mapping.

This (useless) mapping maps A to either 0 or $.

:nnoremap <expr> A col('.') == 1?'$':'0'

If you hit A and the cursor is in the first column, you will jump to end of line. In all other scenarios the cursor jumps to the first column.

Instead of doing it on one line, you could also do it in a function:

nnoremap <expr> A  JumpAround()
function JumpAround()
    if col('.') == 1
        return '$'
        return '0'

Note that there are limitations what you can do in a function called from a map-expression. See :h map-expression.

  • thanks for this. A few questions: (1) are you able to do func () without a function name, or that's just for an example? (2) why do you call execute at the end instead of return?
    – David542
    Jun 13, 2020 at 5:03
  • Finally, (3) In your scenario I would not use map-expression -- why would you use the :call over using the <expr>? When would you ever want to use <expr> then?
    – David542
    Jun 13, 2020 at 5:08
  • 1
    @David542 (1) Typo - fixed (2) The execute just executes the string content. (3) see update
    – Ralf
    Jun 13, 2020 at 6:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.