]>
Commit | Line | Data |
---|---|---|
1 | " rails.vim - Detect a rails application | |
2 | " Author: Tim Pope <http://tpo.pe/> | |
3 | " GetLatestVimScripts: 1567 1 :AutoInstall: rails.vim | |
4 | ||
5 | " Install this file as plugin/rails.vim. See doc/rails.txt for details. (Grab | |
6 | " it from the URL above if you don't have it.) To access it from Vim, see | |
7 | " :help add-local-help (hint: :helptags ~/.vim/doc) Afterwards, you should be | |
8 | " able to do :help rails | |
9 | ||
10 | if exists('g:loaded_rails') || &cp || v:version < 700 | |
11 | finish | |
12 | endif | |
13 | let g:loaded_rails = 1 | |
14 | ||
15 | " Utility Functions {{{1 | |
16 | ||
17 | function! s:error(str) | |
18 | echohl ErrorMsg | |
19 | echomsg a:str | |
20 | echohl None | |
21 | let v:errmsg = a:str | |
22 | endfunction | |
23 | ||
24 | function! s:autoload(...) | |
25 | if !exists("g:autoloaded_rails") && v:version >= 700 | |
26 | runtime! autoload/rails.vim | |
27 | endif | |
28 | if exists("g:autoloaded_rails") | |
29 | if a:0 | |
30 | exe a:1 | |
31 | endif | |
32 | return 1 | |
33 | endif | |
34 | if !exists("g:rails_no_autoload_warning") | |
35 | let g:rails_no_autoload_warning = 1 | |
36 | if v:version >= 700 | |
37 | call s:error("Disabling rails.vim: autoload/rails.vim is missing") | |
38 | else | |
39 | call s:error("Disabling rails.vim: Vim version 7 or higher required") | |
40 | endif | |
41 | endif | |
42 | return "" | |
43 | endfunction | |
44 | ||
45 | " }}}1 | |
46 | " Configuration {{{ | |
47 | ||
48 | function! s:SetOptDefault(opt,val) | |
49 | if !exists("g:".a:opt) | |
50 | let g:{a:opt} = a:val | |
51 | endif | |
52 | endfunction | |
53 | ||
54 | call s:SetOptDefault("rails_statusline",1) | |
55 | call s:SetOptDefault("rails_syntax",1) | |
56 | call s:SetOptDefault("rails_mappings",1) | |
57 | call s:SetOptDefault("rails_abbreviations",1) | |
58 | call s:SetOptDefault("rails_ctags_arguments","--languages=-javascript") | |
59 | call s:SetOptDefault("rails_default_file","README") | |
60 | call s:SetOptDefault("rails_root_url",'http://localhost:3000/') | |
61 | call s:SetOptDefault("rails_modelines",0) | |
62 | call s:SetOptDefault("rails_menu",0) | |
63 | call s:SetOptDefault("rails_gnu_screen",1) | |
64 | call s:SetOptDefault("rails_history_size",5) | |
65 | call s:SetOptDefault("rails_generators","controller\ngenerator\nhelper\nintegration_test\nmailer\nmetal\nmigration\nmodel\nobserver\nperformance_test\nplugin\nresource\nscaffold\nscaffold_controller\nsession_migration\nstylesheets") | |
66 | if exists("g:loaded_dbext") && executable("sqlite3") && ! executable("sqlite") | |
67 | " Since dbext can't find it by itself | |
68 | call s:SetOptDefault("dbext_default_SQLITE_bin","sqlite3") | |
69 | endif | |
70 | ||
71 | " }}}1 | |
72 | " Detection {{{1 | |
73 | ||
74 | function! s:escvar(r) | |
75 | let r = fnamemodify(a:r,':~') | |
76 | let r = substitute(r,'\W','\="_".char2nr(submatch(0))."_"','g') | |
77 | let r = substitute(r,'^\d','_&','') | |
78 | return r | |
79 | endfunction | |
80 | ||
81 | function! s:Detect(filename) | |
82 | let fn = substitute(fnamemodify(a:filename,":p"),'\c^file://','','') | |
83 | let sep = matchstr(fn,'^[^\\/]\{3,\}\zs[\\/]') | |
84 | if sep != "" | |
85 | let fn = getcwd().sep.fn | |
86 | endif | |
87 | if fn =~ '[\/]config[\/]environment\.rb$' | |
88 | return s:BufInit(strpart(fn,0,strlen(fn)-22)) | |
89 | endif | |
90 | if isdirectory(fn) | |
91 | let fn = fnamemodify(fn,':s?[\/]$??') | |
92 | else | |
93 | let fn = fnamemodify(fn,':s?\(.*\)[\/][^\/]*$?\1?') | |
94 | endif | |
95 | let ofn = "" | |
96 | let nfn = fn | |
97 | while nfn != ofn && nfn != "" | |
98 | if exists("s:_".s:escvar(nfn)) | |
99 | return s:BufInit(nfn) | |
100 | endif | |
101 | let ofn = nfn | |
102 | let nfn = fnamemodify(nfn,':h') | |
103 | endwhile | |
104 | let ofn = "" | |
105 | while fn != ofn | |
106 | if filereadable(fn . "/config/environment.rb") | |
107 | return s:BufInit(fn) | |
108 | endif | |
109 | let ofn = fn | |
110 | let fn = fnamemodify(ofn,':s?\(.*\)[\/]\(app\|config\|db\|doc\|features\|lib\|log\|public\|script\|spec\|stories\|test\|tmp\|vendor\)\($\|[\/].*$\)?\1?') | |
111 | endwhile | |
112 | return 0 | |
113 | endfunction | |
114 | ||
115 | function! s:BufInit(path) | |
116 | let s:_{s:escvar(a:path)} = 1 | |
117 | if s:autoload() | |
118 | return RailsBufInit(a:path) | |
119 | endif | |
120 | endfunction | |
121 | ||
122 | " }}}1 | |
123 | " Initialization {{{1 | |
124 | ||
125 | augroup railsPluginDetect | |
126 | autocmd! | |
127 | autocmd BufNewFile,BufRead * call s:Detect(expand("<afile>:p")) | |
128 | autocmd VimEnter * if expand("<amatch>") == "" && !exists("b:rails_root") | call s:Detect(getcwd()) | endif | if exists("b:rails_root") | silent doau User BufEnterRails | endif | |
129 | autocmd FileType netrw if !exists("b:rails_root") | call s:Detect(expand("<afile>:p")) | endif | if exists("b:rails_root") | silent doau User BufEnterRails | endif | |
130 | autocmd BufEnter * if exists("b:rails_root")|silent doau User BufEnterRails|endif | |
131 | autocmd BufLeave * if exists("b:rails_root")|silent doau User BufLeaveRails|endif | |
132 | autocmd Syntax railslog if s:autoload()|call rails#log_syntax()|endif | |
133 | augroup END | |
134 | ||
135 | command! -bar -bang -nargs=* -complete=dir Rails :if s:autoload()|call rails#new_app_command(<bang>0,<f-args>)|endif | |
136 | ||
137 | " }}}1 | |
138 | " abolish.vim support {{{1 | |
139 | ||
140 | function! s:function(name) | |
141 | return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '<SNR>\d\+_'),'')) | |
142 | endfunction | |
143 | ||
144 | augroup railsPluginAbolish | |
145 | autocmd! | |
146 | autocmd VimEnter * call s:abolish_setup() | |
147 | augroup END | |
148 | ||
149 | function! s:abolish_setup() | |
150 | if exists('g:Abolish') && has_key(g:Abolish,'Coercions') | |
151 | if !has_key(g:Abolish.Coercions,'l') | |
152 | let g:Abolish.Coercions.l = s:function('s:abolish_l') | |
153 | endif | |
154 | if !has_key(g:Abolish.Coercions,'t') | |
155 | let g:Abolish.Coercions.t = s:function('s:abolish_t') | |
156 | endif | |
157 | endif | |
158 | endfunction | |
159 | ||
160 | function! s:abolish_l(word) | |
161 | let singular = rails#singularize(a:word) | |
162 | return a:word ==? singular ? rails#pluralize(a:word) : singular | |
163 | endfunction | |
164 | ||
165 | function! s:abolish_t(word) | |
166 | if a:word =~# '\u' | |
167 | return rails#pluralize(rails#underscore(a:word)) | |
168 | else | |
169 | return rails#singularize(rails#camelize(a:word)) | |
170 | endif | |
171 | endfunction | |
172 | ||
173 | " }}}1 | |
174 | " Menus {{{1 | |
175 | ||
176 | if !(g:rails_menu && has("menu")) | |
177 | finish | |
178 | endif | |
179 | ||
180 | function! s:sub(str,pat,rep) | |
181 | return substitute(a:str,'\v\C'.a:pat,a:rep,'') | |
182 | endfunction | |
183 | ||
184 | function! s:gsub(str,pat,rep) | |
185 | return substitute(a:str,'\v\C'.a:pat,a:rep,'g') | |
186 | endfunction | |
187 | ||
188 | function! s:menucmd(priority) | |
189 | return 'anoremenu <script> '.(exists("$CREAM") ? 87 : '').s:gsub(g:rails_installed_menu,'[^.]','').'.'.a:priority.' ' | |
190 | endfunction | |
191 | ||
192 | function! s:CreateMenus() abort | |
193 | if exists("g:rails_installed_menu") && g:rails_installed_menu != "" | |
194 | exe "aunmenu ".s:gsub(g:rails_installed_menu,'\&','') | |
195 | unlet g:rails_installed_menu | |
196 | endif | |
197 | if has("menu") && (exists("g:did_install_default_menus") || exists("$CREAM")) && g:rails_menu | |
198 | if g:rails_menu > 1 | |
199 | let g:rails_installed_menu = '&Rails' | |
200 | else | |
201 | let g:rails_installed_menu = '&Plugin.&Rails' | |
202 | endif | |
203 | let dots = s:gsub(g:rails_installed_menu,'[^.]','') | |
204 | let menucmd = s:menucmd(200) | |
205 | if exists("$CREAM") | |
206 | exe menucmd.g:rails_installed_menu.'.-PSep- :' | |
207 | exe menucmd.g:rails_installed_menu.'.&Related\ file\ :R\ /\ Alt+] :R<CR>' | |
208 | exe menucmd.g:rails_installed_menu.'.&Alternate\ file\ :A\ /\ Alt+[ :A<CR>' | |
209 | exe menucmd.g:rails_installed_menu.'.&File\ under\ cursor\ Ctrl+Enter :Rfind<CR>' | |
210 | else | |
211 | exe menucmd.g:rails_installed_menu.'.-PSep- :' | |
212 | exe menucmd.g:rails_installed_menu.'.&Related\ file\ :R\ /\ ]f :R<CR>' | |
213 | exe menucmd.g:rails_installed_menu.'.&Alternate\ file\ :A\ /\ [f :A<CR>' | |
214 | exe menucmd.g:rails_installed_menu.'.&File\ under\ cursor\ gf :Rfind<CR>' | |
215 | endif | |
216 | exe menucmd.g:rails_installed_menu.'.&Other\ files.Application\ &Controller :Rcontroller application<CR>' | |
217 | exe menucmd.g:rails_installed_menu.'.&Other\ files.Application\ &Helper :Rhelper application<CR>' | |
218 | exe menucmd.g:rails_installed_menu.'.&Other\ files.Application\ &Javascript :Rjavascript application<CR>' | |
219 | exe menucmd.g:rails_installed_menu.'.&Other\ files.Application\ &Layout :Rlayout application<CR>' | |
220 | exe menucmd.g:rails_installed_menu.'.&Other\ files.Application\ &README :R doc/README_FOR_APP<CR>' | |
221 | exe menucmd.g:rails_installed_menu.'.&Other\ files.&Environment :Renvironment<CR>' | |
222 | exe menucmd.g:rails_installed_menu.'.&Other\ files.&Database\ Configuration :R config/database.yml<CR>' | |
223 | exe menucmd.g:rails_installed_menu.'.&Other\ files.Database\ &Schema :Rmigration 0<CR>' | |
224 | exe menucmd.g:rails_installed_menu.'.&Other\ files.R&outes :Rinitializer<CR>' | |
225 | exe menucmd.g:rails_installed_menu.'.&Other\ files.&Test\ Helper :Rintegrationtest<CR>' | |
226 | exe menucmd.g:rails_installed_menu.'.-FSep- :' | |
227 | exe menucmd.g:rails_installed_menu.'.Ra&ke\ :Rake :Rake<CR>' | |
228 | let menucmd = substitute(menucmd,'200 $','500 ','') | |
229 | exe menucmd.g:rails_installed_menu.'.&Server\ :Rserver.&Start\ :Rserver :Rserver<CR>' | |
230 | exe menucmd.g:rails_installed_menu.'.&Server\ :Rserver.&Force\ start\ :Rserver! :Rserver!<CR>' | |
231 | exe menucmd.g:rails_installed_menu.'.&Server\ :Rserver.&Kill\ :Rserver!\ - :Rserver! -<CR>' | |
232 | exe substitute(menucmd,'<script>','<script> <silent>','').g:rails_installed_menu.'.&Evaluate\ Ruby\.\.\.\ :Rp :call <SID>menuprompt("Rp","Code to execute and output: ")<CR>' | |
233 | exe menucmd.g:rails_installed_menu.'.&Console\ :Rscript :Rscript console<CR>' | |
234 | exe menucmd.g:rails_installed_menu.'.&Preview\ :Rpreview :Rpreview<CR>' | |
235 | exe menucmd.g:rails_installed_menu.'.&Log\ file\ :Rlog :Rlog<CR>' | |
236 | exe substitute(s:sub(menucmd,'anoremenu','vnoremenu'),'<script>','<script> <silent>','').g:rails_installed_menu.'.E&xtract\ as\ partial\ :Rextract :call <SID>menuprompt("'."'".'<,'."'".'>Rextract","Partial name (e.g., template or /controller/template): ")<CR>' | |
237 | exe menucmd.g:rails_installed_menu.'.&Migration\ writer\ :Rinvert :Rinvert<CR>' | |
238 | exe menucmd.' '.g:rails_installed_menu.'.-HSep- :' | |
239 | exe substitute(menucmd,'<script>','<script> <silent>','').g:rails_installed_menu.'.&Help\ :help\ rails :if <SID>autoload()<Bar>exe RailsHelpCommand("")<Bar>endif<CR>' | |
240 | exe substitute(menucmd,'<script>','<script> <silent>','').g:rails_installed_menu.'.Abo&ut\ :if <SID>autoload()<Bar>exe RailsHelpCommand("about")<Bar>endif<CR>' | |
241 | let g:rails_did_menus = 1 | |
242 | call s:ProjectMenu() | |
243 | call s:menuBufLeave() | |
244 | if exists("b:rails_root") | |
245 | call s:menuBufEnter() | |
246 | endif | |
247 | endif | |
248 | endfunction | |
249 | ||
250 | function! s:ProjectMenu() | |
251 | if exists("g:rails_did_menus") && g:rails_history_size > 0 | |
252 | if !exists("g:RAILS_HISTORY") | |
253 | let g:RAILS_HISTORY = "" | |
254 | endif | |
255 | let history = g:RAILS_HISTORY | |
256 | let menu = s:gsub(g:rails_installed_menu,'\&','') | |
257 | silent! exe "aunmenu <script> ".menu.".Projects" | |
258 | let dots = s:gsub(menu,'[^.]','') | |
259 | exe 'anoremenu <script> <silent> '.(exists("$CREAM") ? '87' : '').dots.'.100 '.menu.'.Pro&jects.&New\.\.\.\ :Rails :call <SID>menuprompt("Rails","New application path and additional arguments: ")<CR>' | |
260 | exe 'anoremenu <script> '.menu.'.Pro&jects.-FSep- :' | |
261 | while history =~ '\n' | |
262 | let proj = matchstr(history,'^.\{-\}\ze\n') | |
263 | let history = s:sub(history,'^.{-}\n','') | |
264 | exe 'anoremenu <script> '.menu.'.Pro&jects.'.s:gsub(proj,'[.\\ ]','\\&').' :e '.s:gsub(proj."/".g:rails_default_file,'[ !%#]','\\&')."<CR>" | |
265 | endwhile | |
266 | endif | |
267 | endfunction | |
268 | ||
269 | function! s:menuBufEnter() | |
270 | if exists("g:rails_installed_menu") && g:rails_installed_menu != "" | |
271 | let menu = s:gsub(g:rails_installed_menu,'\&','') | |
272 | exe 'amenu enable '.menu.'.*' | |
273 | if RailsFileType() !~ '^view\>' | |
274 | exe 'vmenu disable '.menu.'.Extract\ as\ partial' | |
275 | endif | |
276 | if RailsFileType() !~ '^\%(db-\)\=migration$' || RailsFilePath() =~ '\<db/schema\.rb$' | |
277 | exe 'amenu disable '.menu.'.Migration\ writer' | |
278 | endif | |
279 | call s:ProjectMenu() | |
280 | silent! exe 'aunmenu '.menu.'.Rake\ tasks' | |
281 | silent! exe 'aunmenu '.menu.'.Generate' | |
282 | silent! exe 'aunmenu '.menu.'.Destroy' | |
283 | if rails#app().cache.needs('rake_tasks') || empty(rails#app().rake_tasks()) | |
284 | exe substitute(s:menucmd(300),'<script>','<script> <silent>','').g:rails_installed_menu.'.Rake\ &tasks\ :Rake.Fill\ this\ menu :call rails#app().rake_tasks()<Bar>call <SID>menuBufLeave()<Bar>call <SID>menuBufEnter()<CR>' | |
285 | else | |
286 | let i = 0 | |
287 | while i < len(rails#app().rake_tasks()) | |
288 | let task = rails#app().rake_tasks()[i] | |
289 | exe s:menucmd(300).g:rails_installed_menu.'.Rake\ &tasks\ :Rake.'.s:sub(task,':',':.').' :Rake '.task.'<CR>' | |
290 | let i += 1 | |
291 | endwhile | |
292 | endif | |
293 | let i = 0 | |
294 | let menucmd = substitute(s:menucmd(400),'<script>','<script> <silent>','').g:rails_installed_menu | |
295 | while i < len(rails#app().generators()) | |
296 | let generator = rails#app().generators()[i] | |
297 | exe menucmd.'.&Generate\ :Rgen.'.s:gsub(generator,'_','\\ ').' :call <SID>menuprompt("Rgenerate '.generator.'","Arguments for script/generate '.generator.': ")<CR>' | |
298 | exe menucmd.'.&Destroy\ :Rdestroy.'.s:gsub(generator,'_','\\ ').' :call <SID>menuprompt("Rdestroy '.generator.'","Arguments for script/destroy '.generator.': ")<CR>' | |
299 | let i += 1 | |
300 | endwhile | |
301 | endif | |
302 | endfunction | |
303 | ||
304 | function! s:menuBufLeave() | |
305 | if exists("g:rails_installed_menu") && g:rails_installed_menu != "" | |
306 | let menu = s:gsub(g:rails_installed_menu,'\&','') | |
307 | exe 'amenu disable '.menu.'.*' | |
308 | exe 'amenu enable '.menu.'.Help\ ' | |
309 | exe 'amenu enable '.menu.'.About\ ' | |
310 | exe 'amenu enable '.menu.'.Projects' | |
311 | silent! exe 'aunmenu '.menu.'.Rake\ tasks' | |
312 | silent! exe 'aunmenu '.menu.'.Generate' | |
313 | silent! exe 'aunmenu '.menu.'.Destroy' | |
314 | exe s:menucmd(300).g:rails_installed_menu.'.Rake\ tasks\ :Rake.-TSep- :' | |
315 | exe s:menucmd(400).g:rails_installed_menu.'.&Generate\ :Rgen.-GSep- :' | |
316 | exe s:menucmd(400).g:rails_installed_menu.'.&Destroy\ :Rdestroy.-DSep- :' | |
317 | endif | |
318 | endfunction | |
319 | ||
320 | function! s:menuprompt(vimcmd,prompt) | |
321 | let res = inputdialog(a:prompt,'','!!!') | |
322 | if res == '!!!' | |
323 | return "" | |
324 | endif | |
325 | exe a:vimcmd." ".res | |
326 | endfunction | |
327 | ||
328 | call s:CreateMenus() | |
329 | ||
330 | augroup railsPluginMenu | |
331 | autocmd! | |
332 | autocmd User BufEnterRails call s:menuBufEnter() | |
333 | autocmd User BufLeaveRails call s:menuBufLeave() | |
334 | " g:RAILS_HISTORY hasn't been set when s:InitPlugin() is called. | |
335 | autocmd VimEnter * call s:ProjectMenu() | |
336 | augroup END | |
337 | ||
338 | " }}}1 | |
339 | " vim:set sw=2 sts=2: |