diff --git a/.vim/autoload/rails.vim b/.vim/autoload/rails.vim
deleted file mode 100644
index 8cc5efb..0000000
--- a/.vim/autoload/rails.vim
+++ /dev/null
@@ -1,4570 +0,0 @@
-" autoload/rails.vim
-" Author: Tim Pope
-
-" Install this file as autoload/rails.vim.
-
-if exists('g:autoloaded_rails') || &cp
- finish
-endif
-let g:autoloaded_rails = '4.4'
-
-let s:cpo_save = &cpo
-set cpo&vim
-
-" Utility Functions {{{1
-
-let s:app_prototype = {}
-let s:file_prototype = {}
-let s:buffer_prototype = {}
-let s:readable_prototype = {}
-
-function! s:add_methods(namespace, method_names)
- for name in a:method_names
- let s:{a:namespace}_prototype[name] = s:function('s:'.a:namespace.'_'.name)
- endfor
-endfunction
-
-function! s:function(name)
- return function(substitute(a:name,'^s:',matchstr(expand(''), '\d\+_'),''))
-endfunction
-
-function! s:sub(str,pat,rep)
- return substitute(a:str,'\v\C'.a:pat,a:rep,'')
-endfunction
-
-function! s:gsub(str,pat,rep)
- return substitute(a:str,'\v\C'.a:pat,a:rep,'g')
-endfunction
-
-function! s:startswith(string,prefix)
- return strpart(a:string, 0, strlen(a:prefix)) ==# a:prefix
-endfunction
-
-function! s:compact(ary)
- return s:sub(s:sub(s:gsub(a:ary,'\n\n+','\n'),'\n$',''),'^\n','')
-endfunction
-
-function! s:uniq(list)
- let seen = {}
- let i = 0
- while i < len(a:list)
- if has_key(seen,a:list[i])
- call remove(a:list, i)
- else
- let seen[a:list[i]] = 1
- let i += 1
- endif
- endwhile
- return a:list
-endfunction
-
-function! s:scrub(collection,item)
- " Removes item from a newline separated collection
- let col = "\n" . a:collection
- let idx = stridx(col,"\n".a:item."\n")
- let cnt = 0
- while idx != -1 && cnt < 100
- let col = strpart(col,0,idx).strpart(col,idx+strlen(a:item)+1)
- let idx = stridx(col,"\n".a:item."\n")
- let cnt += 1
- endwhile
- return strpart(col,1)
-endfunction
-
-function! s:escarg(p)
- return s:gsub(a:p,'[ !%#]','\\&')
-endfunction
-
-function! s:esccmd(p)
- return s:gsub(a:p,'[!%#]','\\&')
-endfunction
-
-function! s:rquote(str)
- " Imperfect but adequate for Ruby arguments
- if a:str =~ '^[A-Za-z0-9_/.:-]\+$'
- return a:str
- elseif &shell =~? 'cmd'
- return '"'.s:gsub(s:gsub(a:str,'\','\\'),'"','\\"').'"'
- else
- return "'".s:gsub(s:gsub(a:str,'\','\\'),"'","'\\\\''")."'"
- endif
-endfunction
-
-function! s:sname()
- return fnamemodify(s:file,':t:r')
-endfunction
-
-function! s:pop_command()
- if exists("s:command_stack") && len(s:command_stack) > 0
- exe remove(s:command_stack,-1)
- endif
-endfunction
-
-function! s:push_chdir(...)
- if !exists("s:command_stack") | let s:command_stack = [] | endif
- if exists("b:rails_root") && (a:0 ? getcwd() !=# rails#app().path() : !s:startswith(getcwd(), rails#app().path()))
- let chdir = exists("*haslocaldir") && haslocaldir() ? "lchdir " : "chdir "
- call add(s:command_stack,chdir.s:escarg(getcwd()))
- exe chdir.s:escarg(rails#app().path())
- else
- call add(s:command_stack,"")
- endif
-endfunction
-
-function! s:app_path(...) dict
- return join([self.root]+a:000,'/')
-endfunction
-
-function! s:app_has_file(file) dict
- return filereadable(self.path(a:file))
-endfunction
-
-function! s:app_find_file(name, ...) dict abort
- let trim = strlen(self.path())+1
- if a:0
- let path = s:pathjoin(map(s:pathsplit(a:1),'self.path(v:val)'))
- else
- let path = s:pathjoin([self.path()])
- endif
- let suffixesadd = s:pathjoin(get(a:000,1,&suffixesadd))
- let default = get(a:000,2,'')
- let oldsuffixesadd = &l:suffixesadd
- try
- let &suffixesadd = suffixesadd
- " Versions before 7.1.256 returned directories from findfile
- if type(default) == type(0) && (v:version < 702 || default == -1)
- let all = findfile(a:name,path,-1)
- if v:version < 702
- call filter(all,'!isdirectory(v:val)')
- endif
- call map(all,'s:gsub(strpart(fnamemodify(v:val,":p"),trim),"\\\\","/")')
- return default < 0 ? all : get(all,default-1,'')
- elseif type(default) == type(0)
- let found = findfile(a:name,path,default)
- else
- let i = 1
- let found = findfile(a:name,path)
- while v:version < 702 && found != "" && isdirectory(found)
- let i += 1
- let found = findfile(a:name,path,i)
- endwhile
- endif
- return found == "" ? default : s:gsub(strpart(fnamemodify(found,':p'),trim),'\\','/')
- finally
- let &l:suffixesadd = oldsuffixesadd
- endtry
-endfunction
-
-call s:add_methods('app',['path','has_file','find_file'])
-
-" Split a path into a list. From pathogen.vim
-function! s:pathsplit(path) abort
- if type(a:path) == type([]) | return copy(a:path) | endif
- let split = split(a:path,'\\\@'
- if matchstr(self.getline(a:lnum+1),'^'.spc) && !matchstr(self.getline(a:lnum+1),'^'.spc.endpat) && matchstr(cline,endpat)
- return a:lnum
- endif
- let endl = a:lnum
- while endl <= self.line_count()
- let endl += 1
- if self.getline(endl) =~ '^'.spc.endpat
- return endl
- elseif self.getline(endl) =~ '^=begin\>'
- while self.getline(endl) !~ '^=end\>' && endl <= self.line_count()
- let endl += 1
- endwhile
- let endl += 1
- elseif self.getline(endl) !~ '^'.spc && self.getline(endl) !~ '^\s*\%(#.*\)\=$'
- return 0
- endif
- endwhile
- return 0
-endfunction
-
-function! s:endof(lnum)
- return rails#buffer().end_of(a:lnum)
-endfunction
-
-function! s:readable_last_opening_line(start,pattern,limit) dict abort
- let line = a:start
- while line > a:limit && self.getline(line) !~ a:pattern
- let line -= 1
- endwhile
- let lend = self.end_of(line)
- if line > a:limit && (lend < 0 || lend >= a:start)
- return line
- else
- return -1
- endif
-endfunction
-
-function! s:lastopeningline(pattern,limit,start)
- return rails#buffer().last_opening_line(a:start,a:pattern,a:limit)
-endfunction
-
-function! s:readable_define_pattern() dict abort
- if self.name() =~ '\.yml$'
- return '^\%(\h\k*:\)\@='
- endif
- let define = '^\s*def\s\+\(self\.\)\='
- if self.name() =~# '\.rake$'
- let define .= "\\\|^\\s*\\%(task\\\|file\\)\\s\\+[:'\"]"
- endif
- if self.name() =~# '/schema\.rb$'
- let define .= "\\\|^\\s*create_table\\s\\+[:'\"]"
- endif
- if self.type_name('test')
- let define .= '\|^\s*test\s*[''"]'
- endif
- return define
-endfunction
-
-function! s:readable_last_method_line(start) dict abort
- return self.last_opening_line(a:start,self.define_pattern(),0)
-endfunction
-
-function! s:lastmethodline(start)
- return rails#buffer().last_method_line(a:start)
-endfunction
-
-function! s:readable_last_method(start) dict abort
- let lnum = self.last_method_line(a:start)
- let line = self.getline(lnum)
- if line =~# '^\s*test\s*\([''"]\).*\1'
- let string = matchstr(line,'^\s*\w\+\s*\([''"]\)\zs.*\ze\1')
- return 'test_'.s:gsub(string,' +','_')
- elseif lnum
- return s:sub(matchstr(line,'\%('.self.define_pattern().'\)\zs\h\%(\k\|[:.]\)*[?!=]\='),':$','')
- else
- return ""
- endif
-endfunction
-
-function! s:lastmethod(...)
- return rails#buffer().last_method(a:0 ? a:1 : line("."))
-endfunction
-
-function! s:readable_last_format(start) dict abort
- if self.type_name('view')
- let format = fnamemodify(self.path(),':r:e')
- if format == ''
- return get({'rhtml': 'html', 'rxml': 'xml', 'rjs': 'js', 'haml': 'html'},fnamemodify(self.path(),':e'),'')
- else
- return format
- endif
- endif
- let rline = self.last_opening_line(a:start,'\C^\s*\%(mail\>.*\|respond_to\)\s*\%(\.*\|respond_to\)\s*\%(\ rline
- let match = matchstr(self.getline(line),'\C^\s*'.variable.'\s*\.\s*\zs\h\k*')
- if match != ''
- return match
- endif
- let line -= 1
- endwhile
- endif
- return ""
-endfunction
-
-function! s:lastformat(start)
- return rails#buffer().last_format(a:start)
-endfunction
-
-function! s:format(...)
- let format = rails#buffer().last_format(a:0 > 1 ? a:2 : line("."))
- return format ==# '' && a:0 ? a:1 : format
-endfunction
-
-call s:add_methods('readable',['end_of','last_opening_line','last_method_line','last_method','last_format','define_pattern'])
-
-let s:view_types = split('rhtml,erb,rxml,builder,rjs,mab,liquid,haml,dryml,mn,slim',',')
-
-function! s:viewspattern()
- return '\%('.join(s:view_types,'\|').'\)'
-endfunction
-
-function! s:controller(...)
- return rails#buffer().controller_name(a:0 ? a:1 : 0)
-endfunction
-
-function! s:readable_controller_name(...) dict abort
- let f = self.name()
- if has_key(self,'getvar') && self.getvar('rails_controller') != ''
- return self.getvar('rails_controller')
- elseif f =~ '\ get(self,last_lines_ftime,0)
- let self.last_lines = readfile(self.path())
- let self.last_lines_ftime = ftime
- endif
- return get(self,'last_lines',[])
-endfunction
-
-function! s:file_getline(lnum,...) dict abort
- if a:0
- return self.lines[lnum-1 : a:1-1]
- else
- return self.lines[lnum-1]
- endif
-endfunction
-
-function! s:buffer_lines() dict abort
- return self.getline(1,'$')
-endfunction
-
-function! s:buffer_getline(...) dict abort
- if a:0 == 1
- return get(call('getbufline',[self.number()]+a:000),0,'')
- else
- return call('getbufline',[self.number()]+a:000)
- endif
-endfunction
-
-function! s:readable_line_count() dict abort
- return len(self.lines())
-endfunction
-
-function! s:environment()
- if exists('$RAILS_ENV')
- return $RAILS_ENV
- else
- return "development"
- endif
-endfunction
-
-function! s:Complete_environments(...)
- return s:completion_filter(rails#app().environments(),a:0 ? a:1 : "")
-endfunction
-
-function! s:warn(str)
- echohl WarningMsg
- echomsg a:str
- echohl None
- " Sometimes required to flush output
- echo ""
- let v:warningmsg = a:str
-endfunction
-
-function! s:error(str)
- echohl ErrorMsg
- echomsg a:str
- echohl None
- let v:errmsg = a:str
-endfunction
-
-function! s:debug(str)
- if exists("g:rails_debug") && g:rails_debug
- echohl Debug
- echomsg a:str
- echohl None
- endif
-endfunction
-
-function! s:buffer_getvar(varname) dict abort
- return getbufvar(self.number(),a:varname)
-endfunction
-
-function! s:buffer_setvar(varname, val) dict abort
- return setbufvar(self.number(),a:varname,a:val)
-endfunction
-
-call s:add_methods('buffer',['getvar','setvar'])
-
-" }}}1
-" "Public" Interface {{{1
-
-" RailsRoot() is the only official public function
-
-function! rails#underscore(str)
- let str = s:gsub(a:str,'::','/')
- let str = s:gsub(str,'(\u+)(\u\l)','\1_\2')
- let str = s:gsub(str,'(\l|\d)(\u)','\1_\2')
- let str = tolower(str)
- return str
-endfunction
-
-function! rails#camelize(str)
- let str = s:gsub(a:str,'/(.=)','::\u\1')
- let str = s:gsub(str,'%([_-]|<)(.)','\u\1')
- return str
-endfunction
-
-function! rails#singularize(word)
- " Probably not worth it to be as comprehensive as Rails but we can
- " still hit the common cases.
- let word = a:word
- if word =~? '\.js$' || word == ''
- return word
- endif
- let word = s:sub(word,'eople$','ersons')
- let word = s:sub(word,'%([Mm]ov|[aeio])@ 0 && getbufvar(nr,'rails_file_type') != ''
- return getbufvar(nr,'rails_file_type')
- elseif f =~ '_controller\.rb$' || f =~ '\'
- let r = "controller-api"
- else
- let r = "controller"
- endif
- elseif f =~ '_api\.rb'
- let r = "api"
- elseif f =~ '\')
- if class == "ActiveResource::Base"
- let class = "ares"
- let r = "model-ares"
- elseif class == 'ActionMailer::Base'
- let r = "mailer"
- elseif class != ''
- let class = tolower(s:gsub(class,'[^A-Z]',''))
- let r = "model-".class
- elseif f =~ '_mailer\.rb$'
- let r = "mailer"
- elseif top =~ '\<\%(validates_\w\+_of\|set_\%(table_name\|primary_key\)\|has_one\|has_many\|belongs_to\)\>'
- let r = "model-arb"
- else
- let r = "model"
- endif
- elseif f =~ '\.*\.'
- let r = "view-layout-" . e
- elseif f =~ '\<\%(app/views\|components\)/.*/_\k\+\.\k\+\%(\.\k\+\)\=$'
- let r = "view-partial-" . e
- elseif f =~ '\.*\.' || f =~ '\'
- if e == "yml"
- let r = "fixtures-yaml"
- else
- let r = "fixtures" . (e == "" ? "" : "-" . e)
- endif
- elseif f =~ '\'
- let r = "db-migration"
- elseif f=~ '\.*\.rb$'
- let r = "config-routes"
- elseif f =~ '\'
- let cmd = 'script/rails '.a:cmd
- else
- let cmd = 'script/'.a:cmd
- endif
- return self.ruby_shell_command(cmd)
-endfunction
-
-function! s:app_background_script_command(cmd) dict abort
- let cmd = s:esccmd(self.script_shell_command(a:cmd))
- if has_key(self,'options') && has_key(self.options,'gnu_screen')
- let screen = self.options.gnu_screen
- else
- let screen = g:rails_gnu_screen
- endif
- if has("gui_win32")
- if &shellcmdflag == "-c" && ($PATH . &shell) =~? 'cygwin'
- silent exe "!cygstart -d ".s:rquote(self.path())." ruby ".a:cmd
- else
- exe "!start ".cmd
- endif
- elseif exists("$STY") && !has("gui_running") && screen && executable("screen")
- silent exe "!screen -ln -fn -t ".s:sub(s:sub(a:cmd,'\s.*',''),'^%(script|-rcommand)/','rails-').' '.cmd
- elseif exists("$TMUX") && !has("gui_running") && screen && executable("tmux")
- silent exe '!tmux new-window -d -n "'.s:sub(s:sub(a:cmd,'\s.*',''),'^%(script|-rcommand)/','rails-').'" "'.cmd.'"'
- else
- exe "!".cmd
- endif
- return v:shell_error
-endfunction
-
-function! s:app_execute_script_command(cmd) dict abort
- exe '!'.s:esccmd(self.script_shell_command(a:cmd))
- return v:shell_error
-endfunction
-
-function! s:app_lightweight_ruby_eval(ruby,...) dict abort
- let def = a:0 ? a:1 : ""
- if !executable("ruby")
- return def
- endif
- let args = '-e '.s:rquote('begin; require %{rubygems}; rescue LoadError; end; begin; require %{active_support}; rescue LoadError; end; '.a:ruby)
- let cmd = self.ruby_shell_command(args)
- " If the shell is messed up, this command could cause an error message
- silent! let results = system(cmd)
- return v:shell_error == 0 ? results : def
-endfunction
-
-function! s:app_eval(ruby,...) dict abort
- let def = a:0 ? a:1 : ""
- if !executable("ruby")
- return def
- endif
- let args = "-r./config/boot -r ".s:rquote(self.path("config/environment"))." -e ".s:rquote(a:ruby)
- let cmd = self.ruby_shell_command(args)
- " If the shell is messed up, this command could cause an error message
- silent! let results = system(cmd)
- return v:shell_error == 0 ? results : def
-endfunction
-
-call s:add_methods('app', ['ruby_shell_command','script_shell_command','execute_script_command','background_script_command','lightweight_ruby_eval','eval'])
-
-" }}}1
-" Commands {{{1
-
-function! s:prephelp()
- let fn = fnamemodify(s:file,':h:h').'/doc/'
- if filereadable(fn.'rails.txt')
- if !filereadable(fn.'tags') || getftime(fn.'tags') <= getftime(fn.'rails.txt')
- silent! helptags `=fn`
- endif
- endif
-endfunction
-
-function! RailsHelpCommand(...)
- call s:prephelp()
- let topic = a:0 ? a:1 : ""
- if topic == "" || topic == "-"
- return "help rails"
- elseif topic =~ '^g:'
- return "help ".topic
- elseif topic =~ '^-'
- return "help rails".topic
- else
- return "help rails-".topic
- endif
-endfunction
-
-function! s:BufCommands()
- call s:BufFinderCommands()
- call s:BufNavCommands()
- call s:BufScriptWrappers()
- command! -buffer -bar -nargs=? -bang -count -complete=customlist,s:Complete_rake Rake :call s:Rake(0,! && ? -1 : ,)
- command! -buffer -bar -nargs=? -bang -range -complete=customlist,s:Complete_preview Rpreview :call s:Preview(0,,)
- command! -buffer -bar -nargs=? -bang -complete=customlist,s:Complete_environments Rlog :call s:Log(0,)
- command! -buffer -bar -nargs=* -bang -complete=customlist,s:Complete_set Rset :call s:Set(0,)
- command! -buffer -bar -nargs=0 Rtags :call rails#app().tags_command()
- " Embedding all this logic directly into the command makes the error
- " messages more concise.
- command! -buffer -bar -nargs=? -bang Rdoc :
- \ if 0 || =~ "^\\([:'-]\\|g:\\)" |
- \ exe RailsHelpCommand() |
- \ else | call s:Doc(0,) | endif
- command! -buffer -bar -nargs=0 -bang Rrefresh :if 0|unlet! g:autoloaded_rails|source `=s:file`|endif|call s:Refresh(0)
- if exists(":NERDTree")
- command! -buffer -bar -nargs=? -complete=customlist,s:Complete_cd Rtree :NERDTree `=rails#app().path()`
- endif
- if exists("g:loaded_dbext")
- command! -buffer -bar -nargs=? -complete=customlist,s:Complete_environments Rdbext :call s:BufDatabase(2,)|let b:dbext_buffer_defaulted = 1
- endif
- let ext = expand("%:e")
- if ext =~ s:viewspattern()
- " TODO: complete controller names with trailing slashes here
- command! -buffer -bar -bang -nargs=? -range -complete=customlist,s:controllerList Rextract :,call s:Extract(0,)
- endif
- if RailsFilePath() =~ '\0)
- endif
-endfunction
-
-function! s:Doc(bang, string)
- if a:string != ""
- if exists("g:rails_search_url")
- let query = substitute(a:string,'[^A-Za-z0-9_.~-]','\="%".printf("%02X",char2nr(submatch(0)))','g')
- let url = printf(g:rails_search_url, query)
- else
- return s:error("specify a g:rails_search_url with %s for a query placeholder")
- endif
- elseif isdirectory(rails#app().path("doc/api/classes"))
- let url = rails#app().path("/doc/api/index.html")
- elseif s:getpidfor("0.0.0.0","8808") > 0
- let url = "http://localhost:8808"
- else
- let url = "http://api.rubyonrails.org"
- endif
- call s:initOpenURL()
- if exists(":OpenURL")
- exe "OpenURL ".s:escarg(url)
- else
- return s:error("No :OpenURL command found")
- endif
-endfunction
-
-function! s:Log(bang,arg)
- if a:arg == ""
- let lf = "log/".s:environment().".log"
- else
- let lf = "log/".a:arg.".log"
- endif
- let size = getfsize(rails#app().path(lf))
- if size >= 1048576
- call s:warn("Log file is ".((size+512)/1024)."KB. Consider :Rake log:clear")
- endif
- if a:bang
- exe "cgetfile ".lf
- clast
- else
- if exists(":Tail")
- Tail `=rails#app().path(lf)`
- else
- pedit `=rails#app().path(lf)`
- endif
- endif
-endfunction
-
-function! rails#new_app_command(bang,...)
- if a:0 == 0
- let msg = "rails.vim ".g:autoloaded_rails
- if a:bang && exists('b:rails_root') && rails#buffer().type_name() == ''
- echo msg." (Rails)"
- elseif a:bang && exists('b:rails_root')
- echo msg." (Rails-".rails#buffer().type_name().")"
- elseif a:bang
- echo msg
- else
- !rails
- endif
- return
- endif
- let args = map(copy(a:000),'expand(v:val)')
- if a:bang
- let args = ['--force'] + args
- endif
- exe '!rails '.join(map(copy(args),'s:rquote(v:val)'),' ')
- for dir in args
- if dir !~# '^-' && filereadable(dir.'/'.g:rails_default_file)
- edit `=dir.'/'.g:rails_default_file`
- return
- endif
- endfor
-endfunction
-
-function! s:app_tags_command() dict
- if exists("g:Tlist_Ctags_Cmd")
- let cmd = g:Tlist_Ctags_Cmd
- elseif executable("exuberant-ctags")
- let cmd = "exuberant-ctags"
- elseif executable("ctags-exuberant")
- let cmd = "ctags-exuberant"
- elseif executable("ctags")
- let cmd = "ctags"
- elseif executable("ctags.exe")
- let cmd = "ctags.exe"
- else
- return s:error("ctags not found")
- endif
- exe '!'.cmd.' -f '.s:escarg(self.path("tmp/tags")).' -R --langmap="ruby:+.rake.builder.rjs" '.g:rails_ctags_arguments.' '.s:escarg(self.path())
-endfunction
-
-call s:add_methods('app',['tags_command'])
-
-function! s:Refresh(bang)
- if exists("g:rubycomplete_rails") && g:rubycomplete_rails && has("ruby") && exists('g:rubycomplete_completions')
- silent! ruby ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
- silent! ruby if defined?(ActiveSupport::Dependencies); ActiveSupport::Dependencies.clear; elsif defined?(Dependencies); Dependencies.clear; end
- if a:bang
- silent! ruby ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
- endif
- endif
- call rails#app().cache.clear()
- silent doautocmd User BufLeaveRails
- if a:bang
- for key in keys(s:apps)
- if type(s:apps[key]) == type({})
- call s:apps[key].cache.clear()
- endif
- call extend(s:apps[key],filter(copy(s:app_prototype),'type(v:val) == type(function("tr"))'),'force')
- endfor
- endif
- let i = 1
- let max = bufnr('$')
- while i <= max
- let rr = getbufvar(i,"rails_root")
- if rr != ""
- call setbufvar(i,"rails_refresh",1)
- endif
- let i += 1
- endwhile
- silent doautocmd User BufEnterRails
-endfunction
-
-function! s:RefreshBuffer()
- if exists("b:rails_refresh") && b:rails_refresh
- let oldroot = b:rails_root
- unlet! b:rails_root
- let b:rails_refresh = 0
- call RailsBufInit(oldroot)
- unlet! b:rails_refresh
- endif
-endfunction
-
-" }}}1
-" Rake {{{1
-
-function! s:app_rake_tasks() dict
- if self.cache.needs('rake_tasks')
- call s:push_chdir()
- try
- let lines = split(system("rake -T"),"\n")
- finally
- call s:pop_command()
- endtry
- if v:shell_error != 0
- return []
- endif
- call map(lines,'matchstr(v:val,"^rake\\s\\+\\zs\\S*")')
- call filter(lines,'v:val != ""')
- call self.cache.set('rake_tasks',lines)
- endif
- return self.cache.get('rake_tasks')
-endfunction
-
-call s:add_methods('app', ['rake_tasks'])
-
-let s:efm_backtrace='%D(in\ %f),'
- \.'%\\s%#from\ %f:%l:%m,'
- \.'%\\s%#from\ %f:%l:,'
- \.'%\\s#{RAILS_ROOT}/%f:%l:\ %#%m,'
- \.'%\\s%##\ %f:%l:%m,'
- \.'%\\s%##\ %f:%l,'
- \.'%\\s%#[%f:%l:\ %#%m,'
- \.'%\\s%#%f:%l:\ %#%m,'
- \.'%\\s%#%f:%l:,'
- \.'%m\ [%f:%l]:'
-
-function! s:makewithruby(arg,bang,...)
- let old_make = &makeprg
- try
- let &l:makeprg = rails#app().ruby_shell_command(a:arg)
- exe 'make'.(a:bang ? '!' : '')
- if !a:bang
- cwindow
- endif
- finally
- let &l:makeprg = old_make
- endtry
-endfunction
-
-function! s:Rake(bang,lnum,arg)
- let self = rails#app()
- let lnum = a:lnum < 0 ? 0 : a:lnum
- let old_makeprg = &l:makeprg
- let old_errorformat = &l:errorformat
- try
- if exists('b:bundler_root') && b:bundler_root ==# rails#app().path()
- let &l:makeprg = 'bundle exec rake'
- else
- let &l:makeprg = 'rake'
- endif
- let &l:errorformat = s:efm_backtrace
- let arg = a:arg
- if &filetype == "ruby" && arg == '' && g:rails_modelines
- let mnum = s:lastmethodline(lnum)
- let str = getline(mnum)."\n".getline(mnum+1)."\n".getline(mnum+2)."\n"
- let pat = '\s\+\zs.\{-\}\ze\%(\n\|\s\s\|#{\@!\|$\)'
- let mat = matchstr(str,'#\s*rake'.pat)
- let mat = s:sub(mat,'\s+$','')
- if mat != ""
- let arg = mat
- endif
- endif
- if arg == ''
- let opt = s:getopt('task','bl')
- if opt != ''
- let arg = opt
- else
- let arg = rails#buffer().default_rake_task(lnum)
- endif
- endif
- if !has_key(self,'options') | let self.options = {} | endif
- if arg == '-'
- let arg = get(self.options,'last_rake_task','')
- endif
- let self.options['last_rake_task'] = arg
- let withrubyargs = '-r ./config/boot -r '.s:rquote(self.path('config/environment')).' -e "puts \%((in \#{Dir.getwd}))" '
- if arg =~# '^notes\>'
- let &l:errorformat = '%-P%f:,\ \ *\ [%*[\ ]%l]\ [%t%*[^]]] %m,\ \ *\ [%*[\ ]%l] %m,%-Q'
- " %D to chdir is apparently incompatible with %P multiline messages
- call s:push_chdir(1)
- exe 'make! '.arg
- call s:pop_command()
- if !a:bang
- cwindow
- endif
- elseif arg =~# '^\%(stats\|routes\|secret\|time:zones\|db:\%(charset\|collation\|fixtures:identify\>.*\|migrate:status\|version\)\)\%([: ]\|$\)'
- let &l:errorformat = '%D(in\ %f),%+G%.%#'
- exe 'make! '.arg
- if !a:bang
- copen
- endif
- elseif arg =~ '^preview\>'
- exe (lnum == 0 ? '' : lnum).'R'.s:gsub(arg,':','/')
- elseif arg =~ '^runner:'
- let arg = s:sub(arg,'^runner:','')
- let root = matchstr(arg,'%\%(:\w\)*')
- let file = expand(root).matchstr(arg,'%\%(:\w\)*\zs.*')
- if file =~ '#.*$'
- let extra = " -- -n ".matchstr(file,'#\zs.*')
- let file = s:sub(file,'#.*','')
- else
- let extra = ''
- endif
- if self.has_file(file) || self.has_file(file.'.rb')
- call s:makewithruby(withrubyargs.'-r"'.file.'"'.extra,a:bang,file !~# '_\%(spec\|test\)\%(\.rb\)\=$')
- else
- call s:makewithruby(withrubyargs.'-e '.s:esccmd(s:rquote(arg)),a:bang)
- endif
- elseif arg == 'run' || arg == 'runner'
- call s:makewithruby(withrubyargs.'-r"'.RailsFilePath().'"',a:bang,RailsFilePath() !~# '_\%(spec\|test\)\%(\.rb\)\=$')
- elseif arg =~ '^run:'
- let arg = s:sub(arg,'^run:','')
- let arg = s:sub(arg,'^\%:h',expand('%:h'))
- let arg = s:sub(arg,'^%(\%|$|#@=)',expand('%'))
- let arg = s:sub(arg,'#(\w+[?!=]=)$',' -- -n\1')
- call s:makewithruby(withrubyargs.'-r'.arg,a:bang,arg !~# '_\%(spec\|test\)\.rb$')
- else
- exe 'make! '.arg
- if !a:bang
- cwindow
- endif
- endif
- finally
- let &l:errorformat = old_errorformat
- let &l:makeprg = old_makeprg
- endtry
-endfunction
-
-function! s:readable_default_rake_task(lnum) dict abort
- let app = self.app()
- let lnum = a:lnum < 0 ? 0 : a:lnum
- if self.getvar('&buftype') == 'quickfix'
- return '-'
- elseif self.getline(lnum) =~# '# rake '
- return matchstr(self.getline(lnum),'\C# rake \zs.*')
- elseif self.getline(self.last_method_line(lnum)-1) =~# '# rake '
- return matchstr(self.getline(self.last_method_line(lnum)-1),'\C# rake \zs.*')
- elseif self.getline(self.last_method_line(lnum)) =~# '# rake '
- return matchstr(self.getline(self.last_method_line(lnum)),'\C# rake \zs.*')
- elseif self.getline(1) =~# '# rake ' && !lnum
- return matchstr(self.getline(1),'\C# rake \zs.*')
- elseif self.type_name('config-routes')
- return 'routes'
- elseif self.type_name('fixtures-yaml') && lnum
- return "db:fixtures:identify LABEL=".self.last_method(lnum)
- elseif self.type_name('fixtures') && lnum == 0
- return "db:fixtures:load FIXTURES=".s:sub(fnamemodify(self.name(),':r'),'^.{-}/fixtures/','')
- elseif self.type_name('task')
- let mnum = self.last_method_line(lnum)
- let line = getline(mnum)
- " We can't grab the namespace so only run tasks at the start of the line
- if line =~# '^\%(task\|file\)\>'
- return self.last_method(a:lnum)
- else
- return matchstr(self.getline(1),'\C# rake \zs.*')
- endif
- elseif self.type_name('spec')
- if self.name() =~# '\ 0
- return 'spec SPEC="'.self.path().'":'.lnum
- else
- return 'spec SPEC="'.self.path().'"'
- endif
- elseif self.type_name('test')
- let meth = self.last_method(lnum)
- if meth =~ '^test_'
- let call = " -n".meth.""
- else
- let call = ""
- endif
- if self.type_name('test-unit','test-functional','test-integration')
- return s:sub(s:gsub(self.type_name(),'-',':'),'unit$|functional$','&s').' TEST="'.self.path().'"'.s:sub(call,'^ ',' TESTOPTS=')
- elseif self.name() =~# '\ 0
- return 'cucumber FEATURE="'.self.path().'":'.lnum
- else
- return 'cucumber FEATURE="'.self.path().'"'
- endif
- elseif self.type_name('cucumber')
- return 'cucumber'
- else
- return ''
- endif
-endfunction
-
-function! s:Complete_rake(A,L,P)
- return s:completion_filter(rails#app().rake_tasks(),a:A)
-endfunction
-
-call s:add_methods('readable',['default_rake_task'])
-
-" }}}1
-" Preview {{{1
-
-function! s:initOpenURL()
- if !exists(":OpenURL")
- if has("gui_mac") || has("gui_macvim") || exists("$SECURITYSESSIONID")
- command -bar -nargs=1 OpenURL :!open
- elseif has("gui_win32")
- command -bar -nargs=1 OpenURL :!start cmd /cstart /b
- elseif executable("sensible-browser")
- command -bar -nargs=1 OpenURL :!sensible-browser
- endif
- endif
-endfunction
-
-function! s:scanlineforuris(line)
- let url = matchstr(a:line,"\\v\\C%(%(GET|PUT|POST|DELETE)\\s+|\\w+://[^/]*)/[^ \n\r\t<>\"]*[^] .,;\n\r\t<>\":]")
- if url =~ '\C^\u\+\s\+'
- let method = matchstr(url,'^\u\+')
- let url = matchstr(url,'\s\+\zs.*')
- if method !=? "GET"
- let url .= (url =~ '?' ? '&' : '?') . '_method='.tolower(method)
- endif
- endif
- if url != ""
- return [url]
- else
- return []
- endif
-endfunction
-
-function! s:readable_preview_urls(lnum) dict abort
- let urls = []
- let start = self.last_method_line(a:lnum) - 1
- while start > 0 && self.getline(start) =~ '^\s*\%(\%(-\=\|<%\)#.*\)\=$'
- let urls = s:scanlineforuris(self.getline(start)) + urls
- let start -= 1
- endwhile
- let start = 1
- while start < self.line_count() && self.getline(start) =~ '^\s*\%(\%(-\=\|<%\)#.*\)\=$'
- let urls += s:scanlineforuris(self.getline(start))
- let start += 1
- endwhile
- if has_key(self,'getvar') && self.getvar('rails_preview') != ''
- let url += [self.getvar('rails_preview')]
- end
- if self.name() =~ '^public/stylesheets/sass/'
- let urls = urls + [s:sub(s:sub(self.name(),'^public/stylesheets/sass/','/stylesheets/'),'\.s[ac]ss$','.css')]
- elseif self.name() =~ '^public/'
- let urls = urls + [s:sub(self.name(),'^public','')]
- elseif self.name() =~ '^app/assets/stylesheets/'
- let urls = urls + ['/assets/application.css']
- elseif self.name() =~ '^app/assets/javascripts/'
- let urls = urls + ['/assets/application.js']
- elseif self.name() =~ '^app/stylesheets/'
- let urls = urls + [s:sub(s:sub(self.name(),'^app/stylesheets/','/stylesheets/'),'\.less$','.css')]
- elseif self.name() =~ '^app/scripts/'
- let urls = urls + [s:sub(s:sub(self.name(),'^app/scripts/','/javascripts/'),'\.coffee$','.js')]
- elseif self.controller_name() != '' && self.controller_name() != 'application'
- if self.type_name('controller') && self.last_method(a:lnum) != ''
- let urls += ['/'.self.controller_name().'/'.self.last_method(a:lnum).'/']
- elseif self.type_name('controller','view-layout','view-partial')
- let urls += ['/'.self.controller_name().'/']
- elseif self.type_name('view')
- let urls += ['/'.s:controller().'/'.fnamemodify(self.name(),':t:r:r').'/']
- endif
- endif
- return urls
-endfunction
-
-call s:add_methods('readable',['preview_urls'])
-
-function! s:Preview(bang,lnum,arg)
- let root = s:getopt("root_url")
- if root == ''
- let root = s:getopt("url")
- endif
- let root = s:sub(root,'/$','')
- if a:arg =~ '://'
- let uri = a:arg
- elseif a:arg != ''
- let uri = root.'/'.s:sub(a:arg,'^/','')
- else
- let uri = get(rails#buffer().preview_urls(a:lnum),0,'')
- let uri = root.'/'.s:sub(s:sub(uri,'^/',''),'/$','')
- endif
- call s:initOpenURL()
- if exists(':OpenURL') && !a:bang
- exe 'OpenURL '.uri
- else
- " Work around bug where URLs ending in / get handled as FTP
- let url = uri.(uri =~ '/$' ? '?' : '')
- silent exe 'pedit '.url
- wincmd w
- if &filetype == ''
- if uri =~ '\.css$'
- setlocal filetype=css
- elseif uri =~ '\.js$'
- setlocal filetype=javascript
- elseif getline(1) =~ '^\s*<'
- setlocal filetype=xhtml
- endif
- endif
- call RailsBufInit(rails#app().path())
- map q :bwipe
- wincmd p
- if !a:bang
- call s:warn("Define a :OpenURL command to use a browser")
- endif
- endif
-endfunction
-
-function! s:Complete_preview(A,L,P)
- return rails#buffer().preview_urls(a:L =~ '^\d' ? matchstr(a:L,'^\d\+') : line('.'))
-endfunction
-
-" }}}1
-" Script Wrappers {{{1
-
-function! s:BufScriptWrappers()
- command! -buffer -bar -nargs=* -complete=customlist,s:Complete_script Rscript :call rails#app().script_command(0,)
- command! -buffer -bar -nargs=* -complete=customlist,s:Complete_generate Rgenerate :call rails#app().generate_command(0,)
- command! -buffer -bar -nargs=* -complete=customlist,s:Complete_destroy Rdestroy :call rails#app().destroy_command(0,)
- command! -buffer -bar -nargs=? -bang -complete=customlist,s:Complete_server Rserver :call rails#app().server_command(0,)
- command! -buffer -bang -nargs=1 -range=0 -complete=customlist,s:Complete_ruby Rrunner :call rails#app().runner_command(0 ? -2 : (==?:-1),)
- command! -buffer -nargs=1 -range=0 -complete=customlist,s:Complete_ruby Rp :call rails#app().runner_command(==?:-1,'p begin '..' end')
- command! -buffer -nargs=1 -range=0 -complete=customlist,s:Complete_ruby Rpp :call rails#app().runner_command(==?:-1,'require %{pp}; pp begin '..' end')
- command! -buffer -nargs=1 -range=0 -complete=customlist,s:Complete_ruby Ry :call rails#app().runner_command(==?:-1,'y begin '..' end')
-endfunction
-
-function! s:app_generators() dict
- if self.cache.needs('generators')
- let generators = self.relglob("vendor/plugins/","*/generators/*")
- let generators += self.relglob("","lib/generators/*")
- call filter(generators,'v:val =~ "/$"')
- let generators += split(glob(expand("~/.rails/generators")."/*"),"\n")
- call map(generators,'s:sub(v:val,"^.*[\\\\/]generators[\\\\/]\\ze.","")')
- call map(generators,'s:sub(v:val,"[\\\\/]$","")')
- call self.cache.set('generators',generators)
- endif
- return sort(split(g:rails_generators,"\n") + self.cache.get('generators'))
-endfunction
-
-function! s:app_script_command(bang,...) dict
- let str = ""
- let cmd = a:0 ? a:1 : "console"
- let c = 2
- while c <= a:0
- let str .= " " . s:rquote(a:{c})
- let c += 1
- endwhile
- if cmd ==# "plugin"
- call self.cache.clear('generators')
- endif
- if a:bang || cmd =~# 'console'
- return self.background_script_command(cmd.str)
- else
- return self.execute_script_command(cmd.str)
- endif
-endfunction
-
-function! s:app_runner_command(count,args) dict
- if a:count == -2
- return self.script_command(a:bang,"runner",a:args)
- else
- let str = self.ruby_shell_command('-r./config/boot -e "require '."'commands/runner'".'" '.s:rquote(a:args))
- let res = s:sub(system(str),'\n$','')
- if a:count < 0
- echo res
- else
- exe a:count.'put =res'
- endif
- endif
-endfunction
-
-function! s:getpidfor(bind,port)
- if has("win32") || has("win64")
- let netstat = system("netstat -anop tcp")
- let pid = matchstr(netstat,'\<'.a:bind.':'.a:port.'\>.\{-\}LISTENING\s\+\zs\d\+')
- elseif executable('lsof')
- let pid = system("lsof -i 4tcp@".a:bind.':'.a:port."|grep LISTEN|awk '{print $2}'")
- let pid = s:sub(pid,'\n','')
- else
- let pid = ""
- endif
- return pid
-endfunction
-
-function! s:app_server_command(bang,arg) dict
- let port = matchstr(a:arg,'\%(-p\|--port=\=\)\s*\zs\d\+')
- if port == ''
- let port = "3000"
- endif
- " TODO: Extract bind argument
- let bind = "0.0.0.0"
- if a:bang && executable("ruby")
- let pid = s:getpidfor(bind,port)
- if pid =~ '^\d\+$'
- echo "Killing server with pid ".pid
- if !has("win32")
- call system("ruby -e 'Process.kill(:TERM,".pid.")'")
- sleep 100m
- endif
- call system("ruby -e 'Process.kill(9,".pid.")'")
- sleep 100m
- endif
- if a:arg == "-"
- return
- endif
- endif
- if has_key(self,'options') && has_key(self.options,'gnu_screen')
- let screen = self.options.gnu_screen
- else
- let screen = g:rails_gnu_screen
- endif
- if has("win32") || has("win64") || (exists("$STY") && !has("gui_running") && screen && executable("screen")) || (exists("$TMUX") && !has("gui_running") && screen && executable("tmux"))
- call self.background_script_command('server '.a:arg)
- else
- " --daemon would be more descriptive but lighttpd does not support it
- call self.execute_script_command('server '.a:arg." -d")
- endif
- call s:setopt('a:root_url','http://'.(bind=='0.0.0.0'?'localhost': bind).':'.port.'/')
-endfunction
-
-function! s:app_destroy_command(bang,...) dict
- if a:0 == 0
- return self.execute_script_command('destroy')
- elseif a:0 == 1
- return self.execute_script_command('destroy '.s:rquote(a:1))
- endif
- let str = ""
- let c = 1
- while c <= a:0
- let str .= " " . s:rquote(a:{c})
- let c += 1
- endwhile
- call self.execute_script_command('destroy'.str)
- call self.cache.clear('user_classes')
-endfunction
-
-function! s:app_generate_command(bang,...) dict
- if a:0 == 0
- return self.execute_script_command('generate')
- elseif a:0 == 1
- return self.execute_script_command('generate '.s:rquote(a:1))
- endif
- let cmd = join(map(copy(a:000),'s:rquote(v:val)'),' ')
- if cmd !~ '-p\>' && cmd !~ '--pretend\>'
- let execstr = self.script_shell_command('generate '.cmd.' -p -f')
- let res = system(execstr)
- let g:res = res
- let junk = '\%(\e\[[0-9;]*m\)\='
- let file = matchstr(res,junk.'\s\+\%(create\|force\)'.junk.'\s\+\zs\f\+\.rb\ze\n')
- if file == ""
- let file = matchstr(res,junk.'\s\+\%(identical\)'.junk.'\s\+\zs\f\+\.rb\ze\n')
- endif
- else
- let file = ""
- endif
- if !self.execute_script_command('generate '.cmd) && file != ''
- call self.cache.clear('user_classes')
- call self.cache.clear('features')
- if file =~ '^db/migrate/\d\d\d\d'
- let file = get(self.relglob('',s:sub(file,'\d+','[0-9]*[0-9]')),-1,file)
- endif
- edit `=self.path(file)`
- endif
-endfunction
-
-call s:add_methods('app', ['generators','script_command','runner_command','server_command','destroy_command','generate_command'])
-
-function! s:Complete_script(ArgLead,CmdLine,P)
- let cmd = s:sub(a:CmdLine,'^\u\w*\s+','')
- if cmd !~ '^[ A-Za-z0-9_=:-]*$'
- return []
- elseif cmd =~# '^\w*$'
- return s:completion_filter(rails#app().relglob("script/","**/*"),a:ArgLead)
- elseif cmd =~# '^\%(plugin\)\s\+'.a:ArgLead.'$'
- return s:completion_filter(["discover","list","install","update","remove","source","unsource","sources"],a:ArgLead)
- elseif cmd =~# '\%(plugin\)\s\+\%(install\|remove\)\s\+'.a:ArgLead.'$' || cmd =~ '\%(generate\|destroy\)\s\+plugin\s\+'.a:ArgLead.'$'
- return s:pluginList(a:ArgLead,a:CmdLine,a:P)
- elseif cmd =~# '^\%(generate\|destroy\)\s\+'.a:ArgLead.'$'
- return s:completion_filter(rails#app().generators(),a:ArgLead)
- elseif cmd =~# '^\%(generate\|destroy\)\s\+\w\+\s\+'.a:ArgLead.'$'
- let target = matchstr(cmd,'^\w\+\s\+\%(\w\+:\)\=\zs\w\+\ze\s\+')
- if target =~# '^\w*controller$'
- return filter(s:controllerList(a:ArgLead,"",""),'v:val !=# "application"')
- elseif target ==# 'generator'
- return s:completion_filter(map(rails#app().relglob('lib/generators/','*'),'s:sub(v:val,"/$","")'))
- elseif target ==# 'helper'
- return s:helperList(a:ArgLead,"","")
- elseif target ==# 'integration_test' || target ==# 'integration_spec' || target ==# 'feature'
- return s:integrationtestList(a:ArgLead,"","")
- elseif target ==# 'metal'
- return s:metalList(a:ArgLead,"","")
- elseif target ==# 'migration' || target ==# 'session_migration'
- return s:migrationList(a:ArgLead,"","")
- elseif target =~# '^\w*\%(model\|resource\)$' || target =~# '\w*scaffold\%(_controller\)\=$' || target ==# 'mailer'
- return s:modelList(a:ArgLead,"","")
- elseif target ==# 'observer'
- let observers = s:observerList("","","")
- let models = s:modelList("","","")
- if cmd =~# '^destroy\>'
- let models = []
- endif
- call filter(models,'index(observers,v:val) < 0')
- return s:completion_filter(observers + models,a:ArgLead)
- else
- return []
- endif
- elseif cmd =~# '^\%(generate\|destroy\)\s\+scaffold\s\+\w\+\s\+'.a:ArgLead.'$'
- return filter(s:controllerList(a:ArgLead,"",""),'v:val !=# "application"')
- return s:completion_filter(rails#app().environments())
- elseif cmd =~# '^\%(console\)\s\+\(--\=\w\+\s\+\)\='.a:ArgLead."$"
- return s:completion_filter(rails#app().environments()+["-s","--sandbox"],a:ArgLead)
- elseif cmd =~# '^\%(server\)\s\+.*-e\s\+'.a:ArgLead."$"
- return s:completion_filter(rails#app().environments(),a:ArgLead)
- elseif cmd =~# '^\%(server\)\s\+'
- if a:ArgLead =~# '^--environment='
- return s:completion_filter(map(copy(rails#app().environments()),'"--environment=".v:val'),a:ArgLead)
- else
- return filter(["-p","-b","-e","-m","-d","-u","-c","-h","--port=","--binding=","--environment=","--mime-types=","--daemon","--debugger","--charset=","--help"],'s:startswith(v:val,a:ArgLead)')
- endif
- endif
- return ""
-endfunction
-
-function! s:CustomComplete(A,L,P,cmd)
- let L = "Rscript ".a:cmd." ".s:sub(a:L,'^\h\w*\s+','')
- let P = a:P - strlen(a:L) + strlen(L)
- return s:Complete_script(a:A,L,P)
-endfunction
-
-function! s:Complete_server(A,L,P)
- return s:CustomComplete(a:A,a:L,a:P,"server")
-endfunction
-
-function! s:Complete_console(A,L,P)
- return s:CustomComplete(a:A,a:L,a:P,"console")
-endfunction
-
-function! s:Complete_generate(A,L,P)
- return s:CustomComplete(a:A,a:L,a:P,"generate")
-endfunction
-
-function! s:Complete_destroy(A,L,P)
- return s:CustomComplete(a:A,a:L,a:P,"destroy")
-endfunction
-
-function! s:Complete_ruby(A,L,P)
- return s:completion_filter(rails#app().user_classes()+["ActiveRecord::Base"],a:A)
-endfunction
-
-" }}}1
-" Navigation {{{1
-
-function! s:BufNavCommands()
- command! -buffer -bar -nargs=? -complete=customlist,s:Complete_cd Rcd :cd `=rails#app().path()`
- command! -buffer -bar -nargs=? -complete=customlist,s:Complete_cd Rlcd :lcd `=rails#app().path()`
- command! -buffer -bar -nargs=* -count=1 -complete=customlist,s:Complete_find Rfind :call s:Find(,'' ,)
- command! -buffer -bar -nargs=* -count=1 -complete=customlist,s:Complete_find REfind :call s:Find(,'E',)
- command! -buffer -bar -nargs=* -count=1 -complete=customlist,s:Complete_find RSfind :call s:Find(,'S',)
- command! -buffer -bar -nargs=* -count=1 -complete=customlist,s:Complete_find RVfind :call s:Find(,'V',)
- command! -buffer -bar -nargs=* -count=1 -complete=customlist,s:Complete_find RTfind :call s:Find(,'T',)
- command! -buffer -bar -nargs=* -count=1 -complete=customlist,s:Complete_find Rsfind :RSfind
- command! -buffer -bar -nargs=* -count=1 -complete=customlist,s:Complete_find Rtabfind :RTfind
- command! -buffer -bar -nargs=* -bang -complete=customlist,s:Complete_edit Redit :call s:Edit(,'' ,)
- command! -buffer -bar -nargs=* -bang -complete=customlist,s:Complete_edit REedit :call s:Edit(,'E',)
- command! -buffer -bar -nargs=* -bang -complete=customlist,s:Complete_edit RSedit :call s:Edit(,'S',)
- command! -buffer -bar -nargs=* -bang -complete=customlist,s:Complete_edit RVedit :call s:Edit(,'V',)
- command! -buffer -bar -nargs=* -bang -complete=customlist,s:Complete_edit RTedit :call s:Edit(,'T',)
- command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_edit RDedit :call s:Edit(,'D',)
- command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related A :call s:Alternate('', ,,,)
- command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related AE :call s:Alternate('E',,,,)
- command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related AS :call s:Alternate('S',,,,)
- command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related AV :call s:Alternate('V',,,,)
- command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related AT :call s:Alternate('T',,,,)
- command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related AD :call s:Alternate('D',,,,)
- command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related AN :call s:Related('' ,,,,)
- command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related R :call s:Related('' ,,,,)
- command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related RE :call s:Related('E',,,,)
- command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related RS :call s:Related('S',,,,)
- command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related RV :call s:Related('V',,,,)
- command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related RT :call s:Related('T',,,,)
- command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related RD :call s:Related('D',,,,)
-endfunction
-
-function! s:djump(def)
- let def = s:sub(a:def,'^[#:]','')
- if def =~ '^\d\+$'
- exe def
- elseif def =~ '^!'
- if expand('%') !~ '://' && !isdirectory(expand('%:p:h'))
- call mkdir(expand('%:p:h'),'p')
- endif
- elseif def != ''
- let ext = matchstr(def,'\.\zs.*')
- let def = matchstr(def,'[^.]*')
- let v:errmsg = ''
- silent! exe "djump ".def
- if ext != '' && (v:errmsg == '' || v:errmsg =~ '^E387')
- let rpat = '\C^\s*\%(mail\>.*\|respond_to\)\s*\%(\ 0
- let variable = matchstr(getline(rline),rpat)
- let success = search('\C^\s*'.variable.'\s*\.\s*\zs'.ext.'\>','',end)
- if !success
- silent! exe "djump ".def
- endif
- endif
- endif
- endif
-endfunction
-
-function! s:Find(count,cmd,...)
- let str = ""
- if a:0
- let i = 1
- while i < a:0
- let str .= s:escarg(a:{i}) . " "
- let i += 1
- endwhile
- let file = a:{i}
- let tail = matchstr(file,'[#!].*$\|:\d*\%(:in\>.*\)\=$')
- if tail != ""
- let file = s:sub(file,'[#!].*$|:\d*%(:in>.*)=$','')
- endif
- if file != ""
- let file = s:RailsIncludefind(file)
- endif
- else
- let file = s:RailsFind()
- let tail = ""
- endif
- call s:findedit((a:count==1?'' : a:count).a:cmd,file.tail,str)
-endfunction
-
-function! s:Edit(count,cmd,...)
- if a:0
- let str = ""
- let i = 1
- while i < a:0
- let str .= "`=a:".i."` "
- let i += 1
- endwhile
- let file = a:{i}
- call s:findedit(s:editcmdfor(a:cmd),file,str)
- else
- exe s:editcmdfor(a:cmd)
- endif
-endfunction
-
-function! s:fuzzyglob(arg)
- return s:gsub(s:gsub(a:arg,'[^/.]','[&]*'),'%(/|^)\.@!|\.','&*')
-endfunction
-
-function! s:Complete_find(ArgLead, CmdLine, CursorPos)
- let paths = s:pathsplit(&l:path)
- let seen = {}
- for path in paths
- if s:startswith(path,rails#app().path()) && path !~ '[][*]'
- let path = path[strlen(rails#app().path()) + 1 : ]
- for file in rails#app().relglob(path == '' ? '' : path.'/',s:fuzzyglob(rails#underscore(a:ArgLead)), a:ArgLead =~# '\u' ? '.rb' : '')
- let seen[file] = 1
- endfor
- endif
- endfor
- return s:autocamelize(sort(keys(seen)),a:ArgLead)
-endfunction
-
-function! s:Complete_edit(ArgLead, CmdLine, CursorPos)
- return s:completion_filter(rails#app().relglob("",s:fuzzyglob(a:ArgLead)),a:ArgLead)
-endfunction
-
-function! s:Complete_cd(ArgLead, CmdLine, CursorPos)
- let all = rails#app().relglob("",a:ArgLead."*")
- call filter(all,'v:val =~ "/$"')
- return filter(all,'s:startswith(v:val,a:ArgLead)')
-endfunction
-
-function! RailsIncludeexpr()
- " Is this foolproof?
- if mode() =~ '[iR]' || expand("") != v:fname
- return s:RailsIncludefind(v:fname)
- else
- return s:RailsIncludefind(v:fname,1)
- endif
-endfunction
-
-function! s:linepeak()
- let line = getline(line("."))
- let line = s:sub(line,'^(.{'.col(".").'}).*','\1')
- let line = s:sub(line,'([:"'."'".']|\%[qQ]=[[({<])=\f*$','')
- return line
-endfunction
-
-function! s:matchcursor(pat)
- let line = getline(".")
- let lastend = 0
- while lastend >= 0
- let beg = match(line,'\C'.a:pat,lastend)
- let end = matchend(line,'\C'.a:pat,lastend)
- if beg < col(".") && end >= col(".")
- return matchstr(line,'\C'.a:pat,lastend)
- endif
- let lastend = end
- endwhile
- return ""
-endfunction
-
-function! s:findit(pat,repl)
- let res = s:matchcursor(a:pat)
- if res != ""
- return substitute(res,'\C'.a:pat,a:repl,'')
- else
- return ""
- endif
-endfunction
-
-function! s:findamethod(func,repl)
- return s:findit('\s*\<\%('.a:func.'\)\s*(\=\s*[@:'."'".'"]\(\f\+\)\>.\=',a:repl)
-endfunction
-
-function! s:findasymbol(sym,repl)
- return s:findit('\s*\%(:\%('.a:sym.'\)\s*=>\|\<'.a:sym.':\)\s*(\=\s*[@:'."'".'"]\(\f\+\)\>.\=',a:repl)
-endfunction
-
-function! s:findfromview(func,repl)
- " ( ) ( ) ( \1 ) ( )
- return s:findit('\s*\%(<%\)\==\=\s*\<\%('.a:func.'\)\s*(\=\s*[@:'."'".'"]\(\f\+\)\>['."'".'"]\=\s*\%(%>\s*\)\=',a:repl)
-endfunction
-
-function! s:RailsFind()
- if filereadable(expand(""))
- return expand("")
- endif
-
- " UGH
- let buffer = rails#buffer()
- let format = s:format('html')
-
- let res = s:findit('\v\s*.=',expand('%:h').'/\1')
- if res != ""|return res.(fnamemodify(res,':e') == '' ? '.rb' : '')|endif
-
- let res = s:findit('\v['."'".'"]=',expand('%:h').'\1')
- if res != ""|return res|endif
-
- let res = rails#underscore(s:findit('\v\s*<%(include|extend)\(=\s*<([[:alnum:]_:]+)>','\1'))
- if res != ""|return res.".rb"|endif
-
- let res = s:findamethod('require','\1')
- if res != ""|return res.(fnamemodify(res,':e') == '' ? '.rb' : '')|endif
-
- let res = s:findamethod('belongs_to\|has_one\|composed_of\|validates_associated\|scaffold','app/models/\1.rb')
- if res != ""|return res|endif
-
- let res = rails#singularize(s:findamethod('has_many\|has_and_belongs_to_many','app/models/\1'))
- if res != ""|return res.".rb"|endif
-
- let res = rails#singularize(s:findamethod('create_table\|change_table\|drop_table\|add_column\|rename_column\|remove_column\|add_index','app/models/\1'))
- if res != ""|return res.".rb"|endif
-
- let res = rails#singularize(s:findasymbol('through','app/models/\1'))
- if res != ""|return res.".rb"|endif
-
- let res = s:findamethod('fixtures','fixtures/\1')
- if res != ""
- return RailsFilePath() =~ '\\|\\|,\s*to:\)\s*','app/controllers/\1')
- if res =~ '#'|return s:sub(res,'#','_controller.rb#')|endif
-
- let res = s:findamethod('layout','\=s:findlayout(submatch(1))')
- if res != ""|return res|endif
-
- let res = s:findasymbol('layout','\=s:findlayout(submatch(1))')
- if res != ""|return res|endif
-
- let res = s:findamethod('helper','app/helpers/\1_helper.rb')
- if res != ""|return res|endif
-
- let res = s:findasymbol('controller','app/controllers/\1_controller.rb')
- if res != ""|return res|endif
-
- let res = s:findasymbol('action','\1')
- if res != ""|return res|endif
-
- let res = s:findasymbol('template','app/views/\1')
- if res != ""|return res|endif
-
- let res = s:sub(s:sub(s:findasymbol('partial','\1'),'^/',''),'[^/]+$','_&')
- if res != ""|return res."\n".s:findview(res)|endif
-
- let res = s:sub(s:sub(s:findfromview('render\s*(\=\s*\%(:partial\s\+=>\|partial:\)\s*','\1'),'^/',''),'[^/]+$','_&')
- if res != ""|return res."\n".s:findview(res)|endif
-
- let res = s:findamethod('render\>\s*\%(:\%(template\|action\)\s\+=>\|template:\|action:\)\s*','\1.'.format.'\n\1')
- if res != ""|return res|endif
-
- let res = s:sub(s:findfromview('render','\1'),'^/','')
- if buffer.type_name('view') | let res = s:sub(res,'[^/]+$','_&') | endif
- if res != ""|return res."\n".s:findview(res)|endif
-
- let res = s:findamethod('redirect_to\s*(\=\s*\%\(:action\s\+=>\|\','/application')
- if res != '' && fnamemodify(res, ':e') == '' " Append the default extension iff the filename doesn't already contains an extension
- let res .= '.js'
- end
- if res != ""|return res|endif
-
- if buffer.type_name('controller')
- let contr = s:controller()
- let view = s:findit('\s*\(\=','/\1')
- let res = s:findview(contr.'/'.view)
- if res != ""|return res|endif
- endif
-
- let old_isfname = &isfname
- try
- set isfname=@,48-57,/,-,_,:,#
- " TODO: grab visual selection in visual mode
- let cfile = expand("")
- finally
- let &isfname = old_isfname
- endtry
- let res = s:RailsIncludefind(cfile,1)
- return res
-endfunction
-
-function! s:app_named_route_file(route) dict
- call self.route_names()
- if self.cache.has("named_routes") && has_key(self.cache.get("named_routes"),a:route)
- return self.cache.get("named_routes")[a:route]
- endif
- return ""
-endfunction
-
-function! s:app_route_names() dict
- if self.cache.needs("named_routes")
- let exec = "ActionController::Routing::Routes.named_routes.each {|n,r| puts %{#{n} app/controllers/#{r.requirements[:controller]}_controller.rb##{r.requirements[:action]}}}"
- let string = self.eval(exec)
- let routes = {}
- for line in split(string,"\n")
- let route = split(line," ")
- let name = route[0]
- let routes[name] = route[1]
- endfor
- call self.cache.set("named_routes",routes)
- endif
-
- return keys(self.cache.get("named_routes"))
-endfunction
-
-call s:add_methods('app', ['route_names','named_route_file'])
-
-function! RailsNamedRoutes()
- return rails#app().route_names()
-endfunction
-
-function! s:RailsIncludefind(str,...)
- if a:str ==# "ApplicationController"
- return "application_controller.rb\napp/controllers/application.rb"
- elseif a:str ==# "Test::Unit::TestCase"
- return "test/unit/testcase.rb"
- endif
- let str = a:str
- if a:0 == 1
- " Get the text before the filename under the cursor.
- " We'll cheat and peak at this in a bit
- let line = s:linepeak()
- let line = s:sub(line,'([:"'."'".']|\%[qQ]=[[({<])=\f*$','')
- else
- let line = ""
- endif
- let str = s:sub(str,'^\s*','')
- let str = s:sub(str,'\s*$','')
- let str = s:sub(str,'^:=[:@]','')
- let str = s:sub(str,':0x\x+$','') " For # style output
- let str = s:gsub(str,"[\"']",'')
- if line =~# '\<\(require\|load\)\s*(\s*$'
- return str
- elseif str =~# '^\l\w*#\w\+$'
- return 'app/controllers/'.s:sub(str,'#','_controller.rb#')
- endif
- let str = rails#underscore(str)
- let fpat = '\(\s*\%("\f*"\|:\f*\|'."'\\f*'".'\)\s*,\s*\)*'
- if a:str =~# '\u'
- " Classes should always be in .rb files
- let str .= '.rb'
- elseif line =~# ':partial\s*=>\s*'
- let str = s:sub(str,'[^/]+$','_&')
- let str = s:findview(str)
- elseif line =~# '\\s*'
- let str = s:findview(s:sub(str,'^/=','layouts/'))
- elseif line =~# ':controller\s*=>\s*'
- let str = 'app/controllers/'.str.'_controller.rb'
- elseif line =~# '\\s*$' && rails#buffer().type_name('config-routes'))
- if line !~# ':as\s*=>\s*$'
- let str = s:sub(str,'_%(path|url)$','')
- let str = s:sub(str,'^hash_for_','')
- endif
- let file = rails#app().named_route_file(str)
- if file == ""
- let str = s:sub(str,'^formatted_','')
- if str =~# '^\%(new\|edit\)_'
- let str = 'app/controllers/'.s:sub(rails#pluralize(str),'^(new|edit)_(.*)','\2_controller.rb#\1')
- elseif str ==# rails#singularize(str)
- " If the word can't be singularized, it's probably a link to the show
- " method. We should verify by checking for an argument, but that's
- " difficult the way things here are currently structured.
- let str = 'app/controllers/'.rails#pluralize(str).'_controller.rb#show'
- else
- let str = 'app/controllers/'.str.'_controller.rb#index'
- endif
- else
- let str = file
- endif
- elseif str !~ '/'
- " If we made it this far, we'll risk making it singular.
- let str = rails#singularize(str)
- let str = s:sub(str,'_id$','')
- endif
- if str =~ '^/' && !filereadable(str)
- let str = s:sub(str,'^/','')
- endif
- if str =~# '^lib/' && !filereadable(str)
- let str = s:sub(str,'^lib/','')
- endif
- return str
-endfunction
-
-" }}}1
-" File Finders {{{1
-
-function! s:addfilecmds(type)
- let l = s:sub(a:type,'^.','\l&')
- let cmds = 'ESVTD '
- let cmd = ''
- while cmds != ''
- let cplt = " -complete=customlist,".s:sid.l."List"
- exe "command! -buffer -bar ".(cmd == 'D' ? '-range=0 ' : '')."-nargs=*".cplt." R".cmd.l." :call s:".l.'Edit("'.(cmd == 'D' ? '' : '').cmd.'",)'
- let cmd = strpart(cmds,0,1)
- let cmds = strpart(cmds,1)
- endwhile
-endfunction
-
-function! s:BufFinderCommands()
- command! -buffer -bar -nargs=+ Rnavcommand :call s:Navcommand(0,)
- call s:addfilecmds("metal")
- call s:addfilecmds("model")
- call s:addfilecmds("view")
- call s:addfilecmds("controller")
- call s:addfilecmds("mailer")
- call s:addfilecmds("migration")
- call s:addfilecmds("observer")
- call s:addfilecmds("helper")
- call s:addfilecmds("layout")
- call s:addfilecmds("fixtures")
- call s:addfilecmds("locale")
- if rails#app().has('test') || rails#app().has('spec')
- call s:addfilecmds("unittest")
- call s:addfilecmds("functionaltest")
- endif
- if rails#app().has('test') || rails#app().has('spec') || rails#app().has('cucumber')
- call s:addfilecmds("integrationtest")
- endif
- if rails#app().has('spec')
- call s:addfilecmds("spec")
- endif
- call s:addfilecmds("stylesheet")
- call s:addfilecmds("javascript")
- call s:addfilecmds("plugin")
- call s:addfilecmds("task")
- call s:addfilecmds("lib")
- call s:addfilecmds("environment")
- call s:addfilecmds("initializer")
-endfunction
-
-function! s:completion_filter(results,A)
- let results = sort(type(a:results) == type("") ? split(a:results,"\n") : copy(a:results))
- call filter(results,'v:val !~# "\\~$"')
- let filtered = filter(copy(results),'s:startswith(v:val,a:A)')
- if !empty(filtered) | return filtered | endif
- let regex = s:gsub(a:A,'[^/]','[&].*')
- let filtered = filter(copy(results),'v:val =~# "^".regex')
- if !empty(filtered) | return filtered | endif
- let regex = s:gsub(a:A,'.','[&].*')
- let filtered = filter(copy(results),'v:val =~# regex')
- return filtered
-endfunction
-
-function! s:autocamelize(files,test)
- if a:test =~# '^\u'
- return s:completion_filter(map(copy(a:files),'rails#camelize(v:val)'),a:test)
- else
- return s:completion_filter(a:files,a:test)
- endif
-endfunction
-
-function! s:app_relglob(path,glob,...) dict
- if exists("+shellslash") && ! &shellslash
- let old_ss = &shellslash
- let &shellslash = 1
- endif
- let path = a:path
- if path !~ '^/' && path !~ '^\w:'
- let path = self.path(path)
- endif
- let suffix = a:0 ? a:1 : ''
- let full_paths = split(glob(path.a:glob.suffix),"\n")
- let relative_paths = []
- for entry in full_paths
- if suffix == '' && isdirectory(entry) && entry !~ '/$'
- let entry .= '/'
- endif
- let relative_paths += [entry[strlen(path) : -strlen(suffix)-1]]
- endfor
- if exists("old_ss")
- let &shellslash = old_ss
- endif
- return relative_paths
-endfunction
-
-call s:add_methods('app', ['relglob'])
-
-function! s:relglob(...)
- return join(call(rails#app().relglob,a:000,rails#app()),"\n")
-endfunction
-
-function! s:helperList(A,L,P)
- return s:autocamelize(rails#app().relglob("app/helpers/","**/*","_helper.rb"),a:A)
-endfunction
-
-function! s:controllerList(A,L,P)
- let con = rails#app().relglob("app/controllers/","**/*",".rb")
- call map(con,'s:sub(v:val,"_controller$","")')
- return s:autocamelize(con,a:A)
-endfunction
-
-function! s:mailerList(A,L,P)
- return s:autocamelize(rails#app().relglob("app/mailers/","**/*",".rb"),a:A)
-endfunction
-
-function! s:viewList(A,L,P)
- let c = s:controller(1)
- let top = rails#app().relglob("app/views/",s:fuzzyglob(a:A))
- call filter(top,'v:val !~# "\\~$"')
- if c != '' && a:A !~ '/'
- let local = rails#app().relglob("app/views/".c."/","*.*[^~]")
- return s:completion_filter(local+top,a:A)
- endif
- return s:completion_filter(top,a:A)
-endfunction
-
-function! s:layoutList(A,L,P)
- return s:completion_filter(rails#app().relglob("app/views/layouts/","*"),a:A)
-endfunction
-
-function! s:stylesheetList(A,L,P)
- let list = rails#app().relglob('app/assets/stylesheets/','**/*.*','')
- call map(list,'s:sub(v:val,"\\..*$","")')
- let list += rails#app().relglob('public/stylesheets/','**/*','.css')
- if rails#app().has('sass')
- call extend(list,rails#app().relglob('public/stylesheets/sass/','**/*','.s?ss'))
- call s:uniq(list)
- endif
- return s:completion_filter(list,a:A)
-endfunction
-
-function! s:javascriptList(A,L,P)
- let list = rails#app().relglob('app/assets/javascripts/','**/*.*','')
- call map(list,'s:sub(v:val,"\\..*$","")')
- let list += rails#app().relglob("public/javascripts/","**/*",".js")
- return s:completion_filter(list,a:A)
-endfunction
-
-function! s:metalList(A,L,P)
- return s:autocamelize(rails#app().relglob("app/metal/","**/*",".rb"),a:A)
-endfunction
-
-function! s:modelList(A,L,P)
- let models = rails#app().relglob("app/models/","**/*",".rb")
- call filter(models,'v:val !~# "_observer$"')
- return s:autocamelize(models,a:A)
-endfunction
-
-function! s:observerList(A,L,P)
- return s:autocamelize(rails#app().relglob("app/models/","**/*","_observer.rb"),a:A)
-endfunction
-
-function! s:fixturesList(A,L,P)
- return s:completion_filter(rails#app().relglob("test/fixtures/","**/*")+rails#app().relglob("spec/fixtures/","**/*"),a:A)
-endfunction
-
-function! s:localeList(A,L,P)
- return s:completion_filter(rails#app().relglob("config/locales/","**/*"),a:A)
-endfunction
-
-function! s:migrationList(A,L,P)
- if a:A =~ '^\d'
- let migrations = rails#app().relglob("db/migrate/",a:A."[0-9_]*",".rb")
- return map(migrations,'matchstr(v:val,"^[0-9]*")')
- else
- let migrations = rails#app().relglob("db/migrate/","[0-9]*[0-9]_*",".rb")
- call map(migrations,'s:sub(v:val,"^[0-9]*_","")')
- return s:autocamelize(migrations,a:A)
- endif
-endfunction
-
-function! s:unittestList(A,L,P)
- let found = []
- if rails#app().has('test')
- let found += rails#app().relglob("test/unit/","**/*","_test.rb")
- endif
- if rails#app().has('spec')
- let found += rails#app().relglob("spec/models/","**/*","_spec.rb")
- endif
- return s:autocamelize(found,a:A)
-endfunction
-
-function! s:functionaltestList(A,L,P)
- let found = []
- if rails#app().has('test')
- let found += rails#app().relglob("test/functional/","**/*","_test.rb")
- endif
- if rails#app().has('spec')
- let found += rails#app().relglob("spec/controllers/","**/*","_spec.rb")
- let found += rails#app().relglob("spec/mailers/","**/*","_spec.rb")
- endif
- return s:autocamelize(found,a:A)
-endfunction
-
-function! s:integrationtestList(A,L,P)
- if a:A =~# '^\u'
- return s:autocamelize(rails#app().relglob("test/integration/","**/*","_test.rb"),a:A)
- endif
- let found = []
- if rails#app().has('test')
- let found += rails#app().relglob("test/integration/","**/*","_test.rb")
- endif
- if rails#app().has('spec')
- let found += rails#app().relglob("spec/requests/","**/*","_spec.rb")
- let found += rails#app().relglob("spec/integration/","**/*","_spec.rb")
- endif
- if rails#app().has('cucumber')
- let found += rails#app().relglob("features/","**/*",".feature")
- endif
- return s:completion_filter(found,a:A)
-endfunction
-
-function! s:specList(A,L,P)
- return s:completion_filter(rails#app().relglob("spec/","**/*","_spec.rb"),a:A)
-endfunction
-
-function! s:pluginList(A,L,P)
- if a:A =~ '/'
- return s:completion_filter(rails#app().relglob('vendor/plugins/',matchstr(a:A,'.\{-\}/').'**/*'),a:A)
- else
- return s:completion_filter(rails#app().relglob('vendor/plugins/',"*","/init.rb"),a:A)
- endif
-endfunction
-
-" Task files, not actual rake tasks
-function! s:taskList(A,L,P)
- let all = rails#app().relglob("lib/tasks/","**/*",".rake")
- if RailsFilePath() =~ '\','".name."',\"".prefix."\",".string(suffix).",".string(filter).",".string(default).",)"
- let cmd = strpart(cmds,0,1)
- let cmds = strpart(cmds,1)
- endwhile
-endfunction
-
-function! s:CommandList(A,L,P)
- let cmd = matchstr(a:L,'\CR[A-Z]\=\w\+')
- exe cmd." &"
- let lp = s:last_prefix . "\n"
- let res = []
- while lp != ""
- let p = matchstr(lp,'.\{-\}\ze\n')
- let lp = s:sub(lp,'.{-}\n','')
- let res += rails#app().relglob(p,s:last_filter,s:last_suffix)
- endwhile
- if s:last_camelize
- return s:autocamelize(res,a:A)
- else
- return s:completion_filter(res,a:A)
- endif
-endfunction
-
-function! s:CommandEdit(cmd,name,prefix,suffix,filter,default,...)
- if a:0 && a:1 == "&"
- let s:last_prefix = a:prefix
- let s:last_suffix = a:suffix
- let s:last_filter = a:filter
- let s:last_camelize = (a:suffix =~# '\.rb$')
- else
- if a:default == "both()"
- if s:model() != ""
- let default = s:model()
- else
- let default = s:controller()
- endif
- elseif a:default == "model()"
- let default = s:model(1)
- elseif a:default == "controller()"
- let default = s:controller(1)
- else
- let default = a:default
- endif
- call s:EditSimpleRb(a:cmd,a:name,a:0 ? a:1 : default,a:prefix,a:suffix)
- endif
-endfunction
-
-function! s:EditSimpleRb(cmd,name,target,prefix,suffix,...)
- let cmd = s:findcmdfor(a:cmd)
- if a:target == ""
- " Good idea to emulate error numbers like this?
- return s:error("E471: Argument required")
- endif
- let f = a:0 ? a:target : rails#underscore(a:target)
- let jump = matchstr(f,'[#!].*\|:\d*\%(:in\)\=$')
- let f = s:sub(f,'[#!].*|:\d*%(:in)=$','')
- if jump =~ '^!'
- let cmd = s:editcmdfor(cmd)
- endif
- if f == '.'
- let f = s:sub(f,'\.$','')
- else
- let f .= a:suffix.jump
- endif
- let f = s:gsub(a:prefix,'\n',f.'\n').f
- return s:findedit(cmd,f)
-endfunction
-
-function! s:app_migration(file) dict
- let arg = a:file
- if arg =~ '^0$\|^0\=[#:]'
- let suffix = s:sub(arg,'^0*','')
- if self.has_file('db/schema.rb')
- return 'db/schema.rb'.suffix
- elseif self.has_file('db/'.s:environment().'_structure.sql')
- return 'db/'.s:environment().'_structure.sql'.suffix
- else
- return 'db/schema.rb'.suffix
- endif
- elseif arg =~ '^\d$'
- let glob = '00'.arg.'_*.rb'
- elseif arg =~ '^\d\d$'
- let glob = '0'.arg.'_*.rb'
- elseif arg =~ '^\d\d\d$'
- let glob = ''.arg.'_*.rb'
- elseif arg == ''
- let glob = '*.rb'
- else
- let glob = '*'.rails#underscore(arg).'*rb'
- endif
- let files = split(glob(self.path('db/migrate/').glob),"\n")
- if arg == ''
- return get(files,-1,'')
- endif
- call map(files,'strpart(v:val,1+strlen(self.path()))')
- let keep = get(files,0,'')
- if glob =~# '^\*.*\*rb'
- let pattern = glob[1:-4]
- call filter(files,'v:val =~# ''db/migrate/\d\+_''.pattern.''\.rb''')
- let keep = get(files,0,keep)
- endif
- return keep
-endfunction
-
-call s:add_methods('app', ['migration'])
-
-function! s:migrationEdit(cmd,...)
- let cmd = s:findcmdfor(a:cmd)
- let arg = a:0 ? a:1 : ''
- let migr = arg == "." ? "db/migrate" : rails#app().migration(arg)
- if migr != ''
- call s:findedit(cmd,migr)
- else
- return s:error("Migration not found".(arg=='' ? '' : ': '.arg))
- endif
-endfunction
-
-function! s:fixturesEdit(cmd,...)
- if a:0
- let c = rails#underscore(a:1)
- else
- let c = rails#pluralize(s:model(1))
- endif
- if c == ""
- return s:error("E471: Argument required")
- endif
- let e = fnamemodify(c,':e')
- let e = e == '' ? e : '.'.e
- let c = fnamemodify(c,':r')
- let file = get(rails#app().test_suites(),0,'test').'/fixtures/'.c.e
- if file =~ '\.\w\+$' && rails#app().find_file(c.e,["test/fixtures","spec/fixtures"]) ==# ''
- call s:edit(a:cmd,file)
- else
- call s:findedit(a:cmd,rails#app().find_file(c.e,["test/fixtures","spec/fixtures"],[".yml",".csv"],file))
- endif
-endfunction
-
-function! s:localeEdit(cmd,...)
- let c = a:0 ? a:1 : rails#app().default_locale()
- if c =~# '\.'
- call s:edit(a:cmd,rails#app().find_file(c,'config/locales',[],'config/locales/'.c))
- else
- call s:findedit(a:cmd,rails#app().find_file(c,'config/locales',['.yml','.rb'],'config/locales/'.c))
- endif
-endfunction
-
-function! s:metalEdit(cmd,...)
- if a:0
- call s:EditSimpleRb(a:cmd,"metal",a:1,"app/metal/",".rb")
- else
- call s:EditSimpleRb(a:cmd,"metal",'config/boot',"",".rb")
- endif
-endfunction
-
-function! s:modelEdit(cmd,...)
- call s:EditSimpleRb(a:cmd,"model",a:0? a:1 : s:model(1),"app/models/",".rb")
-endfunction
-
-function! s:observerEdit(cmd,...)
- call s:EditSimpleRb(a:cmd,"observer",a:0? a:1 : s:model(1),"app/models/","_observer.rb")
-endfunction
-
-function! s:viewEdit(cmd,...)
- if a:0 && a:1 =~ '^[^!#:]'
- let view = matchstr(a:1,'[^!#:]*')
- elseif rails#buffer().type_name('controller','mailer')
- let view = s:lastmethod(line('.'))
- else
- let view = ''
- endif
- if view == ''
- return s:error("No view name given")
- elseif view == '.'
- return s:edit(a:cmd,'app/views')
- elseif view !~ '/' && s:controller(1) != ''
- let view = s:controller(1) . '/' . view
- endif
- if view !~ '/'
- return s:error("Cannot find view without controller")
- endif
- let file = "app/views/".view
- let found = s:findview(view)
- if found != ''
- let dir = fnamemodify(rails#app().path(found),':h')
- if !isdirectory(dir)
- if a:0 && a:1 =~ '!'
- call mkdir(dir,'p')
- else
- return s:error('No such directory')
- endif
- endif
- call s:edit(a:cmd,found)
- elseif file =~ '\.\w\+$'
- call s:findedit(a:cmd,file)
- else
- let format = s:format(rails#buffer().type_name('mailer') ? 'text' : 'html')
- if glob(rails#app().path(file.'.'.format).'.*[^~]') != ''
- let file .= '.' . format
- endif
- call s:findedit(a:cmd,file)
- endif
-endfunction
-
-function! s:findview(name)
- let self = rails#buffer()
- let name = a:name
- let pre = 'app/views/'
- if name !~# '/'
- let controller = self.controller_name(1)
- if controller != ''
- let name = controller.'/'.name
- endif
- endif
- if name =~# '\.\w\+\.\w\+$' || name =~# '\.'.s:viewspattern().'$'
- return pre.name
- else
- for format in ['.'.s:format('html'), '']
- for type in s:view_types
- if self.app().has_file(pre.name.format.'.'.type)
- return pre.name.format.'.'.type
- endif
- endfor
- endfor
- endif
- return ''
-endfunction
-
-function! s:findlayout(name)
- return s:findview("layouts/".(a:name == '' ? 'application' : a:name))
-endfunction
-
-function! s:layoutEdit(cmd,...)
- if a:0
- return s:viewEdit(a:cmd,"layouts/".a:1)
- endif
- let file = s:findlayout(s:controller(1))
- if file == ""
- let file = s:findlayout("application")
- endif
- if file == ""
- let file = "app/views/layouts/application.html.erb"
- endif
- call s:edit(a:cmd,s:sub(file,'^/',''))
-endfunction
-
-function! s:controllerEdit(cmd,...)
- let suffix = '.rb'
- if a:0 == 0
- let controller = s:controller(1)
- if rails#buffer().type_name() =~# '^view\%(-layout\|-partial\)\@!'
- let suffix .= '#'.expand('%:t:r')
- endif
- else
- let controller = a:1
- endif
- if rails#app().has_file("app/controllers/".controller."_controller.rb") || !rails#app().has_file("app/controllers/".controller.".rb")
- let suffix = "_controller".suffix
- endif
- return s:EditSimpleRb(a:cmd,"controller",controller,"app/controllers/",suffix)
-endfunction
-
-function! s:mailerEdit(cmd,...)
- return s:EditSimpleRb(a:cmd,"mailer",a:0? a:1 : s:controller(1),"app/mailers/\napp/models/",".rb")
-endfunction
-
-function! s:helperEdit(cmd,...)
- return s:EditSimpleRb(a:cmd,"helper",a:0? a:1 : s:controller(1),"app/helpers/","_helper.rb")
-endfunction
-
-function! s:stylesheetEdit(cmd,...)
- let name = a:0 ? a:1 : s:controller(1)
- if rails#app().has('sass') && rails#app().has_file('public/stylesheets/sass/'.name.'.sass')
- return s:EditSimpleRb(a:cmd,"stylesheet",name,"public/stylesheets/sass/",".sass",1)
- elseif rails#app().has('sass') && rails#app().has_file('public/stylesheets/sass/'.name.'.scss')
- return s:EditSimpleRb(a:cmd,"stylesheet",name,"public/stylesheets/sass/",".scss",1)
- elseif rails#app().has('lesscss') && rails#app().has_file('app/stylesheets/'.name.'.less')
- return s:EditSimpleRb(a:cmd,"stylesheet",name,"app/stylesheets/",".less",1)
- else
- let types = rails#app().relglob('app/assets/stylesheets/'.name,'.*','')
- if !empty(types)
- return s:EditSimpleRb(a:cmd,'stylesheet',name,'app/assets/stylesheets/',types[0],1)
- else
- return s:EditSimpleRb(a:cmd,'stylesheet',name,'public/stylesheets/','.css',1)
- endif
- endif
-endfunction
-
-function! s:javascriptEdit(cmd,...)
- let name = a:0 ? a:1 : s:controller(1)
- if rails#app().has('coffee') && rails#app().has_file('app/scripts/'.name.'.coffee')
- return s:EditSimpleRb(a:cmd,'javascript',name,'app/scripts/','.coffee',1)
- elseif rails#app().has('coffee') && rails#app().has_file('app/scripts/'.name.'.js')
- return s:EditSimpleRb(a:cmd,'javascript',name,'app/scripts/','.js',1)
- else
- let types = rails#app().relglob('app/assets/javascripts/'.name,'.*','')
- if !empty(types)
- return s:EditSimpleRb(a:cmd,'javascript',name,'app/assets/javascripts/',types[0],1)
- else
- return s:EditSimpleRb(a:cmd,'javascript',name,'public/javascripts/','.js',1)
- endif
- endif
-endfunction
-
-function! s:unittestEdit(cmd,...)
- let f = rails#underscore(a:0 ? matchstr(a:1,'[^!#:]*') : s:model(1))
- let jump = a:0 ? matchstr(a:1,'[!#:].*') : ''
- if jump =~ '!'
- let cmd = s:editcmdfor(a:cmd)
- else
- let cmd = s:findcmdfor(a:cmd)
- endif
- let mapping = {'test': ['test/unit/','_test.rb'], 'spec': ['spec/models/','_spec.rb']}
- let tests = map(filter(rails#app().test_suites(),'has_key(mapping,v:val)'),'get(mapping,v:val)')
- if empty(tests)
- let tests = [mapping['test']]
- endif
- for [prefix, suffix] in tests
- if !a:0 && rails#buffer().type_name('model-aro') && f != '' && f !~# '_observer$'
- if rails#app().has_file(prefix.f.'_observer'.suffix)
- return s:findedit(cmd,prefix.f.'_observer'.suffix.jump)
- endif
- endif
- endfor
- for [prefix, suffix] in tests
- if rails#app().has_file(prefix.f.suffix)
- return s:findedit(cmd,prefix.f.suffix.jump)
- endif
- endfor
- return s:EditSimpleRb(a:cmd,"unittest",f.jump,tests[0][0],tests[0][1],1)
-endfunction
-
-function! s:functionaltestEdit(cmd,...)
- let f = rails#underscore(a:0 ? matchstr(a:1,'[^!#:]*') : s:controller(1))
- let jump = a:0 ? matchstr(a:1,'[!#:].*') : ''
- if jump =~ '!'
- let cmd = s:editcmdfor(a:cmd)
- else
- let cmd = s:findcmdfor(a:cmd)
- endif
- let mapping = {'test': [['test/functional/'],['_test.rb','_controller_test.rb']], 'spec': [['spec/controllers/','spec/mailers/'],['_spec.rb','_controller_spec.rb']]}
- let tests = map(filter(rails#app().test_suites(),'has_key(mapping,v:val)'),'get(mapping,v:val)')
- if empty(tests)
- let tests = [mapping[tests]]
- endif
- for [prefixes, suffixes] in tests
- for prefix in prefixes
- for suffix in suffixes
- if rails#app().has_file(prefix.f.suffix)
- return s:findedit(cmd,prefix.f.suffix.jump)
- endif
- endfor
- endfor
- endfor
- return s:EditSimpleRb(a:cmd,"functionaltest",f.jump,tests[0][0][0],tests[0][1][0],1)
-endfunction
-
-function! s:integrationtestEdit(cmd,...)
- if !a:0
- return s:EditSimpleRb(a:cmd,"integrationtest","test/test_helper\nfeatures/support/env\nspec/spec_helper","",".rb")
- endif
- let f = rails#underscore(matchstr(a:1,'[^!#:]*'))
- let jump = matchstr(a:1,'[!#:].*')
- if jump =~ '!'
- let cmd = s:editcmdfor(a:cmd)
- else
- let cmd = s:findcmdfor(a:cmd)
- endif
- let tests = [['test/integration/','_test.rb'], [ 'spec/requests/','_spec.rb'], [ 'spec/integration/','_spec.rb'], [ 'features/','.feature']]
- call filter(tests, 'isdirectory(rails#app().path(v:val[0]))')
- if empty(tests)
- let tests = [['test/integration/','_test.rb']]
- endif
- for [prefix, suffix] in tests
- if rails#app().has_file(prefix.f.suffix)
- return s:findedit(cmd,prefix.f.suffix.jump)
- elseif rails#app().has_file(prefix.rails#underscore(f).suffix)
- return s:findedit(cmd,prefix.rails#underscore(f).suffix.jump)
- endif
- endfor
- return s:EditSimpleRb(a:cmd,"integrationtest",f.jump,tests[0][0],tests[0][1],1)
-endfunction
-
-function! s:specEdit(cmd,...)
- if a:0
- return s:EditSimpleRb(a:cmd,"spec",a:1,"spec/","_spec.rb")
- else
- call s:EditSimpleRb(a:cmd,"spec","spec_helper","spec/",".rb")
- endif
-endfunction
-
-function! s:pluginEdit(cmd,...)
- let cmd = s:findcmdfor(a:cmd)
- let plugin = ""
- let extra = ""
- if RailsFilePath() =~ '\','split')
- let cmd = s:sub(cmd,'find>','edit')
- return cmd
-endfunction
-
-function! s:try(cmd) abort
- if !exists(":try")
- " I've seen at least one weird setup without :try
- exe a:cmd
- else
- try
- exe a:cmd
- catch
- call s:error(s:sub(v:exception,'^.{-}:\zeE',''))
- return 0
- endtry
- endif
- return 1
-endfunction
-
-function! s:findedit(cmd,files,...) abort
- let cmd = s:findcmdfor(a:cmd)
- let files = type(a:files) == type([]) ? copy(a:files) : split(a:files,"\n")
- if len(files) == 1
- let file = files[0]
- else
- let file = get(filter(copy(files),'rails#app().has_file(s:sub(v:val,"#.*|:\\d*$",""))'),0,get(files,0,''))
- endif
- if file =~ '[#!]\|:\d*\%(:in\)\=$'
- let djump = matchstr(file,'!.*\|#\zs.*\|:\zs\d*\ze\%(:in\)\=$')
- let file = s:sub(file,'[#!].*|:\d*%(:in)=$','')
- else
- let djump = ''
- endif
- if file == ''
- let testcmd = "edit"
- elseif isdirectory(rails#app().path(file))
- let arg = file == "." ? rails#app().path() : rails#app().path(file)
- let testcmd = s:editcmdfor(cmd).' '.(a:0 ? a:1 . ' ' : '').s:escarg(arg)
- exe testcmd
- return
- elseif rails#app().path() =~ '://' || cmd =~ 'edit' || cmd =~ 'split'
- if file !~ '^/' && file !~ '^\w:' && file !~ '://'
- let file = s:escarg(rails#app().path(file))
- endif
- let testcmd = s:editcmdfor(cmd).' '.(a:0 ? a:1 . ' ' : '').file
- else
- let testcmd = cmd.' '.(a:0 ? a:1 . ' ' : '').file
- endif
- if s:try(testcmd)
- call s:djump(djump)
- endif
-endfunction
-
-function! s:edit(cmd,file,...)
- let cmd = s:editcmdfor(a:cmd)
- let cmd .= ' '.(a:0 ? a:1 . ' ' : '')
- let file = a:file
- if file !~ '^/' && file !~ '^\w:' && file !~ '://'
- exe cmd."`=fnamemodify(rails#app().path(file),':.')`"
- else
- exe cmd.file
- endif
-endfunction
-
-function! s:Alternate(cmd,line1,line2,count,...)
- if a:0
- if a:count && a:cmd !~# 'D'
- return call('s:Find',[1,a:line1.a:cmd]+a:000)
- elseif a:count
- return call('s:Edit',[1,a:line1.a:cmd]+a:000)
- else
- return call('s:Edit',[1,a:cmd]+a:000)
- endif
- else
- let file = s:getopt(a:count ? 'related' : 'alternate', 'bl')
- if file == ''
- let file = rails#buffer().related(a:count)
- endif
- if file != ''
- call s:findedit(a:cmd,file)
- else
- call s:warn("No alternate file is defined")
- endif
- endif
-endfunction
-
-function! s:Related(cmd,line1,line2,count,...)
- if a:count == 0 && a:0 == 0
- return s:Alternate(a:cmd,a:line1,a:line1,a:line1)
- else
- return call('s:Alternate',[a:cmd,a:line1,a:line2,a:count]+a:000)
- endif
-endfunction
-
-function! s:Complete_related(A,L,P)
- if a:L =~# '^[[:alpha:]]'
- return s:Complete_edit(a:A,a:L,a:P)
- else
- return s:Complete_find(a:A,a:L,a:P)
- endif
-endfunction
-
-function! s:readable_related(...) dict abort
- let f = self.name()
- if a:0 && a:1
- let lastmethod = self.last_method(a:1)
- if self.type_name('controller','mailer') && lastmethod != ""
- let root = s:sub(s:sub(s:sub(f,'/application%(_controller)=\.rb$','/shared_controller.rb'),'/%(controllers|models|mailers)/','/views/'),'%(_controller)=\.rb$','/'.lastmethod)
- let format = self.last_format(a:1)
- if format == ''
- let format = self.type_name('mailer') ? 'text' : 'html'
- endif
- if glob(self.app().path().'/'.root.'.'.format.'.*[^~]') != ''
- return root . '.' . format
- else
- return root
- endif
- elseif f =~ '\ me')
- let migration = "db/migrate/".get(candidates,0,migrations[0]).".rb"
- endif
- return migration . (exists('l:lastmethod') && lastmethod != '' ? '#'.lastmethod : '')
- elseif f =~ '\??').'/layout.'.fnamemodify(f,':e')
- else
- let dest = f
- endif
- return s:sub(s:sub(dest,' 1
- return s:error("Incorrect number of arguments")
- endif
- if a:1 =~ '[^a-z0-9_/.]'
- return s:error("Invalid partial name")
- endif
- let rails_root = rails#app().path()
- let ext = expand("%:e")
- let file = s:sub(a:1,'%(/|^)\zs_\ze[^/]*$','')
- let first = a:firstline
- let last = a:lastline
- let range = first.",".last
- if rails#buffer().type_name('view-layout')
- if RailsFilePath() =~ '\'
- let curdir = 'app/views/shared'
- if file !~ '/'
- let file = "shared/" .file
- endif
- else
- let curdir = s:sub(RailsFilePath(),'.*]+)'.erub2.'\s*$'
- let collection = s:sub(getline(first-1),'^'.fspaces.erub1.'for\s+(\k+)\s+in\s+([^ >]+)'.erub2.'\s*$','\1>\2')
- elseif getline(first-1) =~ '\v^'.fspaces.erub1.'([^ %>]+)\.each\s+do\s+\|\s*(\k+)\s*\|'.erub2.'\s*$'
- let collection = s:sub(getline(first-1),'^'.fspaces.erub1.'([^ %>]+)\.each\s+do\s+\|\s*(\k+)\s*\|'.erub2.'\s*$','\2>\1')
- endif
- if collection != ''
- let var = matchstr(collection,'^\k\+')
- let collection = s:sub(collection,'^\k+\>','')
- let first -= 1
- let last += 1
- endif
- else
- let fspaces = spaces
- endif
- let renderstr = "render :partial => '".fnamemodify(file,":r:r")."'"
- if collection != ""
- let renderstr .= ", :collection => ".collection
- elseif "@".name != var
- let renderstr .= ", :object => ".var
- endif
- if ext =~? '^\%(rhtml\|erb\|dryml\)$'
- let renderstr = "<%= ".renderstr." %>"
- elseif ext == "rxml" || ext == "builder"
- let renderstr = "xml << ".s:sub(renderstr,"render ","render(").")"
- elseif ext == "rjs"
- let renderstr = "page << ".s:sub(renderstr,"render ","render(").")"
- elseif ext == "haml"
- let renderstr = "= ".renderstr
- elseif ext == "mn"
- let renderstr = "_".renderstr
- endif
- let buf = @@
- silent exe range."yank"
- let partial = @@
- let @@ = buf
- let old_ai = &ai
- try
- let &ai = 0
- silent exe "norm! :".first.",".last."change\".fspaces.renderstr."\.\"
- finally
- let &ai = old_ai
- endtry
- if renderstr =~ '<%'
- norm ^6w
- else
- norm ^5w
- endif
- let ft = &ft
- let shortout = fnamemodify(out,':.')
- silent split `=shortout`
- silent %delete
- let &ft = ft
- let @@ = partial
- silent put
- 0delete
- let @@ = buf
- if spaces != ""
- silent! exe '%substitute/^'.spaces.'//'
- endif
- silent! exe '%substitute?\%(\w\|[@:"'."'".'-]\)\@?'.name.'?g'
- 1
-endfunction
-
-" }}}1
-" Migration Inversion {{{1
-
-function! s:mkeep(str)
- " Things to keep (like comments) from a migration statement
- return matchstr(a:str,' #[^{].*')
-endfunction
-
-function! s:mextargs(str,num)
- if a:str =~ '^\s*\w\+\s*('
- return s:sub(matchstr(a:str,'^\s*\w\+\s*\zs(\%([^,)]\+[,)]\)\{,'.a:num.'\}'),',$',')')
- else
- return s:sub(s:sub(matchstr(a:str,'\w\+\>\zs\s*\%([^,){ ]*[, ]*\)\{,'.a:num.'\}'),'[, ]*$',''),'^\s+',' ')
- endif
-endfunction
-
-function! s:migspc(line)
- return matchstr(a:line,'^\s*')
-endfunction
-
-function! s:invertrange(beg,end)
- let str = ""
- let lnum = a:beg
- while lnum <= a:end
- let line = getline(lnum)
- let add = ""
- if line == ''
- let add = ' '
- elseif line =~ '^\s*\(#[^{].*\)\=$'
- let add = line
- elseif line =~ '\'
- let add = s:migspc(line)."drop_table".s:mextargs(line,1).s:mkeep(line)
- let lnum = s:endof(lnum)
- elseif line =~ '\'
- let add = s:sub(line,'\s*\(=\s*([^,){ ]*).*','create_table \1 do |t|'."\n".matchstr(line,'^\s*').'end').s:mkeep(line)
- elseif line =~ '\'
- let add = s:migspc(line).'remove_column'.s:mextargs(line,2).s:mkeep(line)
- elseif line =~ '\'
- let add = s:sub(line,'','add_column')
- elseif line =~ '\'
- let add = s:migspc(line).'remove_index'.s:mextargs(line,1)
- let mat = matchstr(line,':name\s*=>\s*\zs[^ ,)]*')
- if mat != ''
- let add = s:sub(add,'\)=$',', :name => '.mat.'&')
- else
- let mat = matchstr(line,'\[^,]*,\s*\zs\%(\[[^]]*\]\|[:"'."'".']\w*["'."'".']\=\)')
- if mat != ''
- let add = s:sub(add,'\)=$',', :column => '.mat.'&')
- endif
- endif
- let add .= s:mkeep(line)
- elseif line =~ '\'
- let add = s:sub(s:sub(line,'\s*','')
- elseif line =~ '\'
- let add = s:sub(line,''
- let add = s:migspc(line).'change_column'.s:mextargs(line,2).s:mkeep(line)
- elseif line =~ '\'
- let add = s:migspc(line).'change_column_default'.s:mextargs(line,2).s:mkeep(line)
- elseif line =~ '\.update_all(\(["'."'".']\).*\1)$' || line =~ '\.update_all \(["'."'".']\).*\1$'
- " .update_all('a = b') => .update_all('b = a')
- let pre = matchstr(line,'^.*\.update_all[( ][}'."'".'"]')
- let post = matchstr(line,'["'."'".'])\=$')
- let mat = strpart(line,strlen(pre),strlen(line)-strlen(pre)-strlen(post))
- let mat = s:gsub(','.mat.',','%(,\s*)@<=([^ ,=]{-})(\s*\=\s*)([^,=]{-})%(\s*,)@=','\3\2\1')
- let add = pre.s:sub(s:sub(mat,'^,',''),',$','').post
- elseif line =~ '^s\*\%(if\|unless\|while\|until\|for\)\>'
- let lnum = s:endof(lnum)
- endif
- if lnum == 0
- return -1
- endif
- if add == ""
- let add = s:sub(line,'^\s*\zs.*','raise ActiveRecord::IrreversibleMigration')
- elseif add == " "
- let add = ""
- endif
- let str = add."\n".str
- let lnum += 1
- endwhile
- let str = s:gsub(str,'(\s*raise ActiveRecord::IrreversibleMigration\n)+','\1')
- return str
-endfunction
-
-function! s:Invert(bang)
- let err = "Could not parse method"
- let src = "up"
- let dst = "down"
- let beg = search('\%('.&l:define.'\).*'.src.'\>',"w")
- let end = s:endof(beg)
- if beg + 1 == end
- let src = "down"
- let dst = "up"
- let beg = search('\%('.&l:define.'\).*'.src.'\>',"w")
- let end = s:endof(beg)
- endif
- if !beg || !end
- return s:error(err)
- endif
- let str = s:invertrange(beg+1,end-1)
- if str == -1
- return s:error(err)
- endif
- let beg = search('\%('.&l:define.'\).*'.dst.'\>',"w")
- let end = s:endof(beg)
- if !beg || !end
- return s:error(err)
- endif
- if foldclosed(beg) > 0
- exe beg."foldopen!"
- endif
- if beg + 1 < end
- exe (beg+1).",".(end-1)."delete _"
- endif
- if str != ''
- exe beg.'put =str'
- exe 1+beg
- endif
-endfunction
-
-" }}}1
-" Cache {{{1
-
-let s:cache_prototype = {'dict': {}}
-
-function! s:cache_clear(...) dict
- if a:0 == 0
- let self.dict = {}
- elseif has_key(self,'dict') && has_key(self.dict,a:1)
- unlet! self.dict[a:1]
- endif
-endfunction
-
-function! rails#cache_clear(...)
- if exists('b:rails_root')
- return call(rails#app().cache.clear,a:000,rails#app().cache)
- endif
-endfunction
-
-function! s:cache_get(...) dict
- if a:0 == 1
- return self.dict[a:1]
- else
- return self.dict
- endif
-endfunction
-
-function! s:cache_has(key) dict
- return has_key(self.dict,a:key)
-endfunction
-
-function! s:cache_needs(key) dict
- return !has_key(self.dict,a:key)
-endfunction
-
-function! s:cache_set(key,value) dict
- let self.dict[a:key] = a:value
-endfunction
-
-call s:add_methods('cache', ['clear','needs','has','get','set'])
-
-let s:app_prototype.cache = s:cache_prototype
-
-" }}}1
-" Syntax {{{1
-
-function! s:resetomnicomplete()
- if exists("+completefunc") && &completefunc == 'syntaxcomplete#Complete'
- if exists("g:loaded_syntax_completion")
- " Ugly but necessary, until we have our own completion
- unlet g:loaded_syntax_completion
- silent! delfunction syntaxcomplete#Complete
- endif
- endif
-endfunction
-
-function! s:helpermethods()
- return ""
- \."atom_feed audio_path audio_tag auto_discovery_link_tag auto_link "
- \."button_to button_to_function "
- \."cache capture cdata_section check_box check_box_tag collection_select concat content_for content_tag content_tag_for csrf_meta_tag current_cycle cycle "
- \."date_select datetime_select debug distance_of_time_in_words distance_of_time_in_words_to_now div_for dom_class dom_id draggable_element draggable_element_js drop_receiving_element drop_receiving_element_js "
- \."email_field email_field_tag error_message_on error_messages_for escape_javascript escape_once excerpt "
- \."favicon_link_tag field_set_tag fields_for file_field file_field_tag form form_for form_tag "
- \."grouped_collection_select grouped_options_for_select "
- \."hidden_field hidden_field_tag highlight "
- \."image_path image_submit_tag image_tag input "
- \."javascript_cdata_section javascript_include_tag javascript_path javascript_tag "
- \."l label label_tag link_to link_to_function link_to_if link_to_unless link_to_unless_current localize "
- \."mail_to "
- \."number_field number_field_tag number_to_currency number_to_human number_to_human_size number_to_percentage number_to_phone number_with_delimiter number_with_precision "
- \."option_groups_from_collection_for_select options_for_select options_from_collection_for_select "
- \."password_field password_field_tag path_to_audio path_to_image path_to_javascript path_to_stylesheet path_to_video phone_field phone_field_tag pluralize "
- \."radio_button radio_button_tag range_field range_field_tag raw remote_function reset_cycle "
- \."safe_concat sanitize sanitize_css search_field search_field_tag select select_date select_datetime select_day select_hour select_minute select_month select_second select_tag select_time select_year simple_format sortable_element sortable_element_js strip_links strip_tags stylesheet_link_tag stylesheet_path submit_tag "
- \."t tag telephone_field telephone_field_tag text_area text_area_tag text_field text_field_tag time_ago_in_words time_select time_zone_options_for_select time_zone_select translate truncate "
- \."update_page update_page_tag url_field url_field_tag url_for url_options "
- \."video_path video_tag visual_effect "
- \."word_wrap"
-endfunction
-
-function! s:app_user_classes() dict
- if self.cache.needs("user_classes")
- let controllers = self.relglob("app/controllers/","**/*",".rb")
- call map(controllers,'v:val == "application" ? v:val."_controller" : v:val')
- let classes =
- \ self.relglob("app/models/","**/*",".rb") +
- \ controllers +
- \ self.relglob("app/helpers/","**/*",".rb") +
- \ self.relglob("lib/","**/*",".rb")
- call map(classes,'rails#camelize(v:val)')
- call self.cache.set("user_classes",classes)
- endif
- return self.cache.get('user_classes')
-endfunction
-
-function! s:app_user_assertions() dict
- if self.cache.needs("user_assertions")
- if self.has_file("test/test_helper.rb")
- let assertions = map(filter(s:readfile(self.path("test/test_helper.rb")),'v:val =~ "^ def assert_"'),'matchstr(v:val,"^ def \\zsassert_\\w\\+")')
- else
- let assertions = []
- endif
- call self.cache.set("user_assertions",assertions)
- endif
- return self.cache.get('user_assertions')
-endfunction
-
-call s:add_methods('app', ['user_classes','user_assertions'])
-
-function! s:BufSyntax()
- if (!exists("g:rails_syntax") || g:rails_syntax)
- let buffer = rails#buffer()
- let s:javascript_functions = "$ $$ $A $F $H $R $w jQuery"
- let classes = s:gsub(join(rails#app().user_classes(),' '),'::',' ')
- if &syntax == 'ruby'
- if classes != ''
- exe "syn keyword rubyRailsUserClass ".classes." containedin=rubyClassDeclaration,rubyModuleDeclaration,rubyClass,rubyModule"
- endif
- if buffer.type_name() == ''
- syn keyword rubyRailsMethod params request response session headers cookies flash
- endif
- if buffer.type_name('api')
- syn keyword rubyRailsAPIMethod api_method inflect_names
- endif
- if buffer.type_name() ==# 'model' || buffer.type_name('model-arb')
- syn keyword rubyRailsARMethod default_scope named_scope scope serialize
- syn keyword rubyRailsARAssociationMethod belongs_to has_one has_many has_and_belongs_to_many composed_of accepts_nested_attributes_for
- syn keyword rubyRailsARCallbackMethod before_create before_destroy before_save before_update before_validation before_validation_on_create before_validation_on_update
- syn keyword rubyRailsARCallbackMethod after_create after_destroy after_save after_update after_validation after_validation_on_create after_validation_on_update
- syn keyword rubyRailsARCallbackMethod around_create around_destroy around_save around_update
- syn keyword rubyRailsARCallbackMethod after_commit after_find after_initialize after_rollback after_touch
- syn keyword rubyRailsARClassMethod attr_accessible attr_protected attr_readonly establish_connection set_inheritance_column set_locking_column set_primary_key set_sequence_name set_table_name
- syn keyword rubyRailsARValidationMethod validate validates validate_on_create validate_on_update validates_acceptance_of validates_associated validates_confirmation_of validates_each validates_exclusion_of validates_format_of validates_inclusion_of validates_length_of validates_numericality_of validates_presence_of validates_size_of validates_uniqueness_of
- syn keyword rubyRailsMethod logger
- endif
- if buffer.type_name('model-aro')
- syn keyword rubyRailsARMethod observe
- endif
- if buffer.type_name('mailer')
- syn keyword rubyRailsMethod logger url_for polymorphic_path polymorphic_url
- syn keyword rubyRailsRenderMethod mail render
- syn keyword rubyRailsControllerMethod attachments default helper helper_attr helper_method
- endif
- if buffer.type_name('controller','view','helper')
- syn keyword rubyRailsMethod params request response session headers cookies flash
- syn keyword rubyRailsRenderMethod render
- syn keyword rubyRailsMethod logger polymorphic_path polymorphic_url
- endif
- if buffer.type_name('helper','view')
- exe "syn keyword rubyRailsHelperMethod ".s:gsub(s:helpermethods(),'<%(content_for|select)\s+','')
- syn match rubyRailsHelperMethod '\