I'm working with a YAML file that has an integer as ID which appears every 4-6 lines. I'm looking to add a record in the middle of this file (for readability) that keeps the sequential numbering intact.
File format below. Any ideas?
- id: 1
type: string
option: diff_string
other: alt_string // note: 'other' option does not appear for all records
- id: 2
type: string
option: diff_string
//new record would go here as id: 3, increasing id: # of all following records by 1
- id: 3
type: string
option: diff_string
other: alt_string
I believe you can achieve what you want with setting a counter (here: variable g:I
) to 1:
let g:I=1
And then execute a substitution on each line that matches ^- id: \d\+$
:
%g/^- id: \d\+$/ s/\d\+/\=g:I/|let g:I=g:I+1
The substition uses the \=
thingy (see :help sub-replace-expression
) to substitue \d\+
with the actual value of g:I
. After the substition, the counter is incremented (let g:I=g:I+1
).
With the g/^- id: \d\+$/
you ensure that the substition is only performed on lines matching ^- id: \d\+
.
Edit If you want to have a map for it, you can place the following snippet into your .vimrc:
nnoremap resync :let g:I=1<CR>:%g/^- id: \d\+$/ s/\d\+/\=g:I/\|let g:I=g:I+1<CR>
which allows to resync your ids by typing resync
in normal mode.
Note the escaping of the |
with the \
and the use of <CR>
where you would press enter.
in order to increment all subsequent ids from cursor line + 1:
:.+1,$g/^- id: \d\+$/exec 'normal! 0' . nr2char(1)
(nr2char(1)
is like keying CTRL-A in).
You can also do:
:.+1,$g/^- id: \d\+$/normal! 0^A
Where you enter ^A
typing CTRL-V then CTRL-A. Note that I prefer the first version: you can copy-paste it around, there is no literal control character in the code.
Detail:
.+1,$
is the range from next line till end of file. :help range
.:g
command operates on all lines obeying to a pattern. The opposite is :v
. :help :g
/^- id: \d\+$/
matches - id:
at the start of a line, followed by 1 or more digits and then end of line (:help pattern
):normal!
plays normal commands: 0 to go to start of line, CTRL-A to increment next number.If you want a mapping:
nnoremap <F1> :.+1,$g/^- id: \d\+$/exec 'normal! 0' . nr2char(1)<enter>
Put that in your vimrc, and now enjoy pressing F1 in normal mode, and watch all ids below cursor line incrementing.
I would use the following short and straightforward substitution command.
:,$s/^- id: \zs\d\+/\=submatch(0)+1/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With