I am trying to write my first vim macro. The goal is to map a line containing a keyword to google doc string format.
So the input is:
'keyword' : value,
and desired output would be:
keyword (value) :
So I assume the easiest way would be to define a macro.
In console mode I used wdwwD
from the beginning of the line to successfully delete everything around my keyword.
But binding it to a macro (with additionally adding j0
to get a new line) yields the following output : keyword' : value
I've also tried f'r f'Dj0
but it resulted in the same output.
So it seems like I am doing something wrong but repeating the sequence yields my desired output, but not binding it to a macro even though thats what it supposed to do, right?
My example is
Battery_config = {
'charging_efficiency' : 0.8,
'discharging_efficiency' : 0.99,
'hourly_self_discharge': 0.005
}
So I assume the easiest way would be to define a macro
You mean normal mode sequence. But there's a problem: your line may or may not end with "comma". So at first it's tempting to do something like this:
nnoremap <Leader>d ^"ayi'$"byBS<C-R>a<Space>(<C-R>b)<Space>:<Esc>
Explanation:
^
--- go to the first non-blank char"ayi'
--- yank keyword into reg 'a' (yank inside quotes)$
--- go to the end of line"byB
--- yank value into reg 'b' (yank WORD backward)S
--- clear line and switch into insert mode (also needs set autoindent
to preserve line indent)<C-R>a (<C-R>b) :
--- finally type keyword (value) :
<Esc>
--- get back to normal modeHowever, it fails on 'hourly_self_discharge': 0.005
and it's not so easy to fix it (well, of course, you can do ^"ayi'$"byiW:let @b=trim(@b,',')<CR>S<C-R>a<Space>(<C-R>b)<Space>:<Esc>
, but it's even uglier than before).
Another point is that we'd like to be able to work over an arbitrary visual selection without corrupting other data. So it seems much more profitable to go with regexps in Ex mode:
noremap <Leader>d :s/\v'(\w+)'\s*:\s*([0-9.-]+),?/\1 (\2) :/<CR>
Explanation:
noremap ...
--- now it should work both in normal and visual mode without any effort!:s/\v.../.../<CR>
--- substitute using 'very magic' mode'(\w+)'
--- capture the keyword into the 1st submatch\s*:\s*
--- match colon with optional space around([0-9.-]+)
--- (hopefully) capture the value into the 2nd submatch,?
--- optional comma\1 (\2) :
--- compose output string from submatchesNow try ggVG<Leader>d
to process the whole file at once.