+++ title = "Vim: Expressions in replacement text" date = "2020-06-14" author = "Ceda EI" tags = ["vim", "neovim", "replacements"] keywords = ["vim", "neovim", "replacements"] description = "Modifying the selection in a :s[ubstitute]// command" showFullContent = false +++ Often times I find myself needing to modify the selection in a substitute command in a non-trivial way. From a recent example, I needed to convert the numbers in the `id` of the `div`s to hexadecimal after decrementing them by 1. Basically, I had to convert ```html
...
...
...
...
...
...
``` to ```html
...
...
...
...
...
...
``` Doing this manually is tiring, I could have used macros but I instead chose an even simpler approach. Vim allows to use expressions in the replacement part of the substitute command if it starts with `\=`. So, the replacement can be simply done using `\=` and `printf`. What I did was simply use the following command after selecting the text in a visual selection. `:'<,'>s/\v(someprefix)(\d+)/\=printf("%s%X", submatch(1), submatch(2) - 1)` The breakdown is as follows: - `:'<,'>`: Sets the range to visual selection. - `s/`: Starts the substitution. - `\v`: Enables "very magic mode". This allows for writing simpler regular expressions without having to escape special characters. - `(someprefix)(\d+)`: Captures the string `someprefix` in group 1 and the number that follows in group 2. - `/`: Ends the search and starts replacement. - `\=`: Tells Vim to treat the following text as an expression. - `printf(`: `printf` is a function that takes a format string and values for the format parameters. - `"%s%X"`: The format string. `%s` means to print the parameter as a string. `%X` means to convert the parameter to a hexadecimal number in capital letters (`%x` for small). - `submatch(1)`: It retrieves the first matched group. - `submatch(2) - 1`: It retrieves the second matched group and subtracts one from it. ### References - `:help sub-replace-expression` - `:help submatch` - `:help printf` - `:help /magic` - `:help :s`