mochsner
mochsner

Reputation: 325

Multi-line edit starting at the same character (= sign) [no macros?]

I'm working on an ansible playbook, where VIm seems to prove to be an extremely useful tool for (lots of similar patterns in style/formatting and such), and I'm hoping to take my current situation (since been written) to turn it into a Vim lesson.

I've made extensive use of code blocks to make multi-line edits, but I think I've reached their limit and wanted to reach out to figure out how I might approach making line edits more dynamically. In this scenario, I have a block of code that I'm trying to transform

from:

rcon.port=25575
rcon.password=strong-password
enable-rcon=true

into:

- { regexp: '^rcon.port', line: 'rcon.port=25575' }
- { regexp: '^rcon.password', line: 'rcon.password=strong-password' }
- { regexp: '^enable-rcon', line: 'enable-rcon=true' }

To do that, the first part is fairly simple. Shift-I, then ctrl-V for block, traverse lines to edit, type - { regexp: '^" to get to the following:

- { regexp: '^rcon.port=25575
- { regexp: '^rcon.password=strong-password
- { regexp: '^enable-rcon=true

Unfortunately, from there I'm a bit lost as the macros (and whether or not that's overkill or not) are still a bit unclear to me. Are there any possible approaches to solve this problem other than macros?

I'm not looking for a full solution, but simply a hint for the best (or only approach) here, and if there are any tricks to thinking about this in the Vim way.

Any links to good documentation/learning resources for macros would be AWESOME as well! I'm still new to Vim, so bear with me... thanks!

Upvotes: 1

Views: 68

Answers (2)

110100100
110100100

Reputation: 199

Building off @Stephen Warren's answer the following works as required:

:%s/^\(\(.\+\)=.\+\)/- regex: '\2', line: '\1' }/

The match section is:

  • From the beginning of the line ^

  • It has two groups rather than one \(\)

    • The first group is the outer one that matches the entire line

    • The second group is the inner group that matches up to the =

  • Match one or more characters \+ is used rather than the greedy * for matching either side of the =

The replace section:

  • Basically your expected output calling on the previously matched groups \1 and \2

Upvotes: 3

Stephen Warren
Stephen Warren

Reputation: 279

Perhaps something like the following regular expression substitutions:

:%s/^\(.*\)$/- { regexp: '^\1' }/

Or with all relevant lines visually selected:

CTRL-o

:s/^\(.*\)$/- { regexp: '^\1' }/

I guess I should explain that a bit more:

: Enter command mode.

% Apply to all lines.

s Substitute.

/xxx/yyy/ Replace xxx with yyy.

^ Anchor at start of input string

(xxx) (in match string) capture whatever matches xxx.

\1 (in replacement string) replace with whatever matched (xxx).

.* Match any amount of any characters.

$ Anchor at end of input string.

Replacement string is emitted into the result literally without any interpretation, except for stuff like \1.

Upvotes: 2

Related Questions