]>
Commit | Line | Data |
---|---|---|
0d23b6e5 BB |
1 | " |
2 | " Vim Rspec | |
3 | " Last change: March 5 2009 | |
4 | " Version> 0.0.5 | |
5 | " Maintainer: Eustáquio 'TaQ' Rangel | |
6 | " License: GPL | |
7 | " URL: git://github.com/taq/vim-rspec | |
8 | " | |
9 | " Script to run the spec command inside Vim | |
10 | " To install, unpack the files on your ~/.vim directory and source it | |
11 | " | |
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 | |
17 | ||
18 | let s:xsltproc_cmd = "" | |
19 | let s:grep_cmd = "" | |
20 | let s:hpricot_cmd = "" | |
21 | let s:xslt = 0 | |
22 | let s:hpricot = 0 | |
23 | let s:helper_dir = expand("<sfile>:h") | |
24 | ||
25 | function! s:find_xslt() | |
26 | return system("xsltproc --version | head -n1") | |
27 | endfunction | |
28 | ||
29 | function! s:find_grep() | |
30 | return system("grep --version | head -n1") | |
31 | endfunction | |
32 | ||
33 | function! s:find_hpricot() | |
34 | return system("gem search -i hpricot") | |
35 | endfunction | |
36 | ||
37 | function! s:error_msg(msg) | |
38 | echohl ErrorMsg | |
39 | echo a:msg | |
40 | echohl None | |
41 | endfunction | |
42 | ||
43 | function! s:notice_msg(msg) | |
44 | echohl MoreMsg | |
45 | echo a:msg | |
46 | echohl None | |
47 | endfunction | |
48 | ||
49 | function! s:fetch(varname, default) | |
50 | if exists("g:".a:varname) | |
51 | return eval("g:".a:varname) | |
52 | else | |
53 | return a:default | |
54 | endif | |
55 | endfunction | |
56 | ||
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 | |
61 | end | |
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 | |
65 | end | |
66 | if !s:hpricot && !s:xslt | |
67 | call s:error_msg("You need the hpricot gem or xsltproc to run this script.") | |
68 | return | |
69 | end | |
70 | if len(s:grep_cmd)<1 | |
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.") | |
74 | return | |
75 | end | |
76 | end | |
77 | let l:bufn = bufname("%") | |
78 | ||
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" | |
85 | end | |
86 | ||
87 | " filters | |
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") | |
90 | ||
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." - " | |
94 | ||
95 | " run just the current file | |
96 | if a:type=="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 | |
102 | else | |
103 | call s:error_msg("Seems ".l:bufn." is not a *_spec.rb file") | |
104 | return | |
105 | end | |
106 | else | |
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." ...") | |
110 | else | |
111 | " try to find a spec directory on the current path | |
112 | let l:tokens = split(l:dir,"/") | |
113 | let 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) | |
118 | let l:dir = l:path | |
119 | break | |
120 | end | |
121 | endfor | |
122 | if len(l:dir)>0 | |
123 | call s:notice_msg("Running spec with ".l:type." on the spec directory found (".l:dir.") ...") | |
124 | else | |
125 | call s:error_msg("No ".l:dir."/spec directory found") | |
126 | return | |
127 | end | |
128 | end | |
129 | if isdirectory(l:dir)<0 | |
130 | call s:error_msg("Could not find the ".l:dir." directory.") | |
131 | return | |
132 | end | |
133 | let l:spec = s:fetch("RspecBin", "spec") . s:fetch("RspecOpts", "") | |
134 | let l:spec = l:spec . " -f h " . l:dir . " -p **/*_spec.rb" | |
135 | end | |
136 | ||
137 | " run the spec command | |
138 | let s:cmd = l:spec." | ".l:filter." 2> /dev/null | grep \"^[-\+\[\\#\\* ]\"" | |
139 | echo | |
140 | ||
141 | " put the result on a new buffer | |
142 | silent exec "new" | |
143 | setl buftype=nofile | |
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>" | |
148 | setl foldmethod=expr | |
149 | setl foldexpr=getline(v:lnum)=~'^\+' | |
150 | setl foldtext=\"+--\ \".string(v:foldend-v:foldstart+1).\"\ passed\ \" | |
151 | call cursor(1,1) | |
152 | endfunction | |
153 | ||
154 | function! s:TryToOpen() | |
155 | let l:line = getline(".") | |
156 | if match(l:line,'^ [\/\.]')<0 | |
157 | call s:error_msg("No file found.") | |
158 | return | |
159 | end | |
160 | let l:tokens = split(l:line,":") | |
161 | silent exec "sp ".substitute(l:tokens[0],'/^\s\+',"","") | |
162 | call cursor(l:tokens[1],1) | |
163 | endfunction | |
164 | ||
165 | function! RunSpec() | |
166 | call s:RunSpecMain("file") | |
167 | endfunction | |
168 | ||
169 | function! RunSpecs() | |
170 | call s:RunSpecMain("dir") | |
171 | endfunction | |
172 | ||
173 | command! RunSpec call RunSpec() | |
174 | command! RunSpecs call RunSpecs() |