# Multiple or divide number under cursor with given amount and replace it with the result

I can increment the number under the cursor (by e.g. 10) by doing

10`<C-a>`

But how do I multiply the number under the cursor with x amount and the replace it in the same way I do when incrementing by a constant amount?

There's no magic, single operation for arithmetic. You can use substitution with sub-replace expression. This will replace all numbers on the current line with their value multiplied by 5.

``````s/\d\+/\=submatch(0)*5/
``````

The `\=` operator tells Vim to treat everything that follows as an expression, evaluate it, and use the result as the replacement of the final matched text. And when `submatch(0)` is evaluated it returns whatever the pattern on the left matched. I'm multiplying that by 5, as I mentioned.

Tune the pattern part as needed for your particular situation. I'm matching any numbers but you could just put `10` there though that's not particularly useful for general needs. If there are other things on the line that you want to ignore you could use `\zs` and `\ze` to isolate a number. This one will only effect a number that follows a colon at the beginning of the line:

``````s/^:\zs\d\+\ze/\=submatch(0)*5/
``````

Rather than describe in detail how sub-replace expressions generally work in this space you can look at my answer here: How to run a substitute command on only a certain part of the line

• Dont you need a string to number conversion on submatch? Or are you relying on implicit coercions? Feb 25, 2021 at 15:31
• I am converting. Somewhere in the docs there are instructions on how to convert a string to a number. Something like `"100" + 0 => 100`, i.e. arithmetic is pretty explicit conversion. Feb 25, 2021 at 15:57

You could use the following to reimplement a mechanism similar to `<c-a>` but for multiplication:

``````function! MultiplyInPlace(count) abort
" Get the word under the cursor
let current_word = expand('<cword>')

" If we don't match a number return
if (current_word !~ '\d\+')
return
endif

" Get cursor position
let col = getcurpos()

" Calculate the result and replace in buffer
let res = current_word * a:count
execute 's/\%' . col . 'c' . current_word . '/' . res

" Move back to the number we changed
normal! g``
endfunction

" Use [count]<leader><c-x> to multiply number under cursor by [count]
``````

The idea is to create a function `MultiplyInPlace()` which takes a count as argument. The function will use `:h <cword>` to get the word under the cursor and match it against `/\d\+/` to make sure it's a number (`:h expr-=~`).

If it's a number a simple multiplication is done and we use a substitute command forged with `execute` to do the replacement. (`:h :execute`).

In the substitute command get use the `:h /\%c` atom to match the current column of the cursor to avoid the bug described by @Benji in their comment on this answer.

The last line is needed to avoid the cursor jumping at the beginning of the line. (`:h g``)

Then you can create a normal mode mapping (here `<leader><c-x>`) which will take a count and call the function with it (and use 1) if no count is provided. (`:h v:count`)

You can then adapt the code pretty simply to also handle the divisions (either create a second function `DivideInPlace()` or add a new argument to `MultiplyInPlace()` to switch between behaviors).

• There is a bug in the above. Because of the way `s` is used to replace the word, if there are two of the same numbers on the line, the first will be replaced even if the cursor is over the second. Feb 5, 2022 at 14:16
• That's true thanks @BenjiYork for pointing that out. I edited my answer: By using `getcurpos()` to get the column where the cursor is and using `/\%c` in the pattern I think the bug is fixed. Feb 7, 2022 at 12:54