Does anybody have a .vimrc file geared specifically for Ruby development?
Here's something I wrote to switch block delimiters (do/end <=3D> {})
It creates a :B command that will turn
foo{|x| f(x); g; bar(x)}
into
foo do |x|
f(x)
g
bar(x)
end
and contrariwise.
You can also turn do/end into {} by selecting the block in visual mode and =
using the=20
<Leader>B (in my case ,B) mapping.
(cut/paste carefully since it contains ESC and other 'raw' chars.
=0C
"{{{ Ruby block delimiter conversion: do end <=3D> { }
"Copyright =A9 2005 Mauricio Fernandez
"Subject to the Ruby license.
" requires matchit and friends=20
" since it uses the % and =3D bindings
function! s:String_Strip(str)
let s =3D substitute(a:str, '\v^\s*', '', '')
return substitute(s, '\v\s*$', '', '')
endfunction
function! s:RubyBlockBraceToDoEnd(lineno)
" { } =3D> do end
let oldz =3D getreg("z")
call setreg("z", "")
execute 'normal ^f{%l"zd$'
let suffix =3D s:String_Strip(getreg("z"))
call setreg("z", oldz)
let orig =3D getline(".")
let repl =3D substitute(orig, '\v\s*\{\s*(\|[^|]*\|)?.*', ' do \1', '')
call setline(".", repl)
let nextline =3D substitute(orig, '\v[^{]*\v\s*\{\s*(\|[^|]*\|)?', '', =
'')
let nextline =3D substitute(nextline, '\}[^}]*$', '', '')
let numlines =3D 0
=20
" uncomment one of the following:
=20
" (1) just insert the body without splitting the lines on ;
"call append(a:lineno, nextline)
"call append(a:lineno+1, 'end' . suffix)
"
=20
" (2) try to split on ; ...
call append(a:lineno, 'end' . suffix)
" this is what we would want to do:=20
"let nextline =3D substitute(nextline, ';', "\n", 'g')
=20
while stridx(nextline, ";") !=3D -1
let eom =3D stridx(nextline, ";")
let line =3D s:String_Strip(strpart(nextline, 0, eom))
call append(a:lineno + numlines, line)=20
let numlines =3D numlines + 1
let nextline =3D strpart(nextline, eom+1, strlen(nextline) - eom - 1)
endwhile
let nextline =3D s:String_Strip(nextline)
if strlen(nextline) > 0
call append(a:lineno + numlines, nextline)
let numlines =3D numlines + 1
endif
" this is what it all began with...
"execute 'normal :s/\v\s*\{\s*(\|.*\|)?/ do \1\r/=0D'
"execute 'normal g_cw=0Dend=1B'
execute 'normal V' . (1 + numlines) . 'j=3D'
"echo "{ } =3D> do end"
endfunction
function! s:RubyBlockDoEndToBrace(_firstline, _lastline)
" do end =3D> { }
let linenum =3D a:_firstline + 1
let orig =3D getline(".")
while linenum < a:_lastline - 1
let addline =3D getline(linenum)
if '\v^\s*$' !~ addline
let addline =3D substitute(addline, '\v^\s*', '', '')
let addline =3D substitute(addline, '\s*$', '; ', '')
let orig =3D orig . addline
endif
let linenum =3D linenum + 1
endwhile
let l =3D substitute(getline(a:_lastline-1), '\v^\s*', '', '')
let l =3D substitute(l, '\s*$', '', '')
let orig =3D orig . l
let l =3D substitute(getline(a:_lastline), '\v^\s*end(\.|\s|$)@=3D', ' =
}', '')
let l =3D substitute(l, '\s*$', '', '')
let orig =3D orig . l
=20
"echo orig
"input(orig)
let repl =3D substitute(orig, '\v\s*do\s*(\|[^|]*\|)?', '{\1 ', '')
"execute 'normal d' . (a:_lastline - a:_firstline) . 'j'
execute ':' . a:_firstline . ',' . a:_lastline . 'd'
call append(a:_firstline - 1, repl)
execute ':' . a:_firstline
"echo "do end =3D> { }"
endfunction
map <SID>xx <SID>xx
let s:sid =3D maparg("<SID>xx")
unmap <SID>xx
let s:sid =3D substitute(s:sid, 'xx', '', '')
function! <SID>RubyBlockSwitchDelimiters() range
set nofoldenable
if a:firstline =3D=3D a:lastline
let braceidx =3D match(getline("."), '{')
let doidx =3D match(getline("."), '\<do\>')
if braceidx !=3D -1 && (doidx =3D=3D -1 || braceidx < doidx)
call s:RubyBlockBraceToDoEnd(a:firstline)
elseif doidx !=3D -1
execute 'normal /\<do\>' . "\n" . 'V%:call ' .=20
\ s:sid . 'RubyBlockSwitchDelimiters()' . "\n"
else
echo "No block found"
end
else
call s:RubyBlockDoEndToBrace(a:firstline, a:lastline)
endif
"execute 'normal V2k=3D'
"execute 'normal v5j'
endfunction
command! -range B <line1>,<line2>call <SID>RubyBlockSwitchDelimiters()
vmap <Leader>B :call <SID>RubyBlockSwitchDelimiters()<cr>
"vmap <Leader>B :B<cr>
=0C
--=20
Mauricio Fernandez