23tux
23tux

Reputation: 14746

Insert visual vim selection in the line below at the same position

I have a tedious task of converting chords from leadsheets into an inline format.

The format I have

             G       A
Never gonna give you up
             F#m     Bm
Never gonna let you down
             G   A          F#    Bm
Never gonna run around and desert you

And the format I need would b

Never gonna g[G]ive you [A]up
Never gonna l[F#m]et you do[Bm]wn
Never gonna r[G]un a[A]round and d[F#]esert [Bm]you

The problem with a script in Ruby or Python is, that the format isn't very consistent. So there could be newlines, weird characters, sometimes the chords are seperated with a dash... I haven't looked through all of the files, but I suspect more malformed stuff.

So I thought, if I have to go through of every leadsheet by hand, at least I can save some time using vim. This is the mapping I've come up with so far:

nmap <C-X> viWc[]<ESC>PviWx<down>p

But I few things I can't figure out is:

  1. Sometimes the chords already have brackets, then I don't want to surround them with more brackets. Any idea how to only add brackets, if the chord isn't already surrounded with them?
  2. It would be cool to do this with whole lines of chords. Sometimes there are multiple chords on the same line, and selecting them one by one is tedious. Any idea on how to operate the mapping above on a whole line?

Upvotes: 2

Views: 124

Answers (1)

B.G.
B.G.

Reputation: 6036

well point 1 could be solved by adding the brackets around the chords on every second line:

:g/^/s/\[\=\zs[a-zA-Z#]\+\ze]\=/\[\0\]/g|+t+|-d

Credits: https://vi.stackexchange.com/questions/34785/search-and-replace-on-odd-even-numbered-lines-using-g

This however sucks, because it moves arround the chords, so we have to remove all brackets first and replace them with space

:%s/\[\([a-zA-Z#]\+\)\]/\1  /g

Then we can do the first line again, but remove some space too. Since there are no brackets left, it gets simpler (Note we use other brackets to get ride of some side effect the following code has):

:g/^/s/\([a-zA-Z#]\+\) \{0,3\}/\{\1\} /g|+t+|-d

Also we add a trailing whitespace at the end of the line so that the df} command will not move the cursor to a wrong place

Now that we have curly brackets everywhere, we can use reverse search with ?{ and then create a macro that jumps from results to result and moves it down, replaces the curly brackets with normal brackets and then calls itself (recursive macro):

gg0
qqq
?{<CR>
qq
df}jPr]F{r[n@qq
@q

And nearly all should be done.

The result:

                   
Never gonna g[G]ive you [A]up
                   
Never gonna l[F#m]et you dow[Bm]n
                         
Never gonna r[G]un a[A]round and d[F#]esert [Bm]you                  

Note, we have to search backwards (? instead of /) so we can delete the chords directly.

If you have problems understanding what I did, feel free to ask.

Upvotes: 1

Related Questions