Bunch of changes inspired by r00k
This commit is contained in:
1
vim/bundle/vim-bundler/.gitignore
vendored
Normal file
1
vim/bundle/vim-bundler/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/doc/tags
|
||||
2
vim/bundle/vim-bundler/CONTRIBUTING.markdown
Normal file
2
vim/bundle/vim-bundler/CONTRIBUTING.markdown
Normal file
@@ -0,0 +1,2 @@
|
||||
See the contribution guidelines for
|
||||
[rails.vim](https://github.com/tpope/vim-rails/blob/HEAD/CONTRIBUTING.markdown).
|
||||
55
vim/bundle/vim-bundler/README.markdown
Normal file
55
vim/bundle/vim-bundler/README.markdown
Normal file
@@ -0,0 +1,55 @@
|
||||
# bundler.vim
|
||||
|
||||
This is a lightweight bag of Vim goodies for
|
||||
[Bundler](http://gembundler.com), best accompanied by
|
||||
[rake.vim](https://github.com/tpope/vim-rake) and/or
|
||||
[rails.vim](https://github.com/tpope/vim-rails). Features:
|
||||
|
||||
* `:Bundle`, which wraps `bundle`.
|
||||
* An internalized version of `bundle open`: `:Bopen` (and `:Bsplit`,
|
||||
`:Btabedit`, etc.).
|
||||
* `'path'` and `'tags'` are automatically altered to include all gems
|
||||
from your bundle. (Generate those tags with
|
||||
[gem-ctags](https://github.com/tpope/gem-ctags)!)
|
||||
* Highlight Bundler keywords in `Gemfile`.
|
||||
* Support for `gf` in `Gemfile.lock`, plus syntax highlighting that
|
||||
distinguishes between installed and missing gems.
|
||||
|
||||
## Installation
|
||||
|
||||
If you don't have a preferred installation method, I recommend
|
||||
installing [pathogen.vim](https://github.com/tpope/vim-pathogen), and
|
||||
then simply copy and paste:
|
||||
|
||||
cd ~/.vim/bundle
|
||||
git clone git://github.com/tpope/vim-bundler.git
|
||||
|
||||
Once help tags have been generated, you can view the manual with
|
||||
`:help bundler`.
|
||||
|
||||
## FAQ
|
||||
|
||||
> I installed the plugin and started Vim. Why don't any of the commands
|
||||
> exist?
|
||||
|
||||
This plugin cares about the current file, not the current working
|
||||
directory. Edit a file that's covered by a `Gemfile`.
|
||||
|
||||
> I opened a new tab. Why don't any of the commands exist?
|
||||
|
||||
This plugin cares about the current file, not the current working
|
||||
directory. Edit a file that's covered by a `Gemfile`.
|
||||
|
||||
## Self-Promotion
|
||||
|
||||
Like bundler.vim? Follow the repository on
|
||||
[GitHub](https://github.com/tpope/vim-bundler) and vote for it on
|
||||
[vim.org](http://www.vim.org/scripts/script.php?script_id=4280). And if
|
||||
you're feeling especially charitable, follow [tpope](http://tpo.pe/) on
|
||||
[Twitter](http://twitter.com/tpope) and
|
||||
[GitHub](https://github.com/tpope).
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) Tim Pope. Distributed under the same terms as Vim itself.
|
||||
See `:help license`.
|
||||
26
vim/bundle/vim-bundler/compiler/bundler.vim
Normal file
26
vim/bundle/vim-bundler/compiler/bundler.vim
Normal file
@@ -0,0 +1,26 @@
|
||||
" Vim compiler file
|
||||
|
||||
if exists("current_compiler")
|
||||
finish
|
||||
endif
|
||||
let current_compiler = "bundler"
|
||||
|
||||
let s:cpo_save = &cpo
|
||||
set cpo-=C
|
||||
|
||||
CompilerSet makeprg=bundle
|
||||
|
||||
CompilerSet errorformat=
|
||||
\%+E%f:%l:\ parse\ error,
|
||||
\%W%f:%l:\ warning:\ %m,
|
||||
\%E%f:%l:in\ %*[^:]:\ %m,
|
||||
\%E%f:%l:\ %m,
|
||||
\%-C%\tfrom\ %f:%l:in\ %.%#,
|
||||
\%-Z%\tfrom\ %f:%l,
|
||||
\%-Z%p^,
|
||||
\%-G%.%#
|
||||
|
||||
let &cpo = s:cpo_save
|
||||
unlet s:cpo_save
|
||||
|
||||
" vim: sw=2:
|
||||
68
vim/bundle/vim-bundler/doc/bundler.txt
Normal file
68
vim/bundle/vim-bundler/doc/bundler.txt
Normal file
@@ -0,0 +1,68 @@
|
||||
*bundler.txt* Support for Ruby's Bundler
|
||||
|
||||
Author: Tim Pope <http://tpo.pe/>
|
||||
License: Same terms as Vim itself (see |license|)
|
||||
|
||||
This plugin is only available if 'compatible' is not set.
|
||||
|
||||
INTRODUCTION *bundler*
|
||||
|
||||
This lightweight companion to rails.vim and rake.vim provides support for
|
||||
Bundler. In addition to the below commands, it also syntax highlights
|
||||
Gemfile and Gemfile.lock, and alters 'path' and 'tags' to include bundled
|
||||
gems. I recommend gem-ctags for generating tags for your gems.
|
||||
|
||||
COMMANDS *bundler-commands*
|
||||
|
||||
*bundler-:Bundle*
|
||||
:Bundle[!] [args] Invoke `bundle` via |:make|.
|
||||
|
||||
|
||||
*bundler-:Bopen*
|
||||
:Bopen[!] [gem] With no argument, edits the Gemfile. Otherwise,
|
||||
effectively does a `bundle open` of a gem inside of
|
||||
Vim, including an |:lcd| to the gem's root directory.
|
||||
Add ! to discard the current buffer's changes.
|
||||
|
||||
*bundler-:Bedit*
|
||||
:Bedit[!] [gem] Like |:Bopen|, but don't |:lcd| afterwards.
|
||||
|
||||
*bundler-:Bsplit*
|
||||
:Bsplit[!] [gem] Like |:Bopen|, but horizontally split. Add ! to
|
||||
suppress the |:lcd|.
|
||||
|
||||
*bundler-:Bvsplit*
|
||||
:Bvsplit[!] [gem] Like |:Bopen|, but vertically split. Add ! to
|
||||
suppress the |:lcd|.
|
||||
|
||||
*bundler-:Btabedit*
|
||||
:Btabedit[!] [gem] Like |:Bopen|, but use a new tab. Add ! to
|
||||
suppress the |:lcd|.
|
||||
|
||||
*bundler-:Bpedit*
|
||||
:Bpedit[!] [gem] Like |:Bopen|, but use a preview window. Add ! to
|
||||
suppress the |:lcd|.
|
||||
|
||||
API *bundler-api*
|
||||
|
||||
Use bundler#project(root) to retrieve an object for the project at the given
|
||||
root path. If no path is given, the current buffer's project root is used.
|
||||
An empty object is returned if no project is found. Use |empty()| to check
|
||||
for that.
|
||||
|
||||
On the bundler#project() object, versions() returns a dictionary mapping
|
||||
between gem names and their locked versions, paths() returns a dictionary
|
||||
mapping between gem names and their installation path (omitting gems which
|
||||
aren't installed), and has(gem) returns true if the given gem name is in the
|
||||
bundle (regardless of whether or not it is installed).
|
||||
|
||||
The original data structures are returned for performance reasons. Do not
|
||||
mutate.
|
||||
|
||||
ABOUT *bundler-about*
|
||||
|
||||
Grab the latest version or report a bug on GitHub:
|
||||
|
||||
http://github.com/tpope/vim-bundler
|
||||
|
||||
vim:tw=78:et:ft=help:norl:
|
||||
581
vim/bundle/vim-bundler/plugin/bundler.vim
Normal file
581
vim/bundle/vim-bundler/plugin/bundler.vim
Normal file
@@ -0,0 +1,581 @@
|
||||
" bundler.vim - Support for Ruby's Bundler
|
||||
" Maintainer: Tim Pope <http://tpo.pe/>
|
||||
" Version: 2.0
|
||||
|
||||
if exists('g:loaded_bundler') || &cp || v:version < 700
|
||||
finish
|
||||
endif
|
||||
let g:loaded_bundler = 1
|
||||
|
||||
" Utility {{{1
|
||||
|
||||
function! s:function(name) abort
|
||||
return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '<SNR>\d\+_'),''))
|
||||
endfunction
|
||||
|
||||
function! s:sub(str,pat,rep) abort
|
||||
return substitute(a:str,'\v\C'.a:pat,a:rep,'')
|
||||
endfunction
|
||||
|
||||
function! s:gsub(str,pat,rep) abort
|
||||
return substitute(a:str,'\v\C'.a:pat,a:rep,'g')
|
||||
endfunction
|
||||
|
||||
function! s:shellesc(arg) abort
|
||||
if a:arg =~ '^[A-Za-z0-9_/.-]\+$'
|
||||
return a:arg
|
||||
else
|
||||
return shellescape(a:arg)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:fnameescape(file) abort
|
||||
if exists('*fnameescape')
|
||||
return fnameescape(a:file)
|
||||
else
|
||||
return escape(a:file," \t\n*?[{`$\\%#'\"|!<")
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:shellslash(path)
|
||||
if exists('+shellslash') && !&shellslash
|
||||
return s:gsub(a:path,'\\','/')
|
||||
else
|
||||
return a:path
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:completion_filter(results,A)
|
||||
let results = sort(copy(a:results))
|
||||
call filter(results,'v:val !~# "\\~$"')
|
||||
let filtered = filter(copy(results),'v:val[0:strlen(a:A)-1] ==# 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 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:throw(string) abort
|
||||
let v:errmsg = 'bundler: '.a:string
|
||||
throw v:errmsg
|
||||
endfunction
|
||||
|
||||
function! s:warn(str)
|
||||
echohl WarningMsg
|
||||
echomsg a:str
|
||||
echohl None
|
||||
let v:warningmsg = a:str
|
||||
endfunction
|
||||
|
||||
function! s:add_methods(namespace, method_names) abort
|
||||
for name in a:method_names
|
||||
let s:{a:namespace}_prototype[name] = s:function('s:'.a:namespace.'_'.name)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
let s:commands = []
|
||||
function! s:command(definition) abort
|
||||
let s:commands += [a:definition]
|
||||
endfunction
|
||||
|
||||
function! s:define_commands()
|
||||
for command in s:commands
|
||||
exe 'command! -buffer '.command
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
augroup bundler_utility
|
||||
autocmd!
|
||||
autocmd User Bundler call s:define_commands()
|
||||
augroup END
|
||||
|
||||
let s:abstract_prototype = {}
|
||||
|
||||
" }}}1
|
||||
" Syntax highlighting {{{1
|
||||
|
||||
function! s:syntaxfile()
|
||||
syntax keyword rubyGemfileMethod gemspec gem source path git group platforms env ruby
|
||||
hi def link rubyGemfileMethod Function
|
||||
endfunction
|
||||
|
||||
function! s:syntaxlock()
|
||||
setlocal iskeyword+=-,.
|
||||
syn match gemfilelockHeading '^[[:upper:]]\+$'
|
||||
syn match gemfilelockKey '^\s\+\zs\S\+:'he=e-1 skipwhite nextgroup=gemfilelockRevision
|
||||
syn match gemfilelockKey 'remote:'he=e-1 skipwhite nextgroup=gemfilelockRemote
|
||||
syn match gemfilelockRemote '\S\+' contained
|
||||
syn match gemfilelockRevision '[[:alnum:]._-]\+$' contained
|
||||
syn match gemfilelockGem '^\s\+\zs[[:alnum:]._-]\+\%([ !]\|$\)\@=' contains=gemfilelockFound,gemfilelockMissing skipwhite nextgroup=gemfilelockVersions,gemfilelockBang
|
||||
syn match gemfilelockVersions '([^()]*)' contained contains=gemfilelockVersion
|
||||
syn match gemfilelockVersion '[^,()]*' contained
|
||||
syn match gemfilelockBang '!' contained
|
||||
if !empty(bundler#project())
|
||||
exe 'syn match gemfilelockFound "\<\%(bundler\|' . join(keys(s:project().paths()), '\|') . '\)\>" contained'
|
||||
exe 'syn match gemfilelockMissing "\<\%(' . join(keys(filter(s:project().versions(), '!has_key(s:project().paths(), v:key)')), '\|') . '\)\>" contained'
|
||||
else
|
||||
exe 'syn match gemfilelockFound "\<\%(\S*\)\>" contained'
|
||||
endif
|
||||
syn match gemfilelockHeading '^PLATFORMS$' nextgroup=gemfilelockPlatform skipnl skipwhite
|
||||
syn match gemfilelockPlatform '^ \zs[[:alnum:]._-]\+$' contained nextgroup=gemfilelockPlatform skipnl skipwhite
|
||||
|
||||
hi def link gemfilelockHeading PreProc
|
||||
hi def link gemfilelockPlatform Typedef
|
||||
hi def link gemfilelockKey Identifier
|
||||
hi def link gemfilelockRemote String
|
||||
hi def link gemfilelockRevision Number
|
||||
hi def link gemfilelockFound Statement
|
||||
hi def link gemfilelockMissing Error
|
||||
hi def link gemfilelockVersion Type
|
||||
hi def link gemfilelockBang Special
|
||||
endfunction
|
||||
|
||||
function! s:setuplock()
|
||||
nnoremap <silent><buffer> gf :Bopen <C-R><C-F><CR>
|
||||
nnoremap <silent><buffer> <C-W>f :Bsplit <C-R><C-F><CR>
|
||||
nnoremap <silent><buffer> <C-W><C-F> :Bsplit <C-R><C-F><CR>
|
||||
nnoremap <silent><buffer> <C-W>gf :Btabedit <C-R><C-F><CR>
|
||||
endfunction
|
||||
|
||||
augroup bundler_syntax
|
||||
autocmd!
|
||||
autocmd BufNewFile,BufRead */.bundle/config set filetype=yaml
|
||||
autocmd BufNewFile,BufRead Gemfile set filetype=ruby
|
||||
autocmd Syntax ruby if expand('<afile>:t') ==? 'gemfile' | call s:syntaxfile() | endif
|
||||
autocmd BufNewFile,BufRead [Gg]emfile.lock setf gemfilelock
|
||||
autocmd FileType gemfilelock set suffixesadd=.rb
|
||||
autocmd Syntax gemfilelock call s:syntaxlock()
|
||||
autocmd FileType gemfilelock call s:setuplock()
|
||||
autocmd User Rails/Gemfile.lock call s:setuplock()
|
||||
augroup END
|
||||
|
||||
" }}}1
|
||||
" Initialization {{{1
|
||||
|
||||
function! s:FindBundlerRoot(path) abort
|
||||
let path = s:shellslash(a:path)
|
||||
let fn = fnamemodify(path,':s?[\/]$??')
|
||||
let ofn = ""
|
||||
let nfn = fn
|
||||
while fn != ofn
|
||||
if filereadable(fn.'/Gemfile')
|
||||
return s:sub(simplify(fnamemodify(fn,':p')),'[\\/]$','')
|
||||
endif
|
||||
let ofn = fn
|
||||
let fn = fnamemodify(ofn,':h')
|
||||
endwhile
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! s:Detect(path)
|
||||
if !exists('b:bundler_root')
|
||||
let dir = s:FindBundlerRoot(a:path)
|
||||
if dir != ''
|
||||
let b:bundler_root = dir
|
||||
endif
|
||||
endif
|
||||
if exists('b:bundler_root')
|
||||
silent doautocmd User Bundler
|
||||
endif
|
||||
endfunction
|
||||
|
||||
augroup bundler
|
||||
autocmd!
|
||||
autocmd FileType * call s:Detect(expand('<afile>:p'))
|
||||
autocmd BufNewFile,BufReadPost *
|
||||
\ if empty(&filetype) |
|
||||
\ call s:Detect(expand('<afile>:p')) |
|
||||
\ endif
|
||||
autocmd VimEnter * if expand('<amatch>')==''|call s:Detect(getcwd())|endif
|
||||
augroup END
|
||||
|
||||
" }}}1
|
||||
" Project {{{1
|
||||
|
||||
let s:project_prototype = {}
|
||||
let s:projects = {}
|
||||
|
||||
function! bundler#project(...) abort
|
||||
let dir = a:0 ? a:1 : (exists('b:bundler_root') && b:bundler_root !=# '' ? b:bundler_root : s:FindBundlerRoot(expand('%:p')))
|
||||
if dir !=# ''
|
||||
if has_key(s:projects,dir)
|
||||
let project = get(s:projects,dir)
|
||||
else
|
||||
let project = {'root': dir}
|
||||
let s:projects[dir] = project
|
||||
endif
|
||||
return extend(extend(project,s:project_prototype,'keep'),s:abstract_prototype,'keep')
|
||||
endif
|
||||
return {}
|
||||
endfunction
|
||||
|
||||
function! s:project(...) abort
|
||||
let project = a:0 ? bundler#project(a:1) : bundler#project()
|
||||
if empty(project)
|
||||
call s:throw('not a Bundler project: '.(a:0 ? a:1 : expand('%')))
|
||||
else
|
||||
return project
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:project_path(...) dict abort
|
||||
return join([self.root]+a:000,'/')
|
||||
endfunction
|
||||
|
||||
call s:add_methods('project',['path'])
|
||||
|
||||
function! s:project_locked() dict abort
|
||||
let lock_file = self.path('Gemfile.lock')
|
||||
let time = getftime(lock_file)
|
||||
if time != -1 && time != get(self,'_lock_time',-1)
|
||||
let self._locked = {'git': [], 'gem': [], 'path': []}
|
||||
let self._versions = {}
|
||||
|
||||
for line in readfile(lock_file)
|
||||
if line =~# '^\S'
|
||||
let properties = {'versions': {}}
|
||||
if has_key(self._locked, tolower(line))
|
||||
call extend(self._locked[tolower(line)], [properties])
|
||||
endif
|
||||
elseif line =~# '^ \w\+: '
|
||||
let properties[matchstr(line, '\w\+')] = matchstr(line, ': \zs.*')
|
||||
elseif line =~# '^ [a-zA-Z0-9._-]\+\s\+(\d\+'
|
||||
let name = split(line, ' ')[0]
|
||||
let ver = substitute(line, '.*(\|).*', '', 'g')
|
||||
let properties.versions[name] = ver
|
||||
let self._versions[name] = ver
|
||||
endif
|
||||
endfor
|
||||
let self._lock_time = time
|
||||
endif
|
||||
return get(self, '_locked', {})
|
||||
endfunction
|
||||
|
||||
function! s:project_paths(...) dict abort
|
||||
call self.locked()
|
||||
let time = get(self, '_lock_time', -1)
|
||||
if a:0 && a:1 ==# 'refresh' || time != -1 && time != get(self, '_path_time', -1)
|
||||
let paths = {}
|
||||
|
||||
let chdir = exists("*haslocaldir") && haslocaldir() ? "lchdir" : "chdir"
|
||||
let cwd = getcwd()
|
||||
|
||||
" Explicitly setting $PATH means /etc/zshenv on OS X can't touch it.
|
||||
if executable('env')
|
||||
let prefix = 'env PATH='.s:shellesc($PATH).' '
|
||||
else
|
||||
let prefix = ''
|
||||
endif
|
||||
|
||||
let gem_paths = []
|
||||
if exists('$GEM_PATH')
|
||||
let gem_paths = split($GEM_PATH, has('win32') ? ';' : ':')
|
||||
else
|
||||
try
|
||||
exe chdir s:fnameescape(self.path())
|
||||
let gem_paths = split(system(prefix.'ruby -rubygems -e "print Gem.path.join(%(;))"'), ';')
|
||||
finally
|
||||
exe chdir s:fnameescape(cwd)
|
||||
endtry
|
||||
endif
|
||||
|
||||
let abi_version = matchstr(get(gem_paths, 0, '1.9.1'), '[0-9.]\+$')
|
||||
for config in [expand('~/.bundle/config'), self.path('.bundle/config')]
|
||||
if filereadable(config)
|
||||
let body = join(readfile(config), "\n")
|
||||
let bundle_path = matchstr(body, "\\C\\<BUNDLE_PATH: \\zs[^\n]*")
|
||||
if !empty(bundle_path)
|
||||
if body =~# '\C\<BUNDLE_DISABLE_SHARED_GEMS:'
|
||||
let gem_paths = [self.path(bundle_path, 'ruby', abi_version)]
|
||||
else
|
||||
let gem_paths = [self.path(bundle_path)]
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
for source in self._locked.git
|
||||
for [name, ver] in items(source.versions)
|
||||
for path in gem_paths
|
||||
let dir = path . '/bundler/gems/' . matchstr(source.remote, '.*/\zs.\{-\}\ze\%(\.git\)\=$') . '-' . source.revision[0:11]
|
||||
if isdirectory(dir)
|
||||
let files = split(glob(dir . '/*/' . name . '.gemspec'), "\n")
|
||||
if empty(files)
|
||||
let paths[name] = dir
|
||||
else
|
||||
let paths[name] = files[0][0 : -10-strlen(name)]
|
||||
endif
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
endfor
|
||||
|
||||
for source in self._locked.path
|
||||
for [name, ver] in items(source.versions)
|
||||
if source.remote !~# '^/'
|
||||
let local = simplify(self.path(source.remote))
|
||||
else
|
||||
let local = source.remote
|
||||
endif
|
||||
let files = split(glob(local . '/*/' . name . '.gemspec'), "\n")
|
||||
if empty(files)
|
||||
let paths[name] = local
|
||||
else
|
||||
let paths[name] = files[0][0 : -10-strlen(name)]
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
for source in self._locked.gem
|
||||
for [name, ver] in items(source.versions)
|
||||
for path in gem_paths
|
||||
let dir = path . '/gems/' . name . '-' . ver
|
||||
if isdirectory(dir)
|
||||
let paths[name] = dir
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
if !has_key(paths, name)
|
||||
for path in gem_paths
|
||||
let dir = glob(path . '/gems/' . name . '-' . ver . '-*')
|
||||
if isdirectory(dir)
|
||||
let paths[name] = dir
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
let self._path_time = time
|
||||
let self._paths = paths
|
||||
let self._sorted = sort(values(paths))
|
||||
let index = index(self._sorted, self.path())
|
||||
if index > 0
|
||||
call insert(self._sorted, remove(self._sorted,index))
|
||||
endif
|
||||
call self.alter_buffer_paths()
|
||||
return paths
|
||||
endif
|
||||
return get(self,'_paths',{})
|
||||
endfunction
|
||||
|
||||
function! s:project_sorted() dict abort
|
||||
call self.paths()
|
||||
return get(self, '_sorted', [])
|
||||
endfunction
|
||||
|
||||
function! s:project_gems() dict abort
|
||||
return self.paths()
|
||||
endfunction
|
||||
|
||||
function! s:project_versions() dict abort
|
||||
call self.locked()
|
||||
return get(self, '_versions', {})
|
||||
endfunction
|
||||
|
||||
function! s:project_has(gem) dict abort
|
||||
call self.locked()
|
||||
return has_key(self.versions(), a:gem)
|
||||
endfunction
|
||||
|
||||
call s:add_methods('project', ['locked', 'gems', 'paths', 'sorted', 'versions', 'has'])
|
||||
|
||||
" }}}1
|
||||
" Buffer {{{1
|
||||
|
||||
let s:buffer_prototype = {}
|
||||
|
||||
function! s:buffer(...) abort
|
||||
let buffer = {'#': bufnr(a:0 ? a:1 : '%')}
|
||||
let g:buffer = buffer
|
||||
call extend(extend(buffer,s:buffer_prototype,'keep'),s:abstract_prototype,'keep')
|
||||
if buffer.getvar('bundler_root') !=# ''
|
||||
return buffer
|
||||
endif
|
||||
call s:throw('not a Bundler project: '.(a:0 ? a:1 : expand('%')))
|
||||
endfunction
|
||||
|
||||
function! bundler#buffer(...) abort
|
||||
return s:buffer(a:0 ? a:1 : '%')
|
||||
endfunction
|
||||
|
||||
function! s:buffer_getvar(var) dict abort
|
||||
return getbufvar(self['#'],a:var)
|
||||
endfunction
|
||||
|
||||
function! s:buffer_setvar(var,value) dict abort
|
||||
return setbufvar(self['#'],a:var,a:value)
|
||||
endfunction
|
||||
|
||||
function! s:buffer_project() dict abort
|
||||
return s:project(self.getvar('bundler_root'))
|
||||
endfunction
|
||||
|
||||
call s:add_methods('buffer',['getvar','setvar','project'])
|
||||
|
||||
" }}}1
|
||||
" Bundle {{{1
|
||||
|
||||
function! s:push_chdir()
|
||||
if !exists("s:command_stack") | let s:command_stack = [] | endif
|
||||
let chdir = exists("*haslocaldir") && haslocaldir() ? "lchdir " : "chdir "
|
||||
call add(s:command_stack,chdir.s:fnameescape(getcwd()))
|
||||
exe chdir.'`=s:project().path()`'
|
||||
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:Bundle(bang,arg)
|
||||
let old_makeprg = &l:makeprg
|
||||
let old_errorformat = &l:errorformat
|
||||
let old_compiler = get(b:, 'current_compiler', '')
|
||||
try
|
||||
compiler bundler
|
||||
execute 'make! '.a:arg
|
||||
if a:bang ==# ''
|
||||
return 'if !empty(getqflist()) | cfirst | endif'
|
||||
else
|
||||
return ''
|
||||
endif
|
||||
finally
|
||||
let &l:errorformat = old_errorformat
|
||||
let &l:makeprg = old_makeprg
|
||||
let b:current_compiler = old_compiler
|
||||
if empty(b:current_compiler)
|
||||
unlet b:current_compiler
|
||||
endif
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:BundleComplete(A,L,P)
|
||||
if a:L =~# '^\S\+\s\+\%(show\|update\) '
|
||||
return s:completion_filter(keys(s:project().paths()),a:A)
|
||||
endif
|
||||
return s:completion_filter(['install','update','exec','package','config','check','list','show','outdated','console','viz','benchmark'],a:A)
|
||||
endfunction
|
||||
|
||||
function! s:SetupMake() abort
|
||||
compiler bundler
|
||||
endfunction
|
||||
|
||||
call s:command("-bar -bang -nargs=? -complete=customlist,s:BundleComplete Bundle :execute s:Bundle('<bang>',<q-args>)")
|
||||
|
||||
augroup bundler_make
|
||||
autocmd FileType gemfilelock call s:SetupMake()
|
||||
autocmd FileType ruby
|
||||
\ if expand('<afile>:t') ==? 'gemfile' |
|
||||
\ call s:SetupMake() |
|
||||
\ endif
|
||||
autocmd QuickFixCmdPre make,lmake
|
||||
\ if &makeprg =~# '^bundle' && exists('b:bundler_root') |
|
||||
\ call s:push_chdir() |
|
||||
\ endif
|
||||
autocmd QuickFixCmdPost make,lmake
|
||||
\ if &makeprg =~# '^bundle' && exists('b:bundler_root') |
|
||||
\ call s:pop_command() |
|
||||
\ call s:project().paths("refresh") |
|
||||
\ endif
|
||||
augroup END
|
||||
|
||||
" }}}1
|
||||
" Bopen {{{1
|
||||
|
||||
function! s:Open(cmd,gem,lcd)
|
||||
if a:gem ==# '' && a:lcd
|
||||
return a:cmd.' `=bundler#buffer().project().path("Gemfile")`'
|
||||
elseif a:gem ==# ''
|
||||
return a:cmd.' `=bundler#buffer().project().path("Gemfile.lock")`'
|
||||
else
|
||||
if !has_key(s:project().paths(), a:gem)
|
||||
call s:project().paths('refresh')
|
||||
endif
|
||||
if !has_key(s:project().paths(), a:gem)
|
||||
if has_key(s:project().versions(), a:gem)
|
||||
let v:errmsg = "Gem \"".a:gem."\" is in bundle but not installed"
|
||||
else
|
||||
let v:errmsg = "Gem \"".a:gem."\" is not in bundle"
|
||||
endif
|
||||
return 'echoerr v:errmsg'
|
||||
endif
|
||||
let path = fnameescape(bundler#buffer().project().paths()[a:gem])
|
||||
let exec = a:cmd.' '.path
|
||||
if a:cmd =~# '^pedit' && a:lcd
|
||||
let exec .= '|wincmd P|lcd '.path.'|wincmd p'
|
||||
elseif a:lcd
|
||||
let exec .= '|lcd '.path
|
||||
endif
|
||||
return exec
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:OpenComplete(A,L,P)
|
||||
return s:completion_filter(keys(s:project().paths()),a:A)
|
||||
endfunction
|
||||
|
||||
call s:command("-bar -bang -nargs=? -complete=customlist,s:OpenComplete Bopen :execute s:Open('edit<bang>',<q-args>,1)")
|
||||
call s:command("-bar -bang -nargs=? -complete=customlist,s:OpenComplete Bedit :execute s:Open('edit<bang>',<q-args>,0)")
|
||||
call s:command("-bar -bang -nargs=? -complete=customlist,s:OpenComplete Bsplit :execute s:Open('split',<q-args>,<bang>1)")
|
||||
call s:command("-bar -bang -nargs=? -complete=customlist,s:OpenComplete Bvsplit :execute s:Open('vsplit',<q-args>,<bang>1)")
|
||||
call s:command("-bar -bang -nargs=? -complete=customlist,s:OpenComplete Btabedit :execute s:Open('tabedit',<q-args>,<bang>1)")
|
||||
call s:command("-bar -bang -nargs=? -complete=customlist,s:OpenComplete Bpedit :execute s:Open('pedit',<q-args>,<bang>1)")
|
||||
|
||||
" }}}1
|
||||
" Paths {{{1
|
||||
|
||||
function! s:build_path_option(paths,suffix) abort
|
||||
return join(map(copy(a:paths),'",".escape(s:shellslash(v:val."/".a:suffix),", ")'),'')
|
||||
endfunction
|
||||
|
||||
function! s:buffer_alter_paths() dict abort
|
||||
if self.getvar('&suffixesadd') =~# '\.rb\>'
|
||||
let new = self.project().sorted()
|
||||
let old = type(self.getvar('bundler_paths')) == type([]) ? self.getvar('bundler_paths') : []
|
||||
for [option, suffix] in [['path', 'lib'], ['tags', 'tags']]
|
||||
let value = self.getvar('&'.option)
|
||||
if !empty(old)
|
||||
let drop = s:build_path_option(old,suffix)
|
||||
let index = stridx(value,drop)
|
||||
if index > 0
|
||||
let value = value[0:index-1] . value[index+strlen(drop):-1]
|
||||
endif
|
||||
endif
|
||||
call self.setvar('&'.option,value.s:build_path_option(new,suffix))
|
||||
endfor
|
||||
call self.setvar('bundler_paths',new)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
call s:add_methods('buffer',['alter_paths'])
|
||||
|
||||
function! s:project_alter_buffer_paths() dict abort
|
||||
for bufnr in range(1,bufnr('$'))
|
||||
if getbufvar(bufnr,'bundler_root') ==# self.path()
|
||||
let vim_parsing_quirk = s:buffer(bufnr).alter_paths()
|
||||
endif
|
||||
if getbufvar(bufnr, '&syntax') ==# 'gemfilelock'
|
||||
call setbufvar(bufnr, '&syntax', 'gemfilelock')
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
call s:add_methods('project',['alter_buffer_paths'])
|
||||
|
||||
augroup bundler_path
|
||||
autocmd!
|
||||
autocmd User Bundler call s:buffer().alter_paths()
|
||||
augroup END
|
||||
|
||||
" }}}1
|
||||
|
||||
" vim:set sw=2 sts=2:
|
||||
Reference in New Issue
Block a user