Skip to content

Instantly share code, notes, and snippets.

@jgdavey
Created November 12, 2010 23:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jgdavey/674892 to your computer and use it in GitHub Desktop.
Save jgdavey/674892 to your computer and use it in GitHub Desktop.
function! s:ToggleDoEndOrBrackets()
let char = getline('.')[col('.')-1]
if char =~ '[{}]'
if char=='}'
norm %
endif
norm h
" Bracket touching previous word
if getline('.')[col('.')-1] =~ '[^ ;]'
exe "norm! a "
endif
norm lmd
let begin_num = line('.')
let begin_line = getline('.')
norm %
let end_num = line('.')
norm! send
norm me`dsdo
norm! ='e`d
if begin_num == end_num " Was a one-liner
" Has block parameters
if search('\vdo *\|', 'c', begin_num)
let end_of_line = '2f|'
else
let end_of_line = 'e'
endif
exe "norm! `ehi\<cr>\<esc>me`d".end_of_line."a\<cr>\<esc>"
norm `d
if search('do|', 'c', begin_num) | :.s/do|/do |/ | endif
:'d,'eTrim
norm `d
endif
else
let w = expand('<cword>')
if w =~ '\vdo|end'
if w=='end'
norm %
elseif char == 'o'
norm! h
endif
let begin_num = line('.')
norm md%
let end_num = line('.')
norm! ciw}
norm! `dciw{
if (end_num-begin_num) == 2
norm! JJ`d
" Remove extraneous spaces
if search(' \+', 'c', begin_num) | :.s/\([^ ]\) \+/\1 /g | endif
if search('{ |', 'c', begin_num) | :.s/{ |/{|/ | endif
normal `d
endif
else
throw 'Cannot toggle block: cursor is not on {, }, do or end'
endif
endif
endfunction
nnoremap <leader>b :call <sid>ToggleDoEndOrBrackets()<CR>
@jgdavey
Copy link
Author

jgdavey commented Nov 13, 2010

Current limitations:

  • You must have your cursor on {, }, do, or end for it to work.
  • Going from do/end to brackets will only revert to one line if there's only one line between the do and end

@cmatheson
Copy link

This is a cool plugin. Did you know that matchit.vim does this as well when used with vim-ruby? It also works with if, case, def, etc.

@jgdavey
Copy link
Author

jgdavey commented Dec 23, 2010

This plugin actually uses matchit.vim to find the matching do/end or { } pairs, but toggles ruby blocks between the two. It has moved to this repo: https://github.com/jgdavey/vim-blockle/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment