I'm trying to write what I thought would be a simple macro to take some values that have been yanked into some registers (a & b) and use bc to do some addition with those values.

Here is the expression/part I'm stuck on...

:let @c=trim(system("echo '@a + @b' | bc"))

if I replace those @a and @b references with the register contents manually then the expression/command works as expected.

Any idea what I'm missing here?


By putting @a and @b inside the quotes you're preventing Vim from evaluating them so you're really just passing the literal strings "@a" and "@b".

Pull them out of the quotes and build a Vim string using the concatenation operator...

:let @c=trim(system("echo '" . @a . " + " . @b . "' | bc"))

So if @a and @b contain, for example, 2 and 3, respectively, then you're passing the string

echo '2 + 3' | bc

to the system() function as you intended.

Alternatively, you can use printf() to build the string:

:let @c=trim(system(printf("echo '%s + %s' | bc", @a, @b)))

A lot of people prefer this to having a bunch of concat operators.

In both cases @a and @b are exposed so they get evaluated as Vim expressions and, thus, resolve to the contained values.

  • Thanks for answer, worked a charm! I'd tried a similar expression earlier, but was using the wrong concatenation operator, +'s instead of the .'s
    – cewood
    Oct 27 at 15:37
  • 2
    Aha! You're not the first to do that, I'm sure. :) Check out the update. printf() is considered nicer by many. It works similarly to printf in shells and programming languages.
    – B Layer
    Oct 27 at 15:39

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.