3 " Last change: March 5 2009
5 " Maintainer: Eustáquio 'TaQ' Rangel
7 " URL: git://github.com/taq/vim-rspec
9 " Script to run the spec command inside Vim
10 " To install, unpack the files on your ~/.vim directory and source it
12 " The following options can be set/overridden in your .vimrc
13 " * g:RspecXSLPath :: Path to xsl file
14 " * g:RspecRBFilePath :: Path to vim-rspec.rb
15 " * g:RspecBin :: Rspec binary command (in rspec 2 this is 'rspec')
16 " * g:RspecOpts :: Opts to send to rspec call
18 let s:xsltproc_cmd = ""
20 let s:hpricot_cmd = ""
23 let s:helper_dir = expand("<sfile>:h")
25 function! s:find_xslt()
26 return system("xsltproc --version | head -n1")
29 function! s:find_grep()
30 return system("grep --version | head -n1")
33 function! s:find_hpricot()
34 return system("gem search -i hpricot")
37 function! s:error_msg(msg)
43 function! s:notice_msg(msg)
49 function! s:fetch(varname, default)
50 if exists("g:".a:varname)
51 return eval("g:".a:varname)
57 function! s:RunSpecMain(type)
58 if len(s:xsltproc_cmd)<1
59 let s:xsltproc_cmd = s:find_xslt()
60 let s:xslt = match(s:xsltproc_cmd,'\d')>=0
62 if len(s:hpricot_cmd)<1
63 let s:hpricot_cmd = s:find_hpricot()
64 let s:hpricot = match(s:hpricot_cmd,'true')>=0
66 if !s:hpricot && !s:xslt
67 call s:error_msg("You need the hpricot gem or xsltproc to run this script.")
71 let s:grep_cmd = s:find_grep()
72 if match(s:grep_cmd,'\d')<0
73 call s:error_msg("You need grep to run this script.")
77 let l:bufn = bufname("%")
79 " find the installed rspec command
80 let l:default_cmd = ""
81 if executable("spec")==1
82 let l:default_cmd = "spec"
83 elseif executable("rspec")==1
84 let l:default_cmd = "rspec"
88 let l:xsl = s:fetch("RspecXSLPath", s:helper_dir."/vim-rspec.xsl")
89 let l:rubys = s:fetch("RspecRBPath", s:helper_dir."/vim-rspec.rb")
91 " hpricot gets the priority
92 let l:type = s:hpricot ? "hpricot" : "xsltproc"
93 let l:filter = s:hpricot ? "ruby ".l:rubys : "xsltproc --novalid --html ".l:xsl." - "
95 " run just the current file
97 if match(l:bufn,'_spec.rb')>=0
98 call s:notice_msg("Running spec on the current file with ".l:type." ...")
99 let l:spec_bin = s:fetch("RspecBin",l:default_cmd)
100 let l:spec_opts = s:fetch("RspecOpts", "")
101 let l:spec = l:spec_bin . " " . l:spec_opts . " -f h " . l:bufn
103 call s:error_msg("Seems ".l:bufn." is not a *_spec.rb file")
107 let l:dir = expand("%:p:h")
108 if isdirectory(l:dir."/spec")>0
109 call s:notice_msg("Running spec on the spec directory with ".l:type." ...")
111 " try to find a spec directory on the current path
112 let l:tokens = split(l:dir,"/")
114 for l:item in l:tokens
115 call remove(l:tokens,-1)
116 let l:path = "/".join(l:tokens,"/")."/spec"
117 if isdirectory(l:path)
123 call s:notice_msg("Running spec with ".l:type." on the spec directory found (".l:dir.") ...")
125 call s:error_msg("No ".l:dir."/spec directory found")
129 if isdirectory(l:dir)<0
130 call s:error_msg("Could not find the ".l:dir." directory.")
133 let l:spec = s:fetch("RspecBin", "spec") . s:fetch("RspecOpts", "")
134 let l:spec = l:spec . " -f h " . l:dir . " -p **/*_spec.rb"
137 " run the spec command
138 let s:cmd = l:spec." | ".l:filter." 2> /dev/null | grep \"^[-\+\[\\#\\* ]\""
141 " put the result on a new buffer
144 silent exec "r! ".s:cmd
145 setl syntax=vim-rspec
146 silent exec "nnoremap <buffer> <cr> :call <SID>TryToOpen()<cr>"
147 silent exec "nnoremap <buffer> q :q<CR>"
149 setl foldexpr=getline(v:lnum)=~'^\+'
150 setl foldtext=\"+--\ \".string(v:foldend-v:foldstart+1).\"\ passed\ \"
154 function! s:TryToOpen()
155 let l:line = getline(".")
156 if match(l:line,'^ [\/\.]')<0
157 call s:error_msg("No file found.")
160 let l:tokens = split(l:line,":")
161 silent exec "sp ".substitute(l:tokens[0],'/^\s\+',"","")
162 call cursor(l:tokens[1],1)
166 call s:RunSpecMain("file")
170 call s:RunSpecMain("dir")
173 command! RunSpec call RunSpec()
174 command! RunSpecs call RunSpecs()