7

Is there any easy way to toggle "do/end" and "{}" in ruby in Vim?

(TextMate does this with ^{.)

TK.
  • 27,073
  • 20
  • 64
  • 72

3 Answers3

6

You'd have to either use searchpair(), or to play with % (as long as matchit is installed, and as you are on begin/end), then mark the two positions, test whether it's text or brackets, and finally update the two lines.

nnoremap <buffer> <c-x>{ :call <sid>ToggleBeginOrBracket()<cr>

let s:k_be = [ 'begin', 'end' ]
function! s:ToggleBeginOrBracket()
  let c = lh#position#char_at_mark('.')
  if c =~ '[{}]'
    " don't use matchit for {,}
    exe 'normal! %s'.s:k_be[1-(c=='}')]."\<esc>``s".s:k_be[(c=='}')]."\<esc>"
  else
    let w = expand('<cword>')
    if w == 'begin'
      " use mathit
      normal %
      exe "normal! ciw}\<esc>``ciw{\<esc>"
    elseif w == 'end'
      " use mathit
      normal %
      exe "normal! ciw{\<esc>``ciw}\<esc>"
    else
      throw 'Cannot toggle block: cursor is not on {, }, begin, nor end'
    endif
  endif
endfunction

Where lh#position#char_at_mark() is defined here.

PS: this is definitively a SO question as it combines ruby context, and advanced vim scripting.

Luc Hermitte
  • 31,979
  • 7
  • 69
  • 83
  • Yeah, there's no reason for the complicated solution. Just use matchit.vim. :) – graywh Jul 14 '10 at 21:32
  • Matchit does not solve OP's request. (And even without vim involded, it still concerns the tuning of a development tool, for development purposes) – Luc Hermitte Jul 15 '10 at 18:12
4

Check out this new plugin: https://github.com/jgdavey/vim-blockle.

30 chars pad

kizzx2
  • 18,775
  • 14
  • 76
  • 83
1

There is a splitjoin.vim plugin that does this nicely (gJ/gS mappings for splitting/joining).

Paweł Gościcki
  • 9,066
  • 5
  • 70
  • 81