1
0
Fork 0
mirror of synced 2024-11-22 16:55:34 -05:00

Updated vimrc

This commit is contained in:
amix 2015-07-13 11:22:46 +01:00
parent 9a2843c2a5
commit d7752b59ae
301 changed files with 4699 additions and 7969 deletions

6
.gitmodules vendored
View file

@ -1,6 +0,0 @@
[submodule "sources_non_forked/vim-gitgutter"]
path = sources_non_forked/vim-gitgutter
url = git://github.com/airblade/vim-gitgutter.git
[submodule "sources_non_forked/gruvbox"]
path = sources_non_forked/gruvbox
url = git@github.com:morhetz/gruvbox.git

View file

@ -69,6 +69,7 @@ I recommend reading the docs of these plugins to understand them better. Each of
* [bufexplorer.zip](https://github.com/vim-scripts/bufexplorer.zip): Buffer Explorer / Browser. This plugin can be opened with `<leader+o>` * [bufexplorer.zip](https://github.com/vim-scripts/bufexplorer.zip): Buffer Explorer / Browser. This plugin can be opened with `<leader+o>`
* [NERD Tree](https://github.com/scrooloose/nerdtree): A tree explorer plugin for vim * [NERD Tree](https://github.com/scrooloose/nerdtree): A tree explorer plugin for vim
* [ack.vim](https://github.com/mileszs/ack.vim): Vim plugin for the Perl module / CLI script 'ack' * [ack.vim](https://github.com/mileszs/ack.vim): Vim plugin for the Perl module / CLI script 'ack'
* [ag.vim](https://github.com/rking/ag.vim): A much faster Ack
* [ctrlp.vim](https://github.com/kien/ctrlp.vim): Fuzzy file, buffer, mru and tag finder. In my config it's mapped to `<Ctrl+F>`, because `<Ctrl+P>` is used by YankRing * [ctrlp.vim](https://github.com/kien/ctrlp.vim): Fuzzy file, buffer, mru and tag finder. In my config it's mapped to `<Ctrl+F>`, because `<Ctrl+P>` is used by YankRing
* [mru.vim](https://github.com/vim-scripts/mru.vim): Plugin to manage Most Recently Used (MRU) files. Includes my own fork which adds syntax highlighting to MRU. This plugin can be opened with `<leader+f>` * [mru.vim](https://github.com/vim-scripts/mru.vim): Plugin to manage Most Recently Used (MRU) files. Includes my own fork which adds syntax highlighting to MRU. This plugin can be opened with `<leader+f>`
* [open_file_under_cursor.vim](https://github.com/amix/open_file_under_cursor.vim): Open file under cursor when pressing `gf` * [open_file_under_cursor.vim](https://github.com/amix/open_file_under_cursor.vim): Open file under cursor when pressing `gf`

View file

@ -4,7 +4,7 @@ Run your favorite search tool from Vim, with an enhanced results list.
This plugin was designed as a Vim frontend for the Perl module [App::Ack]. Ack This plugin was designed as a Vim frontend for the Perl module [App::Ack]. Ack
can be used as a replacement for 99% of the uses of _grep_. The plugin allows can be used as a replacement for 99% of the uses of _grep_. The plugin allows
you to run ack from vim, and shows the results in a split window. you to run ack from Vim, and shows the results in a split window.
But here's a little secret for the Vim-seasoned: it's just a light wrapper for But here's a little secret for the Vim-seasoned: it's just a light wrapper for
Vim's [grepprg] and the [quickfix] window for match results. This makes it easy Vim's [grepprg] and the [quickfix] window for match results. This makes it easy
@ -28,13 +28,21 @@ It is recommended to use one of the popular plugin managers for Vim. There are
many and you probably already have a preferred one, but a few examples for your many and you probably already have a preferred one, but a few examples for your
copy-and-paste convenience: copy-and-paste convenience:
#### Pathogen
$ git clone https://github.com/mileszs/ack.vim.git ~/.vim/bundle/ack.vim
#### Vundle #### Vundle
```vim
Plugin 'mileszs/ack.vim' Plugin 'mileszs/ack.vim'
```
#### NeoBundle #### NeoBundle
```vim
NeoBundle 'mileszs/ack.vim' NeoBundle 'mileszs/ack.vim'
```
#### Manual (not recommended) #### Manual (not recommended)
@ -127,6 +135,7 @@ Please see [the Github releases page][releases].
* Fix the quick help overlay clobbering the list mappings * Fix the quick help overlay clobbering the list mappings
* Fix `:AckFile` when using Dispatch * Fix `:AckFile` when using Dispatch
* Restore original `'makeprg'` and `'errorformat'` when using Dispatch * Restore original `'makeprg'` and `'errorformat'` when using Dispatch
* Arrow keys also work for auto-preview (#158)
* Internal refactoring and clean-up * Internal refactoring and clean-up
## Credits ## Credits

View file

@ -27,11 +27,7 @@ function! ack#Ack(cmd, args) "{{{
endif endif
" If no pattern is provided, search for the word under the cursor " If no pattern is provided, search for the word under the cursor
if empty(a:args) let l:grepargs = empty(a:args) ? expand("<cword>") : a:args . join(a:000, ' ')
let l:grepargs = expand("<cword>")
else
let l:grepargs = a:args . join(a:000, ' ')
end
" NOTE: we escape special chars, but not everything using shellescape to " NOTE: we escape special chars, but not everything using shellescape to
" allow for passing arguments etc " allow for passing arguments etc
@ -118,6 +114,8 @@ function! s:ApplyMappings() "{{{
if exists("g:ackpreview") " if auto preview in on, remap j and k keys if exists("g:ackpreview") " if auto preview in on, remap j and k keys
nnoremap <buffer> <silent> j j<CR><C-W><C-W> nnoremap <buffer> <silent> j j<CR><C-W><C-W>
nnoremap <buffer> <silent> k k<CR><C-W><C-W> nnoremap <buffer> <silent> k k<CR><C-W><C-W>
nmap <buffer> <silent> <Down> j
nmap <buffer> <silent> <Up> k
endif endif
endfunction "}}} endfunction "}}}
@ -157,17 +155,11 @@ function! s:QuickHelp() "{{{
execute 'edit' globpath(&rtp, 'doc/ack_quick_help.txt') execute 'edit' globpath(&rtp, 'doc/ack_quick_help.txt')
silent normal gg silent normal gg
setlocal buftype=nofile setlocal buftype=nofile bufhidden=hide nobuflisted
setlocal bufhidden=hide setlocal nomodifiable noswapfile
setlocal noswapfile
setlocal nobuflisted
setlocal nomodifiable
setlocal filetype=help setlocal filetype=help
setlocal nonumber setlocal nonumber norelativenumber nowrap
setlocal norelativenumber setlocal foldmethod=diff foldlevel=20
setlocal nowrap
setlocal foldlevel=20
setlocal foldmethod=diff
nnoremap <buffer> <silent> ? :q!<CR>:call ack#ShowResults()<CR> nnoremap <buffer> <silent> ? :q!<CR>:call ack#ShowResults()<CR>
endfunction "}}} endfunction "}}}

View file

@ -84,18 +84,23 @@ g:ackprg
Default for ubuntu: "ack-grep" Default for ubuntu: "ack-grep"
Default for other systems: "ack" Default for other systems: "ack"
Use this option to specify the ack command and its options Use this option to specify the search command and its default arguments.
Example: Example:
> >
let g:ackprg = "other-bin-ack" let g:ackprg = "ag --vimgrep"
< <
*g:ack_default_options* *g:ack_default_options*
g:ack_default_options g:ack_default_options
Default: " -s -H --nocolor --nogroup --column" Default: " -s -H --nocolor --nogroup --column"
Use this option to specify the options used by ack Use this option to specify the default arguments given to `ack`. This is only
used if |g:ackprg| has not been customized from the default--if you are using
a custom search program instead of Ack, set your preferred options in
|g:ackprg|.
NOTE: This option may be deprecated in the future. ~
Example: Example:
> >

View file

@ -71,8 +71,8 @@ command! -bang -nargs=* -complete=file LAckAdd call ack#Ack('lgrepadd<bang
command! -bang -nargs=* -complete=file AckFile call ack#Ack('grep<bang> -g', <q-args>) command! -bang -nargs=* -complete=file AckFile call ack#Ack('grep<bang> -g', <q-args>)
command! -bang -nargs=* -complete=help AckHelp call ack#AckHelp('grep<bang>', <q-args>) command! -bang -nargs=* -complete=help AckHelp call ack#AckHelp('grep<bang>', <q-args>)
command! -bang -nargs=* -complete=help LAckHelp call ack#AckHelp('lgrep<bang>', <q-args>) command! -bang -nargs=* -complete=help LAckHelp call ack#AckHelp('lgrep<bang>', <q-args>)
command! -bang -nargs=* -complete=help AckWindow call ack#AckWindow('grep<bang>', <q-args>) command! -bang -nargs=* AckWindow call ack#AckWindow('grep<bang>', <q-args>)
command! -bang -nargs=* -complete=help LAckWindow call ack#AckWindow('lgrep<bang>', <q-args>) command! -bang -nargs=* LAckWindow call ack#AckWindow('lgrep<bang>', <q-args>)
let g:loaded_ack = 1 let g:loaded_ack = 1

2
sources_non_forked/ag.vim/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
tags
ag-vim.tgz

View file

@ -0,0 +1,76 @@
# ag.vim #
This plugin is a front for ag, A.K.A.
[the_silver_searcher](https://github.com/ggreer/the_silver_searcher). Ag can
be used as a replacement for 153% of the uses of `ack`. This plugin will allow
you to run ag from vim, and shows the results in a split window.
## Installation ##
See [the_silver_searcher's README](https://github.com/ggreer/the_silver_searcher#installing) for its installation instructions (if you haven't installed it already).
You have to first install [ag](https://github.com/ggreer/the_silver_searcher), itself. On Mac+Homebrew, Gentoo Linux, several others, there's package named `the_silver_searcher`, but if your OS/distro don't have one, the GitHub repo installs fine:
Vim has various ways of installing plugins, the standard way is in [the documentation](http://vimdoc.sourceforge.net/htmldoc/usr_05.html#plugin), but most people use a plugin to manage their plugins. If you don't already have a preferred plugin manager plugin, why not try one of the following?
- [vim-plug](https://github.com/junegunn/vim-plug#readme)
- [vim-pathogen](https://github.com/tpope/vim-pathogen#readme)
- [Vundle.vim](https://github.com/gmarik/Vundle.vim#readme)
- Or, if you don't use any sort of Vim plugin management:
```sh
cd ~/.vim/bundle && git clone https://github.com/rking/ag.vim ag && echo "set runtimepath^=~/.vim/bundle/ag" >> ~/.vimrc
```
Then open vim and rum `:helptags ~/.vim/bundle/ag/doc`.
### Configuration ###
You can specify a custom ag name and path in your .vimrc like so:
let g:agprg="<custom-ag-path-goes-here> --vimgrep"
You can configure ag.vim to always start searching from your project root
instead of the cwd
let g:ag_working_path_mode="r"
## Usage ##
:Ag [options] {pattern} [{directory}]
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 `:Ag`, `:AgAdd`, `:LAg`, and `:LAgAdd` respectively. (See `doc/ag.txt`, or install and `:h Ag` for more information.)
### Gotchas ###
Some characters have special meaning, and need to be escaped your search pattern. For instance, '#'. You have to escape it like this `:Ag '\\\#define foo'` to search for `#define foo`. (From [blueyed in issue #5](https://github.com/mileszs/ack.vim/issues/5).)
Sometimes `git grep` is even faster, though in my experience it's not noticeably so.
### Keyboard Shortcuts ###
In the quickfix window, you can use:
e to open file and close the quickfix window
o to open (same as enter)
go to preview file (open but maintain focus on ag.vim results)
t to open in new tab
T to open in new tab silently
h to open in horizontal split
H to open in horizontal split silently
v to open in vertical split
gv to open in vertical split silently
q to close the quickfix window
### Acknowledgements ###
This Vim plugin is derived (and by derived, I mean copied, almost entirely)
from [milesz's ack.vim](https://github.com/mileszs/ack.vim), which I also
recommend installing since you might be in a situation where you have ack but
not ag, and don't want to stop to install ag. Also, ack supports `--type`, and
a few other features.

View file

@ -0,0 +1,3 @@
task :tgz do
sh 'cd ..; tar czvf ag/ag-vim.tgz ag/{plugin,autoload,doc}'
end

View file

@ -0,0 +1,216 @@
" NOTE: You must, of course, install ag / the_silver_searcher
" FIXME: Delete deprecated options below on or after 15-7 (6 months from when they were changed) {{{
if exists("g:agprg")
let g:ag_prg = g:agprg
endif
if exists("g:aghighlight")
let g:ag_highlight = g:aghighlight
endif
if exists("g:agformat")
let g:ag_format = g:agformat
endif
" }}} FIXME: Delete the deprecated options above on or after 15-7 (6 months from when they were changed)
" Location of the ag utility
if !exists("g:ag_prg")
" --vimgrep (consistent output we can parse) is available from version 0.25.0+
if split(system("ag --version"), "[ \n\r\t]")[2] =~ '\d\+.\(\(2[5-9]\)\|\([3-9][0-9]\)\)\(.\d\+\)\?'
let g:ag_prg="ag --vimgrep"
else
" --noheading seems odd here, but see https://github.com/ggreer/the_silver_searcher/issues/361
let g:ag_prg="ag --column --nogroup --noheading"
endif
endif
if !exists("g:ag_apply_qmappings")
let g:ag_apply_qmappings=1
endif
if !exists("g:ag_apply_lmappings")
let g:ag_apply_lmappings=1
endif
if !exists("g:ag_qhandler")
let g:ag_qhandler="botright copen"
endif
if !exists("g:ag_lhandler")
let g:ag_lhandler="botright lopen"
endif
if !exists("g:ag_mapping_message")
let g:ag_mapping_message=1
endif
if !exists("g:ag_working_path_mode")
let g:ag_working_path_mode = 'c'
endif
function! ag#AgBuffer(cmd, args)
let l:bufs = filter(range(1, bufnr('$')), 'buflisted(v:val)')
let l:files = []
for buf in l:bufs
let l:file = fnamemodify(bufname(buf), ':p')
if !isdirectory(l:file)
call add(l:files, l:file)
endif
endfor
call ag#Ag(a:cmd, a:args . ' ' . join(l:files, ' '))
endfunction
function! ag#Ag(cmd, args)
let l:ag_executable = get(split(g:ag_prg, " "), 0)
" Ensure that `ag` is installed
if !executable(l:ag_executable)
echoe "Ag command '" . l:ag_executable . "' was not found. Is the silver searcher installed and on your $PATH?"
return
endif
" If no pattern is provided, search for the word under the cursor
if empty(a:args)
let l:grepargs = expand("<cword>")
else
let l:grepargs = a:args . join(a:000, ' ')
end
" Format, used to manage column jump
if a:cmd =~# '-g$'
let s:ag_format_backup=g:ag_format
let g:ag_format="%f"
elseif exists("s:ag_format_backup")
let g:ag_format=s:ag_format_backup
elseif !exists("g:ag_format")
let g:ag_format="%f:%l:%c:%m"
endif
let l:grepprg_bak=&grepprg
let l:grepformat_bak=&grepformat
let l:t_ti_bak=&t_ti
let l:t_te_bak=&t_te
try
let &grepprg=g:ag_prg
let &grepformat=g:ag_format
set t_ti=
set t_te=
if g:ag_working_path_mode ==? 'r' " Try to find the projectroot for current buffer
let l:cwd_back = getcwd()
let l:cwd = s:guessProjectRoot()
try
exe "lcd ".l:cwd
catch
echom 'Failed to change directory to:'.l:cwd
finally
silent! execute a:cmd . " " . escape(l:grepargs, '|')
exe "lcd ".l:cwd_back
endtry
else " Someone chose an undefined value or 'c' so we revert to the default
silent! execute a:cmd . " " . escape(l:grepargs, '|')
endif
finally
let &grepprg=l:grepprg_bak
let &grepformat=l:grepformat_bak
let &t_ti=l:t_ti_bak
let &t_te=l:t_te_bak
endtry
if a:cmd =~# '^l'
let l:match_count = len(getloclist(winnr()))
else
let l:match_count = len(getqflist())
endif
if a:cmd =~# '^l' && l:match_count
exe g:ag_lhandler
let l:apply_mappings = g:ag_apply_lmappings
let l:matches_window_prefix = 'l' " we're using the location list
elseif l:match_count
exe g:ag_qhandler
let l:apply_mappings = g:ag_apply_qmappings
let l:matches_window_prefix = 'c' " we're using the quickfix window
endif
" If highlighting is on, highlight the search keyword.
if exists('g:ag_highlight')
let @/ = matchstr(a:args, "\\v(-)\@<!(\<)\@<=\\w+|['\"]\\zs.{-}\\ze['\"]")
call feedkeys(":let &hlsearch=1 \| echo \<CR>", 'n')
end
redraw!
if l:match_count
if l:apply_mappings
nnoremap <silent> <buffer> h <C-W><CR><C-w>K
nnoremap <silent> <buffer> H <C-W><CR><C-w>K<C-w>b
nnoremap <silent> <buffer> o <CR>
nnoremap <silent> <buffer> t <C-w><CR><C-w>T
nnoremap <silent> <buffer> T <C-w><CR><C-w>TgT<C-W><C-W>
nnoremap <silent> <buffer> v <C-w><CR><C-w>H<C-W>b<C-W>J<C-W>t
exe 'nnoremap <silent> <buffer> e <CR><C-w><C-w>:' . l:matches_window_prefix .'close<CR>'
exe 'nnoremap <silent> <buffer> go <CR>:' . l:matches_window_prefix . 'open<CR>'
exe 'nnoremap <silent> <buffer> q :' . l:matches_window_prefix . 'close<CR>'
exe 'nnoremap <silent> <buffer> gv :let b:height=winheight(0)<CR><C-w><CR><C-w>H:' . l:matches_window_prefix . 'open<CR><C-w>J:exe printf(":normal %d\<lt>c-w>_", b:height)<CR>'
" Interpretation:
" :let b:height=winheight(0)<CR> Get the height of the quickfix/location list window
" <CR><C-w> Open the current item in a new split
" <C-w>H Slam the newly opened window against the left edge
" :copen<CR> -or- :lopen<CR> Open either the quickfix window or the location list (whichever we were using)
" <C-w>J Slam the quickfix/location list window against the bottom edge
" :exe printf(":normal %d\<lt>c-w>_", b:height)<CR> Restore the quickfix/location list window's height from before we opened the match
if g:ag_mapping_message && l:apply_mappings
echom "ag.vim keys: q=quit <cr>/e/t/h/v=enter/edit/tab/split/vsplit go/T/H/gv=preview versions of same"
endif
endif
else
echom 'No matches for "'.a:args.'"'
endif
endfunction
function! ag#AgFromSearch(cmd, args)
let search = getreg('/')
" translate vim regular expression to perl regular expression.
let search = substitute(search,'\(\\<\|\\>\)','\\b','g')
call ag#Ag(a:cmd, '"' . search .'" '. a:args)
endfunction
function! ag#GetDocLocations()
let dp = ''
for p in split(&runtimepath,',')
let p = p.'doc/'
if isdirectory(p)
let dp = p.'*.txt '.dp
endif
endfor
return dp
endfunction
function! ag#AgHelp(cmd,args)
let args = a:args.' '.ag#GetDocLocations()
call ag#Ag(a:cmd,args)
endfunction
function! s:guessProjectRoot()
let l:splitsearchdir = split(getcwd(), "/")
while len(l:splitsearchdir) > 2
let l:searchdir = '/'.join(l:splitsearchdir, '/').'/'
for l:marker in ['.rootdir', '.git', '.hg', '.svn', 'bzr', '_darcs', 'build.xml']
" found it! Return the dir
if filereadable(l:searchdir.l:marker) || isdirectory(l:searchdir.l:marker)
return l:searchdir
endif
endfor
let l:splitsearchdir = l:splitsearchdir[0:-2] " Splice the list to get rid of the tail directory
endwhile
" Nothing found, fallback to current working dir
return getcwd()
endfunction

View file

@ -0,0 +1,174 @@
*ag.txt* Plugin that integrates ag with Vim
==============================================================================
INTRODUCTION *ag*
This plugin is a front for the_silver_searcher: ag. Ag can be used as a
replacement for ack. This plugin will allow you to run ag from vim, and shows
the results in a split window.
:Ag[!] [options] {pattern} [{directory}] *:Ag*
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.
:AgBuffer[!] [options] {pattern} *:AgBuffer*
Search for {pattern} in all open buffers. Behaves just like the |:grep|
command, but will open the |Quickfix| window for you. If [!] is not given
the first error is jumped to.
Note: this will not find changes in modified buffers, since ag can only
find what is on disk! You can save buffers automatically when searching
with the 'autowrite' option. A buffer will be ignored if it is a directory
(an explorer, like netrw).
:AgAdd [options] {pattern} [{directory}] *:AgAdd*
Just like |:Ag|, but instead of making a new list, the matches are
appended to the current |quickfix| list.
:AgFromSearch [{directory}] *:AgFromSearch*
Just like |:Ag| but the pattern is from previous search.
:LAg [options] {pattern} [{directory}] *:LAg*
Just like |:Ag| but instead of the |quickfix| list, matches are placed in
the current |location-list|.
:LAgBuffer [options] {pattern} *:LAgBuffer*
Just like |:AgBuffer| but instead of the |quickfix| list, matches are
placed in the current |location-list|.
:LAgAdd [options] {pattern} [{directory}] *:LAgAdd*
Just like |:AgAdd| but instead of the |quickfix| list, matches are added
to the current |location-list|
:AgFile [options] {pattern} [{directory}] *:AgFile*
Search recursively in {directory} (which defaults to the current
directory) for filenames matching the {pattern}. Behaves just like the
|:grep| command, but will open the |Quickfix| window for you.
:AgHelp[!] [options] {pattern} *:AgHelp*
Search vim documentation files for the {pattern}. Behaves just like the
|:Ag| command, but searches only vim documentation .txt files
:LAgHelp [options] {pattern} *:LAgHelp*
Just like |:AgHelp| 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. <Enter> on a
line in this window will open the file, and place the cursor on the matching
line.
See http://geoff.greer.fm/2011/12/27/the-silver-searcher-better-than-ack/ for
more information.
==============================================================================
OPTIONS *ag-options*
*g:ag_prg*
The location of the Ag program, and any options you want passed to it before
searching. Default: "ag --vimgrep" (for parsable output). Example: >
let g:ag_prg="ag --vimgrep --smart-case"
<
Note: the `--vimgrep` option was added in Ag 0.25.0. If ag.vim detects that
you're using a lower version, the following default will be used instead: >
let g:ag_prg="ag --column --nogroup --noheading"
<
This works around inconsistent behaviors in earlier Ag versions, but it is
recommended that you upgrade if possible for a better experience. `--vimgrep`
supports multiple matches on the same line of text, for example.
For background, see: https://github.com/rking/ag.vim/pull/88
*g:ag_working_path_mode*
A mapping that describes where ag will be run. Default is the current working
directory. Specifying 'r' as the argument will tell it to run from the project
rootdirectory. For now any other mapping will result to the default.
Example:
let g:ag_working_path_mode='r'
*g:ag_highlight*
If 1, highlight the search terms after searching. Default: 0. Example: >
let g:ag_highlight=1
<
*g:ag_format*
Format to recognize the matches. See 'errorformat' for more info. Default:
"%f" when searching for files, "%f:%l:%c:%m" if not otherwise set. For
example, if your `g:ag_prg` is set to just "ag" (no column numbers in the
output, so when you jump to a match your cursor will be on the start of the
line): >
let g:ag_format="%f:%l:%m"
<
*g:ag_apply_lmappings*
Whether or not to add custom mappings to location list windows opened by this
plugin. Only applies if you're using the location list. Default 1. Example: >
let g:ag_apply_lmappings=0
<
*g:ag_apply_qmappings*
Whether or not to add custom mappings to quickfix windows opened by this
plugin. Only applies if you're using the error list. Default 1. Example: >
let g:ag_apply_qmappings=0
<
*g:ag_lhandler*
A custom command used to open the location list after it's populated.
Default: "botright lopen". You might want to set this to change where the
location list is opened, or what size it is. Example: >
let g:ag_lhandler="topleft lopen"
<
*g:ag_qhandler*
A custom command used to open the error list after it's populated. Default:
"botright copen". You might want to set this to change where the quickfix
window is opened, or what size it is. Example: >
let g:ag_qhandler="copen 20"
<
*g:ag_mapping_message*
Whether or not to show the message explaining the extra mappings that are
added to the results list this plugin populates. This message is not shown if
the mappings are not applied (see |g:ag_apply_qmappings| and
|g:ag_apply_lmappings| for more info. Default 1. Example: >
let g:ag_mapping_message=0
<
==============================================================================
MAPPINGS *ag-mappings*
The following keyboard shortcuts are available in the quickfix window:
e open file and close the quickfix window.
o open file (same as enter).
go preview file (open but maintain focus on ag.vim results).
t open in a new tab.
T open in new tab silently.
h open in horizontal split.
H open in horizontal split silently.
v open in vertical split.
gv open in vertical split silently.
q close the quickfix window.
vim:tw=78:fo=tcq2:ft=help:norl:

View file

@ -0,0 +1,11 @@
" NOTE: You must, of course, install ag / the_silver_searcher
command! -bang -nargs=* -complete=file Ag call ag#Ag('grep<bang>',<q-args>)
command! -bang -nargs=* -complete=file AgBuffer call ag#AgBuffer('grep<bang>',<q-args>)
command! -bang -nargs=* -complete=file AgAdd call ag#Ag('grepadd<bang>', <q-args>)
command! -bang -nargs=* -complete=file AgFromSearch call ag#AgFromSearch('grep<bang>', <q-args>)
command! -bang -nargs=* -complete=file LAg call ag#Ag('lgrep<bang>', <q-args>)
command! -bang -nargs=* -complete=file LAgBuffer call ag#AgBuffer('lgrep<bang>',<q-args>)
command! -bang -nargs=* -complete=file LAgAdd call ag#Ag('lgrepadd<bang>', <q-args>)
command! -bang -nargs=* -complete=file AgFile call ag#Ag('grep<bang> -g', <q-args>)
command! -bang -nargs=* -complete=help AgHelp call ag#AgHelp('grep<bang>',<q-args>)
command! -bang -nargs=* -complete=help LAgHelp call ag#AgHelp('lgrep<bang>',<q-args>)

View file

@ -24,6 +24,10 @@
let s:cpo_save = &cpo let s:cpo_save = &cpo
set cpo&vim set cpo&vim
function! s:const(val, min, max)
return min([max([a:val, a:min]), a:max])
endfunction
function! s:get_color(group, attr) function! s:get_color(group, attr)
return synIDattr(synIDtrans(hlID(a:group)), a:attr) return synIDattr(synIDtrans(hlID(a:group)), a:attr)
endfunction endfunction
@ -78,28 +82,27 @@ function! s:setup_pad(bufnr, vert, size, repel)
execute winnr('#') . 'wincmd w' execute winnr('#') . 'wincmd w'
endfunction endfunction
function! s:hmargin()
let nwidth = max([len(string(line('$'))) + 1, &numberwidth])
let width = t:goyo_width + (&number ? nwidth : 0)
return (&columns - width)
endfunction
function! s:resize_pads() function! s:resize_pads()
let t:goyo_width = max([2, t:goyo_width])
let t:goyo_margin_top = min([max([2, t:goyo_margin_top]), &lines / 2 - 1])
let t:goyo_margin_bottom = min([max([2, t:goyo_margin_bottom]), &lines / 2 - 1])
let hmargin = s:hmargin()
augroup goyop augroup goyop
autocmd! autocmd!
augroup END augroup END
call s:setup_pad(t:goyo_pads.t, 0, t:goyo_margin_top - 1, 'j')
call s:setup_pad(t:goyo_pads.b, 0, t:goyo_margin_bottom - 2, 'k')
call s:setup_pad(t:goyo_pads.l, 1, hmargin / 2 - 1, 'l')
call s:setup_pad(t:goyo_pads.r, 1, hmargin / 2 - 1, 'h')
let t:goyo_width = winwidth(0) let t:goyo_dim.width = s:const(t:goyo_dim.width, 2, &columns)
let t:goyo_dim.height = s:const(t:goyo_dim.height, 2, &lines)
let vmargin = max([0, (&lines - t:goyo_dim.height) / 2 - 1])
let yoff = s:const(t:goyo_dim.yoff, - vmargin, vmargin)
let top = vmargin + yoff
let bot = vmargin - yoff - 1
call s:setup_pad(t:goyo_pads.t, 0, top, 'j')
call s:setup_pad(t:goyo_pads.b, 0, bot, 'k')
let nwidth = max([len(string(line('$'))) + 1, &numberwidth])
let width = t:goyo_dim.width + (&number ? nwidth : 0)
let hmargin = max([0, (&columns - width) / 2 - 1])
let xoff = s:const(t:goyo_dim.xoff, - hmargin, hmargin)
call s:setup_pad(t:goyo_pads.l, 1, hmargin + xoff, 'l')
call s:setup_pad(t:goyo_pads.r, 1, hmargin - xoff, 'h')
endfunction endfunction
function! s:tranquilize() function! s:tranquilize()
@ -145,11 +148,11 @@ endfunction
function! s:maps_resize() function! s:maps_resize()
let commands = { let commands = {
\ '=': ':<c-u>let [t:goyo_width, t:goyo_margin_top, t:goyo_margin_bottom] = t:goyo_initial_dim <bar> call <sid>resize_pads()<cr>', \ '=': ':<c-u>let t:goyo_dim = <sid>parse_arg(t:goyo_dim_expr) <bar> call <sid>resize_pads()<cr>',
\ '>': ':<c-u>let t:goyo_width = winwidth(0) + 2 * v:count1 <bar> call <sid>resize_pads()<cr>', \ '>': ':<c-u>let t:goyo_dim.width = winwidth(0) + 2 * v:count1 <bar> call <sid>resize_pads()<cr>',
\ '<': ':<c-u>let t:goyo_width = winwidth(0) - 2 * v:count1 <bar> call <sid>resize_pads()<cr>', \ '<': ':<c-u>let t:goyo_dim.width = winwidth(0) - 2 * v:count1 <bar> call <sid>resize_pads()<cr>',
\ '+': ':<c-u>let t:goyo_margin_top -= v:count1 <bar> let t:goyo_margin_bottom -= v:count1 <bar> call <sid>resize_pads()<cr>', \ '+': ':<c-u>let t:goyo_dim.height += 2 * v:count1 <bar> call <sid>resize_pads()<cr>',
\ '-': ':<c-u>let t:goyo_margin_top += v:count1 <bar> let t:goyo_margin_bottom += v:count1 <bar> call <sid>resize_pads()<cr>' \ '-': ':<c-u>let t:goyo_dim.height -= 2 * v:count1 <bar> call <sid>resize_pads()<cr>'
\ } \ }
let mapped = filter(keys(commands), "empty(maparg(\"\<c-w>\".v:val, 'n'))") let mapped = filter(keys(commands), "empty(maparg(\"\<c-w>\".v:val, 'n'))")
for c in mapped for c in mapped
@ -158,7 +161,12 @@ function! s:maps_resize()
return mapped return mapped
endfunction endfunction
function! s:goyo_on(width) function! s:goyo_on(dim)
let dim = s:parse_arg(a:dim)
if empty(dim)
return
endif
let s:orig_tab = tabpagenr() let s:orig_tab = tabpagenr()
let settings = let settings =
\ { 'laststatus': &laststatus, \ { 'laststatus': &laststatus,
@ -177,10 +185,8 @@ function! s:goyo_on(width)
tab split tab split
let t:goyo_master = winbufnr(0) let t:goyo_master = winbufnr(0)
let t:goyo_width = a:width let t:goyo_dim = dim
let t:goyo_margin_top = get(g:, 'goyo_margin_top', 4) let t:goyo_dim_expr = a:dim
let t:goyo_margin_bottom = get(g:, 'goyo_margin_bottom', 4)
let t:goyo_initial_dim = [t:goyo_width, t:goyo_margin_top, t:goyo_margin_bottom]
let t:goyo_pads = {} let t:goyo_pads = {}
let t:goyo_revert = settings let t:goyo_revert = settings
let t:goyo_maps = extend(s:maps_nop(), s:maps_resize()) let t:goyo_maps = extend(s:maps_nop(), s:maps_resize())
@ -360,19 +366,60 @@ function! s:goyo_off()
silent! doautocmd User GoyoLeave silent! doautocmd User GoyoLeave
endfunction endfunction
function! goyo#execute(bang, ...) function! s:relsz(expr, limit)
let width = a:0 > 0 ? a:1 : get(g:, 'goyo_width', 80) if a:expr !~ '%$'
return str2nr(a:expr)
endif
return a:limit * str2nr(a:expr[:-2]) / 100
endfunction
function! s:parse_arg(arg)
if exists('g:goyo_height') || !exists('g:goyo_margin_top') && !exists('g:goyo_margin_bottom')
let height = s:relsz(get(g:, 'goyo_height', '85%'), &lines)
let yoff = 0
else
let top = max([0, s:relsz(get(g:, 'goyo_margin_top', 4), &lines)])
let bot = max([0, s:relsz(get(g:, 'goyo_margin_bottom', 4), &lines)])
let height = &lines - top - bot
let yoff = top - bot
endif
let dim = { 'width': s:relsz(get(g:, 'goyo_width', 80), &columns),
\ 'height': height,
\ 'xoff': 0,
\ 'yoff': yoff }
if empty(a:arg)
return dim
endif
let parts = matchlist(a:arg, '^\s*\([0-9]\+%\?\)\?\([+-][0-9]\+%\?\)\?\%(x\([0-9]\+%\?\)\?\([+-][0-9]\+%\?\)\?\)\?\s*$')
if empty(parts)
echohl WarningMsg
echo 'Invalid dimension expression: '.a:arg
echohl None
return {}
endif
if !empty(parts[1]) | let dim.width = s:relsz(parts[1], &columns) | endif
if !empty(parts[2]) | let dim.xoff = s:relsz(parts[2], &columns) | endif
if !empty(parts[3]) | let dim.height = s:relsz(parts[3], &lines) | endif
if !empty(parts[4]) | let dim.yoff = s:relsz(parts[4], &lines) | endif
return dim
endfunction
function! goyo#execute(bang, dim)
if a:bang if a:bang
if exists('#goyo') if exists('#goyo')
call s:goyo_off() call s:goyo_off()
endif endif
else else
if exists('#goyo') == 0 if exists('#goyo') == 0
call s:goyo_on(width) call s:goyo_on(a:dim)
elseif a:0 > 0 elseif !empty(a:dim)
let t:goyo_width = width let dim = s:parse_arg(a:dim)
if !empty(dim)
let t:goyo_dim = dim
let t:goyo_dim_expr = a:dim
call s:resize_pads() call s:resize_pads()
endif
else else
call s:goyo_off() call s:goyo_off()
end end

View file

@ -21,4 +21,4 @@
" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION " OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. " WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
command! -nargs=? -bar -bang Goyo call goyo#execute(<bang>0, <args>) command! -nargs=? -bar -bang Goyo call goyo#execute(<bang>0, <q-args>)

View file

@ -66,48 +66,42 @@ Then reload vim, run `:Helptags`, and check out `:help NERD_tree.txt`.
Faq Faq
--- ---
__Q. Can I have the nerdtree on every tab automatically?__ > Is there any support for `git` flags?
A. Nope. If this is something you want then chances are you aren't using tabs Yes, install [nerdtree-git-plugin](https://github.com/Xuyuanp/nerdtree-git-plugin).
and buffers as they were intended to be used. Read this
> Can I have the nerdtree on every tab automatically?
Nope. If this is something you want then chances are you aren't using tabs and
buffers as they were intended to be used. Read this
http://stackoverflow.com/questions/102384/using-vims-tabs-like-buffers http://stackoverflow.com/questions/102384/using-vims-tabs-like-buffers
If you are interested in this behaviour then consider [vim-nerdtree-tabs](https://github.com/jistr/vim-nerdtree-tabs) If you are interested in this behaviour then consider [vim-nerdtree-tabs](https://github.com/jistr/vim-nerdtree-tabs)
__Q. How can I open a NERDTree automatically when vim starts up?__ > How can I open a NERDTree automatically when vim starts up?
A. Stick this in your vimrc: `autocmd vimenter * NERDTree` 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?__ > How can I open a NERDTree automatically when vim starts up if no files were specified?
A. Stick this in your vimrc Stick this in your vimrc
autocmd StdinReadPre * let s:std_in=1 autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
__Q. How can I map a specific key or shortcut to open NERDTree?__ > How can I map a specific key or shortcut to open NERDTree?
A. Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever key you want): Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever key you want):
`map <C-n> :NERDTreeToggle<CR>` map <C-n> :NERDTreeToggle<CR>
__Q. How can I close vim if the only window left open is a NERDTree?__ > How can I close vim if the only window left open is a NERDTree?
A. Stick this in your vimrc: Stick this in your vimrc:
`autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif` autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif
> Can I have different highlighting for different file extensions?
Changelog See here: https://github.com/scrooloose/nerdtree/issues/433#issuecomment-92590696
---------
4.2.0 (2011-12-28)
* Add NERDTreeDirArrows option to make the UI use pretty arrow chars instead of the old +~| chars to define the tree structure (sickill)
* shift the syntax highlighting out into its own syntax file (gnap) * add some mac specific options to the filesystem menu - for macvim only (andersonfreitas)
* Add NERDTreeMinimalUI option to remove some non functional parts of the nerdtree ui (camthompson)
* tweak the behaviour of :NERDTreeFind - see :help :NERDTreeFind for the new behaviour (benjamingeiger)
* if no name is given to :Bookmark, make it default to the name of the target file/dir (minyoung)
* use 'file' completion when doing copying, create, and move operations (EvanDotPro)
* lots of misc bug fixes (paddyoloughlin, sdewald, camthompson, Vitaly Bogdanov, AndrewRadev, mathias, scottstvnsn, kml, wycats, me RAWR!)

View file

@ -34,6 +34,17 @@ function! nerdtree#compareNodes(n1, n2)
return a:n1.path.compareTo(a:n2.path) return a:n1.path.compareTo(a:n2.path)
endfunction endfunction
"FUNCTION: nerdtree#compareNodesBySortKey(n1, n2) {{{2
function! nerdtree#compareNodesBySortKey(n1, n2)
if a:n1.path.getSortKey() <# a:n2.path.getSortKey()
return -1
elseif a:n1.path.getSortKey() ># a:n2.path.getSortKey()
return 1
else
return 0
endif
endfunction
" FUNCTION: nerdtree#deprecated(func, [msg]) {{{2 " FUNCTION: nerdtree#deprecated(func, [msg]) {{{2
" Issue a deprecation warning for a:func. If a second arg is given, use this " Issue a deprecation warning for a:func. If a second arg is given, use this
" as the deprecation message " as the deprecation message
@ -95,175 +106,9 @@ function! nerdtree#runningWindows()
return has("win16") || has("win32") || has("win64") return has("win16") || has("win32") || has("win64")
endfunction endfunction
"FUNCTION: nerdtree#treeMarkupReg(dir) {{{2
function! nerdtree#treeMarkupReg()
if g:NERDTreeDirArrows
return '^\([▾▸] \| \+[▾▸] \| \+\)'
endif
return '^[ `|]*[\-+~]'
endfunction
"FUNCTION: nerdtree#treeUpDirLine(dir) {{{2
function! nerdtree#treeUpDirLine()
return '.. (up a dir)'
endfunction
"FUNCTION: nerdtree#treeWid(dir) {{{2
function! nerdtree#treeWid()
return 2
endfunction
" SECTION: View Functions {{{1 " SECTION: View Functions {{{1
"============================================================ "============================================================
"FUNCTION: nerdtree#closeTree() {{{2
"Closes the primary NERD tree window for this tab
function! nerdtree#closeTree()
if !nerdtree#isTreeOpen()
throw "NERDTree.NoTreeFoundError: no NERDTree is open"
endif
if winnr("$") != 1
if winnr() == nerdtree#getTreeWinNum()
call nerdtree#exec("wincmd p")
let bufnr = bufnr("")
call nerdtree#exec("wincmd p")
else
let bufnr = bufnr("")
endif
call nerdtree#exec(nerdtree#getTreeWinNum() . " wincmd w")
close
call nerdtree#exec(bufwinnr(bufnr) . " wincmd w")
else
close
endif
endfunction
"FUNCTION: nerdtree#closeTreeIfOpen() {{{2
"Closes the NERD tree window if it is open
function! nerdtree#closeTreeIfOpen()
if nerdtree#isTreeOpen()
call nerdtree#closeTree()
endif
endfunction
"FUNCTION: nerdtree#closeTreeIfQuitOnOpen() {{{2
"Closes the NERD tree window if the close on open option is set
function! nerdtree#closeTreeIfQuitOnOpen()
if g:NERDTreeQuitOnOpen && nerdtree#isTreeOpen()
call nerdtree#closeTree()
endif
endfunction
"FUNCTION: nerdtree#dumpHelp {{{2
"prints out the quick help
function! nerdtree#dumpHelp()
let old_h = @h
if b:treeShowHelp ==# 1
let @h= "\" NERD tree (" . nerdtree#version() . ") quickhelp~\n"
let @h=@h."\" ============================\n"
let @h=@h."\" File node mappings~\n"
let @h=@h."\" ". (g:NERDTreeMouseMode ==# 3 ? "single" : "double") ."-click,\n"
let @h=@h."\" <CR>,\n"
if b:NERDTreeType ==# "primary"
let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in prev window\n"
else
let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in current window\n"
endif
if b:NERDTreeType ==# "primary"
let @h=@h."\" ". g:NERDTreeMapPreview .": preview\n"
endif
let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n"
let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n"
let @h=@h."\" middle-click,\n"
let @h=@h."\" ". g:NERDTreeMapOpenSplit .": open split\n"
let @h=@h."\" ". g:NERDTreeMapPreviewSplit .": preview split\n"
let @h=@h."\" ". g:NERDTreeMapOpenVSplit .": open vsplit\n"
let @h=@h."\" ". g:NERDTreeMapPreviewVSplit .": preview vsplit\n"
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Directory node mappings~\n"
let @h=@h."\" ". (g:NERDTreeMouseMode ==# 1 ? "double" : "single") ."-click,\n"
let @h=@h."\" ". g:NERDTreeMapActivateNode .": open & close node\n"
let @h=@h."\" ". g:NERDTreeMapOpenRecursively .": recursively open node\n"
let @h=@h."\" ". g:NERDTreeMapCloseDir .": close parent of node\n"
let @h=@h."\" ". g:NERDTreeMapCloseChildren .": close all child nodes of\n"
let @h=@h."\" current node recursively\n"
let @h=@h."\" middle-click,\n"
let @h=@h."\" ". g:NERDTreeMapOpenExpl.": explore selected dir\n"
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Bookmark table mappings~\n"
let @h=@h."\" double-click,\n"
let @h=@h."\" ". g:NERDTreeMapActivateNode .": open bookmark\n"
let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n"
let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n"
let @h=@h."\" ". g:NERDTreeMapDeleteBookmark .": delete bookmark\n"
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Tree navigation mappings~\n"
let @h=@h."\" ". g:NERDTreeMapJumpRoot .": go to root\n"
let @h=@h."\" ". g:NERDTreeMapJumpParent .": go to parent\n"
let @h=@h."\" ". g:NERDTreeMapJumpFirstChild .": go to first child\n"
let @h=@h."\" ". g:NERDTreeMapJumpLastChild .": go to last child\n"
let @h=@h."\" ". g:NERDTreeMapJumpNextSibling .": go to next sibling\n"
let @h=@h."\" ". g:NERDTreeMapJumpPrevSibling .": go to prev sibling\n"
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Filesystem mappings~\n"
let @h=@h."\" ". g:NERDTreeMapChangeRoot .": change tree root to the\n"
let @h=@h."\" selected dir\n"
let @h=@h."\" ". g:NERDTreeMapUpdir .": move tree root up a dir\n"
let @h=@h."\" ". g:NERDTreeMapUpdirKeepOpen .": move tree root up a dir\n"
let @h=@h."\" but leave old root open\n"
let @h=@h."\" ". g:NERDTreeMapRefresh .": refresh cursor dir\n"
let @h=@h."\" ". g:NERDTreeMapRefreshRoot .": refresh current root\n"
let @h=@h."\" ". g:NERDTreeMapMenu .": Show menu\n"
let @h=@h."\" ". g:NERDTreeMapChdir .":change the CWD to the\n"
let @h=@h."\" selected dir\n"
let @h=@h."\" ". g:NERDTreeMapCWD .":change tree root to CWD\n"
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Tree filtering mappings~\n"
let @h=@h."\" ". g:NERDTreeMapToggleHidden .": hidden files (" . (b:NERDTreeShowHidden ? "on" : "off") . ")\n"
let @h=@h."\" ". g:NERDTreeMapToggleFilters .": file filters (" . (b:NERDTreeIgnoreEnabled ? "on" : "off") . ")\n"
let @h=@h."\" ". g:NERDTreeMapToggleFiles .": files (" . (b:NERDTreeShowFiles ? "on" : "off") . ")\n"
let @h=@h."\" ". g:NERDTreeMapToggleBookmarks .": bookmarks (" . (b:NERDTreeShowBookmarks ? "on" : "off") . ")\n"
"add quickhelp entries for each custom key map
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Custom mappings~\n"
for i in g:NERDTreeKeyMap.All()
if !empty(i.quickhelpText)
let @h=@h."\" ". i.key .": ". i.quickhelpText ."\n"
endif
endfor
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Other mappings~\n"
let @h=@h."\" ". g:NERDTreeMapQuit .": Close the NERDTree window\n"
let @h=@h."\" ". g:NERDTreeMapToggleZoom .": Zoom (maximize-minimize)\n"
let @h=@h."\" the NERDTree window\n"
let @h=@h."\" ". g:NERDTreeMapHelp .": toggle help\n"
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Bookmark commands~\n"
let @h=@h."\" :Bookmark [<name>]\n"
let @h=@h."\" :BookmarkToRoot <name>\n"
let @h=@h."\" :RevealBookmark <name>\n"
let @h=@h."\" :OpenBookmark <name>\n"
let @h=@h."\" :ClearBookmarks [<names>]\n"
let @h=@h."\" :ClearAllBookmarks\n"
silent! put h
elseif g:NERDTreeMinimalUI == 0
let @h="\" Press ". g:NERDTreeMapHelp ." for help\n"
silent! put h
endif
let @h = old_h
endfunction
"FUNCTION: nerdtree#echo {{{2 "FUNCTION: nerdtree#echo {{{2
"A wrapper for :echo. Appends 'NERDTree:' on the front of all messages "A wrapper for :echo. Appends 'NERDTree:' on the front of all messages
" "
@ -294,114 +139,9 @@ function! nerdtree#echoWarning(msg)
echohl normal echohl normal
endfunction endfunction
"FUNCTION: nerdtree#getTreeWinNum() {{{2
"gets the nerd tree window number for this tab
function! nerdtree#getTreeWinNum()
if exists("t:NERDTreeBufName")
return bufwinnr(t:NERDTreeBufName)
else
return -1
endif
endfunction
"FUNCTION: nerdtree#isTreeOpen() {{{2
function! nerdtree#isTreeOpen()
return nerdtree#getTreeWinNum() != -1
endfunction
"FUNCTION: nerdtree#putCursorOnBookmarkTable(){{{2
"Places the cursor at the top of the bookmarks table
function! nerdtree#putCursorOnBookmarkTable()
if !b:NERDTreeShowBookmarks
throw "NERDTree.IllegalOperationError: cant find bookmark table, bookmarks arent active"
endif
if g:NERDTreeMinimalUI
return cursor(1, 2)
endif
let rootNodeLine = b:NERDTree.ui.getRootLineNum()
let line = 1
while getline(line) !~# '^>-\+Bookmarks-\+$'
let line = line + 1
if line >= rootNodeLine
throw "NERDTree.BookmarkTableNotFoundError: didnt find the bookmarks table"
endif
endwhile
call cursor(line, 2)
endfunction
"FUNCTION: nerdtree#putCursorInTreeWin(){{{2
"Places the cursor in the nerd tree window
function! nerdtree#putCursorInTreeWin()
if !nerdtree#isTreeOpen()
throw "NERDTree.InvalidOperationError: cant put cursor in NERD tree window, no window exists"
endif
call nerdtree#exec(nerdtree#getTreeWinNum() . "wincmd w")
endfunction
"FUNCTION: nerdtree#renderBookmarks {{{2
function! nerdtree#renderBookmarks()
if g:NERDTreeMinimalUI == 0
call setline(line(".")+1, ">----------Bookmarks----------")
call cursor(line(".")+1, col("."))
endif
for i in g:NERDTreeBookmark.Bookmarks()
call setline(line(".")+1, i.str())
call cursor(line(".")+1, col("."))
endfor
call setline(line(".")+1, '')
call cursor(line(".")+1, col("."))
endfunction
"FUNCTION: nerdtree#renderView {{{2 "FUNCTION: nerdtree#renderView {{{2
function! nerdtree#renderView() function! nerdtree#renderView()
call b:NERDTree.render() call b:NERDTree.render()
endfunction endfunction
"
"FUNCTION: nerdtree#stripMarkupFromLine(line, removeLeadingSpaces){{{2
"returns the given line with all the tree parts stripped off
"
"Args:
"line: the subject line
"removeLeadingSpaces: 1 if leading spaces are to be removed (leading spaces =
"any spaces before the actual text of the node)
function! nerdtree#stripMarkupFromLine(line, removeLeadingSpaces)
let line = a:line
"remove the tree parts and the leading space
let line = substitute (line, nerdtree#treeMarkupReg(),"","")
"strip off any read only flag
let line = substitute (line, ' \[RO\]', "","")
"strip off any bookmark flags
let line = substitute (line, ' {[^}]*}', "","")
"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
endif
let line = substitute (line,' -> .*',"","") " remove link to
if wasdir ==# 1
let line = substitute (line, '/\?$', '/', "")
endif
if a:removeLeadingSpaces
let line = substitute (line, '^ *', '', '')
endif
return line
endfunction
" vim: set sw=4 sts=4 et fdm=marker: " vim: set sw=4 sts=4 et fdm=marker:

View file

@ -85,7 +85,7 @@ endfunction
"FUNCTION: s:activateAll() {{{1 "FUNCTION: s:activateAll() {{{1
"handle the user activating the updir line "handle the user activating the updir line
function! s:activateAll() function! s:activateAll()
if getline(".") ==# nerdtree#treeUpDirLine() if getline(".") ==# g:NERDTreeUI.UpDirLine()
return nerdtree#ui_glue#upDir(0) return nerdtree#ui_glue#upDir(0)
endif endif
endfunction endfunction
@ -93,13 +93,13 @@ endfunction
"FUNCTION: s:activateDirNode() {{{1 "FUNCTION: s:activateDirNode() {{{1
"handle the user activating a tree node "handle the user activating a tree node
function! s:activateDirNode(node) function! s:activateDirNode(node)
call a:node.activate({'reuse': 1}) call a:node.activate()
endfunction endfunction
"FUNCTION: s:activateFileNode() {{{1 "FUNCTION: s:activateFileNode() {{{1
"handle the user activating a tree node "handle the user activating a tree node
function! s:activateFileNode(node) function! s:activateFileNode(node)
call a:node.activate({'reuse': 1, 'where': 'p'}) call a:node.activate({'reuse': 'all', 'where': 'p'})
endfunction endfunction
"FUNCTION: s:activateBookmark() {{{1 "FUNCTION: s:activateBookmark() {{{1
@ -212,7 +212,7 @@ function! s:closeTreeWindow()
exec "buffer " . b:NERDTreePreviousBuf exec "buffer " . b:NERDTreePreviousBuf
else else
if winnr("$") > 1 if winnr("$") > 1
call nerdtree#closeTree() call g:NERDTree.Close()
else else
call nerdtree#echo("Cannot close last window") call nerdtree#echo("Cannot close last window")
endif endif
@ -275,20 +275,20 @@ function! s:findAndRevealPath()
endif endif
else else
if !p.isUnder(g:NERDTreeFileNode.GetRootForTab().path) if !p.isUnder(g:NERDTreeFileNode.GetRootForTab().path)
if !nerdtree#isTreeOpen() if !g:NERDTree.IsOpen()
call g:NERDTreeCreator.TogglePrimary('') call g:NERDTreeCreator.TogglePrimary('')
else else
call nerdtree#putCursorInTreeWin() call g:NERDTree.CursorToTreeWin()
endif endif
let b:NERDTreeShowHidden = g:NERDTreeShowHidden let b:NERDTreeShowHidden = g:NERDTreeShowHidden
call s:chRoot(g:NERDTreeDirNode.New(p.getParent())) call s:chRoot(g:NERDTreeDirNode.New(p.getParent()))
else else
if !nerdtree#isTreeOpen() if !g:NERDTree.IsOpen()
call g:NERDTreeCreator.TogglePrimary("") call g:NERDTreeCreator.TogglePrimary("")
endif endif
endif endif
endif endif
call nerdtree#putCursorInTreeWin() call g:NERDTree.CursorToTreeWin()
call b:NERDTreeRoot.reveal(p) call b:NERDTreeRoot.reveal(p)
if p.isUnixHiddenFile() if p.isUnixHiddenFile()
@ -312,7 +312,7 @@ function! s:handleLeftClick()
endfor endfor
if currentNode.path.isDirectory if currentNode.path.isDirectory
if startToCur =~# nerdtree#treeMarkupReg() && startToCur =~# '[+~▾▸] \?$' if startToCur =~# g:NERDTreeUI.MarkupReg() && startToCur =~# '[+~▾▸] \?$'
call currentNode.activate() call currentNode.activate()
return return
endif endif
@ -320,11 +320,11 @@ function! s:handleLeftClick()
if (g:NERDTreeMouseMode ==# 2 && currentNode.path.isDirectory) || g:NERDTreeMouseMode ==# 3 if (g:NERDTreeMouseMode ==# 2 && currentNode.path.isDirectory) || g:NERDTreeMouseMode ==# 3
let char = strpart(startToCur, strlen(startToCur)-1, 1) let char = strpart(startToCur, strlen(startToCur)-1, 1)
if char !~# nerdtree#treeMarkupReg() if char !~# g:NERDTreeUI.MarkupReg()
if currentNode.path.isDirectory if currentNode.path.isDirectory
call currentNode.activate() call currentNode.activate()
else else
call currentNode.activate({'reuse': 1, 'where': 'p'}) call currentNode.activate({'reuse': 'all', 'where': 'p'})
endif endif
return return
endif endif
@ -547,7 +547,7 @@ endfunction
function! nerdtree#ui_glue#setupCommands() function! nerdtree#ui_glue#setupCommands()
command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreatePrimary('<args>') command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreatePrimary('<args>')
command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.TogglePrimary('<args>') command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.TogglePrimary('<args>')
command! -n=0 -bar NERDTreeClose :call nerdtree#closeTreeIfOpen() command! -n=0 -bar NERDTreeClose :call g:NERDTree.Close()
command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreatePrimary('<args>') command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreatePrimary('<args>')
command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror() command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror()
command! -n=0 -bar NERDTreeFind call s:findAndRevealPath() command! -n=0 -bar NERDTreeFind call s:findAndRevealPath()

View file

@ -34,6 +34,8 @@ CONTENTS *NERDTree-contents*
4.The NERD tree API.......................|NERDTreeAPI| 4.The NERD tree API.......................|NERDTreeAPI|
4.1.Key map API.......................|NERDTreeKeymapAPI| 4.1.Key map API.......................|NERDTreeKeymapAPI|
4.2.Menu API..........................|NERDTreeMenuAPI| 4.2.Menu API..........................|NERDTreeMenuAPI|
4.3.Menu API..........................|NERDTreeAddPathFilter()|
4.4.Path Listener API.................|NERDTreePathListenerAPI|
5.About...................................|NERDTreeAbout| 5.About...................................|NERDTreeAbout|
6.Changelog...............................|NERDTreeChangelog| 6.Changelog...............................|NERDTreeChangelog|
7.Credits.................................|NERDTreeCredits| 7.Credits.................................|NERDTreeCredits|
@ -131,7 +133,7 @@ The following features and functionality are provided by the NERD tree:
:NERDTreeFind *:NERDTreeFind* :NERDTreeFind *:NERDTreeFind*
Find the current file in the tree. Find the current file in the tree.
If not tree exists and the current file is under vim's CWD, then init a If no tree exists and the current file is under vim's CWD, then init a
tree at the CWD and reveal the file. Otherwise init a tree in the current tree at the CWD and reveal the file. Otherwise init a tree in the current
file's directory. file's directory.
@ -1173,6 +1175,44 @@ Where selecting "a (s)ub menu" will lead to a second menu: >
When any of the 3 concrete menu items are selected the function "SomeFunction" When any of the 3 concrete menu items are selected the function "SomeFunction"
will be called. will be called.
------------------------------------------------------------------------------
4.3 NERDTreeAddPathFilter(callback) *NERDTreeAddPathFilter()*
Path filters are essentially a more powerful version of |NERDTreeIgnore|.
If the simple regex matching in |NERDTreeIgnore| is not enough then use
|NERDTreeAddPathFilter()| to add a callback function that paths will be
checked against when the decision to ignore them is made. Example >
call NERDTreeAddPathFilter('MyFilter')
function! MyFilter(params)
"params is a dict containing keys: 'nerdtree' and 'path' which are
"g:NERDTree and g:NERDTreePath objects
"return 1 to ignore params['path'] or 0 otherwise
endfunction
<
------------------------------------------------------------------------------
4.4 Path Listener API *NERDTreePathListenerAPI*
Use this API if you want to run a callback for events on Path objects. E.G >
call g:NERDTreePathNotifier.AddListener("init", "MyListener")
"....
function! MyListener(event)
"This function will be called whenever a Path object is created.
"a:event is an object that contains a bunch of relevant info -
"including the path in question. See lib/event.vim for details.
endfunction
<
Current events supported:
init ~
refresh ~
refreshFlags ~
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
NERDTreeRender() *NERDTreeRender()* NERDTreeRender() *NERDTreeRender()*
Re-renders the NERD tree buffer. Useful if you change the state of the Re-renders the NERD tree buffer. Useful if you change the state of the
@ -1203,6 +1243,8 @@ Next
- add 'scope' argument to the key map API - add 'scope' argument to the key map API
- add NERDTreeCustomIgnoreFilter hook - needs doc - add NERDTreeCustomIgnoreFilter hook - needs doc
- add magic [[dir]] and [[file]] flags to NERDTreeIgnore - add magic [[dir]] and [[file]] flags to NERDTreeIgnore
- add support for custom path filters. See :help NERDTreeAddPathFilter()
- add path listener API. See :help NERDTreePathListenerAPI.
4.2.0 4.2.0
- Add NERDTreeDirArrows option to make the UI use pretty arrow chars - Add NERDTreeDirArrows option to make the UI use pretty arrow chars

View file

@ -253,7 +253,7 @@ endfunction
" FUNCTION: Bookmark.str() {{{1 " FUNCTION: Bookmark.str() {{{1
" Get the string that should be rendered in the view for this bookmark " Get the string that should be rendered in the view for this bookmark
function! s:Bookmark.str() function! s:Bookmark.str()
let pathStrMaxLen = winwidth(nerdtree#getTreeWinNum()) - 4 - len(self.name) let pathStrMaxLen = winwidth(g:NERDTree.GetWinNum()) - 4 - len(self.name)
if &nu if &nu
let pathStrMaxLen = pathStrMaxLen - &numberwidth let pathStrMaxLen = pathStrMaxLen - &numberwidth
endif endif

View file

@ -43,6 +43,11 @@ endfunction
function! s:Creator.createPrimary(name) function! s:Creator.createPrimary(name)
let path = self._pathForString(a:name) let path = self._pathForString(a:name)
"abort if exception was thrown (bookmark/dir doesn't exist)
if empty(path)
return
endif
"if instructed to, then change the vim CWD to the dir the NERDTree is "if instructed to, then change the vim CWD to the dir the NERDTree is
"inited in "inited in
if g:NERDTreeChDirMode != 0 if g:NERDTreeChDirMode != 0
@ -50,8 +55,8 @@ function! s:Creator.createPrimary(name)
endif endif
if g:NERDTree.ExistsForTab() if g:NERDTree.ExistsForTab()
if nerdtree#isTreeOpen() if g:NERDTree.IsOpen()
call nerdtree#closeTree() call g:NERDTree.Close()
endif endif
unlet t:NERDTreeBufName unlet t:NERDTreeBufName
endif endif
@ -163,8 +168,8 @@ function! s:Creator.createMirror()
return return
endif endif
if g:NERDTree.ExistsForTab() && nerdtree#isTreeOpen() if g:NERDTree.ExistsForTab() && g:NERDTree.IsOpen()
call nerdtree#closeTree() call g:NERDTree.Close()
endif endif
let t:NERDTreeBufName = bufferName let t:NERDTreeBufName = bufferName
@ -328,14 +333,14 @@ endfunction
"initialized. "initialized.
function! s:Creator.togglePrimary(dir) function! s:Creator.togglePrimary(dir)
if g:NERDTree.ExistsForTab() if g:NERDTree.ExistsForTab()
if !nerdtree#isTreeOpen() if !g:NERDTree.IsOpen()
call self._createTreeWin() call self._createTreeWin()
if !&hidden if !&hidden
call b:NERDTree.render() call b:NERDTree.render()
endif endif
call b:NERDTree.ui.restoreScreenState() call b:NERDTree.ui.restoreScreenState()
else else
call nerdtree#closeTree() call g:NERDTree.Close()
endif endif
else else
call self.createPrimary(a:dir) call self.createPrimary(a:dir)

View file

@ -3,6 +3,73 @@
let s:NERDTree = {} let s:NERDTree = {}
let g:NERDTree = s:NERDTree let g:NERDTree = s:NERDTree
"FUNCTION: s:NERDTree.AddPathFilter() {{{1
function! s:NERDTree.AddPathFilter(callback)
call add(s:NERDTree.PathFilters(), a:callback)
endfunction
"FUNCTION: s:NERDTree.Close() {{{1
"Closes the primary NERD tree window for this tab
function! s:NERDTree.Close()
if !s:NERDTree.IsOpen()
return
endif
if winnr("$") != 1
if winnr() == s:NERDTree.GetWinNum()
call nerdtree#exec("wincmd p")
let bufnr = bufnr("")
call nerdtree#exec("wincmd p")
else
let bufnr = bufnr("")
endif
call nerdtree#exec(s:NERDTree.GetWinNum() . " wincmd w")
close
call nerdtree#exec(bufwinnr(bufnr) . " wincmd w")
else
close
endif
endfunction
"FUNCTION: s:NERDTree.CloseIfQuitOnOpen() {{{1
"Closes the NERD tree window if the close on open option is set
function! s:NERDTree.CloseIfQuitOnOpen()
if g:NERDTreeQuitOnOpen && s:NERDTree.IsOpen()
call s:NERDTree.Close()
endif
endfunction
"FUNCTION: s:NERDTree.CursorToBookmarkTable(){{{1
"Places the cursor at the top of the bookmarks table
function! s:NERDTree.CursorToBookmarkTable()
if !b:NERDTreeShowBookmarks
throw "NERDTree.IllegalOperationError: cant find bookmark table, bookmarks arent active"
endif
if g:NERDTreeMinimalUI
return cursor(1, 2)
endif
let rootNodeLine = b:NERDTree.ui.getRootLineNum()
let line = 1
while getline(line) !~# '^>-\+Bookmarks-\+$'
let line = line + 1
if line >= rootNodeLine
throw "NERDTree.BookmarkTableNotFoundError: didnt find the bookmarks table"
endif
endwhile
call cursor(line, 2)
endfunction
"FUNCTION: s:NERDTree.CursorToTreeWin(){{{1
"Places the cursor in the nerd tree window
function! s:NERDTree.CursorToTreeWin()
call g:NERDTree.MustBeOpen()
call nerdtree#exec(g:NERDTree.GetWinNum() . "wincmd w")
endfunction
" Function: s:NERDTree.ExistsForBuffer() {{{1 " Function: s:NERDTree.ExistsForBuffer() {{{1
" Returns 1 if a nerd tree root exists in the current buffer " Returns 1 if a nerd tree root exists in the current buffer
function! s:NERDTree.ExistsForBuf() function! s:NERDTree.ExistsForBuf()
@ -23,6 +90,29 @@ function! s:NERDTree.ForCurrentBuf()
endif endif
endfunction endfunction
"FUNCTION: s:NERDTree.GetWinNum() {{{1
"gets the nerd tree window number for this tab
function! s:NERDTree.GetWinNum()
if exists("t:NERDTreeBufName")
return bufwinnr(t:NERDTreeBufName)
else
return -1
endif
endfunction
"FUNCTION: s:NERDTree.IsOpen() {{{1
function! s:NERDTree.IsOpen()
return s:NERDTree.GetWinNum() != -1
endfunction
"FUNCTION: s:NERDTree.MustBeOpen() {{{1
function! s:NERDTree.MustBeOpen()
if !s:NERDTree.IsOpen()
throw "NERDTree.TreeNotOpen"
endif
endfunction
"FUNCTION: s:NERDTree.New() {{{1
function! s:NERDTree.New(path) function! s:NERDTree.New(path)
let newObj = copy(self) let newObj = copy(self)
let newObj.ui = g:NERDTreeUI.New(newObj) let newObj.ui = g:NERDTreeUI.New(newObj)
@ -31,9 +121,17 @@ function! s:NERDTree.New(path)
return newObj return newObj
endfunction endfunction
"FUNCTION: s:NERDTree.PathFilters() {{{1
function! s:NERDTree.PathFilters()
if !exists('s:NERDTree._PathFilters')
let s:NERDTree._PathFilters = []
endif
return s:NERDTree._PathFilters
endfunction
"FUNCTION: s:NERDTree.render() {{{1 "FUNCTION: s:NERDTree.render() {{{1
"A convenience function - since this is called often "A convenience function - since this is called often
function! s:NERDTree.render() function! s:NERDTree.render()
call self.ui.render() call self.ui.render()
endfunction endfunction

View file

@ -40,7 +40,7 @@ function! s:Opener._checkToCloseTree(newtab)
endif endif
if (a:newtab && self._where == 't') || !a:newtab if (a:newtab && self._where == 't') || !a:newtab
call nerdtree#closeTreeIfQuitOnOpen() call g:NERDTree.CloseIfQuitOnOpen()
endif endif
endfunction endfunction
@ -131,7 +131,8 @@ endfunction
" 'where': Specifies whether the node should be opened in new split/tab or in " 'where': Specifies whether the node should be opened in new split/tab or in
" the previous window. Can be either 'v' or 'h' or 't' (for open in " the previous window. Can be either 'v' or 'h' or 't' (for open in
" new tab) " new tab)
" 'reuse': if a window is displaying the file then jump the cursor there " 'reuse': if a window is displaying the file then jump the cursor there. Can
" 'all', 'currenttab' or empty to not reuse.
" 'keepopen': dont close the tree window " 'keepopen': dont close the tree window
" 'stay': open the file, but keep the cursor in the tree win " 'stay': open the file, but keep the cursor in the tree win
function! s:Opener.New(path, opts) function! s:Opener.New(path, opts)
@ -139,7 +140,13 @@ function! s:Opener.New(path, opts)
let newObj._path = a:path let newObj._path = a:path
let newObj._stay = nerdtree#has_opt(a:opts, 'stay') let newObj._stay = nerdtree#has_opt(a:opts, 'stay')
let newObj._reuse = nerdtree#has_opt(a:opts, 'reuse')
if has_key(a:opts, 'reuse')
let newObj._reuse = a:opts['reuse']
else
let newObj._reuse = ''
endif
let newObj._keepopen = nerdtree#has_opt(a:opts, 'keepopen') let newObj._keepopen = nerdtree#has_opt(a:opts, 'keepopen')
let newObj._where = has_key(a:opts, 'where') ? a:opts['where'] : '' let newObj._where = has_key(a:opts, 'where') ? a:opts['where'] : ''
let newObj._treetype = b:NERDTreeType let newObj._treetype = b:NERDTreeType
@ -189,7 +196,7 @@ function! s:Opener._newSplit()
try try
exec(splitMode." sp ") exec(splitMode." sp ")
catch /^Vim\%((\a\+)\)\=:E37/ catch /^Vim\%((\a\+)\)\=:E37/
call nerdtree#putCursorInTreeWin() call g:NERDTree.CursorToTreeWin()
throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified." throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified."
catch /^Vim\%((\a\+)\)\=:/ catch /^Vim\%((\a\+)\)\=:/
"do nothing "do nothing
@ -219,7 +226,7 @@ function! s:Opener._newVSplit()
vnew vnew
"resize the nerd tree back to the original size "resize the nerd tree back to the original size
call nerdtree#putCursorInTreeWin() call g:NERDTree.CursorToTreeWin()
exec("silent vertical resize ". winwidth) exec("silent vertical resize ". winwidth)
call nerdtree#exec('wincmd p') call nerdtree#exec('wincmd p')
endfunction endfunction
@ -235,7 +242,7 @@ endfunction
"FUNCTION: Opener._openFile() {{{1 "FUNCTION: Opener._openFile() {{{1
function! s:Opener._openFile() function! s:Opener._openFile()
if self._reuse && self._reuseWindow() if self._reuseWindow()
return return
endif endif
@ -288,7 +295,7 @@ function! s:Opener._previousWindow()
call nerdtree#exec('wincmd p') call nerdtree#exec('wincmd p')
endif endif
catch /^Vim\%((\a\+)\)\=:E37/ catch /^Vim\%((\a\+)\)\=:E37/
call nerdtree#putCursorInTreeWin() call g:NERDTree.CursorToTreeWin()
throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified." throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified."
catch /^Vim\%((\a\+)\)\=:/ catch /^Vim\%((\a\+)\)\=:/
echo v:exception echo v:exception
@ -307,13 +314,22 @@ endfunction
" "
"return 1 if we were successful "return 1 if we were successful
function! s:Opener._reuseWindow() function! s:Opener._reuseWindow()
if empty(self._reuse)
return 0
endif
"check the current tab for the window "check the current tab for the window
let winnr = bufwinnr('^' . self._path.str() . '$') let winnr = bufwinnr('^' . self._path.str() . '$')
if winnr != -1 if winnr != -1
call nerdtree#exec(winnr . "wincmd w") call nerdtree#exec(winnr . "wincmd w")
call self._checkToCloseTree(0) call self._checkToCloseTree(0)
return 1 return 1
else endif
if self._reuse == 'currenttab'
return 0
endif
"check other tabs "check other tabs
let tabnr = self._path.tabnr() let tabnr = self._path.tabnr()
if tabnr if tabnr
@ -323,7 +339,7 @@ function! s:Opener._reuseWindow()
call nerdtree#exec(winnr . "wincmd w") call nerdtree#exec(winnr . "wincmd w")
return 1 return 1
endif endif
endif
return 0 return 0
endfunction endfunction

View file

@ -1,6 +1,12 @@
"we need to use this number many times for sorting... so we calculate it only "we need to use this number many times for sorting... so we calculate it only
"once here "once here
let s:NERDTreeSortStarIndex = index(g:NERDTreeSortOrder, '*') let s:NERDTreeSortStarIndex = index(g:NERDTreeSortOrder, '*')
" used in formating sortKey, e.g. '%04d'
if exists("log10")
let s:sortKeyFormat = "%0" . float2nr(ceil(log10(len(g:NERDTreeSortOrder)))) . "d"
else
let s:sortKeyFormat = "%04d"
endif
"CLASS: Path "CLASS: Path
"============================================================ "============================================================
@ -361,6 +367,24 @@ function! s:Path.getSortOrderIndex()
return s:NERDTreeSortStarIndex return s:NERDTreeSortStarIndex
endfunction endfunction
"FUNCTION: Path.getSortKey() {{{1
"returns a string used in compare function for sorting
function! s:Path.getSortKey()
if !exists("self._sortKey")
let path = self.getLastPathComponent(1)
if !g:NERDTreeSortHiddenFirst
let path = substitute(path, '^[._]', '', '')
endif
if !g:NERDTreeCaseSensitiveSort
let path = tolower(path)
endif
let self._sortKey = printf(s:sortKeyFormat, self.getSortOrderIndex()) . path
endif
return self._sortKey
endfunction
"FUNCTION: Path.isUnixHiddenFile() {{{1 "FUNCTION: Path.isUnixHiddenFile() {{{1
"check for unix hidden files "check for unix hidden files
function! s:Path.isUnixHiddenFile() function! s:Path.isUnixHiddenFile()
@ -392,6 +416,12 @@ function! s:Path.ignore()
return 1 return 1
endif endif
endfor endfor
for callback in g:NERDTree.PathFilters()
if {callback}({'path': self, 'nerdtree': b:NERDTree})
return 1
endif
endfor
endif endif
"dont show hidden files unless instructed to "dont show hidden files unless instructed to
@ -403,10 +433,6 @@ function! s:Path.ignore()
return 1 return 1
endif endif
if exists("*NERDTreeCustomIgnoreFilter") && NERDTreeCustomIgnoreFilter(self)
return 1
endif
return 0 return 0
endfunction endfunction
@ -611,7 +637,7 @@ function! s:Path.str(...)
if has_key(self, '_strFor' . format) if has_key(self, '_strFor' . format)
exec 'let toReturn = self._strFor' . format . '()' exec 'let toReturn = self._strFor' . format . '()'
else else
raise 'NERDTree.UnknownFormatError: unknown format "'. format .'"' throw 'NERDTree.UnknownFormatError: unknown format "'. format .'"'
endif endif
else else
let toReturn = self._str() let toReturn = self._str()

View file

@ -246,8 +246,12 @@ function! s:TreeDirNode._initChildren(silent)
"filter out the .. and . directories "filter out the .. and . directories
"Note: we must match .. AND ../ cos sometimes the globpath returns "Note: we must match .. AND ../ cos sometimes the globpath returns
"../ for path with strange chars (eg $) "../ for path with strange chars (eg $)
if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$' " if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$'
"
" Regular expression is too expensive. Use simply string comparison
" instead
if i[len(i)-3:2] != ".." && i[len(i)-2:2] != ".." &&
\ i[len(i)-2:1] != "." && i[len(i)-1] != "."
"put the next file in a new node and attach it "put the next file in a new node and attach it
try try
let path = g:NERDTreePath.New(i) let path = g:NERDTreePath.New(i)
@ -405,8 +409,12 @@ function! s:TreeDirNode.refresh()
"filter out the .. and . directories "filter out the .. and . directories
"Note: we must match .. AND ../ cos sometimes the globpath returns "Note: we must match .. AND ../ cos sometimes the globpath returns
"../ for path with strange chars (eg $) "../ for path with strange chars (eg $)
if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$' "if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$'
" Regular expression is too expensive. Use simply string comparison
" instead
if i[len(i)-3:2] != ".." && i[len(i)-2:2] != ".." &&
\ i[len(i)-2:1] != "." && i[len(i)-1] != "."
try try
"create a new path and see if it exists in this nodes children "create a new path and see if it exists in this nodes children
let path = g:NERDTreePath.New(i) let path = g:NERDTreePath.New(i)
@ -504,7 +512,7 @@ endfunction
"directory priority. "directory priority.
" "
function! s:TreeDirNode.sortChildren() function! s:TreeDirNode.sortChildren()
let CompareFunc = function("nerdtree#compareNodes") let CompareFunc = function("nerdtree#compareNodesBySortKey")
call sort(self.children, CompareFunc) call sort(self.children, CompareFunc)
endfunction endfunction

View file

@ -3,11 +3,6 @@
let s:UI = {} let s:UI = {}
let g:NERDTreeUI = s:UI let g:NERDTreeUI = s:UI
function! s:UI.lolcats()
echomsg "lolcats"
endfunction
"FUNCTION: s:UI.centerView() {{{2 "FUNCTION: s:UI.centerView() {{{2
"centers the nerd tree window around the cursor (provided the nerd tree "centers the nerd tree window around the cursor (provided the nerd tree
"options permit) "options permit)
@ -15,13 +10,121 @@ function! s:UI.centerView()
if g:NERDTreeAutoCenter if g:NERDTreeAutoCenter
let current_line = winline() let current_line = winline()
let lines_to_top = current_line let lines_to_top = current_line
let lines_to_bottom = winheight(nerdtree#getTreeWinNum()) - current_line let lines_to_bottom = winheight(g:NERDTree.GetWinNum()) - current_line
if lines_to_top < g:NERDTreeAutoCenterThreshold || lines_to_bottom < g:NERDTreeAutoCenterThreshold if lines_to_top < g:NERDTreeAutoCenterThreshold || lines_to_bottom < g:NERDTreeAutoCenterThreshold
normal! zz normal! zz
endif endif
endif endif
endfunction endfunction
"FUNCTION: s:UI._dumpHelp {{{1
"prints out the quick help
function! s:UI._dumpHelp()
let old_h = @h
if b:treeShowHelp ==# 1
let @h= "\" NERD tree (" . nerdtree#version() . ") quickhelp~\n"
let @h=@h."\" ============================\n"
let @h=@h."\" File node mappings~\n"
let @h=@h."\" ". (g:NERDTreeMouseMode ==# 3 ? "single" : "double") ."-click,\n"
let @h=@h."\" <CR>,\n"
if b:NERDTreeType ==# "primary"
let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in prev window\n"
else
let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in current window\n"
endif
if b:NERDTreeType ==# "primary"
let @h=@h."\" ". g:NERDTreeMapPreview .": preview\n"
endif
let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n"
let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n"
let @h=@h."\" middle-click,\n"
let @h=@h."\" ". g:NERDTreeMapOpenSplit .": open split\n"
let @h=@h."\" ". g:NERDTreeMapPreviewSplit .": preview split\n"
let @h=@h."\" ". g:NERDTreeMapOpenVSplit .": open vsplit\n"
let @h=@h."\" ". g:NERDTreeMapPreviewVSplit .": preview vsplit\n"
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Directory node mappings~\n"
let @h=@h."\" ". (g:NERDTreeMouseMode ==# 1 ? "double" : "single") ."-click,\n"
let @h=@h."\" ". g:NERDTreeMapActivateNode .": open & close node\n"
let @h=@h."\" ". g:NERDTreeMapOpenRecursively .": recursively open node\n"
let @h=@h."\" ". g:NERDTreeMapCloseDir .": close parent of node\n"
let @h=@h."\" ". g:NERDTreeMapCloseChildren .": close all child nodes of\n"
let @h=@h."\" current node recursively\n"
let @h=@h."\" middle-click,\n"
let @h=@h."\" ". g:NERDTreeMapOpenExpl.": explore selected dir\n"
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Bookmark table mappings~\n"
let @h=@h."\" double-click,\n"
let @h=@h."\" ". g:NERDTreeMapActivateNode .": open bookmark\n"
let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n"
let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n"
let @h=@h."\" ". g:NERDTreeMapDeleteBookmark .": delete bookmark\n"
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Tree navigation mappings~\n"
let @h=@h."\" ". g:NERDTreeMapJumpRoot .": go to root\n"
let @h=@h."\" ". g:NERDTreeMapJumpParent .": go to parent\n"
let @h=@h."\" ". g:NERDTreeMapJumpFirstChild .": go to first child\n"
let @h=@h."\" ". g:NERDTreeMapJumpLastChild .": go to last child\n"
let @h=@h."\" ". g:NERDTreeMapJumpNextSibling .": go to next sibling\n"
let @h=@h."\" ". g:NERDTreeMapJumpPrevSibling .": go to prev sibling\n"
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Filesystem mappings~\n"
let @h=@h."\" ". g:NERDTreeMapChangeRoot .": change tree root to the\n"
let @h=@h."\" selected dir\n"
let @h=@h."\" ". g:NERDTreeMapUpdir .": move tree root up a dir\n"
let @h=@h."\" ". g:NERDTreeMapUpdirKeepOpen .": move tree root up a dir\n"
let @h=@h."\" but leave old root open\n"
let @h=@h."\" ". g:NERDTreeMapRefresh .": refresh cursor dir\n"
let @h=@h."\" ". g:NERDTreeMapRefreshRoot .": refresh current root\n"
let @h=@h."\" ". g:NERDTreeMapMenu .": Show menu\n"
let @h=@h."\" ". g:NERDTreeMapChdir .":change the CWD to the\n"
let @h=@h."\" selected dir\n"
let @h=@h."\" ". g:NERDTreeMapCWD .":change tree root to CWD\n"
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Tree filtering mappings~\n"
let @h=@h."\" ". g:NERDTreeMapToggleHidden .": hidden files (" . (b:NERDTreeShowHidden ? "on" : "off") . ")\n"
let @h=@h."\" ". g:NERDTreeMapToggleFilters .": file filters (" . (b:NERDTreeIgnoreEnabled ? "on" : "off") . ")\n"
let @h=@h."\" ". g:NERDTreeMapToggleFiles .": files (" . (b:NERDTreeShowFiles ? "on" : "off") . ")\n"
let @h=@h."\" ". g:NERDTreeMapToggleBookmarks .": bookmarks (" . (b:NERDTreeShowBookmarks ? "on" : "off") . ")\n"
"add quickhelp entries for each custom key map
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Custom mappings~\n"
for i in g:NERDTreeKeyMap.All()
if !empty(i.quickhelpText)
let @h=@h."\" ". i.key .": ". i.quickhelpText ."\n"
endif
endfor
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Other mappings~\n"
let @h=@h."\" ". g:NERDTreeMapQuit .": Close the NERDTree window\n"
let @h=@h."\" ". g:NERDTreeMapToggleZoom .": Zoom (maximize-minimize)\n"
let @h=@h."\" the NERDTree window\n"
let @h=@h."\" ". g:NERDTreeMapHelp .": toggle help\n"
let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Bookmark commands~\n"
let @h=@h."\" :Bookmark [<name>]\n"
let @h=@h."\" :BookmarkToRoot <name>\n"
let @h=@h."\" :RevealBookmark <name>\n"
let @h=@h."\" :OpenBookmark <name>\n"
let @h=@h."\" :ClearBookmarks [<names>]\n"
let @h=@h."\" :ClearAllBookmarks\n"
silent! put h
elseif g:NERDTreeMinimalUI == 0
let @h="\" Press ". g:NERDTreeMapHelp ." for help\n"
silent! put h
endif
let @h = old_h
endfunction
"FUNCTION: s:UI.new(nerdtree) {{{1 "FUNCTION: s:UI.new(nerdtree) {{{1
function! s:UI.New(nerdtree) function! s:UI.New(nerdtree)
let newObj = copy(self) let newObj = copy(self)
@ -56,14 +159,14 @@ function! s:UI.getPath(ln)
endif endif
endif endif
if line ==# nerdtree#treeUpDirLine() if line ==# s:UI.UpDirLine()
return b:NERDTreeRoot.path.getParent() return b:NERDTreeRoot.path.getParent()
endif endif
let indent = self._indentLevelFor(line) let indent = self._indentLevelFor(line)
"remove the tree parts and the leading space "remove the tree parts and the leading space
let curFile = nerdtree#stripMarkupFromLine(line, 0) let curFile = self._stripMarkup(line, 0)
let wasdir = 0 let wasdir = 0
if curFile =~# '/$' if curFile =~# '/$'
@ -76,7 +179,7 @@ function! s:UI.getPath(ln)
while lnum > 0 while lnum > 0
let lnum = lnum - 1 let lnum = lnum - 1
let curLine = getline(lnum) let curLine = getline(lnum)
let curLineStripped = nerdtree#stripMarkupFromLine(curLine, 1) let curLineStripped = self._stripMarkup(curLine, 1)
"have we reached the top of the tree? "have we reached the top of the tree?
if lnum == rootLine if lnum == rootLine
@ -127,7 +230,7 @@ function! s:UI.getLineNum(file_node)
let indent = self._indentLevelFor(curLine) let indent = self._indentLevelFor(curLine)
if indent ==# curPathComponent if indent ==# curPathComponent
let curLine = nerdtree#stripMarkupFromLine(curLine, 1) let curLine = self._stripMarkup(curLine, 1)
let curPath = join(pathcomponents, '/') . '/' . curLine let curPath = join(pathcomponents, '/') . '/' . curLine
if stridx(fullpath, curPath, 0) ==# 0 if stridx(fullpath, curPath, 0) ==# 0
@ -146,7 +249,6 @@ function! s:UI.getLineNum(file_node)
return -1 return -1
endfunction endfunction
"FUNCTION: s:UI.getRootLineNum(){{{1 "FUNCTION: s:UI.getRootLineNum(){{{1
"gets the line number of the root node "gets the line number of the root node
function! s:UI.getRootLineNum() function! s:UI.getRootLineNum()
@ -157,9 +259,9 @@ function! s:UI.getRootLineNum()
return rootLine return rootLine
endfunction endfunction
"FUNCTION: s:UI._indentLevelFor(line) {{{2 "FUNCTION: s:UI._indentLevelFor(line) {{{1
function! s:UI._indentLevelFor(line) function! s:UI._indentLevelFor(line)
let level = match(a:line, '[^ \-+~▸▾`|]') / nerdtree#treeWid() let level = match(a:line, '[^ \-+~▸▾`|]') / s:UI.IndentWid()
" check if line includes arrows " check if line includes arrows
if match(a:line, '[▸▾]') > -1 if match(a:line, '[▸▾]') > -1
" decrement level as arrow uses 3 ascii chars " decrement level as arrow uses 3 ascii chars
@ -168,8 +270,38 @@ function! s:UI._indentLevelFor(line)
return level return level
endfunction endfunction
"FUNCTION: s:UI.IndentWid() {{{1
function! s:UI.IndentWid()
return 2
endfunction
"FUNCTION: s:UI.restoreScreenState() {{{2 "FUNCTION: s:UI.MarkupReg() {{{1
function! s:UI.MarkupReg()
if g:NERDTreeDirArrows
return '^\([▾▸] \| \+[▾▸] \| \+\)'
endif
return '^[ `|]*[\-+~]'
endfunction
"FUNCTION: s:UI._renderBookmarks {{{1
function! s:UI._renderBookmarks()
if g:NERDTreeMinimalUI == 0
call setline(line(".")+1, ">----------Bookmarks----------")
call cursor(line(".")+1, col("."))
endif
for i in g:NERDTreeBookmark.Bookmarks()
call setline(line(".")+1, i.str())
call cursor(line(".")+1, col("."))
endfor
call setline(line(".")+1, '')
call cursor(line(".")+1, col("."))
endfunction
"FUNCTION: s:UI.restoreScreenState() {{{1
" "
"Sets the screen state back to what it was when nerdtree#saveScreenState was last "Sets the screen state back to what it was when nerdtree#saveScreenState was last
"called. "called.
@ -189,23 +321,60 @@ function! s:UI.restoreScreenState()
let &scrolloff=old_scrolloff let &scrolloff=old_scrolloff
endfunction endfunction
"FUNCTION: s:UI.saveScreenState() {{{2 "FUNCTION: s:UI.saveScreenState() {{{1
"Saves the current cursor position in the current buffer and the window "Saves the current cursor position in the current buffer and the window
"scroll position "scroll position
function! s:UI.saveScreenState() function! s:UI.saveScreenState()
let win = winnr() let win = winnr()
try call g:NERDTree.CursorToTreeWin()
call nerdtree#putCursorInTreeWin()
let self._screenState = {} let self._screenState = {}
let self._screenState['oldPos'] = getpos(".") let self._screenState['oldPos'] = getpos(".")
let self._screenState['oldTopLine'] = line("w0") let self._screenState['oldTopLine'] = line("w0")
let self._screenState['oldWindowSize']= winwidth("") let self._screenState['oldWindowSize']= winwidth("")
call nerdtree#exec(win . "wincmd w") call nerdtree#exec(win . "wincmd w")
catch /^NERDTree.InvalidOperationError/
endtry
endfunction endfunction
"FUNCTION: s:UI.render() {{{2 "FUNCTION: s:UI._stripMarkup(line, removeLeadingSpaces){{{1
"returns the given line with all the tree parts stripped off
"
"Args:
"line: the subject line
"removeLeadingSpaces: 1 if leading spaces are to be removed (leading spaces =
"any spaces before the actual text of the node)
function! s:UI._stripMarkup(line, removeLeadingSpaces)
let line = a:line
"remove the tree parts and the leading space
let line = substitute (line, g:NERDTreeUI.MarkupReg(),"","")
"strip off any read only flag
let line = substitute (line, ' \[RO\]', "","")
"strip off any bookmark flags
let line = substitute (line, ' {[^}]*}', "","")
"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
endif
let line = substitute (line,' -> .*',"","") " remove link to
if wasdir ==# 1
let line = substitute (line, '/\?$', '/', "")
endif
if a:removeLeadingSpaces
let line = substitute (line, '^ *', '', '')
endif
return line
endfunction
"FUNCTION: s:UI.render() {{{1
function! s:UI.render() function! s:UI.render()
setlocal modifiable setlocal modifiable
@ -218,7 +387,7 @@ function! s:UI.render()
"delete all lines in the buffer (being careful not to clobber a register) "delete all lines in the buffer (being careful not to clobber a register)
silent 1,$delete _ silent 1,$delete _
call nerdtree#dumpHelp() call self._dumpHelp()
"delete the blank line before the help and add one after it "delete the blank line before the help and add one after it
if g:NERDTreeMinimalUI == 0 if g:NERDTreeMinimalUI == 0
@ -227,12 +396,12 @@ function! s:UI.render()
endif endif
if b:NERDTreeShowBookmarks if b:NERDTreeShowBookmarks
call nerdtree#renderBookmarks() call self._renderBookmarks()
endif endif
"add the 'up a dir' line "add the 'up a dir' line
if !g:NERDTreeMinimalUI if !g:NERDTreeMinimalUI
call setline(line(".")+1, nerdtree#treeUpDirLine()) call setline(line(".")+1, s:UI.UpDirLine())
call cursor(line(".")+1, col(".")) call cursor(line(".")+1, col("."))
endif endif
@ -295,7 +464,7 @@ function! s:UI.toggleShowBookmarks()
let b:NERDTreeShowBookmarks = !b:NERDTreeShowBookmarks let b:NERDTreeShowBookmarks = !b:NERDTreeShowBookmarks
if b:NERDTreeShowBookmarks if b:NERDTreeShowBookmarks
call b:NERDTree.render() call b:NERDTree.render()
call nerdtree#putCursorOnBookmarkTable() call g:NERDTree.CursorToBookmarkTable()
else else
call b:NERDTree.ui.renderViewSavingPosition() call b:NERDTree.ui.renderViewSavingPosition()
endif endif
@ -330,3 +499,8 @@ function! s:UI.toggleZoom()
let b:NERDTreeZoomed = 1 let b:NERDTreeZoomed = 1
endif endif
endfunction endfunction
"FUNCTION: s:UI.UpDirLine() {{{1
function! s:UI.UpDirLine()
return '.. (up a dir)'
endfunction

View file

@ -148,7 +148,7 @@ call nerdtree#ui_glue#setupCommands()
"============================================================ "============================================================
augroup NERDTree augroup NERDTree
"Save the cursor position whenever we close the nerd tree "Save the cursor position whenever we close the nerd tree
exec "autocmd BufLeave ". g:NERDTreeCreator.BufNamePrefix() ."* call b:NERDTree.ui.saveScreenState()" exec "autocmd BufLeave ". g:NERDTreeCreator.BufNamePrefix() ."* if g:NERDTree.IsOpen() | call b:NERDTree.ui.saveScreenState() | endif"
"disallow insert mode in the NERDTree "disallow insert mode in the NERDTree
exec "autocmd BufEnter ". g:NERDTreeCreator.BufNamePrefix() ."* stopinsert" exec "autocmd BufEnter ". g:NERDTreeCreator.BufNamePrefix() ."* stopinsert"
@ -185,8 +185,8 @@ function! NERDTreeRender()
endfunction endfunction
function! NERDTreeFocus() function! NERDTreeFocus()
if nerdtree#isTreeOpen() if g:NERDTree.IsOpen()
call nerdtree#putCursorInTreeWin() call g:NERDTree.CursorToTreeWin()
else else
call g:NERDTreeCreator.TogglePrimary("") call g:NERDTreeCreator.TogglePrimary("")
endif endif
@ -196,6 +196,11 @@ function! NERDTreeCWD()
call NERDTreeFocus() call NERDTreeFocus()
call nerdtree#ui_glue#chRootCwd() call nerdtree#ui_glue#chRootCwd()
endfunction endfunction
function! NERDTreeAddPathFilter(callback)
call g:NERDTree.AddPathFilter(a:callback)
endfunction
" SECTION: Post Source Actions {{{1 " SECTION: Post Source Actions {{{1
call nerdtree#postSourceActions() call nerdtree#postSourceActions()

View file

@ -53,21 +53,22 @@ are detected, the user is notified and is happy because they didn't have to
compile their code or execute their script to find them. compile their code or execute their script to find them.
At the time of this writing, syntastic has checking plugins for ActionScript, At the time of this writing, syntastic has checking plugins for ActionScript,
Ada, API Blueprint, AppleScript, AsciiDoc, ASM, BEMHTML, Bro, Bourne shell, Ada, API Blueprint, AppleScript, AsciiDoc, ASM, BEMHTML, Bro, Bourne shell, C,
C, C++, C#, Cabal, Chef, CoffeeScript, Coco, Coq, CSS, Cucumber, CUDA, D, C++, C#, Cabal, Chef, CoffeeScript, Coco, Coq, CSS, Cucumber, CUDA, D, Dart,
Dart, DocBook, Dust, Elixir, Erlang, eRuby, Fortran, Gentoo metadata, GLSL, DocBook, Dust, Elixir, Erlang, eRuby, Fortran, Gentoo metadata, GLSL, Go, Haml,
Go, Haml, Haskell, Haxe, Handlebars, HSS, HTML, Java, JavaScript, JSON, JSX, Haskell, Haxe, Handlebars, HSS, HTML, Java, JavaScript, JSON, JSX, LESS, Lex,
LESS, Lex, Limbo, LISP, LLVM intermediate language, Lua, Markdown, MATLAB, Limbo, LISP, LLVM intermediate language, Lua, Markdown, MATLAB, Mercury, NASM,
NASM, Objective-C, Objective-C++, OCaml, Perl, Perl POD, PHP, gettext Portable Nix, Objective-C, Objective-C++, OCaml, Perl, Perl POD, PHP, gettext Portable
Object, OS X and iOS property lists, Puppet, Python, R, Racket, Relax NG, Object, OS X and iOS property lists, Puppet, Python, R, Racket, Relax NG,
reStructuredText, RPM spec, Ruby, SASS/SCSS, Scala, Slim, SML, Tcl, TeX, reStructuredText, RPM spec, Ruby, SASS/SCSS, Scala, Slim, SML, Sphinx, Tcl,
Texinfo, Twig, TypeScript, Vala, Verilog, VHDL, VimL, xHtml, XML, XSLT, YACC, TeX, Texinfo, Twig, TypeScript, Vala, Verilog, VHDL, VimL, xHtml, XML, XSLT,
YAML, z80, Zope page templates, and zsh. See the [wiki][3] for details about YACC, YAML, z80, Zope page templates, and zsh. See the [wiki][3] for details
the corresponding supported checkers. about the corresponding supported checkers.
A number of third-party Vim plugins also provide checkers for syntastic, A number of third-party Vim plugins also provide checkers for syntastic,
for example: [omnisharp-vim][25], [rust.vim][12], [syntastic-extras][26], for example: [omnisharp-vim][25], [rust.vim][12], [syntastic-extras][26],
[syntastic-more][27], and [vim-swift][24]. [syntastic-more][27], [vim-crystal][29], [vim-eastwood][28], and
[vim-swift][24].
Below is a screenshot showing the methods that Syntastic uses to display syntax 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 errors. Note that, in practise, you will only have a subset of these methods
@ -410,7 +411,7 @@ work around it:
```vim ```vim
nnoremap <silent> <C-d> :lclose<CR>:bdelete<CR> nnoremap <silent> <C-d> :lclose<CR>:bdelete<CR>
cabbrev <silent> bd lclose\|bdelete cabbrev <silent> bd <C-r>=(getcmdtype()==#':' && getcmdpos()==1 ? 'lclose\|bdelete' : 'bd')<CR>
``` ```
<a name="otherresources"></a> <a name="otherresources"></a>
@ -456,6 +457,8 @@ a look at [jedi-vim][7], [python-mode][8], or [YouCompleteMe][9].
[25]: https://github.com/OmniSharp/omnisharp-vim [25]: https://github.com/OmniSharp/omnisharp-vim
[26]: https://github.com/myint/syntastic-extras [26]: https://github.com/myint/syntastic-extras
[27]: https://github.com/roktas/syntastic-more [27]: https://github.com/roktas/syntastic-more
[28]: https://github.com/venantius/vim-eastwood
[29]: https://github.com/rhysd/vim-crystal
<!-- <!--
vim:tw=79:sw=4: vim:tw=79:sw=4:

View file

@ -1,4 +1,4 @@
if exists("g:loaded_syntastic_c_autoload") || !exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_c_autoload') || !exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_c_autoload = 1 let g:loaded_syntastic_c_autoload = 1
@ -21,8 +21,8 @@ function! syntastic#c#ReadConfig(file) abort " {{{2
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_CHECKERS, 'ReadConfig: looking for', a:file) call syntastic#log#debug(g:_SYNTASTIC_DEBUG_CHECKERS, 'ReadConfig: looking for', a:file)
" search upwards from the current file's directory " search upwards from the current file's directory
let config = findfile(a:file, '.;') let config = syntastic#util#findFileInParent(a:file, expand('%:p:h', 1))
if config == '' if config ==# ''
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_CHECKERS, 'ReadConfig: file not found') call syntastic#log#debug(g:_SYNTASTIC_DEBUG_CHECKERS, 'ReadConfig: file not found')
return '' return ''
endif endif
@ -44,7 +44,7 @@ function! syntastic#c#ReadConfig(file) abort " {{{2
endtry endtry
" filter out empty lines and comments " filter out empty lines and comments
call filter(lines, 'v:val !~ ''\v^(\s*#|$)''') call filter(lines, 'v:val !~# ''\v^(\s*#|$)''')
" remove leading and trailing spaces " remove leading and trailing spaces
call map(lines, 'substitute(v:val, ''\m^\s\+'', "", "")') call map(lines, 'substitute(v:val, ''\m^\s\+'', "", "")')
@ -53,7 +53,7 @@ function! syntastic#c#ReadConfig(file) abort " {{{2
let parameters = [] let parameters = []
for line in lines for line in lines
let matches = matchstr(line, '\m\C^\s*-I\s*\zs.\+') let matches = matchstr(line, '\m\C^\s*-I\s*\zs.\+')
if matches != '' if matches !=# ''
" this one looks like an absolute path " this one looks like an absolute path
if match(matches, '\m^\%(/\|\a:\)') != -1 if match(matches, '\m^\%(/\|\a:\)') != -1
call add(parameters, '-I' . matches) call add(parameters, '-I' . matches)
@ -120,9 +120,9 @@ endfunction " }}}2
" register a handler dictionary object " register a handler dictionary object
function! s:_registerHandler(regex, function, args) abort " {{{2 function! s:_registerHandler(regex, function, args) abort " {{{2
let handler = {} let handler = {}
let handler["regex"] = a:regex let handler['regex'] = a:regex
let handler["func"] = function(a:function) let handler['func'] = function(a:function)
let handler["args"] = a:args let handler['args'] = a:args
call add(s:handlers, handler) call add(s:handlers, handler)
endfunction " }}}2 endfunction " }}}2
@ -223,10 +223,10 @@ function! s:_get_cflags(ft, ck, opts) abort " {{{2
" check if the user manually set some cflags " check if the user manually set some cflags
let b_cflags = s:_get_checker_var('b', a:ft, a:ck, 'cflags', '') let b_cflags = s:_get_checker_var('b', a:ft, a:ck, 'cflags', '')
if b_cflags == '' if b_cflags ==# ''
if a:ft ==# 'c' || a:ft ==# 'cpp'
" check whether to search for include files at all " check whether to search for include files at all
if !s:_get_checker_var('g', a:ft, a:ck, 'no_include_search', 0) if !s:_get_checker_var('g', a:ft, a:ck, 'no_include_search', 0)
if a:ft ==# 'c' || a:ft ==# 'cpp'
" refresh the include file search if desired " refresh the include file search if desired
if s:_get_checker_var('g', a:ft, a:ck, 'auto_refresh_includes', 0) if s:_get_checker_var('g', a:ft, a:ck, 'auto_refresh_includes', 0)
let flags .= ' ' . s:_search_headers() let flags .= ' ' . s:_search_headers()
@ -280,15 +280,15 @@ function! s:_search_headers() abort " {{{2
" search current buffer " search current buffer
for line in lines for line in lines
let file = matchstr(line, '\m"\zs\S\+\ze"') let file = matchstr(line, '\m"\zs\S\+\ze"')
if file != '' if file !=# ''
call add(files, file) call add(files, file)
continue continue
endif endif
for handler in s:handlers for handler in s:handlers
if line =~# handler["regex"] if line =~# handler['regex']
let includes .= call(handler["func"], handler["args"]) let includes .= call(handler['func'], handler['args'])
call add(found, handler["regex"]) call add(found, handler['regex'])
break break
endif endif
endfor endfor
@ -296,7 +296,7 @@ function! s:_search_headers() abort " {{{2
" search included headers " search included headers
for hfile in files for hfile in files
if hfile != '' if hfile !=# ''
let filename = expand('%:p:h', 1) . syntastic#util#Slash() . hfile let filename = expand('%:p:h', 1) . syntastic#util#Slash() . hfile
try try
@ -308,14 +308,14 @@ function! s:_search_headers() abort " {{{2
call filter(lines, 'v:val =~# ''\m^\s*#\s*include''') call filter(lines, 'v:val =~# ''\m^\s*#\s*include''')
for handler in s:handlers for handler in s:handlers
if index(found, handler["regex"]) != -1 if index(found, handler['regex']) != -1
continue continue
endif endif
for line in lines for line in lines
if line =~# handler["regex"] if line =~# handler['regex']
let includes .= call(handler["func"], handler["args"]) let includes .= call(handler['func'], handler['args'])
call add(found, handler["regex"]) call add(found, handler['regex'])
break break
endif endif
endfor endfor

View file

@ -1,4 +1,4 @@
if exists("g:loaded_syntastic_log_autoload") || !exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_log_autoload') || !exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_log_autoload = 1 let g:loaded_syntastic_log_autoload = 1
@ -11,19 +11,19 @@ let s:one_time_notices_issued = []
" Public functions {{{1 " Public functions {{{1
function! syntastic#log#info(msg) abort " {{{2 function! syntastic#log#info(msg) abort " {{{2
echomsg "syntastic: info: " . a:msg echomsg 'syntastic: info: ' . a:msg
endfunction " }}}2 endfunction " }}}2
function! syntastic#log#warn(msg) abort " {{{2 function! syntastic#log#warn(msg) abort " {{{2
echohl WarningMsg echohl WarningMsg
echomsg "syntastic: warning: " . a:msg echomsg 'syntastic: warning: ' . a:msg
echohl None echohl None
endfunction " }}}2 endfunction " }}}2
function! syntastic#log#error(msg) abort " {{{2 function! syntastic#log#error(msg) abort " {{{2
execute "normal \<Esc>" execute "normal \<Esc>"
echohl ErrorMsg echohl ErrorMsg
echomsg "syntastic: error: " . a:msg echomsg 'syntastic: error: ' . a:msg
echohl None echohl None
endfunction " }}}2 endfunction " }}}2
@ -88,9 +88,9 @@ function! syntastic#log#debugShowOptions(level, names) abort " {{{2
let leader = s:_log_timestamp() let leader = s:_log_timestamp()
call s:_logRedirect(1) call s:_logRedirect(1)
let vlist = copy(type(a:names) == type("") ? [a:names] : a:names) let vlist = copy(type(a:names) == type('') ? [a:names] : a:names)
if !empty(vlist) if !empty(vlist)
call map(vlist, "'&' . v:val . ' = ' . strtrans(string(eval('&' . v:val)))") call map(vlist, "'&' . v:val . ' = ' . strtrans(string(eval('&' . v:val))) . (s:_is_modified(v:val) ? ' (!)' : '')")
echomsg leader . join(vlist, ', ') echomsg leader . join(vlist, ', ')
endif endif
call s:_logRedirect(0) call s:_logRedirect(0)
@ -104,10 +104,10 @@ function! syntastic#log#debugShowVariables(level, names) abort " {{{2
let leader = s:_log_timestamp() let leader = s:_log_timestamp()
call s:_logRedirect(1) call s:_logRedirect(1)
let vlist = type(a:names) == type("") ? [a:names] : a:names let vlist = type(a:names) == type('') ? [a:names] : a:names
for name in vlist for name in vlist
let msg = s:_format_variable(name) let msg = s:_format_variable(name)
if msg != '' if msg !=# ''
echomsg leader . msg echomsg leader . msg
endif endif
endfor endfor
@ -123,6 +123,21 @@ function! syntastic#log#debugDump(level) abort " {{{2
call syntastic#log#debugShowVariables( a:level, sort(keys(g:_SYNTASTIC_DEFAULTS)) ) call syntastic#log#debugShowVariables( a:level, sort(keys(g:_SYNTASTIC_DEFAULTS)) )
endfunction " }}}2 endfunction " }}}2
function! syntastic#log#ndebug(level, title, messages) abort " {{{2
if s:_isDebugEnabled(a:level)
return
endif
call syntastic#log#error(a:title)
if type(a:messages) == type([])
for msg in a:messages
echomsg msg
endfor
else
echomsg a:messages
endif
endfunction " }}}2
" }}}1 " }}}1
" Private functions {{{1 " Private functions {{{1
@ -140,7 +155,7 @@ let s:_isDebugEnabled = function(exists('*and') ? 's:_isDebugEnabled_smart' : 's
lockvar s:_isDebugEnabled lockvar s:_isDebugEnabled
function! s:_logRedirect(on) abort " {{{2 function! s:_logRedirect(on) abort " {{{2
if exists("g:syntastic_debug_file") if exists('g:syntastic_debug_file')
if a:on if a:on
try try
execute 'redir >> ' . fnameescape(expand(g:syntastic_debug_file, 1)) execute 'redir >> ' . fnameescape(expand(g:syntastic_debug_file, 1))
@ -174,6 +189,20 @@ function! s:_format_variable(name) abort " {{{2
return join(vals, ', ') return join(vals, ', ')
endfunction " }}}2 endfunction " }}}2
function! s:_is_modified(name) abort " {{{2
if !exists('s:option_defaults')
let s:option_defaults = {}
endif
if !has_key(s:option_defaults, a:name)
let opt_save = eval('&' . a:name)
execute 'set ' . a:name . '&'
let s:option_defaults[a:name] = eval('&' . a:name)
execute 'let &' . a:name . ' = ' . string(opt_save)
endif
return s:option_defaults[a:name] !=# eval('&' . a:name)
endfunction " }}}2
" }}}1 " }}}1
let &cpo = s:save_cpo let &cpo = s:save_cpo

View file

@ -1,4 +1,4 @@
if exists("g:loaded_syntastic_postprocess_autoload") || !exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_postprocess_autoload') || !exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_postprocess_autoload = 1 let g:loaded_syntastic_postprocess_autoload = 1

View file

@ -1,4 +1,4 @@
if exists("g:loaded_syntastic_preprocess_autoload") || !exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_preprocess_autoload') || !exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_preprocess_autoload = 1 let g:loaded_syntastic_preprocess_autoload = 1
@ -13,14 +13,14 @@ function! syntastic#preprocess#cabal(errors) abort " {{{2
let star = 0 let star = 0
for err in a:errors for err in a:errors
if star if star
if err == '' if err ==# ''
let star = 0 let star = 0
else else
let out[-1] .= ' ' . err let out[-1] .= ' ' . err
endif endif
else else
call add(out, err) call add(out, err)
if err =~ '\m^*\s' if err =~# '\m^*\s'
let star = 1 let star = 1
endif endif
endif endif
@ -68,10 +68,15 @@ function! syntastic#preprocess#flow(errors) abort " {{{2
let false = 0 let false = 0
let null = '' let null = ''
let idx = 0
while idx < len(a:errors) && a:errors[idx][0] != '{'
let idx += 1
endwhile
" A hat tip to Marc Weber for this trick " A hat tip to Marc Weber for this trick
" http://stackoverflow.com/questions/17751186/iterating-over-a-string-in-vimscript-or-parse-a-json-file/19105763#19105763 " http://stackoverflow.com/questions/17751186/iterating-over-a-string-in-vimscript-or-parse-a-json-file/19105763#19105763
try try
let errs = eval(join(a:errors, '')) let errs = eval(join(a:errors[idx :], ''))
catch catch
let errs = {} let errs = {}
endtry endtry
@ -88,7 +93,7 @@ function! syntastic#preprocess#flow(errors) abort " {{{2
\ m['path'] . ':' . \ m['path'] . ':' .
\ m['line'] . ':' . \ m['line'] . ':' .
\ m['start'] . ':' . \ m['start'] . ':' .
\ (m['line'] ==# m['endline'] ? m['end'] . ':' : '') . \ (m['line'] ==# m['endline'] && str2nr(m['end']) > 0 ? m['end'] . ':' : '') .
\ ' ' . m['descr'] \ ' ' . m['descr']
if len(t) if len(t)
@ -123,8 +128,15 @@ endfunction " }}}2
" @vimlint(EVL102, 0, l:false) " @vimlint(EVL102, 0, l:false)
" @vimlint(EVL102, 0, l:null) " @vimlint(EVL102, 0, l:null)
function! syntastic#preprocess#iconv(errors) abort " {{{2
return
\ (has('iconv') || has('iconv/dyn')) && &encoding !=# '' && &encoding !=# 'utf-8' ?
\ map(a:errors, 'iconv(v:val, "utf-8", &encoding)') :
\ a:errors
endfunction " }}}2
function! syntastic#preprocess#killEmpty(errors) abort " {{{2 function! syntastic#preprocess#killEmpty(errors) abort " {{{2
return filter(copy(a:errors), 'v:val != ""') return filter(copy(a:errors), 'v:val !=# ""')
endfunction " }}}2 endfunction " }}}2
function! syntastic#preprocess#perl(errors) abort " {{{2 function! syntastic#preprocess#perl(errors) abort " {{{2
@ -204,7 +216,7 @@ function! syntastic#preprocess#rparse(errors) abort " {{{2
" remove uninteresting lines and handle continuations " remove uninteresting lines and handle continuations
let i = 0 let i = 0
while i < len(errlist) while i < len(errlist)
if i > 0 && errlist[i][:1] == ' ' && errlist[i] !~ '\m\s\+\^$' if i > 0 && errlist[i][:1] ==# ' ' && errlist[i] !~# '\m\s\+\^$'
let errlist[i-1] .= errlist[i][1:] let errlist[i-1] .= errlist[i][1:]
call remove(errlist, i) call remove(errlist, i)
elseif errlist[i] !~# '\m^\(Lint:\|Lint checking:\|Error in\) ' elseif errlist[i] !~# '\m^\(Lint:\|Lint checking:\|Error in\) '
@ -224,7 +236,7 @@ function! syntastic#preprocess#rparse(errors) abort " {{{2
call add(out, 'E:' . fname . ':' . line . ': ' . parts[1]) call add(out, 'E:' . fname . ':' . line . ': ' . parts[1])
endfor endfor
endif endif
if len(parts) >= 5 && parts[4] != '' if len(parts) >= 5 && parts[4] !=# ''
call add(out, 'E:' . fname . ':0: ' . parts[1] . ' - ' . parts[4] . ' messages not shown') call add(out, 'E:' . fname . ':0: ' . parts[1] . ' - ' . parts[4] . ' messages not shown')
endif endif
elseif match(e, '\m^Lint checking: ') == 0 elseif match(e, '\m^Lint checking: ') == 0

View file

@ -1,4 +1,4 @@
if exists('g:loaded_syntastic_util_autoload') || !exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_util_autoload') || !exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_util_autoload = 1 let g:loaded_syntastic_util_autoload = 1
@ -21,7 +21,7 @@ endfunction " }}}2
" Get directory separator " Get directory separator
function! syntastic#util#Slash() abort " {{{2 function! syntastic#util#Slash() abort " {{{2
return (!exists("+shellslash") || &shellslash) ? '/' : '\' return (!exists('+shellslash') || &shellslash) ? '/' : '\'
endfunction " }}}2 endfunction " }}}2
function! syntastic#util#CygwinPath(path) abort " {{{2 function! syntastic#util#CygwinPath(path) abort " {{{2
@ -53,19 +53,19 @@ function! syntastic#util#tmpdir() abort " {{{2
if (has('unix') || has('mac')) && executable('mktemp') if (has('unix') || has('mac')) && executable('mktemp')
" TODO: option "-t" to mktemp(1) is not portable " TODO: option "-t" to mktemp(1) is not portable
let tmp = $TMPDIR != '' ? $TMPDIR : $TMP != '' ? $TMP : '/tmp' let tmp = $TMPDIR !=# '' ? $TMPDIR : $TMP !=# '' ? $TMP : '/tmp'
let out = split(syntastic#util#system('mktemp -q -d ' . tmp . '/vim-syntastic-' . getpid() . '-XXXXXXXX'), "\n") let out = split(syntastic#util#system('mktemp -q -d ' . tmp . '/vim-syntastic-' . getpid() . '-XXXXXXXX'), "\n")
if v:shell_error == 0 && len(out) == 1 if v:shell_error == 0 && len(out) == 1
let tempdir = out[0] let tempdir = out[0]
endif endif
endif endif
if tempdir == '' if tempdir ==# ''
if has('win32') || has('win64') if has('win32') || has('win64')
let tempdir = $TEMP . syntastic#util#Slash() . 'vim-syntastic-' . getpid() let tempdir = $TEMP . syntastic#util#Slash() . 'vim-syntastic-' . getpid()
elseif has('win32unix') elseif has('win32unix')
let tempdir = syntastic#util#CygwinPath('/tmp/vim-syntastic-' . getpid()) let tempdir = syntastic#util#CygwinPath('/tmp/vim-syntastic-' . getpid())
elseif $TMPDIR != '' elseif $TMPDIR !=# ''
let tempdir = $TMPDIR . '/vim-syntastic-' . getpid() let tempdir = $TMPDIR . '/vim-syntastic-' . getpid()
else else
let tempdir = '/tmp/vim-syntastic-' . getpid() let tempdir = '/tmp/vim-syntastic-' . getpid()
@ -97,7 +97,7 @@ function! syntastic#util#rmrf(what) abort " {{{2
\ has('win16') || has('win95') || has('dos16') || has('dos32') ? 'deltree /Y' : '' \ has('win16') || has('win95') || has('dos16') || has('dos32') ? 'deltree /Y' : ''
endif endif
if s:rmrf != '' if s:rmrf !=# ''
silent! call syntastic#util#system(s:rmrf . ' ' . syntastic#util#shescape(a:what)) silent! call syntastic#util#system(s:rmrf . ' ' . syntastic#util#shescape(a:what))
else else
call s:_rmrf(a:what) call s:_rmrf(a:what)
@ -120,7 +120,7 @@ endfunction " }}}2
function! syntastic#util#parseShebang() abort " {{{2 function! syntastic#util#parseShebang() abort " {{{2
for lnum in range(1, 5) for lnum in range(1, 5)
let line = getline(lnum) let line = getline(lnum)
if line =~ '^#!' if line =~# '^#!'
let line = substitute(line, '\v^#!\s*(\S+/env(\s+-\S+)*\s+)?', '', '') let line = substitute(line, '\v^#!\s*(\S+/env(\s+-\S+)*\s+)?', '', '')
let exe = matchstr(line, '\m^\S*\ze') let exe = matchstr(line, '\m^\S*\ze')
let args = split(matchstr(line, '\m^\S*\zs.*')) let args = split(matchstr(line, '\m^\S*\zs.*'))
@ -140,8 +140,8 @@ function! syntastic#util#var(name, ...) abort " {{{2
endfunction " }}}2 endfunction " }}}2
" Parse a version string. Return an array of version components. " Parse a version string. Return an array of version components.
function! syntastic#util#parseVersion(version) abort " {{{2 function! syntastic#util#parseVersion(version, ...) abort " {{{2
return map(split(matchstr( a:version, '\v^\D*\zs\d+(\.\d+)+\ze' ), '\m\.'), 'str2nr(v:val)') return map(split(matchstr( a:version, a:0 ? a:1 : '\v^\D*\zs\d+(\.\d+)+\ze' ), '\m\.'), 'str2nr(v:val)')
endfunction " }}}2 endfunction " }}}2
" Verify that the 'installed' version is at least the 'required' version. " Verify that the 'installed' version is at least the 'required' version.
@ -164,7 +164,7 @@ function! syntastic#util#compareLexi(a, b) abort " {{{2
return a_element > b_element ? 1 : -1 return a_element > b_element ? 1 : -1
endif endif
endfor endfor
" Everything matched, so it is at least the required version. " still here, thus everything matched
return 0 return 0
endfunction " }}}2 endfunction " }}}2
@ -190,7 +190,7 @@ function! syntastic#util#wideMsg(msg) abort " {{{2
"This is here because it is possible for some error messages to "This is here because it is possible for some error messages to
"begin with \n which will cause a "press enter" prompt. "begin with \n which will cause a "press enter" prompt.
let msg = substitute(a:msg, "\n", "", "g") let msg = substitute(a:msg, "\n", '', 'g')
"convert tabs to spaces so that the tabs count towards the window "convert tabs to spaces so that the tabs count towards the window
"width as the proper amount of characters "width as the proper amount of characters
@ -226,13 +226,23 @@ function! syntastic#util#bufIsActive(buffer) abort " {{{2
return 0 return 0
endfunction " }}}2 endfunction " }}}2
" start in directory a:where and walk up the parent folders until it " start in directory a:where and walk up the parent folders until it finds a
" finds a file matching a:what; return path to that file " file named a:what; return path to that file
function! syntastic#util#findInParent(what, where) abort " {{{2 function! syntastic#util#findFileInParent(what, where) abort " {{{2
let old_suffixesadd = &suffixesadd
let &suffixesadd = ''
let file = findfile(a:what, escape(a:where, ' ') . ';')
let &suffixesadd = old_suffixesadd
return file
endfunction " }}}2
" start in directory a:where and walk up the parent folders until it finds a
" file matching a:what; return path to that file
function! syntastic#util#findGlobInParent(what, where) abort " {{{2
let here = fnamemodify(a:where, ':p') let here = fnamemodify(a:where, ':p')
let root = syntastic#util#Slash() let root = syntastic#util#Slash()
if syntastic#util#isRunningWindows() && here[1] == ':' if syntastic#util#isRunningWindows() && here[1] ==# ':'
" The drive letter is an ever-green source of fun. That's because " The drive letter is an ever-green source of fun. That's because
" we don't care about running syntastic on Amiga these days. ;) " we don't care about running syntastic on Amiga these days. ;)
let root = fnamemodify(root, ':p') let root = fnamemodify(root, ':p')
@ -240,7 +250,7 @@ function! syntastic#util#findInParent(what, where) abort " {{{2
endif endif
let old = '' let old = ''
while here != '' while here !=# ''
let p = split(globpath(here, a:what, 1), '\n') let p = split(globpath(here, a:what, 1), '\n')
if !empty(p) if !empty(p)
@ -284,7 +294,7 @@ endfunction " }}}2
" Escape arguments " Escape arguments
function! syntastic#util#argsescape(opt) abort " {{{2 function! syntastic#util#argsescape(opt) abort " {{{2
if type(a:opt) == type('') && a:opt != '' if type(a:opt) == type('') && a:opt !=# ''
return [a:opt] return [a:opt]
elseif type(a:opt) == type([]) elseif type(a:opt) == type([])
return map(copy(a:opt), 'syntastic#util#shescape(v:val)') return map(copy(a:opt), 'syntastic#util#shescape(v:val)')
@ -323,11 +333,10 @@ function! syntastic#util#dictFilter(errors, filter) abort " {{{2
endtry endtry
endfunction " }}}2 endfunction " }}}2
" Return a [high, low] list of integers, representing the time " Return a [seconds, fractions] list of strings, representing the
" (hopefully high resolution) since program start " (hopefully high resolution) time since program start
" TODO: This assumes reltime() returns a list of integers.
function! syntastic#util#stamp() abort " {{{2 function! syntastic#util#stamp() abort " {{{2
return reltime(g:_SYNTASTIC_START) return split( split(reltimestr(reltime(g:_SYNTASTIC_START)))[0], '\.' )
endfunction " }}}2 endfunction " }}}2
" }}}1 " }}}1
@ -345,14 +354,14 @@ function! s:_translateFilter(filters) abort " {{{2
endfor endfor
if conditions == [] if conditions == []
let conditions = ["1"] let conditions = ['1']
endif endif
return len(conditions) == 1 ? conditions[0] : join(map(conditions, '"(" . v:val . ")"'), ' && ') return len(conditions) == 1 ? conditions[0] : join(map(conditions, '"(" . v:val . ")"'), ' && ')
endfunction " }}}2 endfunction " }}}2
function! s:_translateElement(key, term) abort " {{{2 function! s:_translateElement(key, term) abort " {{{2
let fkey = a:key let fkey = a:key
if fkey[0] == '!' if fkey[0] ==# '!'
let fkey = fkey[1:] let fkey = fkey[1:]
let not = 1 let not = 1
else else
@ -377,13 +386,13 @@ function! s:_translateElement(key, term) abort " {{{2
let op = not ? ' =~# ' : ' !~# ' let op = not ? ' =~# ' : ' !~# '
let ret = 'bufname(str2nr(v:val["bufnr"]))' let ret = 'bufname(str2nr(v:val["bufnr"]))'
let mod = fkey[4:] let mod = fkey[4:]
if mod != '' if mod !=# ''
let ret = 'fnamemodify(' . ret . ', ' . string(mod) . ')' let ret = 'fnamemodify(' . ret . ', ' . string(mod) . ')'
endif endif
let ret .= op . string(a:term) let ret .= op . string(a:term)
else else
call syntastic#log#warn('quiet_messages: ignoring invalid key ' . strtrans(string(fkey))) call syntastic#log#warn('quiet_messages: ignoring invalid key ' . strtrans(string(fkey)))
let ret = "1" let ret = '1'
endif endif
return ret return ret
endfunction " }}}2 endfunction " }}}2

View file

@ -40,16 +40,21 @@ CONTENTS *syntastic-contents*
6.1.Handling of composite filetypes........|syntastic-composite| 6.1.Handling of composite filetypes........|syntastic-composite|
6.2.Editing files over network.............|syntastic-netrw| 6.2.Editing files over network.............|syntastic-netrw|
6.3.The 'shellslash' option................|syntastic-shellslash| 6.3.The 'shellslash' option................|syntastic-shellslash|
6.4.Saving Vim sessions....................|syntastic-sessions|
7.Compatibility with other software............|syntastic-compatibility| 7.Compatibility with other software............|syntastic-compatibility|
7.1.The csh and tcsh shells................|syntastic-csh| 7.1.The csh and tcsh shells................|syntastic-csh|
7.2.Eclim..................................|syntastic-eclim| 7.2.Eclim..................................|syntastic-eclim|
7.3.The fish shell.........................|syntastic-fish| 7.3.The fish shell.........................|syntastic-fish|
7.4.The fizsh shell........................|syntastic-fizsh| 7.4.The fizsh shell........................|syntastic-fizsh|
7.5.The PowerShell shell...................|syntastic-powershell| 7.5.flagship...............................|syntastic-flagship|
7.6.python-mode............................|syntastic-pymode| 7.6.powerline..............................|syntastic-powerline|
7.7.vim-auto-save..........................|syntastic-vim-auto-save| 7.7.The PowerShell shell...................|syntastic-powershell|
7.8.vim-virtualenv.........................|syntastic-vim-virtualenv| 7.8.python-mode............................|syntastic-pymode|
7.9.YouCompleteMe..........................|syntastic-ycm| 7.9.vim-auto-save..........................|syntastic-vim-auto-save|
7.10.vim-go................................|syntastic-vim-go|
7.11.vim-virtualenv........................|syntastic-vim-virtualenv|
7.12.YouCompleteMe.........................|syntastic-ycm|
7.13.The zsh shell and rvm.................|syntastic-zsh|
8.About........................................|syntastic-about| 8.About........................................|syntastic-about|
9.License......................................|syntastic-license| 9.License......................................|syntastic-license|
@ -457,7 +462,7 @@ Use this option to map non-standard filetypes to standard ones. Corresponding
checkers are mapped accordingly, which allows syntastic to check files with checkers are mapped accordingly, which allows syntastic to check files with
non-standard filetypes: > non-standard filetypes: >
let g:syntastic_filetype_map = { let g:syntastic_filetype_map = {
\ "latex": "tex", \ "plaintex": "tex",
\ "gentoo-metadata": "xml" } \ "gentoo-metadata": "xml" }
< <
Composite filetypes can also be mapped to simple types, which disables the Composite filetypes can also be mapped to simple types, which disables the
@ -809,6 +814,16 @@ shell. It should be turned off if your 'shell' (or |g:syntastic_shell|) is
"sh". Most checkers will stop working if 'shellslash' is set to the wrong "sh". Most checkers will stop working if 'shellslash' is set to the wrong
value. value.
------------------------------------------------------------------------------
6.4 Saving Vim sessions *syntastic-sessions*
If you use |:mksession| to save Vim sessions you should probably make sure to
remove option "blank" from 'sessionoptions': >
set sessionoptions-=blank
<
This will prevent |:mksession| from saving |syntastic-error-window| as empty
quickfix windows.
============================================================================== ==============================================================================
7. Compatibility with other software *syntastic-compatibility* 7. Compatibility with other software *syntastic-compatibility*
@ -858,7 +873,34 @@ interactive features of "fizsh". Using a more traditional shell such as "zsh",
let g:syntastic_shell = "/bin/sh" let g:syntastic_shell = "/bin/sh"
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
7.5. The PowerShell shell *syntastic-powershell* 7.5 flagship *syntastic-flagship*
The "flagship" Vim plugin (https://github.com/tpope/vim-flagship) has its
own mechanism of showing flags on the |'statusline'|. To allow "flagship"
to manage syntastic's statusline flag add the following |autocommand| to
your vimrc, rather than explicitly adding the flag to your |'statusline'| as
described in the |syntastic-statusline-flag| section above: >
autocmd User Flags call Hoist("window", "SyntasticStatuslineFlag")
<
------------------------------------------------------------------------------
7.6. powerline *syntastic-powerline*
The "powerline" Vim plugin (https://github.com/powerline/powerline) comes
packaged with a syntastic segment. To customize this segment create a file
~/.config/powerline/themes/vim/default.json, with a content like this: >
{
"segment_data" : {
"powerline.segments.vim.plugin.syntastic.syntastic" : {
"args" : {
"err_format" : "Err: {first_line} #{num} ",
"warn_format" : "Warn: {first_line} #{num} "
}
}
}
}
<
------------------------------------------------------------------------------
7.7. The PowerShell shell *syntastic-powershell*
At the time of this writing, syntastic is not compatible with using "Windows At the time of this writing, syntastic is not compatible with using "Windows
PowerShell" (http://technet.microsoft.com/en-us/library/bb978526.aspx) as Vim's PowerShell" (http://technet.microsoft.com/en-us/library/bb978526.aspx) as Vim's
@ -867,7 +909,7 @@ Vim's 'shell' to a more traditional program, such as "cmd.exe": >
set shell=cmd.exe set shell=cmd.exe
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
7.6 python-mode *syntastic-pymode* 7.8 python-mode *syntastic-pymode*
Syntastic can be used along with the "python-mode" Vim plugin (see Syntastic can be used along with the "python-mode" Vim plugin (see
https://github.com/klen/python-mode). However, they both run syntax checks by https://github.com/klen/python-mode). However, they both run syntax checks by
@ -878,14 +920,27 @@ for python in syntastic (see |syntastic_mode_map|), or disable lint checks in
let g:pymode_lint_write = 0 let g:pymode_lint_write = 0
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
7.7. vim-auto-save *syntastic-vim-auto-save* 7.9. vim-auto-save *syntastic-vim-auto-save*
Syntastic can be used together with the "vim-auto-save" Vim plugin (see Syntastic can be used together with the "vim-auto-save" Vim plugin (see
https://github.com/907th/vim-auto-save). However, syntastic checks in active https://github.com/907th/vim-auto-save). However, syntastic checks in active
mode only work with "vim-auto-save" version 0.1.7 or later. mode only work with "vim-auto-save" version 0.1.7 or later.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
7.8. vim-virtualenv *syntastic-vim-virtualenv* 7.10. vim-go *syntastic-vim-go*
The "vim-go" Vim plugin (https://github.com/fatih/vim-go) uses |quickfix|
lists, and thus doesn't conflict with syntastic (which uses |location-list|
lists). However, both "vim-go" and syntastic run syntax checks by default
when you save buffers to disk, and this can have confusing results. To
avoid both plugins opening error windows, you can either set passive
mode for go in syntastic (see |syntastic_mode_map|), or prevent "vim-go"
from showing a quickfix window when |g:go_fmt_command| fails, by setting
|g:go_fmt_fail_silently| to 1. E.g.: >
let g:go_fmt_fail_silently = 1
<
------------------------------------------------------------------------------
7.11. vim-virtualenv *syntastic-vim-virtualenv*
At the time of this writing, syntastic can't run checkers installed At the time of this writing, syntastic can't run checkers installed
in Python virtual environments activated by "vim-virtualenv" (see in Python virtual environments activated by "vim-virtualenv" (see
@ -893,7 +948,7 @@ https://github.com/jmcantrell/vim-virtualenv). This is a limitation of
"vim-virtualenv". "vim-virtualenv".
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
7.9 YouCompleteMe *syntastic-ycm* 7.12 YouCompleteMe *syntastic-ycm*
Syntastic can be used together with the "YouCompleteMe" Vim plugin (see Syntastic can be used together with the "YouCompleteMe" Vim plugin (see
http://valloric.github.io/YouCompleteMe/). However, by default "YouCompleteMe" http://valloric.github.io/YouCompleteMe/). However, by default "YouCompleteMe"
@ -903,6 +958,18 @@ identifier completer but still run syntastic's checkers for those filetypes you
have to set |ycm_show_diagnostics_ui| to 0. E.g.: > have to set |ycm_show_diagnostics_ui| to 0. E.g.: >
let g:ycm_show_diagnostics_ui = 0 let g:ycm_show_diagnostics_ui = 0
< <
------------------------------------------------------------------------------
7.13 The zsh shell and rvm *syntastic-zsh*
If you're running MacVim together with the "zsh" shell (http://www.zsh.org/)
and "rvm" (https://rvm.io/), you need to be aware that MacVim does not source
the .zshrc file, but will source a .zshenv file. Consequently you have to
either source the "rvm" scripts from within .zshenv, or just change your shell
to something else: >
set shell=/bin/sh
<
Of course, you'll have to make sure "rvm" still works in the new shell.
============================================================================== ==============================================================================
8. About *syntastic-about* 8. About *syntastic-about*

View file

@ -9,7 +9,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_plugin = 1 let g:loaded_syntastic_plugin = 1
@ -19,7 +19,7 @@ if has('reltime')
lockvar! g:_SYNTASTIC_START lockvar! g:_SYNTASTIC_START
endif endif
let g:_SYNTASTIC_VERSION = '3.6.0-57' let g:_SYNTASTIC_VERSION = '3.6.0-122'
lockvar g:_SYNTASTIC_VERSION lockvar g:_SYNTASTIC_VERSION
" Sanity checks {{{1 " Sanity checks {{{1
@ -34,7 +34,7 @@ for s:feature in [
\ 'user_commands' \ 'user_commands'
\ ] \ ]
if !has(s:feature) if !has(s:feature)
call syntastic#log#error("need Vim compiled with feature " . s:feature) call syntastic#log#error('need Vim compiled with feature ' . s:feature)
finish finish
endif endif
endfor endfor
@ -104,7 +104,7 @@ for s:key in keys(g:_SYNTASTIC_DEFAULTS)
endif endif
endfor endfor
if exists("g:syntastic_quiet_warnings") if exists('g:syntastic_quiet_warnings')
call syntastic#log#oneTimeWarn("variable g:syntastic_quiet_warnings is deprecated, please use let g:syntastic_quiet_messages = {'level': 'warnings'} instead") call syntastic#log#oneTimeWarn("variable g:syntastic_quiet_warnings is deprecated, please use let g:syntastic_quiet_messages = {'level': 'warnings'} instead")
if g:syntastic_quiet_warnings if g:syntastic_quiet_warnings
let s:quiet_warnings = get(g:syntastic_quiet_messages, 'type', []) let s:quiet_warnings = get(g:syntastic_quiet_messages, 'type', [])
@ -246,29 +246,29 @@ endif
function! s:BufReadPostHook() abort " {{{2 function! s:BufReadPostHook() abort " {{{2
if g:syntastic_check_on_open if g:syntastic_check_on_open
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_AUTOCOMMANDS, call syntastic#log#debug(g:_SYNTASTIC_DEBUG_AUTOCOMMANDS,
\ 'autocmd: BufReadPost, buffer ' . bufnr("") . ' = ' . string(bufname(str2nr(bufnr(""))))) \ 'autocmd: BufReadPost, buffer ' . bufnr('') . ' = ' . string(bufname(str2nr(bufnr('')))))
call s:UpdateErrors(1, []) call s:UpdateErrors(1, [])
endif endif
endfunction " }}}2 endfunction " }}}2
function! s:BufWritePostHook() abort " {{{2 function! s:BufWritePostHook() abort " {{{2
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_AUTOCOMMANDS, call syntastic#log#debug(g:_SYNTASTIC_DEBUG_AUTOCOMMANDS,
\ 'autocmd: BufWritePost, buffer ' . bufnr("") . ' = ' . string(bufname(str2nr(bufnr(""))))) \ 'autocmd: BufWritePost, buffer ' . bufnr('') . ' = ' . string(bufname(str2nr(bufnr('')))))
call s:UpdateErrors(1, []) call s:UpdateErrors(1, [])
endfunction " }}}2 endfunction " }}}2
function! s:BufEnterHook() abort " {{{2 function! s:BufEnterHook() abort " {{{2
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_AUTOCOMMANDS, call syntastic#log#debug(g:_SYNTASTIC_DEBUG_AUTOCOMMANDS,
\ 'autocmd: BufEnter, buffer ' . bufnr("") . ' = ' . string(bufname(str2nr(bufnr("")))) . \ 'autocmd: BufEnter, buffer ' . bufnr('') . ' = ' . string(bufname(str2nr(bufnr('')))) .
\ ', &buftype = ' . string(&buftype)) \ ', &buftype = ' . string(&buftype))
if &buftype == '' if &buftype ==# ''
call s:notifiers.refresh(g:SyntasticLoclist.current()) call s:notifiers.refresh(g:SyntasticLoclist.current())
elseif &buftype ==# 'quickfix' elseif &buftype ==# 'quickfix'
" TODO: this is needed because in recent versions of Vim lclose " TODO: this is needed because in recent versions of Vim lclose
" can no longer be called from BufWinLeave " can no longer be called from BufWinLeave
" TODO: at this point there is no b:syntastic_loclist " TODO: at this point there is no b:syntastic_loclist
let loclist = filter(copy(getloclist(0)), 'v:val["valid"] == 1') let loclist = filter(copy(getloclist(0)), 'v:val["valid"] == 1')
let owner = str2nr(getbufvar(bufnr(""), 'syntastic_owner_buffer')) let owner = str2nr(getbufvar(bufnr(''), 'syntastic_owner_buffer'))
let buffers = syntastic#util#unique(map(loclist, 'v:val["bufnr"]') + (owner ? [owner] : [])) let buffers = syntastic#util#unique(map(loclist, 'v:val["bufnr"]') + (owner ? [owner] : []))
if get(w:, 'syntastic_loclist_set', 0) && !empty(loclist) && empty(filter( buffers, 'syntastic#util#bufIsActive(v:val)' )) if get(w:, 'syntastic_loclist_set', 0) && !empty(loclist) && empty(filter( buffers, 'syntastic#util#bufIsActive(v:val)' ))
call SyntasticLoclistHide() call SyntasticLoclistHide()
@ -278,7 +278,7 @@ endfunction " }}}2
function! s:QuitPreHook() abort " {{{2 function! s:QuitPreHook() abort " {{{2
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_AUTOCOMMANDS, call syntastic#log#debug(g:_SYNTASTIC_DEBUG_AUTOCOMMANDS,
\ 'autocmd: QuitPre, buffer ' . bufnr("") . ' = ' . string(bufname(str2nr(bufnr(""))))) \ 'autocmd: QuitPre, buffer ' . bufnr('') . ' = ' . string(bufname(str2nr(bufnr('')))))
let b:syntastic_skip_checks = get(b:, 'syntastic_skip_checks', 0) || !syntastic#util#var('check_on_wq') let b:syntastic_skip_checks = get(b:, 'syntastic_skip_checks', 0) || !syntastic#util#var('check_on_wq')
if get(w:, 'syntastic_loclist_set', 0) if get(w:, 'syntastic_loclist_set', 0)
call SyntasticLoclistHide() call SyntasticLoclistHide()
@ -304,6 +304,9 @@ function! s:UpdateErrors(auto_invoked, checker_names) abort " {{{2
let run_checks = !a:auto_invoked || s:modemap.doAutoChecking() let run_checks = !a:auto_invoked || s:modemap.doAutoChecking()
if run_checks if run_checks
call s:CacheErrors(a:checker_names) call s:CacheErrors(a:checker_names)
unlockvar! b:syntastic_changedtick
let b:syntastic_changedtick = b:changedtick
lockvar! b:syntastic_changedtick
endif endif
let loclist = g:SyntasticLoclist.current() let loclist = g:SyntasticLoclist.current()
@ -335,7 +338,7 @@ function! s:UpdateErrors(auto_invoked, checker_names) abort " {{{2
" order, which can lead to missing filetype when jumping " order, which can lead to missing filetype when jumping
" to a new file; the following is a workaround for the " to a new file; the following is a workaround for the
" resulting brain damage " resulting brain damage
if &filetype == '' if &filetype ==# ''
silent! filetype detect silent! filetype detect
endif endif
endif endif
@ -544,11 +547,12 @@ function! SyntasticMake(options) abort " {{{2
let &l:errorformat = old_local_errorformat let &l:errorformat = old_local_errorformat
" }}}3 " }}}3
if !s:_running_windows && (s:_os_name() =~? "FreeBSD" || s:_os_name() =~? "OpenBSD") if !s:_running_windows && (s:_os_name() =~? 'FreeBSD' || s:_os_name() =~? 'OpenBSD')
call syntastic#util#redraw(g:syntastic_full_redraws) call syntastic#util#redraw(g:syntastic_full_redraws)
endif endif
if bailout if bailout
call syntastic#log#ndebug(g:_SYNTASTIC_DEBUG_LOCLIST, 'checker output:', err_lines)
throw 'Syntastic: checker error' throw 'Syntastic: checker error'
endif endif
@ -609,7 +613,7 @@ endfunction " }}}2
" Skip running in special buffers " Skip running in special buffers
function! s:_skip_file() abort " {{{2 function! s:_skip_file() abort " {{{2
let fname = expand('%', 1) let fname = expand('%', 1)
let skip = get(b:, 'syntastic_skip_checks', 0) || (&buftype != '') || let skip = get(b:, 'syntastic_skip_checks', 0) || (&buftype !=# '') ||
\ !filereadable(fname) || getwinvar(0, '&diff') || s:_ignore_file(fname) || \ !filereadable(fname) || getwinvar(0, '&diff') || s:_ignore_file(fname) ||
\ fnamemodify(fname, ':e') =~? g:syntastic_ignore_extensions \ fnamemodify(fname, ':e') =~? g:syntastic_ignore_extensions
if skip if skip
@ -627,7 +631,7 @@ function! s:_explain_skip(filetypes) abort " {{{2
if get(b:, 'syntastic_skip_checks', 0) if get(b:, 'syntastic_skip_checks', 0)
call add(why, 'b:syntastic_skip_checks set') call add(why, 'b:syntastic_skip_checks set')
endif endif
if &buftype != '' if &buftype !=# ''
call add(why, 'buftype = ' . string(&buftype)) call add(why, 'buftype = ' . string(&buftype))
endif endif
if !filereadable(fname) if !filereadable(fname)

View file

@ -1,4 +1,4 @@
if exists("g:loaded_syntastic_notifier_autoloclist") || !exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_notifier_autoloclist') || !exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_notifier_autoloclist = 1 let g:loaded_syntastic_notifier_autoloclist = 1

View file

@ -1,4 +1,4 @@
if exists("g:loaded_syntastic_notifier_balloons") || !exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_notifier_balloons') || !exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_notifier_balloons = 1 let g:loaded_syntastic_notifier_balloons = 1

View file

@ -1,4 +1,4 @@
if exists("g:loaded_syntastic_checker") || !exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_checker') || !exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_checker = 1 let g:loaded_syntastic_checker = 1
@ -25,6 +25,10 @@ function! g:SyntasticChecker.New(args) abort " {{{2
let prefix = 'SyntaxCheckers_' . newObj._filetype . '_' . newObj._name . '_' let prefix = 'SyntaxCheckers_' . newObj._filetype . '_' . newObj._name . '_'
endif endif
if has_key(a:args, 'enable')
let newObj._enable = a:args['enable']
endif
let newObj._locListFunc = function(prefix . 'GetLocList') let newObj._locListFunc = function(prefix . 'GetLocList')
if exists('*' . prefix . 'IsAvailable') if exists('*' . prefix . 'IsAvailable')
@ -54,12 +58,12 @@ endfunction " }}}2
" getExec() or getExecEscaped(). Normally isAvailable() does that for you " getExec() or getExecEscaped(). Normally isAvailable() does that for you
" automatically, but you should keep still this in mind if you change the " automatically, but you should keep still this in mind if you change the
" current checker workflow. " current checker workflow.
function! g:SyntasticChecker.syncExec() dict " {{{2 function! g:SyntasticChecker.syncExec() abort " {{{2
let user_exec = let user_exec =
\ expand( exists('b:syntastic_' . self._name . '_exec') ? b:syntastic_{self._name}_exec : \ expand( exists('b:syntastic_' . self._name . '_exec') ? b:syntastic_{self._name}_exec :
\ syntastic#util#var(self._filetype . '_' . self._name . '_exec'), 1 ) \ syntastic#util#var(self._filetype . '_' . self._name . '_exec'), 1 )
if user_exec != '' && user_exec !=# self._exec if user_exec !=# '' && user_exec !=# self._exec
let self._exec = user_exec let self._exec = user_exec
if has_key(self, '_available') if has_key(self, '_available')
" we have a new _exec on the block, it has to be validated " we have a new _exec on the block, it has to be validated
@ -78,14 +82,29 @@ endfunction " }}}2
function! g:SyntasticChecker.getLocListRaw() abort " {{{2 function! g:SyntasticChecker.getLocListRaw() abort " {{{2
let name = self._filetype . '/' . self._name let name = self._filetype . '/' . self._name
if has_key(self, '_enable')
let status = syntastic#util#var(self._enable, -1)
if status < 0
call syntastic#log#error('checker ' . name . ': checks disabled for security reasons; ' .
\ 'set g:syntastic_' . self._enable . ' to 1 to override')
endif
if status <= 0
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_TRACE, 'getLocList: checker ' . name . ' enabled but not forced')
return []
else
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_TRACE, 'getLocList: checker ' . name . ' forced')
endif
endif
try try
let list = self._locListFunc() let list = self._locListFunc()
if self._exec != '' if self._exec !=# ''
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_TRACE, 'getLocList: checker ' . name . ' returned ' . v:shell_error) call syntastic#log#debug(g:_SYNTASTIC_DEBUG_TRACE, 'getLocList: checker ' . name . ' returned ' . v:shell_error)
endif endif
catch /\m\C^Syntastic: checker error$/ catch /\m\C^Syntastic: checker error$/
let list = [] let list = []
if self._exec != '' if self._exec !=# ''
call syntastic#log#error('checker ' . name . ' returned abnormal status ' . v:shell_error) call syntastic#log#error('checker ' . name . ' returned abnormal status ' . v:shell_error)
else else
call syntastic#log#error('checker ' . name . ' aborted') call syntastic#log#error('checker ' . name . ' aborted')
@ -108,7 +127,13 @@ function! g:SyntasticChecker.getVersion(...) abort " {{{2
call self.log('getVersion: ' . string(command) . ': ' . call self.log('getVersion: ' . string(command) . ': ' .
\ string(split(version_output, "\n", 1)) . \ string(split(version_output, "\n", 1)) .
\ (v:shell_error ? ' (exit code ' . v:shell_error . ')' : '') ) \ (v:shell_error ? ' (exit code ' . v:shell_error . ')' : '') )
call self.setVersion(syntastic#util#parseVersion(version_output)) let parsed_ver = syntastic#util#parseVersion(version_output)
if len(parsed_ver)
call self.setVersion(parsed_ver)
else
call syntastic#log#ndebug(g:_SYNTASTIC_DEBUG_LOCLIST, 'checker output:', split(version_output, "\n", 1))
call syntastic#log#error("checker " . self._filetype . "/" . self._name . ": can't parse version string (abnormal termination?)")
endif
endif endif
return get(self, '_version', []) return get(self, '_version', [])
endfunction " }}}2 endfunction " }}}2
@ -117,8 +142,6 @@ function! g:SyntasticChecker.setVersion(version) abort " {{{2
if len(a:version) if len(a:version)
let self._version = copy(a:version) let self._version = copy(a:version)
call self.log(self.getExec() . ' version =', a:version) call self.log(self.getExec() . ' version =', a:version)
else
call syntastic#log#error("checker " . self._filetype . "/" . self._name . ": can't parse version string (abnormal termination?)")
endif endif
endfunction " }}}2 endfunction " }}}2
@ -152,6 +175,10 @@ function! g:SyntasticChecker.isAvailable() abort " {{{2
return self._available return self._available
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticChecker.isDisabled() abort " {{{2
return has_key(self, '_enable') && syntastic#util#var(self._enable, -1) <= 0
endfunction " }}}2
function! g:SyntasticChecker.wantSort() abort " {{{2 function! g:SyntasticChecker.wantSort() abort " {{{2
return syntastic#util#var(self._filetype . '_' . self._name . '_sort', 0) return syntastic#util#var(self._filetype . '_' . self._name . '_sort', 0)
endfunction " }}}2 endfunction " }}}2
@ -198,7 +225,7 @@ function! g:SyntasticChecker._populateHighlightRegexes(errors) abort " {{{2
for e in a:errors for e in a:errors
if e['valid'] if e['valid']
let term = self._highlightRegexFunc(e) let term = self._highlightRegexFunc(e)
if term != '' if term !=# ''
let e['hl'] = term let e['hl'] = term
endif endif
endif endif

View file

@ -1,4 +1,4 @@
if exists("g:loaded_syntastic_notifier_cursor") || !exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_notifier_cursor') || !exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_notifier_cursor = 1 let g:loaded_syntastic_notifier_cursor = 1

View file

@ -1,4 +1,4 @@
if exists("g:loaded_syntastic_notifier_highlighting") || !exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_notifier_highlighting') || !exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_notifier_highlighting = 1 let g:loaded_syntastic_notifier_highlighting = 1
@ -29,7 +29,7 @@ function! g:SyntasticHighlightingNotifier.enabled() abort " {{{2
return s:has_highlighting && syntastic#util#var('enable_highlighting') return s:has_highlighting && syntastic#util#var('enable_highlighting')
endfunction " }}}2 endfunction " }}}2
" Sets error highlights in the cuirrent window " Sets error highlights in the current window
function! g:SyntasticHighlightingNotifier.refresh(loclist) abort " {{{2 function! g:SyntasticHighlightingNotifier.refresh(loclist) abort " {{{2
if self.enabled() if self.enabled()
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_NOTIFICATIONS, 'highlighting: refresh') call syntastic#log#debug(g:_SYNTASTIC_DEBUG_NOTIFICATIONS, 'highlighting: refresh')

View file

@ -1,4 +1,4 @@
if exists("g:loaded_syntastic_loclist") || !exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_loclist') || !exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_loclist = 1 let g:loaded_syntastic_loclist = 1
@ -13,7 +13,7 @@ function! g:SyntasticLoclist.New(rawLoclist) abort " {{{2
let llist = filter(copy(a:rawLoclist), 'v:val["valid"] == 1') let llist = filter(copy(a:rawLoclist), 'v:val["valid"] == 1')
for e in llist for e in llist
if get(e, 'type', '') == '' if get(e, 'type', '') ==# ''
let e['type'] = 'E' let e['type'] = 'E'
endif endif
endfor endfor
@ -28,7 +28,7 @@ function! g:SyntasticLoclist.New(rawLoclist) abort " {{{2
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticLoclist.current() abort " {{{2 function! g:SyntasticLoclist.current() abort " {{{2
if !exists("b:syntastic_loclist") || empty(b:syntastic_loclist) if !exists('b:syntastic_loclist') || empty(b:syntastic_loclist)
let b:syntastic_loclist = g:SyntasticLoclist.New([]) let b:syntastic_loclist = g:SyntasticLoclist.New([])
endif endif
return b:syntastic_loclist return b:syntastic_loclist
@ -57,7 +57,7 @@ function! g:SyntasticLoclist.isEmpty() abort " {{{2
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticLoclist.isNewerThan(stamp) abort " {{{2 function! g:SyntasticLoclist.isNewerThan(stamp) abort " {{{2
if !exists("self._stamp") if !exists('self._stamp')
let self._stamp = [] let self._stamp = []
return 0 return 0
endif endif
@ -81,10 +81,10 @@ function! g:SyntasticLoclist.getCursorColumns() abort " {{{2
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticLoclist.getStatuslineFlag() abort " {{{2 function! g:SyntasticLoclist.getStatuslineFlag() abort " {{{2
if !exists("self._stl_format") if !exists('self._stl_format')
let self._stl_format = '' let self._stl_format = ''
endif endif
if !exists("self._stl_flag") if !exists('self._stl_flag')
let self._stl_flag = '' let self._stl_flag = ''
endif endif
@ -185,8 +185,8 @@ function! g:SyntasticLoclist.decorate(tag) abort " {{{2
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticLoclist.balloons() abort " {{{2 function! g:SyntasticLoclist.balloons() abort " {{{2
if !exists("self._cachedBalloons") if !exists('self._cachedBalloons')
let sep = has("balloon_multiline") ? "\n" : ' | ' let sep = has('balloon_multiline') ? "\n" : ' | '
let self._cachedBalloons = {} let self._cachedBalloons = {}
for e in self._rawLoclist for e in self._rawLoclist
@ -208,15 +208,15 @@ function! g:SyntasticLoclist.balloons() abort " {{{2
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticLoclist.errors() abort " {{{2 function! g:SyntasticLoclist.errors() abort " {{{2
if !exists("self._cachedErrors") if !exists('self._cachedErrors')
let self._cachedErrors = self.filter({'type': "E"}) let self._cachedErrors = self.filter({'type': 'E'})
endif endif
return self._cachedErrors return self._cachedErrors
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticLoclist.warnings() abort " {{{2 function! g:SyntasticLoclist.warnings() abort " {{{2
if !exists("self._cachedWarnings") if !exists('self._cachedWarnings')
let self._cachedWarnings = self.filter({'type': "W"}) let self._cachedWarnings = self.filter({'type': 'W'})
endif endif
return self._cachedWarnings return self._cachedWarnings
endfunction " }}}2 endfunction " }}}2
@ -229,7 +229,7 @@ endfunction " }}}2
" cache used by EchoCurrentError() " cache used by EchoCurrentError()
function! g:SyntasticLoclist.messages(buf) abort " {{{2 function! g:SyntasticLoclist.messages(buf) abort " {{{2
if !exists("self._cachedMessages") if !exists('self._cachedMessages')
let self._cachedMessages = {} let self._cachedMessages = {}
let errors = self.errors() + self.warnings() let errors = self.errors() + self.warnings()
@ -304,9 +304,9 @@ function! g:SyntasticLoclist.show() abort " {{{2
if !self.isEmpty() if !self.isEmpty()
let num = winnr() let num = winnr()
execute "lopen " . syntastic#util#var('loc_list_height') execute 'lopen ' . syntastic#util#var('loc_list_height')
if num != winnr() if num != winnr()
wincmd p execute num . 'wincmd w'
endif endif
" try to find the loclist window and set w:quickfix_title " try to find the loclist window and set w:quickfix_title
@ -320,7 +320,7 @@ function! g:SyntasticLoclist.show() abort " {{{2
" errors == getloclist(0) is the only somewhat safe way to " errors == getloclist(0) is the only somewhat safe way to
" achieve that " achieve that
if strpart(title, 0, 16) ==# ':SyntasticCheck ' || if strpart(title, 0, 16) ==# ':SyntasticCheck ' ||
\ ( (title == '' || title ==# ':setloclist()') && errors == getloclist(0) ) \ ( (title ==# '' || title ==# ':setloclist()') && errors == getloclist(0) )
call setwinvar(win, 'quickfix_title', ':SyntasticCheck ' . self._name) call setwinvar(win, 'quickfix_title', ':SyntasticCheck ' . self._name)
call setbufvar(buf, 'syntastic_owner_buffer', self._owner) call setbufvar(buf, 'syntastic_owner_buffer', self._owner)
endif endif

View file

@ -1,4 +1,4 @@
if exists("g:loaded_syntastic_modemap") || !exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_modemap') || !exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_modemap = 1 let g:loaded_syntastic_modemap = 1
@ -68,7 +68,7 @@ function! g:SyntasticModeMap.toggleMode() abort " {{{2
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticModeMap.echoMode() abort " {{{2 function! g:SyntasticModeMap.echoMode() abort " {{{2
echo "Syntastic: " . self._mode . " mode enabled" echo 'Syntastic: ' . self._mode . ' mode enabled'
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticModeMap.modeInfo(filetypes) abort " {{{2 function! g:SyntasticModeMap.modeInfo(filetypes) abort " {{{2

View file

@ -1,4 +1,4 @@
if exists("g:loaded_syntastic_notifiers") || !exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_notifiers') || !exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_notifiers = 1 let g:loaded_syntastic_notifiers = 1

View file

@ -1,4 +1,4 @@
if exists("g:loaded_syntastic_registry") || !exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_registry') || !exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_registry = 1 let g:loaded_syntastic_registry = 1
@ -53,7 +53,9 @@ let s:_DEFAULT_CHECKERS = {
\ 'lua': ['luac'], \ 'lua': ['luac'],
\ 'markdown': ['mdl'], \ 'markdown': ['mdl'],
\ 'matlab': ['mlint'], \ 'matlab': ['mlint'],
\ 'mercury': ['mmc'],
\ 'nasm': ['nasm'], \ 'nasm': ['nasm'],
\ 'nix': ['nix'],
\ 'nroff': ['mandoc'], \ 'nroff': ['mandoc'],
\ 'objc': ['gcc'], \ 'objc': ['gcc'],
\ 'objcpp': ['gcc'], \ 'objcpp': ['gcc'],
@ -93,7 +95,7 @@ let s:_DEFAULT_CHECKERS = {
\ 'yaml': ['jsyaml'], \ 'yaml': ['jsyaml'],
\ 'z80': ['z80syntaxchecker'], \ 'z80': ['z80syntaxchecker'],
\ 'zpt': ['zptlint'], \ 'zpt': ['zptlint'],
\ 'zsh': ['zsh', 'shellcheck'], \ 'zsh': ['zsh'],
\ } \ }
lockvar! s:_DEFAULT_CHECKERS lockvar! s:_DEFAULT_CHECKERS
@ -104,6 +106,7 @@ let s:_DEFAULT_FILETYPE_MAP = {
\ 'litcoffee': 'coffee', \ 'litcoffee': 'coffee',
\ 'mail': 'text', \ 'mail': 'text',
\ 'mkd': 'markdown', \ 'mkd': 'markdown',
\ 'pe-puppet': 'puppet',
\ 'sgml': 'docbk', \ 'sgml': 'docbk',
\ 'sgmllnx': 'docbk', \ 'sgmllnx': 'docbk',
\ } \ }
@ -178,12 +181,18 @@ function! g:SyntasticRegistry.getCheckers(ftalias, hints_list) abort " {{{2
\ self._filterCheckersByName(checkers_map, names) : [checkers_map[keys(checkers_map)[0]]] \ self._filterCheckersByName(checkers_map, names) : [checkers_map[keys(checkers_map)[0]]]
endfunction " }}}2 endfunction " }}}2
" Same as getCheckers(), but keep only the checkers available. This runs the " Same as getCheckers(), but keep only the available checkers. This runs the
" corresponding IsAvailable() functions for all checkers. " corresponding IsAvailable() functions for all checkers.
function! g:SyntasticRegistry.getCheckersAvailable(ftalias, hints_list) abort " {{{2 function! g:SyntasticRegistry.getCheckersAvailable(ftalias, hints_list) abort " {{{2
return filter(self.getCheckers(a:ftalias, a:hints_list), 'v:val.isAvailable()') return filter(self.getCheckers(a:ftalias, a:hints_list), 'v:val.isAvailable()')
endfunction " }}}2 endfunction " }}}2
" Same as getCheckers(), but keep only the checkers tyhat are available and
" disabled. This runs the corresponding IsAvailable() functions for all checkers.
function! g:SyntasticRegistry.getCheckersDisabled(ftalias, hints_list) abort " {{{2
return filter(self.getCheckers(a:ftalias, a:hints_list), 'v:val.isDisabled() && v:val.isAvailable()')
endfunction " }}}2
function! g:SyntasticRegistry.getKnownFiletypes() abort " {{{2 function! g:SyntasticRegistry.getKnownFiletypes() abort " {{{2
let types = keys(s:_DEFAULT_CHECKERS) let types = keys(s:_DEFAULT_CHECKERS)
@ -211,15 +220,18 @@ function! g:SyntasticRegistry.echoInfoFor(ftalias_list) abort " {{{2
if len(ft_list) != 1 if len(ft_list) != 1
let available = [] let available = []
let active = [] let active = []
let disabled = []
for ft in ft_list for ft in ft_list
call extend(available, map( self.getNamesOfAvailableCheckers(ft), 'ft . "/" . v:val' )) call extend(available, map( self.getNamesOfAvailableCheckers(ft), 'ft . "/" . v:val' ))
call extend(active, map( self.getCheckersAvailable(ft, []), 'ft . "/" . v:val.getName()' )) call extend(active, map( self.getCheckersAvailable(ft, []), 'ft . "/" . v:val.getName()' ))
call extend(disabled, map( self.getCheckersDisabled(ft, []), 'ft . "/" . v:val.getName()' ))
endfor endfor
else else
let ft = ft_list[0] let ft = ft_list[0]
let available = self.getNamesOfAvailableCheckers(ft) let available = self.getNamesOfAvailableCheckers(ft)
let active = map(self.getCheckersAvailable(ft, []), 'v:val.getName()') let active = map(self.getCheckersAvailable(ft, []), 'v:val.getName()')
let disabled = map(self.getCheckersDisabled(ft, []), 'v:val.getName()')
endif endif
let cnt = len(available) let cnt = len(available)
@ -232,6 +244,13 @@ function! g:SyntasticRegistry.echoInfoFor(ftalias_list) abort " {{{2
let cklist = cnt ? join(active) : '-' let cklist = cnt ? join(active) : '-'
echomsg 'Currently enabled checker' . plural . ': ' . cklist echomsg 'Currently enabled checker' . plural . ': ' . cklist
let cnt = len(disabled)
let plural = cnt != 1 ? 's' : ''
if len(disabled)
let cklist = join(sort(disabled))
echomsg 'Checker' . plural . ' disabled for security reasons: ' . cklist
endif
" Eclim feels entitled to mess with syntastic's variables {{{3 " Eclim feels entitled to mess with syntastic's variables {{{3
if exists(':EclimValidate') && get(g:, 'EclimFileTypeValidate', 1) if exists(':EclimValidate') && get(g:, 'EclimFileTypeValidate', 1)
let disabled = filter(copy(ft_list), 's:_disabled_by_eclim(v:val)') let disabled = filter(copy(ft_list), 's:_disabled_by_eclim(v:val)')
@ -284,7 +303,7 @@ function! g:SyntasticRegistry._loadCheckersFor(filetype) abort " {{{2
return return
endif endif
execute "runtime! syntax_checkers/" . a:filetype . "/*.vim" execute 'runtime! syntax_checkers/' . a:filetype . '/*.vim'
if !has_key(self._checkerMap, a:filetype) if !has_key(self._checkerMap, a:filetype)
let self._checkerMap[a:filetype] = {} let self._checkerMap[a:filetype] = {}

View file

@ -1,4 +1,4 @@
if exists("g:loaded_syntastic_notifier_signs") || !exists("g:loaded_syntastic_plugin") if exists('g:loaded_syntastic_notifier_signs') || !exists('g:loaded_syntastic_plugin')
finish finish
endif endif
let g:loaded_syntastic_notifier_signs = 1 let g:loaded_syntastic_notifier_signs = 1
@ -107,7 +107,7 @@ function! g:SyntasticSignsNotifier._signErrors(loclist) abort " {{{2
let sign_subtype = get(i, 'subtype', '') let sign_subtype = get(i, 'subtype', '')
let sign_type = 'Syntastic' . sign_subtype . sign_severity let sign_type = 'Syntastic' . sign_subtype . sign_severity
execute "sign place " . s:next_sign_id . " line=" . i['lnum'] . " name=" . sign_type . " buffer=" . i['bufnr'] execute 'sign place ' . s:next_sign_id . ' line=' . i['lnum'] . ' name=' . sign_type . ' buffer=' . i['bufnr']
call add(self._bufSignIds(), s:next_sign_id) call add(self._bufSignIds(), s:next_sign_id)
let s:next_sign_id += 1 let s:next_sign_id += 1
endif endif
@ -119,7 +119,7 @@ endfunction " }}}2
function! g:SyntasticSignsNotifier._removeSigns(ids) abort " {{{2 function! g:SyntasticSignsNotifier._removeSigns(ids) abort " {{{2
if has('signs') if has('signs')
for s in reverse(copy(a:ids)) for s in reverse(copy(a:ids))
execute "sign unplace " . s execute 'sign unplace ' . s
call remove(self._bufSignIds(), index(self._bufSignIds(), s)) call remove(self._bufSignIds(), index(self._bufSignIds(), s))
endfor endfor
endif endif
@ -127,7 +127,7 @@ endfunction " }}}2
" Get all the ids of the SyntaxError signs in the buffer " Get all the ids of the SyntaxError signs in the buffer
function! g:SyntasticSignsNotifier._bufSignIds() abort " {{{2 function! g:SyntasticSignsNotifier._bufSignIds() abort " {{{2
if !exists("b:syntastic_private_sign_ids") if !exists('b:syntastic_private_sign_ids')
let b:syntastic_private_sign_ids = [] let b:syntastic_private_sign_ids = []
endif endif
return b:syntastic_private_sign_ids return b:syntastic_private_sign_ids

View file

@ -37,7 +37,7 @@ function! SyntaxCheckers_actionscript_mxmlc_GetHighlightRegex(item)
endif endif
return term != '' ? '\V\<' . escape(term, '\') . '\>' : '' return term !=# '' ? '\V\<' . escape(term, '\') . '\>' : ''
endfunction endfunction
function! SyntaxCheckers_actionscript_mxmlc_GetLocList() dict function! SyntaxCheckers_actionscript_mxmlc_GetLocList() dict

View file

@ -32,8 +32,8 @@ function! SyntaxCheckers_ada_gcc_GetLocList() dict
\ '%-G%f:%s:,' . \ '%-G%f:%s:,' .
\ '%f:%l:%c: %m,' . \ '%f:%l:%c: %m,' .
\ '%f:%l: %m', \ '%f:%l: %m',
\ 'main_flags': '-c -x ada -fsyntax-only', \ 'main_flags': '-c -x ada -gnats',
\ 'header_flags': '-x ada', \ 'header_flags': '-x ada -gnats',
\ 'header_names': '\.ads$' }) \ 'header_names': '\.ads$' })
endfunction endfunction

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_apiblueprint_snowcrash_checker") if exists('g:loaded_syntastic_apiblueprint_snowcrash_checker')
finish finish
endif endif
let g:loaded_syntastic_apiblueprint_snowcrash_checker = 1 let g:loaded_syntastic_apiblueprint_snowcrash_checker = 1

View file

@ -25,7 +25,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_applescript_osacompile_checker") if exists('g:loaded_syntastic_applescript_osacompile_checker')
finish finish
endif endif
let g:loaded_syntastic_applescript_osacompile_checker = 1 let g:loaded_syntastic_applescript_osacompile_checker = 1

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_asciidoc_asciidoc_checker") if exists('g:loaded_syntastic_asciidoc_asciidoc_checker')
finish finish
endif endif
let g:loaded_syntastic_asciidoc_asciidoc_checker = 1 let g:loaded_syntastic_asciidoc_asciidoc_checker = 1

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_bemhtml_bemhtmllint_checker") if exists('g:loaded_syntastic_bemhtml_bemhtmllint_checker')
finish finish
endif endif

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_bro_bro_checker") if exists('g:loaded_syntastic_bro_bro_checker')
finish finish
endif endif
let g:loaded_syntastic_bro_bro_checker = 1 let g:loaded_syntastic_bro_bro_checker = 1
@ -20,7 +20,7 @@ set cpo&vim
function! SyntaxCheckers_bro_bro_GetHighlightRegex(item) function! SyntaxCheckers_bro_bro_GetHighlightRegex(item)
let term = matchstr(a:item['text'], '\m at or near "\zs[^"]\+\ze"') let term = matchstr(a:item['text'], '\m at or near "\zs[^"]\+\ze"')
return term != '' ? '\V\<' . escape(term, '\') . '\>' : '' return term !=# '' ? '\V\<' . escape(term, '\') . '\>' : ''
endfunction endfunction
function! SyntaxCheckers_bro_bro_IsAvailable() dict function! SyntaxCheckers_bro_bro_IsAvailable() dict

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_c_checkpatch_checker") if exists('g:loaded_syntastic_c_checkpatch_checker')
finish finish
endif endif
let g:loaded_syntastic_c_checkpatch_checker = 1 let g:loaded_syntastic_c_checkpatch_checker = 1

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_c_clang_check_checker") if exists('g:loaded_syntastic_c_clang_check_checker')
finish finish
endif endif
let g:loaded_syntastic_c_clang_check_checker = 1 let g:loaded_syntastic_c_clang_check_checker = 1

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_c_clang_tidy_checker") if exists('g:loaded_syntastic_c_clang_tidy_checker')
finish finish
endif endif
let g:loaded_syntastic_c_clang_tidy_checker = 1 let g:loaded_syntastic_c_clang_tidy_checker = 1

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_c_cppcheck_checker") if exists('g:loaded_syntastic_c_cppcheck_checker')
finish finish
endif endif
let g:loaded_syntastic_c_cppcheck_checker = 1 let g:loaded_syntastic_c_cppcheck_checker = 1

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_c_oclint_checker") if exists('g:loaded_syntastic_c_oclint_checker')
finish finish
endif endif
let g:loaded_syntastic_c_oclint_checker = 1 let g:loaded_syntastic_c_oclint_checker = 1

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_c_pc_lint_checker") if exists('g:loaded_syntastic_c_pc_lint_checker')
finish finish
endif endif
let g:loaded_syntastic_c_pc_lint_checker = 1 let g:loaded_syntastic_c_pc_lint_checker = 1
@ -23,7 +23,7 @@ if !exists('g:syntastic_pc_lint_config_file')
endif endif
function! SyntaxCheckers_c_pc_lint_GetLocList() dict function! SyntaxCheckers_c_pc_lint_GetLocList() dict
let config = findfile(g:syntastic_pc_lint_config_file, '.;') let config = syntastic#util#findFileInParent(g:syntastic_pc_lint_config_file, expand('%:p:h', 1))
call self.log('config =', config) call self.log('config =', config)
" -hFs1 - show filename, add space after messages, try to make message 1 line " -hFs1 - show filename, add space after messages, try to make message 1 line

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_c_sparse_checker") if exists('g:loaded_syntastic_c_sparse_checker')
finish finish
endif endif
let g:loaded_syntastic_c_sparse_checker = 1 let g:loaded_syntastic_c_sparse_checker = 1
@ -33,7 +33,7 @@ function! SyntaxCheckers_c_sparse_GetLocList() dict
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'defaults': {'bufnr': bufnr("")}, \ 'defaults': {'bufnr': bufnr('')},
\ 'returns': [0, 1] }) \ 'returns': [0, 1] })
return loclist return loclist
endfunction endfunction

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_c_splint_checker") if exists('g:loaded_syntastic_c_splint_checker')
finish finish
endif endif
let g:loaded_syntastic_c_splint_checker = 1 let g:loaded_syntastic_c_splint_checker = 1

View file

@ -20,11 +20,11 @@ set cpo&vim
function! SyntaxCheckers_cabal_cabal_GetHighlightRegex(item) function! SyntaxCheckers_cabal_cabal_GetHighlightRegex(item)
let field = matchstr(a:item['text'], "\\vParse of field '\\zs[^']+") let field = matchstr(a:item['text'], "\\vParse of field '\\zs[^']+")
if field != '' if field !=# ''
return '\v\c^\s*' . field . '\s*:\s*\zs.*$' return '\v\c^\s*' . field . '\s*:\s*\zs.*$'
endif endif
let field = matchstr(a:item['text'], "\\v(^|\\s)'\\zs[^']+\\ze'") let field = matchstr(a:item['text'], "\\v(^|\\s)'\\zs[^']+\\ze'")
if field != '' if field !=# ''
return '\V\c\<' . escape(field, '\') . '\>' return '\V\c\<' . escape(field, '\') . '\>'
endif endif
return '' return ''

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_chef_foodcritic_checker") if exists('g:loaded_syntastic_chef_foodcritic_checker')
finish finish
endif endif
let g:loaded_syntastic_chef_foodcritic_checker = 1 let g:loaded_syntastic_chef_foodcritic_checker = 1

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_co_coco_checker") if exists('g:loaded_syntastic_co_coco_checker')
finish finish
endif endif
let g:loaded_syntastic_co_coco_checker = 1 let g:loaded_syntastic_co_coco_checker = 1

View file

@ -13,7 +13,7 @@
" Note: this script requires CoffeeScript version 1.6.2 or newer. " Note: this script requires CoffeeScript version 1.6.2 or newer.
" "
if exists("g:loaded_syntastic_coffee_coffee_checker") if exists('g:loaded_syntastic_coffee_coffee_checker')
finish finish
endif endif
let g:loaded_syntastic_coffee_coffee_checker = 1 let g:loaded_syntastic_coffee_coffee_checker = 1

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_coffee_coffeelint_checker") if exists('g:loaded_syntastic_coffee_coffeelint_checker')
finish finish
endif endif
let g:loaded_syntastic_coffee_coffeelint_checker = 1 let g:loaded_syntastic_coffee_coffeelint_checker = 1

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_coq_coqtop_checker") if exists('g:loaded_syntastic_coq_coqtop_checker')
finish finish
endif endif
let g:loaded_syntastic_coq_coqtop_checker = 1 let g:loaded_syntastic_coq_coqtop_checker = 1

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_cpp_clang_check_checker") if exists('g:loaded_syntastic_cpp_clang_check_checker')
finish finish
endif endif
let g:loaded_syntastic_cpp_clang_check_checker = 1 let g:loaded_syntastic_cpp_clang_check_checker = 1

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_cpp_clang_tidy_checker") if exists('g:loaded_syntastic_cpp_clang_tidy_checker')
finish finish
endif endif
let g:loaded_syntastic_cpp_clang_tidy_checker = 1 let g:loaded_syntastic_cpp_clang_tidy_checker = 1

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_cpp_cppcheck_checker") if exists('g:loaded_syntastic_cpp_cppcheck_checker')
finish finish
endif endif
let g:loaded_syntastic_cpp_cppcheck_checker = 1 let g:loaded_syntastic_cpp_cppcheck_checker = 1

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_cpp_cpplint_checker") if exists('g:loaded_syntastic_cpp_cpplint_checker')
finish finish
endif endif
let g:loaded_syntastic_cpp_cpplint_checker = 1 let g:loaded_syntastic_cpp_cpplint_checker = 1

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_cpp_oclint_checker") if exists('g:loaded_syntastic_cpp_oclint_checker')
finish finish
endif endif
let g:loaded_syntastic_cpp_oclint_checker = 1 let g:loaded_syntastic_cpp_oclint_checker = 1

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_cpp_pc_lint_checker") if exists('g:loaded_syntastic_cpp_pc_lint_checker')
finish finish
endif endif
let g:loaded_syntastic_cpp_pc_lint_checker = 1 let g:loaded_syntastic_cpp_pc_lint_checker = 1

View file

@ -0,0 +1,48 @@
"============================================================================
"File: verapp.vim
"Description: Syntax checking plugin for syntastic.vim
"Maintainer: Lucas Verney <phyks@phyks.me>
"License: This program is free software. It comes without any warranty,
" to the extent permitted by applicable law. You can redistribute
" it and/or modify it under the terms of the Do What The Fuck You
" Want To Public License, Version 2, as published by Sam Hocevar.
" See http://sam.zoy.org/wtfpl/COPYING for more details.
"
" Tested with Vera++ 1.3.0
"============================================================================
if exists('g:loaded_syntastic_cpp_verapp_checker')
finish
endif
let g:loaded_syntastic_cpp_verapp_checker = 1
if !exists('g:syntastic_verapp_config_file')
let g:syntastic_verapp_config_file = '.syntastic_verapp_config'
endif
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_cpp_verapp_GetLocList() dict
let makeprg = self.makeprgBuild({
\ 'args': syntastic#c#ReadConfig(g:syntastic_verapp_config_file),
\ 'args_after': '--show-rule --no-duplicate -S -c -' })
let errorformat = '%f:%t:%l:%c:%m'
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'preprocess': 'checkstyle',
\ 'subtype': 'Style' })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'cpp',
\ 'name': 'verapp',
\ 'exec': 'vera++'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_cs_mcs_checker") if exists('g:loaded_syntastic_cs_mcs_checker')
finish finish
endif endif
let g:loaded_syntastic_cs_mcs_checker = 1 let g:loaded_syntastic_cs_mcs_checker = 1
@ -26,7 +26,7 @@ function! SyntaxCheckers_cs_mcs_GetLocList() dict
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'defaults': {'bufnr': bufnr("")} }) \ 'defaults': {'bufnr': bufnr('')} })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -33,7 +33,7 @@ function! SyntaxCheckers_css_csslint_GetLocList() dict
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'defaults': {'bufnr': bufnr("")} }) \ 'defaults': {'bufnr': bufnr('')} })
endfunction endfunction

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_css_phpcs_checker") if exists('g:loaded_syntastic_css_phpcs_checker')
finish finish
endif endif
let g:loaded_syntastic_css_phpcs_checker = 1 let g:loaded_syntastic_css_phpcs_checker = 1

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_css_prettycss_checker") if exists('g:loaded_syntastic_css_prettycss_checker')
finish finish
endif endif
let g:loaded_syntastic_css_prettycss_checker = 1 let g:loaded_syntastic_css_prettycss_checker = 1
@ -23,8 +23,8 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_css_prettycss_GetHighlightRegex(item) function! SyntaxCheckers_css_prettycss_GetHighlightRegex(item)
let term = matchstr(a:item["text"], '\m (\zs[^)]\+\ze)$') let term = matchstr(a:item['text'], '\m (\zs[^)]\+\ze)$')
if term != '' if term !=# ''
let term = '\V' . escape(term, '\') let term = '\V' . escape(term, '\')
endif endif
return term return term
@ -42,10 +42,10 @@ function! SyntaxCheckers_css_prettycss_GetLocList() dict
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'defaults': {'bufnr': bufnr("")} }) \ 'defaults': {'bufnr': bufnr('')} })
for e in loclist for e in loclist
let e["text"] .= ')' let e['text'] .= ')'
endfor endfor
return loclist return loclist

View file

@ -11,7 +11,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_css_recess_checker") if exists('g:loaded_syntastic_css_recess_checker')
finish finish
endif endif
let g:loaded_syntastic_css_recess_checker = 1 let g:loaded_syntastic_css_recess_checker = 1

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_cucumber_cucumber_checker") if exists('g:loaded_syntastic_cucumber_cucumber_checker')
finish finish
endif endif
let g:loaded_syntastic_cucumber_cucumber_checker = 1 let g:loaded_syntastic_cucumber_cucumber_checker = 1

View file

@ -6,7 +6,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_cuda_nvcc_checker") if exists('g:loaded_syntastic_cuda_nvcc_checker')
finish finish
endif endif
let g:loaded_syntastic_cuda_nvcc_checker = 1 let g:loaded_syntastic_cuda_nvcc_checker = 1

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_dart_dartanalyzer_checker") if exists('g:loaded_syntastic_dart_dartanalyzer_checker')
finish finish
endif endif
let g:loaded_syntastic_dart_dartanalyzer_checker = 1 let g:loaded_syntastic_dart_dartanalyzer_checker = 1

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_docbk_xmllint_checker") if exists('g:loaded_syntastic_docbk_xmllint_checker')
finish finish
endif endif
let g:loaded_syntastic_docbk_xmllint_checker = 1 let g:loaded_syntastic_docbk_xmllint_checker = 1

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_dustjs_swiffer_checker") if exists('g:loaded_syntastic_dustjs_swiffer_checker')
finish finish
endif endif

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_elixir_elixir_checker") if exists('g:loaded_syntastic_elixir_elixir_checker')
finish finish
endif endif
let g:loaded_syntastic_elixir_elixir_checker = 1 let g:loaded_syntastic_elixir_elixir_checker = 1
@ -27,15 +27,9 @@ function! SyntaxCheckers_elixir_elixir_IsAvailable() dict
endfunction endfunction
function! SyntaxCheckers_elixir_elixir_GetLocList() dict function! SyntaxCheckers_elixir_elixir_GetLocList() dict
if !exists('g:syntastic_enable_elixir_checker') || !g:syntastic_enable_elixir_checker
call syntastic#log#error('checker elixir/elixir: checks disabled for security reasons; ' .
\ 'set g:syntastic_enable_elixir_checker to 1 to override')
return []
endif
let make_options = {} let make_options = {}
let compile_command = 'elixir' let compile_command = 'elixir'
let mix_file = syntastic#util#findInParent('mix.exs', expand('%:p:h', 1)) let mix_file = syntastic#util#findFileInParent('mix.exs', expand('%:p:h', 1))
if filereadable(mix_file) if filereadable(mix_file)
let compile_command = 'mix compile' let compile_command = 'mix compile'
@ -53,7 +47,8 @@ endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'elixir', \ 'filetype': 'elixir',
\ 'name': 'elixir'}) \ 'name': 'elixir',
\ 'enable': 'enable_elixir_checker'})
let &cpo = s:save_cpo let &cpo = s:save_cpo
unlet s:save_cpo unlet s:save_cpo

View file

@ -1,56 +1,73 @@
#!/usr/bin/env escript #!/usr/bin/env escript
-export([main/1]).
main([FileName]) -> main([File]) ->
LibDirs = (["ebin", "include", "src", "test"] ++ Dir = get_root(filename:dirname(File)),
filelib:wildcard("{apps,deps,lib}/*/{ebin,include}")), Defs = [strong_validation,
compile(FileName, LibDirs); warn_export_all,
main([FileName, "-rebar", Path, LibDirs]) ->
{ok, L} = file:consult(Path),
P = dict:from_list(L),
Root = filename:dirname(Path),
Lib1 = case dict:find(lib_dirs, P) of
{ok, X} -> lists:map(fun(Sub) -> Root ++ "/" ++ Sub end, X);
_ -> []
end,
Lib2 = case dict:find(sub_dirs, P) of
{ok, Y} -> lists:foldl(
fun(Sub,Sofar) ->
Sofar ++ [
Root ++ "/" ++ Sub,
Root ++ "/" ++ Sub ++ "/include",
Root ++ "/" ++ Sub ++ "/deps",
Root ++ "/" ++ Sub ++ "/lib"
] end, [], Y);
_ -> []
end,
LibDirs1 = LibDirs ++ Lib1 ++ Lib2,
%io:format("~p~n", [LibDirs1]),
compile(FileName, LibDirs1);
main([FileName | LibDirs]) ->
compile(FileName, LibDirs).
compile(FileName, LibDirs) ->
Root = get_root(filename:dirname(FileName)),
ok = code:add_pathsa(LibDirs),
compile:file(FileName,
[warn_obsolete_guard,
warn_unused_import,
warn_shadow_vars,
warn_export_vars, warn_export_vars,
strong_validation, warn_shadow_vars,
report] ++ warn_obsolete_guard,
[{i, filename:join(Root, I)} || I <- LibDirs] ++ warn_unused_import,
case lists:member("deps/pmod_transform/include", LibDirs) of report,
true -> [{parse_transform, pmod_pt}]; {i, Dir ++ "/include"}],
_ -> [] %% `rebar.config` is looked for,
end %% but it is not necessarily the one in the project root.
). %% I.e. it may be one deeper in the project file hierarchy.
RebarFile = rebar_file(Dir),
%% `rebar.config` might contain relative paths.
%% They are relative to the file! Not to the project root.
RebarOpts = rebar_opts(Dir ++ "/" ++ RebarFile),
code:add_patha(filename:absname("ebin")),
%% `compile:file/2` requires the `{i, Path}` to be relative
%% to CWD - no surprise here.
compile:file(File, Defs ++ translate_paths(Dir, RebarOpts));
main(_) ->
io:format("Usage: ~s <file>~n", [escript:script_name()]),
halt(1).
rebar_file(Dir) ->
DirList = filename:split(Dir),
case lists:last(DirList) of
"test" ->
"rebar.test.config";
_ ->
"rebar.config"
end.
rebar_opts(RebarFile) ->
Dir = get_root(filename:dirname(RebarFile)),
case file:consult(RebarFile) of
{ok, Terms} ->
RebarLibDirs = proplists:get_value(lib_dirs, Terms, []),
lists:foreach(
fun(LibDir) ->
code:add_pathsa(filelib:wildcard(LibDir ++ "/*/ebin"))
end, RebarLibDirs),
RebarDepsDir = proplists:get_value(deps_dir, Terms, "deps"),
code:add_pathsa(filelib:wildcard(RebarDepsDir ++ "/*/ebin")),
IncludeDeps = {i, filename:join(Dir, RebarDepsDir)},
proplists:get_value(erl_opts, Terms, []) ++ [IncludeDeps];
{error, _} when RebarFile == "rebar.config" ->
fallback_opts();
{error, _} ->
rebar_opts("rebar.config")
end.
fallback_opts() ->
code:add_pathsa(filelib:wildcard("deps/*/ebin")),
code:add_pathsa(nested_app_ebins()),
[
{ i, filename:absname("apps") }, { i, filename:absname("deps") } | [ { i, filename:absname(Path) } || Path <- filelib:wildcard("deps/*/apps")]
].
nested_app_ebins() ->
DetectedAppSrcFiles = filelib:wildcard("deps/*/apps/**/*.app.src"),
[apps_dir_from_src(AppSrcFile)||AppSrcFile<-DetectedAppSrcFiles].
apps_dir_from_src(SrcFile) ->
SrcDir = filename:dirname(SrcFile),
filename:join(SrcDir, "../../ebin").
get_root(Dir) -> get_root(Dir) ->
Path = filename:split(filename:absname(Dir)), Path = filename:split(filename:absname(Dir)),
@ -64,3 +81,15 @@ get_root(["test" | Tail], _Path) ->
lists:reverse(Tail); lists:reverse(Tail);
get_root([_ | Tail], Path) -> get_root([_ | Tail], Path) ->
get_root(Tail, Path). get_root(Tail, Path).
translate_paths(Dir, RebarOpts) ->
[ translate_path(Dir, Opt) || Opt <- RebarOpts ].
translate_path(Dir, {i, Path}) ->
case Path of
%% absolute
"/" ++ _ -> {i, Path};
%% relative -> make absolute taking rebar.config location into account
_ -> {i, filename:join([Dir, Path])}
end;
translate_path(_, Other) -> Other.

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_erlang_syntaxerl_checker") if exists('g:loaded_syntastic_erlang_syntaxerl_checker')
finish finish
endif endif

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_eruby_ruby_checker") if exists('g:loaded_syntastic_eruby_ruby_checker')
finish finish
endif endif
let g:loaded_syntastic_eruby_ruby_checker = 1 let g:loaded_syntastic_eruby_ruby_checker = 1
@ -35,7 +35,7 @@ function! SyntaxCheckers_eruby_ruby_GetLocList() dict
" TODO: encodings became useful in ruby 1.9 :) " TODO: encodings became useful in ruby 1.9 :)
if s:ruby_new if s:ruby_new
let enc = &fileencoding != '' ? &fileencoding : &encoding let enc = &fileencoding !=# '' ? &fileencoding : &encoding
let encoding_spec = ', :encoding => "' . (enc ==? 'utf-8' ? 'UTF-8' : 'BINARY') . '"' let encoding_spec = ', :encoding => "' . (enc ==? 'utf-8' ? 'UTF-8' : 'BINARY') . '"'
else else
let encoding_spec = '' let encoding_spec = ''
@ -69,7 +69,7 @@ function! SyntaxCheckers_eruby_ruby_GetLocList() dict
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env, \ 'env': env,
\ 'defaults': { 'bufnr': bufnr(""), 'vcol': 1 } }) \ 'defaults': { 'bufnr': bufnr(''), 'vcol': 1 } })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_fortran_gfortran_checker") if exists('g:loaded_syntastic_fortran_gfortran_checker')
finish finish
endif endif
let g:loaded_syntastic_fortran_gfortran_checker = 1 let g:loaded_syntastic_fortran_gfortran_checker = 1
@ -19,28 +19,75 @@ if !exists('g:syntastic_fortran_compiler_options')
let g:syntastic_fortran_compiler_options = '' let g:syntastic_fortran_compiler_options = ''
endif endif
let s:type_map = {}
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_fortran_gfortran_IsAvailable() dict function! SyntaxCheckers_fortran_gfortran_IsAvailable() dict " {{{1
if !exists('g:syntastic_fortran_compiler') if !exists('g:syntastic_fortran_compiler')
let g:syntastic_fortran_compiler = self.getExec() let g:syntastic_fortran_compiler = self.getExec()
endif endif
call self.log('g:syntastic_fortran_compiler = ', g:syntastic_fortran_compiler) call self.log('g:syntastic_fortran_compiler = ', g:syntastic_fortran_compiler)
return executable(expand(g:syntastic_fortran_compiler, 1)) return executable(expand(g:syntastic_fortran_compiler, 1))
endfunction endfunction " }}}1
function! SyntaxCheckers_fortran_gfortran_GetLocList() dict " @vimlint(EVL104, 1, l:errorformat)
return syntastic#c#GetLocList('fortran', 'gfortran', { function! SyntaxCheckers_fortran_gfortran_GetLocList() dict " {{{1
\ 'errorformat': call s:SetCompilerType(g:syntastic_fortran_compiler)
if !has_key(s:type_map, g:syntastic_fortran_compiler)
call syntastic#log#error("checker fortran/gfortran: can't parse version string (abnormal termination?)")
return []
endif
if s:type_map[g:syntastic_fortran_compiler] ==# 'gfortran'
let errorformat =
\ '%-C %#,'. \ '%-C %#,'.
\ '%-C %#%.%#,'. \ '%-C %#%.%#,'.
\ '%A%f:%l.%c:,'. \ '%A%f:%l%[.:]%c:,'.
\ '%Z%trror: %m,'. \ '%Z%\m%\%%(Fatal %\)%\?%trror: %m,'.
\ '%Z%tarning: %m,'. \ '%Z%tarning: %m,'.
\ '%-G%.%#', \ '%-G%.%#'
if !exists('g:syntastic_fortran_gfortran_sort')
let g:syntastic_fortran_gfortran_sort = 0
endif
elseif s:type_map[g:syntastic_fortran_compiler] ==# 'ifort'
let errorformat =
\ '%E%f(%l): error #%n: %m,'.
\ '%W%f(%l): warning #%n: %m,'.
\ '%W%f(%l): remark #%n: %m,'.
\ '%-Z%p^,'.
\ '%-G%.%#'
if !exists('g:syntastic_fortran_gfortran_sort')
let g:syntastic_fortran_gfortran_sort = 1
endif
endif
return syntastic#c#GetLocList('fortran', 'gfortran', {
\ 'errorformat': errorformat,
\ 'main_flags': '-fsyntax-only' }) \ 'main_flags': '-fsyntax-only' })
endfunction endfunction " }}}1
" @vimlint(EVL104, 0, l:errorformat)
" Utilities {{{1
function! s:SetCompilerType(exe) " {{{2
if !has_key(s:type_map, a:exe)
try
let ver = filter( split(syntastic#util#system(syntastic#util#shescape(a:exe) . ' --version'), '\n'),
\ 'v:val =~# "\\v^%(GNU Fortran|ifort) "' )[0]
if ver =~# '\m^GNU Fortran '
let s:type_map[a:exe] = 'gfortran'
elseif ver =~# '\m^ifort '
let s:type_map[a:exe] = 'ifort'
endif
catch /\m^Vim\%((\a\+)\)\=:E684/
" do nothing
endtry
endif
endfunction " }}}2
" }}}
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'fortran', \ 'filetype': 'fortran',

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_glsl_cgc_checker") if exists('g:loaded_syntastic_glsl_cgc_checker')
finish finish
endif endif
let g:loaded_syntastic_glsl_cgc_checker = 1 let g:loaded_syntastic_glsl_cgc_checker = 1
@ -33,8 +33,8 @@ function! SyntaxCheckers_glsl_cgc_GetLocList() dict " {{{1
\ 'args': (exists('g:syntastic_glsl_options') ? ' ' . g:syntastic_glsl_options : '') }) \ 'args': (exists('g:syntastic_glsl_options') ? ' ' . g:syntastic_glsl_options : '') })
let errorformat = let errorformat =
\ "%E%f(%l) : error %m," . \ '%E%f(%l) : error %m,' .
\ "%W%f(%l) : warning %m" \ '%W%f(%l) : warning %m'
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,

View file

@ -14,7 +14,7 @@
" Use a BufWritePre autocommand to that end: " Use a BufWritePre autocommand to that end:
" autocmd FileType go autocmd BufWritePre <buffer> Fmt " autocmd FileType go autocmd BufWritePre <buffer> Fmt
if exists("g:loaded_syntastic_go_go_checker") if exists('g:loaded_syntastic_go_go_checker')
finish finish
endif endif
let g:loaded_syntastic_go_go_checker = 1 let g:loaded_syntastic_go_go_checker = 1
@ -58,8 +58,8 @@ function! SyntaxCheckers_go_go_GetLocList() dict
let opts = syntastic#util#var('go_go_test_args') let opts = syntastic#util#var('go_go_test_args')
let cleanup = 1 let cleanup = 1
endif endif
let opt_str = (type(opts) != type('') || opts != '') ? join(syntastic#util#argsescape(opts)) : opts let opt_str = (type(opts) != type('') || opts !=# '') ? join(syntastic#util#argsescape(opts)) : opts
let makeprg = self.getExec() . ' ' . cmd . ' ' . opt_str . ' ' . syntastic#c#NullOutput() let makeprg = self.getExec() . ' ' . cmd . ' ' . opt_str
" The first pattern is for warnings from C compilers. " The first pattern is for warnings from C compilers.
let errorformat = let errorformat =

View file

@ -14,7 +14,7 @@
" Use a BufWritePre autocommand to that end: " Use a BufWritePre autocommand to that end:
" autocmd FileType go autocmd BufWritePre <buffer> Fmt " autocmd FileType go autocmd BufWritePre <buffer> Fmt
if exists("g:loaded_syntastic_go_gofmt_checker") if exists('g:loaded_syntastic_go_gofmt_checker')
finish finish
endif endif
let g:loaded_syntastic_go_gofmt_checker = 1 let g:loaded_syntastic_go_gofmt_checker = 1

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_go_golint_checker") if exists('g:loaded_syntastic_go_golint_checker')
finish finish
endif endif
let g:loaded_syntastic_go_golint_checker = 1 let g:loaded_syntastic_go_golint_checker = 1

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_go_gotype_checker") if exists('g:loaded_syntastic_go_gotype_checker')
finish finish
endif endif
let g:loaded_syntastic_go_gotype_checker = 1 let g:loaded_syntastic_go_gotype_checker = 1

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_go_govet_checker") if exists('g:loaded_syntastic_go_govet_checker')
finish finish
endif endif
let g:loaded_syntastic_go_govet_checker = 1 let g:loaded_syntastic_go_govet_checker = 1

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_haml_haml_lint_checker") if exists('g:loaded_syntastic_haml_haml_lint_checker')
finish finish
endif endif
let g:loaded_syntastic_haml_haml_lint_checker = 1 let g:loaded_syntastic_haml_haml_lint_checker = 1

View file

@ -9,7 +9,7 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_handlebars_handlebars_checker") if exists('g:loaded_syntastic_handlebars_handlebars_checker')
finish finish
endif endif
let g:loaded_syntastic_handlebars_handlebars_checker = 1 let g:loaded_syntastic_handlebars_handlebars_checker = 1
@ -22,7 +22,7 @@ function! SyntaxCheckers_handlebars_handlebars_GetLocList() dict
let errorformat = let errorformat =
\ '%EError: %m on line %l:,' . \ '%EError: %m on line %l:,' .
\ "%EError: %m,". \ '%EError: %m,' .
\ '%Z%p^,' . \ '%Z%p^,' .
\ '%-G%.%#' \ '%-G%.%#'
@ -30,7 +30,7 @@ function! SyntaxCheckers_handlebars_handlebars_GetLocList() dict
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'postprocess': ['guards'], \ 'postprocess': ['guards'],
\ 'defaults': {'bufnr': bufnr("")} }) \ 'defaults': {'bufnr': bufnr('')} })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -30,20 +30,23 @@ function! SyntaxCheckers_haskell_ghc_mod_IsAvailable() dict
" know the version in order to know how to find out the version. :) " know the version in order to know how to find out the version. :)
" Try "ghc-mod version". " Try "ghc-mod version".
let ver = filter(split(syntastic#util#system(self.getExecEscaped() . ' version'), '\n'), 'v:val =~# ''\m\sversion''') let version_output = split(syntastic#util#system(self.getExecEscaped() . ' version'), '\n', 1)
let ver = filter(copy(version_output), 'v:val =~# ''\m\sversion''')
if !len(ver) if !len(ver)
" That didn't work. Try "ghc-mod" alone. " That didn't work. Try "ghc-mod" alone.
let ver = filter(split(syntastic#util#system(self.getExecEscaped()), '\n'), 'v:val =~# ''\m\sversion''') let version_output = split(syntastic#util#system(self.getExecEscaped()), '\n', 1)
let ver = filter(copy(version_output), 'v:val =~# ''\m\sversion''')
endif endif
let parsed_ver = len(ver) ? syntastic#util#parseVersion(ver[0]) : []
if len(ver) if len(parsed_ver)
" Encouraged by the great success in finding out the version, now we " Encouraged by the great success in finding out the version, now we
" need either a Vim that can handle NULs in system() output, or a " need either a Vim that can handle NULs in system() output, or a
" ghc-mod that has the "--boundary" option. " ghc-mod that has the "--boundary" option.
let parsed_ver = syntastic#util#parseVersion(ver[0])
call self.setVersion(parsed_ver) call self.setVersion(parsed_ver)
let s:ghc_mod_new = syntastic#util#versionIsAtLeast(parsed_ver, [2, 1, 2]) let s:ghc_mod_new = syntastic#util#versionIsAtLeast(parsed_ver, [2, 1, 2])
else else
call syntastic#log#ndebug(g:_SYNTASTIC_DEBUG_LOCLIST, 'checker output:', version_output)
call syntastic#log#error("checker haskell/ghc_mod: can't parse version string (abnormal termination?)") call syntastic#log#error("checker haskell/ghc_mod: can't parse version string (abnormal termination?)")
let s:ghc_mod_new = -1 let s:ghc_mod_new = -1
endif endif
@ -68,6 +71,7 @@ function! SyntaxCheckers_haskell_ghc_mod_GetLocList() dict
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'preprocess': 'iconv',
\ 'postprocess': ['compressWhitespace'], \ 'postprocess': ['compressWhitespace'],
\ 'returns': [0] }) \ 'returns': [0] })
endfunction endfunction

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_haskell_hdevtools_checker") if exists('g:loaded_syntastic_haskell_hdevtools_checker')
finish finish
endif endif
let g:loaded_syntastic_haskell_hdevtools_checker = 1 let g:loaded_syntastic_haskell_hdevtools_checker = 1

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_haxe_haxe_checker") if exists('g:loaded_syntastic_haxe_haxe_checker')
finish finish
endif endif
let g:loaded_syntastic_haxe_haxe_checker = 1 let g:loaded_syntastic_haxe_haxe_checker = 1
@ -24,13 +24,13 @@ function! SyntaxCheckers_haxe_haxe_GetLocList() dict
elseif exists('g:vaxe_hxml') elseif exists('g:vaxe_hxml')
let hxml = g:vaxe_hxml let hxml = g:vaxe_hxml
else else
let hxml = syntastic#util#findInParent('*.hxml', expand('%:p:h', 1)) let hxml = syntastic#util#findGlobInParent('*.hxml', expand('%:p:h', 1))
endif endif
let hxml = fnamemodify(hxml, ':p') let hxml = fnamemodify(hxml, ':p')
call self.log('hxml =', hxml) call self.log('hxml =', hxml)
if hxml != '' if hxml !=# ''
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'fname': syntastic#util#shescape(fnamemodify(hxml, ':t')) }) \ 'fname': syntastic#util#shescape(fnamemodify(hxml, ':t')) })

View file

@ -10,7 +10,7 @@
" "
"============================================================================ "============================================================================
if exists("g:loaded_syntastic_hss_hss_checker") if exists('g:loaded_syntastic_hss_hss_checker')
finish finish
endif endif
let g:loaded_syntastic_hss_hss_checker = 1 let g:loaded_syntastic_hss_hss_checker = 1

View file

@ -9,16 +9,8 @@
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
" "
"============================================================================ "============================================================================
"
" Note: if you need to check HTML5 sources, you might consider installing a
" fork of HTML Tidy, named "HTML Tidy for HTML5":
"
" http://w3c.github.io/tidy-html5/
"
" HTML Tidy for HTML5 can be used without changes by this checker, just install
" it and point g:syntastic_html_tidy_exec to the executable.
if exists("g:loaded_syntastic_html_tidy_checker") if exists('g:loaded_syntastic_html_tidy_checker')
finish finish
endif endif
let g:loaded_syntastic_html_tidy_checker = 1 let g:loaded_syntastic_html_tidy_checker = 1
@ -102,40 +94,40 @@ let s:IGNORE_ERRORS = [
lockvar! s:IGNORE_ERRORS lockvar! s:IGNORE_ERRORS
let s:BLOCKLEVEL_TAGS = [ let s:BLOCKLEVEL_TAGS = [
\ "main", \ 'main',
\ "section", \ 'section',
\ "article", \ 'article',
\ "aside", \ 'aside',
\ "header", \ 'header',
\ "footer", \ 'footer',
\ "nav", \ 'nav',
\ "figure", \ 'figure',
\ "figcaption" \ 'figcaption'
\ ] \ ]
lockvar! s:BLOCKLEVEL_TAGS lockvar! s:BLOCKLEVEL_TAGS
let s:INLINE_TAGS = [ let s:INLINE_TAGS = [
\ "video", \ 'video',
\ "audio", \ 'audio',
\ "source", \ 'source',
\ "embed", \ 'embed',
\ "mark", \ 'mark',
\ "progress", \ 'progress',
\ "meter", \ 'meter',
\ "time", \ 'time',
\ "ruby", \ 'ruby',
\ "rt", \ 'rt',
\ "rp", \ 'rp',
\ "canvas", \ 'canvas',
\ "command", \ 'command',
\ "details", \ 'details',
\ "datalist" \ 'datalist'
\ ] \ ]
lockvar! s:INLINE_TAGS lockvar! s:INLINE_TAGS
let s:EMPTY_TAGS = [ let s:EMPTY_TAGS = [
\ "wbr", \ 'wbr',
\ "keygen" \ 'keygen'
\ ] \ ]
lockvar! s:EMPTY_TAGS lockvar! s:EMPTY_TAGS
@ -152,7 +144,7 @@ function! SyntaxCheckers_html_tidy_GetLocList() dict " {{{1
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'defaults': {'bufnr': bufnr("")}, \ 'defaults': {'bufnr': bufnr('')},
\ 'returns': [0, 1, 2] }) \ 'returns': [0, 1, 2] })
" filter out valid HTML5 from the errors " filter out valid HTML5 from the errors

Some files were not shown because too many files have changed in this diff Show more