When working with Jinja templates and YAML for Ansible configuration, I often copy+paste a variable name (say, nginx_root
) and then need to wrap it in double curly braces: {{ nginx_root }}
. This gets cumbersome to do manually, so I want to be able to type a Vim key binding to wrap the current word under the cursor in double curly braces.
Using the vim-surround plugin, I can add the desired curly braces to the word under the cursor via ysiw}lysiw{
, but that is many more key strokes than I would prefer. I have tried the following Vim key binding, but invoking it in normal mode has no visible effect at all:
" Wrap text under cursor with double curly braces (e.g., for Jinja variables)
nnoremap <C-J> ysiw}lysiw{
Ergo, my questions are:
Using stock Vim functionality, the vim-surround plugin, and/or any other combination of tooling, how can one bind a key that will wrap the current word under the cursor with space-padded double curly braces? e.g., nginx_root
→ {{ nginx_root }}
Is there a way to also achieve this in insert mode, with the cursor just to the right of the word? (nginx_root*
, where *
is the cursor position)
How would one bind a key (preferably available in both normal and insert modes) to insert {{ * }}
at the current cursor position, where *
is the position of the cursor after insertion? (This would facilitate entering new Jinja variables, versus operating on copy+pasted variables as noted above.)
Your mapping does not work because it uses :noremap
. It is correct to avoid remapping (via the nore
part of the command) as much as possible, but as you're invoking surround.vim's ys
mapping in there, there's no (easy) way around it:
nmap <C-J> ysiw}lysiw{
That double surrounding is awkward, and actually not necessary, because the plugin allows to define custom replacements, as per :help surround-customizing
.
The following defines a new replacement on d
(for "double"; 100 = char2nr('d')
); with it, you can add double curlies to a word via ysiwd
:
let g:surround_100 = "{{ \r }}"
To only define the mapping for certain filetype(s), replace the g:
with b:
. I would recommend putting this then into ~/.vim/ftplugin/{filetype}_whatever.vim
(or {filetype}/whatever.vim
; cp. :help ftplugin-name
) instead of defining lots of :autocmd FileType {filetype} ...
; it's cleaner and scales better; requires that you have :filetype plugin on
, though.
The surround.vim plugin also offers an insert mode <C-g>s
mapping. I would recommend against insert mode mappings for these kinds of edits; it's against Vim's mode-based model, and only few (and awkward key combinations with Ctrl or Alt) keys are available there.
To insert a template, a simple mapping will do. You can position the cursor in between the added curlies via the special <Left>
keys:
:nnoremap <C-g>d a{{ }}<Left><Left><Left>
:inoremap <C-g>d {{ }}<Left><Left><Left>