rails.vim 13 KB

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