Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
" Ruby snippets
" Last change: August 6 2007
" Version> 0.1.0
" Maintainer: Eustáquio 'TaQ' Rangel
" License: GPL
" Thanks to: Andy Wokula and Antonio Terceiro for help and patches.
if exists("b:rubysnippets_ignore")
let b:rubysnippets_ignore = 1
let b:rubysigncount = 1
" Create a dictionary for some options
let b:rubysnippets_options = {}
if exists("g:rubysnippets_skip_names")
let b:rubysnippets_options["class"] = ["","$a "]
let b:rubysnippets_options["module"] = ["","$a "]
let b:rubysnippets_options["def"] = ["","$a "]
let b:rubysnippets_options["class"] = [" ClassName","w"]
let b:rubysnippets_options["module"] = [" ModuleName","w"]
let b:rubysnippets_options["def"] = [" method_name","w"]
" See the Ruby documentation for the word under the cursor.
" Based on the tip on
function! s:RubySnippetsDoc(keyword)
" We need a browser here! it gets the value from the g:rubysnippets_browser var
" Some possible values we can use (GNU/Linux based):
" firefox -new-window
" firefox -new-tab
" xterm -bg black -fg white -e lynx
if !exists("g:rubysnippets_browser")
" default URL, thanks James Britt!
let url = "\&q=".a:keyword
" if you want to search elsewhere ...
if exists("g:rubysnippets_search_url")
let url = g:rubysnippets_search_url
exec "!".g:rubysnippets_browser." '".url."'"
map <buffer> <silent> rd :call <SID>RubySnippetsDoc(expand("<cword>"))<cr><cr>
" Insert a sign on the current file. The sign can be text (>>) if you're
" using vim on a console'or a little ruby icon if you're using GUI.
" '
function! s:RubySnippetsInsertSign()
exe ":sign place ".b:rubysigncount." line=".line(".")." name=rubysign file=".expand("%:p")
let b:rubysigncount += 1
" just enable the feature if vim was compiled with signs support
if has("signs")
let icon_image = "ruby.xpm"
let icon_path = split(&rtp,",")[0]."/pixmaps/"
if has("win32")
let icon_image="ruby.bmp"
exe ":sign define rubysign text=>> linehl=Warning texthl=Error icon=".icon_path.icon_image
"map <buffer> is :call <SID>RubySnippetsInsertSign()<CR>
map <buffer> rs :sign unplace<CR>
" Simple abbreviations
iab <buffer> <silent> atr attr_reader
iab <buffer> <silent> atw attr_writer
iab <buffer> <silent> atc attr_accessor
" Keep the current line value with the contents of the abbreviation.
" Used as a way to guess when a keyword does not need to behave the usual way
" on this script.
function! s:RubySnippetsKeepLine(line,expr)
let pos = getpos(".")
let pre = strpart(a:line,0,pos[2])
let aft = strpart(a:line,pos[2])
let char = nr2char(getchar(1))
let inc = char!=" " ? 1 : -1
let move = strlen(a:expr)+inc
call setline(line("."),pre.a:expr.char.aft)
call feedkeys("\<esc>".move."la".(inc<0?" ":""),"m")
" Create a indentation string with tabs, based on the
" current line indentation. It checks if the expandtab
" option is set, and if so insert space characters, if
" not, find how many tabs are inserted based on the value
" of the tabstop option.
function! s:RubySnippetsCreateIndentation()
let char = &expandtab==1 ? " " : "\t"
let qty = indent(".") / (&expandtab==1 ? 1 : &tabstop)
return repeat(char,qty)
" RubySnippetsFor()
" Here we have a snippet to work with for.
" It works on empty lines, or lines with one or two strings,
" where it insert a default 'for' structure and change its
" strings checking how many strings are on the current line.
" It works like this:
" current line result
" ------------ ------
" <empty> for item in collection
" end
" @people for item in @people
" end
" person @people for person in @people
" end
" It works on Insert Mode, when you type 'for' as the first string on
" the line, and <C-F> on Insert and Normal Modes.
function! s:RubySnippetsFor(insert)
let line = getline(".")
let token = split(line)
let listc = ["for","item","in","collection"]
let indent = s:RubySnippetsCreateIndentation()
if len(token)>0 && token[0]!="for" && a:insert==1
call s:RubySnippetsKeepLine(line,"for")
if len(token)==1
let listc[3] = token[0]
if len(token)==2
let listc[1] = token[0]
let listc[3] = token[1]
call setline(line("."),indent.join(listc))
call append(line("."),indent."end")
call feedkeys("o")
"iab <buffer> for <esc>:call <SID>RubySnippetsFor(1)<cr>
"map <buffer> <C-F> :call <SID>RubySnippetsFor(0)<cr>
"imap <buffer> <C-F> <ESC>:call <SID>RubySnippetsFor(0)<cr>
" Used to create 'one-liners' and blocks, but just when
" the method have a dot before its name.
function! s:RubySnippetsOneLinersAndBlocks(expr,aft,append,match,keys)
let line = getline(".")
let pos = getpos(".")
let pre = strpart(line,0,pos[2])
let subs = strpart(line,pos[2]-1,1)
" let's check for a match to fire the transformation
if len(a:match)>0
if subs!=a:match
call s:RubySnippetsKeepLine(line,a:expr)
" if the match is an empty string, we check for nothing more there
let tokens = split(line)
if len(tokens)>0 && tokens[0]!=a:expr
call s:RubySnippetsKeepLine(line,a:expr)
" change the current line
call setline(".",pre.a:expr.a:aft)
" check for the append list size
let size = len(a:append)
" if don't need to append something, change the cursor position and go to
" insert mode'
if size<1
let pos[2] = pos[2]+len(a:expr)+len(a:aft)-1
call setpos(".",pos)
call feedkeys("i","n")
let indent = s:RubySnippetsCreateIndentation()
let cnt = 0
while cnt < size
let a:append[cnt] = indent.a:append[cnt]
let cnt = cnt + 1
call append(line("."),a:append)
if len(a:keys)>0
call feedkeys(a:keys)
" blocks
iab <buffer> <silent> each <esc>:call <SID>RubySnippetsOneLinersAndBlocks("each" ," do \|item\|" ,["end"],".","o")<cr>
iab <buffer> <silent> each_with_index <esc>:call <SID>RubySnippetsOneLinersAndBlocks("each_with_index" ," do \|item,index\|",["end"],".","o")<cr>
iab <buffer> <silent> inject <esc>:call <SID>RubySnippetsOneLinersAndBlocks("inject" ," do \|memo,obj\|" ,["end"],".","o")<cr>
iab <buffer> <silent> begin <esc>:call <SID>RubySnippetsOneLinersAndBlocks("begin" ,"",["rescue Exception => e","end"],"","o")<cr>
iab <buffer> <silent> class <esc>:call <SID>RubySnippetsOneLinersAndBlocks("class" ,b:rubysnippets_options["class"][0],["end"],"",b:rubysnippets_options["class"][1])<cr>
iab <buffer> <silent> module <esc>:call <SID>RubySnippetsOneLinersAndBlocks("module" ,b:rubysnippets_options["module"][0],["end"],"",b:rubysnippets_options["module"][1])<cr>
iab <buffer> <silent> def <esc>:call <SID>RubySnippetsOneLinersAndBlocks("def" ,b:rubysnippets_options["def"][0],["end"],"",b:rubysnippets_options["def"][1])<cr>
" one-liners
"iab <buffer> <silent> collect <esc>:call <SID>RubySnippetsOneLinersAndBlocks("collect" ," {\|item\| }",[],".","")<cr>
iab <buffer> <silent> detect <esc>:call <SID>RubySnippetsOneLinersAndBlocks("detect" ," {\|item\| }",[],".","")<cr>
"iab <buffer> <silent> find <esc>:call <SID>RubySnippetsOneLinersAndBlocks("find" ," {\|item\| }",[],".","")<cr>
"iab <buffer> <silent> find_all <esc>:call <SID>RubySnippetsOneLinersAndBlocks("find_all"," {\|item\| }",[],".","")<cr>
"iab <buffer> <silent> map <esc>:call <SID>RubySnippetsOneLinersAndBlocks("map" ," {\|item\| }",[],".","")<cr>
iab <buffer> <silent> reject <esc>:call <SID>RubySnippetsOneLinersAndBlocks("reject" ," {\|item\| }",[],".","")<cr>
"iab <buffer> <silent> select <esc>:call <SID>RubySnippetsOneLinersAndBlocks("select" ," {\|item\| }",[],".","")<cr>
iab <buffer> <silent> partition <esc>:call <SID>RubySnippetsOneLinersAndBlocks("partition"," {\|item\| }",[],".","")<cr>
" Create a Ruby hash representation with a list of even string parameters.
" If it's an odd number, do nothing.
function! s:RubySnippetsMakeHash(line)
let tokens = split(a:line)
let leng = len(tokens)
if leng==0 || leng%2!=0
return ""
let qtde = leng/2
let lnum = 0
let list = []
let lpos = 0
while lnum < qtde
call add(list,tokens[lpos]."=>".tokens[lpos+1])
let lnum = lnum+1
let lpos = lpos+2
return "{".join(list,",")."}"
" The hash is created using <C-H> on Insert and Normal Modes, where it will search
" for the positions of { and } and convert all the strings PAIRS inside
" a hash, like this:
" {1 :one 2 :two 3 :three 4 :four}
" will become
" {1=>:one,2=>:two,3=>:three,4=>:four}
" The { and } are mandatory, they identify a hash needing to be formatted.
" If it is an odd number, do nothing.
function! s:RubySnippetsHash()
let line = getline(".")
let cpos = getpos(".") " check where the cursor is
let flag = line[cpos[2]-1]=="{" ? "" : "b" " if its over a { char, we need to search forward
let ppos = searchpairpos("{","","}",flag) " search for the open/close pair
if ppos[0]==0 || ppos[1]==0 " if it's not found, we just return
let ini = flag=="b" ? ppos[1] : cpos[2] " check the start position
let end = stridx(line,"}",ini+1) " check the end position
let subs = strpart(line,ini,end-ini) " get the substring
if match(subs,'[a-zA-Z0-9: ''""]\+')<0 " if there is a hash already there, return
let pre = strpart(line,0,ini-1) " the substring before the hash
let pos = strpart(line,end+1) " the substring after the hash
let rst = s:RubySnippetsMakeHash(subs) " make the hash!
if strlen(rst)<1 " nothing there, go away!
call setline(line("."),pre.rst.pos) " change the current line
let posi = getpos(".")
let endp = stridx(getline("."),"}",ini+1)
let posi[2] = endp+1
call setpos(".",posi) " position the cursor
imap <buffer> <C-H> <ESC>:call <SID>RubySnippetsHash()<cr>
map <buffer> <C-H> <ESC>:call <SID>RubySnippetsHash()<cr>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment