Browse Source

Merge branch 'master' of github.com:windhamdavid/dave

windhamdavid 13 years ago
parent
commit
774633a8f4

+ 8 - 0
dotfiles/.bash_profile

@@ -0,0 +1,8 @@
+PATH=/usr/local/bin:$PATH
+
+# Setting PATH for MacPython 2.5
+# The orginal version is saved in .bash_profile.pysave
+PATH="/Library/Frameworks/Python.framework/Versions/Current/bin:${PATH}"
+export PATH
+[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
+[[ -s "$HOME/.nvm/nvm.sh" ]] && source "$HOME/.nvm/nvm.sh" # Load nvm into shell session

+ 4 - 0
dotfiles/.gitignore

@@ -0,0 +1,4 @@
+.DS_Store
+.svn
+*~
+.*.swp

+ 32 - 0
dotfiles/.gitignore_global

@@ -0,0 +1,32 @@
+ehthumbs.db
+Icon?
+Thumbs.db
+.DS_Store?
+.DS_Store
+.svn
+*~
+.*.swp
+*.com
+*.class
+*.dll
+*.exe
+*.o
+*.so
+
+# Packages #
+############
+*.7z
+*.dmg
+*.gz
+*.iso
+*.jar
+*.rar
+*.tar
+*.zip
+
+# Logs and databases #
+######################
+*.log
+*.sql
+*.sqlite
+

+ 280 - 0
dotfiles/vim/Tabular.vim

@@ -0,0 +1,280 @@
+" Tabular:     Align columnar data using regex-designated column boundaries
+" Maintainer:  Matthew Wozniski (mjw@drexel.edu)
+" Date:        Thu, 11 Oct 2007 00:35:34 -0400
+" Version:     0.1
+
+" Abort if running in vi-compatible mode or the user doesn't want us.
+if &cp || exists('g:tabular_loaded')
+  if &cp && &verbose
+    echo "Not loading Tabular in compatible mode."
+  endif
+  finish
+endif
+
+let g:tabular_loaded = 1
+
+" Stupid vimscript crap                                                   {{{1
+let s:savecpo = &cpo
+set cpo&vim
+
+" Private Things                                                          {{{1
+
+" Dictionary of command name to command
+let s:TabularCommands = {}
+
+" Generate tab completion list for :Tabularize                            {{{2
+" Return a list of commands that match the command line typed so far.
+" NOTE: Tries to handle commands with spaces in the name, but Vim doesn't seem
+"       to handle that terribly well... maybe I should give up on that.
+function! s:CompleteTabularizeCommand(argstart, cmdline, cursorpos)
+  let names = keys(s:TabularCommands)
+  if exists("b:TabularCommands")
+    let names += keys(b:TabularCommands)
+  endif
+
+  let cmdstart = substitute(a:cmdline, '^\s*\S\+\s*', '', '')
+
+  return filter(names, 'v:val =~# ''^\V'' . escape(cmdstart, ''\'')')
+endfunction
+
+" Choose the proper command map from the given command line               {{{2
+" Returns [ command map, command line with leading <buffer> removed ]
+function! s:ChooseCommandMap(commandline)
+  let map = s:TabularCommands
+  let cmd = a:commandline
+
+  if cmd =~# '^<buffer>\s\+'
+    if !exists('b:TabularCommands')
+      let b:TabularCommands = {}
+    endif
+    let map = b:TabularCommands
+    let cmd = substitute(cmd, '^<buffer>\s\+', '', '')
+  endif
+
+  return [ map, cmd ]
+endfunction
+
+" Parse '/pattern/format' into separate pattern and format parts.         {{{2
+" If parsing fails, return [ '', '' ]
+function! s:ParsePattern(string)
+  if a:string[0] != '/'
+    return ['','']
+  endif
+
+  let pat = '\\\@<!\%(\\\\\)\{-}\zs/' . tabular#ElementFormatPattern() . '*$'
+  let format = matchstr(a:string[1:-1], pat)
+  if !empty(format)
+    let format = format[1 : -1]
+    let pattern = a:string[1 : -len(format) - 2]
+  else
+    let pattern = a:string[1 : -1]
+  endif
+
+  return [pattern, format]
+endfunction
+
+" Split apart a list of | separated expressions.                          {{{2
+function! s:SplitCommands(string)
+  if a:string =~ '^\s*$'
+    return []
+  endif
+
+  let end = match(a:string, "[\"'|]")
+
+  " Loop until we find a delimiting | or end-of-string
+  while end != -1 && (a:string[end] != '|' || a:string[end+1] == '|')
+    if a:string[end] == "'"
+      let end = match(a:string, "'", end+1) + 1
+      if end == 0
+        throw "No matching end single quote"
+      endif
+    elseif a:string[end] == '"'
+      " Find a " preceded by an even number of \ (or 0)
+      let pattern = '\%(\\\@<!\%(\\\\\)*\)\@<="'
+      let end = matchend(a:string, pattern, end+1) + 1
+      if end == 0
+        throw "No matching end double quote"
+      endif
+    else " Found ||
+      let end += 2
+    endif
+
+    let end = match(a:string, "[\"'|]", end)
+  endwhile
+
+  if end == 0 || a:string[0 : end - (end > 0)] =~ '^\s*$'
+    throw "Empty element"
+  endif
+
+  if end == -1
+    let rv = [ a:string ]
+  else
+    let rv = [ a:string[0 : end-1] ] + s:SplitCommands(a:string[end+1 : -1])
+  endif
+
+  return rv
+endfunction
+
+" Public Things                                                           {{{1
+
+" Command associating a command name with a simple pattern command        {{{2
+" AddTabularPattern[!] [<buffer>] name /pattern[/format]
+"
+" If <buffer> is provided, the command will only be available in the current
+" buffer, and will be used instead of any global command with the same name.
+"
+" If a command with the same name and scope already exists, it is an error,
+" unless the ! is provided, in which case the existing command will be
+" replaced.
+"
+" pattern is a regex describing the delimiter to be used.
+"
+" format describes the format pattern to be used.  The default will be used if
+" none is provided.
+com! -nargs=+ -bang AddTabularPattern
+   \ call AddTabularPattern(<q-args>, <bang>0)
+
+function! AddTabularPattern(command, force)
+  try
+    let [ commandmap, rest ] = s:ChooseCommandMap(a:command)
+
+    let name = matchstr(rest, '.\{-}\ze\s*/')
+    let pattern = substitute(rest, '.\{-}\s*\ze/', '', '')
+
+    let [ pattern, format ] = s:ParsePattern(pattern)
+
+    if empty(name) || empty(pattern)
+      throw "Invalid arguments!"
+    endif
+
+    if !a:force && has_key(commandmap, name)
+      throw string(name) . " is already defined, use ! to overwrite."
+    endif
+
+    let command = "tabular#TabularizeStrings(a:lines, " . string(pattern)
+
+    if !empty(format)
+      let command .=  ", " . string(format)
+    endif
+
+    let command .= ")"
+
+    let commandmap[name] = ":call tabular#PipeRange("
+          \ . string(pattern) . ","
+          \ . string(command) . ")"
+  catch
+    echohl ErrorMsg
+    echomsg "AddTabularPattern: " . v:exception
+    echohl None
+  endtry
+endfunction
+
+" Command associating a command name with a pipeline of functions         {{{2
+" AddTabularPipeline[!] [<buffer>] name /pattern/ func [ | func2 [ | func3 ] ]
+"
+" If <buffer> is provided, the command will only be available in the current
+" buffer, and will be used instead of any global command with the same name.
+"
+" If a command with the same name and scope already exists, it is an error,
+" unless the ! is provided, in which case the existing command will be
+" replaced.
+"
+" pattern is a regex that will be used to determine which lines will be
+" filtered.  If the cursor line doesn't match the pattern, using the command
+" will be a no-op, otherwise the cursor and all contiguous lines matching the
+" pattern will be filtered.
+"
+" Each 'func' argument represents a function to be called.  This function
+" will have access to a:lines, a List containing one String per line being
+" filtered.
+com! -nargs=+ -bang AddTabularPipeline
+   \ call AddTabularPipeline(<q-args>, <bang>0)
+
+function! AddTabularPipeline(command, force)
+  try
+    let [ commandmap, rest ] = s:ChooseCommandMap(a:command)
+
+    let name = matchstr(rest, '.\{-}\ze\s*/')
+    let pattern = substitute(rest, '.\{-}\s*\ze/', '', '')
+
+    let commands = matchstr(pattern, '^/.\{-}\\\@<!\%(\\\\\)\{-}/\zs.*')
+    let pattern = matchstr(pattern, '/\zs.\{-}\\\@<!\%(\\\\\)\{-}\ze/')
+
+    if empty(name) || empty(pattern)
+      throw "Invalid arguments!"
+    endif
+
+    if !a:force && has_key(commandmap, name)
+      throw string(name) . " is already defined, use ! to overwrite."
+    endif
+
+    let commandlist = s:SplitCommands(commands)
+
+    if empty(commandlist)
+      throw "Must provide a list of functions!"
+    endif
+
+    let cmd = ":call tabular#PipeRange(" . string(pattern)
+
+    for command in commandlist
+      let cmd .= "," . string(command)
+    endfor
+
+    let cmd .= ")"
+
+    let commandmap[name] = cmd
+  catch
+    echohl ErrorMsg
+    echomsg "AddTabularPipeline: " . v:exception
+    echohl None
+  endtry
+endfunction
+
+" Tabularize /pattern[/format]                                            {{{2
+" Tabularize name
+"
+" Align text, either using the given pattern, or the command associated with
+" the given name.
+com! -nargs=+ -range -complete=customlist,<SID>CompleteTabularizeCommand
+   \ Tabularize <line1>,<line2>call Tabularize(<q-args>)
+
+function! Tabularize(command) range
+  let range = a:firstline . ',' . a:lastline
+
+  try
+    let [ pattern, format ] = s:ParsePattern(a:command)
+
+    if !empty(pattern)
+      let cmd  = "tabular#TabularizeStrings(a:lines, " . string(pattern)
+
+      if !empty(format)
+        let cmd .= "," . string(format)
+      endif
+
+      let cmd .= ")"
+
+      exe range . 'call tabular#PipeRange(pattern, cmd)'
+    else
+      if exists('b:TabularCommands') && has_key(b:TabularCommands, a:command)
+        let command = b:TabularCommands[a:command]
+      elseif has_key(s:TabularCommands, a:command)
+        let command = s:TabularCommands[a:command]
+      else
+        throw "Unrecognized command " . string(a:command)
+      endif
+
+      exe range . command
+    endif
+  catch
+    echohl ErrorMsg
+    echomsg "Tabularize: " . v:exception
+    echohl None
+    return
+  endtry
+endfunction
+
+" Stupid vimscript crap, part 2                                           {{{1
+let &cpo = s:savecpo
+unlet s:savecpo
+
+" vim:set sw=2 sts=2 fdm=marker:

+ 340 - 0
dotfiles/vim/rails.vim

@@ -0,0 +1,340 @@
+" rails.vim - Detect a rails application
+" Author:       Tim Pope <vimNOSPAM@tpope.org>
+" GetLatestVimScripts: 1567 1 :AutoInstall: rails.vim
+" URL:          http://rails.vim.tpope.net/
+
+" Install this file as plugin/rails.vim.  See doc/rails.txt for details. (Grab
+" it from the URL above if you don't have it.)  To access it from Vim, see
+" :help add-local-help (hint: :helptags ~/.vim/doc) Afterwards, you should be
+" able to do :help rails
+
+if exists('g:loaded_rails') || &cp || v:version < 700
+  finish
+endif
+let g:loaded_rails = 1
+
+" Utility Functions {{{1
+
+function! s:error(str)
+  echohl ErrorMsg
+  echomsg a:str
+  echohl None
+  let v:errmsg = a:str
+endfunction
+
+function! s:autoload(...)
+  if !exists("g:autoloaded_rails") && v:version >= 700
+    runtime! autoload/rails.vim
+  endif
+  if exists("g:autoloaded_rails")
+    if a:0
+      exe a:1
+    endif
+    return 1
+  endif
+  if !exists("g:rails_no_autoload_warning")
+    let g:rails_no_autoload_warning = 1
+    if v:version >= 700
+      call s:error("Disabling rails.vim: autoload/rails.vim is missing")
+    else
+      call s:error("Disabling rails.vim: Vim version 7 or higher required")
+    endif
+  endif
+  return ""
+endfunction
+
+" }}}1
+" Configuration {{{
+
+function! s:SetOptDefault(opt,val)
+  if !exists("g:".a:opt)
+    let g:{a:opt} = a:val
+  endif
+endfunction
+
+call s:SetOptDefault("rails_statusline",1)
+call s:SetOptDefault("rails_syntax",1)
+call s:SetOptDefault("rails_mappings",1)
+call s:SetOptDefault("rails_abbreviations",1)
+call s:SetOptDefault("rails_ctags_arguments","--exclude=\"*.js\"")
+call s:SetOptDefault("rails_default_file","README")
+call s:SetOptDefault("rails_root_url",'http://localhost:3000/')
+call s:SetOptDefault("rails_modelines",0)
+call s:SetOptDefault("rails_menu",1)
+call s:SetOptDefault("rails_gnu_screen",1)
+call s:SetOptDefault("rails_history_size",5)
+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")
+if exists("g:loaded_dbext") && executable("sqlite3") && ! executable("sqlite")
+  " Since dbext can't find it by itself
+  call s:SetOptDefault("dbext_default_SQLITE_bin","sqlite3")
+endif
+
+" }}}1
+" Detection {{{1
+
+function! s:escvar(r)
+  let r = fnamemodify(a:r,':~')
+  let r = substitute(r,'\W','\="_".char2nr(submatch(0))."_"','g')
+  let r = substitute(r,'^\d','_&','')
+  return r
+endfunction
+
+function! s:Detect(filename)
+  let fn = substitute(fnamemodify(a:filename,":p"),'\c^file://','','')
+  let sep = matchstr(fn,'^[^\\/]\{3,\}\zs[\\/]')
+  if sep != ""
+    let fn = getcwd().sep.fn
+  endif
+  if fn =~ '[\/]config[\/]environment\.rb$'
+    return s:BufInit(strpart(fn,0,strlen(fn)-22))
+  endif
+  if isdirectory(fn)
+    let fn = fnamemodify(fn,':s?[\/]$??')
+  else
+    let fn = fnamemodify(fn,':s?\(.*\)[\/][^\/]*$?\1?')
+  endif
+  let ofn = ""
+  let nfn = fn
+  while nfn != ofn && nfn != ""
+    if exists("s:_".s:escvar(nfn))
+      return s:BufInit(nfn)
+    endif
+    let ofn = nfn
+    let nfn = fnamemodify(nfn,':h')
+  endwhile
+  let ofn = ""
+  while fn != ofn
+    if filereadable(fn . "/config/environment.rb")
+      return s:BufInit(fn)
+    endif
+    let ofn = fn
+    let fn = fnamemodify(ofn,':s?\(.*\)[\/]\(app\|config\|db\|doc\|features\|lib\|log\|public\|script\|spec\|stories\|test\|tmp\|vendor\)\($\|[\/].*$\)?\1?')
+  endwhile
+  return 0
+endfunction
+
+function! s:BufInit(path)
+  let s:_{s:escvar(a:path)} = 1
+  if s:autoload()
+    return RailsBufInit(a:path)
+  endif
+endfunction
+
+" }}}1
+" Initialization {{{1
+
+augroup railsPluginDetect
+  autocmd!
+  autocmd BufNewFile,BufRead * call s:Detect(expand("<afile>:p"))
+  autocmd VimEnter * if expand("<amatch>") == "" && !exists("b:rails_root") | call s:Detect(getcwd()) | endif | if exists("b:rails_root") | silent doau User BufEnterRails | endif
+  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
+  autocmd BufEnter * if exists("b:rails_root")|silent doau User BufEnterRails|endif
+  autocmd BufLeave * if exists("b:rails_root")|silent doau User BufLeaveRails|endif
+  autocmd Syntax railslog if s:autoload()|call rails#log_syntax()|endif
+augroup END
+
+command! -bar -bang -nargs=* -complete=dir Rails :if s:autoload()|call rails#new_app_command(<bang>0,<f-args>)|endif
+
+" }}}1
+" abolish.vim support {{{1
+
+function! s:function(name)
+    return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '<SNR>\d\+_'),''))
+endfunction
+
+augroup railsPluginAbolish
+  autocmd!
+  autocmd VimEnter * call s:abolish_setup()
+augroup END
+
+function! s:abolish_setup()
+  if exists('g:Abolish') && has_key(g:Abolish,'Coercions')
+    if !has_key(g:Abolish.Coercions,'l')
+      let g:Abolish.Coercions.l = s:function('s:abolish_l')
+    endif
+    if !has_key(g:Abolish.Coercions,'t')
+      let g:Abolish.Coercions.t = s:function('s:abolish_t')
+    endif
+  endif
+endfunction
+
+function! s:abolish_l(word)
+  let singular = rails#singularize(a:word)
+  return a:word ==? singular ? rails#pluralize(a:word) : singular
+endfunction
+
+function! s:abolish_t(word)
+  if a:word =~# '\u'
+    return rails#pluralize(rails#underscore(a:word))
+  else
+    return rails#singularize(rails#camelize(a:word))
+  endif
+endfunction
+
+" }}}1
+" Menus {{{1
+
+if !(g:rails_menu && has("menu"))
+  finish
+endif
+
+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:menucmd(priority)
+  return 'anoremenu <script> '.(exists("$CREAM") ? 87 : '').s:gsub(g:rails_installed_menu,'[^.]','').'.'.a:priority.' '
+endfunction
+
+function! s:CreateMenus() abort
+  if exists("g:rails_installed_menu") && g:rails_installed_menu != ""
+    exe "aunmenu ".s:gsub(g:rails_installed_menu,'\&','')
+    unlet g:rails_installed_menu
+  endif
+  if has("menu") && (exists("g:did_install_default_menus") || exists("$CREAM")) && g:rails_menu
+    if g:rails_menu > 1
+      let g:rails_installed_menu = '&Rails'
+    else
+      let g:rails_installed_menu = '&Plugin.&Rails'
+    endif
+    let dots = s:gsub(g:rails_installed_menu,'[^.]','')
+    let menucmd = s:menucmd(200)
+    if exists("$CREAM")
+      exe menucmd.g:rails_installed_menu.'.-PSep- :'
+      exe menucmd.g:rails_installed_menu.'.&Related\ file\	:R\ /\ Alt+] :R<CR>'
+      exe menucmd.g:rails_installed_menu.'.&Alternate\ file\	:A\ /\ Alt+[ :A<CR>'
+      exe menucmd.g:rails_installed_menu.'.&File\ under\ cursor\	Ctrl+Enter :Rfind<CR>'
+    else
+      exe menucmd.g:rails_installed_menu.'.-PSep- :'
+      exe menucmd.g:rails_installed_menu.'.&Related\ file\	:R\ /\ ]f :R<CR>'
+      exe menucmd.g:rails_installed_menu.'.&Alternate\ file\	:A\ /\ [f :A<CR>'
+      exe menucmd.g:rails_installed_menu.'.&File\ under\ cursor\	gf :Rfind<CR>'
+    endif
+    exe menucmd.g:rails_installed_menu.'.&Other\ files.Application\ &Controller :find app/controllers/application.rb<CR>'
+    exe menucmd.g:rails_installed_menu.'.&Other\ files.Application\ &Helper :find app/helpers/application_helper.rb<CR>'
+    exe menucmd.g:rails_installed_menu.'.&Other\ files.Application\ &Javascript :find public/javascripts/application.js<CR>'
+    exe menucmd.g:rails_installed_menu.'.&Other\ files.Application\ &Layout :Rlayout application<CR>'
+    exe menucmd.g:rails_installed_menu.'.&Other\ files.Application\ &README :find doc/README_FOR_APP<CR>'
+    exe menucmd.g:rails_installed_menu.'.&Other\ files.&Environment :find config/environment.rb<CR>'
+    exe menucmd.g:rails_installed_menu.'.&Other\ files.&Database\ Configuration :find config/database.yml<CR>'
+    exe menucmd.g:rails_installed_menu.'.&Other\ files.Database\ &Schema :Rmigration 0<CR>'
+    exe menucmd.g:rails_installed_menu.'.&Other\ files.R&outes :find config/routes.rb<CR>'
+    exe menucmd.g:rails_installed_menu.'.&Other\ files.&Test\ Helper :find test/test_helper.rb<CR>'
+    exe menucmd.g:rails_installed_menu.'.-FSep- :'
+    exe menucmd.g:rails_installed_menu.'.Ra&ke\	:Rake :Rake<CR>'
+    let menucmd = substitute(menucmd,'200 $','500 ','')
+    exe menucmd.g:rails_installed_menu.'.&Server\	:Rserver.&Start\	:Rserver :Rserver<CR>'
+    exe menucmd.g:rails_installed_menu.'.&Server\	:Rserver.&Force\ start\	:Rserver! :Rserver!<CR>'
+    exe menucmd.g:rails_installed_menu.'.&Server\	:Rserver.&Kill\	:Rserver!\ - :Rserver! -<CR>'
+    exe substitute(menucmd,'<script>','<script> <silent>','').g:rails_installed_menu.'.&Evaluate\ Ruby\.\.\.\	:Rp :call <SID>menuprompt("Rp","Code to execute and output: ")<CR>'
+    exe menucmd.g:rails_installed_menu.'.&Console\	:Rscript :Rscript console<CR>'
+    exe menucmd.g:rails_installed_menu.'.&Preview\	:Rpreview :Rpreview<CR>'
+    exe menucmd.g:rails_installed_menu.'.&Log\ file\	:Rlog :Rlog<CR>'
+    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>'
+    exe menucmd.g:rails_installed_menu.'.&Migration\ writer\	:Rinvert :Rinvert<CR>'
+    exe menucmd.'         '.g:rails_installed_menu.'.-HSep- :'
+    exe substitute(menucmd,'<script>','<script> <silent>','').g:rails_installed_menu.'.&Help\	:help\ rails :if <SID>autoload()<Bar>exe RailsHelpCommand("")<Bar>endif<CR>'
+    exe substitute(menucmd,'<script>','<script> <silent>','').g:rails_installed_menu.'.Abo&ut\	 :if <SID>autoload()<Bar>exe RailsHelpCommand("about")<Bar>endif<CR>'
+    let g:rails_did_menus = 1
+    call s:ProjectMenu()
+    call s:menuBufLeave()
+    if exists("b:rails_root")
+      call s:menuBufEnter()
+    endif
+  endif
+endfunction
+
+function! s:ProjectMenu()
+  if exists("g:rails_did_menus") && g:rails_history_size > 0
+    if !exists("g:RAILS_HISTORY")
+      let g:RAILS_HISTORY = ""
+    endif
+    let history = g:RAILS_HISTORY
+    let menu = s:gsub(g:rails_installed_menu,'\&','')
+    silent! exe "aunmenu <script> ".menu.".Projects"
+    let dots = s:gsub(menu,'[^.]','')
+    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>'
+    exe 'anoremenu <script> '.menu.'.Pro&jects.-FSep- :'
+    while history =~ '\n'
+      let proj = matchstr(history,'^.\{-\}\ze\n')
+      let history = s:sub(history,'^.{-}\n','')
+      exe 'anoremenu <script> '.menu.'.Pro&jects.'.s:gsub(proj,'[.\\ ]','\\&').' :e '.s:gsub(proj."/".g:rails_default_file,'[ !%#]','\\&')."<CR>"
+    endwhile
+  endif
+endfunction
+
+function! s:menuBufEnter()
+  if exists("g:rails_installed_menu") && g:rails_installed_menu != ""
+    let menu = s:gsub(g:rails_installed_menu,'\&','')
+    exe 'amenu enable '.menu.'.*'
+    if RailsFileType() !~ '^view\>'
+      exe 'vmenu disable '.menu.'.Extract\ as\ partial'
+    endif
+    if RailsFileType() !~ '^\%(db-\)\=migration$' || RailsFilePath() =~ '\<db/schema\.rb$'
+      exe 'amenu disable '.menu.'.Migration\ writer'
+    endif
+    call s:ProjectMenu()
+    silent! exe 'aunmenu       '.menu.'.Rake\ tasks'
+    silent! exe 'aunmenu       '.menu.'.Generate'
+    silent! exe 'aunmenu       '.menu.'.Destroy'
+    if rails#app().cache.needs('rake_tasks') || empty(rails#app().rake_tasks())
+      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>'
+    else
+      let i = 0
+      while i < len(rails#app().rake_tasks())
+        let task = rails#app().rake_tasks()[i]
+        exe s:menucmd(300).g:rails_installed_menu.'.Rake\ &tasks\	:Rake.'.s:sub(task,':',':.').' :Rake '.task.'<CR>'
+        let i += 1
+      endwhile
+    endif
+    let i = 0
+    let menucmd = substitute(s:menucmd(400),'<script>','<script> <silent>','').g:rails_installed_menu
+    while i < len(rails#app().generators())
+      let generator = rails#app().generators()[i]
+      exe menucmd.'.&Generate\	:Rgen.'.s:gsub(generator,'_','\\ ').' :call <SID>menuprompt("Rgenerate '.generator.'","Arguments for script/generate '.generator.': ")<CR>'
+      exe menucmd.'.&Destroy\	:Rdestroy.'.s:gsub(generator,'_','\\ ').' :call <SID>menuprompt("Rdestroy '.generator.'","Arguments for script/destroy '.generator.': ")<CR>'
+      let i += 1
+    endwhile
+  endif
+endfunction
+
+function! s:menuBufLeave()
+  if exists("g:rails_installed_menu") && g:rails_installed_menu != ""
+    let menu = s:gsub(g:rails_installed_menu,'\&','')
+    exe 'amenu disable '.menu.'.*'
+    exe 'amenu enable  '.menu.'.Help\	'
+    exe 'amenu enable  '.menu.'.About\	'
+    exe 'amenu enable  '.menu.'.Projects'
+    silent! exe 'aunmenu       '.menu.'.Rake\ tasks'
+    silent! exe 'aunmenu       '.menu.'.Generate'
+    silent! exe 'aunmenu       '.menu.'.Destroy'
+    exe s:menucmd(300).g:rails_installed_menu.'.Rake\ tasks\	:Rake.-TSep- :'
+    exe s:menucmd(400).g:rails_installed_menu.'.&Generate\	:Rgen.-GSep- :'
+    exe s:menucmd(400).g:rails_installed_menu.'.&Destroy\	:Rdestroy.-DSep- :'
+  endif
+endfunction
+
+function! s:menuprompt(vimcmd,prompt)
+  let res = inputdialog(a:prompt,'','!!!')
+  if res == '!!!'
+    return ""
+  endif
+  exe a:vimcmd." ".res
+endfunction
+
+call s:CreateMenus()
+
+augroup railsPluginMenu
+  autocmd!
+  autocmd User BufEnterRails call s:menuBufEnter()
+  autocmd User BufLeaveRails call s:menuBufLeave()
+  " g:RAILS_HISTORY hasn't been set when s:InitPlugin() is called.
+  autocmd VimEnter *         call s:ProjectMenu()
+augroup END
+
+" }}}1
+" vim:set sw=2 sts=2:

+ 97 - 0
dotfiles/vim/railscasts.vim

@@ -0,0 +1,97 @@
+" Vim color scheme based on http://github.com/jpo/vim-railscasts-theme
+"
+" Name:        railscasts.vim
+" Maintainer:  Ryan Bates
+" License:     MIT
+
+set background=dark
+hi clear
+if exists("syntax_on")
+  syntax reset
+endif
+let g:colors_name = "railscasts"
+
+" Colors
+" Brown        #BC9357
+" Dark Blue    #6D9CBD
+" Dark Green   #509E50
+" Dark Orange  #CC7733
+" Light Blue   #CFCFFF
+" Light Green  #A5C160
+" Tan          #FFC66D
+" Red          #DA4938 
+
+hi Normal     guifg=#E6E1DC guibg=#232323
+hi Cursor     guibg=#FFFFFF
+hi CursorLine guibg=#333435
+hi LineNr     guifg=#666666
+hi Visual     guibg=#5A647E
+hi Search     guifg=NONE    guibg=#131313  gui=NONE
+hi Folded     guifg=#F6F3E8 guibg=#444444  gui=NONE
+hi Directory  guifg=#A5C160 gui=NONE
+hi Error      guifg=#FFFFFF guibg=#990000
+hi MatchParen guifg=NONE    guibg=#131313
+hi Title      guifg=#E6E1DC
+
+hi Comment    guifg=#BC9357 guibg=NONE     gui=italic
+hi! link Todo Comment
+
+hi String     guifg=#A5C160
+hi! link Number String
+hi! link rubyStringDelimiter String
+
+" nil, self, symbols
+hi Constant guifg=#6D9CBD
+
+" def, end, include, load, require, alias, super, yield, lambda, proc
+hi Define guifg=#CC7733 gui=NONE
+hi! link Include Define
+hi! link Keyword Define
+hi! link Macro Define
+
+" #{foo}, <%= bar %>
+hi Delimiter guifg=#509E50
+" hi erubyDelimiter guifg=NONE
+
+" function name (after def)
+hi Function guifg=#FFC66D gui=NONE
+
+"@var, @@var, $var
+hi Identifier guifg=#CFCFFF gui=NONE
+
+" #if, #else, #endif
+
+" case, begin, do, for, if, unless, while, until, else
+hi Statement guifg=#CC7733 gui=NONE
+hi! link PreProc Statement
+hi! link PreCondit Statement
+
+" SomeClassName
+hi Type guifg=NONE gui=NONE
+
+" has_many, respond_to, params
+hi railsMethod guifg=#DA4938 gui=NONE
+
+hi DiffAdd guifg=#E6E1DC guibg=#144212
+hi DiffDelete guifg=#E6E1DC guibg=#660000
+
+hi xmlTag guifg=#E8BF6A
+hi! link xmlTagName  xmlTag
+hi! link xmlEndTag   xmlTag
+hi! link xmlArg      xmlTag
+hi! link htmlTag     xmlTag
+hi! link htmlTagName xmlTagName
+hi! link htmlEndTag  xmlEndTag
+hi! link htmlArg     xmlArg
+
+" Popup Menu
+" ----------
+" normal item in popup
+hi Pmenu guifg=#F6F3E8 guibg=#444444 gui=NONE
+" selected item in popup
+hi PmenuSel guifg=#000000 guibg=#A5C160 gui=NONE
+" scrollbar in popup
+hi PMenuSbar guibg=#5A647E gui=NONE
+" thumb of the scrollbar in the popup
+hi PMenuThumb guibg=#AAAAAA gui=NONE
+

+ 247 - 0
dotfiles/vim/snipMate.vim

@@ -0,0 +1,247 @@
+" File:          snipMate.vim
+" Author:        Michael Sanders
+" Last Updated:  July 13, 2009
+" Version:       0.83
+" Description:   snipMate.vim implements some of TextMate's snippets features in
+"                Vim. A snippet is a piece of often-typed text that you can
+"                insert into your document using a trigger word followed by a "<tab>".
+"
+"                For more help see snipMate.txt; you can do this by using:
+"                :helptags ~/.vim/doc
+"                :h snipMate.txt
+
+if exists('loaded_snips') || &cp || version < 700
+	finish
+endif
+let loaded_snips = 1
+if !exists('snips_author') | let snips_author = 'Me' | endif
+
+au BufRead,BufNewFile *.snippets\= set ft=snippet
+au FileType snippet setl noet fdm=indent
+
+let s:snippets = {} | let s:multi_snips = {}
+
+if !exists('snippets_dir')
+	let snippets_dir = substitute(globpath(&rtp, 'snippets/'), "\n", ',', 'g')
+endif
+
+fun! MakeSnip(scope, trigger, content, ...)
+	let multisnip = a:0 && a:1 != ''
+	let var = multisnip ? 's:multi_snips' : 's:snippets'
+	if !has_key({var}, a:scope) | let {var}[a:scope] = {} | endif
+	if !has_key({var}[a:scope], a:trigger)
+		let {var}[a:scope][a:trigger] = multisnip ? [[a:1, a:content]] : a:content
+	elseif multisnip | let {var}[a:scope][a:trigger] += [[a:1, a:content]]
+	else
+		echom 'Warning in snipMate.vim: Snippet '.a:trigger.' is already defined.'
+				\ .' See :h multi_snip for help on snippets with multiple matches.'
+	endif
+endf
+
+fun! ExtractSnips(dir, ft)
+	for path in split(globpath(a:dir, '*'), "\n")
+		if isdirectory(path)
+			let pathname = fnamemodify(path, ':t')
+			for snipFile in split(globpath(path, '*.snippet'), "\n")
+				call s:ProcessFile(snipFile, a:ft, pathname)
+			endfor
+		elseif fnamemodify(path, ':e') == 'snippet'
+			call s:ProcessFile(path, a:ft)
+		endif
+	endfor
+endf
+
+" Processes a single-snippet file; optionally add the name of the parent
+" directory for a snippet with multiple matches.
+fun s:ProcessFile(file, ft, ...)
+	let keyword = fnamemodify(a:file, ':t:r')
+	if keyword  == '' | return | endif
+	try
+		let text = join(readfile(a:file), "\n")
+	catch /E484/
+		echom "Error in snipMate.vim: couldn't read file: ".a:file
+	endtry
+	return a:0 ? MakeSnip(a:ft, a:1, text, keyword)
+			\  : MakeSnip(a:ft, keyword, text)
+endf
+
+fun! ExtractSnipsFile(file, ft)
+	if !filereadable(a:file) | return | endif
+	let text = readfile(a:file)
+	let inSnip = 0
+	for line in text + ["\n"]
+		if inSnip && (line[0] == "\t" || line == '')
+			let content .= strpart(line, 1)."\n"
+			continue
+		elseif inSnip
+			call MakeSnip(a:ft, trigger, content[:-2], name)
+			let inSnip = 0
+		endif
+
+		if line[:6] == 'snippet'
+			let inSnip = 1
+			let trigger = strpart(line, 8)
+			let name = ''
+			let space = stridx(trigger, ' ') + 1
+			if space " Process multi snip
+				let name = strpart(trigger, space)
+				let trigger = strpart(trigger, 0, space - 1)
+			endif
+			let content = ''
+		endif
+	endfor
+endf
+
+fun! ResetSnippets()
+	let s:snippets = {} | let s:multi_snips = {} | let g:did_ft = {}
+endf
+
+let g:did_ft = {}
+fun! GetSnippets(dir, filetypes)
+	for ft in split(a:filetypes, '\.')
+		if has_key(g:did_ft, ft) | continue | endif
+		call s:DefineSnips(a:dir, ft, ft)
+		if ft == 'objc' || ft == 'cpp' || ft == 'cs'
+			call s:DefineSnips(a:dir, 'c', ft)
+		elseif ft == 'xhtml'
+			call s:DefineSnips(a:dir, 'html', 'xhtml')
+		endif
+		let g:did_ft[ft] = 1
+	endfor
+endf
+
+" Define "aliasft" snippets for the filetype "realft".
+fun s:DefineSnips(dir, aliasft, realft)
+	for path in split(globpath(a:dir, a:aliasft.'/')."\n".
+					\ globpath(a:dir, a:aliasft.'-*/'), "\n")
+		call ExtractSnips(path, a:realft)
+	endfor
+	for path in split(globpath(a:dir, a:aliasft.'.snippets')."\n".
+					\ globpath(a:dir, a:aliasft.'-*.snippets'), "\n")
+		call ExtractSnipsFile(path, a:realft)
+	endfor
+endf
+
+fun! TriggerSnippet()
+	if exists('g:SuperTabMappingForward')
+		if g:SuperTabMappingForward == "<tab>"
+			let SuperTabKey = "\<c-n>"
+		elseif g:SuperTabMappingBackward == "<tab>"
+			let SuperTabKey = "\<c-p>"
+		endif
+	endif
+
+	if pumvisible() " Update snippet if completion is used, or deal with supertab
+		if exists('SuperTabKey')
+			call feedkeys(SuperTabKey) | return ''
+		endif
+		call feedkeys("\<esc>a", 'n') " Close completion menu
+		call feedkeys("\<tab>") | return ''
+	endif
+
+	if exists('g:snipPos') | return snipMate#jumpTabStop(0) | endif
+
+	let word = matchstr(getline('.'), '\S\+\%'.col('.').'c')
+	for scope in [bufnr('%')] + split(&ft, '\.') + ['_']
+		let [trigger, snippet] = s:GetSnippet(word, scope)
+		" If word is a trigger for a snippet, delete the trigger & expand
+		" the snippet.
+		if snippet != ''
+			let col = col('.') - len(trigger)
+			sil exe 's/\V'.escape(trigger, '/.').'\%#//'
+			return snipMate#expandSnip(snippet, col)
+		endif
+	endfor
+
+	if exists('SuperTabKey')
+		call feedkeys(SuperTabKey)
+		return ''
+	endif
+	return "\<tab>"
+endf
+
+fun! BackwardsSnippet()
+	if exists('g:snipPos') | return snipMate#jumpTabStop(1) | endif
+
+	if exists('g:SuperTabMappingForward')
+		if g:SuperTabMappingBackward == "<s-tab>"
+			let SuperTabKey = "\<c-p>"
+		elseif g:SuperTabMappingForward == "<s-tab>"
+			let SuperTabKey = "\<c-n>"
+		endif
+	endif
+	if exists('SuperTabKey')
+		call feedkeys(SuperTabKey)
+		return ''
+	endif
+	return "\<s-tab>"
+endf
+
+" Check if word under cursor is snippet trigger; if it isn't, try checking if
+" the text after non-word characters is (e.g. check for "foo" in "bar.foo")
+fun s:GetSnippet(word, scope)
+	let word = a:word | let snippet = ''
+	while snippet == ''
+		if exists('s:snippets["'.a:scope.'"]["'.escape(word, '\"').'"]')
+			let snippet = s:snippets[a:scope][word]
+		elseif exists('s:multi_snips["'.a:scope.'"]["'.escape(word, '\"').'"]')
+			let snippet = s:ChooseSnippet(a:scope, word)
+			if snippet == '' | break | endif
+		else
+			if match(word, '\W') == -1 | break | endif
+			let word = substitute(word, '.\{-}\W', '', '')
+		endif
+	endw
+	if word == '' && a:word != '.' && stridx(a:word, '.') != -1
+		let [word, snippet] = s:GetSnippet('.', a:scope)
+	endif
+	return [word, snippet]
+endf
+
+fun s:ChooseSnippet(scope, trigger)
+	let snippet = []
+	let i = 1
+	for snip in s:multi_snips[a:scope][a:trigger]
+		let snippet += [i.'. '.snip[0]]
+		let i += 1
+	endfor
+	if i == 2 | return s:multi_snips[a:scope][a:trigger][0][1] | endif
+	let num = inputlist(snippet) - 1
+	return num == -1 ? '' : s:multi_snips[a:scope][a:trigger][num][1]
+endf
+
+fun! ShowAvailableSnips()
+	let line  = getline('.')
+	let col   = col('.')
+	let word  = matchstr(getline('.'), '\S\+\%'.col.'c')
+	let words = [word]
+	if stridx(word, '.')
+		let words += split(word, '\.', 1)
+	endif
+	let matchlen = 0
+	let matches = []
+	for scope in [bufnr('%')] + split(&ft, '\.') + ['_']
+		let triggers = has_key(s:snippets, scope) ? keys(s:snippets[scope]) : []
+		if has_key(s:multi_snips, scope)
+			let triggers += keys(s:multi_snips[scope])
+		endif
+		for trigger in triggers
+			for word in words
+				if word == ''
+					let matches += [trigger] " Show all matches if word is empty
+				elseif trigger =~ '^'.word
+					let matches += [trigger]
+					let len = len(word)
+					if len > matchlen | let matchlen = len | endif
+				endif
+			endfor
+		endfor
+	endfor
+
+	" This is to avoid a bug with Vim when using complete(col - matchlen, matches)
+	" (Issue#46 on the Google Code snipMate issue tracker).
+	call setline(line('.'), substitute(line, repeat('.', matchlen).'\%'.col.'c', '', ''))
+	call complete(col, matches)
+	return ''
+endf
+" vim:noet:sw=4:ts=4:ft=vim