1

This question is really two questions.

First question: Does vimscript support having interpolated strings as values in a dictionary?

Second question: Is it possible to remap keys from within a loop? While items is an obvious choice (to me) for creating the loop, I'm open to other loops if they allow this.

" attempted code:
let path_dict = {
  \'o.': './',
  \'o/': "$p_root",
  \'oc': "$p_css",
  \'oh': "$p_html",
  \'oj': "$p_js",
  \'ol': "$p_learn",
  \}

for [keybinding, filepath] in items(path_dict)
  nnoremap <Leader>keybinding :call Notrw(filepath)<CR>
endfor

" desired result:
" nnoremap <Leader>o/ :call Notrw($p_root)<CR>
" nnoremap <Leader>oh :call Notrw($p_html)<CR>
" nnoremap <Leader>oc :call Notrw($p_css)<CR>
" nnoremap <Leader>oj :call Notrw($p_js)<CR>
" nnoremap <Leader>ol :call Notrw($p_learn)<CR>
" nnoremap <Leader>o. :call Notrw('./')<CR>
  • 1
    The question was a joke but this answer by Carpetsmoker shows a way to create mappings in a loop. The trick is to use execute. (We may have another question with mappings in a loops but I can't find it right now) – statox Jan 9 '18 at 13:48
  • for interpolating variables into commands use the :exe command and you can of course create mappings in a loop. – Christian Brabandt Jan 9 '18 at 13:53
3

Does vimscript support having interpolated strings as values in a dictionary?

No, but you can have (nearly) arbitrary expressions within dictionary values:

let a = {
    \ 'goodbye': variable,
    \ 'world': $ENVVAR,
    \ 'hello': printf('%d', 10),
    \}

Is it possible to remap keys from within a loop? While items is an obvious choice (to me) for creating the loop, I'm open to other loops if they allow this.

Using execute it is possible to do anything in a loop. Any command sequence which can be uttered in a script can be wrapped in a string and executed (possibly up to minor syntax changes). For instance,

for [keybinding, filepath] in items(path_dict)
    execute 'nnoremap <Leader>'.keybinding ':call Notrw('.filepath.')'
endfor

Note that execute inserts spaces between successive arguments (such as between keybinding and ':call). To suppress this you must concatenate the strings using .. An alternative to concatenation is to use printf. Note that since execute is effectively what is called eval in other languages, standard string validation security warnings apply.

There are two cases where vim allows true "interpolation."

1) In unix/linux (at least), and only in filename arguments, you may use backticks to supply filename(s) as a result of an external command

:next `find . -name ver\\*.c -print`

Escaping can be difficult.

2) In variable names only, you can use another variable (see :h curly-braces-names) interpolated into the name. For example,

my_{adjective}_variable
echo my_{&background}_message

refer to the interpolated variable as you'd expect, e.g., my_blue_variable, or my_dark_message.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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