1

In vim I sometimes want to quickly change the content of a variable using its current content as template using vim editing capabilities.

For example I want to append the word "bar" to the existing variable myvar.

let myvar="foo"

A possible workflow could be a ex-command (say Edit) editing myvar in a new buffer with "foo" as its contend and upon saving the buffer it would overwrite the new content (i.e. "foo bar") to the variable:

:Edit myvar

I feel there must be an elegant solution, possibly even another workflow than the one outlined above.

2 Answers 2

7

You've picked an unfortunate example, as it's more easily achieved with:

let myvar .= 'bar'

Still, for more complicated edits, you could use the following commands:

  1. Insert the variable into the buffer:

    o<C-R>=myvar<CR>
    

    N.B. In the above, <C-R> denotes a press of Ctrl-R, and <CR> is a press of Return.

  2. Perform your edits.

  3. Reassign the contents of the line to the variable and delete the line:

    :let myvar = getline('.') | d
    

Steps 1 & 3 can be converted into mappings:

:nnoremap <expr> <leader>ev "o\<C-R>=" . input('Variable: ', 'myvar', 'var') . "\<CR>"
:nnoremap <expr> <leader>av ':let ' . input('Variable: ', 'myvar', 'var') . " = getline('.') <bar> d\<CR>"

These prompt the user for which variable they want to edit/assign to, offering a default of myvar, and using variable completion so you don't have to type out the whole variable name.

If you always want to edit myvar, you can just replace the call to input() with myvar. If you only want to be asked in the first mapping, then you could save the name of the variable selected in a variable and use that in the second mapping: at that point you'd probably be better off using a mapping that calls a function instead of attempting to cram it into a one-liner.

Creating a more polished, complete solution as described in the question is left as an exercise to the reader. You'd probably want to set up a function to create the new buffer and insert the contents of the variable, and a BufWriteCmd autocommand to intercept the saving of that buffer (and only that buffer) and instead reassign to the variable.

Further reading:

  • :help i_CTRL-R_=
  • :help getline()
  • :help :d
  • :help :map-expr
  • :help input()
  • :help :command-completion
  • :help :function
  • :help autocommand
  • :help Cmd-event
1
  • I've accepted this solutions since extensively elaborated, adaptable and doesn't require a plugin (which I prefer). I agree, the example was somewhat unfortunate. Commented May 1, 2018 at 5:10
2

The plugin editvar does this. Just use :Editvar myvar, where myvar is a variable. This opens a window with the variable's contents. You can type :w to update the variable value.

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.