vimtricks.wiki Concise Vim tricks, one at a time.

How do I define a multi-line string in Vimscript without concatenation or escape sequences?

Answer

let {var} =<< {marker}

Explanation

Vim 8.1 introduced a heredoc syntax for Vimscript that lets you assign multi-line text to a variable using a delimiter marker — no \n concatenation or awkward escape sequences required. The result is a List of strings, one per line.

How it works

let template =<< END
hello world
foo bar
END
  • =<< is the heredoc operator
  • Everything between the marker lines (here END) becomes a list item per line
  • The closing marker must appear at the very start of a line with no leading whitespace
  • The marker name can be any word (e.g., EOF, TEXT, HEREDOC)
  • The resulting variable is a List, so template[0] is 'hello world'

Example

Join and execute a multi-line Ex script without string concatenation:

let cmds =<< EOF
setlocal noexpandtab
setlocal tabstop=4
retab!
EOF
execute join(cmds, "\n")

Or pass JSON to a processing function without painful quoting:

let payload =<< JSON
{"name": "vim", "version": 9}
JSON
let data = json_decode(join(payload, ''))
echo data.name

Tips

  • Use =<< trim END to strip leading whitespace from each line (Vim 8.1.1744+), allowing indented heredocs in functions
  • In Neovim Lua, use a Lua string literal ([[...]]) instead for the same effect
  • Vim9 script supports the same syntax
  • Requires Vim 8.1+; check with :echo has('patch-8.1.0051')

Next

How do I enable matchit so % jumps between if/else/end style pairs?