diff --git a/README.md b/README.md index cd7f7772..2e0a51c3 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ I recommend reading the docs of these plugins to understand them better. Each of * [goyo.vim](https://github.com/junegunn/goyo.vim) and [vim-zenroom2](https://github.com/amix/vim-zenroom2): Remove all clutter and focus only on the essential. Similar to iA Writer or Write Room [Read more here](http://amix.dk/blog/post/19744) * [vim-commentary](https://github.com/tpope/vim-commentary): Comment stuff out. Use `gcc` to comment out a line (takes a count), `gc` to comment out the target of a motion. `gcu` uncomments a set of adjacent commented lines. +* [syntastic](https://github.com/scrooloose/syntastic): Syntax checking hacks for vim ## Included color schemes diff --git a/autoload/pathogen.vim b/autoload/pathogen.vim index 7b89ccaf..a13ae08f 100755 --- a/autoload/pathogen.vim +++ b/autoload/pathogen.vim @@ -1,6 +1,6 @@ " pathogen.vim - path option manipulation " Maintainer: Tim Pope -" Version: 2.2 +" Version: 2.3 " Install in ~/.vim/autoload (or ~\vimfiles\autoload). " @@ -8,52 +8,49 @@ " ~\vimfiles\bundle), adding `execute pathogen#infect()` to the top of your " .vimrc is the only other setup necessary. " -" The API is documented inline below. For maximum ease of reading, -" :set foldmethod=marker +" The API is documented inline below. if exists("g:loaded_pathogen") || &cp finish endif let g:loaded_pathogen = 1 -function! s:warn(msg) - echohl WarningMsg - echomsg a:msg - echohl NONE -endfunction - " Point of entry for basic default usage. Give a relative path to invoke -" pathogen#incubate() (defaults to "bundle/{}"), or an absolute path to invoke -" pathogen#surround(). For backwards compatibility purposes, a full path that -" does not end in {} or * is given to pathogen#runtime_prepend_subdirectories() -" instead. -function! pathogen#infect(...) abort " {{{1 - for path in a:0 ? reverse(copy(a:000)) : ['bundle/{}'] - if path =~# '^[^\\/]\+$' - call s:warn('Change pathogen#infect('.string(path).') to pathogen#infect('.string(path.'/{}').')') - call pathogen#incubate(path . '/{}') - elseif path =~# '^[^\\/]\+[\\/]\%({}\|\*\)$' - call pathogen#incubate(path) - elseif path =~# '[\\/]\%({}\|\*\)$' +" pathogen#interpose() (defaults to "bundle/{}"), or an absolute path to invoke +" pathogen#surround(). Curly braces are expanded with pathogen#expand(): +" "bundle/{}" finds all subdirectories inside "bundle" inside all directories +" in the runtime path. +function! pathogen#infect(...) abort + for path in a:0 ? filter(reverse(copy(a:000)), 'type(v:val) == type("")') : ['bundle/{}'] + if path =~# '^\%({\=[$~\\/]\|{\=\w:[\\/]\).*[{}*]' call pathogen#surround(path) - else + elseif path =~# '^\%([$~\\/]\|\w:[\\/]\)' call s:warn('Change pathogen#infect('.string(path).') to pathogen#infect('.string(path.'/{}').')') call pathogen#surround(path . '/{}') + elseif path =~# '[{}*]' + call pathogen#interpose(path) + else + call s:warn('Change pathogen#infect('.string(path).') to pathogen#infect('.string(path.'/{}').')') + call pathogen#interpose(path . '/{}') endif endfor call pathogen#cycle_filetype() + if pathogen#is_disabled($MYVIMRC) + return 'finish' + endif return '' -endfunction " }}}1 +endfunction " Split a path into a list. -function! pathogen#split(path) abort " {{{1 +function! pathogen#split(path) abort if type(a:path) == type([]) | return a:path | endif + if empty(a:path) | return [] | endif let split = split(a:path,'\\\@"),'!isdirectory(v:val)')) && (!filereadable(dir.sep.'doc'.sep.'tags') || filewritable(dir.sep.'doc'.sep.'tags')) - silent! execute 'helptags' pathogen#fnameescape(dir.'/doc') - endif - endfor - endfor -endfunction " }}}1 - -command! -bar Helptags :call pathogen#helptags() - -" Execute the given command. This is basically a backdoor for --remote-expr. -function! pathogen#execute(...) abort " {{{1 - for command in a:000 - execute command - endfor - return '' -endfunction " }}}1 +" Backport of fnameescape(). +function! pathogen#fnameescape(string) abort + if exists('*fnameescape') + return fnameescape(a:string) + elseif a:string ==# '-' + return '\-' + else + return substitute(escape(a:string," \t\n*?[{`$\\%#'\"|!<"),'^[+>]','\\&','') + endif +endfunction " Like findfile(), but hardcoded to use the runtimepath. function! pathogen#runtime_findfile(file,count) abort "{{{1 @@ -246,18 +247,38 @@ function! pathogen#runtime_findfile(file,count) abort "{{{1 else return fnamemodify(file,':p') endif -endfunction " }}}1 +endfunction -" Backport of fnameescape(). -function! pathogen#fnameescape(string) abort " {{{1 - if exists('*fnameescape') - return fnameescape(a:string) - elseif a:string ==# '-' - return '\-' +" Section: Deprecated + +function! s:warn(msg) abort + echohl WarningMsg + echomsg a:msg + echohl NONE +endfunction + +" Prepend all subdirectories of path to the rtp, and append all 'after' +" directories in those subdirectories. Deprecated. +function! pathogen#runtime_prepend_subdirectories(path) abort + call s:warn('Change pathogen#runtime_prepend_subdirectories('.string(a:path).') to pathogen#infect('.string(a:path.'/{}').')') + return pathogen#surround(a:path . pathogen#slash() . '{}') +endfunction + +function! pathogen#incubate(...) abort + let name = a:0 ? a:1 : 'bundle/{}' + call s:warn('Change pathogen#incubate('.(a:0 ? string(a:1) : '').') to pathogen#infect('.string(name).')') + return pathogen#interpose(name) +endfunction + +" Deprecated alias for pathogen#interpose(). +function! pathogen#runtime_append_all_bundles(...) abort + if a:0 + call s:warn('Change pathogen#runtime_append_all_bundles('.string(a:1).') to pathogen#infect('.string(a:1.'/{}').')') else - return substitute(escape(a:string," \t\n*?[{`$\\%#'\"|!<"),'^[+>]','\\&','') + call s:warn('Change pathogen#runtime_append_all_bundles() to pathogen#infect()') endif -endfunction " }}}1 + return pathogen#interpose(a:0 ? a:1 . '/{}' : 'bundle/{}') +endfunction if exists(':Vedit') finish @@ -265,7 +286,7 @@ endif let s:vopen_warning = 0 -function! s:find(count,cmd,file,lcd) " {{{1 +function! s:find(count,cmd,file,lcd) let rtp = pathogen#join(1,pathogen#split(&runtimepath)) let file = pathogen#runtime_findfile(a:file,a:count) if file ==# '' @@ -284,10 +305,10 @@ function! s:find(count,cmd,file,lcd) " {{{1 else return a:cmd.' '.pathogen#fnameescape(file) . warning endif -endfunction " }}}1 +endfunction -function! s:Findcomplete(A,L,P) " {{{1 - let sep = pathogen#separator() +function! s:Findcomplete(A,L,P) + let sep = pathogen#slash() let cheats = { \'a': 'autoload', \'d': 'doc', @@ -312,7 +333,7 @@ function! s:Findcomplete(A,L,P) " {{{1 endfor endfor return sort(keys(found)) -endfunction " }}}1 +endfunction command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Ve :execute s:find(,'edit',,0) command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vedit :execute s:find(,'edit',,0) @@ -323,4 +344,4 @@ command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vtabed command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vpedit :execute s:find(,'pedit',,1) command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vread :execute s:find(,'read',,1) -" vim:set et sw=2: +" vim:set et sw=2 foldmethod=expr foldexpr=getline(v\:lnum)=~'^\"\ Section\:'?'>1'\:getline(v\:lnum)=~#'^fu'?'a1'\:getline(v\:lnum)=~#'^endf'?'s1'\:'=': diff --git a/bundle/ack.vim/README.md b/bundle/ack.vim/README.md index e7182452..008fb3dd 100644 --- a/bundle/ack.vim/README.md +++ b/bundle/ack.vim/README.md @@ -1,101 +1,60 @@ -# ack.vim # +# ack.vim This plugin is a front for the Perl module [App::Ack](http://search.cpan.org/~petdance/ack/ack). Ack can be used as a replacement for 99% of the uses of _grep_. This plugin will allow you to run ack from vim, and shows the results in a split window. -The *Official Version* of this plugin is available at [vim.org](http://www.vim.org/scripts/script.php?script_id=2572). - -## Installation ## - +## Installation ### Ack -You have to install [ack](http://betterthangrep.com/), of course. - -Install on Debian / Ubuntu with: - - sudo apt-get install ack-grep - -Install on Fedora with: - - su -l -c 'yum install ack' - -Install on openSUSE with: - - sudo zypper install ack - -Install on Gentoo with: - - sudo emerge ack - -Install with Homebrew: - - brew install ack - -Install with MacPorts: - - sudo port install p5-app-ack - -Install with Gentoo Prefix: - - emerge ack - -Install on FreeBSD with: - - cd /usr/ports/textproc/p5-ack/ && make install clean - -You can specify a custom ack name and path in your .vimrc like so: - - let g:ackprg=" -H --nocolor --nogroup --column" - -Otherwise, you are on your own. +You will need the ack(>= 2.0), of course, to install it follow the +[manual](http://beyondgrep.com/install/) ### The Plugin -If you have [Rake](http://rake.rubyforge.org/) installed, you can just run: `rake install`. +To install it is recommended to use one of the popular package managers for Vim, +rather than installing by drag and drop all required files into your `.vim` folder. -Otherwise, the file ack.vim goes in ~/.vim/plugin, and the ack.txt file belongs in ~/.vim/doc. Be sure to run +#### Manual (not recommended) - :helptags ~/.vim/doc +Just +[download](https://github.com/mileszs/ack.vim/archive/kb-improve-readme.zip) the +plugin and put it in your `~/.vim/`(or `%PROGRAMFILES%/Vim/vimfiles` on windows) -afterwards. +#### Vundle + Bundle 'mileszs/ack.vim' -## Usage ## +#### NeoBundle - :Ack [options] {pattern} [{directory}] + NeoBundle 'mileszs/ack.vim' -Search recursively in {directory} (which defaults to the current directory) for the {pattern}. +## Usage + + :Ack [options] {pattern} [{directories}] + +Search recursively in {directory} (which defaults to the current directory) for +the {pattern}. Files containing the search term will be listed in the split window, along with the line number of the occurrence, once for each occurrence. [Enter] on a line in this window will open the file, and place the cursor on the matching line. -Just like where you use :grep, :grepadd, :lgrep, and :lgrepadd, you can use `:Ack`, `:AckAdd`, `:LAck`, and `:LAckAdd` respectively. (See `doc/ack.txt`, or install and `:h Ack` for more information.) +Just like where you use :grep, :grepadd, :lgrep, and :lgrepadd, you can use +`:Ack`, `:AckAdd`, `:LAck`, and `:LAckAdd` respectively. +(See `doc/ack.txt`, or install and `:h Ack` for more information.) -**From the [ack docs](http://betterthangrep.com/)** (my favorite feature): +For more ack options see +[ack documentation](http://beyondgrep.com/documentation/) - --type=TYPE, --type=noTYPE - - Specify the types of files to include or exclude from a search. TYPE is a filetype, like perl or xml. --type=perl can also be specified as --perl, and --type=noperl can be done as --noperl. - - If a file is of both type "foo" and "bar", specifying --foo and --nobar will exclude the file, because an exclusion takes precedence over an inclusion. - - Type specifications can be repeated and are ORed together. - - See ack --help=types for a list of valid types. - -### Gotchas ### - -Some characters have special meaning, and need to be escaped your search pattern. For instance, '#'. You have to escape it like this `:Ack '\\\#define foo'` to search for `#define foo`. (From [blueyed in issue #5](https://github.com/mileszs/ack.vim/issues/5).) - -### Keyboard Shortcuts ### +### Keyboard Shortcuts In the quickfix window, you can use: o to open (same as enter) + O to open and close quickfix window go to preview file (open but maintain focus on ack.vim results) t to open in new tab T to open in new tab silently @@ -106,9 +65,67 @@ In the quickfix window, you can use: q to close the quickfix window This Vim plugin is derived (and by derived, I mean copied, essentially) from -Antoine Imbert's blog post [Ack and Vim -Integration](http://blog.ant0ine.com/typepad/2007/03/ack-and-vim-integration.html) (in -particular, the function at the bottom of the post). I added a help file that +Antoine Imbert's blog post +[Ack and Vim Integration](http://blog.ant0ine.com/typepad/2007/03/ack-and-vim-integration.html) +(in particular, the function at the bottom of the post). I added a help file that provides just enough reference to get you going. I also highly recommend you -check out the docs for the Perl script 'ack', for obvious reasons: [ack - -grep-like text finder](http://betterthangrep.com/). +check out the docs for the Perl script 'ack', for obvious reasons: +[ack - grep-like text finder](http://beyondgrep.com/). + +### Gotchas + +Some characters have special meaning, and need to be escaped your search +pattern. For instance, '#'. You have to escape it like this `:Ack '\\\#define +foo'` to search for '#define foo'. (From blueyed in issue #5.) + +## Changelog + +### 1.0 + +* Remove support to ack 1.x +* Start to use a Changelog +* Use `autoload` directory to define functions, instead of `plugin`. +* Add option to auto fold the results(`g:ack_autofold_results`) +* Improve documentation, list all options and shortcuts +* Improve highlight option to work when passes directories or use quotes. +* Add g:ack_mapping +* Add g:ack_default_options +* Add a help toggle `?`(like NERDTree) + +### 1.0.1 + +* Fixes #124. Bug with `g:ack_autofold_results` + +### 1.0.2 + +* Add compatibility with [vim-dispatch](https://github.com/tpope/vim-dispatch) + +### 1.0.3 + +* Fixes #127. Use `&l:hlsearch` instead of `v:hlsearch` to keep compatibility +with versions that does not have this variable. + +### 1.0.4 + +* Fixes #128. Always apply mappings, even when using vim-dispatch. + +### 1.0.5 + +* Fixes #128. Fixes the `errorformat` for ack when using vim-dispatch. +* Do not use vim-dispatch by default. To use vim-dispath must set +`g:ack_use_dispatch` + +### 1.0.6 + +* Fixes highlight function to work when user passes options. Ex.: Ack -i test + Thank's @mannih. (#131, #134) + +### 1.0.7 + +* Fixes highlight function to work when passes more than one option, or options +with double dashes(--option) Thank's to @MiguelLatorre and @mannih + +### 1.0.8 + +* Fixes (again) highlight, now using negative look behind. +* Change mappings `o` and `O` to behave as documented diff --git a/bundle/ack.vim/doc/ack.txt b/bundle/ack.vim/doc/ack.txt index ec06da3a..6b1be331 100644 --- a/bundle/ack.vim/doc/ack.txt +++ b/bundle/ack.vim/doc/ack.txt @@ -16,7 +16,7 @@ shows the results in a split window. Search recursively in {directory} (which defaults to the current directory) for the {pattern}. Behaves just like the |:grep| command, but will open the |Quickfix| window for you. If [!] is not given the first - error is jumped to. + occurence is jumped to. :AckAdd [options] {pattern} [{directory}] *:AckAdd* @@ -45,7 +45,7 @@ shows the results in a split window. :AckHelp[!] [options] {pattern} *:AckHelp* - Search vim documentation files for the {pattern}. Behaves just like the + Search vim documentation files for the {pattern}. Behaves just like the |:Ack| command, but searches only vim documentation .txt files :LAckHelp [options] {pattern} *:LAckHelp* @@ -53,6 +53,16 @@ shows the results in a split window. Just like |:AckHelp| but instead of the |quickfix| list, matches are placed in the current |location-list|. +:AckWindow[!] [options] {pattern} *:AckWindow* + + Search all buffers visible in the screen (current tab page only) files for + the {pattern}. + +:LAckWindow [options] {pattern} *:LAckWindow* + + Just like |:AckWindow| but instead of the |quickfix| list, matches are + placed in the current |location-list|. + Files containing the search term will be listed in the split window, along with the line number of the occurrence, once for each occurrence. on a line in this window will open the file, and place the cursor on the matching @@ -60,6 +70,151 @@ line. See http://betterthangrep.com/ for more information. + +============================================================================== +CONFIGURATION *ack-configuration* + + *g:ackprg* +g:ackprg +Default for ubuntu: "ack-grep" +Default for other systems: "ack" + +Use this option to specify the ack command and its options + +Example: +> + let g:ackprg = "other-bin-ack" +< + + *g:ack_default_options* +g:ack_default_options +Default: " -s -H --nocolor --nogroup --column" + +Use this option to specify the options used by ack + +Example: +> + let g:ack_default_options = + \ " -s -H --nocolor --nogroup --column --smart-case --follow" +< + + *g:ack_apply_qmappings* +g:ack_apply_qmappings +Default: 1 + +This option enable mappings on quickview window. + + *g:ack_apply_lmappings* +g:ack_apply_lmappings +Default: 1 + +This option enable mappings on Location list window. + + *g:ack_mappings* +g:ack_mappings +Default: { + \ "t": "T", + \ "T": "TgTj", + \ "o": "", + \ "O": ":ccl", + \ "go": "j", + \ "h": "K", + \ "H": "Kb", + \ "v": "HbJt", + \ "gv": "HbJ" } + +This option list all maps create on quickfix/Location list window. + +Example, if you want to open the result in the middle of the screen: +> + let g:ack_mappings = { "o": "zz" } +< + + *g:ack_qhandler* +g:ack_qhandler +Default: "botright copen" + +Command to open the quickview window. + +If you want to open a quickview window with 30 lines you can do: +> + let g:ack_qhandler = "botright copen 30" +< + + *g:ack_lhandler* +g:ack_lhandler +Default: "botright lopen" + +Command to open the Location list window. + +If you want to open a Location list window with 30 lines you can do: +> + let g:ack_lhandler = "botright lopen 30" +< + + *g:ackhighlight* + +g:ackhighlight +Default: 0 + +Use this option to highlight the searched term. + +Example: +> + let g:ackhighlight = 1 +< + + *g:ack_autoclose* +g:ack_autoclose +Default: 0 + +Use this option to specify whether to close the quickfix window after +using any of the shortcuts. + +Example: +> + let g:ack_autoclose = 1 +< + + *g:ack_autofold_results* + +g:ack_autofold_results +Default: 0 + +Use this option to fold the results in quickfix by file name. Only the current +fold will be open by default and while you press 'j' and 'k' to move between the +results if you hit other fold the last one will be closed and the current will +be open. + +Example: +> + let g:ack_autofold_results = 1 +< + + *g:ackpreview* + +g:ackpreview +Default: 0 + +Use this option to automagically open the file with 'j' or 'k'. + +Example: +> + let g:ackpreview = 1 +< + + *g:ack_use_dispatch* + +g:ack_use_dispatch +Default: 0 + +Use this option to use vim-dispatch to search the results in background + +Example: +> + let g:ack_use_dispatch = 1 +< + ============================================================================== MAPPINGS *ack-mappings* @@ -67,6 +222,8 @@ The following keyboard shortcuts are available in the quickfix window: o open file (same as enter). +O open file and close quickfix window. + go preview file (open but maintain focus on ack.vim results). t open in a new tab. diff --git a/bundle/ack.vim/plugin/ack.vim b/bundle/ack.vim/plugin/ack.vim index 3c664bd5..6d6c55bc 100644 --- a/bundle/ack.vim/plugin/ack.vim +++ b/bundle/ack.vim/plugin/ack.vim @@ -1,16 +1,17 @@ -" NOTE: You must, of course, install the ack script -" in your path. -" On Debian / Ubuntu: -" sudo apt-get install ack-grep -" With MacPorts: -" sudo port install p5-app-ack -" With Homebrew: -" brew install ack +if !exists("g:ack_default_options") + let g:ack_default_options = " -s -H --nocolor --nogroup --column" +endif " Location of the ack utility if !exists("g:ackprg") - let s:ackcommand = executable('ack-grep') ? 'ack-grep' : 'ack' - let g:ackprg=s:ackcommand." -H --nocolor --nogroup --column" + if executable('ack') + let g:ackprg = "ack" + elseif executable('ack-grep') + let g:ackprg = "ack-grep" + else + finish + endif + let g:ackprg .= g:ack_default_options endif if !exists("g:ack_apply_qmappings") @@ -21,102 +22,54 @@ if !exists("g:ack_apply_lmappings") let g:ack_apply_lmappings = !exists("g:ack_lhandler") endif +if !exists("g:ack_use_dispatch") + let g:ack_use_dispatch = 0 +end + +let s:ack_mappings = { + \ "t": "T", + \ "T": "TgTj", + \ "o": "", + \ "O": "pc", + \ "go": "p", + \ "h": "K", + \ "H": "Kb", + \ "v": "HbJt", + \ "gv": "HbJ" } + +if exists("g:ack_mappings") + let g:ack_mappings = extend(s:ack_mappings, g:ack_mappings) +else + let g:ack_mappings = s:ack_mappings +endif + if !exists("g:ack_qhandler") - let g:ack_qhandler="botright copen" + let g:ack_qhandler = "botright copen" endif if !exists("g:ack_lhandler") - let g:ack_lhandler="botright lopen" + let g:ack_lhandler = "botright lopen" endif -function! s:Ack(cmd, args) - redraw - echo "Searching ..." +if !exists("g:ackhighlight") + let g:ackhighlight = 0 +endif - " If no pattern is provided, search for the word under the cursor - if empty(a:args) - let l:grepargs = expand("") - else - let l:grepargs = a:args . join(a:000, ' ') - end +if !exists("g:ack_autoclose") + let g:ack_autoclose = 0 +endif - " Format, used to manage column jump - if a:cmd =~# '-g$' - let g:ackformat="%f" - else - let g:ackformat="%f:%l:%c:%m,%f:%l:%m" - end +if !exists("g:ack_autofold_results") + let g:ack_autofold_results = 0 +endif - let grepprg_bak=&grepprg - let grepformat_bak=&grepformat - try - let &grepprg=g:ackprg - let &grepformat=g:ackformat - silent execute a:cmd . " " . escape(l:grepargs, '|') - finally - let &grepprg=grepprg_bak - let &grepformat=grepformat_bak - endtry - - if a:cmd =~# '^l' - exe g:ack_lhandler - let l:apply_mappings = g:ack_apply_lmappings - let l:close_cmd = ':lclose' - else - exe g:ack_qhandler - let l:apply_mappings = g:ack_apply_qmappings - let l:close_cmd = ':cclose' - endif - - if l:apply_mappings - exec "nnoremap q " . l:close_cmd - exec "nnoremap t T" - exec "nnoremap T TgT" - exec "nnoremap o " - exec "nnoremap go " - exec "nnoremap h K" - exec "nnoremap H Kb" - exec "nnoremap v HbJt" - exec "nnoremap gv HbJ" - endif - - " If highlighting is on, highlight the search keyword. - if exists("g:ackhighlight") - let @/ = substitute(l:grepargs,'["'']','','g') - set hlsearch - end - - redraw! -endfunction - -function! s:AckFromSearch(cmd, args) - let search = getreg('/') - " translate vim regular expression to perl regular expression. - let search = substitute(search,'\(\\<\|\\>\)','\\b','g') - call s:Ack(a:cmd, '"' . search .'" '. a:args) -endfunction - -function! s:GetDocLocations() - let dp = '' - for p in split(&rtp,',') - let p = p.'/doc/' - if isdirectory(p) - let dp = p.'*.txt '.dp - endif - endfor - return dp -endfunction - -function! s:AckHelp(cmd,args) - let args = a:args.' '.s:GetDocLocations() - call s:Ack(a:cmd,args) -endfunction - -command! -bang -nargs=* -complete=file Ack call s:Ack('grep',) -command! -bang -nargs=* -complete=file AckAdd call s:Ack('grepadd', ) -command! -bang -nargs=* -complete=file AckFromSearch call s:AckFromSearch('grep', ) -command! -bang -nargs=* -complete=file LAck call s:Ack('lgrep', ) -command! -bang -nargs=* -complete=file LAckAdd call s:Ack('lgrepadd', ) -command! -bang -nargs=* -complete=file AckFile call s:Ack('grep -g', ) -command! -bang -nargs=* -complete=help AckHelp call s:AckHelp('grep',) -command! -bang -nargs=* -complete=help LAckHelp call s:AckHelp('lgrep',) +command! -bang -nargs=* -complete=file Ack call ack#Ack('grep', ) +command! -bang -nargs=* -complete=file AckAdd call ack#Ack('grepadd', ) +command! -bang -nargs=* -complete=file AckFromSearch call ack#AckFromSearch('grep', ) +command! -bang -nargs=* -complete=file LAck call ack#Ack('lgrep', ) +command! -bang -nargs=* -complete=file LAckAdd call ack#Ack('lgrepadd', ) +command! -bang -nargs=* -complete=file AckFile call ack#Ack('grep -g', ) +command! -bang -nargs=* -complete=help AckHelp call ack#AckHelp('grep', ) +command! -bang -nargs=* -complete=help LAckHelp call ack#AckHelp('lgrep', ) +command! -bang -nargs=* -complete=help AckWindow call ack#AckWindow('grep', ) +command! -bang -nargs=* -complete=help LAckWindow call ack#AckWindow('lgrep', ) diff --git a/bundle/goyo.vim/plugin/goyo.vim b/bundle/goyo.vim/plugin/goyo.vim index 751162ce..c64d4aae 100644 --- a/bundle/goyo.vim/plugin/goyo.vim +++ b/bundle/goyo.vim/plugin/goyo.vim @@ -46,7 +46,7 @@ function! s:init_pad(command) execute a:command setlocal buftype=nofile bufhidden=wipe nomodifiable nobuflisted noswapfile - \ nonu nocursorline winfixwidth winfixheight statusline=\ + \ nonu nocursorline nocursorcolumn winfixwidth winfixheight statusline=\ if exists('&rnu') setlocal nornu endif @@ -64,7 +64,8 @@ function! s:setup_pad(bufnr, vert, size) execute win . 'wincmd w' execute (a:vert ? 'vertical ' : '') . 'resize ' . max([0, a:size]) augroup goyop - autocmd WinEnter call s:blank() + autocmd WinEnter,CursorMoved nested call s:blank() + autocmd WinLeave call s:hide_statusline() augroup END " To hide scrollbars of pad windows in GVim @@ -104,17 +105,23 @@ function! s:tranquilize() \ 'StatusLine', 'StatusLineNC', 'SignColumn'] " -1 on Vim / '' on GVim if bg == -1 || empty(bg) - call s:set_color(grp, '', 'NONE') call s:set_color(grp, 'fg', get(g:, 'goyo_bg', 'black')) call s:set_color(grp, 'bg', 'NONE') else call s:set_color(grp, 'fg', bg) call s:set_color(grp, 'bg', bg) endif + call s:set_color(grp, '', 'NONE') endfor endfunction +function! s:hide_statusline() + let &l:statusline = repeat(' ', winwidth(0)) +endfunction + function! s:goyo_on(width) + let s:orig_tab = tabpagenr() + " New tab tab split @@ -125,10 +132,10 @@ function! s:goyo_on(width) \ { 'laststatus': &laststatus, \ 'showtabline': &showtabline, \ 'fillchars': &fillchars, + \ 'winminwidth': &winminwidth, \ 'winwidth': &winwidth, \ 'winminheight': &winminheight, \ 'winheight': &winheight, - \ 'statusline': &statusline, \ 'ruler': &ruler, \ 'sidescroll': &sidescroll, \ 'sidescrolloff': &sidescrolloff @@ -143,6 +150,12 @@ function! s:goyo_on(width) silent! GitGutterDisable endif + " vim-signify + let t:goyo_disabled_signify = exists('b:sy') && b:sy.active + if t:goyo_disabled_signify + SignifyToggle + endif + " vim-airline let t:goyo_disabled_airline = exists("#airline") if t:goyo_disabled_airline @@ -175,10 +188,10 @@ function! s:goyo_on(width) endif " Global options - set winwidth=1 let &winheight = max([&winminheight, 1]) set winminheight=1 set winheight=1 + set winminwidth=1 winwidth=1 set laststatus=0 set showtabline=0 set noruler @@ -202,19 +215,20 @@ function! s:goyo_on(width) call s:resize_pads() call s:tranquilize() - let &statusline = repeat(' ', winwidth(0)) - augroup goyo autocmd! autocmd BufWinLeave call s:goyo_off() autocmd TabLeave * call s:goyo_off() autocmd VimResized * call s:resize_pads() autocmd ColorScheme * call s:tranquilize() + autocmd WinEnter,WinLeave call s:hide_statusline() augroup END + call s:hide_statusline() if exists('g:goyo_callbacks[0]') call g:goyo_callbacks[0]() endif + silent! doautocmd User GoyoEnter endfunction function! s:goyo_off() @@ -239,9 +253,12 @@ function! s:goyo_off() let goyo_revert = t:goyo_revert let goyo_disabled_gitgutter = t:goyo_disabled_gitgutter + let goyo_disabled_signify = t:goyo_disabled_signify let goyo_disabled_airline = t:goyo_disabled_airline let goyo_disabled_powerline = t:goyo_disabled_powerline let goyo_disabled_lightline = t:goyo_disabled_lightline + let goyo_orig_buffer = t:goyo_master + let [line, col] = [line('.'), col('.')] if tabpagenr() == 1 tabnew @@ -249,7 +266,15 @@ function! s:goyo_off() bd endif tabclose + execute 'normal! '.s:orig_tab.'gt' + if winbufnr(0) == goyo_orig_buffer + execute printf('normal! %dG%d|', line, col) + endif + let wmw = remove(goyo_revert, 'winminwidth') + let ww = remove(goyo_revert, 'winwidth') + let &winwidth = ww + let &winminwidth = wmw let wmh = remove(goyo_revert, 'winminheight') let wh = remove(goyo_revert, 'winheight') let &winheight = max([wmh, 1]) @@ -265,6 +290,12 @@ function! s:goyo_off() silent! GitGutterEnable endif + if goyo_disabled_signify + silent! if !b:sy.active + SignifyToggle + endif + endif + if goyo_disabled_airline && !exists("#airline") AirlineToggle silent! AirlineRefresh @@ -286,22 +317,29 @@ function! s:goyo_off() if exists('g:goyo_callbacks[1]') call g:goyo_callbacks[1]() endif + silent! doautocmd User GoyoLeave endfunction -function! s:goyo(...) +function! s:goyo(bang, ...) let width = a:0 > 0 ? a:1 : get(g:, 'goyo_width', 80) - if exists('#goyo') == 0 - call s:goyo_on(width) - elseif a:0 > 0 - let t:goyo_width = width - call s:resize_pads() + if a:bang + if exists('#goyo') + call s:goyo_off() + endif else - call s:goyo_off() + if exists('#goyo') == 0 + call s:goyo_on(width) + elseif a:0 > 0 + let t:goyo_width = width + call s:resize_pads() + else + call s:goyo_off() + end end endfunction -command! -nargs=? Goyo call s:goyo() +command! -nargs=? -bar -bang Goyo call s:goyo('' == '!', ) let &cpo = s:cpo_save unlet s:cpo_save diff --git a/bundle/nerdtree/README.markdown b/bundle/nerdtree/README.markdown index e6178091..9dacf682 100644 --- a/bundle/nerdtree/README.markdown +++ b/bundle/nerdtree/README.markdown @@ -60,7 +60,7 @@ Installation cd ~/.vim/bundle git clone https://github.com/scrooloose/nerdtree.git -Then reload vim, run `:helptags`, and check out `:help NERD_tree.txt`. +Then reload vim, run `:Helptags`, and check out `:help NERD_tree.txt`. Faq @@ -80,7 +80,10 @@ A. Stick this in your vimrc: `autocmd vimenter * NERDTree` __Q. How can I open a NERDTree automatically when vim starts up if no files were specified?__ -A. Stick this in your vimrc `autocmd vimenter * if !argc() | NERDTree | endif` +A. Stick this in your vimrc + + autocmd StdinReadPre * let s:std_in=1 + autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif __Q. How can I map a specific key or shortcut to open NERDTree?__ diff --git a/bundle/nerdtree/autoload/nerdtree.vim b/bundle/nerdtree/autoload/nerdtree.vim index 3a2d71a6..539e7838 100644 --- a/bundle/nerdtree/autoload/nerdtree.vim +++ b/bundle/nerdtree/autoload/nerdtree.vim @@ -9,29 +9,6 @@ endfunction " SECTION: General Functions {{{1 "============================================================ -"FUNCTION: nerdtree#bufInWindows(bnum){{{2 -"[[STOLEN FROM VTREEEXPLORER.VIM]] -"Determine the number of windows open to this buffer number. -"Care of Yegappan Lakshman. Thanks! -" -"Args: -"bnum: the subject buffers buffer number -function! nerdtree#bufInWindows(bnum) - let cnt = 0 - let winnum = 1 - while 1 - let bufnum = winbufnr(winnum) - if bufnum < 0 - break - endif - if bufnum ==# a:bnum - let cnt = cnt + 1 - endif - let winnum = winnum + 1 - endwhile - - return cnt -endfunction "FUNCTION: nerdtree#checkForBrowse(dir) {{{2 "inits a secondary nerd tree in the current buffer if appropriate @@ -57,81 +34,6 @@ function! nerdtree#compareNodes(n1, n2) return a:n1.path.compareTo(a:n2.path) endfunction -" FUNCTION: nerdtree#createDefaultBindings() {{{2 -function! nerdtree#createDefaultBindings() - let s = '' . s:SID() . '_' - - call NERDTreeAddKeyMap({ 'key': '', 'scope': "all", 'callback': s."handleMiddleMouse" }) - call NERDTreeAddKeyMap({ 'key': '', 'scope': "all", 'callback': s."handleLeftClick" }) - call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "DirNode", 'callback': s."activateDirNode" }) - call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "FileNode", 'callback': s."activateFileNode" }) - call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "Bookmark", 'callback': s."activateBookmark" }) - call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "all", 'callback': s."activateAll" }) - - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "DirNode", 'callback': s."activateDirNode" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "FileNode", 'callback': s."activateFileNode" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "Bookmark", 'callback': s."activateBookmark" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "all", 'callback': s."activateAll" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': "Node", 'callback': s."openHSplit" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': "Node", 'callback': s."openVSplit" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': "Bookmark", 'callback': s."openHSplit" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': "Bookmark", 'callback': s."openVSplit" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': "Node", 'callback': s."previewNodeCurrent" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': "Node", 'callback': s."previewNodeVSplit" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': "Node", 'callback': s."previewNodeHSplit" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': "Bookmark", 'callback': s."previewNodeCurrent" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': "Bookmark", 'callback': s."previewNodeVSplit" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': "Bookmark", 'callback': s."previewNodeHSplit" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenRecursively, 'scope': "DirNode", 'callback': s."openNodeRecursively" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdir, 'scope': "all", 'callback': s."upDirCurrentRootClosed" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdirKeepOpen, 'scope': "all", 'callback': s."upDirCurrentRootOpen" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChangeRoot, 'scope': "Node", 'callback': s."chRoot" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChdir, 'scope': "Node", 'callback': s."chCwd" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapQuit, 'scope': "all", 'callback': s."closeTreeWindow" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCWD, 'scope': "all", 'callback': "nerdtree#chRootCwd" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefreshRoot, 'scope': "all", 'callback': s."refreshRoot" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefresh, 'scope': "Node", 'callback': s."refreshCurrent" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapHelp, 'scope': "all", 'callback': s."displayHelp" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleZoom, 'scope': "all", 'callback': s."toggleZoom" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleHidden, 'scope': "all", 'callback': s."toggleShowHidden" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFilters, 'scope': "all", 'callback': s."toggleIgnoreFilter" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFiles, 'scope': "all", 'callback': s."toggleShowFiles" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleBookmarks, 'scope': "all", 'callback': s."toggleShowBookmarks" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseDir, 'scope': "Node", 'callback': s."closeCurrentDir" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseChildren, 'scope': "DirNode", 'callback': s."closeChildren" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapMenu, 'scope': "Node", 'callback': s."showMenu" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpParent, 'scope': "Node", 'callback': s."jumpToParent" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpFirstChild, 'scope': "Node", 'callback': s."jumpToFirstChild" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpLastChild, 'scope': "Node", 'callback': s."jumpToLastChild" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpRoot, 'scope': "all", 'callback': s."jumpToRoot" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpNextSibling, 'scope': "Node", 'callback': s."jumpToNextSibling" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpPrevSibling, 'scope': "Node", 'callback': s."jumpToPrevSibling" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': "Node", 'callback': s."openInNewTab" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': "Node", 'callback': s."openInNewTabSilent" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': "Bookmark", 'callback': s."openInNewTab" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': "Bookmark", 'callback': s."openInNewTabSilent" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenExpl, 'scope': "DirNode", 'callback': s."openExplorer" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapDeleteBookmark, 'scope': "Bookmark", 'callback': s."deleteBookmark" }) -endfunction - " FUNCTION: nerdtree#deprecated(func, [msg]) {{{2 " Issue a deprecation warning for a:func. If a second arg is given, use this " as the deprecation message @@ -147,15 +49,6 @@ function! nerdtree#deprecated(func, ...) endif endfunction -"FUNCTION: nerdtree#escChars(dir) {{{2 -function! nerdtree#escChars() - if nerdtree#runningWindows() - return " `\|\"#%&,?()\*^<>" - endif - - return " \\`\|\"#%&,?()\*^<>[]" -endfunction - " FUNCTION: nerdtree#exec(cmd) {{{2 " same as :exec cmd but eventignore=all is set for the duration function! nerdtree#exec(cmd) @@ -165,68 +58,11 @@ function! nerdtree#exec(cmd) let &ei = old_ei endfunction -" FUNCTION: nerdtree#findAndRevealPath() {{{2 -function! nerdtree#findAndRevealPath() - try - let p = g:NERDTreePath.New(expand("%:p")) - catch /^NERDTree.InvalidArgumentsError/ - call nerdtree#echo("no file for the current buffer") - return - endtry - - if p.isUnixHiddenPath() - let showhidden=g:NERDTreeShowHidden - let g:NERDTreeShowHidden = 1 - endif - - if !nerdtree#treeExistsForTab() - try - let cwd = g:NERDTreePath.New(getcwd()) - catch /^NERDTree.InvalidArgumentsError/ - call nerdtree#echo("current directory does not exist.") - let cwd = p.getParent() - endtry - - if p.isUnder(cwd) - call g:NERDTreeCreator.CreatePrimary(cwd.str()) - else - call g:NERDTreeCreator.CreatePrimary(p.getParent().str()) - endif - else - if !p.isUnder(g:NERDTreeFileNode.GetRootForTab().path) - if !nerdtree#isTreeOpen() - call g:NERDTreeCreator.TogglePrimary('') - else - call nerdtree#putCursorInTreeWin() - endif - let b:NERDTreeShowHidden = g:NERDTreeShowHidden - call nerdtree#chRoot(g:NERDTreeDirNode.New(p.getParent())) - else - if !nerdtree#isTreeOpen() - call g:NERDTreeCreator.TogglePrimary("") - endif - endif - endif - call nerdtree#putCursorInTreeWin() - call b:NERDTreeRoot.reveal(p) - - if p.isUnixHiddenFile() - let g:NERDTreeShowHidden = showhidden - endif -endfunction - " FUNCTION: nerdtree#has_opt(options, name) {{{2 function! nerdtree#has_opt(options, name) return has_key(a:options, a:name) && a:options[a:name] == 1 endfunction -" FUNCTION: nerdtree#invokeKeyMap(key) {{{2 -"this is needed since I cant figure out how to invoke dict functions from a -"key map -function! nerdtree#invokeKeyMap(key) - call g:NERDTreeKeyMap.Invoke(a:key) -endfunction - " FUNCTION: nerdtree#loadClassFiles() {{{2 function! nerdtree#loadClassFiles() runtime lib/nerdtree/path.vim @@ -238,12 +74,17 @@ function! nerdtree#loadClassFiles() runtime lib/nerdtree/tree_dir_node.vim runtime lib/nerdtree/opener.vim runtime lib/nerdtree/creator.vim + runtime lib/nerdtree/flag_set.vim + runtime lib/nerdtree/nerdtree.vim + runtime lib/nerdtree/ui.vim + runtime lib/nerdtree/event.vim + runtime lib/nerdtree/notifier.vim endfunction " FUNCTION: nerdtree#postSourceActions() {{{2 function! nerdtree#postSourceActions() call g:NERDTreeBookmark.CacheBookmarks(0) - call nerdtree#createDefaultBindings() + call nerdtree#ui_glue#createDefaultBindings() "load all nerdtree plugins runtime! nerdtree_plugin/**/*.vim @@ -254,44 +95,6 @@ function! nerdtree#runningWindows() return has("win16") || has("win32") || has("win64") endfunction -" Function: s:SID() {{{2 -function s:SID() - if !exists("s:sid") - let s:sid = matchstr(expand(''), '\zs\d\+\ze_SID$') - endif - return s:sid -endfun - -" FUNCTION: nerdtree#tabpagevar(tabnr, var) {{{2 -function! nerdtree#tabpagevar(tabnr, var) - let currentTab = tabpagenr() - let old_ei = &ei - set ei=all - - exec "tabnext " . a:tabnr - let v = -1 - if exists('t:' . a:var) - exec 'let v = t:' . a:var - endif - exec "tabnext " . currentTab - - let &ei = old_ei - - return v -endfunction - -" Function: nerdtree#treeExistsForBuffer() {{{2 -" Returns 1 if a nerd tree root exists in the current buffer -function! nerdtree#treeExistsForBuf() - return exists("b:NERDTreeRoot") -endfunction - -" Function: nerdtree#treeExistsForTab() {{{2 -" Returns 1 if a nerd tree root exists in the current tab -function! nerdtree#treeExistsForTab() - return exists("t:NERDTreeBufName") -endfunction - "FUNCTION: nerdtree#treeMarkupReg(dir) {{{2 function! nerdtree#treeMarkupReg() if g:NERDTreeDirArrows @@ -311,76 +114,9 @@ function! nerdtree#treeWid() return 2 endfunction -"FUNCTION: nerdtree#upDir(keepState) {{{2 -"moves the tree up a level -" -"Args: -"keepState: 1 if the current root should be left open when the tree is -"re-rendered -function! nerdtree#upDir(keepState) - let cwd = b:NERDTreeRoot.path.str({'format': 'UI'}) - if cwd ==# "/" || cwd =~# '^[^/]..$' - call nerdtree#echo("already at top dir") - else - if !a:keepState - call b:NERDTreeRoot.close() - endif - - let oldRoot = b:NERDTreeRoot - - if empty(b:NERDTreeRoot.parent) - let path = b:NERDTreeRoot.path.getParent() - let newRoot = g:NERDTreeDirNode.New(path) - call newRoot.open() - call newRoot.transplantChild(b:NERDTreeRoot) - let b:NERDTreeRoot = newRoot - else - let b:NERDTreeRoot = b:NERDTreeRoot.parent - endif - - if g:NERDTreeChDirMode ==# 2 - call b:NERDTreeRoot.path.changeToDir() - endif - - call nerdtree#renderView() - call oldRoot.putCursorHere(0, 0) - endif -endfunction - -" Function: nerdtree#unique(list) {{{2 -" returns a:list without duplicates -function! nerdtree#unique(list) - let uniqlist = [] - for elem in a:list - if index(uniqlist, elem) ==# -1 - let uniqlist += [elem] - endif - endfor - return uniqlist -endfunction - " SECTION: View Functions {{{1 "============================================================ -" -"FUNCTION: nerdtree#centerView() {{{2 -"centers the nerd tree window around the cursor (provided the nerd tree -"options permit) -function! nerdtree#centerView() - if g:NERDTreeAutoCenter - let current_line = winline() - let lines_to_top = current_line - let lines_to_bottom = winheight(nerdtree#getTreeWinNum()) - current_line - if lines_to_top < g:NERDTreeAutoCenterThreshold || lines_to_bottom < g:NERDTreeAutoCenterThreshold - normal! zz - endif - endif -endfunction -" FUNCTION: nerdtree#chRoot(node) {{{2 -" changes the current root to the selected one -function! nerdtree#chRoot(node) - call s:chRoot(a:node) -endfunction "FUNCTION: nerdtree#closeTree() {{{2 "Closes the primary NERD tree window for this tab function! nerdtree#closeTree() @@ -513,7 +249,7 @@ function! nerdtree#dumpHelp() let @h=@h."\" ". g:NERDTreeMapHelp .": toggle help\n" let @h=@h."\"\n\" ----------------------------\n" let @h=@h."\" Bookmark commands~\n" - let @h=@h."\" :Bookmark \n" + let @h=@h."\" :Bookmark []\n" let @h=@h."\" :BookmarkToRoot \n" let @h=@h."\" :RevealBookmark \n" let @h=@h."\" :OpenBookmark \n" @@ -558,92 +294,6 @@ function! nerdtree#echoWarning(msg) echohl normal endfunction -"FUNCTION: nerdtree#firstUsableWindow(){{{2 -"find the window number of the first normal window -function! nerdtree#firstUsableWindow() - let i = 1 - while i <= winnr("$") - let bnum = winbufnr(i) - if bnum != -1 && getbufvar(bnum, '&buftype') ==# '' - \ && !getwinvar(i, '&previewwindow') - \ && (!getbufvar(bnum, '&modified') || &hidden) - return i - endif - - let i += 1 - endwhile - return -1 -endfunction - -"FUNCTION: nerdtree#getPath(ln) {{{2 -"Gets the full path to the node that is rendered on the given line number -" -"Args: -"ln: the line number to get the path for -" -"Return: -"A path if a node was selected, {} if nothing is selected. -"If the 'up a dir' line was selected then the path to the parent of the -"current root is returned -function! nerdtree#getPath(ln) - let line = getline(a:ln) - - let rootLine = g:NERDTreeFileNode.GetRootLineNum() - - "check to see if we have the root node - if a:ln == rootLine - return b:NERDTreeRoot.path - endif - - if !g:NERDTreeDirArrows - " in case called from outside the tree - if line !~# '^ *[|`▸▾ ]' || line =~# '^$' - return {} - endif - endif - - if line ==# nerdtree#treeUpDirLine() - return b:NERDTreeRoot.path.getParent() - endif - - let indent = nerdtree#indentLevelFor(line) - - "remove the tree parts and the leading space - let curFile = nerdtree#stripMarkupFromLine(line, 0) - - let wasdir = 0 - if curFile =~# '/$' - let wasdir = 1 - let curFile = substitute(curFile, '/\?$', '/', "") - endif - - let dir = "" - let lnum = a:ln - while lnum > 0 - let lnum = lnum - 1 - let curLine = getline(lnum) - let curLineStripped = nerdtree#stripMarkupFromLine(curLine, 1) - - "have we reached the top of the tree? - if lnum == rootLine - let dir = b:NERDTreeRoot.path.str({'format': 'UI'}) . dir - break - endif - if curLineStripped =~# '/$' - let lpindent = nerdtree#indentLevelFor(curLine) - if lpindent < indent - let indent = indent - 1 - - let dir = substitute (curLineStripped,'^\\', "", "") . dir - continue - endif - endif - endwhile - let curFile = b:NERDTreeRoot.path.drive . dir . curFile - let toReturn = g:NERDTreePath.New(curFile) - return toReturn -endfunction - "FUNCTION: nerdtree#getTreeWinNum() {{{2 "gets the nerd tree window number for this tab function! nerdtree#getTreeWinNum() @@ -654,111 +304,11 @@ function! nerdtree#getTreeWinNum() endif endfunction -"FUNCTION: nerdtree#indentLevelFor(line) {{{2 -function! nerdtree#indentLevelFor(line) - let level = match(a:line, '[^ \-+~▸▾`|]') / nerdtree#treeWid() - " check if line includes arrows - if match(a:line, '[▸▾]') > -1 - " decrement level as arrow uses 3 ascii chars - let level = level - 1 - endif - return level -endfunction - "FUNCTION: nerdtree#isTreeOpen() {{{2 function! nerdtree#isTreeOpen() return nerdtree#getTreeWinNum() != -1 endfunction -"FUNCTION: nerdtree#isWindowUsable(winnumber) {{{2 -"Returns 0 if opening a file from the tree in the given window requires it to -"be split, 1 otherwise -" -"Args: -"winnumber: the number of the window in question -function! nerdtree#isWindowUsable(winnumber) - "gotta split if theres only one window (i.e. the NERD tree) - if winnr("$") ==# 1 - return 0 - endif - - let oldwinnr = winnr() - call nerdtree#exec(a:winnumber . "wincmd p") - let specialWindow = getbufvar("%", '&buftype') != '' || getwinvar('%', '&previewwindow') - let modified = &modified - call nerdtree#exec(oldwinnr . "wincmd p") - - "if its a special window e.g. quickfix or another explorer plugin then we - "have to split - if specialWindow - return 0 - endif - - if &hidden - return 1 - endif - - return !modified || nerdtree#bufInWindows(winbufnr(a:winnumber)) >= 2 -endfunction - -" FUNCTION: nerdtree#jumpToChild(direction) {{{2 -" Args: -" direction: 0 if going to first child, 1 if going to last -function! nerdtree#jumpToChild(currentNode, direction) - if a:currentNode.isRoot() - return nerdtree#echo("cannot jump to " . (a:direction ? "last" : "first") . " child") - end - let dirNode = a:currentNode.parent - let childNodes = dirNode.getVisibleChildren() - - let targetNode = childNodes[0] - if a:direction - let targetNode = childNodes[len(childNodes) - 1] - endif - - if targetNode.equals(a:currentNode) - let siblingDir = a:currentNode.parent.findOpenDirSiblingWithVisibleChildren(a:direction) - if siblingDir != {} - let indx = a:direction ? siblingDir.getVisibleChildCount()-1 : 0 - let targetNode = siblingDir.getChildByIndex(indx, 1) - endif - endif - - call targetNode.putCursorHere(1, 0) - - call nerdtree#centerView() -endfunction - -" FUNCTION: nerdtree#jumpToSibling(currentNode, forward) {{{2 -" moves the cursor to the sibling of the current node in the given direction -" -" Args: -" forward: 1 if the cursor should move to the next sibling, 0 if it should -" move back to the previous sibling -function! nerdtree#jumpToSibling(currentNode, forward) - let sibling = a:currentNode.findSibling(a:forward) - - if !empty(sibling) - call sibling.putCursorHere(1, 0) - call nerdtree#centerView() - endif -endfunction - -"FUNCTION: nerdtree#promptToDelBuffer(bufnum, msg){{{2 -"prints out the given msg and, if the user responds by pushing 'y' then the -"buffer with the given bufnum is deleted -" -"Args: -"bufnum: the buffer that may be deleted -"msg: a message that will be echoed to the user asking them if they wish to -" del the buffer -function! nerdtree#promptToDelBuffer(bufnum, msg) - echo a:msg - if nr2char(getchar()) ==# 'y' - exec "silent bdelete! " . a:bufnum - endif -endfunction - "FUNCTION: nerdtree#putCursorOnBookmarkTable(){{{2 "Places the cursor at the top of the bookmarks table function! nerdtree#putCursorOnBookmarkTable() @@ -770,7 +320,7 @@ function! nerdtree#putCursorOnBookmarkTable() return cursor(1, 2) endif - let rootNodeLine = g:NERDTreeFileNode.GetRootLineNum() + let rootNodeLine = b:NERDTree.ui.getRootLineNum() let line = 1 while getline(line) !~# '^>-\+Bookmarks-\+$' @@ -810,116 +360,10 @@ function! nerdtree#renderBookmarks() endfunction "FUNCTION: nerdtree#renderView {{{2 -"The entry function for rendering the tree function! nerdtree#renderView() - setlocal modifiable - - "remember the top line of the buffer and the current line so we can - "restore the view exactly how it was - let curLine = line(".") - let curCol = col(".") - let topLine = line("w0") - - "delete all lines in the buffer (being careful not to clobber a register) - silent 1,$delete _ - - call nerdtree#dumpHelp() - - "delete the blank line before the help and add one after it - if g:NERDTreeMinimalUI == 0 - call setline(line(".")+1, "") - call cursor(line(".")+1, col(".")) - endif - - if b:NERDTreeShowBookmarks - call nerdtree#renderBookmarks() - endif - - "add the 'up a dir' line - if !g:NERDTreeMinimalUI - call setline(line(".")+1, nerdtree#treeUpDirLine()) - call cursor(line(".")+1, col(".")) - endif - - "draw the header line - let header = b:NERDTreeRoot.path.str({'format': 'UI', 'truncateTo': winwidth(0)}) - call setline(line(".")+1, header) - call cursor(line(".")+1, col(".")) - - "draw the tree - let old_o = @o - let @o = b:NERDTreeRoot.renderToString() - silent put o - let @o = old_o - - "delete the blank line at the top of the buffer - silent 1,1delete _ - - "restore the view - let old_scrolloff=&scrolloff - let &scrolloff=0 - call cursor(topLine, 1) - normal! zt - call cursor(curLine, curCol) - let &scrolloff = old_scrolloff - - setlocal nomodifiable -endfunction - -"FUNCTION: nerdtree#renderViewSavingPosition {{{2 -"Renders the tree and ensures the cursor stays on the current node or the -"current nodes parent if it is no longer available upon re-rendering -function! nerdtree#renderViewSavingPosition() - let currentNode = g:NERDTreeFileNode.GetSelected() - - "go up the tree till we find a node that will be visible or till we run - "out of nodes - while currentNode != {} && !currentNode.isVisible() && !currentNode.isRoot() - let currentNode = currentNode.parent - endwhile - - call nerdtree#renderView() - - if currentNode != {} - call currentNode.putCursorHere(0, 0) - endif + call b:NERDTree.render() endfunction " -"FUNCTION: nerdtree#restoreScreenState() {{{2 -" -"Sets the screen state back to what it was when nerdtree#saveScreenState was last -"called. -" -"Assumes the cursor is in the NERDTree window -function! nerdtree#restoreScreenState() - if !exists("b:NERDTreeOldTopLine") || !exists("b:NERDTreeOldPos") || !exists("b:NERDTreeOldWindowSize") - return - endif - exec("silent vertical resize ".b:NERDTreeOldWindowSize) - - let old_scrolloff=&scrolloff - let &scrolloff=0 - call cursor(b:NERDTreeOldTopLine, 0) - normal! zt - call setpos(".", b:NERDTreeOldPos) - let &scrolloff=old_scrolloff -endfunction - -"FUNCTION: nerdtree#saveScreenState() {{{2 -"Saves the current cursor position in the current buffer and the window -"scroll position -function! nerdtree#saveScreenState() - let win = winnr() - try - call nerdtree#putCursorInTreeWin() - let b:NERDTreeOldPos = getpos(".") - let b:NERDTreeOldTopLine = line("w0") - let b:NERDTreeOldWindowSize = winwidth("") - call nerdtree#exec(win . "wincmd w") - catch /^NERDTree.InvalidOperationError/ - endtry -endfunction - "FUNCTION: nerdtree#stripMarkupFromLine(line, removeLeadingSpaces){{{2 "returns the given line with all the tree parts stripped off " @@ -941,6 +385,9 @@ function! nerdtree#stripMarkupFromLine(line, removeLeadingSpaces) "strip off any executable flags let line = substitute (line, '*\ze\($\| \)', "","") + "strip off any generic flags + let line = substitute (line, '\[[^]]*\]', "","") + let wasdir = 0 if line =~# '/$' let wasdir = 1 @@ -957,424 +404,4 @@ function! nerdtree#stripMarkupFromLine(line, removeLeadingSpaces) return line endfunction -"SECTION: Interface bindings {{{1 -"============================================================ - -"FUNCTION: s:activateAll() {{{2 -"handle the user activating the updir line -function! s:activateAll() - if getline(".") ==# nerdtree#treeUpDirLine() - return nerdtree#upDir(0) - endif -endfunction -"FUNCTION: s:activateDirNode() {{{2 -"handle the user activating a tree node -function! s:activateDirNode(node) - call a:node.activate({'reuse': 1}) -endfunction - -"FUNCTION: s:activateFileNode() {{{2 -"handle the user activating a tree node -function! s:activateFileNode(node) - call a:node.activate({'reuse': 1, 'where': 'p'}) -endfunction - -"FUNCTION: s:activateBookmark() {{{2 -"handle the user activating a bookmark -function! s:activateBookmark(bm) - call a:bm.activate(!a:bm.path.isDirectory ? {'where': 'p'} : {}) -endfunction - -" FUNCTION: nerdtree#bookmarkNode(name) {{{2 -" Associate the current node with the given name -function! nerdtree#bookmarkNode(...) - let currentNode = g:NERDTreeFileNode.GetSelected() - if currentNode != {} - let name = a:1 - if empty(name) - let name = currentNode.path.getLastPathComponent(0) - endif - try - call currentNode.bookmark(name) - call nerdtree#renderView() - catch /^NERDTree.IllegalBookmarkNameError/ - call nerdtree#echo("bookmark names must not contain spaces") - endtry - else - call nerdtree#echo("select a node first") - endif -endfunction - -" FUNCTION: s:chCwd(node) {{{2 -function! s:chCwd(node) - try - call a:node.path.changeToDir() - catch /^NERDTree.PathChangeError/ - call nerdtree#echoWarning("could not change cwd") - endtry -endfunction - -" FUNCTION: s:chRoot(node) {{{2 -" changes the current root to the selected one -function! s:chRoot(node) - call a:node.makeRoot() - call nerdtree#renderView() - call b:NERDTreeRoot.putCursorHere(0, 0) -endfunction - -" FUNCTION: s:chRootCwd() {{{2 -" changes the current root to CWD -function! nerdtree#chRootCwd() - try - let cwd = g:NERDTreePath.New(getcwd()) - catch /^NERDTree.InvalidArgumentsError/ - call nerdtree#echo("current directory does not exist.") - return - endtry - if cwd.str() == g:NERDTreeFileNode.GetRootForTab().path.str() - return - endif - call nerdtree#chRoot(g:NERDTreeDirNode.New(cwd)) -endfunction - -" FUNCTION: nerdtree#clearBookmarks(bookmarks) {{{2 -function! nerdtree#clearBookmarks(bookmarks) - if a:bookmarks ==# '' - let currentNode = g:NERDTreeFileNode.GetSelected() - if currentNode != {} - call currentNode.clearBookmarks() - endif - else - for name in split(a:bookmarks, ' ') - let bookmark = g:NERDTreeBookmark.BookmarkFor(name) - call bookmark.delete() - endfor - endif - call nerdtree#renderView() -endfunction - -" FUNCTION: s:closeChildren(node) {{{2 -" closes all childnodes of the current node -function! s:closeChildren(node) - call a:node.closeChildren() - call nerdtree#renderView() - call a:node.putCursorHere(0, 0) -endfunction - -" FUNCTION: s:closeCurrentDir(node) {{{2 -" closes the parent dir of the current node -function! s:closeCurrentDir(node) - let parent = a:node.parent - if parent ==# {} || parent.isRoot() - call nerdtree#echo("cannot close tree root") - else - call a:node.parent.close() - call nerdtree#renderView() - call a:node.parent.putCursorHere(0, 0) - endif -endfunction - -" FUNCTION: s:closeTreeWindow() {{{2 -" close the tree window -function! s:closeTreeWindow() - if b:NERDTreeType ==# "secondary" && b:NERDTreePreviousBuf != -1 - exec "buffer " . b:NERDTreePreviousBuf - else - if winnr("$") > 1 - call nerdtree#closeTree() - else - call nerdtree#echo("Cannot close last window") - endif - endif -endfunction - -" FUNCTION: s:deleteBookmark(bm) {{{2 -" if the cursor is on a bookmark, prompt to delete -function! s:deleteBookmark(bm) - echo "Are you sure you wish to delete the bookmark:\n\"" . a:bm.name . "\" (yN):" - - if nr2char(getchar()) ==# 'y' - try - call a:bm.delete() - call nerdtree#renderView() - redraw - catch /^NERDTree/ - call nerdtree#echoWarning("Could not remove bookmark") - endtry - else - call nerdtree#echo("delete aborted" ) - endif - -endfunction - -" FUNCTION: s:displayHelp() {{{2 -" toggles the help display -function! s:displayHelp() - let b:treeShowHelp = b:treeShowHelp ? 0 : 1 - call nerdtree#renderView() - call nerdtree#centerView() -endfunction - -"FUNCTION: s:handleLeftClick() {{{2 -"Checks if the click should open the current node -function! s:handleLeftClick() - let currentNode = g:NERDTreeFileNode.GetSelected() - if currentNode != {} - - "the dir arrows are multibyte chars, and vim's string functions only - "deal with single bytes - so split the line up with the hack below and - "take the line substring manually - let line = split(getline(line(".")), '\zs') - let startToCur = "" - for i in range(0,len(line)-1) - let startToCur .= line[i] - endfor - - if currentNode.path.isDirectory - if startToCur =~# nerdtree#treeMarkupReg() && startToCur =~# '[+~▾▸] \?$' - call currentNode.activate() - return - endif - endif - - if (g:NERDTreeMouseMode ==# 2 && currentNode.path.isDirectory) || g:NERDTreeMouseMode ==# 3 - let char = strpart(startToCur, strlen(startToCur)-1, 1) - if char !~# nerdtree#treeMarkupReg() - if currentNode.path.isDirectory - call currentNode.activate() - else - call currentNode.activate({'reuse': 1, 'where': 'p'}) - endif - return - endif - endif - endif -endfunction - -" FUNCTION: s:handleMiddleMouse() {{{2 -function! s:handleMiddleMouse() - let curNode = g:NERDTreeFileNode.GetSelected() - if curNode ==# {} - call nerdtree#echo("Put the cursor on a node first" ) - return - endif - - if curNode.path.isDirectory - call nerdtree#openExplorer(curNode) - else - call curNode.open({'where': 'h'}) - endif -endfunction - -" FUNCTION: s:jumpToFirstChild() {{{2 -" wrapper for the jump to child method -function! s:jumpToFirstChild(node) - call nerdtree#jumpToChild(a:node, 0) -endfunction - -" FUNCTION: s:jumpToLastChild() {{{2 -" wrapper for the jump to child method -function! s:jumpToLastChild(node) - call nerdtree#jumpToChild(a:node, 1) -endfunction - -" FUNCTION: s:jumpToParent(node) {{{2 -" moves the cursor to the parent of the current node -function! s:jumpToParent(node) - if !empty(a:node.parent) - call a:node.parent.putCursorHere(1, 0) - call nerdtree#centerView() - else - call nerdtree#echo("cannot jump to parent") - endif -endfunction - -" FUNCTION: s:jumpToRoot() {{{2 -" moves the cursor to the root node -function! s:jumpToRoot() - call b:NERDTreeRoot.putCursorHere(1, 0) - call nerdtree#centerView() -endfunction - -" FUNCTION: s:jumpToNextSibling(node) {{{2 -function! s:jumpToNextSibling(node) - call nerdtree#jumpToSibling(a:node, 1) -endfunction - -" FUNCTION: s:jumpToPrevSibling(node) {{{2 -function! s:jumpToPrevSibling(node) - call nerdtree#jumpToSibling(a:node, 0) -endfunction - -" FUNCTION: nerdtree#openBookmark(name) {{{2 -" put the cursor on the given bookmark and, if its a file, open it -function! nerdtree#openBookmark(name) - try - let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0) - call targetNode.putCursorHere(0, 1) - redraw! - catch /^NERDTree.BookmarkedNodeNotFoundError/ - call nerdtree#echo("note - target node is not cached") - let bookmark = g:NERDTreeBookmark.BookmarkFor(a:name) - let targetNode = g:NERDTreeFileNode.New(bookmark.path) - endtry - if targetNode.path.isDirectory - call targetNode.openExplorer() - else - call targetNode.open({'where': 'p'}) - endif -endfunction - -" FUNCTION: s:openHSplit(target) {{{2 -function! s:openHSplit(target) - call a:target.activate({'where': 'h'}) -endfunction - -" FUNCTION: s:openVSplit(target) {{{2 -function! s:openVSplit(target) - call a:target.activate({'where': 'v'}) -endfunction - -" FUNCTION: s:openExplorer(node) {{{2 -function! s:openExplorer(node) - call a:node.openExplorer() -endfunction - -" FUNCTION: s:openInNewTab(target) {{{2 -function! s:openInNewTab(target) - call a:target.activate({'where': 't'}) -endfunction - -" FUNCTION: s:openInNewTabSilent(target) {{{2 -function! s:openInNewTabSilent(target) - call a:target.activate({'where': 't', 'stay': 1}) -endfunction - -" FUNCTION: s:openNodeRecursively(node) {{{2 -function! s:openNodeRecursively(node) - call nerdtree#echo("Recursively opening node. Please wait...") - call a:node.openRecursively() - call nerdtree#renderView() - redraw - call nerdtree#echo("Recursively opening node. Please wait... DONE") -endfunction - -"FUNCTION: s:previewNodeCurrent(node) {{{2 -function! s:previewNodeCurrent(node) - call a:node.open({'stay': 1, 'where': 'p', 'keepopen': 1}) -endfunction - -"FUNCTION: s:previewNodeHSplit(node) {{{2 -function! s:previewNodeHSplit(node) - call a:node.open({'stay': 1, 'where': 'h', 'keepopen': 1}) -endfunction - -"FUNCTION: s:previewNodeVSplit(node) {{{2 -function! s:previewNodeVSplit(node) - call a:node.open({'stay': 1, 'where': 'v', 'keepopen': 1}) -endfunction - -" FUNCTION: nerdtree#revealBookmark(name) {{{2 -" put the cursor on the node associate with the given name -function! nerdtree#revealBookmark(name) - try - let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0) - call targetNode.putCursorHere(0, 1) - catch /^NERDTree.BookmarkNotFoundError/ - call nerdtree#echo("Bookmark isnt cached under the current root") - endtry -endfunction - -" FUNCTION: s:refreshRoot() {{{2 -" Reloads the current root. All nodes below this will be lost and the root dir -" will be reloaded. -function! s:refreshRoot() - call nerdtree#echo("Refreshing the root node. This could take a while...") - call b:NERDTreeRoot.refresh() - call nerdtree#renderView() - redraw - call nerdtree#echo("Refreshing the root node. This could take a while... DONE") -endfunction - -" FUNCTION: s:refreshCurrent(node) {{{2 -" refreshes the root for the current node -function! s:refreshCurrent(node) - let node = a:node - if !node.path.isDirectory - let node = node.parent - endif - - call nerdtree#echo("Refreshing node. This could take a while...") - call node.refresh() - call nerdtree#renderView() - redraw - call nerdtree#echo("Refreshing node. This could take a while... DONE") -endfunction - -" FUNCTION: s:showMenu(node) {{{2 -function! s:showMenu(node) - let mc = g:NERDTreeMenuController.New(g:NERDTreeMenuItem.AllEnabled()) - call mc.showMenu() -endfunction - -" FUNCTION: s:toggleIgnoreFilter() {{{2 -" toggles the use of the NERDTreeIgnore option -function! s:toggleIgnoreFilter() - let b:NERDTreeIgnoreEnabled = !b:NERDTreeIgnoreEnabled - call nerdtree#renderViewSavingPosition() - call nerdtree#centerView() -endfunction - -" FUNCTION: s:toggleShowBookmarks() {{{2 -" toggles the display of bookmarks -function! s:toggleShowBookmarks() - let b:NERDTreeShowBookmarks = !b:NERDTreeShowBookmarks - if b:NERDTreeShowBookmarks - call nerdtree#renderView() - call nerdtree#putCursorOnBookmarkTable() - else - call nerdtree#renderViewSavingPosition() - endif - call nerdtree#centerView() -endfunction - -" FUNCTION: s:toggleShowFiles() {{{2 -" toggles the display of hidden files -function! s:toggleShowFiles() - let b:NERDTreeShowFiles = !b:NERDTreeShowFiles - call nerdtree#renderViewSavingPosition() - call nerdtree#centerView() -endfunction - -" FUNCTION: s:toggleShowHidden() {{{2 -" toggles the display of hidden files -function! s:toggleShowHidden() - let b:NERDTreeShowHidden = !b:NERDTreeShowHidden - call nerdtree#renderViewSavingPosition() - call nerdtree#centerView() -endfunction - -" FUNCTION: s:toggleZoom() {{{2 -" zoom (maximize/minimize) the NERDTree window -function! s:toggleZoom() - if exists("b:NERDTreeZoomed") && b:NERDTreeZoomed - let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize - exec "silent vertical resize ". size - let b:NERDTreeZoomed = 0 - else - exec "vertical resize" - let b:NERDTreeZoomed = 1 - endif -endfunction - -" FUNCTION: s:upDirCurrentRootOpen() {{{2 -function! s:upDirCurrentRootOpen() - call nerdtree#upDir(1) -endfunction - -" FUNCTION: s:upDirCurrentRootClosed() {{{2 -function! s:upDirCurrentRootClosed() - call nerdtree#upDir(0) -endfunction - " vim: set sw=4 sts=4 et fdm=marker: diff --git a/bundle/nerdtree/doc/NERD_tree.txt b/bundle/nerdtree/doc/NERD_tree.txt index bf038962..5d5b3f6f 100644 --- a/bundle/nerdtree/doc/NERD_tree.txt +++ b/bundle/nerdtree/doc/NERD_tree.txt @@ -109,7 +109,7 @@ The following features and functionality are provided by the NERD tree: < :NERDTreeFromBookmark *:NERDTreeFromBookmark* Opens a fresh NERD tree with the root initialized to the dir for - . This only reason to use this command over :NERDTree is for + . The only reason to use this command over :NERDTree is for the completion (which is for bookmarks rather than directories). :NERDTreeToggle [ | ] *:NERDTreeToggle* @@ -160,7 +160,7 @@ click bookmarks or use the |NERDTree-o| mapping to activate them. See also, Note that the following commands are only available in the NERD tree buffer. -:Bookmark +:Bookmark [] Bookmark the current node as . If there is already a bookmark, it is overwritten. must not contain spaces. If is not provided, it defaults to the file or directory name. @@ -358,7 +358,7 @@ Default key: O Map option: NERDTreeMapOpenRecursively Applies to: directories. -Recursively opens the selelected directory. +Recursively opens the selected directory. All files and directories are cached, but if a directory would not be displayed due to file filters (see |'NERDTreeIgnore'| |NERDTree-f|) or the @@ -462,8 +462,8 @@ Jump to the previous sibling of the selected node. ------------------------------------------------------------------------------ *NERDTree-C* Default key: C -Map option: NERDTreeMapChdir -Applies to: directories. +Map option: NERDTreeMapChangeRoot +Applies to: files and directories. Make the selected directory node the new tree root. If a file is selected, its parent is used. @@ -609,17 +609,19 @@ NERD tree. These options should be set in your vimrc. |'loaded_nerd_tree'| Turns off the script. -|'NERDChristmasTree'| Tells the NERD tree to make itself colourful - and pretty. - |'NERDTreeAutoCenter'| Controls whether the NERD tree window centers when the cursor moves within a specified distance to the top/bottom of the window. + |'NERDTreeAutoCenterThreshold'| Controls the sensitivity of autocentering. |'NERDTreeCaseSensitiveSort'| Tells the NERD tree whether to be case sensitive or not when sorting nodes. +|'NERDTreeSortHiddenFirst'| Tells the NERD tree whether to take the dot + at the beginning of the hidden file names + into account when sorting nodes. + |'NERDTreeChDirMode'| Tells the NERD tree if/when it should change vim's current working directory. @@ -631,8 +633,13 @@ NERD tree. These options should be set in your vimrc. |'NERDTreeIgnore'| Tells the NERD tree which files to ignore. +|'NERDTreeRespectWildIgnore'| Tells the NERD tree to respect |'wildignore'|. + |'NERDTreeBookmarksFile'| Where the bookmarks are stored. +|'NERDTreeBookmarksSort'| Whether the bookmarks list is sorted on + display. + |'NERDTreeMouseMode'| Tells the NERD tree how to handle mouse clicks. @@ -667,8 +674,8 @@ NERD tree. These options should be set in your vimrc. |'NERDTreeDirArrows'| Tells the NERD tree to use arrows instead of + ~ chars when displaying directories. -|'NERDTreeCasadeOpenSingleChildDir'| - Casade open while selected directory has only +|'NERDTreeCascadeOpenSingleChildDir'| + Cascade open while selected directory has only one child that also is a directory. |'NERDTreeAutoDeleteBuffer'| Tells the NERD tree to automatically remove @@ -686,15 +693,6 @@ If this plugin is making you feel homicidal, it may be a good idea to turn it off with this line in your vimrc: > let loaded_nerd_tree=1 < ------------------------------------------------------------------------------- - *'NERDChristmasTree'* -Values: 0 or 1. -Default: 1. - -If this option is set to 1 then some extra syntax highlighting elements are -added to the nerd tree to make it more colourful. - -Set it to 0 for a more vanilla looking tree. ------------------------------------------------------------------------------ *'NERDTreeAutoCenter'* @@ -817,6 +815,13 @@ line: > The file filters can be turned on and off dynamically with the |NERDTree-f| mapping. +------------------------------------------------------------------------------ + *'NERDTreeRespectWildIgnore'* +Values: 0 or 1. +Default: 0. + +If set to 1, the |'wildignore'| setting is respected. + ------------------------------------------------------------------------------ *'NERDTreeBookmarksFile'* Values: a path @@ -824,6 +829,14 @@ Default: $HOME/.NERDTreeBookmarks This is where bookmarks are saved. See |NERDTreeBookmarkCommands|. +------------------------------------------------------------------------------ + *'NERDTreeBookmarksSort'* +Values: 0 or 1 +Default: 1 + +If set to 0 then the bookmarks list is not sorted. +If set to 1 the bookmarks list is sorted. + ------------------------------------------------------------------------------ *'NERDTreeMouseMode'* Values: 1, 2 or 3. @@ -987,16 +1000,17 @@ option: > < ------------------------------------------------------------------------------ - *'NERDTreeCasadeOpenSingleChildDir'* + *'NERDTreeCascadeOpenSingleChildDir'* Values: 0 or 1 Default: 1. When opening dir nodes, this option tells NERDTree to recursively open dirs that have only one child which is also a dir. NERDTree will stop when it finds -a dir that contains anything but another single dir. This option may be useful -for Java projects. Use one of the follow lines to set this option: > - let NERDTreeCasadeOpenSingleChildDir=0 - let NERDTreeCasadeOpenSingleChildDir=1 +a dir that contains anything but another single dir. This option also causes +the |NERDTree-x| mapping to close dirs in the same manner. This option may be +useful for Java projects. Use one of the follow lines to set this option: > + let NERDTreeCascadeOpenSingleChildDir=0 + let NERDTreeCascadeOpenSingleChildDir=1 < ------------------------------------------------------------------------------ @@ -1046,6 +1060,9 @@ NERDTreeAddKeyMap({options}) *NERDTreeAddKeyMap()* "callback" - the function the new mapping will be bound to "quickhelpText" - the text that will appear in the quickhelp (see |NERDTree-?|) + "override" - if 1 then this new mapping will override whatever previous + mapping was defined for the key/scope combo. Useful for overriding the + default mappings. Additionally, a "scope" argument may be supplied. This constrains the mapping so that it is only activated if the cursor is on a certain object. @@ -1062,8 +1079,8 @@ NERDTreeAddKeyMap({options}) *NERDTreeAddKeyMap()* call NERDTreeAddKeyMap({ \ 'key': 'foo', \ 'callback': 'NERDTreeCDHandler', - \ 'quickhelpText': 'echo full path of current node' }) - \ 'scope': 'DirNode' + \ 'quickhelpText': 'echo full path of current node', + \ 'scope': 'DirNode' }) function! NERDTreeCDHandler(dirnode) call a:dirnode.changeToDir() diff --git a/bundle/nerdtree/lib/nerdtree/bookmark.vim b/bundle/nerdtree/lib/nerdtree/bookmark.vim index 5b845d81..6de9be4c 100644 --- a/bundle/nerdtree/lib/nerdtree/bookmark.vim +++ b/bundle/nerdtree/lib/nerdtree/bookmark.vim @@ -19,7 +19,9 @@ function! s:Bookmark.AddBookmark(name, path) endif endfor call add(s:Bookmark.Bookmarks(), s:Bookmark.New(a:name, a:path)) - call s:Bookmark.Sort() + if g:NERDTreeBookmarksSort ==# 1 + call s:Bookmark.Sort() + endif endfunction " FUNCTION: Bookmark.Bookmarks() {{{1 @@ -101,7 +103,9 @@ function! s:Bookmark.CacheBookmarks(silent) call nerdtree#echo(invalidBookmarksFound . " invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.") endif endif - call s:Bookmark.Sort() + if g:NERDTreeBookmarksSort ==# 1 + call s:Bookmark.Sort() + endif endif endfunction @@ -271,7 +275,7 @@ function! s:Bookmark.toRoot() let targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path) endtry call targetNode.makeRoot() - call nerdtree#renderView() + call b:NERDTree.render() call targetNode.putCursorHere(0, 0) endif endfunction @@ -289,7 +293,7 @@ function! s:Bookmark.validate() return 1 else call s:Bookmark.CacheBookmarks(1) - call nerdtree#renderView() + call b:NERDTree.render() call nerdtree#echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.") return 0 endif diff --git a/bundle/nerdtree/lib/nerdtree/creator.vim b/bundle/nerdtree/lib/nerdtree/creator.vim index 7f0721f0..86f951ae 100644 --- a/bundle/nerdtree/lib/nerdtree/creator.vim +++ b/bundle/nerdtree/lib/nerdtree/creator.vim @@ -7,18 +7,18 @@ let g:NERDTreeCreator = s:Creator "FUNCTION: s:Creator._bindMappings() {{{1 function! s:Creator._bindMappings() - "make do the same as the default 'o' mapping - exec "nnoremap :call nerdtree#invokeKeyMap('". g:NERDTreeMapActivateNode ."')" + "make do the same as the activate node mapping + nnoremap :call nerdtree#ui_glue#invokeKeyMap(g:NERDTreeMapActivateNode) call g:NERDTreeKeyMap.BindAll() - command! -buffer -nargs=? Bookmark :call nerdtree#bookmarkNode('') - command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#revealBookmark('') - command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#openBookmark('') - command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#clearBookmarks('') + command! -buffer -nargs=? Bookmark :call nerdtree#ui_glue#bookmarkNode('') + command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#ui_glue#revealBookmark('') + command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#ui_glue#openBookmark('') + command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#ui_glue#clearBookmarks('') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=+ BookmarkToRoot call g:NERDTreeBookmark.ToRoot('') - command! -buffer -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() call nerdtree#renderView() - command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) call nerdtree#renderView() + command! -buffer -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() call b:NERDTree.render() + command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) call b:NERDTree.render() command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write() endfunction @@ -49,26 +49,23 @@ function! s:Creator.createPrimary(name) call path.changeToDir() endif - if nerdtree#treeExistsForTab() + if g:NERDTree.ExistsForTab() if nerdtree#isTreeOpen() call nerdtree#closeTree() endif unlet t:NERDTreeBufName endif - let newRoot = g:NERDTreeDirNode.New(path) - call newRoot.open() - call self._createTreeWin() + call self._createNERDTree(path) + let b:NERDTreeType = "primary" let b:treeShowHelp = 0 let b:NERDTreeIgnoreEnabled = 1 let b:NERDTreeShowFiles = g:NERDTreeShowFiles let b:NERDTreeShowHidden = g:NERDTreeShowHidden let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks - let b:NERDTreeRoot = newRoot - let b:NERDTreeType = "primary" - call nerdtree#renderView() + call b:NERDTree.render() call b:NERDTreeRoot.putCursorHere(0, 0) call self._broadcastInitEvent() @@ -99,18 +96,26 @@ function! s:Creator.createSecondary(dir) exec "silent edit " . self._nextBufferName() let b:NERDTreePreviousBuf = bufnr(previousBuf) - - let b:NERDTreeRoot = g:NERDTreeDirNode.New(path) - call b:NERDTreeRoot.open() - + call self._createNERDTree(path) call self._setCommonBufOptions() let b:NERDTreeType = "secondary" - call nerdtree#renderView() + call b:NERDTree.render() call self._broadcastInitEvent() endfunction +" FUNCTION: s:Creator._createNERDTree(path) {{{1 +function! s:Creator._createNERDTree(path) + let b:NERDTree = g:NERDTree.New(a:path) + "TODO: This is kept for compatability only since many things use + "b:NERDTreeRoot instead of the new NERDTree.root + "Remove this one day + let b:NERDTreeRoot = b:NERDTree.root + + call b:NERDTree.root.open() +endfunction + " FUNCTION: s:Creator.CreateMirror() {{{1 function! s:Creator.CreateMirror() let creator = s:Creator.New() @@ -122,12 +127,12 @@ function! s:Creator.createMirror() "get the names off all the nerd tree buffers let treeBufNames = [] for i in range(1, tabpagenr("$")) - let nextName = nerdtree#tabpagevar(i, 'NERDTreeBufName') + let nextName = self._tabpagevar(i, 'NERDTreeBufName') if nextName != -1 && (!exists("t:NERDTreeBufName") || nextName != t:NERDTreeBufName) call add(treeBufNames, nextName) endif endfor - let treeBufNames = nerdtree#unique(treeBufNames) + let treeBufNames = self._uniq(treeBufNames) "map the option names (that the user will be prompted with) to the nerd "tree buffer names @@ -158,7 +163,7 @@ function! s:Creator.createMirror() return endif - if nerdtree#treeExistsForTab() && nerdtree#isTreeOpen() + if g:NERDTree.ExistsForTab() && nerdtree#isTreeOpen() call nerdtree#closeTree() endif @@ -166,7 +171,7 @@ function! s:Creator.createMirror() call self._createTreeWin() exec 'buffer ' . bufferName if !&hidden - call nerdtree#renderView() + call b:NERDTree.render() endif endfunction @@ -279,8 +284,8 @@ function! s:Creator._setCommonBufOptions() let b:NERDTreeShowFiles = g:NERDTreeShowFiles let b:NERDTreeShowHidden = g:NERDTreeShowHidden let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks - setfiletype nerdtree call self._bindMappings() + setlocal filetype=nerdtree endfunction "FUNCTION: s:Creator._setupStatusline() {{{1 @@ -290,6 +295,24 @@ function! s:Creator._setupStatusline() endif endfunction +" FUNCTION: s:Creator._tabpagevar(tabnr, var) {{{1 +function! s:Creator._tabpagevar(tabnr, var) + let currentTab = tabpagenr() + let old_ei = &ei + set ei=all + + exec "tabnext " . a:tabnr + let v = -1 + if exists('t:' . a:var) + exec 'let v = t:' . a:var + endif + exec "tabnext " . currentTab + + let &ei = old_ei + + return v +endfunction + "FUNCTION: s:Creator.TogglePrimary(dir) {{{1 function! s:Creator.TogglePrimary(dir) let creator = s:Creator.New() @@ -304,13 +327,13 @@ endfunction "dir: the full path for the root node (is only used if the NERD tree is being "initialized. function! s:Creator.togglePrimary(dir) - if nerdtree#treeExistsForTab() + if g:NERDTree.ExistsForTab() if !nerdtree#isTreeOpen() call self._createTreeWin() if !&hidden - call nerdtree#renderView() + call b:NERDTree.render() endif - call nerdtree#restoreScreenState() + call b:NERDTree.ui.restoreScreenState() else call nerdtree#closeTree() endif @@ -319,4 +342,16 @@ function! s:Creator.togglePrimary(dir) endif endfunction +" Function: s:Creator._uniq(list) {{{1 +" returns a:list without duplicates +function! s:Creator._uniq(list) + let uniqlist = [] + for elem in a:list + if index(uniqlist, elem) ==# -1 + let uniqlist += [elem] + endif + endfor + return uniqlist +endfunction + " vim: set sw=4 sts=4 et fdm=marker: diff --git a/bundle/nerdtree/lib/nerdtree/key_map.vim b/bundle/nerdtree/lib/nerdtree/key_map.vim index 86457652..2411406e 100644 --- a/bundle/nerdtree/lib/nerdtree/key_map.vim +++ b/bundle/nerdtree/lib/nerdtree/key_map.vim @@ -44,7 +44,7 @@ function! s:KeyMap.bind() let premap = self.key == "" ? " " : " " - exec 'nnoremap '. self.key . premap . ':call nerdtree#invokeKeyMap("'. keymapInvokeString .'")' + exec 'nnoremap '. self.key . premap . ':call nerdtree#ui_glue#invokeKeyMap("'. keymapInvokeString .'")' endfunction "FUNCTION: KeyMap.Remove(key, scope) {{{1 @@ -79,6 +79,16 @@ endfunction "If a keymap has the scope of "all" then it will be called if no other keymap "is found for a:key and the scope. function! s:KeyMap.Invoke(key) + + "required because clicking the command window below another window still + "invokes the mapping - but changes the window cursor + "is in first + " + "TODO: remove this check when the vim bug is fixed + if !g:NERDTree.ExistsForBuf() + return {} + endif + let node = g:NERDTreeFileNode.GetSelected() if !empty(node) @@ -124,8 +134,14 @@ endfunction "FUNCTION: KeyMap.Create(options) {{{1 function! s:KeyMap.Create(options) - let newKeyMap = copy(self) let opts = extend({'scope': 'all', 'quickhelpText': ''}, copy(a:options)) + + "dont override other mappings unless the 'override' option is given + if get(opts, 'override', 0) == 0 && !empty(s:KeyMap.FindFor(opts['key'], opts['scope'])) + return + end + + let newKeyMap = copy(self) let newKeyMap.key = opts['key'] let newKeyMap.quickhelpText = opts['quickhelpText'] let newKeyMap.callback = opts['callback'] diff --git a/bundle/nerdtree/lib/nerdtree/menu_item.vim b/bundle/nerdtree/lib/nerdtree/menu_item.vim index 6fb9d9e3..92c1bbbf 100644 --- a/bundle/nerdtree/lib/nerdtree/menu_item.vim +++ b/bundle/nerdtree/lib/nerdtree/menu_item.vim @@ -90,7 +90,7 @@ endfunction "callback function! s:MenuItem.execute() if len(self.children) - let mc = s:MenuController.New(self.children) + let mc = g:NERDTreeMenuController.New(self.children) call mc.showMenu() else if self.callback != -1 diff --git a/bundle/nerdtree/lib/nerdtree/opener.vim b/bundle/nerdtree/lib/nerdtree/opener.vim index bcc0d4fc..845e55c4 100644 --- a/bundle/nerdtree/lib/nerdtree/opener.vim +++ b/bundle/nerdtree/lib/nerdtree/opener.vim @@ -3,6 +3,29 @@ let s:Opener = {} let g:NERDTreeOpener = s:Opener +"FUNCTION: s:Opener._bufInWindows(bnum){{{1 +"[[STOLEN FROM VTREEEXPLORER.VIM]] +"Determine the number of windows open to this buffer number. +"Care of Yegappan Lakshman. Thanks! +" +"Args: +"bnum: the subject buffers buffer number +function! s:Opener._bufInWindows(bnum) + let cnt = 0 + let winnum = 1 + while 1 + let bufnum = winbufnr(winnum) + if bufnum < 0 + break + endif + if bufnum ==# a:bnum + let cnt = cnt + 1 + endif + let winnum = winnum + 1 + endwhile + + return cnt +endfunction "FUNCTION: Opener._checkToCloseTree(newtab) {{{1 "Check the class options and global options (i.e. NERDTreeQuitOnOpen) to see "if the tree should be closed now. @@ -21,6 +44,24 @@ function! s:Opener._checkToCloseTree(newtab) endif endfunction + +"FUNCTION: s:Opener._firstUsableWindow(){{{1 +"find the window number of the first normal window +function! s:Opener._firstUsableWindow() + let i = 1 + while i <= winnr("$") + let bnum = winbufnr(i) + if bnum != -1 && getbufvar(bnum, '&buftype') ==# '' + \ && !getwinvar(i, '&previewwindow') + \ && (!getbufvar(bnum, '&modified') || &hidden) + return i + endif + + let i += 1 + endwhile + return -1 +endfunction + "FUNCTION: Opener._gotoTargetWin() {{{1 function! s:Opener._gotoTargetWin() if b:NERDTreeType ==# "secondary" @@ -48,6 +89,37 @@ function! s:Opener._gotoTargetWin() endif endfunction +"FUNCTION: s:Opener._isWindowUsable(winnumber) {{{1 +"Returns 0 if opening a file from the tree in the given window requires it to +"be split, 1 otherwise +" +"Args: +"winnumber: the number of the window in question +function! s:Opener._isWindowUsable(winnumber) + "gotta split if theres only one window (i.e. the NERD tree) + if winnr("$") ==# 1 + return 0 + endif + + let oldwinnr = winnr() + call nerdtree#exec(a:winnumber . "wincmd p") + let specialWindow = getbufvar("%", '&buftype') != '' || getwinvar('%', '&previewwindow') + let modified = &modified + call nerdtree#exec(oldwinnr . "wincmd p") + + "if its a special window e.g. quickfix or another explorer plugin then we + "have to split + if specialWindow + return 0 + endif + + if &hidden + return 1 + endif + + return !modified || self._bufInWindows(winbufnr(a:winnumber)) >= 2 +endfunction + "FUNCTION: Opener.New(path, opts) {{{1 "Args: " @@ -190,7 +262,7 @@ function! s:Opener._openDirectory(node) call self._gotoTargetWin() if empty(self._where) call a:node.makeRoot() - call nerdtree#renderView() + call b:NERDTree.render() call a:node.putCursorHere(0, 0) elseif self._where == 't' call g:NERDTreeCreator.CreatePrimary(a:node.path.str()) @@ -206,12 +278,12 @@ endfunction "FUNCTION: Opener._previousWindow() {{{1 function! s:Opener._previousWindow() - if !nerdtree#isWindowUsable(winnr("#")) && nerdtree#firstUsableWindow() ==# -1 + if !self._isWindowUsable(winnr("#")) && self._firstUsableWindow() ==# -1 call self._newSplit() else try - if !nerdtree#isWindowUsable(winnr("#")) - call nerdtree#exec(nerdtree#firstUsableWindow() . "wincmd w") + if !self._isWindowUsable(winnr("#")) + call nerdtree#exec(self._firstUsableWindow() . "wincmd w") else call nerdtree#exec('wincmd p') endif diff --git a/bundle/nerdtree/lib/nerdtree/path.vim b/bundle/nerdtree/lib/nerdtree/path.vim index 58bb0138..5de1dfe2 100644 --- a/bundle/nerdtree/lib/nerdtree/path.vim +++ b/bundle/nerdtree/lib/nerdtree/path.vim @@ -33,8 +33,10 @@ function! s:Path.bookmarkNames() endfunction "FUNCTION: Path.cacheDisplayString() {{{1 -function! s:Path.cacheDisplayString() - let self.cachedDisplayString = self.getLastPathComponent(1) +function! s:Path.cacheDisplayString() abort + let self.cachedDisplayString = self.flagSet.renderToString() + + let self.cachedDisplayString .= self.getLastPathComponent(1) if self.isExecutable let self.cachedDisplayString = self.cachedDisplayString . '*' @@ -103,6 +105,10 @@ function! s:Path.compareTo(path) elseif thisSS > thatSS return 1 else + if !g:NERDTreeSortHiddenFirst + let thisPath = substitute(thisPath, '^[._]', '', '') + let thatPath = substitute(thatPath, '^[._]', '', '') + endif "if the sort sequences are the same then compare the paths "alphabetically let pathCompare = g:NERDTreeCaseSensitiveSort ? thisPath <# thatPath : thisPath " + endif + + return " \\`\|\"#%&,?()\*^<>[]" +endfunction + "FUNCTION: Path.getDir() {{{1 " "Returns this path if it is a directory, else this paths parent. @@ -439,6 +471,7 @@ function! s:Path.New(path) call newPath.readInfoFromDisk(s:Path.AbsolutePathFor(a:path)) let newPath.cachedDisplayString = "" + let newPath.flagSet = g:NERDTreeFlagSet.New() return newPath endfunction @@ -516,6 +549,13 @@ endfunction "FUNCTION: Path.refresh() {{{1 function! s:Path.refresh() call self.readInfoFromDisk(self.str()) + call g:NERDTreePathNotifier.NotifyListeners('refresh', self, {}) + call self.cacheDisplayString() +endfunction + +"FUNCTION: Path.refreshFlags() {{{1 +function! s:Path.refreshFlags() + call g:NERDTreePathNotifier.NotifyListeners('refreshFlags', self, {}) call self.cacheDisplayString() endfunction @@ -604,7 +644,7 @@ endfunction " " returns a string that can be used with :cd function! s:Path._strForCd() - return escape(self.str(), nerdtree#escChars()) + return escape(self.str(), self._escChars()) endfunction "FUNCTION: Path._strForEdit() {{{1 @@ -612,7 +652,7 @@ endfunction "Return: the string for this path that is suitable to be used with the :edit "command function! s:Path._strForEdit() - let p = escape(self.str({'format': 'UI'}), nerdtree#escChars()) + let p = escape(self.str({'format': 'UI'}), self._escChars()) let cwd = getcwd() . s:Path.Slash() "return a relative path if we can @@ -652,7 +692,7 @@ function! s:Path._strForGlob() let toReturn = lead . join(self.pathSegments, s:Path.Slash()) if !nerdtree#runningWindows() - let toReturn = escape(toReturn, nerdtree#escChars()) + let toReturn = escape(toReturn, self._escChars()) endif return toReturn endfunction diff --git a/bundle/nerdtree/lib/nerdtree/tree_dir_node.vim b/bundle/nerdtree/lib/nerdtree/tree_dir_node.vim index e3a068ed..a24c2704 100644 --- a/bundle/nerdtree/lib/nerdtree/tree_dir_node.vim +++ b/bundle/nerdtree/lib/nerdtree/tree_dir_node.vim @@ -21,7 +21,7 @@ unlet s:TreeDirNode.activate function! s:TreeDirNode.activate(...) let opts = a:0 ? a:1 : {} call self.toggleOpen(opts) - call nerdtree#renderView() + call b:NERDTree.render() call self.putCursorHere(0, 0) endfunction @@ -229,7 +229,7 @@ function! s:TreeDirNode._initChildren(silent) let globDir = dir.str({'format': 'Glob'}) if version >= 703 - let filesStr = globpath(globDir, '*', 1) . "\n" . globpath(globDir, '.*', 1) + let filesStr = globpath(globDir, '*', !g:NERDTreeRespectWildIgnore) . "\n" . globpath(globDir, '.*', !g:NERDTreeRespectWildIgnore) else let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*') endif @@ -252,6 +252,7 @@ function! s:TreeDirNode._initChildren(silent) try let path = g:NERDTreePath.New(i) call self.createChild(path, 0) + call g:NERDTreePathNotifier.NotifyListeners('init', path, {}) catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/ let invalidFilesFound += 1 endtry @@ -438,6 +439,20 @@ function! s:TreeDirNode.refresh() endif endfunction +"FUNCTION: TreeDirNode.refreshFlags() {{{1 +unlet s:TreeDirNode.refreshFlags +function! s:TreeDirNode.refreshFlags() + call self.path.refreshFlags() + for i in self.children + call i.refreshFlags() + endfor +endfunction + +"FUNCTION: TreeDirNode.refreshDirFlags() {{{1 +function! s:TreeDirNode.refreshDirFlags() + call self.path.refreshFlags() +endfunction + "FUNCTION: TreeDirNode.reveal(path) {{{1 "reveal the given path, i.e. cache and open all treenodes needed to display it "in the UI @@ -450,7 +465,7 @@ function! s:TreeDirNode.reveal(path) if self.path.equals(a:path.getParent()) let n = self.findNode(a:path) - call nerdtree#renderView() + call b:NERDTree.render() call n.putCursorHere(1,0) return endif @@ -500,7 +515,7 @@ function! s:TreeDirNode.toggleOpen(...) if self.isOpen ==# 1 call self.close() else - if g:NERDTreeCasadeOpenSingleChildDir == 0 + if g:NERDTreeCascadeOpenSingleChildDir == 0 call self.open(opts) else call self.openAlong(opts) diff --git a/bundle/nerdtree/lib/nerdtree/tree_file_node.vim b/bundle/nerdtree/lib/nerdtree/tree_file_node.vim index ab8d3719..b4924d78 100644 --- a/bundle/nerdtree/lib/nerdtree/tree_file_node.vim +++ b/bundle/nerdtree/lib/nerdtree/tree_file_node.vim @@ -178,79 +178,20 @@ function! s:TreeFileNode.findSibling(direction) return {} endfunction -"FUNCTION: TreeFileNode.getLineNum(){{{1 -"returns the line number this node is rendered on, or -1 if it isnt rendered -function! s:TreeFileNode.getLineNum() - "if the node is the root then return the root line no. - if self.isRoot() - return s:TreeFileNode.GetRootLineNum() - endif - - let totalLines = line("$") - - "the path components we have matched so far - let pathcomponents = [substitute(b:NERDTreeRoot.path.str({'format': 'UI'}), '/ *$', '', '')] - "the index of the component we are searching for - let curPathComponent = 1 - - let fullpath = self.path.str({'format': 'UI'}) - - - let lnum = s:TreeFileNode.GetRootLineNum() - while lnum > 0 - let lnum = lnum + 1 - "have we reached the bottom of the tree? - if lnum ==# totalLines+1 - return -1 - endif - - let curLine = getline(lnum) - - let indent = nerdtree#indentLevelFor(curLine) - if indent ==# curPathComponent - let curLine = nerdtree#stripMarkupFromLine(curLine, 1) - - let curPath = join(pathcomponents, '/') . '/' . curLine - if stridx(fullpath, curPath, 0) ==# 0 - if fullpath ==# curPath || strpart(fullpath, len(curPath)-1,1) ==# '/' - let curLine = substitute(curLine, '/ *$', '', '') - call add(pathcomponents, curLine) - let curPathComponent = curPathComponent + 1 - - if fullpath ==# curPath - return lnum - endif - endif - endif - endif - endwhile - return -1 -endfunction - "FUNCTION: TreeFileNode.GetRootForTab(){{{1 "get the root node for this tab function! s:TreeFileNode.GetRootForTab() - if nerdtree#treeExistsForTab() + if g:NERDTree.ExistsForTab() return getbufvar(t:NERDTreeBufName, 'NERDTreeRoot') end return {} endfunction -"FUNCTION: TreeFileNode.GetRootLineNum(){{{1 -"gets the line number of the root node -function! s:TreeFileNode.GetRootLineNum() - let rootLine = 1 - while getline(rootLine) !~# '^\(/\|<\)' - let rootLine = rootLine + 1 - endwhile - return rootLine -endfunction - "FUNCTION: TreeFileNode.GetSelected() {{{1 "gets the treenode that the cursor is currently over function! s:TreeFileNode.GetSelected() try - let path = nerdtree#getPath(line(".")) + let path = b:NERDTree.ui.getPath(line(".")) if path ==# {} return {} endif @@ -270,7 +211,7 @@ endfunction "FUNCTION: TreeFileNode.isRoot() {{{1 "returns 1 if this node is b:NERDTreeRoot function! s:TreeFileNode.isRoot() - if !nerdtree#treeExistsForBuf() + if !g:NERDTree.ExistsForBuf() throw "NERDTree.NoTreeError: No tree exists for the current buffer" endif @@ -348,7 +289,7 @@ endfunction "recurseUpward: try to put the cursor on the parent if the this node isnt "visible function! s:TreeFileNode.putCursorHere(isJump, recurseUpward) - let ln = self.getLineNum() + let ln = b:NERDTree.ui.getLineNum(self) if ln != -1 if a:isJump mark ' @@ -357,11 +298,11 @@ function! s:TreeFileNode.putCursorHere(isJump, recurseUpward) else if a:recurseUpward let node = self - while node != {} && node.getLineNum() ==# -1 + while node != {} && b:NERDTree.ui.getLineNum(node) ==# -1 let node = node.parent call node.open() endwhile - call nerdtree#renderView() + call b:NERDTree.render() call node.putCursorHere(a:isJump, 0) endif endif @@ -372,6 +313,11 @@ function! s:TreeFileNode.refresh() call self.path.refresh() endfunction +"FUNCTION: TreeFileNode.refreshFlags() {{{1 +function! s:TreeFileNode.refreshFlags() + call self.path.refreshFlags() +endfunction + "FUNCTION: TreeFileNode.rename() {{{1 "Calls the rename method for this nodes path obj function! s:TreeFileNode.rename(newName) diff --git a/bundle/nerdtree/nerdtree_plugin/fs_menu.vim b/bundle/nerdtree/nerdtree_plugin/fs_menu.vim index 9b81ed37..4e03f35e 100644 --- a/bundle/nerdtree/nerdtree_plugin/fs_menu.vim +++ b/bundle/nerdtree/nerdtree_plugin/fs_menu.vim @@ -82,13 +82,14 @@ endfunction function! s:promptToRenameBuffer(bufnum, msg, newFileName) echo a:msg if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y' + let quotedFileName = "'" . a:newFileName . "'" " 1. ensure that a new buffer is loaded - exec "badd " . a:newFileName + exec "badd " . quotedFileName " 2. ensure that all windows which display the just deleted filename " display a buffer for a new filename. let s:originalTabNumber = tabpagenr() let s:originalWindowNumber = winnr() - exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':e! " . a:newFileName . "' | endif" + exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec \":e! " . quotedFileName . "\" | endif" exec "tabnext " . s:originalTabNumber exec s:originalWindowNumber . "wincmd w" " 3. We don't need a previous buffer anymore @@ -114,7 +115,10 @@ function! NERDTreeAddNode() let parentNode = b:NERDTreeRoot.findNode(newPath.getParent()) let newTreeNode = g:NERDTreeFileNode.New(newPath) - if parentNode.isOpen || !empty(parentNode.children) + if empty(parentNode) + call b:NERDTreeRoot.refresh() + call b:NERDTree.render() + elseif parentNode.isOpen || !empty(parentNode.children) call parentNode.addChild(newTreeNode, 1) call NERDTreeRender() call newTreeNode.putCursorHere(1, 0) @@ -138,7 +142,7 @@ function! NERDTreeMoveNode() endif try - let bufnum = bufnr(curNode.path.str()) + let bufnum = bufnr("^".curNode.path.str()."$") call curNode.rename(newNodePath) call NERDTreeRender() @@ -186,7 +190,7 @@ function! NERDTreeDeleteNode() "if the node is open in a buffer, ask the user if they want to "close that buffer - let bufnum = bufnr(currentNode.path.str()) + let bufnum = bufnr("^".currentNode.path.str()."$") if buflisted(bufnum) let prompt = "\nNode deleted.\n\nThe file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Delete this buffer? (yN)" call s:promptToDelBuffer(bufnum, prompt) @@ -224,7 +228,10 @@ function! NERDTreeCopyNode() if confirmed try let newNode = currentNode.copy(newNodePath) - if !empty(newNode) + if empty(newNode) + call b:NERDTreeRoot.refresh() + call b:NERDTree.render() + else call NERDTreeRender() call newNode.putCursorHere(0, 0) endif diff --git a/bundle/nerdtree/plugin/NERD_tree.vim b/bundle/nerdtree/plugin/NERD_tree.vim index 5bee03ad..28fd3ad1 100644 --- a/bundle/nerdtree/plugin/NERD_tree.vim +++ b/bundle/nerdtree/plugin/NERD_tree.vim @@ -45,28 +45,30 @@ function! s:initVariable(var, value) endfunction "SECTION: Init variable calls and other random constants {{{2 -call s:initVariable("g:NERDChristmasTree", 1) call s:initVariable("g:NERDTreeAutoCenter", 1) call s:initVariable("g:NERDTreeAutoCenterThreshold", 3) call s:initVariable("g:NERDTreeCaseSensitiveSort", 0) +call s:initVariable("g:NERDTreeSortHiddenFirst", 1) call s:initVariable("g:NERDTreeChDirMode", 0) call s:initVariable("g:NERDTreeMinimalUI", 0) if !exists("g:NERDTreeIgnore") let g:NERDTreeIgnore = ['\~$'] endif call s:initVariable("g:NERDTreeBookmarksFile", expand('$HOME') . '/.NERDTreeBookmarks') +call s:initVariable("g:NERDTreeBookmarksSort", 1) call s:initVariable("g:NERDTreeHighlightCursorline", 1) call s:initVariable("g:NERDTreeHijackNetrw", 1) call s:initVariable("g:NERDTreeMouseMode", 1) call s:initVariable("g:NERDTreeNotificationThreshold", 100) call s:initVariable("g:NERDTreeQuitOnOpen", 0) +call s:initVariable("g:NERDTreeRespectWildIgnore", 0) call s:initVariable("g:NERDTreeShowBookmarks", 0) call s:initVariable("g:NERDTreeShowFiles", 1) call s:initVariable("g:NERDTreeShowHidden", 0) call s:initVariable("g:NERDTreeShowLineNumbers", 0) call s:initVariable("g:NERDTreeSortDirs", 1) call s:initVariable("g:NERDTreeDirArrows", !nerdtree#runningWindows()) -call s:initVariable("g:NERDTreeCasadeOpenSingleChildDir", 1) +call s:initVariable("g:NERDTreeCascadeOpenSingleChildDir", 1) if !exists("g:NERDTreeSortOrder") let g:NERDTreeSortOrder = ['\/$', '*', '\.swp$', '\.bak$', '\~$'] @@ -140,20 +142,13 @@ call nerdtree#loadClassFiles() " SECTION: Commands {{{1 "============================================================ -"init the command that users start the nerd tree with -command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreatePrimary('') -command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.TogglePrimary('') -command! -n=0 -bar NERDTreeClose :call nerdtree#closeTreeIfOpen() -command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreatePrimary('') -command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror() -command! -n=0 -bar NERDTreeFind call nerdtree#findAndRevealPath() -command! -n=0 -bar NERDTreeFocus call NERDTreeFocus() -command! -n=0 -bar NERDTreeCWD call NERDTreeCWD() +call nerdtree#ui_glue#setupCommands() + " SECTION: Auto commands {{{1 "============================================================ augroup NERDTree "Save the cursor position whenever we close the nerd tree - exec "autocmd BufWinLeave ". g:NERDTreeCreator.BufNamePrefix() ."* call nerdtree#saveScreenState()" + exec "autocmd BufLeave ". g:NERDTreeCreator.BufNamePrefix() ."* call b:NERDTree.ui.saveScreenState()" "disallow insert mode in the NERDTree exec "autocmd BufEnter ". g:NERDTreeCreator.BufNamePrefix() ."* stopinsert" @@ -199,7 +194,7 @@ endfunction function! NERDTreeCWD() call NERDTreeFocus() - call nerdtree#chRootCwd() + call nerdtree#ui_glue#chRootCwd() endfunction " SECTION: Post Source Actions {{{1 call nerdtree#postSourceActions() diff --git a/bundle/nerdtree/syntax/nerdtree.vim b/bundle/nerdtree/syntax/nerdtree.vim index 636d2af7..5f7b49cc 100644 --- a/bundle/nerdtree/syntax/nerdtree.vim +++ b/bundle/nerdtree/syntax/nerdtree.vim @@ -1,44 +1,64 @@ let s:tree_up_dir_line = '.. (up a dir)' -"NERDTreeFlags are syntax items that should be invisible, but give clues as to -"how things should be highlighted -syn match NERDTreeFlag #\~# -syn match NERDTreeFlag #\[RO\]# +syn match NERDTreeIgnore #\~# +syn match NERDTreeIgnore #\[RO\]# "highlighting for the .. (up dir) line at the top of the tree execute "syn match NERDTreeUp #\\V". s:tree_up_dir_line ."#" -"highlighting for the ~/+ symbols for the directory nodes -syn match NERDTreeClosable #\~\<# -syn match NERDTreeClosable #\~\.# -syn match NERDTreeOpenable #+\<# -syn match NERDTreeOpenable #+\.#he=e-1 - -"highlighting for the tree structural parts -syn match NERDTreePart #|# -syn match NERDTreePart #`# -syn match NERDTreePartFile #[|`]-#hs=s+1 contains=NERDTreePart - "quickhelp syntax elements -syn match NERDTreeHelpKey #" \{1,2\}[^ ]*:#hs=s+2,he=e-1 -syn match NERDTreeHelpKey #" \{1,2\}[^ ]*,#hs=s+2,he=e-1 -syn match NERDTreeHelpTitle #" .*\~#hs=s+2,he=e-1 contains=NERDTreeFlag -syn match NERDTreeToggleOn #".*(on)#hs=e-2,he=e-1 contains=NERDTreeHelpKey -syn match NERDTreeToggleOff #".*(off)#hs=e-3,he=e-1 contains=NERDTreeHelpKey +syn match NERDTreeHelpKey #" \{1,2\}[^ ]*:#ms=s+2,me=e-1 +syn match NERDTreeHelpKey #" \{1,2\}[^ ]*,#ms=s+2,me=e-1 +syn match NERDTreeHelpTitle #" .*\~#ms=s+2,me=e-1 +syn match NERDTreeToggleOn #(on)#ms=s+1,he=e-1 +syn match NERDTreeToggleOff #(off)#ms=e-3,me=e-1 syn match NERDTreeHelpCommand #" :.\{-}\>#hs=s+3 -syn match NERDTreeHelp #^".*# contains=NERDTreeHelpKey,NERDTreeHelpTitle,NERDTreeFlag,NERDTreeToggleOff,NERDTreeToggleOn,NERDTreeHelpCommand - -"highlighting for readonly files -syn match NERDTreeRO #.*\[RO\]#hs=s+2 contains=NERDTreeFlag,NERDTreeBookmark,NERDTreePart,NERDTreePartFile +syn match NERDTreeHelp #^".*# contains=NERDTreeHelpKey,NERDTreeHelpTitle,NERDTreeIgnore,NERDTreeToggleOff,NERDTreeToggleOn,NERDTreeHelpCommand "highlighting for sym links -syn match NERDTreeLink #[^-| `].* -> # contains=NERDTreeBookmark,NERDTreeOpenable,NERDTreeClosable,NERDTreeDirSlash +syn match NERDTreeLinkTarget #->.*# containedin=NERDTreeDir,NERDTreeFile +syn match NERDTreeLinkFile #.* ->#me=e-3 containedin=NERDTreeFile +syn match NERDTreeLinkDir #.*/ ->#me=e-3 containedin=NERDTreeDir "highlighing for directory nodes and file nodes -syn match NERDTreeDirSlash #/# -syn match NERDTreeDir #[^-| `].*/# contains=NERDTreeLink,NERDTreeDirSlash,NERDTreeOpenable,NERDTreeClosable -syn match NERDTreeExecFile #[|` ].*\*\($\| \)# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark -syn match NERDTreeFile #|-.*# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile -syn match NERDTreeFile #`-.*# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile +syn match NERDTreeDirSlash #/# containedin=NERDTreeDir + +if g:NERDTreeDirArrows + syn match NERDTreeClosable #▾# containedin=NERDTreeDir,NERDTreeFile + syn match NERDTreeOpenable #▸# containedin=NERDTreeDir,NERDTreeFile + + syn match NERDTreeDir #[^▾▸ ].*/# + syn match NERDTreeExecFile #^ .*\*\($\| \)# contains=NERDTreeRO,NERDTreeBookmark + syn match NERDTreeFile #^[^"\.▾▸] *[^▾▸]*# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmark,NERDTreeExecFile + + "highlighting for readonly files + syn match NERDTreeRO # *\zs.*\ze \[RO\]# contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreeFile + + syn match NERDTreeFlags #^ *\zs\[.\]# containedin=NERDTreeFile + syn match NERDTreeFlags #\[.\]# containedin=NERDTreeDir +else + "highlighting for the ~/+ symbols for the directory nodes + syn match NERDTreeClosable #\~\<# + syn match NERDTreeClosable #\~\.# + syn match NERDTreeOpenable #+\<# + syn match NERDTreeOpenable #+\.#he=e-1 + + "highlighting for the tree structural parts + syn match NERDTreePart #|# + syn match NERDTreePart #`# + syn match NERDTreePartFile #[|`]-#hs=s+1 contains=NERDTreePart + + syn match NERDTreeDir #[^-| `].*/# contains=NERDTreeLink,NERDTreeOpenable,NERDTreeClosable + syn match NERDTreeExecFile #[|` ].*\*\($\| \)# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark + syn match NERDTreeFile #|-.*# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile + syn match NERDTreeFile #`-.*# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile + + "highlighting for readonly files + syn match NERDTreeRO #|-.*\[RO\]#he=e-5 contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreePart,NERDTreePartFile + + syn match NERDTreeFlags #-\[.\]# containedin=NERDTreeFile,NERDTreePartFile + syn match NERDTreeFlags #[+~]\zs\[.\]# containedin=NERDTreeDir +endif + syn match NERDTreeCWD #^[-\+Bookmarks-\+$# contains=NERDTreeBookmark syn match NERDTreeBookmarkName #^>.\{-} #he=e-1 contains=NERDTreeBookmarksLeader syn match NERDTreeBookmark #^>.*$# contains=NERDTreeBookmarksLeader,NERDTreeBookmarkName,NERDTreeBookmarksHeader -if exists("g:NERDChristmasTree") && g:NERDChristmasTree - hi def link NERDTreePart Special - hi def link NERDTreePartFile Type - hi def link NERDTreeFile Normal - hi def link NERDTreeExecFile Title - hi def link NERDTreeDirSlash Identifier - hi def link NERDTreeClosable Type -else - hi def link NERDTreePart Normal - hi def link NERDTreePartFile Normal - hi def link NERDTreeFile Normal - hi def link NERDTreeClosable Title -endif +hi def link NERDTreePart Special +hi def link NERDTreePartFile Type +hi def link NERDTreeExecFile Title +hi def link NERDTreeDirSlash Identifier hi def link NERDTreeBookmarksHeader statement hi def link NERDTreeBookmarksLeader ignore @@ -76,13 +87,19 @@ hi def link NERDTreeHelpTitle Macro hi def link NERDTreeToggleOn Question hi def link NERDTreeToggleOff WarningMsg +hi def link NERDTreeLinkTarget Type +hi def link NERDTreeLinkFile Macro +hi def link NERDTreeLinkDir Macro + hi def link NERDTreeDir Directory hi def link NERDTreeUp Directory +hi def link NERDTreeFile Normal hi def link NERDTreeCWD Statement -hi def link NERDTreeLink Macro hi def link NERDTreeOpenable Title -hi def link NERDTreeFlag ignore +hi def link NERDTreeClosable Title +hi def link NERDTreeIgnore ignore hi def link NERDTreeRO WarningMsg hi def link NERDTreeBookmark Statement +hi def link NERDTreeFlags Number hi def link NERDTreeCurrentNode Search diff --git a/bundle/syntastic/CONTRIBUTING.md b/bundle/syntastic/CONTRIBUTING.md index 764ffffc..378b53b3 100644 --- a/bundle/syntastic/CONTRIBUTING.md +++ b/bundle/syntastic/CONTRIBUTING.md @@ -1,49 +1,105 @@ -# Bug reports / Github issues +# CONTRIBUTING +- - - +1\. [Bug reports / GitHub issues](#bugreps) +2\. [Submitting a patch](#patches) +3\. [General style notes](#generalstyle) +4\. [Syntax checker notes](#checkerstyle) +- - - -When reporting a bug make sure you search the existing github issues for the -same/similar issues. If you find one, feel free to add a `+1` comment with any -additional information that may help us solve the issue. + + +## 1. Bug reports / GitHub issues + +Please note that the preferred channel for posting bug reports is the +[issue tracker at GitHub][0]. Reports posted elsewhere are less likely +to be seen by the core team. + +When reporting a bug make sure you search the existing GitHub issues +for the same/similar issues. If you find one, feel free to add a `+1` +comment with any additional information that may help us solve the +issue. When creating a new issue be sure to state the following: -* Steps to reproduce the bug. -* The version of vim you are using. -* The version of syntastic you are using. +* steps to reproduce the bug; +* the version of Vim you are using (run `:ver` to find out); +* the version of syntastic you are using (see `:SyntasticInfo`). -For syntax checker bugs also state the version of the checker executable that you are using. +For syntax checker bugs also state the version of the checker executable +that you are using. Adding debugging information is typically useful +too: -# Submitting a patch +* open a file handled by your checker; +* set `g:syntastic_debug` to 1 or 3; +* run the checker; +* copy the output of `:mes`. -* Fork the repo on github -* Make a [topic branch](https://github.com/dchelimsky/rspec/wiki/Topic-Branches#using-topic-branches-when-contributing-patches) and start hacking -* Submit a pull request based off your topic branch + -Small focused patches are preferred. +## 2. Submitting a patch -Large changes to the code should be discussed with the core team first. Create an issue and explain your plan and see what we say. +Before you consider adding features to syntastic, _please_ spend a few +minutes (re-)reading the latest version of the [manual][1]. Syntastic +is changing rapidly at times, and it's quite possible that some of the +features you want to add exist already. -# General style notes +To submit a patch: -Following the coding conventions/styles used in the syntastic core: +* fork the [repo][2] on GitHub; +* make a [topic branch][3] and start hacking; +* submit a pull request based off your topic branch. -* Use 4 space indents. -* Don't use abbreviated keywords - e.g. use `endfunction`, not `endfun` (there's always room for more fun!). -* Don't use `l:` prefixes for variables unless actually required (i.e. almost never). -* Code for maintainability. We would rather a function be a couple of lines longer and have (for example) some [explaining variables](http://www.refactoring.com/catalog/introduceExplainingVariable.html) to aid readability. +Small, focused patches are preferred. -# Syntax checker style notes +Large changes to the code should be discussed with the core team first. +Create an issue and explain your plan and see what we say. -The preferred style for error format strings is one "clause" per line. E.g. -(from the coffeelint checker): +Also make sure to update the manual whenever applicable. Nobody can use +features that aren't documented. -```viml -let errorformat = '%E%f:%l:%c: %trror: %m,' . - \ 'Syntax%trror: In %f\, %m on line %l,' . - \ '%EError: In %f\, Parse error on line %l: %m,' . - \ '%EError: In %f\, %m on line %l,' . - \ '%W%f(%l): lint warning: %m,' . - \ '%W%f(%l): warning: %m,' . - \ '%E%f(%l): SyntaxError: %m,' . - \ '%-Z%p^,' . - \ '%-G%.%#' + + +## 3. General style notes + +Follow the coding conventions/styles used in the syntastic core: + +* use 4 space indents; +* don't use abbreviated keywords - e.g. use `endfunction`, not `endfun` +(there's always room for more fun!); +* don't use `l:` prefixes for variables unless actually required (i.e. +almost never); +* code for maintainability; we would rather a function be a couple of +lines longer and have (for example) some [explaining variables][4] to +aid readability. + + + +## 4. Syntax checker notes + +Make sure to read the [guide][5] if you plan to add new syntax checkers. + +Use the existing checkers as templates, rather than writing everything +from scratch. + +The preferred style for error format strings is one "clause" per line. +E.g. (from the `coffee` checker): + +```vim +let errorformat = + \ '%E%f:%l:%c: %trror: %m,' . + \ 'Syntax%trror: In %f\, %m on line %l,' . + \ '%EError: In %f\, Parse error on line %l: %m,' . + \ '%EError: In %f\, %m on line %l,' . + \ '%W%f(%l): lint warning: %m,' . + \ '%W%f(%l): warning: %m,' . + \ '%E%f(%l): SyntaxError: %m,' . + \ '%-Z%p^,' . + \ '%-G%.%#' ``` + +[0]: https://github.com/scrooloose/syntastic/issues +[1]: https://github.com/scrooloose/syntastic/blob/master/doc/syntastic.txt +[2]: https://github.com/scrooloose/syntastic +[3]: https://github.com/dchelimsky/rspec/wiki/Topic-Branches#using-topic-branches-when-contributing-patches +[4]: http://www.refactoring.com/catalog/extractVariable.html +[5]: https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide diff --git a/bundle/syntastic/README.markdown b/bundle/syntastic/README.markdown index 653bd7c6..8d96daa7 100644 --- a/bundle/syntastic/README.markdown +++ b/bundle/syntastic/README.markdown @@ -35,15 +35,17 @@ the user is notified and is happy because they didn't have to compile their code or execute their script to find them. At the time of this writing, syntax checking plugins exist for ActionScript, -Ada, AppleScript, AsciiDoc, ASM, BEMHTML, Bourne shell, C, C++, C#, Chef, -CoffeeScript, Coco, Coq, CSS, Cucumber, CUDA, D, Dart, DocBook, Dust, Elixir, -Erlang, eRuby, Fortran, Gentoo metadata, GLSL, Go, Haml, Haskell, Haxe, -Handlebars, HSS, HTML, Java, JavaScript, JSON, JSX, LESS, Lex, Limbo, LISP, -LLVM intermediate language, Lua, MATLAB, NASM, Objective-C, Objective-C++, -OCaml, Perl, Perl POD, PHP, gettext Portable Object, Puppet, Python, Racket, -reStructuredText, Ruby, Rust, SASS/SCSS, Scala, Slim, Tcl, TeX, Texinfo, Twig, -TypeScript, Vala, Verilog, VHDL, VimL, xHtml, XML, XSLT, YACC, YAML, z80, Zope -page templates, and zsh. +Ada, AppleScript, Arduino, AsciiDoc, ASM, BEMHTML, Bro, Bourne shell, C, +C++, C#, Cabal, Chef, CoffeeScript, Coco, Coq, CSS, Cucumber, CUDA, D, Dart, +DocBook, Dust, Elixir, Erlang, eRuby, Fortran, Gentoo metadata, GLSL, Go, +Haml, Haskell, Haxe, Handlebars, HSS, HTML, Java, JavaScript, JSON, JSX, LESS, +Lex, Limbo, LISP, LLVM intermediate language, Lua, MATLAB, NASM, Objective-C, +Objective-C++, OCaml, Perl, Perl POD, PHP, gettext Portable Object, OS X and +iOS property lists, Puppet, Python, Racket, R, reStructuredText, RPM spec, +Ruby, SASS/SCSS, Scala, Slim, Tcl, TeX, Texinfo, Twig, TypeScript, Vala, +Verilog, VHDL, VimL, xHtml, XML, XSLT, YACC, YAML, z80, Zope page templates, +and zsh. See the [wiki][3] for details about the corresponding supported +checkers. Below is a screenshot showing the methods that Syntastic uses to display syntax errors. Note that, in practise, you will only have a subset of these methods @@ -75,9 +77,8 @@ First I'll show you how to install Tim Pope's [pathogen][1] so that it's easy to install syntastic. Do this in your terminal so that you get the `pathogen.vim` file and the directories it needs: ```sh -mkdir -p ~/.vim/autoload ~/.vim/bundle; \ -curl -so ~/.vim/autoload/pathogen.vim \ - https://raw.github.com/tpope/vim-pathogen/master/autoload/pathogen.vim +mkdir -p ~/.vim/autoload ~/.vim/bundle && \ +curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim ``` Next you *need* to add this to your `~/.vimrc`: ```vim @@ -91,7 +92,7 @@ execute pathogen#infect() You now have pathogen installed and can put syntastic into `~/.vim/bundle` like this: ```sh -cd ~/.vim/bundle +cd ~/.vim/bundle && \ git clone https://github.com/scrooloose/syntastic.git ``` Quit vim and start it back up to reload it, then type: @@ -111,6 +112,8 @@ If you get an error when you do this, then you probably didn't install ## 3\. FAQ + + __Q. I installed syntastic but it isn't reporting any errors...__ A. The most likely reason is that none of the syntax checkers that it requires @@ -125,6 +128,18 @@ error output for a syntax checker may have changed. In this case, make sure you have the latest version of the syntax checker installed. If it still fails then create an issue - or better yet, create a pull request. + + +__Q. The `python` checker complains about syntactically valid Python 3 constructs...__ + +A. Configure the `python` checker to call a Python 3 interpreter rather than +Python 2, e.g: +```vim +let g:syntastic_python_python_exec = '/path/to/python3' +``` + + + __Q. The `perl` checker has stopped working...__ A. The `perl` checker runs `perl -c` against your file, which in turn @@ -133,12 +148,24 @@ statements in your file (cf. [perlrun][10]). This is probably fine if you wrote the file yourself, but it's a security problem if you're checking third party files. Since there is currently no way to disable this behaviour while still producing useful results, the checker is now disabled by default. To -(re-)enable it, set `g:syntastic_enable_perl_checker` to 1 in your vimrc: +(re-)enable it, make sure the `g:syntastic_perl_checkers` list includes `perl`, +and set `g:syntastic_enable_perl_checker` to 1 in your vimrc: ```vim let g:syntastic_enable_perl_checker = 1 ``` -__Q. I run a checker and the location list is not updated...__ + + +__Q. What happened to the `rustc` checker?__ + +A. It has been included in the [Rust compiler package][12]. If you have +a recent version of the Rust compiler, the checker should be picked up +automatically by syntastic. + + + +__Q. I run a checker and the location list is not updated...__ +__Q. I run`:lopen` or `:lwindow` and the error window is empty...__ A. By default the location list is changed only when you run the `:Errors` command, in order to minimise conflicts with other plugins. If you want the @@ -148,6 +175,8 @@ your vimrc: let g:syntastic_always_populate_loc_list = 1 ``` + + __Q. How can I pass additional arguments to a checker?__ A. Almost all syntax checkers use the `makeprgBuild()` function. Those checkers @@ -162,6 +191,8 @@ let g:syntastic_ruby_mri_args = "--my --args --here" See `:help syntastic-checker-options` for more information. + + __Q. Syntastic supports several checkers for my filetype - how do I tell it which one(s) to use?__ @@ -181,8 +212,7 @@ To tell syntastic to use `pylint`, you would use this setting: let g:syntastic_python_checkers = ['pylint'] ``` -Some filetypes, like PHP, have style checkers as well as syntax checkers. These -can be chained together like this: +Checkers can be chained together like this: ```vim let g:syntastic_php_checkers = ['php', 'phpcs', 'phpmd'] ``` @@ -190,29 +220,73 @@ let g:syntastic_php_checkers = ['php', 'phpcs', 'phpmd'] This is telling syntastic to run the `php` checker first, and if no errors are found, run `phpcs`, and then `phpmd`. +You can also run checkers explicitly by calling `:SyntasticCheck `. + +e.g. to run `phpcs` and `phpmd`: +```vim +:SyntasticCheck phpcs phpmd +``` + +This works for any checkers available for the current filetype, even if they +aren't listed in `g:syntastic__checkers`. You can't run checkers for +"foreign" filetypes though (e.g. you can't run, say, a Python checker if the +filetype of the current file is `php`). + + + +__Q. What is the difference between syntax checkers and style checkers?__ + +A. The errors and warnings they produce are highlighted differently and can +be filtered by different rules, but otherwise the distinction is pretty much +arbitrary. There is an ongoing effort to keep things consistent, so you can +_generally_ expect messages produced by syntax checkers to be _mostly_ related +to syntax, and messages produced by style checkers to be _mostly_ about style. +But there can be no formal guarantee that, say, a style checker that runs into +a syntax error wouldn't die with a fatal message, nor that a syntax checker +wouldn't give you warnings against using some constructs as being bad practice. +There is also no guarantee that messages marked as "style" are less severe than +the ones marked as "syntax" (whatever that might mean). And there are even a +few Frankenstein checkers (for example `flake8` and `pylama`) that, by their +nature, produce both kinds of messages. Syntastic is not smart enough to be +able to sort out these things by itself. + +In fact it's more useful to look at this from the perspective of filtering +unwanted messages, rather than as an indicator of severity levels. The +distinction between syntax and style is orthogonal to the distinction between +errors and warnings, and thus you can turn off messages based on level, on +type, or both. + +e.g. To disable all style messages: +```vim +let g:syntastic_quiet_messages = { "type": "style" } +``` +See `:help syntastic_quiet_messages` for details. + + + +__Q. How can I display together the errors found by all checkers enabled for +the current file?__ + +A. Set `g:syntastic_aggregate_errors` to 1 in your vimrc: +```vim +let g:syntastic_aggregate_errors = 1 +``` + +See `:help syntastic-aggregating-errors` for more details. + + + __Q. How can I jump between the different errors without using the location list at the bottom of the window?__ -A. Vim provides several built in commands for this. See `:help :lnext` and +A. Vim provides several built-in commands for this. See `:help :lnext` and `:help :lprev`. If you use these commands a lot then you may want to add shortcut mappings to your vimrc, or install something like [unimpaired][2], which provides such mappings (among other things). -__Q. A syntax checker is giving me unwanted/strange style tips?__ - -A. Some filetypes (e.g. php) have style checkers as well as syntax -checkers. You can usually configure the options that are passed to the style -checkers, or just disable them. Take a look at the [wiki][3] to see what -options are available. - -Alternatively, you can use `g:syntastic_quiet_messages` to filter out the -messages you don't want to see. e.g. To turn off all style messages: -```vim -let g:syntastic_quiet_messages = { "type": "style" } -``` -See `:help syntastic_quiet_messages` for details. + __Q. The error window is closed automatically when I :quit the current buffer but not when I :bdelete it?__ @@ -231,8 +305,10 @@ cabbrev bd lclose\|bdelete ## 4\. Other resources The preferred place for posting suggestions, reporting bugs, and general -discussions related to syntastic is the [issue tracker at GitHub][4]. There -are also a [google group][5], and a [syntastic tag at StackOverflow][6]. +discussions related to syntastic is the [issue tracker at GitHub][4]. +A guide for writing syntax checkers can be found in the [wiki][11]. +There are also a dedicated [google group][5], and a +[syntastic tag at StackOverflow][6]. Syntastic aims to provide a common interface to syntax checkers for as many languages as possible. For particular languages, there are, of course, other @@ -248,5 +324,11 @@ a look at [jedi-vim][7], [python-mode][8], or [YouCompleteMe][9]. [6]: http://stackoverflow.com/questions/tagged/syntastic [7]: https://github.com/davidhalter/jedi-vim [8]: https://github.com/klen/python-mode -[9]: https://github.com/Valloric/YouCompleteMe +[9]: http://valloric.github.io/YouCompleteMe/ [10]: http://perldoc.perl.org/perlrun.html#*-c* +[11]: https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide +[12]: https://github.com/rust-lang/rust/ + + diff --git a/bundle/syntastic/autoload/syntastic/c.vim b/bundle/syntastic/autoload/syntastic/c.vim index 4bd79472..5dad1408 100644 --- a/bundle/syntastic/autoload/syntastic/c.vim +++ b/bundle/syntastic/autoload/syntastic/c.vim @@ -62,7 +62,7 @@ endfunction " }}}2 " GetLocList() for C-like compilers function! syntastic#c#GetLocList(filetype, subchecker, options) " {{{2 try - let flags = s:getCflags(a:filetype, a:subchecker, a:options) + let flags = s:_getCflags(a:filetype, a:subchecker, a:options) catch /\m\C^Syntastic: skip checks$/ return [] endtry @@ -70,9 +70,9 @@ function! syntastic#c#GetLocList(filetype, subchecker, options) " {{{2 let makeprg = syntastic#util#shexpand(g:syntastic_{a:filetype}_compiler) . \ ' ' . flags . ' ' . syntastic#util#shexpand('%') - let errorformat = s:getCheckerVar('g', a:filetype, a:subchecker, 'errorformat', a:options['errorformat']) + let errorformat = s:_getCheckerVar('g', a:filetype, a:subchecker, 'errorformat', a:options['errorformat']) - let postprocess = s:getCheckerVar('g', a:filetype, a:subchecker, 'remove_include_errors', 0) ? + let postprocess = s:_getCheckerVar('g', a:filetype, a:subchecker, 'remove_include_errors', 0) ? \ ['filterForeignErrors'] : [] " process makeprg @@ -87,29 +87,29 @@ endfunction " }}}2 " Private functions {{{1 " initialize c/cpp syntax checker handlers -function! s:init() " {{{2 +function! s:_init() " {{{2 let s:handlers = [] let s:cflags = {} - call s:regHandler('\m\', 'syntastic#c#checkPHP', []) - call s:regHandler('\m\', 'syntastic#c#checkPython', []) - call s:regHandler('\m\', 'syntastic#c#checkPHP', []) + call s:_regHandler('\m\', 'syntastic#c#checkPython', []) + call s:_regHandler('\m\= 0 +function! syntastic#log#oneTimeWarn(msg) " {{{2 + if index(s:one_time_notices_issued, a:msg) >= 0 return endif - call add(s:deprecation_notices_issued, a:msg) + call add(s:one_time_notices_issued, a:msg) call syntastic#log#warn(a:msg) endfunction " }}}2 +" @vimlint(EVL102, 1, l:OLD_VAR) +function! syntastic#log#deprecationWarn(old, new, ...) " {{{2 + if exists('g:syntastic_' . a:old) && !exists('g:syntastic_' . a:new) + let msg = 'variable g:syntastic_' . a:old . ' is deprecated, please use ' + + if a:0 + let OLD_VAR = g:syntastic_{a:old} + try + let NEW_VAR = eval(a:1) + let msg .= 'in its stead: let g:syntastic_' . a:new . ' = ' . string(NEW_VAR) + let g:syntastic_{a:new} = NEW_VAR + catch + let msg .= 'g:syntastic_' . a:new . ' instead' + endtry + else + let msg .= 'g:syntastic_' . a:new . ' instead' + let g:syntastic_{a:new} = g:syntastic_{a:old} + endif + + call syntastic#log#oneTimeWarn(msg) + endif +endfunction " }}}2 +" @vimlint(EVL102, 0, l:OLD_VAR) + function! syntastic#log#debug(level, msg, ...) " {{{2 if !s:isDebugEnabled(a:level) return endif - let leader = s:logTimestamp() - call s:logRedirect(1) + let leader = s:_logTimestamp() + call s:_logRedirect(1) if a:0 > 0 " filter out dictionary functions @@ -53,7 +77,7 @@ function! syntastic#log#debug(level, msg, ...) " {{{2 echomsg leader . a:msg endif - call s:logRedirect(0) + call s:_logRedirect(0) endfunction " }}}2 function! syntastic#log#debugShowOptions(level, names) " {{{2 @@ -61,15 +85,15 @@ function! syntastic#log#debugShowOptions(level, names) " {{{2 return endif - let leader = s:logTimestamp() - call s:logRedirect(1) + let leader = s:_logTimestamp() + call s:_logRedirect(1) let vlist = copy(type(a:names) == type("") ? [a:names] : a:names) if !empty(vlist) call map(vlist, "'&' . v:val . ' = ' . strtrans(string(eval('&' . v:val)))") echomsg leader . join(vlist, ', ') endif - call s:logRedirect(0) + call s:_logRedirect(0) endfunction " }}}2 function! syntastic#log#debugShowVariables(level, names) " {{{2 @@ -77,18 +101,18 @@ function! syntastic#log#debugShowVariables(level, names) " {{{2 return endif - let leader = s:logTimestamp() - call s:logRedirect(1) + let leader = s:_logTimestamp() + call s:_logRedirect(1) let vlist = type(a:names) == type("") ? [a:names] : a:names for name in vlist - let msg = s:formatVariable(name) + let msg = s:_formatVariable(name) if msg != '' echomsg leader . msg endif endfor - call s:logRedirect(0) + call s:_logRedirect(0) endfunction " }}}2 function! syntastic#log#debugDump(level) " {{{2 @@ -103,18 +127,19 @@ endfunction " }}}2 " Private functions {{{1 -function! s:isDebugEnabled_smart(level) " {{{2 +function! s:_isDebugEnabled_smart(level) " {{{2 return and(g:syntastic_debug, a:level) endfunction " }}}2 -function! s:isDebugEnabled_dumb(level) " {{{2 +function! s:_isDebugEnabled_dumb(level) " {{{2 " poor man's bit test for bit N, assuming a:level == 2**N return (g:syntastic_debug / a:level) % 2 endfunction " }}}2 -let s:isDebugEnabled = function(exists('*and') ? 's:isDebugEnabled_smart' : 's:isDebugEnabled_dumb') +let s:isDebugEnabled = function(exists('*and') ? 's:_isDebugEnabled_smart' : 's:_isDebugEnabled_dumb') +lockvar s:isDebugEnabled -function! s:logRedirect(on) " {{{2 +function! s:_logRedirect(on) " {{{2 if exists("g:syntastic_debug_file") if a:on try @@ -129,17 +154,11 @@ function! s:logRedirect(on) " {{{2 endif endfunction " }}}2 -function! s:logTimestamp_smart() " {{{2 +function! s:_logTimestamp() " {{{2 return 'syntastic: ' . split(reltimestr(reltime(g:syntastic_start)))[0] . ': ' endfunction " }}}2 -function! s:logTimestamp_dumb() " {{{2 - return 'syntastic: debug: ' -endfunction " }}}2 - -let s:logTimestamp = function(has('reltime') ? 's:logTimestamp_smart' : 's:logTimestamp_dumb') - -function! s:formatVariable(name) " {{{2 +function! s:_formatVariable(name) " {{{2 let vals = [] if exists('g:syntastic_' . a:name) call add(vals, 'g:syntastic_' . a:name . ' = ' . strtrans(string(g:syntastic_{a:name}))) diff --git a/bundle/syntastic/autoload/syntastic/postprocess.vim b/bundle/syntastic/autoload/syntastic/postprocess.vim index 1558f0f8..80fd7cf4 100644 --- a/bundle/syntastic/autoload/syntastic/postprocess.vim +++ b/bundle/syntastic/autoload/syntastic/postprocess.vim @@ -8,31 +8,14 @@ set cpo&vim " Public functions {{{1 -function! s:compareErrorItems(a, b) " {{{2 - if a:a['bufnr'] != a:b['bufnr'] - " group by files - return a:a['bufnr'] - a:b['bufnr'] - elseif a:a['lnum'] != a:b['lnum'] - return a:a['lnum'] - a:b['lnum'] - elseif a:a['type'] !=? a:b['type'] - " errors take precedence over warnings - return a:a['type'] ==? 'e' ? -1 : 1 - else - return get(a:a, 'col', 0) - get(a:b, 'col', 0) - endif -endfunction " }}}2 - -" natural sort -function! syntastic#postprocess#sort(errors) " {{{2 - return sort(copy(a:errors), 's:compareErrorItems') -endfunction " }}}2 - " merge consecutive blanks function! syntastic#postprocess#compressWhitespace(errors) " {{{2 for e in a:errors let e['text'] = substitute(e['text'], "\001", '', 'g') let e['text'] = substitute(e['text'], '\n', ' ', 'g') let e['text'] = substitute(e['text'], '\m\s\{2,}', ' ', 'g') + let e['text'] = substitute(e['text'], '\m^\s\+', '', '') + let e['text'] = substitute(e['text'], '\m\s\+$', '', '') endfor return a:errors @@ -63,6 +46,25 @@ function! syntastic#postprocess#filterForeignErrors(errors) " {{{2 return filter(copy(a:errors), 'get(v:val, "bufnr") == ' . bufnr('')) endfunction " }}}2 +" make sure line numbers are not past end of buffers +" XXX: this loads all referenced buffers in memory +function! syntastic#postprocess#guards(errors) " {{{2 + let buffers = syntastic#util#unique(map(filter(copy(a:errors), 'v:val["valid"]'), 'str2nr(v:val["bufnr"])')) + + let guards = {} + for b in buffers + let guards[b] = len(getbufline(b, 1, '$')) + endfor + + for e in a:errors + if e['valid'] && e['lnum'] > guards[e['bufnr']] + let e['lnum'] = guards[e['bufnr']] + endif + endfor + + return a:errors +endfunction " }}}2 + " }}}1 let &cpo = s:save_cpo diff --git a/bundle/syntastic/autoload/syntastic/preprocess.vim b/bundle/syntastic/autoload/syntastic/preprocess.vim index f1af35be..56998d26 100644 --- a/bundle/syntastic/autoload/syntastic/preprocess.vim +++ b/bundle/syntastic/autoload/syntastic/preprocess.vim @@ -8,6 +8,26 @@ set cpo&vim " Public functions {{{1 +function! syntastic#preprocess#cabal(errors) " {{{2 + let out = [] + let star = 0 + for err in a:errors + if star + if err == '' + let star = 0 + else + let out[-1] .= ' ' . err + endif + else + call add(out, err) + if err =~ '\m^*\s' + let star = 1 + endif + endif + endfor + return out +endfunction " }}}2 + function! syntastic#preprocess#checkstyle(errors) " {{{2 let out = [] let fname = expand('%') @@ -56,6 +76,49 @@ function! syntastic#preprocess#perl(errors) " {{{2 return syntastic#util#unique(out) endfunction " }}}2 +function! syntastic#preprocess#rparse(errors) " {{{2 + let errlist = copy(a:errors) + + " remove uninteresting lines and handle continuations + let i = 0 + while i < len(errlist) + if i > 0 && errlist[i][:1] == ' ' && errlist[i] !~ '\m\s\+\^$' + let errlist[i-1] .= errlist[i][1:] + call remove(errlist, i) + elseif errlist[i] !~ '\m^\(Lint:\|Lint checking:\|Error in\) ' + call remove(errlist, i) + else + let i += 1 + endif + endwhile + + let out = [] + let fname = '' + for e in errlist + if match(e, '\m^Lint: ') == 0 + let parts = matchlist(e, '\m^Lint: \(.*\): found on lines \([0-9, ]\+\)\(+\(\d\+\) more\)\=') + if len(parts) >= 3 + for line in split(parts[2], '\m,\s*') + call add(out, 'E:' . fname . ':' . line . ': ' . parts[1]) + endfor + endif + if len(parts) >= 5 && parts[4] != '' + call add(out, 'E:' . fname . ':0: ' . parts[1] . ' - ' . parts[4] . ' messages not shown') + endif + elseif match(e, '\m^Lint checking: ') == 0 + let fname = matchstr(e, '\m^Lint checking: \zs.*') + elseif match(e, '\m^Error in ') == 0 + call add(out, substitute(e, '\m^Error in .\+ : .\+\ze:\d\+:\d\+: ', 'E:' . fname, '')) + endif + endfor + + return out +endfunction " }}}2 + +function! syntastic#preprocess#tslint(errors) " {{{2 + return map(copy(a:errors), 'substitute(v:val, ''\m^\(([^)]\+)\)\s\(.\+\)$'', ''\2 \1'', "")') +endfunction " }}}2 + function! syntastic#preprocess#validator(errors) " {{{2 let out = [] for e in a:errors diff --git a/bundle/syntastic/autoload/syntastic/util.vim b/bundle/syntastic/autoload/syntastic/util.vim index d1dc2618..51831b47 100644 --- a/bundle/syntastic/autoload/syntastic/util.vim +++ b/bundle/syntastic/autoload/syntastic/util.vim @@ -35,12 +35,12 @@ endfunction " }}}2 " "{'exe': '/usr/bin/perl', 'args': ['-f', '-bar']} function! syntastic#util#parseShebang() " {{{2 - for lnum in range(1,5) + for lnum in range(1, 5) let line = getline(lnum) - if line =~ '^#!' - let exe = matchstr(line, '\m^#!\s*\zs[^ \t]*') - let args = split(matchstr(line, '\m^#!\s*[^ \t]*\zs.*')) + let line = substitute(line, '\v^#!\s*(\S+/env(\s+-\S+)*\s+)?', '', '') + let exe = matchstr(line, '\m^\S*\ze') + let args = split(matchstr(line, '\m^\S*\zs.*')) return { 'exe': exe, 'args': args } endif endfor @@ -58,7 +58,7 @@ endfunction " }}}2 " Parse a version string. Return an array of version components. function! syntastic#util#parseVersion(version) " {{{2 - return split(matchstr( a:version, '\v^\D*\zs\d+(\.\d+)+\ze' ), '\m\.') + return map(split(matchstr( a:version, '\v^\D*\zs\d+(\.\d+)+\ze' ), '\m\.'), 'str2nr(v:val)') endfunction " }}}2 " Run 'command' in a shell and parse output as a version string. @@ -74,20 +74,37 @@ endfunction " }}}2 " " See http://semver.org for info about version numbers. function! syntastic#util#versionIsAtLeast(installed, required) " {{{2 - for idx in range(max([len(a:installed), len(a:required)])) - let installed_element = get(a:installed, idx, 0) - let required_element = get(a:required, idx, 0) - if installed_element != required_element - return installed_element > required_element + return syntastic#util#compareLexi(a:installed, a:required) >= 0 +endfunction " }}}2 + +" Almost lexicographic comparison of two lists of integers. :) If lists +" have different lengths, the "missing" elements are assumed to be 0. +function! syntastic#util#compareLexi(a, b) " {{{2 + for idx in range(max([len(a:a), len(a:b)])) + let a_element = str2nr(get(a:a, idx, 0)) + let b_element = str2nr(get(a:b, idx, 0)) + if a_element != b_element + return a_element > b_element ? 1 : -1 endif endfor " Everything matched, so it is at least the required version. - return 1 + return 0 endfunction " }}}2 " strwidth() was added in Vim 7.3; if it doesn't exist, we use strlen() " and hope for the best :) let s:width = function(exists('*strwidth') ? 'strwidth' : 'strlen') +lockvar s:width + +function! syntastic#util#screenWidth(str, tabstop) " {{{2 + let chunks = split(a:str, "\t", 1) + let width = s:width(chunks[-1]) + for c in chunks[:-2] + let cwidth = s:width(c) + let width += cwidth + a:tabstop - cwidth % a:tabstop + endfor + return width +endfunction " }}}2 "print as much of a:msg as possible without "Press Enter" prompt appearing function! syntastic#util#wideMsg(msg) " {{{2 @@ -101,7 +118,7 @@ function! syntastic#util#wideMsg(msg) " {{{2 "convert tabs to spaces so that the tabs count towards the window "width as the proper amount of characters let chunks = split(msg, "\t", 1) - let msg = join(map(chunks[:-2], 'v:val . repeat(" ", &ts - s:width(v:val) % &ts)'), '') . chunks[-1] + let msg = join(map(chunks[:-2], 'v:val . repeat(" ", &tabstop - s:width(v:val) % &tabstop)'), '') . chunks[-1] let msg = strpart(msg, 0, &columns - 1) set noruler noshowcmd @@ -208,7 +225,7 @@ function! syntastic#util#redraw(full) " {{{2 endfunction " }}}2 function! syntastic#util#dictFilter(errors, filter) " {{{2 - let rules = s:translateFilter(a:filter) + let rules = s:_translateFilter(a:filter) " call syntastic#log#debug(g:SyntasticDebugFilters, "applying filter:", rules) try call filter(a:errors, rules) @@ -218,17 +235,24 @@ function! syntastic#util#dictFilter(errors, filter) " {{{2 endtry endfunction " }}}2 +" Return a [high, low] list of integers, representing the time +" (hopefully high resolution) since program start +" TODO: This assumes reltime() returns a list of integers. +function! syntastic#util#stamp() " {{{2 + return reltime(g:syntastic_start) +endfunction " }}}2 + " }}}1 " Private functions {{{1 -function! s:translateFilter(filters) " {{{2 +function! s:_translateFilter(filters) " {{{2 let conditions = [] for k in keys(a:filters) if type(a:filters[k]) == type([]) - call extend(conditions, map(copy(a:filters[k]), 's:translateElement(k, v:val)')) + call extend(conditions, map(copy(a:filters[k]), 's:_translateElement(k, v:val)')) else - call add(conditions, s:translateElement(k, a:filters[k])) + call add(conditions, s:_translateElement(k, a:filters[k])) endif endfor @@ -238,7 +262,7 @@ function! s:translateFilter(filters) " {{{2 return len(conditions) == 1 ? conditions[0] : join(map(conditions, '"(" . v:val . ")"'), ' && ') endfunction " }}}2 -function! s:translateElement(key, term) " {{{2 +function! s:_translateElement(key, term) " {{{2 if a:key ==? 'level' let ret = 'v:val["type"] !=? ' . string(a:term[0]) elseif a:key ==? 'type' diff --git a/bundle/syntastic/doc/syntastic.txt b/bundle/syntastic/doc/syntastic.txt index 86a5ed2b..8f09e818 100644 --- a/bundle/syntastic/doc/syntastic.txt +++ b/bundle/syntastic/doc/syntastic.txt @@ -36,9 +36,14 @@ CONTENTS *syntastic-contents* 5.3.Configuring specific checkers..........|syntastic-config-makeprg| 6.Notes........................................|syntastic-notes| 6.1.Handling of composite filetypes........|syntastic-composite| - 6.2.Interaction with python-mode...........|syntastic-pymode| - 6.3.Interaction with the fish shell........|syntastic-fish| - 6.4.Using syntastic with the fizsh shell...|syntastic-fizsh| + 6.2.Editing files over network.............|syntastic-netrw| + 6.3.Interaction with python-mode...........|syntastic-pymode| + 6.4.Interaction with YouCompleteMe.........|syntastic-ycm| + 6.5.Interaction with the fish shell........|syntastic-fish| + 6.6.Interaction with PowerShell............|syntastic-powershell| + 6.7.Using syntastic with the fizsh shell...|syntastic-fizsh| + 6.8.Interaction with Eclim.................|syntastic-eclim| + 6.9.Interaction with vim-virtualenv........|syntastic-vim-virtualenv| 7.About........................................|syntastic-about| 8.License......................................|syntastic-license| @@ -62,7 +67,7 @@ Take a look at the wiki for a list of supported filetypes and checkers: https://github.com/scrooloose/syntastic/wiki/Syntax-Checkers Note: This doc only deals with using syntastic. To learn how to write syntax -checker integrations, see the guide on the github wiki: +checker integrations, see the guide on the GitHub wiki: https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide @@ -73,16 +78,17 @@ Syntastic comes preconfigured with a default list of enabled checkers per filetype. This list is kept reasonably short to prevent slowing down Vim or trying to use conflicting checkers. -You can see the list checkers available for the current filetype with the +You can see the list of checkers available for the current filetype with the |:SyntasticInfo| command. -If you want to override the configured list of checkers for a filetype then -see |syntastic-checker-options| for details. You can also change the arguments -passed to a specific checker as well. +You probably want to override the configured list of checkers for the +filetypes you use, and also change the arguments passed to specific checkers +to suit your needs. See |syntastic-checker-options| for details. -Use |:SyntasticCheck| to manually check right now. Use |:SyntasticToggleMode| -to switch between active (checking on writting the buffer) and passive (manual) -checking. +Use |:SyntasticCheck| to manually check right now. Use |:Errors| to open the +|location-list| window, and |:lclose| to close it. You can clear the error +list with |:SyntasticReset|, and you can use |:SyntasticToggleMode| to switch +between active (checking on writing the buffer) and passive (manual) checking. ============================================================================== 2. Functionality provided *syntastic-functionality* @@ -91,7 +97,7 @@ Syntax checking can be done automatically or on demand (see |'syntastic_mode_map'| and |:SyntasticToggleMode| for configuring this). When syntax checking is done, the features below can be used to notify the -user of errors. See |syntastic-options| for how to configure and +user of errors. See |syntastic-global-options| for how to configure and activate/deactivate these features. * A statusline flag @@ -150,13 +156,21 @@ Example: > highlight SyntasticErrorLine guibg=#2f0000 < ------------------------------------------------------------------------------ -2.3. The error window *:Errors* *syntastic-error-window* +2.3. The error window *syntastic-error-window* -You can use the :Errors command to display the errors for the current buffer +You can use the |:Errors| command to display the errors for the current buffer in the |location-list|. -Note that when you use :Errors, the current location list is overwritten with -Syntastic's own location list. +Note that when you use |:Errors|, the current location list is overwritten +with Syntastic's own location list. + +By default syntastic doesn't fill the |location-list| with the errors found by +the checkers, in order to reduce clashes with other plugins. Consequently, if +you run |:lopen| or |:lwindow| rather than |:Errors| to open the error window you +wouldn't see syntastic's list of errors. If you insist on using |:lopen| or +|:lwindow| you should either run |:SyntasticSetLoclist| after running the checks, +or set |syntastic_always_populate_loc_list| which tells syntastic to update the +|location-list| automatically. ------------------------------------------------------------------------------ 2.4. Error highlighting *syntastic-highlighting* @@ -167,6 +181,8 @@ and the SpellCap group is used for warnings. If you wish to customize the colors for highlighting you can use the following groups: SyntasticError - Links to 'SpellBad' by default SyntasticWarning - Links to 'SpellCap' by default + SyntasticStyleError - Links to SyntasticError by default + SyntasticStyleWarning - Links to SyntasticWarning by default Example: > highlight SyntasticError guibg=#2f0000 @@ -186,7 +202,12 @@ If |'syntastic_aggregate_errors'| is set, syntastic runs all checkers that apply (still cf. |syntastic-filetype-checkers|), then aggregates errors found by all checkers in a single list, and notifies you. In this mode each error message is labeled with the name of the checker that generated it, but you can -disable these labels by unsetting '|syntastic_id_checkers|'. +disable generation of these labels by turning off '|syntastic_id_checkers|'. + +If |'syntastic_sort_aggregated_errors'| is set (which is the default), messages +in the aggregated list are grouped by file, then sorted by line number, then +type, then column number. Otherwise messages produced by the same checker are +grouped together. ------------------------------------------------------------------------------ 2.6 Filtering errors *syntastic-filtering-errors* @@ -200,11 +221,14 @@ See also: |'syntastic___quiet_messages'|. ============================================================================== 3. Commands *syntastic-commands* -:Errors *:SyntasticErrors* +:Errors *:Errors* When errors have been detected, use this command to pop up the |location-list| and display the error messages. +Please note that the |:Errors| command overwrites the current location list with +syntastic's own location list. + :SyntasticToggleMode *:SyntasticToggleMode* Toggles syntastic between active and passive mode. See |'syntastic_mode_map'| @@ -227,7 +251,7 @@ the order specified. The rules of |syntastic_aggregate_errors| still apply. Example: > :SyntasticCheck flake8 pylint < -:SyntasticInfo *:SyntasticInfo* +:SyntasticInfo *:SyntasticInfo* The command takes an optional argument, and outputs information about the checkers available for the filetype named by said argument, or for the current @@ -278,12 +302,35 @@ a file with a composite filetype), it might not be immediately obvious which checker has produced a given error message. This variable instructs syntastic to label error messages with the names of the checkers that created them. > let g:syntastic_id_checkers = 0 +< + *'syntastic_sort_aggregated_errors'* +Default: 1 +By default, when results from multiple checkers are aggregated in a single +error list (that is either when |syntastic_aggregate_errors| is enabled, or +when checking a file with a composite filetype), errors are grouped by file, +then sorted by line number, then grouped by type (namely errors take precedence +over warnings), then they are sorted by column number. If you want to leave +messages grouped by checker output, set this variable to 0. > + let g:syntastic_sort_aggregated_errors = 0 < *'syntastic_echo_current_error'* Default: 1 -If enabled, syntastic will echo the error associated with the current line to -the command window. If multiple errors are found, the first will be used. > +If enabled, syntastic will echo current error to the command window. If +multiple errors are found on the same line, |syntastic_cursor_columns| is used +to decide which one is shown. > let g:syntastic_echo_current_error = 1 +< + *'syntastic_cursor_columns'* +Default: 1 +This option controls which errors are echoed to the command window if +|syntastic_echo_current_error| is set and multiple errors are found on the same +line. When the option is enabled, the first error corresponding to the current +column is show. Otherwise, the first error on the current line is echoed, +regardless of the cursor position on the current line. + +When dealing with very large lists of errors, disabling this option can speed +up navigation significantly: > + let g:syntastic_cursor_column = 0 < *'syntastic_enable_signs'* Default: 1 @@ -301,8 +348,8 @@ error symbols can be customized: syntastic_style_warning_symbol - For style warnings, defaults to 'S>' Example: > - let g:syntastic_error_symbol = '✗' - let g:syntastic_warning_symbol = '⚠' + let g:syntastic_error_symbol = "✗" + let g:syntastic_warning_symbol = "⚠" < *'syntastic_enable_balloons'* Default: 1 @@ -374,47 +421,45 @@ Default: {} Use this option to map non-standard filetypes to standard ones. Corresponding checkers are mapped accordingly, which allows syntastic to check files with non-standard filetypes: > - let g:syntastic_filetype_map = { 'latex': 'tex', - \ 'gentoo-metadata': 'xml' } + let g:syntastic_filetype_map = { "latex": "tex", + \ "gentoo-metadata": "xml" } < Composite filetypes can also be mapped to simple types, which disables the default behaviour of running both checkers against the input file: > - let g:syntastic_filetype_map = { 'handlebars.html': 'handlebars' } + let g:syntastic_filetype_map = { "handlebars.html": "handlebars" } < *'syntastic_mode_map'* Default: { "mode": "active", "active_filetypes": [], "passive_filetypes": [] } - Use this option to fine tune when automatic syntax checking is done (or not done). The option should be set to something like: > - let g:syntastic_mode_map = { 'mode': 'active', - \ 'active_filetypes': ['ruby', 'php'], - \ 'passive_filetypes': ['puppet'] } + let g:syntastic_mode_map = { "mode": "active", + \ "active_filetypes": ["ruby", "php"], + \ "passive_filetypes": ["puppet"] } < -"mode" can be mapped to one of two values - "active" or "passive". When set to -active, syntastic does automatic checking whenever a buffer is saved or +"mode" can be mapped to one of two values - "active" or "passive". When set +to "active", syntastic does automatic checking whenever a buffer is saved or initially opened. When set to "passive" syntastic only checks when the user calls |:SyntasticCheck|. The exceptions to these rules are defined with "active_filetypes" and -"passive_filetypes". In passive mode, automatic checks are still done -for all filetypes in the "active_filetypes" array. In active mode, -automatic checks are not done for any filetypes in the -"passive_filetypes" array. +"passive_filetypes". In passive mode, automatic checks are still done for +filetypes in the "active_filetypes" array (and "passive_filetypes" is +ignored). In active mode, automatic checks are not done for any filetypes in +the "passive_filetypes" array ("active_filetypes" is ignored). + +If any of "mode", "active_filetypes", or "passive_filetypes" are left +unspecified, they default to values above. At runtime, the |:SyntasticToggleMode| command can be used to switch between -active and passive mode. - -If any of "mode", "active_filetypes", or "passive_filetypes" are not specified -then they will default to their default value as above. +active and passive modes. *'syntastic_quiet_messages'* Default: {} - Use this option to filter out some of the messages produced by checkers. The option should be set to something like: > let g:syntastic_quiet_messages = { "level": "warnings", @@ -451,7 +496,7 @@ Since filter elements with values [] or '' are ignored, you can disable global filters for particular checkers, by setting the values of the corresponding elements in |'syntastic___quiet_messages'| to [] or ''. For example, the following setting will silence all warnings, except for the -ones produced by 'pylint': > +ones produced by "pylint": > let g:syntastic_quiet_messages = { "level": "warnings" } let g:syntastic_python_pylint_quiet_messages = { "level" : [] } < @@ -483,6 +528,12 @@ statusline: > < If the buffer had 2 warnings, starting on line 5 then this would appear: > [Warn: 5 #2] +< + *'b:syntastic_skip_checks'* +Default: unset +Only the local form |'b:syntastic_skip_checks'| is used. When set to a true +value, no checks are run against the corresponding buffer. Example: > + let b:syntastic_skip_checks = 1 < *'syntastic_full_redraws'* Default: 0 in GUI Vim and MacVim, 1 otherwise @@ -491,6 +542,13 @@ Changing it can in principle make screen redraws smoother, but it can also cause screen to flicker, or cause ghost characters. Leaving it to the default should be safe. + *'syntastic_exit_checks'* +Default: 0 when running under "cmd.exe" on Windows, 1 otherwise +Syntastic attempts to catch abnormal termination conditions from checkers by +looking at their exit codes. The "cmd.exe" shell on Windows make these checks +meaningless, by returning 1 to Vim when the checkers exit with non-zero codes. +The above variable can be used to disable exit code checks in syntastic. + *'syntastic_debug'* Default: 0 Set this to the sum of one or more of the following flags to enable @@ -520,7 +578,7 @@ List of filetypes handled by checkers external to syntastic. If you have a Vim plugin that adds a checker for syntastic, and if the said checker deals with a filetype that is unknown to syntastic, you might consider adding that filetype to this list: > - let g:syntastic_extra_filetypes = [ 'make', 'gitcommit' ] + let g:syntastic_extra_filetypes = [ "make", "gitcommit" ] < This will allow |:SyntasticInfo| to do proper tab completion for the new filetypes. @@ -534,14 +592,14 @@ filetypes. *'g:syntastic__checkers'* You can tell syntastic which checkers to run for a given filetype by setting a variable 'g:syntastic__checkers' to a list of checkers, e.g. > - let g:syntastic_php_checkers = ['php', 'phpcs', 'phpmd'] + let g:syntastic_php_checkers = ["php", "phpcs", "phpmd"] < *'b:syntastic_checkers'* There is also a per-buffer version of this setting, 'b:syntastic_checkers'. When set, it takes precedence over |'g:syntastic__checkers'|. You can use this in an autocmd to configure specific checkers for particular paths: > - autocmd FileType python if stridx(expand('%:p'), '/some/path/') == 0 | - \ let b:syntastic_checkers = ['pylint'] | endif + autocmd FileType python if stridx(expand("%:p"), "/some/path/") == 0 | + \ let b:syntastic_checkers = ["pylint"] | endif < If neither |'g:syntastic__checkers'| nor |'b:syntastic_checkers'| is set, a default list of checker is used. Beware however that this list @@ -557,48 +615,61 @@ Use |:SyntasticInfo| to see which checkers are available for a given filetype. ------------------------------------------------------------------------------ 5.2 Choosing the executable *syntastic-config-exec* - *'syntastic___exec'* -The executable used by a checker is normally defined automatically, when the -checkers is registered. You can however override it by setting the variable -'g:syntastic___exec': > + *'syntastic___exec'* +The executable run by a checker is normally defined automatically, when the +checker is registered. You can however override it, by setting the variable +'g:syntastic___exec': > let g:syntastic_ruby_mri_exec = '~/bin/ruby2' < +This variable has a local version, 'b:syntastic___exec', +which takes precedence over the global one in the corresponding buffer. + + *'b:syntastic__exec'* +And there is also a local variable named 'b:syntastic__exec', which +takes precedence over both 'b:syntastic___exec' and +'g:syntastic___exec' in the buffers where it is defined. + ------------------------------------------------------------------------------ 5.3 Configuring specific checkers *syntastic-config-makeprg* Most checkers use the 'makeprgBuild()' function and provide many options by default - in fact you can customise every part of the command that gets called. - *'syntastic___