vim join lines for matching brackets

vim

Solution

My take:

 qqqqqv%:join
 j@qq@q

Using `join` instead of `J` solves the problem of single lines in Daan's answer.

Step by step:

- `qqq` to clear the 'q' macro (to avoid getting tangled with previous macro definitions)

- `q` to start recording

- `q` to state that it's the 'q' macro we're recording

- `v` for visual marking

- `%` to jump to matching brace

- `:` for command mode, acting on currently marked area

- `join` (plus ENTER) for joining the lines

- `j` to go down one line

- `@q` to call 'q' macro (recursion) (if we hadn't cleared it first, we'd be calling the old definition here, which is not what we want)

- `q` to end recording

- `@q` to execute the macro, which will stop at end-of-file (when the `j` move errors)

Excuse the abundance of `q`'s. I admit putting this on `j` would be more intuitive, but I always use `q` for fire-and-forget macros like this, because it makes the initial clear-and-record (`qqqqq`) so easy to remember (and because most other keys already have macros on them). :-)

Edit: Scratch that last paragraph. I just like hammering at the same key repeatedly like a madman. ;-)

Problem

I have a tool which produces output like this - ``` (check (= Start (+ (if (<= takeA giveA) 0 1) (if (<= takeB giveB) 0 1) (if (<= takeC giveC) 0 1) (if (<= takeD giveD) 0 1)))) (check (and (>= takenBefore_A 0) (<= takenBefore_A 4))) (check (and (>= givenBefore_A 0) (<= givenBefore_A 4))) (check (= risk_A (+ Start 1 (- takenBefore_A givenBefore_A)))) (check (= takenBefore_A (+ (if (<= takeB takeA) 1 0) (if (<= takeC takeA) 1 0) (if (<= takeD takeA) 1 0)))) (check (= givenBefore_A (+ (if (<= giveA takeA) 1 0) (if (<= giveB takeA) 1 0) (if (<= giveC takeA) 1 0) (if (<= giveD takeA) 1 0)))) (check (and (>= takenBefore_B 0) (<= takenBefore_B 4))) (check (and (>= givenBefore_B 0) (<= givenBefore_B 4))) (check (= risk_B (+ Start 1 (- takenBefore_B givenBefore_B)))) (check (= takenBefore_B (+ (if (<= takeA takeB) 1 0) (if (<= takeC takeB) 1 0) (if (<= takeD takeB) 1 0)))) (check (= givenBefore_B (+ (if (<= giveA takeB) 1 0) (if (<= giveB takeB) 1 0) (if (<= giveC takeB) 1 0) (if (<= giveD takeB) 1 0)))) (check (and (>= takenBefore_C 0) (<= takenBefore_C 4))) (check (and (>= givenBefore_C 0) (<= givenBefore_C 4))) (check (= risk_C (+ Start 1 (- takenBefore_C givenBefore_C)))) ``` And I would like to have the output like this - ``` (check (= Start (+ (if (<= takeA giveA) 0 1) (if (<= takeB giveB) 0 1) (if (<= takeC giveC) 0 1) (if (<= takeD giveD) 0 1)))) (check (and (>= takenBefore_A 0) (<= takenBefore_A 4))) (check (and (>= givenBefore_A 0) (<= givenBefore_A 4))) (check (= risk_A (+ Start 1 (- takenBefore_A givenBefore_A)))) (check (= takenBefore_A (+ (if (<= takeB takeA) 1 0) (if (<= takeC takeA) 1 0) (if (<= takeD takeA) 1 0)))) (check (= givenBefore_A (+ (if (<= giveA takeA) 1 0) (if (<= giveB takeA) 1 0) (if (<= giveC takeA) 1 0) (if (<= giveD takeA) 1 0)))) (check (and (>= takenBefore_B 0) (<= takenBefore_B 4))) (check (and (>= givenBefore_B 0) (<= givenBefore_B 4))) (check (= risk_B (+ Start 1 (- takenBefore_B givenBefore_B)))) (check (= takenBefore_B (+ (if (<= takeA takeB) 1 0) (if (<= takeC takeB) 1 0) (if (<= takeD takeB) 1 0)))) (check (= givenBefore_B (+ (if (<= giveA takeB) 1 0) (if (<= giveB takeB) 1 0) (if (<= giveC takeB) 1 0) (if (<= giveD takeB) 1 0)))) (check (and (>= takenBefore_C 0) (<= takenBefore_C 4))) (check (and (>= givenBefore_C 0) (<= givenBefore_C 4))) (check (= risk_C (+ Start 1 (- takenBefore_C givenBefore_C)))) ``` I used the following command in `VIM` to produce the necessary output, depending on how many lines I want to join - ``` :.,+3join ``` I am wondering, if I can automatically do this rather than doing it manually. The keypoint here is that, on each line the number of brackets opened will be equal to number of brackets closed.

Original source