Search code examples
rubyvim

Replacing matching { braces } with do/end in Vim (Ruby)


Does anyone have a plugin or macro to replace matching { braces } with do and end in Vim? Preferably turning a single-line statement like this:

foo.each { |f| f.whatever }

into:

foo.each do |f|
  f.whatever
end

I could make a macro myself for that one case, but I'd like something that could also handle converting existing multi-line, potentially complicated blocks, like:

foo.each { |f|
  f.bars.each { |b| b.whatever }
  hash = { a: 123, b: 456 }
}

into:

foo.each do |f|
  f.bars.each { |b| b.whatever }
  hash = { a: 123, b: 456 }
end

I've looked at vim-surround and rails.vim, and haven't found a way with either.


Solution

  • splitjoin.vim

    It's mentioned in the comments, but should probably be in an answer for visibility:

    splitjoin.vim is a plugin that will do this.

    It works for many languages and works on many kinds of statements that have single-line and multi-line variants (and in particular it can split blocks with braces into do/end style).

    It's actively maintained, as of 2024. (vim-blockle was archived in 2017.)

    From the readme:

    This plugin is meant to simplify a task I've found too common in my workflow: switching between a single-line statement and a multi-line one. It offers the following default keybindings, which can be customized:

    • gS to split a one-liner into multiple lines
    • gJ (with the cursor on the first line of a block) to join a block into a single-line statement.