r/vim•
vesech

Delete a surrounding conditional/loop?

I don't suppose there is a fancy solution I'm missing for deleting a conditional/loop surrounding a block of code?

It's happened enough times to be annoying that I'd like to lose the conditional or loop around a block of code and reindent the block accordingly. For example, using PHP as an example here:-

class SomeClass {
    function __construct($nah, $alright) {
        foreach ($someArray as $value) {
            if (true) {
                echo "hello!";
            }
        }
    }
}

If my cursor was on the 'e' of echo, it'd delete the if (true) conditional around it. Similarly, if my cursor was on the 'i' of the if (true) statement, it'd remove the loop and re-indent the code in kind.

So far, I've managed to hack something together with vim-indent-object that defines mappings for indentation text objects which are great (check out the documentation). Combined with the following macro:-

map dsb VaImk$%dkV`kj<`kdd

This kind of does what I'm after, just wondered if there was something out there a little more robust. The command above broken down a bit:-

  • VaI - Visual select everything in the current indentation level (thanks to the vim-indent-object plugin above), including the lines above
  • mk - Mark the top line of our selection (the conditional) as mark k
  • $%d - Jump to the closing brace of the conditional, and delete it
  • kV`kj - Move up a line and visual highlight the rest of the block up to the indented code
  • < - Shift the block left
  • `kdd - Jump back to the starting line (the conditional) and delete it

Messy as hell though and plus it only works for C-like languages and if there is an else block then we are screwed.

Posted Oct 30, 2010, 1:35 PM UTC

99
dysmas•

typing this on my phone so untested, wont handle else blocks, but you could just do it again inside the else block, will de-dent contents too

mavaBkoj<esc>?{<cr>dd/}<cr>dd'a

on second thoughts something along the lines of

viB"ayvaBVd"aP

seems a little cleaner

2
Refefer•

Ahhh, only in vim land is something like viB"ayvaBVd"aP considered clearer :)

15
jackerran•

I changed up the second one a bit because for some reason mine wasn't re-indenting properly

viB"advaBVd"aPvaB=

1
[deleted]•

[deleted]

1
[deleted]•

[deleted]

1
vesechOP•

Didn't fix the indenting here, but nothing

`[v`]=

couldn't sort out after the first p to make it

vi{djp`[v`]=kdk
1
LurkersA•

Do a ggVG= to re-align the whole file.

1
[deleted]•

Even better, do gg=G and save a keystroke ;)

1
LurkersA•

Cheers :)

1
brombomb•

I might be missing something but what about just using the text objects of i and a?

ci{
ca{

ci{ will delete everything between the Curly braces and leave you in insert mode.

ca{ will delete everything between the curly braces, and the curly braces and leave you in insert mode.

you may be able to string that together with your commands or just add some cursor movement (ie. jci{ )

Just a thought.

1
ktr73•

Also: da{cc Ie, "delete a {" deletes the brackets (and everything inside) and cc deletes the rest putting you at the right indentation (in insert mode). Mapped: map dsb da{cc

2
brombomb•

I knew I was forgetting something. good catch.

1