1
0
Fork 0
mirror of synced 2024-06-26 10:41:09 -04:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Mirosław Pragłowski 2014-10-13 21:54:40 +02:00
commit 55732b09d1
266 changed files with 11284 additions and 3954 deletions

View file

@ -81,6 +81,7 @@ I recommend reading the docs of these plugins to understand them better. Each of
* [goyo.vim](https://github.com/junegunn/goyo.vim) and [vim-zenroom2](https://github.com/amix/vim-zenroom2): * [goyo.vim](https://github.com/junegunn/goyo.vim) and [vim-zenroom2](https://github.com/amix/vim-zenroom2):
Remove all clutter and focus only on the essential. Similar to iA Writer or Write Room [Read more here](http://amix.dk/blog/post/19744) Remove all clutter and focus only on the essential. Similar to iA Writer or Write Room [Read more here](http://amix.dk/blog/post/19744)
* [vim-commentary](https://github.com/tpope/vim-commentary): Comment stuff out. Use `gcc` to comment out a line (takes a count), `gc` to comment out the target of a motion. `gcu` uncomments a set of adjacent commented lines. * [vim-commentary](https://github.com/tpope/vim-commentary): Comment stuff out. Use `gcc` to comment out a line (takes a count), `gc` to comment out the target of a motion. `gcu` uncomments a set of adjacent commented lines.
* [syntastic](https://github.com/scrooloose/syntastic): Syntax checking hacks for vim
## Included color schemes ## Included color schemes

View file

@ -1,6 +1,6 @@
" pathogen.vim - path option manipulation " pathogen.vim - path option manipulation
" Maintainer: Tim Pope <http://tpo.pe/> " Maintainer: Tim Pope <http://tpo.pe/>
" Version: 2.2 " Version: 2.3
" Install in ~/.vim/autoload (or ~\vimfiles\autoload). " Install in ~/.vim/autoload (or ~\vimfiles\autoload).
" "
@ -8,52 +8,49 @@
" ~\vimfiles\bundle), adding `execute pathogen#infect()` to the top of your " ~\vimfiles\bundle), adding `execute pathogen#infect()` to the top of your
" .vimrc is the only other setup necessary. " .vimrc is the only other setup necessary.
" "
" The API is documented inline below. For maximum ease of reading, " The API is documented inline below.
" :set foldmethod=marker
if exists("g:loaded_pathogen") || &cp if exists("g:loaded_pathogen") || &cp
finish finish
endif endif
let g:loaded_pathogen = 1 let g:loaded_pathogen = 1
function! s:warn(msg)
echohl WarningMsg
echomsg a:msg
echohl NONE
endfunction
" Point of entry for basic default usage. Give a relative path to invoke " Point of entry for basic default usage. Give a relative path to invoke
" pathogen#incubate() (defaults to "bundle/{}"), or an absolute path to invoke " pathogen#interpose() (defaults to "bundle/{}"), or an absolute path to invoke
" pathogen#surround(). For backwards compatibility purposes, a full path that " pathogen#surround(). Curly braces are expanded with pathogen#expand():
" does not end in {} or * is given to pathogen#runtime_prepend_subdirectories() " "bundle/{}" finds all subdirectories inside "bundle" inside all directories
" instead. " in the runtime path.
function! pathogen#infect(...) abort " {{{1 function! pathogen#infect(...) abort
for path in a:0 ? reverse(copy(a:000)) : ['bundle/{}'] for path in a:0 ? filter(reverse(copy(a:000)), 'type(v:val) == type("")') : ['bundle/{}']
if path =~# '^[^\\/]\+$' if path =~# '^\%({\=[$~\\/]\|{\=\w:[\\/]\).*[{}*]'
call s:warn('Change pathogen#infect('.string(path).') to pathogen#infect('.string(path.'/{}').')')
call pathogen#incubate(path . '/{}')
elseif path =~# '^[^\\/]\+[\\/]\%({}\|\*\)$'
call pathogen#incubate(path)
elseif path =~# '[\\/]\%({}\|\*\)$'
call pathogen#surround(path) call pathogen#surround(path)
else elseif path =~# '^\%([$~\\/]\|\w:[\\/]\)'
call s:warn('Change pathogen#infect('.string(path).') to pathogen#infect('.string(path.'/{}').')') call s:warn('Change pathogen#infect('.string(path).') to pathogen#infect('.string(path.'/{}').')')
call pathogen#surround(path . '/{}') call pathogen#surround(path . '/{}')
elseif path =~# '[{}*]'
call pathogen#interpose(path)
else
call s:warn('Change pathogen#infect('.string(path).') to pathogen#infect('.string(path.'/{}').')')
call pathogen#interpose(path . '/{}')
endif endif
endfor endfor
call pathogen#cycle_filetype() call pathogen#cycle_filetype()
if pathogen#is_disabled($MYVIMRC)
return 'finish'
endif
return '' return ''
endfunction " }}}1 endfunction
" Split a path into a list. " Split a path into a list.
function! pathogen#split(path) abort " {{{1 function! pathogen#split(path) abort
if type(a:path) == type([]) | return a:path | endif if type(a:path) == type([]) | return a:path | endif
if empty(a:path) | return [] | endif
let split = split(a:path,'\\\@<!\%(\\\\\)*\zs,') let split = split(a:path,'\\\@<!\%(\\\\\)*\zs,')
return map(split,'substitute(v:val,''\\\([\\,]\)'',''\1'',"g")') return map(split,'substitute(v:val,''\\\([\\,]\)'',''\1'',"g")')
endfunction " }}}1 endfunction
" Convert a list to a path. " Convert a list to a path.
function! pathogen#join(...) abort " {{{1 function! pathogen#join(...) abort
if type(a:1) == type(1) && a:1 if type(a:1) == type(1) && a:1
let i = 1 let i = 1
let space = ' ' let space = ' '
@ -77,15 +74,143 @@ function! pathogen#join(...) abort " {{{1
let i += 1 let i += 1
endwhile endwhile
return substitute(path,'^,','','') return substitute(path,'^,','','')
endfunction " }}}1 endfunction
" Convert a list to a path with escaped spaces for 'path', 'tag', etc. " Convert a list to a path with escaped spaces for 'path', 'tag', etc.
function! pathogen#legacyjoin(...) abort " {{{1 function! pathogen#legacyjoin(...) abort
return call('pathogen#join',[1] + a:000) return call('pathogen#join',[1] + a:000)
endfunction " }}}1 endfunction
" Turn filetype detection off and back on again if it was already enabled.
function! pathogen#cycle_filetype() abort
if exists('g:did_load_filetypes')
filetype off
filetype on
endif
endfunction
" Check if a bundle is disabled. A bundle is considered disabled if its
" basename or full name is included in the list g:pathogen_disabled.
function! pathogen#is_disabled(path) abort
if a:path =~# '\~$'
return 1
endif
let sep = pathogen#slash()
let blacklist = map(
\ get(g:, 'pathogen_blacklist', get(g:, 'pathogen_disabled', [])) +
\ pathogen#split($VIMBLACKLIST),
\ 'substitute(v:val, "[\\/]$", "", "")')
return index(blacklist, fnamemodify(a:path, ':t')) != -1 || index(blacklist, a:path) != -1
endfunction "}}}1
" Prepend the given directory to the runtime path and append its corresponding
" after directory. Curly braces are expanded with pathogen#expand().
function! pathogen#surround(path) abort
let sep = pathogen#slash()
let rtp = pathogen#split(&rtp)
let path = fnamemodify(a:path, ':p:?[\\/]\=$??')
let before = filter(pathogen#expand(path), '!pathogen#is_disabled(v:val)')
let after = filter(reverse(pathogen#expand(path.sep.'after')), '!pathogen#is_disabled(v:val[0:-7])')
call filter(rtp, 'index(before + after, v:val) == -1')
let &rtp = pathogen#join(before, rtp, after)
return &rtp
endfunction
" For each directory in the runtime path, add a second entry with the given
" argument appended. Curly braces are expanded with pathogen#expand().
function! pathogen#interpose(name) abort
let sep = pathogen#slash()
let name = a:name
if has_key(s:done_bundles, name)
return ""
endif
let s:done_bundles[name] = 1
let list = []
for dir in pathogen#split(&rtp)
if dir =~# '\<after$'
let list += reverse(filter(pathogen#expand(dir[0:-6].name.sep.'after'), '!pathogen#is_disabled(v:val[0:-7])')) + [dir]
else
let list += [dir] + filter(pathogen#expand(dir.sep.name), '!pathogen#is_disabled(v:val)')
endif
endfor
let &rtp = pathogen#join(pathogen#uniq(list))
return 1
endfunction
let s:done_bundles = {}
" Invoke :helptags on all non-$VIM doc directories in runtimepath.
function! pathogen#helptags() abort
let sep = pathogen#slash()
for glob in pathogen#split(&rtp)
for dir in map(split(glob(glob), "\n"), 'v:val.sep."/doc/".sep')
if (dir)[0 : strlen($VIMRUNTIME)] !=# $VIMRUNTIME.sep && filewritable(dir) == 2 && !empty(split(glob(dir.'*.txt'))) && (!filereadable(dir.'tags') || filewritable(dir.'tags'))
silent! execute 'helptags' pathogen#fnameescape(dir)
endif
endfor
endfor
endfunction
command! -bar Helptags :call pathogen#helptags()
" Execute the given command. This is basically a backdoor for --remote-expr.
function! pathogen#execute(...) abort
for command in a:000
execute command
endfor
return ''
endfunction
" Section: Unofficial
function! pathogen#is_absolute(path) abort
return a:path =~# (has('win32') ? '^\%([\\/]\|\w:\)[\\/]\|^[~$]' : '^[/~$]')
endfunction
" Given a string, returns all possible permutations of comma delimited braced
" alternatives of that string. pathogen#expand('/{a,b}/{c,d}') yields
" ['/a/c', '/a/d', '/b/c', '/b/d']. Empty braces are treated as a wildcard
" and globbed. Actual globs are preserved.
function! pathogen#expand(pattern) abort
if a:pattern =~# '{[^{}]\+}'
let [pre, pat, post] = split(substitute(a:pattern, '\(.\{-\}\){\([^{}]\+\)}\(.*\)', "\\1\001\\2\001\\3", ''), "\001", 1)
let found = map(split(pat, ',', 1), 'pre.v:val.post')
let results = []
for pattern in found
call extend(results, pathogen#expand(pattern))
endfor
return results
elseif a:pattern =~# '{}'
let pat = matchstr(a:pattern, '^.*{}[^*]*\%($\|[\\/]\)')
let post = a:pattern[strlen(pat) : -1]
return map(split(glob(substitute(pat, '{}', '*', 'g')), "\n"), 'v:val.post')
else
return [a:pattern]
endif
endfunction
" \ on Windows unless shellslash is set, / everywhere else.
function! pathogen#slash() abort
return !exists("+shellslash") || &shellslash ? '/' : '\'
endfunction
function! pathogen#separator() abort
return pathogen#slash()
endfunction
" Convenience wrapper around glob() which returns a list.
function! pathogen#glob(pattern) abort
let files = split(glob(a:pattern),"\n")
return map(files,'substitute(v:val,"[".pathogen#slash()."/]$","","")')
endfunction "}}}1
" Like pathogen#glob(), only limit the results to directories.
function! pathogen#glob_directories(pattern) abort
return filter(pathogen#glob(a:pattern),'isdirectory(v:val)')
endfunction "}}}1
" Remove duplicates from a list. " Remove duplicates from a list.
function! pathogen#uniq(list) abort " {{{1 function! pathogen#uniq(list) abort
let i = 0 let i = 0
let seen = {} let seen = {}
while i < len(a:list) while i < len(a:list)
@ -100,142 +225,18 @@ function! pathogen#uniq(list) abort " {{{1
endif endif
endwhile endwhile
return a:list return a:list
endfunction " }}}1
" \ on Windows unless shellslash is set, / everywhere else.
function! pathogen#separator() abort " {{{1
return !exists("+shellslash") || &shellslash ? '/' : '\'
endfunction " }}}1
" Convenience wrapper around glob() which returns a list.
function! pathogen#glob(pattern) abort " {{{1
let files = split(glob(a:pattern),"\n")
return map(files,'substitute(v:val,"[".pathogen#separator()."/]$","","")')
endfunction "}}}1
" Like pathogen#glob(), only limit the results to directories.
function! pathogen#glob_directories(pattern) abort " {{{1
return filter(pathogen#glob(a:pattern),'isdirectory(v:val)')
endfunction "}}}1
" Turn filetype detection off and back on again if it was already enabled.
function! pathogen#cycle_filetype() " {{{1
if exists('g:did_load_filetypes')
filetype off
filetype on
endif
endfunction " }}}1
" Check if a bundle is disabled. A bundle is considered disabled if it ends
" in a tilde or its basename or full name is included in the list
" g:pathogen_disabled.
function! pathogen#is_disabled(path) " {{{1
if a:path =~# '\~$'
return 1
elseif !exists("g:pathogen_disabled")
return 0
endif
let sep = pathogen#separator()
let blacklist = g:pathogen_disabled
return index(blacklist, strpart(a:path, strridx(a:path, sep)+1)) != -1 && index(blacklist, a:path) != 1
endfunction "}}}1
" Prepend the given directory to the runtime path and append its corresponding
" after directory. If the directory is already included, move it to the
" outermost position. Wildcards are added as is. Ending a path in /{} causes
" all subdirectories to be added (except those in g:pathogen_disabled).
function! pathogen#surround(path) abort " {{{1
let sep = pathogen#separator()
let rtp = pathogen#split(&rtp)
if a:path =~# '[\\/]{}$'
let path = fnamemodify(a:path[0:-4], ':p:s?[\\/]\=$??')
let before = filter(pathogen#glob_directories(path.sep.'*'), '!pathogen#is_disabled(v:val)')
let after = filter(reverse(pathogen#glob_directories(path.sep."*".sep."after")), '!pathogen#is_disabled(v:val[0:-7])')
call filter(rtp,'v:val[0:strlen(path)-1] !=# path')
else
let path = fnamemodify(a:path, ':p:s?[\\/]\=$??')
let before = [path]
let after = [path . sep . 'after']
call filter(rtp, 'index(before + after, v:val) == -1')
endif
let &rtp = pathogen#join(before, rtp, after)
return &rtp
endfunction " }}}1
" Prepend all subdirectories of path to the rtp, and append all 'after'
" directories in those subdirectories. Deprecated.
function! pathogen#runtime_prepend_subdirectories(path) " {{{1
call s:warn('Change pathogen#runtime_prepend_subdirectories('.string(a:path).') to pathogen#surround('.string(a:path.'/{}').')')
return pathogen#surround(a:path . pathogen#separator() . '{}')
endfunction " }}}1
" For each directory in the runtime path, add a second entry with the given
" argument appended. If the argument ends in '/{}', add a separate entry for
" each subdirectory. The default argument is 'bundle/{}', which means that
" .vim/bundle/*, $VIM/vimfiles/bundle/*, $VIMRUNTIME/bundle/*,
" $VIM/vim/files/bundle/*/after, and .vim/bundle/*/after will be added (on
" UNIX).
function! pathogen#incubate(...) abort " {{{1
let sep = pathogen#separator()
let name = a:0 ? a:1 : 'bundle/{}'
if "\n".s:done_bundles =~# "\\M\n".name."\n"
return ""
endif
let s:done_bundles .= name . "\n"
let list = []
for dir in pathogen#split(&rtp)
if dir =~# '\<after$'
if name =~# '{}$'
let list += filter(pathogen#glob_directories(substitute(dir,'after$',name[0:-3],'').'*'.sep.'after'), '!pathogen#is_disabled(v:val[0:-7])') + [dir]
else
let list += [dir, substitute(dir, 'after$', '', '') . name . sep . 'after']
endif
else
if name =~# '{}$'
let list += [dir] + filter(pathogen#glob_directories(dir.sep.name[0:-3].'*'), '!pathogen#is_disabled(v:val)')
else
let list += [dir . sep . name, dir]
endif
endif
endfor
let &rtp = pathogen#join(pathogen#uniq(list))
return 1
endfunction " }}}1
" Deprecated alias for pathogen#incubate().
function! pathogen#runtime_append_all_bundles(...) abort " {{{1
if a:0
call s:warn('Change pathogen#runtime_append_all_bundles('.string(a:1).') to pathogen#incubate('.string(a:1.'/{}').')')
else
call s:warn('Change pathogen#runtime_append_all_bundles() to pathogen#incubate()')
endif
return call('pathogen#incubate', map(copy(a:000),'v:val . "/{}"'))
endfunction endfunction
let s:done_bundles = '' " Backport of fnameescape().
" }}}1 function! pathogen#fnameescape(string) abort
if exists('*fnameescape')
" Invoke :helptags on all non-$VIM doc directories in runtimepath. return fnameescape(a:string)
function! pathogen#helptags() abort " {{{1 elseif a:string ==# '-'
let sep = pathogen#separator() return '\-'
for glob in pathogen#split(&rtp) else
for dir in split(glob(glob), "\n") return substitute(escape(a:string," \t\n*?[{`$\\%#'\"|!<"),'^[+>]','\\&','')
if (dir.sep)[0 : strlen($VIMRUNTIME)] !=# $VIMRUNTIME.sep && filewritable(dir.sep.'doc') == 2 && !empty(filter(split(glob(dir.sep.'doc'.sep.'*'),"\n>"),'!isdirectory(v:val)')) && (!filereadable(dir.sep.'doc'.sep.'tags') || filewritable(dir.sep.'doc'.sep.'tags')) endif
silent! execute 'helptags' pathogen#fnameescape(dir.'/doc') endfunction
endif
endfor
endfor
endfunction " }}}1
command! -bar Helptags :call pathogen#helptags()
" Execute the given command. This is basically a backdoor for --remote-expr.
function! pathogen#execute(...) abort " {{{1
for command in a:000
execute command
endfor
return ''
endfunction " }}}1
" Like findfile(), but hardcoded to use the runtimepath. " Like findfile(), but hardcoded to use the runtimepath.
function! pathogen#runtime_findfile(file,count) abort "{{{1 function! pathogen#runtime_findfile(file,count) abort "{{{1
@ -246,18 +247,38 @@ function! pathogen#runtime_findfile(file,count) abort "{{{1
else else
return fnamemodify(file,':p') return fnamemodify(file,':p')
endif endif
endfunction " }}}1 endfunction
" Backport of fnameescape(). " Section: Deprecated
function! pathogen#fnameescape(string) abort " {{{1
if exists('*fnameescape') function! s:warn(msg) abort
return fnameescape(a:string) echohl WarningMsg
elseif a:string ==# '-' echomsg a:msg
return '\-' echohl NONE
endfunction
" Prepend all subdirectories of path to the rtp, and append all 'after'
" directories in those subdirectories. Deprecated.
function! pathogen#runtime_prepend_subdirectories(path) abort
call s:warn('Change pathogen#runtime_prepend_subdirectories('.string(a:path).') to pathogen#infect('.string(a:path.'/{}').')')
return pathogen#surround(a:path . pathogen#slash() . '{}')
endfunction
function! pathogen#incubate(...) abort
let name = a:0 ? a:1 : 'bundle/{}'
call s:warn('Change pathogen#incubate('.(a:0 ? string(a:1) : '').') to pathogen#infect('.string(name).')')
return pathogen#interpose(name)
endfunction
" Deprecated alias for pathogen#interpose().
function! pathogen#runtime_append_all_bundles(...) abort
if a:0
call s:warn('Change pathogen#runtime_append_all_bundles('.string(a:1).') to pathogen#infect('.string(a:1.'/{}').')')
else else
return substitute(escape(a:string," \t\n*?[{`$\\%#'\"|!<"),'^[+>]','\\&','') call s:warn('Change pathogen#runtime_append_all_bundles() to pathogen#infect()')
endif endif
endfunction " }}}1 return pathogen#interpose(a:0 ? a:1 . '/{}' : 'bundle/{}')
endfunction
if exists(':Vedit') if exists(':Vedit')
finish finish
@ -265,7 +286,7 @@ endif
let s:vopen_warning = 0 let s:vopen_warning = 0
function! s:find(count,cmd,file,lcd) " {{{1 function! s:find(count,cmd,file,lcd)
let rtp = pathogen#join(1,pathogen#split(&runtimepath)) let rtp = pathogen#join(1,pathogen#split(&runtimepath))
let file = pathogen#runtime_findfile(a:file,a:count) let file = pathogen#runtime_findfile(a:file,a:count)
if file ==# '' if file ==# ''
@ -284,10 +305,10 @@ function! s:find(count,cmd,file,lcd) " {{{1
else else
return a:cmd.' '.pathogen#fnameescape(file) . warning return a:cmd.' '.pathogen#fnameescape(file) . warning
endif endif
endfunction " }}}1 endfunction
function! s:Findcomplete(A,L,P) " {{{1 function! s:Findcomplete(A,L,P)
let sep = pathogen#separator() let sep = pathogen#slash()
let cheats = { let cheats = {
\'a': 'autoload', \'a': 'autoload',
\'d': 'doc', \'d': 'doc',
@ -312,7 +333,7 @@ function! s:Findcomplete(A,L,P) " {{{1
endfor endfor
endfor endfor
return sort(keys(found)) return sort(keys(found))
endfunction " }}}1 endfunction
command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Ve :execute s:find(<count>,'edit<bang>',<q-args>,0) command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Ve :execute s:find(<count>,'edit<bang>',<q-args>,0)
command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vedit :execute s:find(<count>,'edit<bang>',<q-args>,0) command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vedit :execute s:find(<count>,'edit<bang>',<q-args>,0)
@ -323,4 +344,4 @@ command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vtabed
command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vpedit :execute s:find(<count>,'pedit',<q-args>,<bang>1) command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vpedit :execute s:find(<count>,'pedit',<q-args>,<bang>1)
command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vread :execute s:find(<count>,'read',<q-args>,<bang>1) command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vread :execute s:find(<count>,'read',<q-args>,<bang>1)
" vim:set et sw=2: " vim:set et sw=2 foldmethod=expr foldexpr=getline(v\:lnum)=~'^\"\ Section\:'?'>1'\:getline(v\:lnum)=~#'^fu'?'a1'\:getline(v\:lnum)=~#'^endf'?'s1'\:'=':

View file

@ -1,101 +1,60 @@
# ack.vim # # ack.vim
This plugin is a front for the Perl module This plugin is a front for the Perl module
[App::Ack](http://search.cpan.org/~petdance/ack/ack). Ack can be used as a [App::Ack](http://search.cpan.org/~petdance/ack/ack). Ack can be used as a
replacement for 99% of the uses of _grep_. This plugin will allow you to run replacement for 99% of the uses of _grep_. This plugin will allow you to run
ack from vim, and shows the results in a split window. ack from vim, and shows the results in a split window.
The *Official Version* of this plugin is available at [vim.org](http://www.vim.org/scripts/script.php?script_id=2572). ## Installation
## Installation ##
### Ack ### Ack
You have to install [ack](http://betterthangrep.com/), of course. You will need the ack(>= 2.0), of course, to install it follow the
[manual](http://beyondgrep.com/install/)
Install on Debian / Ubuntu with:
sudo apt-get install ack-grep
Install on Fedora with:
su -l -c 'yum install ack'
Install on openSUSE with:
sudo zypper install ack
Install on Gentoo with:
sudo emerge ack
Install with Homebrew:
brew install ack
Install with MacPorts:
sudo port install p5-app-ack
Install with Gentoo Prefix:
emerge ack
Install on FreeBSD with:
cd /usr/ports/textproc/p5-ack/ && make install clean
You can specify a custom ack name and path in your .vimrc like so:
let g:ackprg="<custom-ack-path-goes-here> -H --nocolor --nogroup --column"
Otherwise, you are on your own.
### The Plugin ### The Plugin
If you have [Rake](http://rake.rubyforge.org/) installed, you can just run: `rake install`. To install it is recommended to use one of the popular package managers for Vim,
rather than installing by drag and drop all required files into your `.vim` folder.
Otherwise, the file ack.vim goes in ~/.vim/plugin, and the ack.txt file belongs in ~/.vim/doc. Be sure to run #### Manual (not recommended)
:helptags ~/.vim/doc Just
[download](https://github.com/mileszs/ack.vim/archive/kb-improve-readme.zip) the
plugin and put it in your `~/.vim/`(or `%PROGRAMFILES%/Vim/vimfiles` on windows)
afterwards. #### Vundle
Bundle 'mileszs/ack.vim'
## Usage ## #### NeoBundle
:Ack [options] {pattern} [{directory}] NeoBundle 'mileszs/ack.vim'
Search recursively in {directory} (which defaults to the current directory) for the {pattern}. ## Usage
:Ack [options] {pattern} [{directories}]
Search recursively in {directory} (which defaults to the current directory) for
the {pattern}.
Files containing the search term will be listed in the split window, along with 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 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. in this window will open the file, and place the cursor on the matching line.
Just like where you use :grep, :grepadd, :lgrep, and :lgrepadd, you can use `:Ack`, `:AckAdd`, `:LAck`, and `:LAckAdd` respectively. (See `doc/ack.txt`, or install and `:h Ack` for more information.) Just like where you use :grep, :grepadd, :lgrep, and :lgrepadd, you can use
`:Ack`, `:AckAdd`, `:LAck`, and `:LAckAdd` respectively.
(See `doc/ack.txt`, or install and `:h Ack` for more information.)
**From the [ack docs](http://betterthangrep.com/)** (my favorite feature): For more ack options see
[ack documentation](http://beyondgrep.com/documentation/)
--type=TYPE, --type=noTYPE ### Keyboard Shortcuts
Specify the types of files to include or exclude from a search. TYPE is a filetype, like perl or xml. --type=perl can also be specified as --perl, and --type=noperl can be done as --noperl.
If a file is of both type "foo" and "bar", specifying --foo and --nobar will exclude the file, because an exclusion takes precedence over an inclusion.
Type specifications can be repeated and are ORed together.
See ack --help=types for a list of valid types.
### Gotchas ###
Some characters have special meaning, and need to be escaped your search pattern. For instance, '#'. You have to escape it like this `:Ack '\\\#define foo'` to search for `#define foo`. (From [blueyed in issue #5](https://github.com/mileszs/ack.vim/issues/5).)
### Keyboard Shortcuts ###
In the quickfix window, you can use: In the quickfix window, you can use:
o to open (same as enter) o to open (same as enter)
O to open and close quickfix window
go to preview file (open but maintain focus on ack.vim results) go to preview file (open but maintain focus on ack.vim results)
t to open in new tab t to open in new tab
T to open in new tab silently T to open in new tab silently
@ -106,9 +65,67 @@ In the quickfix window, you can use:
q to close the quickfix window q to close the quickfix window
This Vim plugin is derived (and by derived, I mean copied, essentially) from This Vim plugin is derived (and by derived, I mean copied, essentially) from
Antoine Imbert's blog post [Ack and Vim Antoine Imbert's blog post
Integration](http://blog.ant0ine.com/typepad/2007/03/ack-and-vim-integration.html) (in [Ack and Vim Integration](http://blog.ant0ine.com/typepad/2007/03/ack-and-vim-integration.html)
particular, the function at the bottom of the post). I added a help file that (in particular, the function at the bottom of the post). I added a help file that
provides just enough reference to get you going. I also highly recommend you provides just enough reference to get you going. I also highly recommend you
check out the docs for the Perl script 'ack', for obvious reasons: [ack - check out the docs for the Perl script 'ack', for obvious reasons:
grep-like text finder](http://betterthangrep.com/). [ack - grep-like text finder](http://beyondgrep.com/).
### Gotchas
Some characters have special meaning, and need to be escaped your search
pattern. For instance, '#'. You have to escape it like this `:Ack '\\\#define
foo'` to search for '#define foo'. (From blueyed in issue #5.)
## Changelog
### 1.0
* Remove support to ack 1.x
* Start to use a Changelog
* Use `autoload` directory to define functions, instead of `plugin`.
* Add option to auto fold the results(`g:ack_autofold_results`)
* Improve documentation, list all options and shortcuts
* Improve highlight option to work when passes directories or use quotes.
* Add g:ack_mapping
* Add g:ack_default_options
* Add a help toggle `?`(like NERDTree)
### 1.0.1
* Fixes #124. Bug with `g:ack_autofold_results`
### 1.0.2
* Add compatibility with [vim-dispatch](https://github.com/tpope/vim-dispatch)
### 1.0.3
* Fixes #127. Use `&l:hlsearch` instead of `v:hlsearch` to keep compatibility
with versions that does not have this variable.
### 1.0.4
* Fixes #128. Always apply mappings, even when using vim-dispatch.
### 1.0.5
* Fixes #128. Fixes the `errorformat` for ack when using vim-dispatch.
* Do not use vim-dispatch by default. To use vim-dispath must set
`g:ack_use_dispatch`
### 1.0.6
* Fixes highlight function to work when user passes options. Ex.: Ack -i test
Thank's @mannih. (#131, #134)
### 1.0.7
* Fixes highlight function to work when passes more than one option, or options
with double dashes(--option) Thank's to @MiguelLatorre and @mannih
### 1.0.8
* Fixes (again) highlight, now using negative look behind.
* Change mappings `o` and `O` to behave as documented

View file

@ -16,7 +16,7 @@ shows the results in a split window.
Search recursively in {directory} (which defaults to the current Search recursively in {directory} (which defaults to the current
directory) for the {pattern}. Behaves just like the |:grep| command, but directory) for the {pattern}. Behaves just like the |:grep| command, but
will open the |Quickfix| window for you. If [!] is not given the first will open the |Quickfix| window for you. If [!] is not given the first
error is jumped to. occurence is jumped to.
:AckAdd [options] {pattern} [{directory}] *:AckAdd* :AckAdd [options] {pattern} [{directory}] *:AckAdd*
@ -45,7 +45,7 @@ shows the results in a split window.
:AckHelp[!] [options] {pattern} *:AckHelp* :AckHelp[!] [options] {pattern} *:AckHelp*
Search vim documentation files for the {pattern}. Behaves just like the Search vim documentation files for the {pattern}. Behaves just like the
|:Ack| command, but searches only vim documentation .txt files |:Ack| command, but searches only vim documentation .txt files
:LAckHelp [options] {pattern} *:LAckHelp* :LAckHelp [options] {pattern} *:LAckHelp*
@ -53,6 +53,16 @@ shows the results in a split window.
Just like |:AckHelp| but instead of the |quickfix| list, matches are placed Just like |:AckHelp| but instead of the |quickfix| list, matches are placed
in the current |location-list|. in the current |location-list|.
:AckWindow[!] [options] {pattern} *:AckWindow*
Search all buffers visible in the screen (current tab page only) files for
the {pattern}.
:LAckWindow [options] {pattern} *:LAckWindow*
Just like |:AckWindow| but instead of the |quickfix| list, matches are
placed in the current |location-list|.
Files containing the search term will be listed in the split window, along 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 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 a line in this window will open the file, and place the cursor on the matching
@ -60,6 +70,151 @@ line.
See http://betterthangrep.com/ for more information. See http://betterthangrep.com/ for more information.
==============================================================================
CONFIGURATION *ack-configuration*
*g:ackprg*
g:ackprg
Default for ubuntu: "ack-grep"
Default for other systems: "ack"
Use this option to specify the ack command and its options
Example:
>
let g:ackprg = "other-bin-ack"
<
*g:ack_default_options*
g:ack_default_options
Default: " -s -H --nocolor --nogroup --column"
Use this option to specify the options used by ack
Example:
>
let g:ack_default_options =
\ " -s -H --nocolor --nogroup --column --smart-case --follow"
<
*g:ack_apply_qmappings*
g:ack_apply_qmappings
Default: 1
This option enable mappings on quickview window.
*g:ack_apply_lmappings*
g:ack_apply_lmappings
Default: 1
This option enable mappings on Location list window.
*g:ack_mappings*
g:ack_mappings
Default: {
\ "t": "<C-W><CR><C-W>T",
\ "T": "<C-W><CR><C-W>TgT<C-W>j",
\ "o": "<CR>",
\ "O": "<CR><C-W><C-W>:ccl<CR>",
\ "go": "<CR><C-W>j",
\ "h": "<C-W><CR><C-W>K",
\ "H": "<C-W><CR><C-W>K<C-W>b",
\ "v": "<C-W><CR><C-W>H<C-W>b<C-W>J<C-W>t",
\ "gv": "<C-W><CR><C-W>H<C-W>b<C-W>J" }
This option list all maps create on quickfix/Location list window.
Example, if you want to open the result in the middle of the screen:
>
let g:ack_mappings = { "o": "<CR>zz" }
<
*g:ack_qhandler*
g:ack_qhandler
Default: "botright copen"
Command to open the quickview window.
If you want to open a quickview window with 30 lines you can do:
>
let g:ack_qhandler = "botright copen 30"
<
*g:ack_lhandler*
g:ack_lhandler
Default: "botright lopen"
Command to open the Location list window.
If you want to open a Location list window with 30 lines you can do:
>
let g:ack_lhandler = "botright lopen 30"
<
*g:ackhighlight*
g:ackhighlight
Default: 0
Use this option to highlight the searched term.
Example:
>
let g:ackhighlight = 1
<
*g:ack_autoclose*
g:ack_autoclose
Default: 0
Use this option to specify whether to close the quickfix window after
using any of the shortcuts.
Example:
>
let g:ack_autoclose = 1
<
*g:ack_autofold_results*
g:ack_autofold_results
Default: 0
Use this option to fold the results in quickfix by file name. Only the current
fold will be open by default and while you press 'j' and 'k' to move between the
results if you hit other fold the last one will be closed and the current will
be open.
Example:
>
let g:ack_autofold_results = 1
<
*g:ackpreview*
g:ackpreview
Default: 0
Use this option to automagically open the file with 'j' or 'k'.
Example:
>
let g:ackpreview = 1
<
*g:ack_use_dispatch*
g:ack_use_dispatch
Default: 0
Use this option to use vim-dispatch to search the results in background
Example:
>
let g:ack_use_dispatch = 1
<
============================================================================== ==============================================================================
MAPPINGS *ack-mappings* MAPPINGS *ack-mappings*
@ -67,6 +222,8 @@ The following keyboard shortcuts are available in the quickfix window:
o open file (same as enter). o open file (same as enter).
O open file and close quickfix window.
go preview file (open but maintain focus on ack.vim results). go preview file (open but maintain focus on ack.vim results).
t open in a new tab. t open in a new tab.

View file

@ -1,16 +1,17 @@
" NOTE: You must, of course, install the ack script if !exists("g:ack_default_options")
" in your path. let g:ack_default_options = " -s -H --nocolor --nogroup --column"
" On Debian / Ubuntu: endif
" sudo apt-get install ack-grep
" With MacPorts:
" sudo port install p5-app-ack
" With Homebrew:
" brew install ack
" Location of the ack utility " Location of the ack utility
if !exists("g:ackprg") if !exists("g:ackprg")
let s:ackcommand = executable('ack-grep') ? 'ack-grep' : 'ack' if executable('ack')
let g:ackprg=s:ackcommand." -H --nocolor --nogroup --column" let g:ackprg = "ack"
elseif executable('ack-grep')
let g:ackprg = "ack-grep"
else
finish
endif
let g:ackprg .= g:ack_default_options
endif endif
if !exists("g:ack_apply_qmappings") if !exists("g:ack_apply_qmappings")
@ -21,102 +22,54 @@ if !exists("g:ack_apply_lmappings")
let g:ack_apply_lmappings = !exists("g:ack_lhandler") let g:ack_apply_lmappings = !exists("g:ack_lhandler")
endif endif
if !exists("g:ack_use_dispatch")
let g:ack_use_dispatch = 0
end
let s:ack_mappings = {
\ "t": "<C-W><CR><C-W>T",
\ "T": "<C-W><CR><C-W>TgT<C-W>j",
\ "o": "<CR>",
\ "O": "<CR><C-W>p<C-W>c",
\ "go": "<CR><C-W>p",
\ "h": "<C-W><CR><C-W>K",
\ "H": "<C-W><CR><C-W>K<C-W>b",
\ "v": "<C-W><CR><C-W>H<C-W>b<C-W>J<C-W>t",
\ "gv": "<C-W><CR><C-W>H<C-W>b<C-W>J" }
if exists("g:ack_mappings")
let g:ack_mappings = extend(s:ack_mappings, g:ack_mappings)
else
let g:ack_mappings = s:ack_mappings
endif
if !exists("g:ack_qhandler") if !exists("g:ack_qhandler")
let g:ack_qhandler="botright copen" let g:ack_qhandler = "botright copen"
endif endif
if !exists("g:ack_lhandler") if !exists("g:ack_lhandler")
let g:ack_lhandler="botright lopen" let g:ack_lhandler = "botright lopen"
endif endif
function! s:Ack(cmd, args) if !exists("g:ackhighlight")
redraw let g:ackhighlight = 0
echo "Searching ..." endif
" If no pattern is provided, search for the word under the cursor if !exists("g:ack_autoclose")
if empty(a:args) let g:ack_autoclose = 0
let l:grepargs = expand("<cword>") endif
else
let l:grepargs = a:args . join(a:000, ' ')
end
" Format, used to manage column jump if !exists("g:ack_autofold_results")
if a:cmd =~# '-g$' let g:ack_autofold_results = 0
let g:ackformat="%f" endif
else
let g:ackformat="%f:%l:%c:%m,%f:%l:%m"
end
let grepprg_bak=&grepprg command! -bang -nargs=* -complete=file Ack call ack#Ack('grep<bang>', <q-args>)
let grepformat_bak=&grepformat command! -bang -nargs=* -complete=file AckAdd call ack#Ack('grepadd<bang>', <q-args>)
try command! -bang -nargs=* -complete=file AckFromSearch call ack#AckFromSearch('grep<bang>', <q-args>)
let &grepprg=g:ackprg command! -bang -nargs=* -complete=file LAck call ack#Ack('lgrep<bang>', <q-args>)
let &grepformat=g:ackformat command! -bang -nargs=* -complete=file LAckAdd call ack#Ack('lgrepadd<bang>', <q-args>)
silent execute a:cmd . " " . escape(l:grepargs, '|') command! -bang -nargs=* -complete=file AckFile call ack#Ack('grep<bang> -g', <q-args>)
finally command! -bang -nargs=* -complete=help AckHelp call ack#AckHelp('grep<bang>', <q-args>)
let &grepprg=grepprg_bak command! -bang -nargs=* -complete=help LAckHelp call ack#AckHelp('lgrep<bang>', <q-args>)
let &grepformat=grepformat_bak command! -bang -nargs=* -complete=help AckWindow call ack#AckWindow('grep<bang>', <q-args>)
endtry command! -bang -nargs=* -complete=help LAckWindow call ack#AckWindow('lgrep<bang>', <q-args>)
if a:cmd =~# '^l'
exe g:ack_lhandler
let l:apply_mappings = g:ack_apply_lmappings
let l:close_cmd = ':lclose<CR>'
else
exe g:ack_qhandler
let l:apply_mappings = g:ack_apply_qmappings
let l:close_cmd = ':cclose<CR>'
endif
if l:apply_mappings
exec "nnoremap <silent> <buffer> q " . l:close_cmd
exec "nnoremap <silent> <buffer> t <C-W><CR><C-W>T"
exec "nnoremap <silent> <buffer> T <C-W><CR><C-W>TgT<C-W><C-W>"
exec "nnoremap <silent> <buffer> o <CR>"
exec "nnoremap <silent> <buffer> go <CR><C-W><C-W>"
exec "nnoremap <silent> <buffer> h <C-W><CR><C-W>K"
exec "nnoremap <silent> <buffer> H <C-W><CR><C-W>K<C-W>b"
exec "nnoremap <silent> <buffer> v <C-W><CR><C-W>H<C-W>b<C-W>J<C-W>t"
exec "nnoremap <silent> <buffer> gv <C-W><CR><C-W>H<C-W>b<C-W>J"
endif
" If highlighting is on, highlight the search keyword.
if exists("g:ackhighlight")
let @/ = substitute(l:grepargs,'["'']','','g')
set hlsearch
end
redraw!
endfunction
function! s:AckFromSearch(cmd, args)
let search = getreg('/')
" translate vim regular expression to perl regular expression.
let search = substitute(search,'\(\\<\|\\>\)','\\b','g')
call s:Ack(a:cmd, '"' . search .'" '. a:args)
endfunction
function! s:GetDocLocations()
let dp = ''
for p in split(&rtp,',')
let p = p.'/doc/'
if isdirectory(p)
let dp = p.'*.txt '.dp
endif
endfor
return dp
endfunction
function! s:AckHelp(cmd,args)
let args = a:args.' '.s:GetDocLocations()
call s:Ack(a:cmd,args)
endfunction
command! -bang -nargs=* -complete=file Ack call s:Ack('grep<bang>',<q-args>)
command! -bang -nargs=* -complete=file AckAdd call s:Ack('grepadd<bang>', <q-args>)
command! -bang -nargs=* -complete=file AckFromSearch call s:AckFromSearch('grep<bang>', <q-args>)
command! -bang -nargs=* -complete=file LAck call s:Ack('lgrep<bang>', <q-args>)
command! -bang -nargs=* -complete=file LAckAdd call s:Ack('lgrepadd<bang>', <q-args>)
command! -bang -nargs=* -complete=file AckFile call s:Ack('grep<bang> -g', <q-args>)
command! -bang -nargs=* -complete=help AckHelp call s:AckHelp('grep<bang>',<q-args>)
command! -bang -nargs=* -complete=help LAckHelp call s:AckHelp('lgrep<bang>',<q-args>)

View file

@ -46,7 +46,7 @@ function! s:init_pad(command)
execute a:command execute a:command
setlocal buftype=nofile bufhidden=wipe nomodifiable nobuflisted noswapfile setlocal buftype=nofile bufhidden=wipe nomodifiable nobuflisted noswapfile
\ nonu nocursorline winfixwidth winfixheight statusline=\ \ nonu nocursorline nocursorcolumn winfixwidth winfixheight statusline=\
if exists('&rnu') if exists('&rnu')
setlocal nornu setlocal nornu
endif endif
@ -64,7 +64,8 @@ function! s:setup_pad(bufnr, vert, size)
execute win . 'wincmd w' execute win . 'wincmd w'
execute (a:vert ? 'vertical ' : '') . 'resize ' . max([0, a:size]) execute (a:vert ? 'vertical ' : '') . 'resize ' . max([0, a:size])
augroup goyop augroup goyop
autocmd WinEnter <buffer> call s:blank() autocmd WinEnter,CursorMoved <buffer> nested call s:blank()
autocmd WinLeave <buffer> call s:hide_statusline()
augroup END augroup END
" To hide scrollbars of pad windows in GVim " To hide scrollbars of pad windows in GVim
@ -104,17 +105,23 @@ function! s:tranquilize()
\ 'StatusLine', 'StatusLineNC', 'SignColumn'] \ 'StatusLine', 'StatusLineNC', 'SignColumn']
" -1 on Vim / '' on GVim " -1 on Vim / '' on GVim
if bg == -1 || empty(bg) if bg == -1 || empty(bg)
call s:set_color(grp, '', 'NONE')
call s:set_color(grp, 'fg', get(g:, 'goyo_bg', 'black')) call s:set_color(grp, 'fg', get(g:, 'goyo_bg', 'black'))
call s:set_color(grp, 'bg', 'NONE') call s:set_color(grp, 'bg', 'NONE')
else else
call s:set_color(grp, 'fg', bg) call s:set_color(grp, 'fg', bg)
call s:set_color(grp, 'bg', bg) call s:set_color(grp, 'bg', bg)
endif endif
call s:set_color(grp, '', 'NONE')
endfor endfor
endfunction endfunction
function! s:hide_statusline()
let &l:statusline = repeat(' ', winwidth(0))
endfunction
function! s:goyo_on(width) function! s:goyo_on(width)
let s:orig_tab = tabpagenr()
" New tab " New tab
tab split tab split
@ -125,10 +132,10 @@ function! s:goyo_on(width)
\ { 'laststatus': &laststatus, \ { 'laststatus': &laststatus,
\ 'showtabline': &showtabline, \ 'showtabline': &showtabline,
\ 'fillchars': &fillchars, \ 'fillchars': &fillchars,
\ 'winminwidth': &winminwidth,
\ 'winwidth': &winwidth, \ 'winwidth': &winwidth,
\ 'winminheight': &winminheight, \ 'winminheight': &winminheight,
\ 'winheight': &winheight, \ 'winheight': &winheight,
\ 'statusline': &statusline,
\ 'ruler': &ruler, \ 'ruler': &ruler,
\ 'sidescroll': &sidescroll, \ 'sidescroll': &sidescroll,
\ 'sidescrolloff': &sidescrolloff \ 'sidescrolloff': &sidescrolloff
@ -143,6 +150,12 @@ function! s:goyo_on(width)
silent! GitGutterDisable silent! GitGutterDisable
endif endif
" vim-signify
let t:goyo_disabled_signify = exists('b:sy') && b:sy.active
if t:goyo_disabled_signify
SignifyToggle
endif
" vim-airline " vim-airline
let t:goyo_disabled_airline = exists("#airline") let t:goyo_disabled_airline = exists("#airline")
if t:goyo_disabled_airline if t:goyo_disabled_airline
@ -175,10 +188,10 @@ function! s:goyo_on(width)
endif endif
" Global options " Global options
set winwidth=1
let &winheight = max([&winminheight, 1]) let &winheight = max([&winminheight, 1])
set winminheight=1 set winminheight=1
set winheight=1 set winheight=1
set winminwidth=1 winwidth=1
set laststatus=0 set laststatus=0
set showtabline=0 set showtabline=0
set noruler set noruler
@ -202,19 +215,20 @@ function! s:goyo_on(width)
call s:resize_pads() call s:resize_pads()
call s:tranquilize() call s:tranquilize()
let &statusline = repeat(' ', winwidth(0))
augroup goyo augroup goyo
autocmd! autocmd!
autocmd BufWinLeave <buffer> call s:goyo_off() autocmd BufWinLeave <buffer> call s:goyo_off()
autocmd TabLeave * call s:goyo_off() autocmd TabLeave * call s:goyo_off()
autocmd VimResized * call s:resize_pads() autocmd VimResized * call s:resize_pads()
autocmd ColorScheme * call s:tranquilize() autocmd ColorScheme * call s:tranquilize()
autocmd WinEnter,WinLeave <buffer> call s:hide_statusline()
augroup END augroup END
call s:hide_statusline()
if exists('g:goyo_callbacks[0]') if exists('g:goyo_callbacks[0]')
call g:goyo_callbacks[0]() call g:goyo_callbacks[0]()
endif endif
silent! doautocmd User GoyoEnter
endfunction endfunction
function! s:goyo_off() function! s:goyo_off()
@ -239,9 +253,12 @@ function! s:goyo_off()
let goyo_revert = t:goyo_revert let goyo_revert = t:goyo_revert
let goyo_disabled_gitgutter = t:goyo_disabled_gitgutter let goyo_disabled_gitgutter = t:goyo_disabled_gitgutter
let goyo_disabled_signify = t:goyo_disabled_signify
let goyo_disabled_airline = t:goyo_disabled_airline let goyo_disabled_airline = t:goyo_disabled_airline
let goyo_disabled_powerline = t:goyo_disabled_powerline let goyo_disabled_powerline = t:goyo_disabled_powerline
let goyo_disabled_lightline = t:goyo_disabled_lightline let goyo_disabled_lightline = t:goyo_disabled_lightline
let goyo_orig_buffer = t:goyo_master
let [line, col] = [line('.'), col('.')]
if tabpagenr() == 1 if tabpagenr() == 1
tabnew tabnew
@ -249,7 +266,15 @@ function! s:goyo_off()
bd bd
endif endif
tabclose tabclose
execute 'normal! '.s:orig_tab.'gt'
if winbufnr(0) == goyo_orig_buffer
execute printf('normal! %dG%d|', line, col)
endif
let wmw = remove(goyo_revert, 'winminwidth')
let ww = remove(goyo_revert, 'winwidth')
let &winwidth = ww
let &winminwidth = wmw
let wmh = remove(goyo_revert, 'winminheight') let wmh = remove(goyo_revert, 'winminheight')
let wh = remove(goyo_revert, 'winheight') let wh = remove(goyo_revert, 'winheight')
let &winheight = max([wmh, 1]) let &winheight = max([wmh, 1])
@ -265,6 +290,12 @@ function! s:goyo_off()
silent! GitGutterEnable silent! GitGutterEnable
endif endif
if goyo_disabled_signify
silent! if !b:sy.active
SignifyToggle
endif
endif
if goyo_disabled_airline && !exists("#airline") if goyo_disabled_airline && !exists("#airline")
AirlineToggle AirlineToggle
silent! AirlineRefresh silent! AirlineRefresh
@ -286,22 +317,29 @@ function! s:goyo_off()
if exists('g:goyo_callbacks[1]') if exists('g:goyo_callbacks[1]')
call g:goyo_callbacks[1]() call g:goyo_callbacks[1]()
endif endif
silent! doautocmd User GoyoLeave
endfunction endfunction
function! s:goyo(...) function! s:goyo(bang, ...)
let width = a:0 > 0 ? a:1 : get(g:, 'goyo_width', 80) let width = a:0 > 0 ? a:1 : get(g:, 'goyo_width', 80)
if exists('#goyo') == 0 if a:bang
call s:goyo_on(width) if exists('#goyo')
elseif a:0 > 0 call s:goyo_off()
let t:goyo_width = width endif
call s:resize_pads()
else else
call s:goyo_off() if exists('#goyo') == 0
call s:goyo_on(width)
elseif a:0 > 0
let t:goyo_width = width
call s:resize_pads()
else
call s:goyo_off()
end
end end
endfunction endfunction
command! -nargs=? Goyo call s:goyo(<args>) command! -nargs=? -bar -bang Goyo call s:goyo('<bang>' == '!', <args>)
let &cpo = s:cpo_save let &cpo = s:cpo_save
unlet s:cpo_save unlet s:cpo_save

View file

@ -60,7 +60,7 @@ Installation
cd ~/.vim/bundle cd ~/.vim/bundle
git clone https://github.com/scrooloose/nerdtree.git git clone https://github.com/scrooloose/nerdtree.git
Then reload vim, run `:helptags`, and check out `:help NERD_tree.txt`. Then reload vim, run `:Helptags`, and check out `:help NERD_tree.txt`.
Faq Faq
@ -80,7 +80,10 @@ A. Stick this in your vimrc: `autocmd vimenter * NERDTree`
__Q. How can I open a NERDTree automatically when vim starts up if no files were specified?__ __Q. How can I open a NERDTree automatically when vim starts up if no files were specified?__
A. Stick this in your vimrc `autocmd vimenter * if !argc() | NERDTree | endif` A. Stick this in your vimrc
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
__Q. How can I map a specific key or shortcut to open NERDTree?__ __Q. How can I map a specific key or shortcut to open NERDTree?__

File diff suppressed because it is too large Load diff

View file

@ -109,7 +109,7 @@ The following features and functionality are provided by the NERD tree:
< <
:NERDTreeFromBookmark <bookmark> *:NERDTreeFromBookmark* :NERDTreeFromBookmark <bookmark> *:NERDTreeFromBookmark*
Opens a fresh NERD tree with the root initialized to the dir for Opens a fresh NERD tree with the root initialized to the dir for
<bookmark>. This only reason to use this command over :NERDTree is for <bookmark>. The only reason to use this command over :NERDTree is for
the completion (which is for bookmarks rather than directories). the completion (which is for bookmarks rather than directories).
:NERDTreeToggle [<start-directory> | <bookmark>] *:NERDTreeToggle* :NERDTreeToggle [<start-directory> | <bookmark>] *:NERDTreeToggle*
@ -160,7 +160,7 @@ click bookmarks or use the |NERDTree-o| mapping to activate them. See also,
Note that the following commands are only available in the NERD tree buffer. Note that the following commands are only available in the NERD tree buffer.
:Bookmark <name> :Bookmark [<name>]
Bookmark the current node as <name>. If there is already a <name> Bookmark the current node as <name>. If there is already a <name>
bookmark, it is overwritten. <name> must not contain spaces. bookmark, it is overwritten. <name> must not contain spaces.
If <name> is not provided, it defaults to the file or directory name. If <name> is not provided, it defaults to the file or directory name.
@ -358,7 +358,7 @@ Default key: O
Map option: NERDTreeMapOpenRecursively Map option: NERDTreeMapOpenRecursively
Applies to: directories. Applies to: directories.
Recursively opens the selelected directory. Recursively opens the selected directory.
All files and directories are cached, but if a directory would not be All files and directories are cached, but if a directory would not be
displayed due to file filters (see |'NERDTreeIgnore'| |NERDTree-f|) or the displayed due to file filters (see |'NERDTreeIgnore'| |NERDTree-f|) or the
@ -462,8 +462,8 @@ Jump to the previous sibling of the selected node.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*NERDTree-C* *NERDTree-C*
Default key: C Default key: C
Map option: NERDTreeMapChdir Map option: NERDTreeMapChangeRoot
Applies to: directories. Applies to: files and directories.
Make the selected directory node the new tree root. If a file is selected, its Make the selected directory node the new tree root. If a file is selected, its
parent is used. parent is used.
@ -609,17 +609,19 @@ NERD tree. These options should be set in your vimrc.
|'loaded_nerd_tree'| Turns off the script. |'loaded_nerd_tree'| Turns off the script.
|'NERDChristmasTree'| Tells the NERD tree to make itself colourful
and pretty.
|'NERDTreeAutoCenter'| Controls whether the NERD tree window centers |'NERDTreeAutoCenter'| Controls whether the NERD tree window centers
when the cursor moves within a specified when the cursor moves within a specified
distance to the top/bottom of the window. distance to the top/bottom of the window.
|'NERDTreeAutoCenterThreshold'| Controls the sensitivity of autocentering. |'NERDTreeAutoCenterThreshold'| Controls the sensitivity of autocentering.
|'NERDTreeCaseSensitiveSort'| Tells the NERD tree whether to be case |'NERDTreeCaseSensitiveSort'| Tells the NERD tree whether to be case
sensitive or not when sorting nodes. sensitive or not when sorting nodes.
|'NERDTreeSortHiddenFirst'| Tells the NERD tree whether to take the dot
at the beginning of the hidden file names
into account when sorting nodes.
|'NERDTreeChDirMode'| Tells the NERD tree if/when it should change |'NERDTreeChDirMode'| Tells the NERD tree if/when it should change
vim's current working directory. vim's current working directory.
@ -631,8 +633,13 @@ NERD tree. These options should be set in your vimrc.
|'NERDTreeIgnore'| Tells the NERD tree which files to ignore. |'NERDTreeIgnore'| Tells the NERD tree which files to ignore.
|'NERDTreeRespectWildIgnore'| Tells the NERD tree to respect |'wildignore'|.
|'NERDTreeBookmarksFile'| Where the bookmarks are stored. |'NERDTreeBookmarksFile'| Where the bookmarks are stored.
|'NERDTreeBookmarksSort'| Whether the bookmarks list is sorted on
display.
|'NERDTreeMouseMode'| Tells the NERD tree how to handle mouse |'NERDTreeMouseMode'| Tells the NERD tree how to handle mouse
clicks. clicks.
@ -667,8 +674,8 @@ NERD tree. These options should be set in your vimrc.
|'NERDTreeDirArrows'| Tells the NERD tree to use arrows instead of |'NERDTreeDirArrows'| Tells the NERD tree to use arrows instead of
+ ~ chars when displaying directories. + ~ chars when displaying directories.
|'NERDTreeCasadeOpenSingleChildDir'| |'NERDTreeCascadeOpenSingleChildDir'|
Casade open while selected directory has only Cascade open while selected directory has only
one child that also is a directory. one child that also is a directory.
|'NERDTreeAutoDeleteBuffer'| Tells the NERD tree to automatically remove |'NERDTreeAutoDeleteBuffer'| Tells the NERD tree to automatically remove
@ -686,15 +693,6 @@ If this plugin is making you feel homicidal, it may be a good idea to turn it
off with this line in your vimrc: > off with this line in your vimrc: >
let loaded_nerd_tree=1 let loaded_nerd_tree=1
< <
------------------------------------------------------------------------------
*'NERDChristmasTree'*
Values: 0 or 1.
Default: 1.
If this option is set to 1 then some extra syntax highlighting elements are
added to the nerd tree to make it more colourful.
Set it to 0 for a more vanilla looking tree.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*'NERDTreeAutoCenter'* *'NERDTreeAutoCenter'*
@ -817,6 +815,13 @@ line: >
The file filters can be turned on and off dynamically with the |NERDTree-f| The file filters can be turned on and off dynamically with the |NERDTree-f|
mapping. mapping.
------------------------------------------------------------------------------
*'NERDTreeRespectWildIgnore'*
Values: 0 or 1.
Default: 0.
If set to 1, the |'wildignore'| setting is respected.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*'NERDTreeBookmarksFile'* *'NERDTreeBookmarksFile'*
Values: a path Values: a path
@ -824,6 +829,14 @@ Default: $HOME/.NERDTreeBookmarks
This is where bookmarks are saved. See |NERDTreeBookmarkCommands|. This is where bookmarks are saved. See |NERDTreeBookmarkCommands|.
------------------------------------------------------------------------------
*'NERDTreeBookmarksSort'*
Values: 0 or 1
Default: 1
If set to 0 then the bookmarks list is not sorted.
If set to 1 the bookmarks list is sorted.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*'NERDTreeMouseMode'* *'NERDTreeMouseMode'*
Values: 1, 2 or 3. Values: 1, 2 or 3.
@ -987,16 +1000,17 @@ option: >
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*'NERDTreeCasadeOpenSingleChildDir'* *'NERDTreeCascadeOpenSingleChildDir'*
Values: 0 or 1 Values: 0 or 1
Default: 1. Default: 1.
When opening dir nodes, this option tells NERDTree to recursively open dirs When opening dir nodes, this option tells NERDTree to recursively open dirs
that have only one child which is also a dir. NERDTree will stop when it finds that have only one child which is also a dir. NERDTree will stop when it finds
a dir that contains anything but another single dir. This option may be useful a dir that contains anything but another single dir. This option also causes
for Java projects. Use one of the follow lines to set this option: > the |NERDTree-x| mapping to close dirs in the same manner. This option may be
let NERDTreeCasadeOpenSingleChildDir=0 useful for Java projects. Use one of the follow lines to set this option: >
let NERDTreeCasadeOpenSingleChildDir=1 let NERDTreeCascadeOpenSingleChildDir=0
let NERDTreeCascadeOpenSingleChildDir=1
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
@ -1046,6 +1060,9 @@ NERDTreeAddKeyMap({options}) *NERDTreeAddKeyMap()*
"callback" - the function the new mapping will be bound to "callback" - the function the new mapping will be bound to
"quickhelpText" - the text that will appear in the quickhelp (see "quickhelpText" - the text that will appear in the quickhelp (see
|NERDTree-?|) |NERDTree-?|)
"override" - if 1 then this new mapping will override whatever previous
mapping was defined for the key/scope combo. Useful for overriding the
default mappings.
Additionally, a "scope" argument may be supplied. This constrains the Additionally, a "scope" argument may be supplied. This constrains the
mapping so that it is only activated if the cursor is on a certain object. mapping so that it is only activated if the cursor is on a certain object.
@ -1062,8 +1079,8 @@ NERDTreeAddKeyMap({options}) *NERDTreeAddKeyMap()*
call NERDTreeAddKeyMap({ call NERDTreeAddKeyMap({
\ 'key': 'foo', \ 'key': 'foo',
\ 'callback': 'NERDTreeCDHandler', \ 'callback': 'NERDTreeCDHandler',
\ 'quickhelpText': 'echo full path of current node' }) \ 'quickhelpText': 'echo full path of current node',
\ 'scope': 'DirNode' \ 'scope': 'DirNode' })
function! NERDTreeCDHandler(dirnode) function! NERDTreeCDHandler(dirnode)
call a:dirnode.changeToDir() call a:dirnode.changeToDir()

View file

@ -19,7 +19,9 @@ function! s:Bookmark.AddBookmark(name, path)
endif endif
endfor endfor
call add(s:Bookmark.Bookmarks(), s:Bookmark.New(a:name, a:path)) call add(s:Bookmark.Bookmarks(), s:Bookmark.New(a:name, a:path))
call s:Bookmark.Sort() if g:NERDTreeBookmarksSort ==# 1
call s:Bookmark.Sort()
endif
endfunction endfunction
" FUNCTION: Bookmark.Bookmarks() {{{1 " FUNCTION: Bookmark.Bookmarks() {{{1
@ -101,7 +103,9 @@ function! s:Bookmark.CacheBookmarks(silent)
call nerdtree#echo(invalidBookmarksFound . " invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.") call nerdtree#echo(invalidBookmarksFound . " invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.")
endif endif
endif endif
call s:Bookmark.Sort() if g:NERDTreeBookmarksSort ==# 1
call s:Bookmark.Sort()
endif
endif endif
endfunction endfunction
@ -271,7 +275,7 @@ function! s:Bookmark.toRoot()
let targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path) let targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path)
endtry endtry
call targetNode.makeRoot() call targetNode.makeRoot()
call nerdtree#renderView() call b:NERDTree.render()
call targetNode.putCursorHere(0, 0) call targetNode.putCursorHere(0, 0)
endif endif
endfunction endfunction
@ -289,7 +293,7 @@ function! s:Bookmark.validate()
return 1 return 1
else else
call s:Bookmark.CacheBookmarks(1) call s:Bookmark.CacheBookmarks(1)
call nerdtree#renderView() call b:NERDTree.render()
call nerdtree#echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.") call nerdtree#echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.")
return 0 return 0
endif endif

View file

@ -7,18 +7,18 @@ let g:NERDTreeCreator = s:Creator
"FUNCTION: s:Creator._bindMappings() {{{1 "FUNCTION: s:Creator._bindMappings() {{{1
function! s:Creator._bindMappings() function! s:Creator._bindMappings()
"make <cr> do the same as the default 'o' mapping "make <cr> do the same as the activate node mapping
exec "nnoremap <silent> <buffer> <cr> :call nerdtree#invokeKeyMap('". g:NERDTreeMapActivateNode ."')<cr>" nnoremap <silent> <buffer> <cr> :call nerdtree#ui_glue#invokeKeyMap(g:NERDTreeMapActivateNode)<cr>
call g:NERDTreeKeyMap.BindAll() call g:NERDTreeKeyMap.BindAll()
command! -buffer -nargs=? Bookmark :call nerdtree#bookmarkNode('<args>') command! -buffer -nargs=? Bookmark :call nerdtree#ui_glue#bookmarkNode('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#revealBookmark('<args>') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#ui_glue#revealBookmark('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#openBookmark('<args>') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#ui_glue#openBookmark('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#clearBookmarks('<args>') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#ui_glue#clearBookmarks('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=+ BookmarkToRoot call g:NERDTreeBookmark.ToRoot('<args>') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=+ BookmarkToRoot call g:NERDTreeBookmark.ToRoot('<args>')
command! -buffer -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() <bar> call nerdtree#renderView() command! -buffer -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() <bar> call b:NERDTree.render()
command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) <bar> call nerdtree#renderView() command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) <bar> call b:NERDTree.render()
command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write() command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write()
endfunction endfunction
@ -49,26 +49,23 @@ function! s:Creator.createPrimary(name)
call path.changeToDir() call path.changeToDir()
endif endif
if nerdtree#treeExistsForTab() if g:NERDTree.ExistsForTab()
if nerdtree#isTreeOpen() if nerdtree#isTreeOpen()
call nerdtree#closeTree() call nerdtree#closeTree()
endif endif
unlet t:NERDTreeBufName unlet t:NERDTreeBufName
endif endif
let newRoot = g:NERDTreeDirNode.New(path)
call newRoot.open()
call self._createTreeWin() call self._createTreeWin()
call self._createNERDTree(path)
let b:NERDTreeType = "primary"
let b:treeShowHelp = 0 let b:treeShowHelp = 0
let b:NERDTreeIgnoreEnabled = 1 let b:NERDTreeIgnoreEnabled = 1
let b:NERDTreeShowFiles = g:NERDTreeShowFiles let b:NERDTreeShowFiles = g:NERDTreeShowFiles
let b:NERDTreeShowHidden = g:NERDTreeShowHidden let b:NERDTreeShowHidden = g:NERDTreeShowHidden
let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks
let b:NERDTreeRoot = newRoot
let b:NERDTreeType = "primary"
call nerdtree#renderView() call b:NERDTree.render()
call b:NERDTreeRoot.putCursorHere(0, 0) call b:NERDTreeRoot.putCursorHere(0, 0)
call self._broadcastInitEvent() call self._broadcastInitEvent()
@ -99,18 +96,26 @@ function! s:Creator.createSecondary(dir)
exec "silent edit " . self._nextBufferName() exec "silent edit " . self._nextBufferName()
let b:NERDTreePreviousBuf = bufnr(previousBuf) let b:NERDTreePreviousBuf = bufnr(previousBuf)
call self._createNERDTree(path)
let b:NERDTreeRoot = g:NERDTreeDirNode.New(path)
call b:NERDTreeRoot.open()
call self._setCommonBufOptions() call self._setCommonBufOptions()
let b:NERDTreeType = "secondary" let b:NERDTreeType = "secondary"
call nerdtree#renderView() call b:NERDTree.render()
call self._broadcastInitEvent() call self._broadcastInitEvent()
endfunction endfunction
" FUNCTION: s:Creator._createNERDTree(path) {{{1
function! s:Creator._createNERDTree(path)
let b:NERDTree = g:NERDTree.New(a:path)
"TODO: This is kept for compatability only since many things use
"b:NERDTreeRoot instead of the new NERDTree.root
"Remove this one day
let b:NERDTreeRoot = b:NERDTree.root
call b:NERDTree.root.open()
endfunction
" FUNCTION: s:Creator.CreateMirror() {{{1 " FUNCTION: s:Creator.CreateMirror() {{{1
function! s:Creator.CreateMirror() function! s:Creator.CreateMirror()
let creator = s:Creator.New() let creator = s:Creator.New()
@ -122,12 +127,12 @@ function! s:Creator.createMirror()
"get the names off all the nerd tree buffers "get the names off all the nerd tree buffers
let treeBufNames = [] let treeBufNames = []
for i in range(1, tabpagenr("$")) for i in range(1, tabpagenr("$"))
let nextName = nerdtree#tabpagevar(i, 'NERDTreeBufName') let nextName = self._tabpagevar(i, 'NERDTreeBufName')
if nextName != -1 && (!exists("t:NERDTreeBufName") || nextName != t:NERDTreeBufName) if nextName != -1 && (!exists("t:NERDTreeBufName") || nextName != t:NERDTreeBufName)
call add(treeBufNames, nextName) call add(treeBufNames, nextName)
endif endif
endfor endfor
let treeBufNames = nerdtree#unique(treeBufNames) let treeBufNames = self._uniq(treeBufNames)
"map the option names (that the user will be prompted with) to the nerd "map the option names (that the user will be prompted with) to the nerd
"tree buffer names "tree buffer names
@ -158,7 +163,7 @@ function! s:Creator.createMirror()
return return
endif endif
if nerdtree#treeExistsForTab() && nerdtree#isTreeOpen() if g:NERDTree.ExistsForTab() && nerdtree#isTreeOpen()
call nerdtree#closeTree() call nerdtree#closeTree()
endif endif
@ -166,7 +171,7 @@ function! s:Creator.createMirror()
call self._createTreeWin() call self._createTreeWin()
exec 'buffer ' . bufferName exec 'buffer ' . bufferName
if !&hidden if !&hidden
call nerdtree#renderView() call b:NERDTree.render()
endif endif
endfunction endfunction
@ -279,8 +284,8 @@ function! s:Creator._setCommonBufOptions()
let b:NERDTreeShowFiles = g:NERDTreeShowFiles let b:NERDTreeShowFiles = g:NERDTreeShowFiles
let b:NERDTreeShowHidden = g:NERDTreeShowHidden let b:NERDTreeShowHidden = g:NERDTreeShowHidden
let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks
setfiletype nerdtree
call self._bindMappings() call self._bindMappings()
setlocal filetype=nerdtree
endfunction endfunction
"FUNCTION: s:Creator._setupStatusline() {{{1 "FUNCTION: s:Creator._setupStatusline() {{{1
@ -290,6 +295,24 @@ function! s:Creator._setupStatusline()
endif endif
endfunction endfunction
" FUNCTION: s:Creator._tabpagevar(tabnr, var) {{{1
function! s:Creator._tabpagevar(tabnr, var)
let currentTab = tabpagenr()
let old_ei = &ei
set ei=all
exec "tabnext " . a:tabnr
let v = -1
if exists('t:' . a:var)
exec 'let v = t:' . a:var
endif
exec "tabnext " . currentTab
let &ei = old_ei
return v
endfunction
"FUNCTION: s:Creator.TogglePrimary(dir) {{{1 "FUNCTION: s:Creator.TogglePrimary(dir) {{{1
function! s:Creator.TogglePrimary(dir) function! s:Creator.TogglePrimary(dir)
let creator = s:Creator.New() let creator = s:Creator.New()
@ -304,13 +327,13 @@ endfunction
"dir: the full path for the root node (is only used if the NERD tree is being "dir: the full path for the root node (is only used if the NERD tree is being
"initialized. "initialized.
function! s:Creator.togglePrimary(dir) function! s:Creator.togglePrimary(dir)
if nerdtree#treeExistsForTab() if g:NERDTree.ExistsForTab()
if !nerdtree#isTreeOpen() if !nerdtree#isTreeOpen()
call self._createTreeWin() call self._createTreeWin()
if !&hidden if !&hidden
call nerdtree#renderView() call b:NERDTree.render()
endif endif
call nerdtree#restoreScreenState() call b:NERDTree.ui.restoreScreenState()
else else
call nerdtree#closeTree() call nerdtree#closeTree()
endif endif
@ -319,4 +342,16 @@ function! s:Creator.togglePrimary(dir)
endif endif
endfunction endfunction
" Function: s:Creator._uniq(list) {{{1
" returns a:list without duplicates
function! s:Creator._uniq(list)
let uniqlist = []
for elem in a:list
if index(uniqlist, elem) ==# -1
let uniqlist += [elem]
endif
endfor
return uniqlist
endfunction
" vim: set sw=4 sts=4 et fdm=marker: " vim: set sw=4 sts=4 et fdm=marker:

View file

@ -44,7 +44,7 @@ function! s:KeyMap.bind()
let premap = self.key == "<LeftRelease>" ? " <LeftRelease>" : " " let premap = self.key == "<LeftRelease>" ? " <LeftRelease>" : " "
exec 'nnoremap <buffer> <silent> '. self.key . premap . ':call nerdtree#invokeKeyMap("'. keymapInvokeString .'")<cr>' exec 'nnoremap <buffer> <silent> '. self.key . premap . ':call nerdtree#ui_glue#invokeKeyMap("'. keymapInvokeString .'")<cr>'
endfunction endfunction
"FUNCTION: KeyMap.Remove(key, scope) {{{1 "FUNCTION: KeyMap.Remove(key, scope) {{{1
@ -79,6 +79,16 @@ endfunction
"If a keymap has the scope of "all" then it will be called if no other keymap "If a keymap has the scope of "all" then it will be called if no other keymap
"is found for a:key and the scope. "is found for a:key and the scope.
function! s:KeyMap.Invoke(key) function! s:KeyMap.Invoke(key)
"required because clicking the command window below another window still
"invokes the <LeftRelease> mapping - but changes the window cursor
"is in first
"
"TODO: remove this check when the vim bug is fixed
if !g:NERDTree.ExistsForBuf()
return {}
endif
let node = g:NERDTreeFileNode.GetSelected() let node = g:NERDTreeFileNode.GetSelected()
if !empty(node) if !empty(node)
@ -124,8 +134,14 @@ endfunction
"FUNCTION: KeyMap.Create(options) {{{1 "FUNCTION: KeyMap.Create(options) {{{1
function! s:KeyMap.Create(options) function! s:KeyMap.Create(options)
let newKeyMap = copy(self)
let opts = extend({'scope': 'all', 'quickhelpText': ''}, copy(a:options)) let opts = extend({'scope': 'all', 'quickhelpText': ''}, copy(a:options))
"dont override other mappings unless the 'override' option is given
if get(opts, 'override', 0) == 0 && !empty(s:KeyMap.FindFor(opts['key'], opts['scope']))
return
end
let newKeyMap = copy(self)
let newKeyMap.key = opts['key'] let newKeyMap.key = opts['key']
let newKeyMap.quickhelpText = opts['quickhelpText'] let newKeyMap.quickhelpText = opts['quickhelpText']
let newKeyMap.callback = opts['callback'] let newKeyMap.callback = opts['callback']

View file

@ -90,7 +90,7 @@ endfunction
"callback "callback
function! s:MenuItem.execute() function! s:MenuItem.execute()
if len(self.children) if len(self.children)
let mc = s:MenuController.New(self.children) let mc = g:NERDTreeMenuController.New(self.children)
call mc.showMenu() call mc.showMenu()
else else
if self.callback != -1 if self.callback != -1

View file

@ -3,6 +3,29 @@
let s:Opener = {} let s:Opener = {}
let g:NERDTreeOpener = s:Opener let g:NERDTreeOpener = s:Opener
"FUNCTION: s:Opener._bufInWindows(bnum){{{1
"[[STOLEN FROM VTREEEXPLORER.VIM]]
"Determine the number of windows open to this buffer number.
"Care of Yegappan Lakshman. Thanks!
"
"Args:
"bnum: the subject buffers buffer number
function! s:Opener._bufInWindows(bnum)
let cnt = 0
let winnum = 1
while 1
let bufnum = winbufnr(winnum)
if bufnum < 0
break
endif
if bufnum ==# a:bnum
let cnt = cnt + 1
endif
let winnum = winnum + 1
endwhile
return cnt
endfunction
"FUNCTION: Opener._checkToCloseTree(newtab) {{{1 "FUNCTION: Opener._checkToCloseTree(newtab) {{{1
"Check the class options and global options (i.e. NERDTreeQuitOnOpen) to see "Check the class options and global options (i.e. NERDTreeQuitOnOpen) to see
"if the tree should be closed now. "if the tree should be closed now.
@ -21,6 +44,24 @@ function! s:Opener._checkToCloseTree(newtab)
endif endif
endfunction endfunction
"FUNCTION: s:Opener._firstUsableWindow(){{{1
"find the window number of the first normal window
function! s:Opener._firstUsableWindow()
let i = 1
while i <= winnr("$")
let bnum = winbufnr(i)
if bnum != -1 && getbufvar(bnum, '&buftype') ==# ''
\ && !getwinvar(i, '&previewwindow')
\ && (!getbufvar(bnum, '&modified') || &hidden)
return i
endif
let i += 1
endwhile
return -1
endfunction
"FUNCTION: Opener._gotoTargetWin() {{{1 "FUNCTION: Opener._gotoTargetWin() {{{1
function! s:Opener._gotoTargetWin() function! s:Opener._gotoTargetWin()
if b:NERDTreeType ==# "secondary" if b:NERDTreeType ==# "secondary"
@ -48,6 +89,37 @@ function! s:Opener._gotoTargetWin()
endif endif
endfunction endfunction
"FUNCTION: s:Opener._isWindowUsable(winnumber) {{{1
"Returns 0 if opening a file from the tree in the given window requires it to
"be split, 1 otherwise
"
"Args:
"winnumber: the number of the window in question
function! s:Opener._isWindowUsable(winnumber)
"gotta split if theres only one window (i.e. the NERD tree)
if winnr("$") ==# 1
return 0
endif
let oldwinnr = winnr()
call nerdtree#exec(a:winnumber . "wincmd p")
let specialWindow = getbufvar("%", '&buftype') != '' || getwinvar('%', '&previewwindow')
let modified = &modified
call nerdtree#exec(oldwinnr . "wincmd p")
"if its a special window e.g. quickfix or another explorer plugin then we
"have to split
if specialWindow
return 0
endif
if &hidden
return 1
endif
return !modified || self._bufInWindows(winbufnr(a:winnumber)) >= 2
endfunction
"FUNCTION: Opener.New(path, opts) {{{1 "FUNCTION: Opener.New(path, opts) {{{1
"Args: "Args:
" "
@ -190,7 +262,7 @@ function! s:Opener._openDirectory(node)
call self._gotoTargetWin() call self._gotoTargetWin()
if empty(self._where) if empty(self._where)
call a:node.makeRoot() call a:node.makeRoot()
call nerdtree#renderView() call b:NERDTree.render()
call a:node.putCursorHere(0, 0) call a:node.putCursorHere(0, 0)
elseif self._where == 't' elseif self._where == 't'
call g:NERDTreeCreator.CreatePrimary(a:node.path.str()) call g:NERDTreeCreator.CreatePrimary(a:node.path.str())
@ -206,12 +278,12 @@ endfunction
"FUNCTION: Opener._previousWindow() {{{1 "FUNCTION: Opener._previousWindow() {{{1
function! s:Opener._previousWindow() function! s:Opener._previousWindow()
if !nerdtree#isWindowUsable(winnr("#")) && nerdtree#firstUsableWindow() ==# -1 if !self._isWindowUsable(winnr("#")) && self._firstUsableWindow() ==# -1
call self._newSplit() call self._newSplit()
else else
try try
if !nerdtree#isWindowUsable(winnr("#")) if !self._isWindowUsable(winnr("#"))
call nerdtree#exec(nerdtree#firstUsableWindow() . "wincmd w") call nerdtree#exec(self._firstUsableWindow() . "wincmd w")
else else
call nerdtree#exec('wincmd p') call nerdtree#exec('wincmd p')
endif endif

View file

@ -33,8 +33,10 @@ function! s:Path.bookmarkNames()
endfunction endfunction
"FUNCTION: Path.cacheDisplayString() {{{1 "FUNCTION: Path.cacheDisplayString() {{{1
function! s:Path.cacheDisplayString() function! s:Path.cacheDisplayString() abort
let self.cachedDisplayString = self.getLastPathComponent(1) let self.cachedDisplayString = self.flagSet.renderToString()
let self.cachedDisplayString .= self.getLastPathComponent(1)
if self.isExecutable if self.isExecutable
let self.cachedDisplayString = self.cachedDisplayString . '*' let self.cachedDisplayString = self.cachedDisplayString . '*'
@ -103,6 +105,10 @@ function! s:Path.compareTo(path)
elseif thisSS > thatSS elseif thisSS > thatSS
return 1 return 1
else else
if !g:NERDTreeSortHiddenFirst
let thisPath = substitute(thisPath, '^[._]', '', '')
let thatPath = substitute(thatPath, '^[._]', '', '')
endif
"if the sort sequences are the same then compare the paths "if the sort sequences are the same then compare the paths
"alphabetically "alphabetically
let pathCompare = g:NERDTreeCaseSensitiveSort ? thisPath <# thatPath : thisPath <? thatPath let pathCompare = g:NERDTreeCaseSensitiveSort ? thisPath <# thatPath : thisPath <? thatPath
@ -141,6 +147,7 @@ function! s:Path.Create(fullpath)
"assume its a file and create "assume its a file and create
else else
call s:Path.createParentDirectories(a:fullpath)
call writefile([], a:fullpath) call writefile([], a:fullpath)
endif endif
catch catch
@ -161,9 +168,11 @@ function! s:Path.copy(dest)
throw "NERDTree.CopyingNotSupportedError: Copying is not supported on this OS" throw "NERDTree.CopyingNotSupportedError: Copying is not supported on this OS"
endif endif
call s:Path.createParentDirectories(a:dest)
let dest = s:Path.WinToUnixPath(a:dest) let dest = s:Path.WinToUnixPath(a:dest)
let cmd = g:NERDTreeCopyCmd . " " . escape(self.str(), nerdtree#escChars()) . " " . escape(dest, nerdtree#escChars()) let cmd = g:NERDTreeCopyCmd . " " . escape(self.str(), self._escChars()) . " " . escape(dest, self._escChars())
let success = system(cmd) let success = system(cmd)
if success != 0 if success != 0
throw "NERDTree.CopyError: Could not copy ''". self.str() ."'' to: '" . a:dest . "'" throw "NERDTree.CopyError: Could not copy ''". self.str() ."'' to: '" . a:dest . "'"
@ -197,6 +206,20 @@ function! s:Path.copyingWillOverwrite(dest)
endif endif
endfunction endfunction
"FUNCTION: Path.createParentDirectories(path) {{{1
"
"create parent directories for this path if needed
"without throwing any errors is those directories already exist
"
"Args:
"path: full path of the node whose parent directories may need to be created
function! s:Path.createParentDirectories(path)
let dir_path = fnamemodify(a:path, ':h')
if !isdirectory(dir_path)
call mkdir(dir_path, 'p')
endif
endfunction
"FUNCTION: Path.delete() {{{1 "FUNCTION: Path.delete() {{{1
" "
"Deletes the file represented by this path. "Deletes the file represented by this path.
@ -268,6 +291,15 @@ function! s:Path.exists()
return filereadable(p) || isdirectory(p) return filereadable(p) || isdirectory(p)
endfunction endfunction
"FUNCTION: Path._escChars() {{{1
function! s:Path._escChars()
if nerdtree#runningWindows()
return " `\|\"#%&,?()\*^<>"
endif
return " \\`\|\"#%&,?()\*^<>[]"
endfunction
"FUNCTION: Path.getDir() {{{1 "FUNCTION: Path.getDir() {{{1
" "
"Returns this path if it is a directory, else this paths parent. "Returns this path if it is a directory, else this paths parent.
@ -439,6 +471,7 @@ function! s:Path.New(path)
call newPath.readInfoFromDisk(s:Path.AbsolutePathFor(a:path)) call newPath.readInfoFromDisk(s:Path.AbsolutePathFor(a:path))
let newPath.cachedDisplayString = "" let newPath.cachedDisplayString = ""
let newPath.flagSet = g:NERDTreeFlagSet.New()
return newPath return newPath
endfunction endfunction
@ -516,6 +549,13 @@ endfunction
"FUNCTION: Path.refresh() {{{1 "FUNCTION: Path.refresh() {{{1
function! s:Path.refresh() function! s:Path.refresh()
call self.readInfoFromDisk(self.str()) call self.readInfoFromDisk(self.str())
call g:NERDTreePathNotifier.NotifyListeners('refresh', self, {})
call self.cacheDisplayString()
endfunction
"FUNCTION: Path.refreshFlags() {{{1
function! s:Path.refreshFlags()
call g:NERDTreePathNotifier.NotifyListeners('refreshFlags', self, {})
call self.cacheDisplayString() call self.cacheDisplayString()
endfunction endfunction
@ -604,7 +644,7 @@ endfunction
" "
" returns a string that can be used with :cd " returns a string that can be used with :cd
function! s:Path._strForCd() function! s:Path._strForCd()
return escape(self.str(), nerdtree#escChars()) return escape(self.str(), self._escChars())
endfunction endfunction
"FUNCTION: Path._strForEdit() {{{1 "FUNCTION: Path._strForEdit() {{{1
@ -612,7 +652,7 @@ endfunction
"Return: the string for this path that is suitable to be used with the :edit "Return: the string for this path that is suitable to be used with the :edit
"command "command
function! s:Path._strForEdit() function! s:Path._strForEdit()
let p = escape(self.str({'format': 'UI'}), nerdtree#escChars()) let p = escape(self.str({'format': 'UI'}), self._escChars())
let cwd = getcwd() . s:Path.Slash() let cwd = getcwd() . s:Path.Slash()
"return a relative path if we can "return a relative path if we can
@ -652,7 +692,7 @@ function! s:Path._strForGlob()
let toReturn = lead . join(self.pathSegments, s:Path.Slash()) let toReturn = lead . join(self.pathSegments, s:Path.Slash())
if !nerdtree#runningWindows() if !nerdtree#runningWindows()
let toReturn = escape(toReturn, nerdtree#escChars()) let toReturn = escape(toReturn, self._escChars())
endif endif
return toReturn return toReturn
endfunction endfunction

View file

@ -21,7 +21,7 @@ unlet s:TreeDirNode.activate
function! s:TreeDirNode.activate(...) function! s:TreeDirNode.activate(...)
let opts = a:0 ? a:1 : {} let opts = a:0 ? a:1 : {}
call self.toggleOpen(opts) call self.toggleOpen(opts)
call nerdtree#renderView() call b:NERDTree.render()
call self.putCursorHere(0, 0) call self.putCursorHere(0, 0)
endfunction endfunction
@ -229,7 +229,7 @@ function! s:TreeDirNode._initChildren(silent)
let globDir = dir.str({'format': 'Glob'}) let globDir = dir.str({'format': 'Glob'})
if version >= 703 if version >= 703
let filesStr = globpath(globDir, '*', 1) . "\n" . globpath(globDir, '.*', 1) let filesStr = globpath(globDir, '*', !g:NERDTreeRespectWildIgnore) . "\n" . globpath(globDir, '.*', !g:NERDTreeRespectWildIgnore)
else else
let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*') let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*')
endif endif
@ -252,6 +252,7 @@ function! s:TreeDirNode._initChildren(silent)
try try
let path = g:NERDTreePath.New(i) let path = g:NERDTreePath.New(i)
call self.createChild(path, 0) call self.createChild(path, 0)
call g:NERDTreePathNotifier.NotifyListeners('init', path, {})
catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/ catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/
let invalidFilesFound += 1 let invalidFilesFound += 1
endtry endtry
@ -438,6 +439,20 @@ function! s:TreeDirNode.refresh()
endif endif
endfunction endfunction
"FUNCTION: TreeDirNode.refreshFlags() {{{1
unlet s:TreeDirNode.refreshFlags
function! s:TreeDirNode.refreshFlags()
call self.path.refreshFlags()
for i in self.children
call i.refreshFlags()
endfor
endfunction
"FUNCTION: TreeDirNode.refreshDirFlags() {{{1
function! s:TreeDirNode.refreshDirFlags()
call self.path.refreshFlags()
endfunction
"FUNCTION: TreeDirNode.reveal(path) {{{1 "FUNCTION: TreeDirNode.reveal(path) {{{1
"reveal the given path, i.e. cache and open all treenodes needed to display it "reveal the given path, i.e. cache and open all treenodes needed to display it
"in the UI "in the UI
@ -450,7 +465,7 @@ function! s:TreeDirNode.reveal(path)
if self.path.equals(a:path.getParent()) if self.path.equals(a:path.getParent())
let n = self.findNode(a:path) let n = self.findNode(a:path)
call nerdtree#renderView() call b:NERDTree.render()
call n.putCursorHere(1,0) call n.putCursorHere(1,0)
return return
endif endif
@ -500,7 +515,7 @@ function! s:TreeDirNode.toggleOpen(...)
if self.isOpen ==# 1 if self.isOpen ==# 1
call self.close() call self.close()
else else
if g:NERDTreeCasadeOpenSingleChildDir == 0 if g:NERDTreeCascadeOpenSingleChildDir == 0
call self.open(opts) call self.open(opts)
else else
call self.openAlong(opts) call self.openAlong(opts)

View file

@ -178,79 +178,20 @@ function! s:TreeFileNode.findSibling(direction)
return {} return {}
endfunction endfunction
"FUNCTION: TreeFileNode.getLineNum(){{{1
"returns the line number this node is rendered on, or -1 if it isnt rendered
function! s:TreeFileNode.getLineNum()
"if the node is the root then return the root line no.
if self.isRoot()
return s:TreeFileNode.GetRootLineNum()
endif
let totalLines = line("$")
"the path components we have matched so far
let pathcomponents = [substitute(b:NERDTreeRoot.path.str({'format': 'UI'}), '/ *$', '', '')]
"the index of the component we are searching for
let curPathComponent = 1
let fullpath = self.path.str({'format': 'UI'})
let lnum = s:TreeFileNode.GetRootLineNum()
while lnum > 0
let lnum = lnum + 1
"have we reached the bottom of the tree?
if lnum ==# totalLines+1
return -1
endif
let curLine = getline(lnum)
let indent = nerdtree#indentLevelFor(curLine)
if indent ==# curPathComponent
let curLine = nerdtree#stripMarkupFromLine(curLine, 1)
let curPath = join(pathcomponents, '/') . '/' . curLine
if stridx(fullpath, curPath, 0) ==# 0
if fullpath ==# curPath || strpart(fullpath, len(curPath)-1,1) ==# '/'
let curLine = substitute(curLine, '/ *$', '', '')
call add(pathcomponents, curLine)
let curPathComponent = curPathComponent + 1
if fullpath ==# curPath
return lnum
endif
endif
endif
endif
endwhile
return -1
endfunction
"FUNCTION: TreeFileNode.GetRootForTab(){{{1 "FUNCTION: TreeFileNode.GetRootForTab(){{{1
"get the root node for this tab "get the root node for this tab
function! s:TreeFileNode.GetRootForTab() function! s:TreeFileNode.GetRootForTab()
if nerdtree#treeExistsForTab() if g:NERDTree.ExistsForTab()
return getbufvar(t:NERDTreeBufName, 'NERDTreeRoot') return getbufvar(t:NERDTreeBufName, 'NERDTreeRoot')
end end
return {} return {}
endfunction endfunction
"FUNCTION: TreeFileNode.GetRootLineNum(){{{1
"gets the line number of the root node
function! s:TreeFileNode.GetRootLineNum()
let rootLine = 1
while getline(rootLine) !~# '^\(/\|<\)'
let rootLine = rootLine + 1
endwhile
return rootLine
endfunction
"FUNCTION: TreeFileNode.GetSelected() {{{1 "FUNCTION: TreeFileNode.GetSelected() {{{1
"gets the treenode that the cursor is currently over "gets the treenode that the cursor is currently over
function! s:TreeFileNode.GetSelected() function! s:TreeFileNode.GetSelected()
try try
let path = nerdtree#getPath(line(".")) let path = b:NERDTree.ui.getPath(line("."))
if path ==# {} if path ==# {}
return {} return {}
endif endif
@ -270,7 +211,7 @@ endfunction
"FUNCTION: TreeFileNode.isRoot() {{{1 "FUNCTION: TreeFileNode.isRoot() {{{1
"returns 1 if this node is b:NERDTreeRoot "returns 1 if this node is b:NERDTreeRoot
function! s:TreeFileNode.isRoot() function! s:TreeFileNode.isRoot()
if !nerdtree#treeExistsForBuf() if !g:NERDTree.ExistsForBuf()
throw "NERDTree.NoTreeError: No tree exists for the current buffer" throw "NERDTree.NoTreeError: No tree exists for the current buffer"
endif endif
@ -348,7 +289,7 @@ endfunction
"recurseUpward: try to put the cursor on the parent if the this node isnt "recurseUpward: try to put the cursor on the parent if the this node isnt
"visible "visible
function! s:TreeFileNode.putCursorHere(isJump, recurseUpward) function! s:TreeFileNode.putCursorHere(isJump, recurseUpward)
let ln = self.getLineNum() let ln = b:NERDTree.ui.getLineNum(self)
if ln != -1 if ln != -1
if a:isJump if a:isJump
mark ' mark '
@ -357,11 +298,11 @@ function! s:TreeFileNode.putCursorHere(isJump, recurseUpward)
else else
if a:recurseUpward if a:recurseUpward
let node = self let node = self
while node != {} && node.getLineNum() ==# -1 while node != {} && b:NERDTree.ui.getLineNum(node) ==# -1
let node = node.parent let node = node.parent
call node.open() call node.open()
endwhile endwhile
call nerdtree#renderView() call b:NERDTree.render()
call node.putCursorHere(a:isJump, 0) call node.putCursorHere(a:isJump, 0)
endif endif
endif endif
@ -372,6 +313,11 @@ function! s:TreeFileNode.refresh()
call self.path.refresh() call self.path.refresh()
endfunction endfunction
"FUNCTION: TreeFileNode.refreshFlags() {{{1
function! s:TreeFileNode.refreshFlags()
call self.path.refreshFlags()
endfunction
"FUNCTION: TreeFileNode.rename() {{{1 "FUNCTION: TreeFileNode.rename() {{{1
"Calls the rename method for this nodes path obj "Calls the rename method for this nodes path obj
function! s:TreeFileNode.rename(newName) function! s:TreeFileNode.rename(newName)

View file

@ -82,13 +82,14 @@ endfunction
function! s:promptToRenameBuffer(bufnum, msg, newFileName) function! s:promptToRenameBuffer(bufnum, msg, newFileName)
echo a:msg echo a:msg
if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y' if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y'
let quotedFileName = "'" . a:newFileName . "'"
" 1. ensure that a new buffer is loaded " 1. ensure that a new buffer is loaded
exec "badd " . a:newFileName exec "badd " . quotedFileName
" 2. ensure that all windows which display the just deleted filename " 2. ensure that all windows which display the just deleted filename
" display a buffer for a new filename. " display a buffer for a new filename.
let s:originalTabNumber = tabpagenr() let s:originalTabNumber = tabpagenr()
let s:originalWindowNumber = winnr() let s:originalWindowNumber = winnr()
exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':e! " . a:newFileName . "' | endif" exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec \":e! " . quotedFileName . "\" | endif"
exec "tabnext " . s:originalTabNumber exec "tabnext " . s:originalTabNumber
exec s:originalWindowNumber . "wincmd w" exec s:originalWindowNumber . "wincmd w"
" 3. We don't need a previous buffer anymore " 3. We don't need a previous buffer anymore
@ -114,7 +115,10 @@ function! NERDTreeAddNode()
let parentNode = b:NERDTreeRoot.findNode(newPath.getParent()) let parentNode = b:NERDTreeRoot.findNode(newPath.getParent())
let newTreeNode = g:NERDTreeFileNode.New(newPath) let newTreeNode = g:NERDTreeFileNode.New(newPath)
if parentNode.isOpen || !empty(parentNode.children) if empty(parentNode)
call b:NERDTreeRoot.refresh()
call b:NERDTree.render()
elseif parentNode.isOpen || !empty(parentNode.children)
call parentNode.addChild(newTreeNode, 1) call parentNode.addChild(newTreeNode, 1)
call NERDTreeRender() call NERDTreeRender()
call newTreeNode.putCursorHere(1, 0) call newTreeNode.putCursorHere(1, 0)
@ -138,7 +142,7 @@ function! NERDTreeMoveNode()
endif endif
try try
let bufnum = bufnr(curNode.path.str()) let bufnum = bufnr("^".curNode.path.str()."$")
call curNode.rename(newNodePath) call curNode.rename(newNodePath)
call NERDTreeRender() call NERDTreeRender()
@ -186,7 +190,7 @@ function! NERDTreeDeleteNode()
"if the node is open in a buffer, ask the user if they want to "if the node is open in a buffer, ask the user if they want to
"close that buffer "close that buffer
let bufnum = bufnr(currentNode.path.str()) let bufnum = bufnr("^".currentNode.path.str()."$")
if buflisted(bufnum) if buflisted(bufnum)
let prompt = "\nNode deleted.\n\nThe file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Delete this buffer? (yN)" let prompt = "\nNode deleted.\n\nThe file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Delete this buffer? (yN)"
call s:promptToDelBuffer(bufnum, prompt) call s:promptToDelBuffer(bufnum, prompt)
@ -224,7 +228,10 @@ function! NERDTreeCopyNode()
if confirmed if confirmed
try try
let newNode = currentNode.copy(newNodePath) let newNode = currentNode.copy(newNodePath)
if !empty(newNode) if empty(newNode)
call b:NERDTreeRoot.refresh()
call b:NERDTree.render()
else
call NERDTreeRender() call NERDTreeRender()
call newNode.putCursorHere(0, 0) call newNode.putCursorHere(0, 0)
endif endif

View file

@ -45,28 +45,30 @@ function! s:initVariable(var, value)
endfunction endfunction
"SECTION: Init variable calls and other random constants {{{2 "SECTION: Init variable calls and other random constants {{{2
call s:initVariable("g:NERDChristmasTree", 1)
call s:initVariable("g:NERDTreeAutoCenter", 1) call s:initVariable("g:NERDTreeAutoCenter", 1)
call s:initVariable("g:NERDTreeAutoCenterThreshold", 3) call s:initVariable("g:NERDTreeAutoCenterThreshold", 3)
call s:initVariable("g:NERDTreeCaseSensitiveSort", 0) call s:initVariable("g:NERDTreeCaseSensitiveSort", 0)
call s:initVariable("g:NERDTreeSortHiddenFirst", 1)
call s:initVariable("g:NERDTreeChDirMode", 0) call s:initVariable("g:NERDTreeChDirMode", 0)
call s:initVariable("g:NERDTreeMinimalUI", 0) call s:initVariable("g:NERDTreeMinimalUI", 0)
if !exists("g:NERDTreeIgnore") if !exists("g:NERDTreeIgnore")
let g:NERDTreeIgnore = ['\~$'] let g:NERDTreeIgnore = ['\~$']
endif endif
call s:initVariable("g:NERDTreeBookmarksFile", expand('$HOME') . '/.NERDTreeBookmarks') call s:initVariable("g:NERDTreeBookmarksFile", expand('$HOME') . '/.NERDTreeBookmarks')
call s:initVariable("g:NERDTreeBookmarksSort", 1)
call s:initVariable("g:NERDTreeHighlightCursorline", 1) call s:initVariable("g:NERDTreeHighlightCursorline", 1)
call s:initVariable("g:NERDTreeHijackNetrw", 1) call s:initVariable("g:NERDTreeHijackNetrw", 1)
call s:initVariable("g:NERDTreeMouseMode", 1) call s:initVariable("g:NERDTreeMouseMode", 1)
call s:initVariable("g:NERDTreeNotificationThreshold", 100) call s:initVariable("g:NERDTreeNotificationThreshold", 100)
call s:initVariable("g:NERDTreeQuitOnOpen", 0) call s:initVariable("g:NERDTreeQuitOnOpen", 0)
call s:initVariable("g:NERDTreeRespectWildIgnore", 0)
call s:initVariable("g:NERDTreeShowBookmarks", 0) call s:initVariable("g:NERDTreeShowBookmarks", 0)
call s:initVariable("g:NERDTreeShowFiles", 1) call s:initVariable("g:NERDTreeShowFiles", 1)
call s:initVariable("g:NERDTreeShowHidden", 0) call s:initVariable("g:NERDTreeShowHidden", 0)
call s:initVariable("g:NERDTreeShowLineNumbers", 0) call s:initVariable("g:NERDTreeShowLineNumbers", 0)
call s:initVariable("g:NERDTreeSortDirs", 1) call s:initVariable("g:NERDTreeSortDirs", 1)
call s:initVariable("g:NERDTreeDirArrows", !nerdtree#runningWindows()) call s:initVariable("g:NERDTreeDirArrows", !nerdtree#runningWindows())
call s:initVariable("g:NERDTreeCasadeOpenSingleChildDir", 1) call s:initVariable("g:NERDTreeCascadeOpenSingleChildDir", 1)
if !exists("g:NERDTreeSortOrder") if !exists("g:NERDTreeSortOrder")
let g:NERDTreeSortOrder = ['\/$', '*', '\.swp$', '\.bak$', '\~$'] let g:NERDTreeSortOrder = ['\/$', '*', '\.swp$', '\.bak$', '\~$']
@ -140,20 +142,13 @@ call nerdtree#loadClassFiles()
" SECTION: Commands {{{1 " SECTION: Commands {{{1
"============================================================ "============================================================
"init the command that users start the nerd tree with call nerdtree#ui_glue#setupCommands()
command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreatePrimary('<args>')
command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.TogglePrimary('<args>')
command! -n=0 -bar NERDTreeClose :call nerdtree#closeTreeIfOpen()
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 NERDTreeFind call nerdtree#findAndRevealPath()
command! -n=0 -bar NERDTreeFocus call NERDTreeFocus()
command! -n=0 -bar NERDTreeCWD call NERDTreeCWD()
" SECTION: Auto commands {{{1 " SECTION: Auto commands {{{1
"============================================================ "============================================================
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 BufWinLeave ". g:NERDTreeCreator.BufNamePrefix() ."* call nerdtree#saveScreenState()" exec "autocmd BufLeave ". g:NERDTreeCreator.BufNamePrefix() ."* call b:NERDTree.ui.saveScreenState()"
"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"
@ -199,7 +194,7 @@ endfunction
function! NERDTreeCWD() function! NERDTreeCWD()
call NERDTreeFocus() call NERDTreeFocus()
call nerdtree#chRootCwd() call nerdtree#ui_glue#chRootCwd()
endfunction endfunction
" SECTION: Post Source Actions {{{1 " SECTION: Post Source Actions {{{1
call nerdtree#postSourceActions() call nerdtree#postSourceActions()

View file

@ -1,44 +1,64 @@
let s:tree_up_dir_line = '.. (up a dir)' let s:tree_up_dir_line = '.. (up a dir)'
"NERDTreeFlags are syntax items that should be invisible, but give clues as to syn match NERDTreeIgnore #\~#
"how things should be highlighted syn match NERDTreeIgnore #\[RO\]#
syn match NERDTreeFlag #\~#
syn match NERDTreeFlag #\[RO\]#
"highlighting for the .. (up dir) line at the top of the tree "highlighting for the .. (up dir) line at the top of the tree
execute "syn match NERDTreeUp #\\V". s:tree_up_dir_line ."#" execute "syn match NERDTreeUp #\\V". s:tree_up_dir_line ."#"
"highlighting for the ~/+ symbols for the directory nodes
syn match NERDTreeClosable #\~\<#
syn match NERDTreeClosable #\~\.#
syn match NERDTreeOpenable #+\<#
syn match NERDTreeOpenable #+\.#he=e-1
"highlighting for the tree structural parts
syn match NERDTreePart #|#
syn match NERDTreePart #`#
syn match NERDTreePartFile #[|`]-#hs=s+1 contains=NERDTreePart
"quickhelp syntax elements "quickhelp syntax elements
syn match NERDTreeHelpKey #" \{1,2\}[^ ]*:#hs=s+2,he=e-1 syn match NERDTreeHelpKey #" \{1,2\}[^ ]*:#ms=s+2,me=e-1
syn match NERDTreeHelpKey #" \{1,2\}[^ ]*,#hs=s+2,he=e-1 syn match NERDTreeHelpKey #" \{1,2\}[^ ]*,#ms=s+2,me=e-1
syn match NERDTreeHelpTitle #" .*\~#hs=s+2,he=e-1 contains=NERDTreeFlag syn match NERDTreeHelpTitle #" .*\~#ms=s+2,me=e-1
syn match NERDTreeToggleOn #".*(on)#hs=e-2,he=e-1 contains=NERDTreeHelpKey syn match NERDTreeToggleOn #(on)#ms=s+1,he=e-1
syn match NERDTreeToggleOff #".*(off)#hs=e-3,he=e-1 contains=NERDTreeHelpKey syn match NERDTreeToggleOff #(off)#ms=e-3,me=e-1
syn match NERDTreeHelpCommand #" :.\{-}\>#hs=s+3 syn match NERDTreeHelpCommand #" :.\{-}\>#hs=s+3
syn match NERDTreeHelp #^".*# contains=NERDTreeHelpKey,NERDTreeHelpTitle,NERDTreeFlag,NERDTreeToggleOff,NERDTreeToggleOn,NERDTreeHelpCommand syn match NERDTreeHelp #^".*# contains=NERDTreeHelpKey,NERDTreeHelpTitle,NERDTreeIgnore,NERDTreeToggleOff,NERDTreeToggleOn,NERDTreeHelpCommand
"highlighting for readonly files
syn match NERDTreeRO #.*\[RO\]#hs=s+2 contains=NERDTreeFlag,NERDTreeBookmark,NERDTreePart,NERDTreePartFile
"highlighting for sym links "highlighting for sym links
syn match NERDTreeLink #[^-| `].* -> # contains=NERDTreeBookmark,NERDTreeOpenable,NERDTreeClosable,NERDTreeDirSlash syn match NERDTreeLinkTarget #->.*# containedin=NERDTreeDir,NERDTreeFile
syn match NERDTreeLinkFile #.* ->#me=e-3 containedin=NERDTreeFile
syn match NERDTreeLinkDir #.*/ ->#me=e-3 containedin=NERDTreeDir
"highlighing for directory nodes and file nodes "highlighing for directory nodes and file nodes
syn match NERDTreeDirSlash #/# syn match NERDTreeDirSlash #/# containedin=NERDTreeDir
syn match NERDTreeDir #[^-| `].*/# contains=NERDTreeLink,NERDTreeDirSlash,NERDTreeOpenable,NERDTreeClosable
syn match NERDTreeExecFile #[|` ].*\*\($\| \)# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark if g:NERDTreeDirArrows
syn match NERDTreeFile #|-.*# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile syn match NERDTreeClosable #▾# containedin=NERDTreeDir,NERDTreeFile
syn match NERDTreeFile #`-.*# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile syn match NERDTreeOpenable #▸# containedin=NERDTreeDir,NERDTreeFile
syn match NERDTreeDir #[^▾▸ ].*/#
syn match NERDTreeExecFile #^ .*\*\($\| \)# contains=NERDTreeRO,NERDTreeBookmark
syn match NERDTreeFile #^[^"\.▾▸] *[^▾▸]*# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmark,NERDTreeExecFile
"highlighting for readonly files
syn match NERDTreeRO # *\zs.*\ze \[RO\]# contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreeFile
syn match NERDTreeFlags #^ *\zs\[.\]# containedin=NERDTreeFile
syn match NERDTreeFlags #\[.\]# containedin=NERDTreeDir
else
"highlighting for the ~/+ symbols for the directory nodes
syn match NERDTreeClosable #\~\<#
syn match NERDTreeClosable #\~\.#
syn match NERDTreeOpenable #+\<#
syn match NERDTreeOpenable #+\.#he=e-1
"highlighting for the tree structural parts
syn match NERDTreePart #|#
syn match NERDTreePart #`#
syn match NERDTreePartFile #[|`]-#hs=s+1 contains=NERDTreePart
syn match NERDTreeDir #[^-| `].*/# contains=NERDTreeLink,NERDTreeOpenable,NERDTreeClosable
syn match NERDTreeExecFile #[|` ].*\*\($\| \)# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark
syn match NERDTreeFile #|-.*# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile
syn match NERDTreeFile #`-.*# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile
"highlighting for readonly files
syn match NERDTreeRO #|-.*\[RO\]#he=e-5 contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreePart,NERDTreePartFile
syn match NERDTreeFlags #-\[.\]# containedin=NERDTreeFile,NERDTreePartFile
syn match NERDTreeFlags #[+~]\zs\[.\]# containedin=NERDTreeDir
endif
syn match NERDTreeCWD #^[</].*$# syn match NERDTreeCWD #^[</].*$#
"highlighting for bookmarks "highlighting for bookmarks
@ -50,19 +70,10 @@ syn match NERDTreeBookmarksHeader #^>-\+Bookmarks-\+$# contains=NERDTreeBookmark
syn match NERDTreeBookmarkName #^>.\{-} #he=e-1 contains=NERDTreeBookmarksLeader syn match NERDTreeBookmarkName #^>.\{-} #he=e-1 contains=NERDTreeBookmarksLeader
syn match NERDTreeBookmark #^>.*$# contains=NERDTreeBookmarksLeader,NERDTreeBookmarkName,NERDTreeBookmarksHeader syn match NERDTreeBookmark #^>.*$# contains=NERDTreeBookmarksLeader,NERDTreeBookmarkName,NERDTreeBookmarksHeader
if exists("g:NERDChristmasTree") && g:NERDChristmasTree hi def link NERDTreePart Special
hi def link NERDTreePart Special hi def link NERDTreePartFile Type
hi def link NERDTreePartFile Type hi def link NERDTreeExecFile Title
hi def link NERDTreeFile Normal hi def link NERDTreeDirSlash Identifier
hi def link NERDTreeExecFile Title
hi def link NERDTreeDirSlash Identifier
hi def link NERDTreeClosable Type
else
hi def link NERDTreePart Normal
hi def link NERDTreePartFile Normal
hi def link NERDTreeFile Normal
hi def link NERDTreeClosable Title
endif
hi def link NERDTreeBookmarksHeader statement hi def link NERDTreeBookmarksHeader statement
hi def link NERDTreeBookmarksLeader ignore hi def link NERDTreeBookmarksLeader ignore
@ -76,13 +87,19 @@ hi def link NERDTreeHelpTitle Macro
hi def link NERDTreeToggleOn Question hi def link NERDTreeToggleOn Question
hi def link NERDTreeToggleOff WarningMsg hi def link NERDTreeToggleOff WarningMsg
hi def link NERDTreeLinkTarget Type
hi def link NERDTreeLinkFile Macro
hi def link NERDTreeLinkDir Macro
hi def link NERDTreeDir Directory hi def link NERDTreeDir Directory
hi def link NERDTreeUp Directory hi def link NERDTreeUp Directory
hi def link NERDTreeFile Normal
hi def link NERDTreeCWD Statement hi def link NERDTreeCWD Statement
hi def link NERDTreeLink Macro
hi def link NERDTreeOpenable Title hi def link NERDTreeOpenable Title
hi def link NERDTreeFlag ignore hi def link NERDTreeClosable Title
hi def link NERDTreeIgnore ignore
hi def link NERDTreeRO WarningMsg hi def link NERDTreeRO WarningMsg
hi def link NERDTreeBookmark Statement hi def link NERDTreeBookmark Statement
hi def link NERDTreeFlags Number
hi def link NERDTreeCurrentNode Search hi def link NERDTreeCurrentNode Search

View file

@ -1,49 +1,105 @@
# Bug reports / Github issues # CONTRIBUTING
- - -
1\. [Bug reports / GitHub issues](#bugreps)
2\. [Submitting a patch](#patches)
3\. [General style notes](#generalstyle)
4\. [Syntax checker notes](#checkerstyle)
- - -
When reporting a bug make sure you search the existing github issues for the <a name="bugreps"></a>
same/similar issues. If you find one, feel free to add a `+1` comment with any
additional information that may help us solve the issue. ## 1. Bug reports / GitHub issues
Please note that the preferred channel for posting bug reports is the
[issue tracker at GitHub][0]. Reports posted elsewhere are less likely
to be seen by the core team.
When reporting a bug make sure you search the existing GitHub issues
for the same/similar issues. If you find one, feel free to add a `+1`
comment with any additional information that may help us solve the
issue.
When creating a new issue be sure to state the following: When creating a new issue be sure to state the following:
* Steps to reproduce the bug. * steps to reproduce the bug;
* The version of vim you are using. * the version of Vim you are using (run `:ver` to find out);
* The version of syntastic you are using. * the version of syntastic you are using (see `:SyntasticInfo`).
For syntax checker bugs also state the version of the checker executable that you are using. For syntax checker bugs also state the version of the checker executable
that you are using. Adding debugging information is typically useful
too:
# Submitting a patch * open a file handled by your checker;
* set `g:syntastic_debug` to 1 or 3;
* run the checker;
* copy the output of `:mes`.
* Fork the repo on github <a name="patches"></a>
* Make a [topic branch](https://github.com/dchelimsky/rspec/wiki/Topic-Branches#using-topic-branches-when-contributing-patches) and start hacking
* Submit a pull request based off your topic branch
Small focused patches are preferred. ## 2. Submitting a patch
Large changes to the code should be discussed with the core team first. Create an issue and explain your plan and see what we say. Before you consider adding features to syntastic, _please_ spend a few
minutes (re-)reading the latest version of the [manual][1]. Syntastic
is changing rapidly at times, and it's quite possible that some of the
features you want to add exist already.
# General style notes To submit a patch:
Following the coding conventions/styles used in the syntastic core: * fork the [repo][2] on GitHub;
* make a [topic branch][3] and start hacking;
* submit a pull request based off your topic branch.
* Use 4 space indents. Small, focused patches are preferred.
* Don't use abbreviated keywords - e.g. use `endfunction`, not `endfun` (there's always room for more fun!).
* Don't use `l:` prefixes for variables unless actually required (i.e. almost never).
* Code for maintainability. We would rather a function be a couple of lines longer and have (for example) some [explaining variables](http://www.refactoring.com/catalog/introduceExplainingVariable.html) to aid readability.
# Syntax checker style notes Large changes to the code should be discussed with the core team first.
Create an issue and explain your plan and see what we say.
The preferred style for error format strings is one "clause" per line. E.g. Also make sure to update the manual whenever applicable. Nobody can use
(from the coffeelint checker): features that aren't documented.
```viml <a name="generalstyle"></a>
let errorformat = '%E%f:%l:%c: %trror: %m,' .
\ 'Syntax%trror: In %f\, %m on line %l,' . ## 3. General style notes
\ '%EError: In %f\, Parse error on line %l: %m,' .
\ '%EError: In %f\, %m on line %l,' . Follow the coding conventions/styles used in the syntastic core:
\ '%W%f(%l): lint warning: %m,' .
\ '%W%f(%l): warning: %m,' . * use 4 space indents;
\ '%E%f(%l): SyntaxError: %m,' . * don't use abbreviated keywords - e.g. use `endfunction`, not `endfun`
\ '%-Z%p^,' . (there's always room for more fun!);
\ '%-G%.%#' * don't use `l:` prefixes for variables unless actually required (i.e.
almost never);
* code for maintainability; we would rather a function be a couple of
lines longer and have (for example) some [explaining variables][4] to
aid readability.
<a name="checkerstyle"></a>
## 4. Syntax checker notes
Make sure to read the [guide][5] if you plan to add new syntax checkers.
Use the existing checkers as templates, rather than writing everything
from scratch.
The preferred style for error format strings is one "clause" per line.
E.g. (from the `coffee` checker):
```vim
let errorformat =
\ '%E%f:%l:%c: %trror: %m,' .
\ 'Syntax%trror: In %f\, %m on line %l,' .
\ '%EError: In %f\, Parse error on line %l: %m,' .
\ '%EError: In %f\, %m on line %l,' .
\ '%W%f(%l): lint warning: %m,' .
\ '%W%f(%l): warning: %m,' .
\ '%E%f(%l): SyntaxError: %m,' .
\ '%-Z%p^,' .
\ '%-G%.%#'
``` ```
[0]: https://github.com/scrooloose/syntastic/issues
[1]: https://github.com/scrooloose/syntastic/blob/master/doc/syntastic.txt
[2]: https://github.com/scrooloose/syntastic
[3]: https://github.com/dchelimsky/rspec/wiki/Topic-Branches#using-topic-branches-when-contributing-patches
[4]: http://www.refactoring.com/catalog/extractVariable.html
[5]: https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide

View file

@ -35,15 +35,17 @@ the user is notified and is happy because they didn't have to compile their
code or execute their script to find them. code or execute their script to find them.
At the time of this writing, syntax checking plugins exist for ActionScript, At the time of this writing, syntax checking plugins exist for ActionScript,
Ada, AppleScript, AsciiDoc, ASM, BEMHTML, Bourne shell, C, C++, C#, Chef, Ada, AppleScript, Arduino, AsciiDoc, ASM, BEMHTML, Bro, Bourne shell, C,
CoffeeScript, Coco, Coq, CSS, Cucumber, CUDA, D, Dart, DocBook, Dust, Elixir, C++, C#, Cabal, Chef, CoffeeScript, Coco, Coq, CSS, Cucumber, CUDA, D, Dart,
Erlang, eRuby, Fortran, Gentoo metadata, GLSL, Go, Haml, Haskell, Haxe, DocBook, Dust, Elixir, Erlang, eRuby, Fortran, Gentoo metadata, GLSL, Go,
Handlebars, HSS, HTML, Java, JavaScript, JSON, JSX, LESS, Lex, Limbo, LISP, Haml, Haskell, Haxe, Handlebars, HSS, HTML, Java, JavaScript, JSON, JSX, LESS,
LLVM intermediate language, Lua, MATLAB, NASM, Objective-C, Objective-C++, Lex, Limbo, LISP, LLVM intermediate language, Lua, MATLAB, NASM, Objective-C,
OCaml, Perl, Perl POD, PHP, gettext Portable Object, Puppet, Python, Racket, Objective-C++, OCaml, Perl, Perl POD, PHP, gettext Portable Object, OS X and
reStructuredText, Ruby, Rust, SASS/SCSS, Scala, Slim, Tcl, TeX, Texinfo, Twig, iOS property lists, Puppet, Python, Racket, R, reStructuredText, RPM spec,
TypeScript, Vala, Verilog, VHDL, VimL, xHtml, XML, XSLT, YACC, YAML, z80, Zope Ruby, SASS/SCSS, Scala, Slim, Tcl, TeX, Texinfo, Twig, TypeScript, Vala,
page templates, and zsh. Verilog, VHDL, VimL, xHtml, XML, XSLT, YACC, YAML, z80, Zope page templates,
and zsh. See the [wiki][3] for details about the corresponding supported
checkers.
Below is a screenshot showing the methods that Syntastic uses to display syntax 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
@ -75,9 +77,8 @@ First I'll show you how to install Tim Pope's [pathogen][1] so that it's easy to
install syntastic. Do this in your terminal so that you get the `pathogen.vim` install syntastic. Do this in your terminal so that you get the `pathogen.vim`
file and the directories it needs: file and the directories it needs:
```sh ```sh
mkdir -p ~/.vim/autoload ~/.vim/bundle; \ mkdir -p ~/.vim/autoload ~/.vim/bundle && \
curl -so ~/.vim/autoload/pathogen.vim \ curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim
https://raw.github.com/tpope/vim-pathogen/master/autoload/pathogen.vim
``` ```
Next you *need* to add this to your `~/.vimrc`: Next you *need* to add this to your `~/.vimrc`:
```vim ```vim
@ -91,7 +92,7 @@ execute pathogen#infect()
You now have pathogen installed and can put syntastic into `~/.vim/bundle` like You now have pathogen installed and can put syntastic into `~/.vim/bundle` like
this: this:
```sh ```sh
cd ~/.vim/bundle cd ~/.vim/bundle && \
git clone https://github.com/scrooloose/syntastic.git git clone https://github.com/scrooloose/syntastic.git
``` ```
Quit vim and start it back up to reload it, then type: Quit vim and start it back up to reload it, then type:
@ -111,6 +112,8 @@ If you get an error when you do this, then you probably didn't install
## 3\. FAQ ## 3\. FAQ
<a name="faqinfo"></a>
__Q. I installed syntastic but it isn't reporting any errors...__ __Q. I installed syntastic but it isn't reporting any errors...__
A. The most likely reason is that none of the syntax checkers that it requires A. The most likely reason is that none of the syntax checkers that it requires
@ -125,6 +128,18 @@ error output for a syntax checker may have changed. In this case, make sure you
have the latest version of the syntax checker installed. If it still fails then have the latest version of the syntax checker installed. If it still fails then
create an issue - or better yet, create a pull request. create an issue - or better yet, create a pull request.
<a name="faqpython3"></a>
__Q. The `python` checker complains about syntactically valid Python 3 constructs...__
A. Configure the `python` checker to call a Python 3 interpreter rather than
Python 2, e.g:
```vim
let g:syntastic_python_python_exec = '/path/to/python3'
```
<a name="faqperl"></a>
__Q. The `perl` checker has stopped working...__ __Q. The `perl` checker has stopped working...__
A. The `perl` checker runs `perl -c` against your file, which in turn A. The `perl` checker runs `perl -c` against your file, which in turn
@ -133,12 +148,24 @@ statements in your file (cf. [perlrun][10]). This is probably fine if you
wrote the file yourself, but it's a security problem if you're checking third wrote the file yourself, but it's a security problem if you're checking third
party files. Since there is currently no way to disable this behaviour while party files. Since there is currently no way to disable this behaviour while
still producing useful results, the checker is now disabled by default. To still producing useful results, the checker is now disabled by default. To
(re-)enable it, set `g:syntastic_enable_perl_checker` to 1 in your vimrc: (re-)enable it, make sure the `g:syntastic_perl_checkers` list includes `perl`,
and set `g:syntastic_enable_perl_checker` to 1 in your vimrc:
```vim ```vim
let g:syntastic_enable_perl_checker = 1 let g:syntastic_enable_perl_checker = 1
``` ```
__Q. I run a checker and the location list is not updated...__ <a name="faqrust"></a>
__Q. What happened to the `rustc` checker?__
A. It has been included in the [Rust compiler package][12]. If you have
a recent version of the Rust compiler, the checker should be picked up
automatically by syntastic.
<a name="faqloclist"></a>
__Q. I run a checker and the location list is not updated...__
__Q. I run`:lopen` or `:lwindow` and the error window is empty...__
A. By default the location list is changed only when you run the `:Errors` A. By default the location list is changed only when you run the `:Errors`
command, in order to minimise conflicts with other plugins. If you want the command, in order to minimise conflicts with other plugins. If you want the
@ -148,6 +175,8 @@ your vimrc:
let g:syntastic_always_populate_loc_list = 1 let g:syntastic_always_populate_loc_list = 1
``` ```
<a name="faqargs"></a>
__Q. How can I pass additional arguments to a checker?__ __Q. How can I pass additional arguments to a checker?__
A. Almost all syntax checkers use the `makeprgBuild()` function. Those checkers A. Almost all syntax checkers use the `makeprgBuild()` function. Those checkers
@ -162,6 +191,8 @@ let g:syntastic_ruby_mri_args = "--my --args --here"
See `:help syntastic-checker-options` for more information. See `:help syntastic-checker-options` for more information.
<a name="faqcheckers"></a>
__Q. Syntastic supports several checkers for my filetype - how do I tell it __Q. Syntastic supports several checkers for my filetype - how do I tell it
which one(s) to use?__ which one(s) to use?__
@ -181,8 +212,7 @@ To tell syntastic to use `pylint`, you would use this setting:
let g:syntastic_python_checkers = ['pylint'] let g:syntastic_python_checkers = ['pylint']
``` ```
Some filetypes, like PHP, have style checkers as well as syntax checkers. These Checkers can be chained together like this:
can be chained together like this:
```vim ```vim
let g:syntastic_php_checkers = ['php', 'phpcs', 'phpmd'] let g:syntastic_php_checkers = ['php', 'phpcs', 'phpmd']
``` ```
@ -190,29 +220,73 @@ let g:syntastic_php_checkers = ['php', 'phpcs', 'phpmd']
This is telling syntastic to run the `php` checker first, and if no errors are This is telling syntastic to run the `php` checker first, and if no errors are
found, run `phpcs`, and then `phpmd`. found, run `phpcs`, and then `phpmd`.
You can also run checkers explicitly by calling `:SyntasticCheck <checker>`.
e.g. to run `phpcs` and `phpmd`:
```vim
:SyntasticCheck phpcs phpmd
```
This works for any checkers available for the current filetype, even if they
aren't listed in `g:syntastic_<filetype>_checkers`. You can't run checkers for
"foreign" filetypes though (e.g. you can't run, say, a Python checker if the
filetype of the current file is `php`).
<a name="faqstyle"></a>
__Q. What is the difference between syntax checkers and style checkers?__
A. The errors and warnings they produce are highlighted differently and can
be filtered by different rules, but otherwise the distinction is pretty much
arbitrary. There is an ongoing effort to keep things consistent, so you can
_generally_ expect messages produced by syntax checkers to be _mostly_ related
to syntax, and messages produced by style checkers to be _mostly_ about style.
But there can be no formal guarantee that, say, a style checker that runs into
a syntax error wouldn't die with a fatal message, nor that a syntax checker
wouldn't give you warnings against using some constructs as being bad practice.
There is also no guarantee that messages marked as "style" are less severe than
the ones marked as "syntax" (whatever that might mean). And there are even a
few Frankenstein checkers (for example `flake8` and `pylama`) that, by their
nature, produce both kinds of messages. Syntastic is not smart enough to be
able to sort out these things by itself.
In fact it's more useful to look at this from the perspective of filtering
unwanted messages, rather than as an indicator of severity levels. The
distinction between syntax and style is orthogonal to the distinction between
errors and warnings, and thus you can turn off messages based on level, on
type, or both.
e.g. To disable all style messages:
```vim
let g:syntastic_quiet_messages = { "type": "style" }
```
See `:help syntastic_quiet_messages` for details.
<a name="faqaggregate"></a>
__Q. How can I display together the errors found by all checkers enabled for
the current file?__
A. Set `g:syntastic_aggregate_errors` to 1 in your vimrc:
```vim
let g:syntastic_aggregate_errors = 1
```
See `:help syntastic-aggregating-errors` for more details.
<a name="faqlnext"></a>
__Q. How can I jump between the different errors without using the location __Q. How can I jump between the different errors without using the location
list at the bottom of the window?__ list at the bottom of the window?__
A. Vim provides several built in commands for this. See `:help :lnext` and A. Vim provides several built-in commands for this. See `:help :lnext` and
`:help :lprev`. `:help :lprev`.
If you use these commands a lot then you may want to add shortcut mappings to If you use these commands a lot then you may want to add shortcut mappings to
your vimrc, or install something like [unimpaired][2], which provides such your vimrc, or install something like [unimpaired][2], which provides such
mappings (among other things). mappings (among other things).
__Q. A syntax checker is giving me unwanted/strange style tips?__ <a name="faqbdelete"></a>
A. Some filetypes (e.g. php) have style checkers as well as syntax
checkers. You can usually configure the options that are passed to the style
checkers, or just disable them. Take a look at the [wiki][3] to see what
options are available.
Alternatively, you can use `g:syntastic_quiet_messages` to filter out the
messages you don't want to see. e.g. To turn off all style messages:
```vim
let g:syntastic_quiet_messages = { "type": "style" }
```
See `:help syntastic_quiet_messages` for details.
__Q. The error window is closed automatically when I :quit the current buffer __Q. The error window is closed automatically when I :quit the current buffer
but not when I :bdelete it?__ but not when I :bdelete it?__
@ -231,8 +305,10 @@ cabbrev <silent> bd lclose\|bdelete
## 4\. Other resources ## 4\. Other resources
The preferred place for posting suggestions, reporting bugs, and general The preferred place for posting suggestions, reporting bugs, and general
discussions related to syntastic is the [issue tracker at GitHub][4]. There discussions related to syntastic is the [issue tracker at GitHub][4].
are also a [google group][5], and a [syntastic tag at StackOverflow][6]. A guide for writing syntax checkers can be found in the [wiki][11].
There are also a dedicated [google group][5], and a
[syntastic tag at StackOverflow][6].
Syntastic aims to provide a common interface to syntax checkers for as many Syntastic aims to provide a common interface to syntax checkers for as many
languages as possible. For particular languages, there are, of course, other languages as possible. For particular languages, there are, of course, other
@ -248,5 +324,11 @@ a look at [jedi-vim][7], [python-mode][8], or [YouCompleteMe][9].
[6]: http://stackoverflow.com/questions/tagged/syntastic [6]: http://stackoverflow.com/questions/tagged/syntastic
[7]: https://github.com/davidhalter/jedi-vim [7]: https://github.com/davidhalter/jedi-vim
[8]: https://github.com/klen/python-mode [8]: https://github.com/klen/python-mode
[9]: https://github.com/Valloric/YouCompleteMe [9]: http://valloric.github.io/YouCompleteMe/
[10]: http://perldoc.perl.org/perlrun.html#*-c* [10]: http://perldoc.perl.org/perlrun.html#*-c*
[11]: https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide
[12]: https://github.com/rust-lang/rust/
<!--
vim:tw=79:sw=4:
-->

View file

@ -62,7 +62,7 @@ endfunction " }}}2
" GetLocList() for C-like compilers " GetLocList() for C-like compilers
function! syntastic#c#GetLocList(filetype, subchecker, options) " {{{2 function! syntastic#c#GetLocList(filetype, subchecker, options) " {{{2
try try
let flags = s:getCflags(a:filetype, a:subchecker, a:options) let flags = s:_getCflags(a:filetype, a:subchecker, a:options)
catch /\m\C^Syntastic: skip checks$/ catch /\m\C^Syntastic: skip checks$/
return [] return []
endtry endtry
@ -70,9 +70,9 @@ function! syntastic#c#GetLocList(filetype, subchecker, options) " {{{2
let makeprg = syntastic#util#shexpand(g:syntastic_{a:filetype}_compiler) . let makeprg = syntastic#util#shexpand(g:syntastic_{a:filetype}_compiler) .
\ ' ' . flags . ' ' . syntastic#util#shexpand('%') \ ' ' . flags . ' ' . syntastic#util#shexpand('%')
let errorformat = s:getCheckerVar('g', a:filetype, a:subchecker, 'errorformat', a:options['errorformat']) let errorformat = s:_getCheckerVar('g', a:filetype, a:subchecker, 'errorformat', a:options['errorformat'])
let postprocess = s:getCheckerVar('g', a:filetype, a:subchecker, 'remove_include_errors', 0) ? let postprocess = s:_getCheckerVar('g', a:filetype, a:subchecker, 'remove_include_errors', 0) ?
\ ['filterForeignErrors'] : [] \ ['filterForeignErrors'] : []
" process makeprg " process makeprg
@ -87,29 +87,29 @@ endfunction " }}}2
" Private functions {{{1 " Private functions {{{1
" initialize c/cpp syntax checker handlers " initialize c/cpp syntax checker handlers
function! s:init() " {{{2 function! s:_init() " {{{2
let s:handlers = [] let s:handlers = []
let s:cflags = {} let s:cflags = {}
call s:regHandler('\m\<cairo', 'syntastic#c#checkPKG', ['cairo', 'cairo']) call s:_regHandler('\m\<cairo', 'syntastic#c#checkPKG', ['cairo', 'cairo'])
call s:regHandler('\m\<freetype', 'syntastic#c#checkPKG', ['freetype', 'freetype2', 'freetype']) call s:_regHandler('\m\<freetype', 'syntastic#c#checkPKG', ['freetype', 'freetype2', 'freetype'])
call s:regHandler('\m\<glade', 'syntastic#c#checkPKG', ['glade', 'libglade-2.0', 'libglade']) call s:_regHandler('\m\<glade', 'syntastic#c#checkPKG', ['glade', 'libglade-2.0', 'libglade'])
call s:regHandler('\m\<glib', 'syntastic#c#checkPKG', ['glib', 'glib-2.0', 'glib']) call s:_regHandler('\m\<glib', 'syntastic#c#checkPKG', ['glib', 'glib-2.0', 'glib'])
call s:regHandler('\m\<gtk', 'syntastic#c#checkPKG', ['gtk', 'gtk+-2.0', 'gtk+', 'glib-2.0', 'glib']) call s:_regHandler('\m\<gtk', 'syntastic#c#checkPKG', ['gtk', 'gtk+-2.0', 'gtk+', 'glib-2.0', 'glib'])
call s:regHandler('\m\<libsoup', 'syntastic#c#checkPKG', ['libsoup', 'libsoup-2.4', 'libsoup-2.2']) call s:_regHandler('\m\<libsoup', 'syntastic#c#checkPKG', ['libsoup', 'libsoup-2.4', 'libsoup-2.2'])
call s:regHandler('\m\<libxml', 'syntastic#c#checkPKG', ['libxml', 'libxml-2.0', 'libxml']) call s:_regHandler('\m\<libxml', 'syntastic#c#checkPKG', ['libxml', 'libxml-2.0', 'libxml'])
call s:regHandler('\m\<pango', 'syntastic#c#checkPKG', ['pango', 'pango']) call s:_regHandler('\m\<pango', 'syntastic#c#checkPKG', ['pango', 'pango'])
call s:regHandler('\m\<SDL', 'syntastic#c#checkPKG', ['sdl', 'sdl']) call s:_regHandler('\m\<SDL', 'syntastic#c#checkPKG', ['sdl', 'sdl'])
call s:regHandler('\m\<opengl', 'syntastic#c#checkPKG', ['opengl', 'gl']) call s:_regHandler('\m\<opengl', 'syntastic#c#checkPKG', ['opengl', 'gl'])
call s:regHandler('\m\<webkit', 'syntastic#c#checkPKG', ['webkit', 'webkit-1.0']) call s:_regHandler('\m\<webkit', 'syntastic#c#checkPKG', ['webkit', 'webkit-1.0'])
call s:regHandler('\m\<php\.h\>', 'syntastic#c#checkPHP', []) call s:_regHandler('\m\<php\.h\>', 'syntastic#c#checkPHP', [])
call s:regHandler('\m\<Python\.h\>', 'syntastic#c#checkPython', []) call s:_regHandler('\m\<Python\.h\>', 'syntastic#c#checkPython', [])
call s:regHandler('\m\<ruby', 'syntastic#c#checkRuby', []) call s:_regHandler('\m\<ruby', 'syntastic#c#checkRuby', [])
endfunction " }}}2 endfunction " }}}2
" return a handler dictionary object " return a handler dictionary object
function! s:regHandler(regex, function, args) " {{{2 function! s:_regHandler(regex, function, args) " {{{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)
@ -118,7 +118,7 @@ function! s:regHandler(regex, function, args) " {{{2
endfunction " }}}2 endfunction " }}}2
" resolve checker-related user variables " resolve checker-related user variables
function! s:getCheckerVar(scope, filetype, subchecker, name, default) " {{{2 function! s:_getCheckerVar(scope, filetype, subchecker, name, default) " {{{2
let prefix = a:scope . ':' . 'syntastic_' let prefix = a:scope . ':' . 'syntastic_'
if exists(prefix . a:filetype . '_' . a:subchecker . '_' . a:name) if exists(prefix . a:filetype . '_' . a:subchecker . '_' . a:name)
return {a:scope}:syntastic_{a:filetype}_{a:subchecker}_{a:name} return {a:scope}:syntastic_{a:filetype}_{a:subchecker}_{a:name}
@ -130,10 +130,10 @@ function! s:getCheckerVar(scope, filetype, subchecker, name, default) " {{{2
endfunction " }}}2 endfunction " }}}2
" resolve user CFLAGS " resolve user CFLAGS
function! s:getCflags(ft, ck, opts) " {{{2 function! s:_getCflags(ft, ck, opts) " {{{2
" determine whether to parse header files as well " determine whether to parse header files as well
if has_key(a:opts, 'header_names') && expand('%') =~? a:opts['header_names'] if has_key(a:opts, 'header_names') && expand('%') =~? a:opts['header_names']
if s:getCheckerVar('g', a:ft, a:ck, 'check_header', 0) if s:_getCheckerVar('g', a:ft, a:ck, 'check_header', 0)
let flags = get(a:opts, 'header_flags', '') . ' -c ' . syntastic#c#NullOutput() let flags = get(a:opts, 'header_flags', '') . ' -c ' . syntastic#c#NullOutput()
else else
" checking headers when check_header is unset: bail out " checking headers when check_header is unset: bail out
@ -143,21 +143,21 @@ function! s:getCflags(ft, ck, opts) " {{{2
let flags = get(a:opts, 'main_flags', '') let flags = get(a:opts, 'main_flags', '')
endif endif
let flags .= ' ' . s:getCheckerVar('g', a:ft, a:ck, 'compiler_options', '') . ' ' . s:getIncludeDirs(a:ft) let flags .= ' ' . s:_getCheckerVar('g', a:ft, a:ck, 'compiler_options', '') . ' ' . s:_getIncludeDirs(a:ft)
" check if the user manually set some cflags " check if the user manually set some cflags
let b_cflags = s:getCheckerVar('b', a:ft, a:ck, 'cflags', '') let b_cflags = s:_getCheckerVar('b', a:ft, a:ck, 'cflags', '')
if b_cflags == '' if b_cflags == ''
" check whether to search for include files at all " check whether to search for include files at all
if !s:getCheckerVar('g', a:ft, a:ck, 'no_include_search', 0) if !s:_getCheckerVar('g', a:ft, a:ck, 'no_include_search', 0)
if a:ft ==# 'c' || a:ft ==# 'cpp' if a:ft ==# 'c' || a:ft ==# 'cpp'
" refresh the include file search if desired " refresh the include file search if desired
if s:getCheckerVar('g', a:ft, a:ck, 'auto_refresh_includes', 0) if s:_getCheckerVar('g', a:ft, a:ck, 'auto_refresh_includes', 0)
let flags .= ' ' . s:searchHeaders() let flags .= ' ' . s:_searchHeaders()
else else
" search for header includes if not cached already " search for header includes if not cached already
if !exists('b:syntastic_' . a:ft . '_includes') if !exists('b:syntastic_' . a:ft . '_includes')
let b:syntastic_{a:ft}_includes = s:searchHeaders() let b:syntastic_{a:ft}_includes = s:_searchHeaders()
endif endif
let flags .= ' ' . b:syntastic_{a:ft}_includes let flags .= ' ' . b:syntastic_{a:ft}_includes
endif endif
@ -169,7 +169,7 @@ function! s:getCflags(ft, ck, opts) " {{{2
endif endif
" add optional config file parameters " add optional config file parameters
let config_file = s:getCheckerVar('g', a:ft, a:ck, 'config_file', '.syntastic_' . a:ft . '_config') let config_file = s:_getCheckerVar('g', a:ft, a:ck, 'config_file', '.syntastic_' . a:ft . '_config')
let flags .= ' ' . syntastic#c#ReadConfig(config_file) let flags .= ' ' . syntastic#c#ReadConfig(config_file)
return flags return flags
@ -177,10 +177,10 @@ endfunction " }}}2
" get the gcc include directory argument depending on the default " get the gcc include directory argument depending on the default
" includes and the optional user-defined 'g:syntastic_c_include_dirs' " includes and the optional user-defined 'g:syntastic_c_include_dirs'
function! s:getIncludeDirs(filetype) " {{{2 function! s:_getIncludeDirs(filetype) " {{{2
let include_dirs = [] let include_dirs = []
if a:filetype =~# '\v^%(c|cpp|d|objc|objcpp)$' && if a:filetype =~# '\v^%(c|cpp|objc|objcpp)$' &&
\ (!exists('g:syntastic_'.a:filetype.'_no_default_include_dirs') || \ (!exists('g:syntastic_'.a:filetype.'_no_default_include_dirs') ||
\ !g:syntastic_{a:filetype}_no_default_include_dirs) \ !g:syntastic_{a:filetype}_no_default_include_dirs)
let include_dirs = copy(s:default_includes) let include_dirs = copy(s:default_includes)
@ -195,7 +195,7 @@ endfunction " }}}2
" search the first 100 lines for include statements that are " search the first 100 lines for include statements that are
" given in the handlers dictionary " given in the handlers dictionary
function! s:searchHeaders() " {{{2 function! s:_searchHeaders() " {{{2
let includes = '' let includes = ''
let files = [] let files = []
let found = [] let found = []
@ -324,7 +324,7 @@ let s:default_includes = [
\ '..' . syntastic#util#Slash() . 'include', \ '..' . syntastic#util#Slash() . 'include',
\ '..' . syntastic#util#Slash() . 'includes' ] \ '..' . syntastic#util#Slash() . 'includes' ]
call s:init() call s:_init()
let &cpo = s:save_cpo let &cpo = s:save_cpo
unlet s:save_cpo unlet s:save_cpo

View file

@ -6,7 +6,7 @@ let g:loaded_syntastic_log_autoload = 1
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
let s:deprecation_notices_issued = [] let s:one_time_notices_issued = []
" Public functions {{{1 " Public functions {{{1
@ -27,22 +27,46 @@ function! syntastic#log#error(msg) " {{{2
echohl None echohl None
endfunction " }}}2 endfunction " }}}2
function! syntastic#log#deprecationWarn(msg) " {{{2 function! syntastic#log#oneTimeWarn(msg) " {{{2
if index(s:deprecation_notices_issued, a:msg) >= 0 if index(s:one_time_notices_issued, a:msg) >= 0
return return
endif endif
call add(s:deprecation_notices_issued, a:msg) call add(s:one_time_notices_issued, a:msg)
call syntastic#log#warn(a:msg) call syntastic#log#warn(a:msg)
endfunction " }}}2 endfunction " }}}2
" @vimlint(EVL102, 1, l:OLD_VAR)
function! syntastic#log#deprecationWarn(old, new, ...) " {{{2
if exists('g:syntastic_' . a:old) && !exists('g:syntastic_' . a:new)
let msg = 'variable g:syntastic_' . a:old . ' is deprecated, please use '
if a:0
let OLD_VAR = g:syntastic_{a:old}
try
let NEW_VAR = eval(a:1)
let msg .= 'in its stead: let g:syntastic_' . a:new . ' = ' . string(NEW_VAR)
let g:syntastic_{a:new} = NEW_VAR
catch
let msg .= 'g:syntastic_' . a:new . ' instead'
endtry
else
let msg .= 'g:syntastic_' . a:new . ' instead'
let g:syntastic_{a:new} = g:syntastic_{a:old}
endif
call syntastic#log#oneTimeWarn(msg)
endif
endfunction " }}}2
" @vimlint(EVL102, 0, l:OLD_VAR)
function! syntastic#log#debug(level, msg, ...) " {{{2 function! syntastic#log#debug(level, msg, ...) " {{{2
if !s:isDebugEnabled(a:level) if !s:isDebugEnabled(a:level)
return return
endif endif
let leader = s:logTimestamp() let leader = s:_logTimestamp()
call s:logRedirect(1) call s:_logRedirect(1)
if a:0 > 0 if a:0 > 0
" filter out dictionary functions " filter out dictionary functions
@ -53,7 +77,7 @@ function! syntastic#log#debug(level, msg, ...) " {{{2
echomsg leader . a:msg echomsg leader . a:msg
endif endif
call s:logRedirect(0) call s:_logRedirect(0)
endfunction " }}}2 endfunction " }}}2
function! syntastic#log#debugShowOptions(level, names) " {{{2 function! syntastic#log#debugShowOptions(level, names) " {{{2
@ -61,15 +85,15 @@ function! syntastic#log#debugShowOptions(level, names) " {{{2
return return
endif endif
let leader = s:logTimestamp() let leader = s:_logTimestamp()
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)))")
echomsg leader . join(vlist, ', ') echomsg leader . join(vlist, ', ')
endif endif
call s:logRedirect(0) call s:_logRedirect(0)
endfunction " }}}2 endfunction " }}}2
function! syntastic#log#debugShowVariables(level, names) " {{{2 function! syntastic#log#debugShowVariables(level, names) " {{{2
@ -77,18 +101,18 @@ function! syntastic#log#debugShowVariables(level, names) " {{{2
return return
endif endif
let leader = s:logTimestamp() let leader = s:_logTimestamp()
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:formatVariable(name) let msg = s:_formatVariable(name)
if msg != '' if msg != ''
echomsg leader . msg echomsg leader . msg
endif endif
endfor endfor
call s:logRedirect(0) call s:_logRedirect(0)
endfunction " }}}2 endfunction " }}}2
function! syntastic#log#debugDump(level) " {{{2 function! syntastic#log#debugDump(level) " {{{2
@ -103,18 +127,19 @@ endfunction " }}}2
" Private functions {{{1 " Private functions {{{1
function! s:isDebugEnabled_smart(level) " {{{2 function! s:_isDebugEnabled_smart(level) " {{{2
return and(g:syntastic_debug, a:level) return and(g:syntastic_debug, a:level)
endfunction " }}}2 endfunction " }}}2
function! s:isDebugEnabled_dumb(level) " {{{2 function! s:_isDebugEnabled_dumb(level) " {{{2
" poor man's bit test for bit N, assuming a:level == 2**N " poor man's bit test for bit N, assuming a:level == 2**N
return (g:syntastic_debug / a:level) % 2 return (g:syntastic_debug / a:level) % 2
endfunction " }}}2 endfunction " }}}2
let s:isDebugEnabled = function(exists('*and') ? 's:isDebugEnabled_smart' : 's:isDebugEnabled_dumb') let s:isDebugEnabled = function(exists('*and') ? 's:_isDebugEnabled_smart' : 's:_isDebugEnabled_dumb')
lockvar s:isDebugEnabled
function! s:logRedirect(on) " {{{2 function! s:_logRedirect(on) " {{{2
if exists("g:syntastic_debug_file") if exists("g:syntastic_debug_file")
if a:on if a:on
try try
@ -129,17 +154,11 @@ function! s:logRedirect(on) " {{{2
endif endif
endfunction " }}}2 endfunction " }}}2
function! s:logTimestamp_smart() " {{{2 function! s:_logTimestamp() " {{{2
return 'syntastic: ' . split(reltimestr(reltime(g:syntastic_start)))[0] . ': ' return 'syntastic: ' . split(reltimestr(reltime(g:syntastic_start)))[0] . ': '
endfunction " }}}2 endfunction " }}}2
function! s:logTimestamp_dumb() " {{{2 function! s:_formatVariable(name) " {{{2
return 'syntastic: debug: '
endfunction " }}}2
let s:logTimestamp = function(has('reltime') ? 's:logTimestamp_smart' : 's:logTimestamp_dumb')
function! s:formatVariable(name) " {{{2
let vals = [] let vals = []
if exists('g:syntastic_' . a:name) if exists('g:syntastic_' . a:name)
call add(vals, 'g:syntastic_' . a:name . ' = ' . strtrans(string(g:syntastic_{a:name}))) call add(vals, 'g:syntastic_' . a:name . ' = ' . strtrans(string(g:syntastic_{a:name})))

View file

@ -8,31 +8,14 @@ set cpo&vim
" Public functions {{{1 " Public functions {{{1
function! s:compareErrorItems(a, b) " {{{2
if a:a['bufnr'] != a:b['bufnr']
" group by files
return a:a['bufnr'] - a:b['bufnr']
elseif a:a['lnum'] != a:b['lnum']
return a:a['lnum'] - a:b['lnum']
elseif a:a['type'] !=? a:b['type']
" errors take precedence over warnings
return a:a['type'] ==? 'e' ? -1 : 1
else
return get(a:a, 'col', 0) - get(a:b, 'col', 0)
endif
endfunction " }}}2
" natural sort
function! syntastic#postprocess#sort(errors) " {{{2
return sort(copy(a:errors), 's:compareErrorItems')
endfunction " }}}2
" merge consecutive blanks " merge consecutive blanks
function! syntastic#postprocess#compressWhitespace(errors) " {{{2 function! syntastic#postprocess#compressWhitespace(errors) " {{{2
for e in a:errors for e in a:errors
let e['text'] = substitute(e['text'], "\001", '', 'g') let e['text'] = substitute(e['text'], "\001", '', 'g')
let e['text'] = substitute(e['text'], '\n', ' ', 'g') let e['text'] = substitute(e['text'], '\n', ' ', 'g')
let e['text'] = substitute(e['text'], '\m\s\{2,}', ' ', 'g') let e['text'] = substitute(e['text'], '\m\s\{2,}', ' ', 'g')
let e['text'] = substitute(e['text'], '\m^\s\+', '', '')
let e['text'] = substitute(e['text'], '\m\s\+$', '', '')
endfor endfor
return a:errors return a:errors
@ -63,6 +46,25 @@ function! syntastic#postprocess#filterForeignErrors(errors) " {{{2
return filter(copy(a:errors), 'get(v:val, "bufnr") == ' . bufnr('')) return filter(copy(a:errors), 'get(v:val, "bufnr") == ' . bufnr(''))
endfunction " }}}2 endfunction " }}}2
" make sure line numbers are not past end of buffers
" XXX: this loads all referenced buffers in memory
function! syntastic#postprocess#guards(errors) " {{{2
let buffers = syntastic#util#unique(map(filter(copy(a:errors), 'v:val["valid"]'), 'str2nr(v:val["bufnr"])'))
let guards = {}
for b in buffers
let guards[b] = len(getbufline(b, 1, '$'))
endfor
for e in a:errors
if e['valid'] && e['lnum'] > guards[e['bufnr']]
let e['lnum'] = guards[e['bufnr']]
endif
endfor
return a:errors
endfunction " }}}2
" }}}1 " }}}1
let &cpo = s:save_cpo let &cpo = s:save_cpo

View file

@ -8,6 +8,26 @@ set cpo&vim
" Public functions {{{1 " Public functions {{{1
function! syntastic#preprocess#cabal(errors) " {{{2
let out = []
let star = 0
for err in a:errors
if star
if err == ''
let star = 0
else
let out[-1] .= ' ' . err
endif
else
call add(out, err)
if err =~ '\m^*\s'
let star = 1
endif
endif
endfor
return out
endfunction " }}}2
function! syntastic#preprocess#checkstyle(errors) " {{{2 function! syntastic#preprocess#checkstyle(errors) " {{{2
let out = [] let out = []
let fname = expand('%') let fname = expand('%')
@ -56,6 +76,49 @@ function! syntastic#preprocess#perl(errors) " {{{2
return syntastic#util#unique(out) return syntastic#util#unique(out)
endfunction " }}}2 endfunction " }}}2
function! syntastic#preprocess#rparse(errors) " {{{2
let errlist = copy(a:errors)
" remove uninteresting lines and handle continuations
let i = 0
while i < len(errlist)
if i > 0 && errlist[i][:1] == ' ' && errlist[i] !~ '\m\s\+\^$'
let errlist[i-1] .= errlist[i][1:]
call remove(errlist, i)
elseif errlist[i] !~ '\m^\(Lint:\|Lint checking:\|Error in\) '
call remove(errlist, i)
else
let i += 1
endif
endwhile
let out = []
let fname = ''
for e in errlist
if match(e, '\m^Lint: ') == 0
let parts = matchlist(e, '\m^Lint: \(.*\): found on lines \([0-9, ]\+\)\(+\(\d\+\) more\)\=')
if len(parts) >= 3
for line in split(parts[2], '\m,\s*')
call add(out, 'E:' . fname . ':' . line . ': ' . parts[1])
endfor
endif
if len(parts) >= 5 && parts[4] != ''
call add(out, 'E:' . fname . ':0: ' . parts[1] . ' - ' . parts[4] . ' messages not shown')
endif
elseif match(e, '\m^Lint checking: ') == 0
let fname = matchstr(e, '\m^Lint checking: \zs.*')
elseif match(e, '\m^Error in ') == 0
call add(out, substitute(e, '\m^Error in .\+ : .\+\ze:\d\+:\d\+: ', 'E:' . fname, ''))
endif
endfor
return out
endfunction " }}}2
function! syntastic#preprocess#tslint(errors) " {{{2
return map(copy(a:errors), 'substitute(v:val, ''\m^\(([^)]\+)\)\s\(.\+\)$'', ''\2 \1'', "")')
endfunction " }}}2
function! syntastic#preprocess#validator(errors) " {{{2 function! syntastic#preprocess#validator(errors) " {{{2
let out = [] let out = []
for e in a:errors for e in a:errors

View file

@ -35,12 +35,12 @@ endfunction " }}}2
" "
"{'exe': '/usr/bin/perl', 'args': ['-f', '-bar']} "{'exe': '/usr/bin/perl', 'args': ['-f', '-bar']}
function! syntastic#util#parseShebang() " {{{2 function! syntastic#util#parseShebang() " {{{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 exe = matchstr(line, '\m^#!\s*\zs[^ \t]*') let line = substitute(line, '\v^#!\s*(\S+/env(\s+-\S+)*\s+)?', '', '')
let args = split(matchstr(line, '\m^#!\s*[^ \t]*\zs.*')) let exe = matchstr(line, '\m^\S*\ze')
let args = split(matchstr(line, '\m^\S*\zs.*'))
return { 'exe': exe, 'args': args } return { 'exe': exe, 'args': args }
endif endif
endfor endfor
@ -58,7 +58,7 @@ 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) " {{{2 function! syntastic#util#parseVersion(version) " {{{2
return split(matchstr( a:version, '\v^\D*\zs\d+(\.\d+)+\ze' ), '\m\.') return map(split(matchstr( a:version, '\v^\D*\zs\d+(\.\d+)+\ze' ), '\m\.'), 'str2nr(v:val)')
endfunction " }}}2 endfunction " }}}2
" Run 'command' in a shell and parse output as a version string. " Run 'command' in a shell and parse output as a version string.
@ -74,20 +74,37 @@ endfunction " }}}2
" "
" See http://semver.org for info about version numbers. " See http://semver.org for info about version numbers.
function! syntastic#util#versionIsAtLeast(installed, required) " {{{2 function! syntastic#util#versionIsAtLeast(installed, required) " {{{2
for idx in range(max([len(a:installed), len(a:required)])) return syntastic#util#compareLexi(a:installed, a:required) >= 0
let installed_element = get(a:installed, idx, 0) endfunction " }}}2
let required_element = get(a:required, idx, 0)
if installed_element != required_element " Almost lexicographic comparison of two lists of integers. :) If lists
return installed_element > required_element " have different lengths, the "missing" elements are assumed to be 0.
function! syntastic#util#compareLexi(a, b) " {{{2
for idx in range(max([len(a:a), len(a:b)]))
let a_element = str2nr(get(a:a, idx, 0))
let b_element = str2nr(get(a:b, idx, 0))
if a_element != b_element
return a_element > b_element ? 1 : -1
endif endif
endfor endfor
" Everything matched, so it is at least the required version. " Everything matched, so it is at least the required version.
return 1 return 0
endfunction " }}}2 endfunction " }}}2
" strwidth() was added in Vim 7.3; if it doesn't exist, we use strlen() " strwidth() was added in Vim 7.3; if it doesn't exist, we use strlen()
" and hope for the best :) " and hope for the best :)
let s:width = function(exists('*strwidth') ? 'strwidth' : 'strlen') let s:width = function(exists('*strwidth') ? 'strwidth' : 'strlen')
lockvar s:width
function! syntastic#util#screenWidth(str, tabstop) " {{{2
let chunks = split(a:str, "\t", 1)
let width = s:width(chunks[-1])
for c in chunks[:-2]
let cwidth = s:width(c)
let width += cwidth + a:tabstop - cwidth % a:tabstop
endfor
return width
endfunction " }}}2
"print as much of a:msg as possible without "Press Enter" prompt appearing "print as much of a:msg as possible without "Press Enter" prompt appearing
function! syntastic#util#wideMsg(msg) " {{{2 function! syntastic#util#wideMsg(msg) " {{{2
@ -101,7 +118,7 @@ function! syntastic#util#wideMsg(msg) " {{{2
"convert tabs to spaces so that the tabs count towards the window "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
let chunks = split(msg, "\t", 1) let chunks = split(msg, "\t", 1)
let msg = join(map(chunks[:-2], 'v:val . repeat(" ", &ts - s:width(v:val) % &ts)'), '') . chunks[-1] let msg = join(map(chunks[:-2], 'v:val . repeat(" ", &tabstop - s:width(v:val) % &tabstop)'), '') . chunks[-1]
let msg = strpart(msg, 0, &columns - 1) let msg = strpart(msg, 0, &columns - 1)
set noruler noshowcmd set noruler noshowcmd
@ -208,7 +225,7 @@ function! syntastic#util#redraw(full) " {{{2
endfunction " }}}2 endfunction " }}}2
function! syntastic#util#dictFilter(errors, filter) " {{{2 function! syntastic#util#dictFilter(errors, filter) " {{{2
let rules = s:translateFilter(a:filter) let rules = s:_translateFilter(a:filter)
" call syntastic#log#debug(g:SyntasticDebugFilters, "applying filter:", rules) " call syntastic#log#debug(g:SyntasticDebugFilters, "applying filter:", rules)
try try
call filter(a:errors, rules) call filter(a:errors, rules)
@ -218,17 +235,24 @@ function! syntastic#util#dictFilter(errors, filter) " {{{2
endtry endtry
endfunction " }}}2 endfunction " }}}2
" Return a [high, low] list of integers, representing the time
" (hopefully high resolution) since program start
" TODO: This assumes reltime() returns a list of integers.
function! syntastic#util#stamp() " {{{2
return reltime(g:syntastic_start)
endfunction " }}}2
" }}}1 " }}}1
" Private functions {{{1 " Private functions {{{1
function! s:translateFilter(filters) " {{{2 function! s:_translateFilter(filters) " {{{2
let conditions = [] let conditions = []
for k in keys(a:filters) for k in keys(a:filters)
if type(a:filters[k]) == type([]) if type(a:filters[k]) == type([])
call extend(conditions, map(copy(a:filters[k]), 's:translateElement(k, v:val)')) call extend(conditions, map(copy(a:filters[k]), 's:_translateElement(k, v:val)'))
else else
call add(conditions, s:translateElement(k, a:filters[k])) call add(conditions, s:_translateElement(k, a:filters[k]))
endif endif
endfor endfor
@ -238,7 +262,7 @@ function! s:translateFilter(filters) " {{{2
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) " {{{2 function! s:_translateElement(key, term) " {{{2
if a:key ==? 'level' if a:key ==? 'level'
let ret = 'v:val["type"] !=? ' . string(a:term[0]) let ret = 'v:val["type"] !=? ' . string(a:term[0])
elseif a:key ==? 'type' elseif a:key ==? 'type'

View file

@ -36,9 +36,14 @@ CONTENTS *syntastic-contents*
5.3.Configuring specific checkers..........|syntastic-config-makeprg| 5.3.Configuring specific checkers..........|syntastic-config-makeprg|
6.Notes........................................|syntastic-notes| 6.Notes........................................|syntastic-notes|
6.1.Handling of composite filetypes........|syntastic-composite| 6.1.Handling of composite filetypes........|syntastic-composite|
6.2.Interaction with python-mode...........|syntastic-pymode| 6.2.Editing files over network.............|syntastic-netrw|
6.3.Interaction with the fish shell........|syntastic-fish| 6.3.Interaction with python-mode...........|syntastic-pymode|
6.4.Using syntastic with the fizsh shell...|syntastic-fizsh| 6.4.Interaction with YouCompleteMe.........|syntastic-ycm|
6.5.Interaction with the fish shell........|syntastic-fish|
6.6.Interaction with PowerShell............|syntastic-powershell|
6.7.Using syntastic with the fizsh shell...|syntastic-fizsh|
6.8.Interaction with Eclim.................|syntastic-eclim|
6.9.Interaction with vim-virtualenv........|syntastic-vim-virtualenv|
7.About........................................|syntastic-about| 7.About........................................|syntastic-about|
8.License......................................|syntastic-license| 8.License......................................|syntastic-license|
@ -62,7 +67,7 @@ Take a look at the wiki for a list of supported filetypes and checkers:
https://github.com/scrooloose/syntastic/wiki/Syntax-Checkers https://github.com/scrooloose/syntastic/wiki/Syntax-Checkers
Note: This doc only deals with using syntastic. To learn how to write syntax Note: This doc only deals with using syntastic. To learn how to write syntax
checker integrations, see the guide on the github wiki: checker integrations, see the guide on the GitHub wiki:
https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide
@ -73,16 +78,17 @@ Syntastic comes preconfigured with a default list of enabled checkers per
filetype. This list is kept reasonably short to prevent slowing down Vim or filetype. This list is kept reasonably short to prevent slowing down Vim or
trying to use conflicting checkers. trying to use conflicting checkers.
You can see the list checkers available for the current filetype with the You can see the list of checkers available for the current filetype with the
|:SyntasticInfo| command. |:SyntasticInfo| command.
If you want to override the configured list of checkers for a filetype then You probably want to override the configured list of checkers for the
see |syntastic-checker-options| for details. You can also change the arguments filetypes you use, and also change the arguments passed to specific checkers
passed to a specific checker as well. to suit your needs. See |syntastic-checker-options| for details.
Use |:SyntasticCheck| to manually check right now. Use |:SyntasticToggleMode| Use |:SyntasticCheck| to manually check right now. Use |:Errors| to open the
to switch between active (checking on writting the buffer) and passive (manual) |location-list| window, and |:lclose| to close it. You can clear the error
checking. list with |:SyntasticReset|, and you can use |:SyntasticToggleMode| to switch
between active (checking on writing the buffer) and passive (manual) checking.
============================================================================== ==============================================================================
2. Functionality provided *syntastic-functionality* 2. Functionality provided *syntastic-functionality*
@ -91,7 +97,7 @@ Syntax checking can be done automatically or on demand (see
|'syntastic_mode_map'| and |:SyntasticToggleMode| for configuring this). |'syntastic_mode_map'| and |:SyntasticToggleMode| for configuring this).
When syntax checking is done, the features below can be used to notify the When syntax checking is done, the features below can be used to notify the
user of errors. See |syntastic-options| for how to configure and user of errors. See |syntastic-global-options| for how to configure and
activate/deactivate these features. activate/deactivate these features.
* A statusline flag * A statusline flag
@ -150,13 +156,21 @@ Example: >
highlight SyntasticErrorLine guibg=#2f0000 highlight SyntasticErrorLine guibg=#2f0000
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
2.3. The error window *:Errors* *syntastic-error-window* 2.3. The error window *syntastic-error-window*
You can use the :Errors command to display the errors for the current buffer You can use the |:Errors| command to display the errors for the current buffer
in the |location-list|. in the |location-list|.
Note that when you use :Errors, the current location list is overwritten with Note that when you use |:Errors|, the current location list is overwritten
Syntastic's own location list. with Syntastic's own location list.
By default syntastic doesn't fill the |location-list| with the errors found by
the checkers, in order to reduce clashes with other plugins. Consequently, if
you run |:lopen| or |:lwindow| rather than |:Errors| to open the error window you
wouldn't see syntastic's list of errors. If you insist on using |:lopen| or
|:lwindow| you should either run |:SyntasticSetLoclist| after running the checks,
or set |syntastic_always_populate_loc_list| which tells syntastic to update the
|location-list| automatically.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
2.4. Error highlighting *syntastic-highlighting* 2.4. Error highlighting *syntastic-highlighting*
@ -167,6 +181,8 @@ and the SpellCap group is used for warnings. If you wish to customize the
colors for highlighting you can use the following groups: colors for highlighting you can use the following groups:
SyntasticError - Links to 'SpellBad' by default SyntasticError - Links to 'SpellBad' by default
SyntasticWarning - Links to 'SpellCap' by default SyntasticWarning - Links to 'SpellCap' by default
SyntasticStyleError - Links to SyntasticError by default
SyntasticStyleWarning - Links to SyntasticWarning by default
Example: > Example: >
highlight SyntasticError guibg=#2f0000 highlight SyntasticError guibg=#2f0000
@ -186,7 +202,12 @@ If |'syntastic_aggregate_errors'| is set, syntastic runs all checkers that
apply (still cf. |syntastic-filetype-checkers|), then aggregates errors found apply (still cf. |syntastic-filetype-checkers|), then aggregates errors found
by all checkers in a single list, and notifies you. In this mode each error by all checkers in a single list, and notifies you. In this mode each error
message is labeled with the name of the checker that generated it, but you can message is labeled with the name of the checker that generated it, but you can
disable these labels by unsetting '|syntastic_id_checkers|'. disable generation of these labels by turning off '|syntastic_id_checkers|'.
If |'syntastic_sort_aggregated_errors'| is set (which is the default), messages
in the aggregated list are grouped by file, then sorted by line number, then
type, then column number. Otherwise messages produced by the same checker are
grouped together.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
2.6 Filtering errors *syntastic-filtering-errors* 2.6 Filtering errors *syntastic-filtering-errors*
@ -200,11 +221,14 @@ See also: |'syntastic_<filetype>_<checker>_quiet_messages'|.
============================================================================== ==============================================================================
3. Commands *syntastic-commands* 3. Commands *syntastic-commands*
:Errors *:SyntasticErrors* :Errors *:Errors*
When errors have been detected, use this command to pop up the |location-list| When errors have been detected, use this command to pop up the |location-list|
and display the error messages. and display the error messages.
Please note that the |:Errors| command overwrites the current location list with
syntastic's own location list.
:SyntasticToggleMode *:SyntasticToggleMode* :SyntasticToggleMode *:SyntasticToggleMode*
Toggles syntastic between active and passive mode. See |'syntastic_mode_map'| Toggles syntastic between active and passive mode. See |'syntastic_mode_map'|
@ -227,7 +251,7 @@ the order specified. The rules of |syntastic_aggregate_errors| still apply.
Example: > Example: >
:SyntasticCheck flake8 pylint :SyntasticCheck flake8 pylint
< <
:SyntasticInfo *:SyntasticInfo* :SyntasticInfo *:SyntasticInfo*
The command takes an optional argument, and outputs information about the The command takes an optional argument, and outputs information about the
checkers available for the filetype named by said argument, or for the current checkers available for the filetype named by said argument, or for the current
@ -278,12 +302,35 @@ a file with a composite filetype), it might not be immediately obvious which
checker has produced a given error message. This variable instructs syntastic checker has produced a given error message. This variable instructs syntastic
to label error messages with the names of the checkers that created them. > to label error messages with the names of the checkers that created them. >
let g:syntastic_id_checkers = 0 let g:syntastic_id_checkers = 0
<
*'syntastic_sort_aggregated_errors'*
Default: 1
By default, when results from multiple checkers are aggregated in a single
error list (that is either when |syntastic_aggregate_errors| is enabled, or
when checking a file with a composite filetype), errors are grouped by file,
then sorted by line number, then grouped by type (namely errors take precedence
over warnings), then they are sorted by column number. If you want to leave
messages grouped by checker output, set this variable to 0. >
let g:syntastic_sort_aggregated_errors = 0
< <
*'syntastic_echo_current_error'* *'syntastic_echo_current_error'*
Default: 1 Default: 1
If enabled, syntastic will echo the error associated with the current line to If enabled, syntastic will echo current error to the command window. If
the command window. If multiple errors are found, the first will be used. > multiple errors are found on the same line, |syntastic_cursor_columns| is used
to decide which one is shown. >
let g:syntastic_echo_current_error = 1 let g:syntastic_echo_current_error = 1
<
*'syntastic_cursor_columns'*
Default: 1
This option controls which errors are echoed to the command window if
|syntastic_echo_current_error| is set and multiple errors are found on the same
line. When the option is enabled, the first error corresponding to the current
column is show. Otherwise, the first error on the current line is echoed,
regardless of the cursor position on the current line.
When dealing with very large lists of errors, disabling this option can speed
up navigation significantly: >
let g:syntastic_cursor_column = 0
< <
*'syntastic_enable_signs'* *'syntastic_enable_signs'*
Default: 1 Default: 1
@ -301,8 +348,8 @@ error symbols can be customized:
syntastic_style_warning_symbol - For style warnings, defaults to 'S>' syntastic_style_warning_symbol - For style warnings, defaults to 'S>'
Example: > Example: >
let g:syntastic_error_symbol = '✗' let g:syntastic_error_symbol = "✗"
let g:syntastic_warning_symbol = '⚠' let g:syntastic_warning_symbol = "⚠"
< <
*'syntastic_enable_balloons'* *'syntastic_enable_balloons'*
Default: 1 Default: 1
@ -374,47 +421,45 @@ Default: {}
Use this option to map non-standard filetypes to standard ones. Corresponding 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 = { 'latex': 'tex', let g:syntastic_filetype_map = { "latex": "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
default behaviour of running both checkers against the input file: > default behaviour of running both checkers against the input file: >
let g:syntastic_filetype_map = { 'handlebars.html': 'handlebars' } let g:syntastic_filetype_map = { "handlebars.html": "handlebars" }
< <
*'syntastic_mode_map'* *'syntastic_mode_map'*
Default: { "mode": "active", Default: { "mode": "active",
"active_filetypes": [], "active_filetypes": [],
"passive_filetypes": [] } "passive_filetypes": [] }
Use this option to fine tune when automatic syntax checking is done (or not Use this option to fine tune when automatic syntax checking is done (or not
done). done).
The option should be set to something like: > The option should be set to something like: >
let g:syntastic_mode_map = { 'mode': 'active', let g:syntastic_mode_map = { "mode": "active",
\ 'active_filetypes': ['ruby', 'php'], \ "active_filetypes": ["ruby", "php"],
\ 'passive_filetypes': ['puppet'] } \ "passive_filetypes": ["puppet"] }
< <
"mode" can be mapped to one of two values - "active" or "passive". When set to "mode" can be mapped to one of two values - "active" or "passive". When set
active, syntastic does automatic checking whenever a buffer is saved or to "active", syntastic does automatic checking whenever a buffer is saved or
initially opened. When set to "passive" syntastic only checks when the user initially opened. When set to "passive" syntastic only checks when the user
calls |:SyntasticCheck|. calls |:SyntasticCheck|.
The exceptions to these rules are defined with "active_filetypes" and The exceptions to these rules are defined with "active_filetypes" and
"passive_filetypes". In passive mode, automatic checks are still done "passive_filetypes". In passive mode, automatic checks are still done for
for all filetypes in the "active_filetypes" array. In active mode, filetypes in the "active_filetypes" array (and "passive_filetypes" is
automatic checks are not done for any filetypes in the ignored). In active mode, automatic checks are not done for any filetypes in
"passive_filetypes" array. the "passive_filetypes" array ("active_filetypes" is ignored).
If any of "mode", "active_filetypes", or "passive_filetypes" are left
unspecified, they default to values above.
At runtime, the |:SyntasticToggleMode| command can be used to switch between At runtime, the |:SyntasticToggleMode| command can be used to switch between
active and passive mode. active and passive modes.
If any of "mode", "active_filetypes", or "passive_filetypes" are not specified
then they will default to their default value as above.
*'syntastic_quiet_messages'* *'syntastic_quiet_messages'*
Default: {} Default: {}
Use this option to filter out some of the messages produced by checkers. The Use this option to filter out some of the messages produced by checkers. The
option should be set to something like: > option should be set to something like: >
let g:syntastic_quiet_messages = { "level": "warnings", let g:syntastic_quiet_messages = { "level": "warnings",
@ -451,7 +496,7 @@ Since filter elements with values [] or '' are ignored, you can disable global
filters for particular checkers, by setting the values of the corresponding filters for particular checkers, by setting the values of the corresponding
elements in |'syntastic_<filetype>_<checker>_quiet_messages'| to [] or ''. For elements in |'syntastic_<filetype>_<checker>_quiet_messages'| to [] or ''. For
example, the following setting will silence all warnings, except for the example, the following setting will silence all warnings, except for the
ones produced by 'pylint': > ones produced by "pylint": >
let g:syntastic_quiet_messages = { "level": "warnings" } let g:syntastic_quiet_messages = { "level": "warnings" }
let g:syntastic_python_pylint_quiet_messages = { "level" : [] } let g:syntastic_python_pylint_quiet_messages = { "level" : [] }
< <
@ -483,6 +528,12 @@ statusline: >
< <
If the buffer had 2 warnings, starting on line 5 then this would appear: > If the buffer had 2 warnings, starting on line 5 then this would appear: >
[Warn: 5 #2] [Warn: 5 #2]
<
*'b:syntastic_skip_checks'*
Default: unset
Only the local form |'b:syntastic_skip_checks'| is used. When set to a true
value, no checks are run against the corresponding buffer. Example: >
let b:syntastic_skip_checks = 1
< <
*'syntastic_full_redraws'* *'syntastic_full_redraws'*
Default: 0 in GUI Vim and MacVim, 1 otherwise Default: 0 in GUI Vim and MacVim, 1 otherwise
@ -491,6 +542,13 @@ Changing it can in principle make screen redraws smoother, but it can also
cause screen to flicker, or cause ghost characters. Leaving it to the default cause screen to flicker, or cause ghost characters. Leaving it to the default
should be safe. should be safe.
*'syntastic_exit_checks'*
Default: 0 when running under "cmd.exe" on Windows, 1 otherwise
Syntastic attempts to catch abnormal termination conditions from checkers by
looking at their exit codes. The "cmd.exe" shell on Windows make these checks
meaningless, by returning 1 to Vim when the checkers exit with non-zero codes.
The above variable can be used to disable exit code checks in syntastic.
*'syntastic_debug'* *'syntastic_debug'*
Default: 0 Default: 0
Set this to the sum of one or more of the following flags to enable Set this to the sum of one or more of the following flags to enable
@ -520,7 +578,7 @@ List of filetypes handled by checkers external to syntastic. If you have a Vim
plugin that adds a checker for syntastic, and if the said checker deals with a plugin that adds a checker for syntastic, and if the said checker deals with a
filetype that is unknown to syntastic, you might consider adding that filetype filetype that is unknown to syntastic, you might consider adding that filetype
to this list: > to this list: >
let g:syntastic_extra_filetypes = [ 'make', 'gitcommit' ] let g:syntastic_extra_filetypes = [ "make", "gitcommit" ]
< <
This will allow |:SyntasticInfo| to do proper tab completion for the new This will allow |:SyntasticInfo| to do proper tab completion for the new
filetypes. filetypes.
@ -534,14 +592,14 @@ filetypes.
*'g:syntastic_<filetype>_checkers'* *'g:syntastic_<filetype>_checkers'*
You can tell syntastic which checkers to run for a given filetype by setting a You can tell syntastic which checkers to run for a given filetype by setting a
variable 'g:syntastic_<filetype>_checkers' to a list of checkers, e.g. > variable 'g:syntastic_<filetype>_checkers' to a list of checkers, e.g. >
let g:syntastic_php_checkers = ['php', 'phpcs', 'phpmd'] let g:syntastic_php_checkers = ["php", "phpcs", "phpmd"]
< <
*'b:syntastic_checkers'* *'b:syntastic_checkers'*
There is also a per-buffer version of this setting, 'b:syntastic_checkers'. There is also a per-buffer version of this setting, 'b:syntastic_checkers'.
When set, it takes precedence over |'g:syntastic_<filetype>_checkers'|. You can When set, it takes precedence over |'g:syntastic_<filetype>_checkers'|. You can
use this in an autocmd to configure specific checkers for particular paths: > use this in an autocmd to configure specific checkers for particular paths: >
autocmd FileType python if stridx(expand('%:p'), '/some/path/') == 0 | autocmd FileType python if stridx(expand("%:p"), "/some/path/") == 0 |
\ let b:syntastic_checkers = ['pylint'] | endif \ let b:syntastic_checkers = ["pylint"] | endif
< <
If neither |'g:syntastic_<filetype>_checkers'| nor |'b:syntastic_checkers'| If neither |'g:syntastic_<filetype>_checkers'| nor |'b:syntastic_checkers'|
is set, a default list of checker is used. Beware however that this list is set, a default list of checker is used. Beware however that this list
@ -557,48 +615,61 @@ Use |:SyntasticInfo| to see which checkers are available for a given filetype.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
5.2 Choosing the executable *syntastic-config-exec* 5.2 Choosing the executable *syntastic-config-exec*
*'syntastic_<filetype>_<subchecker>_exec'* *'syntastic_<filetype>_<checker>_exec'*
The executable used by a checker is normally defined automatically, when the The executable run by a checker is normally defined automatically, when the
checkers is registered. You can however override it by setting the variable checker is registered. You can however override it, by setting the variable
'g:syntastic_<filetype>_<subchecker>_exec': > 'g:syntastic_<filetype>_<checker>_exec': >
let g:syntastic_ruby_mri_exec = '~/bin/ruby2' let g:syntastic_ruby_mri_exec = '~/bin/ruby2'
< <
This variable has a local version, 'b:syntastic_<filetype>_<checker>_exec',
which takes precedence over the global one in the corresponding buffer.
*'b:syntastic_<checker>_exec'*
And there is also a local variable named 'b:syntastic_<checker>_exec', which
takes precedence over both 'b:syntastic_<filetype>_<checker>_exec' and
'g:syntastic_<filetype>_<checker>_exec' in the buffers where it is defined.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
5.3 Configuring specific checkers *syntastic-config-makeprg* 5.3 Configuring specific checkers *syntastic-config-makeprg*
Most checkers use the 'makeprgBuild()' function and provide many options by Most checkers use the 'makeprgBuild()' function and provide many options by
default - in fact you can customise every part of the command that gets called. default - in fact you can customise every part of the command that gets called.
*'syntastic_<filetype>_<subchecker>_<option>'* *'syntastic_<filetype>_<checker>_<option>'*
Checkers that use 'makeprgBuild()' construct a 'makeprg' like this: > Checkers that use 'makeprgBuild()' construct a 'makeprg' like this: >
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'exe': self.getExec(), \ "exe": self.getExec(),
\ 'args': '-a -b -c', \ "args": "-a -b -c",
\ 'post_args': '--more --args', \ "post_args": "--more --args",
\ 'tail': '> /tmp/output' }) \ "tail": "2>/dev/null" })
< <
The result is a 'makeprg' of the form: > The result is a 'makeprg' of the form: >
<exe> <args> <filename> <post_args> <tail> <exe> <args> <fname> <post_args> <tail>
< <
*'syntastic_<filetype>_<subchecker>_exe'*
All arguments above are optional, and can be overridden by setting global All arguments above are optional, and can be overridden by setting global
variables 'g:syntastic_<filetype>_<checker-name>_<option-name>' - even variables 'g:syntastic_<filetype>_<checker-name>_<option-name>' - even
parameters not specified in the call to makeprgBuild(). These variables also parameters not specified in the call to makeprgBuild(). These variables also
have local versions 'b:syntastic_<filetype>_<checker-name>_<option-name>', have local versions 'b:syntastic_<filetype>_<checker-name>_<option-name>',
which take precedence over the global ones in the corresponding buffers. which take precedence over the global ones in the corresponding buffers.
If one of these variables has a non-empty default and you want it to be empty,
you can set it to an empty string, e.g.: >
let g:syntastic_javascript_jslint_args = ""
<
*'syntastic_<filetype>_<checker>_exe'*
The 'exe' is normally the same as the 'exec' attribute described above, in The 'exe' is normally the same as the 'exec' attribute described above, in
which case it may be omitted. However, you can use it to add environment which case it may be omitted. However, you can use it to add environment
variables or additional parameters, e.g. to tell the mri checker to use KANJI variables, or to change the way the checker is run. For example this setup
encoding you could do something like this: > allows you to run PC-Lint under Wine emulation on Linux: >
let g:syntastic_ruby_mri_exe = 'RUBYOPT="-Ke" ruby' let g:syntastic_c_pc_lint_exec = "wine"
let g:syntastic_c_pc_lint_exe = "wine c:/path/to/lint-nt.exe"
< <
To override the args and the tail: > To override the args and the tail: >
let g:syntastic_ruby_mri_args = "--my --args --here" let g:syntastic_c_pc_lint_args = "-w5 -Iz:/usr/include/linux"
let g:syntastic_ruby_mri_tail = "> /tmp/my-output-file-biatch" let g:syntastic_c_pc_lint_tail = "2>/dev/null"
< <
The general form of the override options is: > The general form of the override options is: >
syntastic_<filetype>_<subchecker>_<option-name> syntastic_<filetype>_<checker>_<option-name>
< <
For checkers that do not use the 'makeprgBuild()' function you will have to For checkers that do not use the 'makeprgBuild()' function you will have to
look at the source code of the checker in question. If there are specific look at the source code of the checker in question. If there are specific
@ -621,37 +692,65 @@ See |syntastic_quiet_messages| for the syntax.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
6.1. Handling of composite filetypes *syntastic-composite* 6.1. Handling of composite filetypes *syntastic-composite*
Some Vim plugins use composite filetypes, such as 'django.python' or Some Vim plugins use composite filetypes, such as "django.python" or
'handlebars.html'. Normally, syntastic deals with this situation by splitting "handlebars.html". Normally, syntastic deals with this situation by splitting
the filetype in its simple components, and calling all checkers that apply. the filetype in its simple components, and calling all checkers that apply.
If this behaviour is not desirable, you can disable it by mapping the If this behaviour is not desirable, you can disable it by mapping the
composite filetypes to a simple ones using |syntastic_filetype_map|, e.g.: > composite filetypes to a simple ones using |syntastic_filetype_map|, e.g.: >
let g:syntastic_filetype_map = { 'handlebars.html': 'handlebars' } let g:syntastic_filetype_map = { "handlebars.html": "handlebars" }
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
6.2 Interaction with python-mode *syntastic-pymode* 6.2 Editing files over network *syntastic-netrw*
The standard plugin |netrw| allows Vim to transparently edit files over
network and inside archives. Currently syntastic doesn't support this mode
of operation. It can only check files that can be accessed directly by local
checkers, without any translation or conversion.
------------------------------------------------------------------------------
6.3 Interaction with 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
default when you save buffers to disk, and this is probably not what you want. default when you save buffers to disk, and this is probably not what you want.
To avoid both plugins opening error windows, you can either set passive mode To avoid both plugins opening error windows, you can either set passive mode
for python in syntastic (see |syntastic_mode_map|), or disable lint checks in for python in syntastic (see |syntastic_mode_map|), or disable lint checks in
python-mode, by setting |pymode_lint_write| to 0. E.g.: > 'python-mode', by setting |pymode_lint_write| to 0. E.g.: >
let g:pymode_lint_write = 0 let g:pymode_lint_write = 0
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
6.3 Interaction with the fish shell *syntastic-fish* 6.4 Interaction with YouCompleteMe *syntastic-ycm*
Syntastic can be used together with the 'YouCompleteMe' Vim plugin (see
http://valloric.github.io/YouCompleteMe/). However, by default 'YouCompleteMe'
disables syntastic"s checkers for the "c", "cpp", "objc", and "objcpp"
filetypes, in order to allow its own checkers to run. If you want to use YCM's
identifier completer but still run syntastic's checkers for those filetypes you
have to set |ycm_show_diagnostics_ui| to 0. E.g.: >
let g:ycm_show_diagnostics_ui = 0
<
------------------------------------------------------------------------------
6.5 Interaction with the fish shell *syntastic-fish*
At the time of this writing the 'fish' shell (see http://fishshell.com/) At the time of this writing the 'fish' shell (see http://fishshell.com/)
doesn't support the standard UNIX syntax for file redirections, and thus it doesn't support the standard UNIX syntax for file redirections, and thus it
can't be used together with syntastic. You don't need to change your login can't be used together with syntastic. You don't need to change your login
shell to address this problem, but you do have to point Vim's 'shell' to a more shell to address this problem, but you do have to point Vim's 'shell' to a more
traditional shell, such as 'zsh', 'bash', 'ksh', or even the original Bourne traditional shell, such as "zsh", "bash", "ksh", or even the original Bourne
'sh': > "sh": >
set shell=bash set shell=bash
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
6.4. Using syntastic with the fizsh shell *syntastic-fizsh* 6.6. Interaction with PowerShell *syntastic-powershell*
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
'shell'. You may still run Vim from 'PowerShell', but you do have to point
Vim's 'shell' to a more traditional program, such as 'cmd.exe': >
set shell=cmd.exe
<
------------------------------------------------------------------------------
6.7. Using syntastic with the fizsh shell *syntastic-fizsh*
Using syntastic with the 'fizsh' shell (see https://github.com/zsh-users/fizsh) Using syntastic with the 'fizsh' shell (see https://github.com/zsh-users/fizsh)
is possible, but potentially problematic. In order to do it you'll need to set is possible, but potentially problematic. In order to do it you'll need to set
@ -659,17 +758,34 @@ is possible, but potentially problematic. In order to do it you'll need to set
set shellredir=>%s\ 2>&1 set shellredir=>%s\ 2>&1
< <
Please keep in mind however that Vim can't take advantage of any of the Please keep in mind however that Vim can't take advantage of any of the
interactive features of 'fizsh'. Using a more traditional shell such as 'zsh', interactive features of 'fizsh'. Using a more traditional shell such as "zsh",
'bash', 'ksh', or the original Bourne 'sh' might be a better choice: > "bash", "ksh", or the original Bourne "sh" might be a better choice: >
set shell=zsh set shell=zsh
< <
------------------------------------------------------------------------------
6.8. Interaction with Eclim *syntastic-eclim*
As far as syntastic is concerned there shouldn't be any compatibility problems
with the 'Eclim' Vim plugin (see http://eclim.org/). However, at the time of
this writing there are several reports that 'Eclim' triggers a bug in Vim that
makes syntastic forget some of its configuration parameters. No solutions or
workarounds are known for now.
------------------------------------------------------------------------------
6.9. Interaction with vim-virtualenv *syntastic-vim-virtualenv*
At the time of this writing, syntastic can't run checkers installed
in Python virtual environments activated by 'vim-virtualenv' (see
https://github.com/jmcantrell/vim-virtualenv). This is a limitation of
'vim-virtualenv'.
============================================================================== ==============================================================================
7. About *syntastic-about* 7. About *syntastic-about*
The core maintainers of syntastic are: The core maintainers of syntastic are:
Martin Grenfell (github: scrooloose) Martin Grenfell (GitHub: scrooloose)
Gregor Uhlenheuer (github: kongo2002) Gregor Uhlenheuer (GitHub: kongo2002)
LCD 047 (github: lcd047) LCD 047 (GitHub: lcd047)
Find the latest version of syntastic at: Find the latest version of syntastic at:

View file

@ -16,13 +16,15 @@ let g:loaded_syntastic_plugin = 1
if has('reltime') if has('reltime')
let g:syntastic_start = reltime() let g:syntastic_start = reltime()
lockvar! g:syntastic_start
endif endif
let g:syntastic_version = '3.4.0' let g:syntastic_version = '3.5.0-37'
lockvar g:syntastic_version
" Sanity checks {{{1 " Sanity checks {{{1
for s:feature in ['autocmd', 'eval', 'modify_fname', 'quickfix', 'user_commands'] for s:feature in ['autocmd', 'eval', 'modify_fname', 'quickfix', 'reltime', '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
@ -30,6 +32,8 @@ for s:feature in ['autocmd', 'eval', 'modify_fname', 'quickfix', 'user_commands'
endfor endfor
let s:running_windows = syntastic#util#isRunningWindows() let s:running_windows = syntastic#util#isRunningWindows()
lockvar s:running_windows
if !s:running_windows && executable('uname') if !s:running_windows && executable('uname')
try try
let s:uname = system('uname') let s:uname = system('uname')
@ -37,6 +41,7 @@ if !s:running_windows && executable('uname')
call syntastic#log#error("your shell " . &shell . " doesn't use traditional UNIX syntax for redirections") call syntastic#log#error("your shell " . &shell . " doesn't use traditional UNIX syntax for redirections")
finish finish
endtry endtry
lockvar s:uname
endif endif
" }}}1 " }}}1
@ -51,24 +56,29 @@ let g:syntastic_defaults = {
\ 'bash_hack': 1, \ 'bash_hack': 1,
\ 'check_on_open': 0, \ 'check_on_open': 0,
\ 'check_on_wq': 1, \ 'check_on_wq': 1,
\ 'cursor_columns': 1,
\ 'debug': 0, \ 'debug': 0,
\ 'echo_current_error': 1, \ 'echo_current_error': 1,
\ 'enable_balloons': 1, \ 'enable_balloons': 1,
\ 'enable_highlighting': 1, \ 'enable_highlighting': 1,
\ 'enable_signs': 1, \ 'enable_signs': 1,
\ 'error_symbol': '>>', \ 'error_symbol': '>>',
\ 'exit_checks': !(s:running_windows && &shell =~? '\m\<cmd\.exe$'),
\ 'filetype_map': {}, \ 'filetype_map': {},
\ 'full_redraws': !(has('gui_running') || has('gui_macvim')), \ 'full_redraws': !(has('gui_running') || has('gui_macvim')),
\ 'id_checkers': 1, \ 'id_checkers': 1,
\ 'ignore_extensions': '\c\v^([gx]?z|lzma|bz2)$',
\ 'ignore_files': [], \ 'ignore_files': [],
\ 'loc_list_height': 10, \ 'loc_list_height': 10,
\ 'quiet_messages': {}, \ 'quiet_messages': {},
\ 'reuse_loc_lists': (v:version >= 704), \ 'reuse_loc_lists': 0,
\ 'sort_aggregated_errors': 1,
\ 'stl_format': '[Syntax: line:%F (%t)]', \ 'stl_format': '[Syntax: line:%F (%t)]',
\ 'style_error_symbol': 'S>', \ 'style_error_symbol': 'S>',
\ 'style_warning_symbol': 'S>', \ 'style_warning_symbol': 'S>',
\ 'warning_symbol': '>>' \ 'warning_symbol': '>>'
\ } \ }
lockvar! g:syntastic_defaults
for s:key in keys(g:syntastic_defaults) for s:key in keys(g:syntastic_defaults)
if !exists('g:syntastic_' . s:key) if !exists('g:syntastic_' . s:key)
@ -77,7 +87,7 @@ for s:key in keys(g:syntastic_defaults)
endfor endfor
if exists("g:syntastic_quiet_warnings") if exists("g:syntastic_quiet_warnings")
call syntastic#log#deprecationWarn("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', [])
if type(s:quiet_warnings) != type([]) if type(s:quiet_warnings) != type([])
@ -105,13 +115,19 @@ let s:debug_dump_options = [
if v:version > 703 || (v:version == 703 && has('patch446')) if v:version > 703 || (v:version == 703 && has('patch446'))
call add(s:debug_dump_options, 'shellxescape') call add(s:debug_dump_options, 'shellxescape')
endif endif
lockvar! s:debug_dump_options
" debug constants " debug constants
let g:SyntasticDebugTrace = 1 let g:SyntasticDebugTrace = 1
let g:SyntasticDebugLoclist = 2 lockvar g:SyntasticDebugTrace
let g:SyntasticDebugNotifications = 4 let g:SyntasticDebugLoclist = 2
let g:SyntasticDebugAutocommands = 8 lockvar g:SyntasticDebugLoclist
let g:SyntasticDebugVariables = 16 let g:SyntasticDebugNotifications = 4
lockvar g:SyntasticDebugNotifications
let g:SyntasticDebugAutocommands = 8
lockvar g:SyntasticDebugAutocommands
let g:SyntasticDebugVariables = 16
lockvar g:SyntasticDebugVariables
" }}}1 " }}}1
@ -129,7 +145,7 @@ let s:modemap = g:SyntasticModeMap.Instance()
function! s:CompleteCheckerName(argLead, cmdLine, cursorPos) " {{{2 function! s:CompleteCheckerName(argLead, cmdLine, cursorPos) " {{{2
let checker_names = [] let checker_names = []
for ft in s:resolveFiletypes() for ft in s:resolveFiletypes()
call extend(checker_names, keys(s:registry.getCheckersMap(ft))) call extend(checker_names, s:registry.getNamesOfAvailableCheckers(ft))
endfor endfor
return join(checker_names, "\n") return join(checker_names, "\n")
endfunction " }}}2 endfunction " }}}2
@ -154,7 +170,7 @@ command! -nargs=* -complete=custom,s:CompleteCheckerName SyntasticCheck
\ call syntastic#util#redraw(g:syntastic_full_redraws) \ call syntastic#util#redraw(g:syntastic_full_redraws)
command! Errors call s:ShowLocList() command! Errors call s:ShowLocList()
command! -nargs=? -complete=custom,s:CompleteFiletypes SyntasticInfo command! -nargs=? -complete=custom,s:CompleteFiletypes SyntasticInfo
\ call s:modemap.echoMode() | \ call s:modemap.modeInfo(<f-args>) |
\ call s:registry.echoInfoFor(s:resolveFiletypes(<f-args>)) \ call s:registry.echoInfoFor(s:resolveFiletypes(<f-args>))
command! SyntasticReset command! SyntasticReset
\ call s:ClearCache() | \ call s:ClearCache() |
@ -168,11 +184,6 @@ command! SyntasticSetLoclist call g:SyntasticLoclist.current().setloclist()
augroup syntastic augroup syntastic
autocmd BufReadPost * call s:BufReadPostHook() autocmd BufReadPost * call s:BufReadPostHook()
autocmd BufWritePost * call s:BufWritePostHook() autocmd BufWritePost * call s:BufWritePostHook()
autocmd BufWinEnter * call s:BufWinEnterHook()
" TODO: the next autocmd should be "autocmd BufWinLeave * if &buftype == '' | lclose | endif"
" but in recent versions of Vim lclose can no longer be called from BufWinLeave
autocmd BufEnter * call s:BufEnterHook() autocmd BufEnter * call s:BufEnterHook()
augroup END augroup END
@ -197,32 +208,30 @@ function! s:BufWritePostHook() " {{{2
call s:UpdateErrors(1) call s:UpdateErrors(1)
endfunction " }}}2 endfunction " }}}2
function! s:BufWinEnterHook() " {{{2
call syntastic#log#debug(g:SyntasticDebugAutocommands,
\ 'autocmd: BufWinEnter, buffer ' . bufnr("") . ' = ' . string(bufname(str2nr(bufnr("")))) .
\ ', &buftype = ' . string(&buftype))
if &buftype == ''
call s:notifiers.refresh(g:SyntasticLoclist.current())
endif
endfunction " }}}2
function! s:BufEnterHook() " {{{2 function! s:BufEnterHook() " {{{2
call syntastic#log#debug(g:SyntasticDebugAutocommands, call syntastic#log#debug(g:SyntasticDebugAutocommands,
\ 'autocmd: BufEnter, buffer ' . bufnr("") . ' = ' . string(bufname(str2nr(bufnr("")))) . \ 'autocmd: BufEnter, buffer ' . bufnr("") . ' = ' . string(bufname(str2nr(bufnr("")))) .
\ ', &buftype = ' . string(&buftype)) \ ', &buftype = ' . string(&buftype))
" TODO: at this point there is no b:syntastic_loclist if &buftype == ''
let loclist = filter(getloclist(0), 'v:val["valid"] == 1') call s:notifiers.refresh(g:SyntasticLoclist.current())
let buffers = syntastic#util#unique(map( loclist, 'v:val["bufnr"]' )) elseif &buftype == 'quickfix'
if &buftype == 'quickfix' && !empty(loclist) && empty(filter( buffers, 'syntastic#util#bufIsActive(v:val)' )) " TODO: this is needed because in recent versions of Vim lclose
call g:SyntasticLoclistHide() " can no longer be called from BufWinLeave
" TODO: at this point there is no b:syntastic_loclist
let loclist = filter(copy(getloclist(0)), 'v:val["valid"] == 1')
let owner = str2nr(getbufvar(bufnr(""), 'syntastic_owner_buffer'))
let buffers = syntastic#util#unique(map(loclist, 'v:val["bufnr"]') + (owner ? [owner] : []))
if !empty(loclist) && empty(filter( buffers, 'syntastic#util#bufIsActive(v:val)' ))
call SyntasticLoclistHide()
endif
endif endif
endfunction " }}}2 endfunction " }}}2
function! s:QuitPreHook() " {{{2 function! s:QuitPreHook() " {{{2
call syntastic#log#debug(g:SyntasticDebugAutocommands, call syntastic#log#debug(g:SyntasticDebugAutocommands,
\ 'autocmd: QuitPre, buffer ' . bufnr("") . ' = ' . string(bufname(str2nr(bufnr(""))))) \ 'autocmd: QuitPre, buffer ' . bufnr("") . ' = ' . string(bufname(str2nr(bufnr("")))))
let b:syntastic_skip_checks = !g:syntastic_check_on_wq let b:syntastic_skip_checks = get(b:, 'syntastic_skip_checks', 0) || !syntastic#util#var('check_on_wq')
call g:SyntasticLoclistHide() call SyntasticLoclistHide()
endfunction " }}}2 endfunction " }}}2
" }}}1 " }}}1
@ -231,6 +240,11 @@ endfunction " }}}2
"refresh and redraw all the error info for this buf when saving or reading "refresh and redraw all the error info for this buf when saving or reading
function! s:UpdateErrors(auto_invoked, ...) " {{{2 function! s:UpdateErrors(auto_invoked, ...) " {{{2
call syntastic#log#debugShowVariables(g:SyntasticDebugTrace, 'version')
call syntastic#log#debugShowOptions(g:SyntasticDebugTrace, s:debug_dump_options)
call syntastic#log#debugDump(g:SyntasticDebugVariables)
call syntastic#log#debug(g:SyntasticDebugTrace, 'UpdateErrors' . (a:auto_invoked ? ' (auto)' : '') .
\ ': ' . (a:0 ? join(a:000) : 'default checkers'))
if s:skipFile() if s:skipFile()
return return
endif endif
@ -277,26 +291,26 @@ endfunction " }}}2
"clear the loc list for the buffer "clear the loc list for the buffer
function! s:ClearCache() " {{{2 function! s:ClearCache() " {{{2
call s:notifiers.reset(g:SyntasticLoclist.current()) call s:notifiers.reset(g:SyntasticLoclist.current())
unlet! b:syntastic_loclist call b:syntastic_loclist.destroy()
endfunction " }}}2 endfunction " }}}2
"detect and cache all syntax errors in this buffer "detect and cache all syntax errors in this buffer
function! s:CacheErrors(checker_names) " {{{2 function! s:CacheErrors(checker_names) " {{{2
call syntastic#log#debug(g:SyntasticDebugTrace, 'CacheErrors: ' .
\ (len(a:checker_names) ? join(a:checker_names) : 'default checkers'))
call s:ClearCache() call s:ClearCache()
let newLoclist = g:SyntasticLoclist.New([]) let newLoclist = g:SyntasticLoclist.New([])
if !s:skipFile() if !s:skipFile()
" debug logging {{{3 " debug logging {{{3
call syntastic#log#debugShowVariables(g:SyntasticDebugTrace, 'version')
call syntastic#log#debugShowOptions(g:SyntasticDebugTrace, s:debug_dump_options)
call syntastic#log#debugDump(g:SyntasticDebugVariables)
call syntastic#log#debugShowVariables(g:SyntasticDebugTrace, 'aggregate_errors') call syntastic#log#debugShowVariables(g:SyntasticDebugTrace, 'aggregate_errors')
call syntastic#log#debug(g:SyntasticDebugTrace, 'getcwd() = ' . getcwd()) call syntastic#log#debug(g:SyntasticDebugTrace, 'getcwd() = ' . getcwd())
" }}}3 " }}}3
let filetypes = s:resolveFiletypes() let filetypes = s:resolveFiletypes()
let aggregate_errors = syntastic#util#var('aggregate_errors') let aggregate_errors = syntastic#util#var('aggregate_errors') || len(filetypes) > 1
let decorate_errors = (aggregate_errors || len(filetypes) > 1) && syntastic#util#var('id_checkers') let decorate_errors = aggregate_errors && syntastic#util#var('id_checkers')
let sort_aggregated_errors = aggregate_errors && syntastic#util#var('sort_aggregated_errors')
let clist = [] let clist = []
for type in filetypes for type in filetypes
@ -304,8 +318,15 @@ function! s:CacheErrors(checker_names) " {{{2
endfor endfor
let names = [] let names = []
let unavailable_checkers = 0
for checker in clist for checker in clist
let cname = checker.getFiletype() . '/' . checker.getName() let cname = checker.getFiletype() . '/' . checker.getName()
if !checker.isAvailable()
call syntastic#log#debug(g:SyntasticDebugTrace, 'CacheErrors: Checker ' . cname . ' is not available')
let unavailable_checkers += 1
continue
endif
call syntastic#log#debug(g:SyntasticDebugTrace, 'CacheErrors: Invoking checker: ' . cname) call syntastic#log#debug(g:SyntasticDebugTrace, 'CacheErrors: Invoking checker: ' . cname)
let loclist = checker.getLocList() let loclist = checker.getLocList()
@ -315,6 +336,10 @@ function! s:CacheErrors(checker_names) " {{{2
call loclist.decorate(cname) call loclist.decorate(cname)
endif endif
call add(names, cname) call add(names, cname)
if checker.getWantSort() && !sort_aggregated_errors
call loclist.sort()
call syntastic#log#debug(g:SyntasticDebugLoclist, 'sorted:', loclist)
endif
let newLoclist = newLoclist.extend(loclist) let newLoclist = newLoclist.extend(loclist)
@ -338,7 +363,7 @@ function! s:CacheErrors(checker_names) " {{{2
" }}}3 " }}}3
" issue warning about no active checkers {{{3 " issue warning about no active checkers {{{3
if empty(clist) if len(clist) == unavailable_checkers
if !empty(a:checker_names) if !empty(a:checker_names)
if len(a:checker_names) == 1 if len(a:checker_names) == 1
call syntastic#log#warn('checker ' . a:checker_names[0] . ' is not available') call syntastic#log#warn('checker ' . a:checker_names[0] . ' is not available')
@ -352,9 +377,13 @@ function! s:CacheErrors(checker_names) " {{{2
" }}}3 " }}}3
call syntastic#log#debug(g:SyntasticDebugLoclist, 'aggregated:', newLoclist) call syntastic#log#debug(g:SyntasticDebugLoclist, 'aggregated:', newLoclist)
if sort_aggregated_errors
call newLoclist.sort()
call syntastic#log#debug(g:SyntasticDebugLoclist, 'sorted:', newLoclist)
endif
endif endif
let b:syntastic_loclist = newLoclist call newLoclist.deploy()
endfunction " }}}2 endfunction " }}}2
function! s:ToggleMode() " {{{2 function! s:ToggleMode() " {{{2
@ -385,7 +414,9 @@ endfunction " }}}2
" 'preprocess' - a function to be applied to the error file before parsing errors " 'preprocess' - a function to be applied to the error file before parsing errors
" 'postprocess' - a list of functions to be applied to the error list " 'postprocess' - a list of functions to be applied to the error list
" 'cwd' - change directory to the given path before running the checker " 'cwd' - change directory to the given path before running the checker
" 'env' - environment variables to set before running the checker
" 'returns' - a list of valid exit codes for the checker " 'returns' - a list of valid exit codes for the checker
" @vimlint(EVL102, 1, l:env_save)
function! SyntasticMake(options) " {{{2 function! SyntasticMake(options) " {{{2
call syntastic#log#debug(g:SyntasticDebugTrace, 'SyntasticMake: called with options:', a:options) call syntastic#log#debug(g:SyntasticDebugTrace, 'SyntasticMake: called with options:', a:options)
@ -409,11 +440,31 @@ function! SyntasticMake(options) " {{{2
execute 'lcd ' . fnameescape(a:options['cwd']) execute 'lcd ' . fnameescape(a:options['cwd'])
endif endif
" set environment variables {{{3
let env_save = {}
if has_key(a:options, 'env') && len(a:options['env'])
for key in keys(a:options['env'])
if key =~? '\m^[a-z_]\+$'
exec 'let env_save[' . string(key) . '] = $' . key
exec 'let $' . key . ' = ' . string(a:options['env'][key])
endif
endfor
endif
let $LC_MESSAGES = 'C' let $LC_MESSAGES = 'C'
let $LC_ALL = '' let $LC_ALL = ''
" }}}3
let err_lines = split(system(a:options['makeprg']), "\n", 1) let err_lines = split(system(a:options['makeprg']), "\n", 1)
" restore environment variables {{{3
let $LC_ALL = old_lc_all let $LC_ALL = old_lc_all
let $LC_MESSAGES = old_lc_messages let $LC_MESSAGES = old_lc_messages
if len(env_save)
for key in keys(env_save)
exec 'let $' . key . ' = ' . string(env_save[key])
endfor
endif
" }}}3
call syntastic#log#debug(g:SyntasticDebugLoclist, 'checker output:', err_lines) call syntastic#log#debug(g:SyntasticDebugLoclist, 'checker output:', err_lines)
@ -432,7 +483,15 @@ function! SyntasticMake(options) " {{{2
execute 'lcd ' . fnameescape(old_cwd) execute 'lcd ' . fnameescape(old_cwd)
endif endif
silent! lolder try
silent lolder
catch /\m^Vim\%((\a\+)\)\=:E380/
" E380: At bottom of quickfix stack
call setloclist(0, [], 'r')
catch /\m^Vim\%((\a\+)\)\=:E776/
" E776: No location list
" do nothing
endtry
" restore options {{{3 " restore options {{{3
let &errorformat = old_errorformat let &errorformat = old_errorformat
@ -447,7 +506,7 @@ function! SyntasticMake(options) " {{{2
call syntastic#log#debug(g:SyntasticDebugLoclist, 'raw loclist:', errors) call syntastic#log#debug(g:SyntasticDebugLoclist, 'raw loclist:', errors)
if has_key(a:options, 'returns') && index(a:options['returns'], v:shell_error) == -1 if syntastic#util#var('exit_checks') && has_key(a:options, 'returns') && index(a:options['returns'], v:shell_error) == -1
throw 'Syntastic: checker error' throw 'Syntastic: checker error'
endif endif
@ -474,6 +533,7 @@ function! SyntasticMake(options) " {{{2
return errors return errors
endfunction " }}}2 endfunction " }}}2
" @vimlint(EVL102, 0, l:env_save)
"return a string representing the state of buffer according to "return a string representing the state of buffer according to
"g:syntastic_stl_format "g:syntastic_stl_format
@ -504,9 +564,14 @@ endfunction " }}}2
" Skip running in special buffers " Skip running in special buffers
function! s:skipFile() " {{{2 function! s:skipFile() " {{{2
let force_skip = exists('b:syntastic_skip_checks') ? b:syntastic_skip_checks : 0
let fname = expand('%') let fname = expand('%')
return force_skip || (&buftype != '') || !filereadable(fname) || getwinvar(0, '&diff') || s:ignoreFile(fname) let skip = get(b:, 'syntastic_skip_checks', 0) || (&buftype != '') ||
\ !filereadable(fname) || getwinvar(0, '&diff') || s:ignoreFile(fname) ||
\ fnamemodify(fname, ':e') =~? g:syntastic_ignore_extensions
if skip
call syntastic#log#debug(g:SyntasticDebugTrace, 'skipFile: skipping')
endif
return skip
endfunction " }}}2 endfunction " }}}2
" Take a list of errors and add default values to them from a:options " Take a list of errors and add default values to them from a:options
@ -544,6 +609,7 @@ endfunction " }}}2
function! s:uname() " {{{2 function! s:uname() " {{{2
if !exists('s:uname') if !exists('s:uname')
let s:uname = system('uname') let s:uname = system('uname')
lockvar s:uname
endif endif
return s:uname return s:uname
endfunction " }}}2 endfunction " }}}2

View file

@ -43,6 +43,7 @@ endfunction " }}}2
" Reset the error balloons " Reset the error balloons
" @vimlint(EVL103, 1, a:loclist) " @vimlint(EVL103, 1, a:loclist)
function! g:SyntasticBalloonsNotifier.reset(loclist) " {{{2 function! g:SyntasticBalloonsNotifier.reset(loclist) " {{{2
let b:syntastic_balloons = {}
if has('balloon_eval') if has('balloon_eval')
call syntastic#log#debug(g:SyntasticDebugNotifications, 'balloons: reset') call syntastic#log#debug(g:SyntasticDebugNotifications, 'balloons: reset')
set nobeval set nobeval

View file

@ -13,6 +13,7 @@ function! g:SyntasticChecker.New(args) " {{{2
let newObj._filetype = a:args['filetype'] let newObj._filetype = a:args['filetype']
let newObj._name = a:args['name'] let newObj._name = a:args['name']
let newObj._exec = get(a:args, 'exec', newObj._name) let newObj._exec = get(a:args, 'exec', newObj._name)
let newObj._sort = 0
if has_key(a:args, 'redirect') if has_key(a:args, 'redirect')
let [filetype, name] = split(a:args['redirect'], '/') let [filetype, name] = split(a:args['redirect'], '/')
@ -45,11 +46,9 @@ function! g:SyntasticChecker.getName() " {{{2
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticChecker.getExec() " {{{2 function! g:SyntasticChecker.getExec() " {{{2
if exists('g:syntastic_' . self._filetype . '_' . self._name . '_exec') return
return expand(g:syntastic_{self._filetype}_{self._name}_exec) \ expand( exists('b:syntastic_' . self._name . '_exec') ? b:syntastic_{self._name}_exec :
endif \ syntastic#util#var(self._filetype . '_' . self._name . '_exec', self._exec) )
return self._exec
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticChecker.getExecEscaped() " {{{2 function! g:SyntasticChecker.getExecEscaped() " {{{2
@ -75,6 +74,14 @@ function! g:SyntasticChecker.getLocList() " {{{2
return g:SyntasticLoclist.New(self.getLocListRaw()) return g:SyntasticLoclist.New(self.getLocListRaw())
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticChecker.getWantSort() " {{{2
return self._sort
endfunction " }}}2
function! g:SyntasticChecker.setWantSort(val) " {{{2
let self._sort = a:val
endfunction " }}}2
function! g:SyntasticChecker.makeprgBuild(opts) " {{{2 function! g:SyntasticChecker.makeprgBuild(opts) " {{{2
let basename = self._filetype . '_' . self._name . '_' let basename = self._filetype . '_' . self._name . '_'
@ -89,7 +96,10 @@ function! g:SyntasticChecker.makeprgBuild(opts) " {{{2
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticChecker.isAvailable() " {{{2 function! g:SyntasticChecker.isAvailable() " {{{2
return self._isAvailableFunc() if !has_key(self, '_available')
let self._available = self._isAvailableFunc()
endif
return self._available
endfunction " }}}2 endfunction " }}}2
" }}}1 " }}}1
@ -126,7 +136,7 @@ function! g:SyntasticChecker._populateHighlightRegexes(errors) " {{{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 len(term) > 0 if term != ''
let e['hl'] = term let e['hl'] = term
endif endif
endif endif
@ -135,10 +145,9 @@ function! g:SyntasticChecker._populateHighlightRegexes(errors) " {{{2
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticChecker._getOpt(opts, basename, name, default) " {{{2 function! g:SyntasticChecker._getOpt(opts, basename, name, default) " {{{2
let user_val = syntastic#util#var(a:basename . a:name)
let ret = [] let ret = []
call extend( ret, self._shescape(get(a:opts, a:name . '_before', '')) ) call extend( ret, self._shescape(get(a:opts, a:name . '_before', '')) )
call extend( ret, self._shescape(user_val != '' ? user_val : get(a:opts, a:name, a:default)) ) call extend( ret, self._shescape(syntastic#util#var( a:basename . a:name, get(a:opts, a:name, a:default) )) )
call extend( ret, self._shescape(get(a:opts, a:name . '_after', '')) ) call extend( ret, self._shescape(get(a:opts, a:name . '_after', '')) )
return ret return ret

View file

@ -20,9 +20,10 @@ function! g:SyntasticCursorNotifier.refresh(loclist) " {{{2
if self.enabled() && !a:loclist.isEmpty() if self.enabled() && !a:loclist.isEmpty()
call syntastic#log#debug(g:SyntasticDebugNotifications, 'cursor: refresh') call syntastic#log#debug(g:SyntasticDebugNotifications, 'cursor: refresh')
let b:syntastic_messages = copy(a:loclist.messages(bufnr(''))) let b:syntastic_messages = copy(a:loclist.messages(bufnr('')))
let b:oldLine = -1 let b:syntastic_line = -1
let b:syntastic_cursor_columns = a:loclist.getCursorColumns()
autocmd! syntastic CursorMoved autocmd! syntastic CursorMoved
autocmd syntastic CursorMoved * call g:SyntasticRefreshCursor() autocmd syntastic CursorMoved * call SyntasticRefreshCursor()
endif endif
endfunction " }}}2 endfunction " }}}2
@ -31,7 +32,7 @@ function! g:SyntasticCursorNotifier.reset(loclist) " {{{2
call syntastic#log#debug(g:SyntasticDebugNotifications, 'cursor: reset') call syntastic#log#debug(g:SyntasticDebugNotifications, 'cursor: reset')
autocmd! syntastic CursorMoved autocmd! syntastic CursorMoved
unlet! b:syntastic_messages unlet! b:syntastic_messages
let b:oldLine = -1 let b:syntastic_line = -1
endfunction " }}}2 endfunction " }}}2
" @vimlint(EVL103, 0, a:loclist) " @vimlint(EVL103, 0, a:loclist)
@ -39,29 +40,99 @@ endfunction " }}}2
" Private methods {{{1 " Private methods {{{1
" The following defensive nonsense is needed because of the nature of autocmd function! SyntasticRefreshCursor() " {{{2
function! g:SyntasticRefreshCursor() " {{{2
if !exists('b:syntastic_messages') || empty(b:syntastic_messages) if !exists('b:syntastic_messages') || empty(b:syntastic_messages)
" file not checked " file not checked
return return
endif endif
if !exists('b:oldLine') if !exists('b:syntastic_line')
let b:oldLine = -1 let b:syntastic_line = -1
endif endif
let l = line('.') let l = line('.')
if l == b:oldLine let current_messages = get(b:syntastic_messages, l, {})
return
endif
let b:oldLine = l
if has_key(b:syntastic_messages, l) if !exists('b:syntastic_cursor_columns')
call syntastic#util#wideMsg(b:syntastic_messages[l]) let b:syntastic_cursor_columns = g:syntastic_cursor_columns
endif
if b:syntastic_cursor_columns
let c = virtcol('.')
if !exists('b:syntastic_idx')
let b:syntastic_idx = -1
endif
if s:_isSameIndex(l, b:syntastic_line, c, b:syntastic_idx, current_messages)
return
else
let b:syntastic_line = l
endif
if !empty(current_messages)
let b:syntastic_idx = s:_findIndex(c, current_messages)
call syntastic#util#wideMsg(current_messages[b:syntastic_idx].text)
else
let b:syntastic_idx = -1
echo
endif
else else
echo if l == b:syntastic_line
return
endif
let b:syntastic_line = l
if !empty(current_messages)
call syntastic#util#wideMsg(current_messages[0].text)
else
echo
endif
endif endif
endfunction " }}}2 endfunction " }}}2
" }}}1 " }}}1
" Private functions {{{1
function! s:_isSameIndex(line, old_line, column, idx, messages) " {{{2
if a:old_line >= 0 && a:line == a:old_line && a:idx >= 0
if len(a:messages) <= 1
return 1
endif
if a:messages[a:idx].scol <= a:column || a:idx == 0
if a:idx == len(a:messages) - 1 || a:column < a:messages[a:idx + 1].scol
return 1
else
return 0
endif
else
return 0
endif
else
return 0
endif
endfunction " }}}2
function! s:_findIndex(column, messages) " {{{2
let max = len(a:messages) - 1
if max == 0
return 0
endif
let min = 0
" modified binary search: assign index 0 to columns to the left of the first error
while min < max - 1
let mid = (min + max) / 2
if a:column < a:messages[mid].scol
let max = mid
else
let min = mid
endif
endwhile
return a:column < a:messages[max].scol ? min : max
endfunction " }}}2
" }}}1
" vim: set sw=4 sts=4 et fdm=marker: " vim: set sw=4 sts=4 et fdm=marker:

View file

@ -5,6 +5,7 @@ let g:loaded_syntastic_notifier_highlighting = 1
" Highlighting requires getmatches introduced in 7.1.040 " Highlighting requires getmatches introduced in 7.1.040
let s:has_highlighting = v:version > 701 || (v:version == 701 && has('patch040')) let s:has_highlighting = v:version > 701 || (v:version == 701 && has('patch040'))
lockvar s:has_highlighting
let g:SyntasticHighlightingNotifier = {} let g:SyntasticHighlightingNotifier = {}
@ -18,6 +19,7 @@ function! g:SyntasticHighlightingNotifier.New() " {{{2
if !s:setup_done if !s:setup_done
call self._setup() call self._setup()
let s:setup_done = 1 let s:setup_done = 1
lockvar s:setup_done
endif endif
return newObj return newObj
@ -30,12 +32,12 @@ endfunction " }}}2
" Sets error highlights in the cuirrent window " Sets error highlights in the cuirrent window
function! g:SyntasticHighlightingNotifier.refresh(loclist) " {{{2 function! g:SyntasticHighlightingNotifier.refresh(loclist) " {{{2
if self.enabled() if self.enabled()
call self.reset(a:loclist)
call syntastic#log#debug(g:SyntasticDebugNotifications, 'highlighting: refresh') call syntastic#log#debug(g:SyntasticDebugNotifications, 'highlighting: refresh')
call self._reset()
let buf = bufnr('') let buf = bufnr('')
let issues = filter(a:loclist.copyRaw(), 'v:val["bufnr"] == buf') let issues = filter(a:loclist.copyRaw(), 'v:val["bufnr"] == buf')
for item in issues for item in issues
let group = item['type'] ==? 'E' ? 'SyntasticError' : 'SyntasticWarning' let group = 'Syntastic' . get(item, 'subtype', '') . ( item['type'] ==? 'E' ? 'Error' : 'Warning' )
" The function `Syntastic_{filetype}_{checker}_GetHighlightRegex` is " The function `Syntastic_{filetype}_{checker}_GetHighlightRegex` is
" used to override default highlighting. " used to override default highlighting.
@ -62,11 +64,7 @@ endfunction " }}}2
function! g:SyntasticHighlightingNotifier.reset(loclist) " {{{2 function! g:SyntasticHighlightingNotifier.reset(loclist) " {{{2
if s:has_highlighting if s:has_highlighting
call syntastic#log#debug(g:SyntasticDebugNotifications, 'highlighting: reset') call syntastic#log#debug(g:SyntasticDebugNotifications, 'highlighting: reset')
for match in getmatches() call self._reset()
if stridx(match['group'], 'Syntastic') == 0
call matchdelete(match['id'])
endif
endfor
endif endif
endfunction " }}}2 endfunction " }}}2
" @vimlint(EVL103, 0, a:loclist) " @vimlint(EVL103, 0, a:loclist)
@ -80,14 +78,27 @@ function! g:SyntasticHighlightingNotifier._setup() " {{{2
if s:has_highlighting if s:has_highlighting
if !hlexists('SyntasticError') if !hlexists('SyntasticError')
highlight link SyntasticError SpellBad highlight link SyntasticError SpellBad
endif endif
if !hlexists('SyntasticWarning') if !hlexists('SyntasticWarning')
highlight link SyntasticWarning SpellCap highlight link SyntasticWarning SpellCap
endif endif
if !hlexists('SyntasticStyleError')
highlight link SyntasticStyleError SyntasticError
endif
if !hlexists('SyntasticStyleWarning')
highlight link SyntasticStyleWarning SyntasticWarning
endif
endif endif
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticHighlightingNotifier._reset() " {{{2
for match in getmatches()
if stridx(match['group'], 'Syntastic') == 0
call matchdelete(match['id'])
endif
endfor
endfunction " }}}2
" }}}1 " }}}1
" vim: set sw=4 sts=4 et fdm=marker: " vim: set sw=4 sts=4 et fdm=marker:

View file

@ -20,12 +20,15 @@ function! g:SyntasticLoclist.New(rawLoclist) " {{{2
let newObj._rawLoclist = llist let newObj._rawLoclist = llist
let newObj._name = '' let newObj._name = ''
let newObj._owner = bufnr('')
let newObj._sorted = 0
let newObj._columns = g:syntastic_cursor_columns
return newObj return newObj
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticLoclist.current() " {{{2 function! g:SyntasticLoclist.current() " {{{2
if !exists("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
@ -37,10 +40,30 @@ function! g:SyntasticLoclist.extend(other) " {{{2
return g:SyntasticLoclist.New(list) return g:SyntasticLoclist.New(list)
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticLoclist.sort() " {{{2
if !self._sorted
for e in self._rawLoclist
call s:_setScreenColumn(e)
endfor
call sort(self._rawLoclist, self._columns ? 's:_compareErrorItemsByColumns' : 's:_compareErrorItemsByLines')
let self._sorted = 1
endif
endfunction " }}}2
function! g:SyntasticLoclist.isEmpty() " {{{2 function! g:SyntasticLoclist.isEmpty() " {{{2
return empty(self._rawLoclist) return empty(self._rawLoclist)
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticLoclist.isNewerThan(stamp) " {{{2
if !exists("self._stamp")
let self._stamp = []
return 0
endif
return syntastic#util#compareLexi(self._stamp, a:stamp) > 0
endfunction " }}}2
function! g:SyntasticLoclist.copyRaw() " {{{2 function! g:SyntasticLoclist.copyRaw() " {{{2
return copy(self._rawLoclist) return copy(self._rawLoclist)
endfunction " }}}2 endfunction " }}}2
@ -49,6 +72,14 @@ function! g:SyntasticLoclist.getRaw() " {{{2
return self._rawLoclist return self._rawLoclist
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticLoclist.getBuffers() " {{{2
return syntastic#util#unique(map(copy(self._rawLoclist), 'str2nr(v:val["bufnr"])') + [self._owner])
endfunction " }}}2
function! g:SyntasticLoclist.getCursorColumns() " {{{2
return self._columns
endfunction " }}}2
function! g:SyntasticLoclist.getStatuslineFlag() " {{{2 function! g:SyntasticLoclist.getStatuslineFlag() " {{{2
if !exists("self._stl_format") if !exists("self._stl_format")
let self._stl_format = '' let self._stl_format = ''
@ -114,6 +145,28 @@ function! g:SyntasticLoclist.setName(name) " {{{2
let self._name = a:name let self._name = a:name
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticLoclist.getOwner() " {{{2
return self._owner
endfunction " }}}2
function! g:SyntasticLoclist.setOwner(buffer) " {{{2
let self._owner = type(a:buffer) == type(0) ? a:buffer : str2nr(a:buffer)
endfunction " }}}2
function! g:SyntasticLoclist.deploy() " {{{2
call self.setOwner(bufnr(''))
let self._stamp = syntastic#util#stamp()
for buf in self.getBuffers()
call setbufvar(buf, 'syntastic_loclist', self)
endfor
endfunction " }}}2
function! g:SyntasticLoclist.destroy() " {{{2
for buf in self.getBuffers()
call setbufvar(buf, 'syntastic_loclist', {})
endfor
endfunction " }}}2
function! g:SyntasticLoclist.decorate(tag) " {{{2 function! g:SyntasticLoclist.decorate(tag) " {{{2
for e in self._rawLoclist for e in self._rawLoclist
let e['text'] .= ' [' . a:tag . ']' let e['text'] .= ' [' . a:tag . ']'
@ -144,8 +197,8 @@ endfunction " }}}2
function! g:SyntasticLoclist.messages(buf) " {{{2 function! g:SyntasticLoclist.messages(buf) " {{{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()
for e in errors for e in errors
let b = e['bufnr'] let b = e['bufnr']
let l = e['lnum'] let l = e['lnum']
@ -155,9 +208,32 @@ function! g:SyntasticLoclist.messages(buf) " {{{2
endif endif
if !has_key(self._cachedMessages[b], l) if !has_key(self._cachedMessages[b], l)
let self._cachedMessages[b][l] = e['text'] let self._cachedMessages[b][l] = [e]
elseif self._columns
call add(self._cachedMessages[b][l], e)
endif endif
endfor endfor
if self._columns
if !self._sorted
for b in keys(self._cachedMessages)
for l in keys(self._cachedMessages[b])
if len(self._cachedMessages[b][l]) > 1
for e in self._cachedMessages[b][l]
call s:_setScreenColumn(e)
endfor
call sort(self._cachedMessages[b][l], 's:_compareErrorItemsByColumns')
endif
endfor
endfor
endif
for b in keys(self._cachedMessages)
for l in keys(self._cachedMessages[b])
call s:_removeShadowedItems(self._cachedMessages[b][l])
endfor
endfor
endif
endif endif
return get(self._cachedMessages, a:buf, {}) return get(self._cachedMessages, a:buf, {})
@ -171,7 +247,7 @@ endfunction " }}}2
" "
"Note that all comparisons are done with ==? "Note that all comparisons are done with ==?
function! g:SyntasticLoclist.filter(filters) " {{{2 function! g:SyntasticLoclist.filter(filters) " {{{2
let conditions = values(map(copy(a:filters), 's:translate(v:key, v:val)')) let conditions = values(map(copy(a:filters), 's:_translate(v:key, v:val)'))
let filter = len(conditions) == 1 ? let filter = len(conditions) == 1 ?
\ conditions[0] : join(map(conditions, '"(" . v:val . ")"'), ' && ') \ conditions[0] : join(map(conditions, '"(" . v:val . ")"'), ' && ')
return filter(copy(self._rawLoclist), filter) return filter(copy(self._rawLoclist), filter)
@ -212,6 +288,7 @@ function! g:SyntasticLoclist.show() " {{{2
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)
endif endif
endif endif
endfor endfor
@ -222,7 +299,7 @@ endfunction " }}}2
" Non-method functions {{{1 " Non-method functions {{{1
function! g:SyntasticLoclistHide() " {{{2 function! SyntasticLoclistHide() " {{{2
call syntastic#log#debug(g:SyntasticDebugNotifications, 'loclist: hide') call syntastic#log#debug(g:SyntasticDebugNotifications, 'loclist: hide')
silent! lclose silent! lclose
endfunction " }}}2 endfunction " }}}2
@ -231,10 +308,93 @@ endfunction " }}}2
" Private functions {{{1 " Private functions {{{1
function! s:translate(key, val) " {{{2 function! s:_translate(key, val) " {{{2
return 'get(v:val, ' . string(a:key) . ', "") ==? ' . string(a:val) return 'get(v:val, ' . string(a:key) . ', "") ==? ' . string(a:val)
endfunction " }}}2 endfunction " }}}2
function! s:_setScreenColumn(item) " {{{2
if !has_key(a:item, 'scol')
let col = get(a:item, 'col', 0)
if col != 0 && get(a:item, 'vcol', 0) == 0
let buf = str2nr(a:item['bufnr'])
try
let line = getbufline(buf, a:item['lnum'])[0]
catch /\m^Vim\%((\a\+)\)\=:E684/
let line = ''
endtry
let a:item['scol'] = syntastic#util#screenWidth(strpart(line, 0, col), getbufvar(buf, '&tabstop'))
else
let a:item['scol'] = col
endif
endif
endfunction " }}}2
function! s:_removeShadowedItems(errors) " {{{2
" keep only the first message at a given column
let i = 0
while i < len(a:errors) - 1
let j = i + 1
let dupes = 0
while j < len(a:errors) && a:errors[j].scol == a:errors[i].scol
let dupes = 1
let j += 1
endwhile
if dupes
call remove(a:errors, i + 1, j - 1)
endif
let i += 1
endwhile
" merge messages with the same text
let i = 0
while i < len(a:errors) - 1
let j = i + 1
let dupes = 0
while j < len(a:errors) && a:errors[j].text == a:errors[i].text
let dupes = 1
let j += 1
endwhile
if dupes
call remove(a:errors, i + 1, j - 1)
endif
let i += 1
endwhile
endfunction " }}}2
function! s:_compareErrorItemsByColumns(a, b) " {{{2
if a:a['bufnr'] != a:b['bufnr']
" group by file
return a:a['bufnr'] - a:b['bufnr']
elseif a:a['lnum'] != a:b['lnum']
" sort by line
return a:a['lnum'] - a:b['lnum']
elseif a:a['scol'] != a:b['scol']
" sort by screen column
return a:a['scol'] - a:b['scol']
elseif a:a['type'] !=? a:b['type']
" errors take precedence over warnings
return a:a['type'] ==? 'E' ? -1 : 1
else
return 0
endif
endfunction " }}}2
function! s:_compareErrorItemsByLines(a, b) " {{{2
if a:a['bufnr'] != a:b['bufnr']
" group by file
return a:a['bufnr'] - a:b['bufnr']
elseif a:a['lnum'] != a:b['lnum']
" sort by line
return a:a['lnum'] - a:b['lnum']
elseif a:a['type'] !=? a:b['type']
" errors take precedence over warnings
return a:a['type'] ==? 'E' ? -1 : 1
else
" sort by screen column
return a:a['scol'] - a:b['scol']
endif
endfunction " }}}2
" }}}1 " }}}1
" vim: set sw=4 sts=4 et fdm=marker: " vim: set sw=4 sts=4 et fdm=marker:

View file

@ -19,8 +19,8 @@ endfunction " }}}2
function! g:SyntasticModeMap.synch() " {{{2 function! g:SyntasticModeMap.synch() " {{{2
if exists('g:syntastic_mode_map') if exists('g:syntastic_mode_map')
let self._mode = get(g:syntastic_mode_map, 'mode', 'active') let self._mode = get(g:syntastic_mode_map, 'mode', 'active')
let self._activeFiletypes = get(g:syntastic_mode_map, 'active_filetypes', []) let self._activeFiletypes = copy(get(g:syntastic_mode_map, 'active_filetypes', []))
let self._passiveFiletypes = get(g:syntastic_mode_map, 'passive_filetypes', []) let self._passiveFiletypes = copy(get(g:syntastic_mode_map, 'passive_filetypes', []))
else else
let self._mode = 'active' let self._mode = 'active'
let self._activeFiletypes = [] let self._activeFiletypes = []
@ -62,6 +62,27 @@ function! g:SyntasticModeMap.echoMode() " {{{2
echo "Syntastic: " . self._mode . " mode enabled" echo "Syntastic: " . self._mode . " mode enabled"
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticModeMap.modeInfo(...) " {{{2
echomsg 'Syntastic version: ' . g:syntastic_version
let type = a:0 ? a:1 : &filetype
echomsg 'Info for filetype: ' . type
call self.synch()
echomsg 'Mode: ' . self._mode
if self._mode ==# 'active'
if len(self._passiveFiletypes)
let plural = len(self._passiveFiletypes) != 1 ? 's' : ''
echomsg 'Passive filetype' . plural . ': ' . join(sort(copy(self._passiveFiletypes)))
endif
else
if len(self._activeFiletypes)
let plural = len(self._activeFiletypes) != 1 ? 's' : ''
echomsg 'Active filetype' . plural . ': ' . join(sort(copy(self._activeFiletypes)))
endif
endif
echomsg 'Filetype ' . type . ' is ' . (self.allowsAutoChecking(type) ? 'active' : 'passive')
endfunction " }}}2
" }}}1 " }}}1
" Private methods {{{1 " Private methods {{{1

View file

@ -6,6 +6,10 @@ let g:loaded_syntastic_notifiers = 1
let g:SyntasticNotifiers = {} let g:SyntasticNotifiers = {}
let s:notifier_types = ['signs', 'balloons', 'highlighting', 'cursor', 'autoloclist'] let s:notifier_types = ['signs', 'balloons', 'highlighting', 'cursor', 'autoloclist']
lockvar! s:notifier_types
let s:persistent_notifiers = ['signs', 'balloons']
lockvar! s:persistent_notifiers
" Public methods {{{1 " Public methods {{{1
@ -19,11 +23,27 @@ function! g:SyntasticNotifiers.Instance() " {{{2
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticNotifiers.refresh(loclist) " {{{2 function! g:SyntasticNotifiers.refresh(loclist) " {{{2
if !a:loclist.isEmpty() && !a:loclist.isNewerThan([])
" loclist not fully constructed yet
return
endif
call syntastic#log#debug(g:SyntasticDebugNotifications, 'notifiers: refresh') call syntastic#log#debug(g:SyntasticDebugNotifications, 'notifiers: refresh')
for type in self._enabled_types for type in self._enabled_types
let class = substitute(type, '\m.*', 'Syntastic\u&Notifier', '') let class = substitute(type, '\m.*', 'Syntastic\u&Notifier', '')
if !has_key(g:{class}, 'enabled') || self._notifier[type].enabled() if !has_key(g:{class}, 'enabled') || self._notifier[type].enabled()
call self._notifier[type].refresh(a:loclist) if index(s:persistent_notifiers, type) > -1
" refresh only if loclist has changed since last call
if !exists('b:syntastic_' . type . '_stamp')
let b:syntastic_{type}_stamp = []
endif
if a:loclist.isNewerThan(b:syntastic_{type}_stamp) || a:loclist.isEmpty()
call self._notifier[type].refresh(a:loclist)
let b:syntastic_{type}_stamp = syntastic#util#stamp()
endif
else
call self._notifier[type].refresh(a:loclist)
endif
endif endif
endfor endfor
endfunction " }}}2 endfunction " }}}2
@ -39,6 +59,11 @@ function! g:SyntasticNotifiers.reset(loclist) " {{{2
if has_key(g:{class}, 'reset') if has_key(g:{class}, 'reset')
call self._notifier[type].reset(a:loclist) call self._notifier[type].reset(a:loclist)
endif endif
" also reset stamps
if index(s:persistent_notifiers, type) > -1
let b:syntastic_{type}_stamp = []
endif
endfor endfor
endfunction " }}}2 endfunction " }}}2

View file

@ -9,10 +9,13 @@ let s:defaultCheckers = {
\ 'actionscript':['mxmlc'], \ 'actionscript':['mxmlc'],
\ 'ada': ['gcc'], \ 'ada': ['gcc'],
\ 'applescript': ['osacompile'], \ 'applescript': ['osacompile'],
\ 'arduino': ['avrgcc'],
\ 'asciidoc': ['asciidoc'], \ 'asciidoc': ['asciidoc'],
\ 'asm': ['gcc'], \ 'asm': ['gcc'],
\ 'bro': ['bro'],
\ 'bemhtml': ['bemhtmllint'], \ 'bemhtml': ['bemhtmllint'],
\ 'c': ['gcc'], \ 'c': ['gcc'],
\ 'cabal': ['cabal'],
\ 'chef': ['foodcritic'], \ 'chef': ['foodcritic'],
\ 'co': ['coco'], \ 'co': ['coco'],
\ 'cobol': ['cobc'], \ 'cobol': ['cobc'],
@ -27,7 +30,7 @@ let s:defaultCheckers = {
\ 'dart': ['dartanalyzer'], \ 'dart': ['dartanalyzer'],
\ 'docbk': ['xmllint'], \ 'docbk': ['xmllint'],
\ 'dustjs': ['swiffer'], \ 'dustjs': ['swiffer'],
\ 'elixir': ['elixir'], \ 'elixir': [],
\ 'erlang': ['escript'], \ 'erlang': ['escript'],
\ 'eruby': ['ruby'], \ 'eruby': ['ruby'],
\ 'fortran': ['gfortran'], \ 'fortran': ['gfortran'],
@ -60,19 +63,20 @@ let s:defaultCheckers = {
\ 'pod': ['podchecker'], \ 'pod': ['podchecker'],
\ 'puppet': ['puppet', 'puppetlint'], \ 'puppet': ['puppet', 'puppetlint'],
\ 'python': ['python', 'flake8', 'pylint'], \ 'python': ['python', 'flake8', 'pylint'],
\ 'r': [],
\ 'racket': ['racket'], \ 'racket': ['racket'],
\ 'rst': ['rst2pseudoxml'], \ 'rst': ['rst2pseudoxml'],
\ 'ruby': ['mri'], \ 'ruby': ['mri'],
\ 'rust': ['rustc'],
\ 'sass': ['sass'], \ 'sass': ['sass'],
\ 'scala': ['fsc', 'scalac'], \ 'scala': ['fsc', 'scalac'],
\ 'scss': ['sass', 'scss_lint'], \ 'scss': ['sass', 'scss_lint'],
\ 'sh': ['sh', 'shellcheck'], \ 'sh': ['sh', 'shellcheck'],
\ 'slim': ['slimrb'], \ 'slim': ['slimrb'],
\ 'spec': ['rpmlint'],
\ 'tcl': ['nagelfar'], \ 'tcl': ['nagelfar'],
\ 'tex': ['lacheck', 'chktex'], \ 'tex': ['lacheck', 'chktex'],
\ 'texinfo': ['makeinfo'], \ 'texinfo': ['makeinfo'],
\ 'text': ['atdtool'], \ 'text': [],
\ 'twig': ['twiglint'], \ 'twig': ['twiglint'],
\ 'typescript': ['tsc'], \ 'typescript': ['tsc'],
\ 'vala': ['valac'], \ 'vala': ['valac'],
@ -88,12 +92,15 @@ let s:defaultCheckers = {
\ 'zpt': ['zptlint'], \ 'zpt': ['zptlint'],
\ 'zsh': ['zsh', 'shellcheck'] \ 'zsh': ['zsh', 'shellcheck']
\ } \ }
lockvar! s:defaultCheckers
let s:defaultFiletypeMap = { let s:defaultFiletypeMap = {
\ 'gentoo-metadata': 'xml', \ 'gentoo-metadata': 'xml',
\ 'lhaskell': 'haskell', \ 'lhaskell': 'haskell',
\ 'litcoffee': 'coffee' \ 'litcoffee': 'coffee',
\ 'mail': 'text'
\ } \ }
lockvar! s:defaultFiletypeMap
let g:SyntasticRegistry = {} let g:SyntasticRegistry = {}
@ -101,14 +108,13 @@ let g:SyntasticRegistry = {}
" Public methods {{{1 " Public methods {{{1
" TODO: Handling of filetype aliases: all public methods take aliases as " Note: Handling of filetype aliases: all public methods take aliases as
" parameters, all private methods take normalized filetypes. Public methods " parameters, all private methods take normalized filetypes. Public methods
" are thus supposed to normalize filetypes before calling private methods. " are thus supposed to normalize filetypes before calling private methods.
function! g:SyntasticRegistry.Instance() " {{{2 function! g:SyntasticRegistry.Instance() " {{{2
if !exists('s:SyntasticRegistryInstance') if !exists('s:SyntasticRegistryInstance')
let s:SyntasticRegistryInstance = copy(self) let s:SyntasticRegistryInstance = copy(self)
let s:SyntasticRegistryInstance._checkerRaw = {}
let s:SyntasticRegistryInstance._checkerMap = {} let s:SyntasticRegistryInstance._checkerMap = {}
endif endif
@ -121,29 +127,23 @@ function! g:SyntasticRegistry.CreateAndRegisterChecker(args) " {{{2
call registry._registerChecker(checker) call registry._registerChecker(checker)
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticRegistry.isCheckable(ftalias) " {{{2 " Given a list of checker names hints_list, return a map name --> checker.
let ft = s:normaliseFiletype(a:ftalias) " If hints_list is empty, user settings are are used instead. Checkers are
call self._loadCheckers(ft) " not checked for availability (that is, the corresponding IsAvailable() are
return !empty(self._checkerMap[ft]) " not run).
endfunction " }}}2 function! g:SyntasticRegistry.getCheckers(ftalias, hints_list) " {{{2
let ft = s:_normaliseFiletype(a:ftalias)
call self._loadCheckersFor(ft)
function! g:SyntasticRegistry.getCheckersMap(ftalias) " {{{2 let checkers_map = self._checkerMap[ft]
let ft = s:normaliseFiletype(a:ftalias)
call self._loadCheckers(ft)
return self._checkerMap[ft]
endfunction " }}}2
function! g:SyntasticRegistry.getCheckers(ftalias, list) " {{{2
let checkers_map = self.getCheckersMap(a:ftalias)
if empty(checkers_map) if empty(checkers_map)
return [] return []
endif endif
let ft = s:normaliseFiletype(a:ftalias)
call self._checkDeprecation(ft) call self._checkDeprecation(ft)
let names = let names =
\ !empty(a:list) ? a:list : \ !empty(a:hints_list) ? syntastic#util#unique(a:hints_list) :
\ exists('b:syntastic_checkers') ? b:syntastic_checkers : \ exists('b:syntastic_checkers') ? b:syntastic_checkers :
\ exists('g:syntastic_' . ft . '_checkers') ? g:syntastic_{ft}_checkers : \ exists('g:syntastic_' . ft . '_checkers') ? g:syntastic_{ft}_checkers :
\ get(s:defaultCheckers, ft, 0) \ get(s:defaultCheckers, ft, 0)
@ -152,6 +152,12 @@ function! g:SyntasticRegistry.getCheckers(ftalias, list) " {{{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
" corresponding IsAvailable() functions for all checkers.
function! g:SyntasticRegistry.getCheckersAvailable(ftalias, hints_list) " {{{2
return filter(self.getCheckers(a:ftalias, a:hints_list), 'v:val.isAvailable()')
endfunction " }}}2
function! g:SyntasticRegistry.getKnownFiletypes() " {{{2 function! g:SyntasticRegistry.getKnownFiletypes() " {{{2
let types = keys(s:defaultCheckers) let types = keys(s:defaultCheckers)
@ -168,26 +174,37 @@ function! g:SyntasticRegistry.getKnownFiletypes() " {{{2
return syntastic#util#unique(types) return syntastic#util#unique(types)
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticRegistry.echoInfoFor(ftalias_list) " {{{2 function! g:SyntasticRegistry.getNamesOfAvailableCheckers(ftalias) " {{{2
echomsg "Syntastic info for filetype: " . join(a:ftalias_list, '.') let ft = s:_normaliseFiletype(a:ftalias)
call self._loadCheckersFor(ft)
return keys(filter( copy(self._checkerMap[ft]), 'v:val.isAvailable()' ))
endfunction " }}}2
let ft_list = syntastic#util#unique(map( copy(a:ftalias_list), 's:normaliseFiletype(v:val)' )) function! g:SyntasticRegistry.echoInfoFor(ftalias_list) " {{{2
let ft_list = syntastic#util#unique(map( copy(a:ftalias_list), 's:_normaliseFiletype(v:val)' ))
if len(ft_list) != 1 if len(ft_list) != 1
let available = [] let available = []
let active = [] let active = []
for ft in ft_list for ft in ft_list
call extend(available, map( keys(self.getCheckersMap(ft)), 'ft . "/" . v:val' )) call extend(available, map( self.getNamesOfAvailableCheckers(ft), 'ft . "/" . v:val' ))
call extend(active, map( self.getCheckers(ft, []), 'ft . "/" . v:val.getName()' )) call extend(active, map( self.getCheckersAvailable(ft, []), 'ft . "/" . v:val.getName()' ))
endfor endfor
else else
let ft = ft_list[0] let ft = ft_list[0]
let available = keys(self.getCheckersMap(ft)) let available = self.getNamesOfAvailableCheckers(ft)
let active = map(self.getCheckers(ft, []), 'v:val.getName()') let active = map(self.getCheckersAvailable(ft, []), 'v:val.getName()')
endif endif
echomsg "Available checker(s): " . join(sort(available)) let cnt = len(available)
echomsg "Currently enabled checker(s): " . join(active) let plural = cnt != 1 ? 's' : ''
let cklist = cnt ? join(sort(available)) : '-'
echomsg 'Available checker' . plural . ': ' . cklist
let cnt = len(active)
let plural = cnt != 1 ? 's' : ''
let cklist = cnt ? join(active) : '-'
echomsg 'Currently enabled checker' . plural . ': ' . cklist
endfunction " }}}2 endfunction " }}}2
" }}}1 " }}}1
@ -196,52 +213,39 @@ endfunction " }}}2
function! g:SyntasticRegistry._registerChecker(checker) abort " {{{2 function! g:SyntasticRegistry._registerChecker(checker) abort " {{{2
let ft = a:checker.getFiletype() let ft = a:checker.getFiletype()
if !has_key(self._checkerMap, ft)
if !has_key(self._checkerRaw, ft)
let self._checkerRaw[ft] = []
let self._checkerMap[ft] = {} let self._checkerMap[ft] = {}
endif endif
call self._validateUniqueName(a:checker)
let name = a:checker.getName() let name = a:checker.getName()
call add(self._checkerRaw[ft], name) if has_key(self._checkerMap[ft], name)
throw 'Syntastic: Duplicate syntax checker name: ' . ft . '/' . name
if a:checker.isAvailable()
let self._checkerMap[ft][name] = a:checker
endif endif
let self._checkerMap[ft][name] = a:checker
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticRegistry._filterCheckersByName(checkers_map, list) " {{{2 function! g:SyntasticRegistry._filterCheckersByName(checkers_map, list) " {{{2
return filter( map(copy(a:list), 'get(a:checkers_map, v:val, {})'), '!empty(v:val)' ) return filter( map(copy(a:list), 'get(a:checkers_map, v:val, {})'), '!empty(v:val)' )
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticRegistry._loadCheckers(filetype) " {{{2 function! g:SyntasticRegistry._loadCheckersFor(filetype) " {{{2
if has_key(self._checkerRaw, a:filetype) if has_key(self._checkerMap, a:filetype)
return return
endif endif
execute "runtime! syntax_checkers/" . a:filetype . "/*.vim" execute "runtime! syntax_checkers/" . a:filetype . "/*.vim"
if !has_key(self._checkerRaw, a:filetype) if !has_key(self._checkerMap, a:filetype)
let self._checkerRaw[a:filetype] = []
let self._checkerMap[a:filetype] = {} let self._checkerMap[a:filetype] = {}
endif endif
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticRegistry._validateUniqueName(checker) abort " {{{2
let ft = a:checker.getFiletype()
let name = a:checker.getName()
if index(self._checkerRaw[ft], name) > -1
throw 'Syntastic: Duplicate syntax checker name: ' . ft . '/' . name
endif
endfunction " }}}2
" Check for obsolete variable g:syntastic_<filetype>_checker " Check for obsolete variable g:syntastic_<filetype>_checker
function! g:SyntasticRegistry._checkDeprecation(filetype) " {{{2 function! g:SyntasticRegistry._checkDeprecation(filetype) " {{{2
if exists('g:syntastic_' . a:filetype . '_checker') && !exists('g:syntastic_' . a:filetype . '_checkers') if exists('g:syntastic_' . a:filetype . '_checker') && !exists('g:syntastic_' . a:filetype . '_checkers')
let g:syntastic_{a:filetype}_checkers = [g:syntastic_{a:filetype}_checker] let g:syntastic_{a:filetype}_checkers = [g:syntastic_{a:filetype}_checker]
call syntastic#log#deprecationWarn('variable g:syntastic_' . a:filetype . '_checker is deprecated') call syntastic#log#oneTimeWarn('variable g:syntastic_' . a:filetype . '_checker is deprecated')
endif endif
endfunction " }}}2 endfunction " }}}2
@ -251,7 +255,7 @@ endfunction " }}}2
"resolve filetype aliases, and replace - with _ otherwise we cant name "resolve filetype aliases, and replace - with _ otherwise we cant name
"syntax checker functions legally for filetypes like "gentoo-metadata" "syntax checker functions legally for filetypes like "gentoo-metadata"
function! s:normaliseFiletype(ftalias) " {{{2 function! s:_normaliseFiletype(ftalias) " {{{2
let ft = get(s:defaultFiletypeMap, a:ftalias, a:ftalias) let ft = get(s:defaultFiletypeMap, a:ftalias, a:ftalias)
let ft = get(g:syntastic_filetype_map, ft, ft) let ft = get(g:syntastic_filetype_map, ft, ft)
let ft = substitute(ft, '\m-', '_', 'g') let ft = substitute(ft, '\m-', '_', 'g')

View file

@ -25,6 +25,7 @@ function! g:SyntasticSignsNotifier.New() " {{{2
if !s:setup_done if !s:setup_done
call self._setup() call self._setup()
let s:setup_done = 1 let s:setup_done = 1
lockvar s:setup_done
endif endif
return newObj return newObj
@ -41,7 +42,6 @@ function! g:SyntasticSignsNotifier.refresh(loclist) " {{{2
call self._signErrors(a:loclist) call self._signErrors(a:loclist)
endif endif
call self._removeSigns(old_signs) call self._removeSigns(old_signs)
let s:first_sign_id = s:next_sign_id
endfunction " }}}2 endfunction " }}}2
" }}}1 " }}}1
@ -87,15 +87,20 @@ function! g:SyntasticSignsNotifier._signErrors(loclist) " {{{2
let loclist = a:loclist let loclist = a:loclist
if !loclist.isEmpty() if !loclist.isEmpty()
" errors some first, so that they are not masked by warnings
let buf = bufnr('') let buf = bufnr('')
if !bufloaded(buf)
" signs can be placed only in loaded buffers
return
endif
" errors come first, so that they are not masked by warnings
let issues = copy(loclist.errors()) let issues = copy(loclist.errors())
call extend(issues, loclist.warnings()) call extend(issues, loclist.warnings())
call filter(issues, 'v:val["bufnr"] == buf') call filter(issues, 'v:val["bufnr"] == buf')
let seen = {} let seen = {}
for i in issues for i in issues
if !has_key(seen, i['lnum']) if i['lnum'] > 0 && !has_key(seen, i['lnum'])
let seen[i['lnum']] = 1 let seen[i['lnum']] = 1
let sign_severity = i['type'] ==? 'W' ? 'Warning' : 'Error' let sign_severity = i['type'] ==? 'W' ? 'Warning' : 'Error'
@ -113,9 +118,9 @@ endfunction " }}}2
" Remove the signs with the given ids from this buffer " Remove the signs with the given ids from this buffer
function! g:SyntasticSignsNotifier._removeSigns(ids) " {{{2 function! g:SyntasticSignsNotifier._removeSigns(ids) " {{{2
if has('signs') if has('signs')
for i in a:ids for s in reverse(copy(a:ids))
execute "sign unplace " . i execute "sign unplace " . s
call remove(self._bufSignIds(), index(self._bufSignIds(), i)) call remove(self._bufSignIds(), index(self._bufSignIds(), s))
endfor endfor
endif endif
endfunction " }}}2 endfunction " }}}2

View file

@ -14,10 +14,6 @@ if exists('g:loaded_syntastic_actionscript_mxmlc_checker')
endif endif
let g:loaded_syntastic_actionscript_mxmlc_checker = 1 let g:loaded_syntastic_actionscript_mxmlc_checker = 1
if !exists('g:syntastic_actionscript_mxmlc_conf')
let g:syntastic_actionscript_mxmlc_conf = ''
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
@ -45,10 +41,10 @@ function! SyntaxCheckers_actionscript_mxmlc_GetHighlightRegex(item)
endfunction endfunction
function! SyntaxCheckers_actionscript_mxmlc_GetLocList() dict function! SyntaxCheckers_actionscript_mxmlc_GetLocList() dict
let makeprg = self.makeprgBuild({ call syntastic#log#deprecationWarn('actionscript_mxmlc_conf', 'actionscript_mxmlc_args',
\ 'args_before': (g:syntastic_actionscript_mxmlc_conf != '' ? \ "'-load-config+=' . syntastic#util#shexpand(OLD_VAR)")
\ ' -load-config+=' . g:syntastic_actionscript_mxmlc_conf : ''),
\ 'args_after': '-output=' . syntastic#util#DevNull() }) let makeprg = self.makeprgBuild({ 'args_after': '-output=' . syntastic#util#DevNull() })
let errorformat = let errorformat =
\ '%f(%l): col: %c %trror: %m,' . \ '%f(%l): col: %c %trror: %m,' .

View file

@ -8,7 +8,7 @@
" Want To Public License, Version 2, as published by Sam Hocevar. " Want To Public License, Version 2, as published by Sam Hocevar.
" 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
@ -29,6 +29,7 @@ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'name': 'bemhtmllint', \ 'name': 'bemhtmllint',
\ 'exec': 'bemhtml-lint' }) \ 'exec': 'bemhtml-lint' })
let &cpo = s:save_cpo let &cpo = s:save_cpo
unlet s:save_cpo unlet s:save_cpo
" vim: set et sts=4 sw=4:

View file

@ -53,3 +53,5 @@ call g:SyntasticRegistry.CreateAndRegisterChecker({
let &cpo = s:save_cpo let &cpo = s:save_cpo
unlet s:save_cpo unlet s:save_cpo
" vim: set et sts=4 sw=4:

View file

@ -14,24 +14,27 @@ if exists("g:loaded_syntastic_c_checkpatch_checker")
endif endif
let g:loaded_syntastic_c_checkpatch_checker = 1 let g:loaded_syntastic_c_checkpatch_checker = 1
" Bail if the user doesn't have `checkpatch.pl` or ./scripts/checkpatch.pl installed.
if executable("checkpatch.pl")
let g:syntastic_c_checker_checkpatch_location = 'checkpatch.pl'
elseif executable("./scripts/checkpatch.pl")
let g:syntastic_c_checker_checkpatch_location = './scripts/checkpatch.pl'
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_c_checkpatch_IsAvailable() dict function! SyntaxCheckers_c_checkpatch_IsAvailable() dict
return exists("g:syntastic_c_checker_checkpatch_location") call syntastic#log#deprecationWarn('c_checker_checkpatch_location', 'c_checkpatch_exe')
if !exists('g:syntastic_c_checkpatch_exe') && !executable(self.getExec())
if executable('checkpatch')
let g:syntastic_c_checkpatch_exe = 'checkpatch'
elseif executable('./scripts/checkpatch.pl')
let g:syntastic_c_checkpatch_exe = fnamemodify('./scripts/checkpatch.pl', ':p')
elseif executable('./scripts/checkpatch')
let g:syntastic_c_checkpatch_exe = fnamemodify('./scripts/checkpatch', ':p')
endif
endif
return executable(self.getExec())
endfunction endfunction
function! SyntaxCheckers_c_checkpatch_GetLocList() dict function! SyntaxCheckers_c_checkpatch_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({ 'args_after': '--no-summary --no-tree --terse --file' })
\ 'exe': g:syntastic_c_checker_checkpatch_location,
\ 'args_after': '--no-summary --no-tree --terse --file' })
let errorformat = let errorformat =
\ '%f:%l: %tARNING: %m,' . \ '%f:%l: %tARNING: %m,' .

View file

@ -19,7 +19,7 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_c_make_GetLocList() dict function! SyntaxCheckers_c_make_GetLocList() dict
let makeprg = self.getExecEscaped() . ' -sk' let makeprg = self.makeprgBuild({ 'args': '-sk', 'fname': '' })
let errorformat = let errorformat =
\ '%-G%f:%s:,' . \ '%-G%f:%s:,' .

View file

@ -30,24 +30,34 @@ set cpo&vim
function! SyntaxCheckers_c_oclint_GetLocList() dict function! SyntaxCheckers_c_oclint_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'args_after': '-text', \ 'post_args': '-- -c ' . syntastic#c#ReadConfig(g:syntastic_oclint_config_file) })
\ 'post_args_before': '-- -c ' . syntastic#c#ReadConfig(g:syntastic_oclint_config_file) })
let errorformat = let errorformat =
\ '%E%f:%l:%c: %m P1 ,' .
\ '%E%f:%l:%c: %m P2 ,' .
\ '%W%f:%l:%c: %m P3 ,' .
\ '%E%f:%l:%c: fatal error: %m,' . \ '%E%f:%l:%c: fatal error: %m,' .
\ '%E%f:%l:%c: error: %m,' . \ '%E%f:%l:%c: error: %m,' .
\ '%W%f:%l:%c: warning: %m,' . \ '%W%f:%l:%c: warning: %m,' .
\ '%E%f:%l:%c: %m,' .
\ '%-G%.%#' \ '%-G%.%#'
return SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'subtype': 'Style', \ 'subtype': 'Style',
\ 'postprocess': ['compressWhitespace', 'sort'], \ 'postprocess': ['compressWhitespace'],
\ 'returns': [0, 3, 5] }) \ 'returns': [0, 3, 5] })
for e in loclist
if e['text'] =~# '\v P3( |$)'
let e['type'] = 'W'
endif
let e['text'] = substitute(e['text'], '\m\C P[1-3]$', '', '')
let e['text'] = substitute(e['text'], '\m\C P[1-3] ', ': ', '')
endfor
call self.setWantSort(1)
return loclist
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -35,8 +35,11 @@ function! SyntaxCheckers_c_splint_GetLocList() dict
let errorformat = let errorformat =
\ '%-G%f:%l:%v: %[%#]%[%#]%[%#] Internal Bug %.%#,' . \ '%-G%f:%l:%v: %[%#]%[%#]%[%#] Internal Bug %.%#,' .
\ '%-G%f(%l\,%v): %[%#]%[%#]%[%#] Internal Bug %.%#,' .
\ '%W%f:%l:%v: %m,' . \ '%W%f:%l:%v: %m,' .
\ '%W%f(%l\,%v): %m,' .
\ '%W%f:%l: %m,' . \ '%W%f:%l: %m,' .
\ '%W%f(%l): %m,' .
\ '%-C %\+In file included from %.%#,' . \ '%-C %\+In file included from %.%#,' .
\ '%-C %\+from %.%#,' . \ '%-C %\+from %.%#,' .
\ '%+C %.%#' \ '%+C %.%#'

View file

@ -19,7 +19,8 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_co_coco_GetLocList() dict function! SyntaxCheckers_co_coco_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args_after': '-c -o /tmp' }) let tmpdir = $TMPDIR != '' ? $TMPDIR : $TMP != '' ? $TMP : '/tmp'
let makeprg = self.makeprgBuild({ 'args_after': '-c -o ' . tmpdir })
let errorformat = let errorformat =
\ '%EFailed at: %f,' . \ '%EFailed at: %f,' .

View file

@ -19,7 +19,11 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_coffee_coffeelint_GetLocList() dict function! SyntaxCheckers_coffee_coffeelint_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args_after': '--csv' }) if !exists('s:coffeelint_new')
let s:coffeelint_new = syntastic#util#versionIsAtLeast(syntastic#util#getVersion(
\ self.getExecEscaped() . ' --version'), [1, 4])
endif
let makeprg = self.makeprgBuild({ 'args_after': (s:coffeelint_new ? '--reporter csv' : '--csv') })
let errorformat = let errorformat =
\ '%f\,%l\,%\d%#\,%trror\,%m,' . \ '%f\,%l\,%\d%#\,%trror\,%m,' .

View file

@ -19,17 +19,13 @@ if exists('g:loaded_syntastic_css_csslint_checker')
endif endif
let g:loaded_syntastic_css_csslint_checker = 1 let g:loaded_syntastic_css_csslint_checker = 1
if !exists('g:syntastic_csslint_options')
let g:syntastic_csslint_options = ''
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_css_csslint_GetLocList() dict function! SyntaxCheckers_css_csslint_GetLocList() dict
let makeprg = self.makeprgBuild({ call syntastic#log#deprecationWarn('csslint_options', 'css_csslint_args')
\ 'args': g:syntastic_csslint_options,
\ 'args_after': '--format=compact' }) let makeprg = self.makeprgBuild({ 'args_after': '--format=compact' })
" Print CSS Lint's error/warning messages from compact format. Ignores blank lines. " Print CSS Lint's error/warning messages from compact format. Ignores blank lines.
let errorformat = let errorformat =

View file

@ -43,13 +43,14 @@ 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("")} })
\ 'postprocess': ['sort'] })
for e in loclist for e in loclist
let e["text"] .= ')' let e["text"] .= ')'
endfor endfor
call self.setWantSort(1)
return loclist return loclist
endfunction endfunction

View file

@ -35,6 +35,12 @@ function! SyntaxCheckers_d_dmd_IsAvailable() dict
endfunction endfunction
function! SyntaxCheckers_d_dmd_GetLocList() dict function! SyntaxCheckers_d_dmd_GetLocList() dict
if !exists('g:syntastic_d_include_dirs')
let g:syntastic_d_include_dirs = filter(glob($HOME . '/.dub/packages/*', 1, 1), 'isdirectory(v:val)')
call map(g:syntastic_d_include_dirs, 'isdirectory(v:val . "/source") ? v:val . "/source" : v:val')
call add(g:syntastic_d_include_dirs, './source')
endif
return syntastic#c#GetLocList('d', 'dmd', { return syntastic#c#GetLocList('d', 'dmd', {
\ 'errorformat': \ 'errorformat':
\ '%-G%f:%s:,%f(%l): %m,' . \ '%-G%f:%s:,%f(%l): %m,' .

View file

@ -24,6 +24,11 @@ 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'

View file

@ -32,7 +32,7 @@ main([FileName, "-rebar", Path, LibDirs]) ->
%io:format("~p~n", [LibDirs1]), %io:format("~p~n", [LibDirs1]),
compile(FileName, LibDirs1); compile(FileName, LibDirs1);
main([FileName, LibDirs]) -> main([FileName | LibDirs]) ->
compile(FileName, LibDirs). compile(FileName, LibDirs).
compile(FileName, LibDirs) -> compile(FileName, LibDirs) ->
@ -45,7 +45,12 @@ compile(FileName, LibDirs) ->
warn_export_vars, warn_export_vars,
strong_validation, strong_validation,
report] ++ report] ++
[{i, filename:join(Root, I)} || I <- LibDirs]). [{i, filename:join(Root, I)} || I <- LibDirs] ++
case lists:member("deps/pmod_transform/include", LibDirs) of
true -> [{parse_transform, pmod_pt}];
_ -> []
end
).
get_root(Dir) -> get_root(Dir) ->
Path = filename:split(filename:absname(Dir)), Path = filename:split(filename:absname(Dir)),

View file

@ -30,7 +30,7 @@ function! SyntaxCheckers_erlang_escript_GetLocList() dict
endif endif
let shebang = syntastic#util#parseShebang() let shebang = syntastic#util#parseShebang()
if shebang['exe'] =~# '\m\<escript$' || (shebang['exe'] ==# '/usr/bin/env' && shebang['args'][0] ==# 'escript') if shebang['exe'] ==# 'escript'
let args = '-s' let args = '-s'
let post_args = '' let post_args = ''
else else

View file

@ -38,3 +38,5 @@ call g:SyntasticRegistry.CreateAndRegisterChecker({
let &cpo = s:save_cpo let &cpo = s:save_cpo
unlet s:save_cpo unlet s:save_cpo
" vim: set et sts=4 sw=4:

View file

@ -19,22 +19,17 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_eruby_ruby_IsAvailable() dict function! SyntaxCheckers_eruby_ruby_IsAvailable() dict
if !exists("g:syntastic_ruby_exec") if !exists('g:syntastic_eruby_ruby_exec') && exists('g:syntastic_ruby_exec')
let g:syntastic_ruby_exec = self.getExec() let g:syntastic_eruby_ruby_exec = g:syntastic_ruby_exec
endif endif
return executable(expand(g:syntastic_ruby_exec)) return executable(self.getExec())
endfunction endfunction
function! SyntaxCheckers_eruby_ruby_GetLocList() dict function! SyntaxCheckers_eruby_ruby_GetLocList() dict
let exe = syntastic#util#shexpand(g:syntastic_ruby_exec)
if !syntastic#util#isRunningWindows()
let exe = 'RUBYOPT= ' . exe
endif
let fname = "'" . escape(expand('%'), "\\'") . "'" let fname = "'" . escape(expand('%'), "\\'") . "'"
" TODO: encodings became useful in ruby 1.9 :) " TODO: encodings became useful in ruby 1.9 :)
if syntastic#util#versionIsAtLeast(syntastic#util#getVersion(exe . ' --version'), [1, 9]) if syntastic#util#versionIsAtLeast(syntastic#util#getVersion(self.getExecEscaped(). ' --version'), [1, 9])
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
@ -43,22 +38,32 @@ function! SyntaxCheckers_eruby_ruby_GetLocList() dict
"gsub fixes issue #7, rails has it's own eruby syntax "gsub fixes issue #7, rails has it's own eruby syntax
let makeprg = let makeprg =
\ exe . ' -rerb -e ' . \ self.getExecEscaped() . ' -rerb -e ' .
\ syntastic#util#shescape('puts ERB.new(File.read(' . \ syntastic#util#shescape('puts ERB.new(File.read(' .
\ fname . encoding_spec . \ fname . encoding_spec .
\ ').gsub(''<%='',''<%''), nil, ''-'').src') . \ ').gsub(''<%='',''<%''), nil, ''-'').src') .
\ ' | ' . exe . ' -c' \ ' | ' . self.getExecEscaped() . ' -w -c'
let errorformat = let errorformat = '%-G%\m%.%#warning: %\%%(possibly %\)%\?useless use of a literal in void context,'
" filter out lines starting with ...
" long lines are truncated and wrapped in ... %p then returns the wrong
" column offset
let errorformat .= '%-G%\%.%\%.%\%.%.%#,'
let errorformat .=
\ '%-GSyntax OK,'. \ '%-GSyntax OK,'.
\ '%E-:%l: syntax error\, %m,%Z%p^,'. \ '%E-:%l: syntax error\, %m,%Z%p^,'.
\ '%W-:%l: warning: %m,'. \ '%W-:%l: warning: %m,'.
\ '%Z%p^,'. \ '%Z%p^,'.
\ '%-C%.%#' \ '%-C%.%#'
let env = syntastic#util#isRunningWindows() ? {} : { 'RUBYOPT': '' }
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env,
\ 'defaults': { 'bufnr': bufnr(""), 'vcol': 1 } }) \ 'defaults': { 'bufnr': bufnr(""), 'vcol': 1 } })
endfunction endfunction

View file

@ -19,16 +19,12 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_haml_haml_IsAvailable() dict function! SyntaxCheckers_haml_haml_IsAvailable() dict
if !exists('g:syntastic_haml_interpreter') call syntastic#log#deprecationWarn('haml_interpreter', 'haml_haml_exec')
let g:syntastic_haml_interpreter = self.getExec() return executable(self.getExec())
endif
return executable(expand(g:syntastic_haml_interpreter))
endfunction endfunction
function! SyntaxCheckers_haml_haml_GetLocList() dict function! SyntaxCheckers_haml_haml_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({ 'args_after': '-c' })
\ 'exe': syntastic#util#shexpand(g:syntastic_haml_interpreter),
\ 'args_after': '-c' })
let errorformat = let errorformat =
\ 'Haml error on line %l: %m,' . \ 'Haml error on line %l: %m,' .

View file

@ -29,6 +29,7 @@ function! SyntaxCheckers_handlebars_handlebars_GetLocList() dict
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'postprocess': ['guards'],
\ 'defaults': {'bufnr': bufnr("")} }) \ 'defaults': {'bufnr': bufnr("")} })
endfunction endfunction

View file

@ -19,22 +19,30 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_haskell_hdevtools_GetLocList() dict function! SyntaxCheckers_haskell_hdevtools_GetLocList() dict
let makeprg = self.makeprgBuild({ if !exists('g:syntastic_haskell_hdevtools_args') && exists('g:hdevtools_options')
\ 'exe': self.getExecEscaped() . ' check', call syntastic#log#oneTimeWarn('variable g:hdevtools_options is deprecated, ' .
\ 'args': get(g:, 'hdevtools_options', '') }) \ 'please use g:syntastic_haskell_hdevtools_args instead')
let g:syntastic_haskell_hdevtools_args = g:hdevtools_options
endif
let errorformat= '\%-Z\ %#,'. let makeprg = self.makeprgBuild({
\ '%W%f:%l:%c:\ Warning:\ %m,'. \ 'exe_after': 'check',
\ '%W%f:%l:%c:\ Warning:,'. \ 'fname': syntastic#util#shexpand('%:p') })
\ '%E%f:%l:%c:\ %m,'.
\ '%E%>%f:%l:%c:,'. let errorformat =
\ '%+C\ \ %#%m,'. \ '%-Z %#,'.
\ '%W%>%f:%l:%c:,'. \ '%W%f:%l:%v: Warning: %m,'.
\ '%+C\ \ %#%tarning:\ %m,' \ '%W%f:%l:%v: Warning:,'.
\ '%E%f:%l:%v: %m,'.
\ '%E%>%f:%l:%v:,'.
\ '%+C %#%m,'.
\ '%W%>%f:%l:%v:,'.
\ '%+C %#%tarning: %m,'
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'defaults': {'vcol': 1},
\ 'postprocess': ['compressWhitespace'] }) \ 'postprocess': ['compressWhitespace'] })
endfunction endfunction

View file

@ -14,16 +14,18 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_haskell_hlint_GetLocList() dict function! SyntaxCheckers_haskell_hlint_GetLocList() dict
let makeprg = self.makeprgBuild({}) let makeprg = self.makeprgBuild({
\ 'fname': syntastic#util#shexpand('%:p')})
let errorformat = let errorformat =
\ '%E%f:%l:%c: Error: %m,' . \ '%E%f:%l:%v: Error: %m,' .
\ '%W%f:%l:%c: Warning: %m,' . \ '%W%f:%l:%v: Warning: %m,' .
\ '%C%m' \ '%C%m'
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'defaults': {'vcol': 1},
\ 'postprocess': ['compressWhitespace'] }) \ 'postprocess': ['compressWhitespace'] })
endfunction endfunction

View file

@ -14,31 +14,25 @@ if exists('g:loaded_syntastic_html_jshint_checker')
endif endif
let g:loaded_syntastic_html_jshint_checker = 1 let g:loaded_syntastic_html_jshint_checker = 1
if !exists('g:syntastic_jshint_exec')
let g:syntastic_jshint_exec = 'jshint'
endif
if !exists('g:syntastic_html_jshint_conf')
let g:syntastic_html_jshint_conf = ''
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_html_jshint_IsAvailable() dict function! SyntaxCheckers_html_jshint_IsAvailable() dict
let exe = expand(g:syntastic_jshint_exec) call syntastic#log#deprecationWarn('jshint_exec', 'html_jshint_exec')
return executable(exe) && return executable(self.getExec()) &&
\ syntastic#util#versionIsAtLeast(syntastic#util#getVersion(exe . ' --version'), [2,4]) \ syntastic#util#versionIsAtLeast(syntastic#util#getVersion(self.getExecEscaped() . ' --version'), [2,4])
endfunction endfunction
function! SyntaxCheckers_html_jshint_GetLocList() dict function! SyntaxCheckers_html_jshint_GetLocList() dict
let makeprg = self.makeprgBuild({ call syntastic#log#deprecationWarn('html_jshint_conf', 'html_jshint_args',
\ 'exe': expand(g:syntastic_jshint_exec), \ "'--config ' . syntastic#util#shexpand(OLD_VAR)")
\ 'args': (g:syntastic_html_jshint_conf != '' ? '--config ' . g:syntastic_html_jshint_conf : ''),
\ 'args_after': '--verbose --extract always' }) let makeprg = self.makeprgBuild({ 'args_after': '--verbose --extract always' })
let errorformat = '%A%f: line %l\, col %v\, %m \(%t%*\d\)' let errorformat = '%A%f: line %l\, col %v\, %m \(%t%*\d\)'
call self.setWantSort(1)
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,

View file

@ -10,7 +10,15 @@
" "
"============================================================================ "============================================================================
" "
" Checker option: " 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.
"
" Checker options:
" "
" - g:syntastic_html_tidy_ignore_errors (list; default: []) " - g:syntastic_html_tidy_ignore_errors (list; default: [])
" list of errors to ignore " list of errors to ignore
@ -48,108 +56,112 @@ set cpo&vim
" TODO: join this with xhtml.vim for DRY's sake? " TODO: join this with xhtml.vim for DRY's sake?
function! s:TidyEncOptByFenc() function! s:TidyEncOptByFenc()
let tidy_opts = { let tidy_opts = {
\'utf-8': '-utf8', \ 'utf-8': '-utf8',
\'ascii': '-ascii', \ 'ascii': '-ascii',
\'latin1': '-latin1', \ 'latin1': '-latin1',
\'iso-2022-jp': '-iso-2022', \ 'iso-2022-jp': '-iso-2022',
\'cp1252': '-win1252', \ 'cp1252': '-win1252',
\'macroman': '-mac', \ 'macroman': '-mac',
\'utf-16le': '-utf16le', \ 'utf-16le': '-utf16le',
\'utf-16': '-utf16', \ 'utf-16': '-utf16',
\'big5': '-big5', \ 'big5': '-big5',
\'cp932': '-shiftjis', \ 'cp932': '-shiftjis',
\'sjis': '-shiftjis', \ 'sjis': '-shiftjis',
\'cp850': '-ibm858', \ 'cp850': '-ibm858',
\} \ }
return get(tidy_opts, &fileencoding, '-utf8') return get(tidy_opts, &fileencoding, '-utf8')
endfunction endfunction
let s:ignore_errors = [ let s:ignore_errors = [
\ "<table> lacks \"summary\" attribute", \ "<table> lacks \"summary\" attribute",
\ "not approved by W3C", \ "not approved by W3C",
\ "<input> proprietary attribute \"placeholder\"", \ "<input> proprietary attribute \"placeholder\"",
\ "<meta> proprietary attribute \"charset\"", \ "<meta> proprietary attribute \"charset\"",
\ "<meta> lacks \"content\" attribute", \ "<meta> lacks \"content\" attribute",
\ "inserting \"type\" attribute", \ "inserting \"type\" attribute",
\ "proprietary attribute \"data-", \ "proprietary attribute \"data-",
\ "missing <!DOCTYPE> declaration", \ "missing <!DOCTYPE> declaration",
\ "inserting implicit <body>", \ "inserting implicit <body>",
\ "inserting missing 'title' element", \ "inserting missing 'title' element",
\ "unescaped & or unknown entity", \ "unescaped & or unknown entity",
\ "<input> attribute \"type\" has invalid value", \ "<input> attribute \"type\" has invalid value",
\ "proprietary attribute \"role\"", \ "proprietary attribute \"role\"",
\ "proprietary attribute \"aria-activedescendant\"", \ "proprietary attribute \"aria-activedescendant\"",
\ "proprietary attribute \"aria-atomic\"", \ "proprietary attribute \"aria-atomic\"",
\ "proprietary attribute \"aria-autocomplete\"", \ "proprietary attribute \"aria-autocomplete\"",
\ "proprietary attribute \"aria-busy\"", \ "proprietary attribute \"aria-busy\"",
\ "proprietary attribute \"aria-checked\"", \ "proprietary attribute \"aria-checked\"",
\ "proprietary attribute \"aria-controls\"", \ "proprietary attribute \"aria-controls\"",
\ "proprietary attribute \"aria-describedby\"", \ "proprietary attribute \"aria-describedby\"",
\ "proprietary attribute \"aria-disabled\"", \ "proprietary attribute \"aria-disabled\"",
\ "proprietary attribute \"aria-dropeffect\"", \ "proprietary attribute \"aria-dropeffect\"",
\ "proprietary attribute \"aria-expanded\"", \ "proprietary attribute \"aria-expanded\"",
\ "proprietary attribute \"aria-flowto\"", \ "proprietary attribute \"aria-flowto\"",
\ "proprietary attribute \"aria-grabbed\"", \ "proprietary attribute \"aria-grabbed\"",
\ "proprietary attribute \"aria-haspopup\"", \ "proprietary attribute \"aria-haspopup\"",
\ "proprietary attribute \"aria-hidden\"", \ "proprietary attribute \"aria-hidden\"",
\ "proprietary attribute \"aria-invalid\"", \ "proprietary attribute \"aria-invalid\"",
\ "proprietary attribute \"aria-label\"", \ "proprietary attribute \"aria-label\"",
\ "proprietary attribute \"aria-labelledby\"", \ "proprietary attribute \"aria-labelledby\"",
\ "proprietary attribute \"aria-level\"", \ "proprietary attribute \"aria-level\"",
\ "proprietary attribute \"aria-live\"", \ "proprietary attribute \"aria-live\"",
\ "proprietary attribute \"aria-multiline\"", \ "proprietary attribute \"aria-multiline\"",
\ "proprietary attribute \"aria-multiselectable\"", \ "proprietary attribute \"aria-multiselectable\"",
\ "proprietary attribute \"aria-orientation\"", \ "proprietary attribute \"aria-orientation\"",
\ "proprietary attribute \"aria-owns\"", \ "proprietary attribute \"aria-owns\"",
\ "proprietary attribute \"aria-posinset\"", \ "proprietary attribute \"aria-posinset\"",
\ "proprietary attribute \"aria-pressed\"", \ "proprietary attribute \"aria-pressed\"",
\ "proprietary attribute \"aria-readonly\"", \ "proprietary attribute \"aria-readonly\"",
\ "proprietary attribute \"aria-relevant\"", \ "proprietary attribute \"aria-relevant\"",
\ "proprietary attribute \"aria-relevant\"", \ "proprietary attribute \"aria-relevant\"",
\ "proprietary attribute \"aria-required\"", \ "proprietary attribute \"aria-required\"",
\ "proprietary attribute \"aria-selected\"", \ "proprietary attribute \"aria-selected\"",
\ "proprietary attribute \"aria-setsize\"", \ "proprietary attribute \"aria-setsize\"",
\ "proprietary attribute \"aria-sort\"", \ "proprietary attribute \"aria-sort\"",
\ "proprietary attribute \"aria-valuemax\"", \ "proprietary attribute \"aria-valuemax\"",
\ "proprietary attribute \"aria-valuemin\"", \ "proprietary attribute \"aria-valuemin\"",
\ "proprietary attribute \"aria-valuenow\"", \ "proprietary attribute \"aria-valuenow\"",
\ "proprietary attribute \"aria-valuetext\"" \ "proprietary attribute \"aria-valuetext\""
\ ] \ ]
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
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
let s:empty_tags = [ let s:empty_tags = [
\ "wbr", \ "wbr",
\ "keygen" \ "keygen"
\ ] \ ]
lockvar! s:empty_tags
function! s:IgnoreError(text) function! s:IgnoreError(text)
for i in s:ignore_errors + g:syntastic_html_tidy_ignore_errors for i in s:ignore_errors + g:syntastic_html_tidy_ignore_errors
@ -174,9 +186,7 @@ function! s:Args()
endfunction endfunction
function! SyntaxCheckers_html_tidy_GetLocList() dict function! SyntaxCheckers_html_tidy_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({ 'args_after': s:Args() })
\ 'args_after': s:Args(),
\ 'tail': '2>&1' })
let errorformat = let errorformat =
\ '%Wline %l column %v - Warning: %m,' . \ '%Wline %l column %v - Warning: %m,' .

View file

@ -27,18 +27,27 @@ endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_java_checkstyle_IsAvailable() dict
return
\ executable(self.getExec()) &&
\ filereadable(expand(g:syntastic_java_checkstyle_classpath)) &&
\ filereadable(expand(g:syntastic_java_checkstyle_conf_file))
endfunction
function! SyntaxCheckers_java_checkstyle_GetLocList() dict function! SyntaxCheckers_java_checkstyle_GetLocList() dict
let fname = syntastic#util#shescape( expand('%:p:h') . '/' . expand('%:t') ) let fname = syntastic#util#shescape( expand('%:p:h') . syntastic#util#Slash() . expand('%:t') )
if has('win32unix') if has('win32unix')
let fname = substitute(system('cygpath -m ' . fname), '\m\%x00', '', 'g') let fname = substitute(system('cygpath -m ' . fname), '\m\%x00', '', 'g')
endif endif
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'args_after': '-cp ' . g:syntastic_java_checkstyle_classpath . \ 'args_after': [
\ ' com.puppycrawl.tools.checkstyle.Main -c ' . g:syntastic_java_checkstyle_conf_file . \ '-cp', expand(g:syntastic_java_checkstyle_classpath),
\ ' -f xml', \ 'com.puppycrawl.tools.checkstyle.Main',
\ '-c', expand(g:syntastic_java_checkstyle_conf_file),
\ '-f', 'xml'],
\ 'fname': fname }) \ 'fname': fname })
let errorformat = '%f:%t:%l:%c:%m' let errorformat = '%f:%t:%l:%c:%m'

View file

@ -10,32 +10,36 @@
" 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_java_javac_checker") if exists('g:loaded_syntastic_java_javac_checker')
finish finish
endif endif
let g:loaded_syntastic_java_javac_checker = 1 let g:loaded_syntastic_java_javac_checker = 1
let g:syntastic_java_javac_maven_pom_tags = ["build", "properties"] let g:syntastic_java_javac_maven_pom_tags = ['build', 'properties']
let g:syntastic_java_javac_maven_pom_properties = {} let g:syntastic_java_javac_maven_pom_properties = {}
let s:has_maven = 0 let s:has_maven = 0
" Global Options " Global Options
if !exists("g:syntastic_java_javac_executable") if !exists('g:syntastic_java_javac_executable')
let g:syntastic_java_javac_executable = 'javac' let g:syntastic_java_javac_executable = 'javac'
endif endif
if !exists("g:syntastic_java_maven_executable") if !exists('g:syntastic_java_maven_executable')
let g:syntastic_java_maven_executable = 'mvn' let g:syntastic_java_maven_executable = 'mvn'
endif endif
if !exists("g:syntastic_java_javac_options") if !exists('g:syntastic_java_javac_options')
let g:syntastic_java_javac_options = '-Xlint' let g:syntastic_java_javac_options = '-Xlint'
endif endif
if !exists("g:syntastic_java_javac_classpath") if !exists('g:syntastic_java_maven_options')
let g:syntastic_java_maven_options = ''
endif
if !exists('g:syntastic_java_javac_classpath')
let g:syntastic_java_javac_classpath = '' let g:syntastic_java_javac_classpath = ''
endif endif
if !exists("g:syntastic_java_javac_delete_output") if !exists('g:syntastic_java_javac_delete_output')
let g:syntastic_java_javac_delete_output = 1 let g:syntastic_java_javac_delete_output = 1
endif endif
@ -43,20 +47,22 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! s:CygwinPath(path) function! s:CygwinPath(path)
return substitute(system("cygpath -m " . a:path), '\n', '', 'g') return substitute(system('cygpath -m ' . syntastic#util#shescape(a:path)), "\n", '', 'g')
endfunction endfunction
if !exists("g:syntastic_java_javac_temp_dir") if !exists('g:syntastic_java_javac_temp_dir')
if has('win32') || has('win64') if has('win32') || has('win64')
let g:syntastic_java_javac_temp_dir = $TEMP."\\vim-syntastic-javac" let g:syntastic_java_javac_temp_dir = $TEMP . syntastic#util#Slash() . 'vim-syntastic-javac'
elseif has('win32unix') elseif has('win32unix')
let g:syntastic_java_javac_temp_dir = s:CygwinPath('/tmp/vim-syntastic-javac') let g:syntastic_java_javac_temp_dir = s:CygwinPath('/tmp/vim-syntastic-javac')
elseif $TMPDIR != ''
let g:syntastic_java_javac_temp_dir = $TMPDIR . '/vim-syntastic-javac'
else else
let g:syntastic_java_javac_temp_dir = '/tmp/vim-syntastic-javac' let g:syntastic_java_javac_temp_dir = '/tmp/vim-syntastic-javac'
endif endif
endif endif
if !exists("g:syntastic_java_javac_autoload_maven_classpath") if !exists('g:syntastic_java_javac_autoload_maven_classpath')
let g:syntastic_java_javac_autoload_maven_classpath = 1 let g:syntastic_java_javac_autoload_maven_classpath = 1
endif endif
@ -72,16 +78,16 @@ if !exists('g:syntastic_java_javac_custom_classpath_command')
let g:syntastic_java_javac_custom_classpath_command = '' let g:syntastic_java_javac_custom_classpath_command = ''
endif endif
if !exists("g:syntastic_java_javac_maven_pom_ftime") if !exists('g:syntastic_java_javac_maven_pom_ftime')
let g:syntastic_java_javac_maven_pom_ftime = {} let g:syntastic_java_javac_maven_pom_ftime = {}
endif endif
if !exists("g:syntastic_java_javac_maven_pom_classpath") if !exists('g:syntastic_java_javac_maven_pom_classpath')
let g:syntastic_java_javac_maven_pom_classpath = {} let g:syntastic_java_javac_maven_pom_classpath = {}
endif endif
function! s:RemoveCarriageReturn(line) function! s:RemoveCarriageReturn(line)
return substitute(a:line, '\r', '', 'g') return substitute(a:line, "\r", '', 'g')
endfunction endfunction
" recursively remove directory and all it's sub-directories " recursively remove directory and all it's sub-directories
@ -90,41 +96,30 @@ function! s:RemoveDir(dir)
for f in split(globpath(a:dir, '*'), "\n") for f in split(globpath(a:dir, '*'), "\n")
call s:RemoveDir(f) call s:RemoveDir(f)
endfor endfor
silent! call system('rmdir ' . a:dir) silent! call system('rmdir ' . syntastic#util#shescape(a:dir))
else else
silent! call delete(a:dir) silent! call delete(a:dir)
endif endif
endfunction endfunction
function! s:ClassSep()
return (syntastic#util#isRunningWindows() || has('win32unix')) ? ';' : ':'
endfunction
function! s:AddToClasspath(classpath, path) function! s:AddToClasspath(classpath, path)
if a:path == '' if a:path == ''
return a:classpath return a:classpath
endif endif
if a:classpath != '' && a:path != '' return (a:classpath != '') ? a:classpath . s:ClassSep() . a:path : a:path
if has('win32') || has('win32unix') || has('win64')
return a:classpath . ";" . a:path
else
return a:classpath . ":" . a:path
endif
else
return a:path
endif
endfunction endfunction
function! s:SplitClasspath(classpath) function! s:SplitClasspath(classpath)
if a:classpath == '' return split(a:classpath, s:ClassSep())
return []
endif
if has('win32') || has('win32unix') || has('win64')
return split(a:classpath, ";")
else
return split(a:classpath, ":")
endif
endfunction endfunction
function! s:LoadConfigFile() function! s:LoadConfigFile()
if filereadable(g:syntastic_java_javac_config_file) if filereadable(expand(g:syntastic_java_javac_config_file))
exe 'source '.g:syntastic_java_javac_config_file exe 'source ' . fnameescape(expand(g:syntastic_java_javac_config_file))
endif endif
endfunction endfunction
@ -137,25 +132,25 @@ function! s:SaveClasspath()
endfor endfor
" save classpath to config file " save classpath to config file
if g:syntastic_java_javac_config_file_enabled if g:syntastic_java_javac_config_file_enabled
if filereadable(g:syntastic_java_javac_config_file) if filereadable(expand(g:syntastic_java_javac_config_file))
" load lines from config file " load lines from config file
let lines = readfile(g:syntastic_java_javac_config_file) let lines = readfile(expand(g:syntastic_java_javac_config_file))
" strip g:syntastic_java_javac_classpath options from config file lines " strip g:syntastic_java_javac_classpath options from config file lines
let i = 0 let i = 0
while i < len(lines) while i < len(lines)
if match(lines[i], 'g:syntastic_java_javac_classpath') != -1 if match(lines[i], 'g:syntastic_java_javac_classpath') != -1
call remove(lines, i) call remove(lines, i)
let i -= 1 else
let i += 1
endif endif
let i += 1
endwhile endwhile
else else
let lines = [] let lines = []
endif endif
" add new g:syntastic_java_javac_classpath option to config " add new g:syntastic_java_javac_classpath option to config
call add(lines, 'let g:syntastic_java_javac_classpath = "'.path.'"') call add(lines, 'let g:syntastic_java_javac_classpath = ' . string(path))
" save config file lines " save config file lines
call writefile(lines, g:syntastic_java_javac_config_file) call writefile(lines, expand(g:syntastic_java_javac_config_file))
endif endif
" set new classpath " set new classpath
let g:syntastic_java_javac_classpath = path let g:syntastic_java_javac_classpath = path
@ -169,7 +164,7 @@ function! s:EditClasspath()
let path = [] let path = []
let pathlines = split(g:syntastic_java_javac_classpath, "\n") let pathlines = split(g:syntastic_java_javac_classpath, "\n")
for p in pathlines for p in pathlines
let path += s:SplitClasspath(p) call extend(path, s:SplitClasspath(p))
endfor endfor
execute (len(path) + 5) . 'sp ' . fnameescape(command) execute (len(path) + 5) . 'sp ' . fnameescape(command)
@ -192,7 +187,7 @@ function! s:SaveConfig()
let lines = getline(1, line('$')) let lines = getline(1, line('$'))
if g:syntastic_java_javac_config_file_enabled if g:syntastic_java_javac_config_file_enabled
" save config file lines " save config file lines
call writefile(lines, g:syntastic_java_javac_config_file) call writefile(lines, expand(g:syntastic_java_javac_config_file))
endif endif
let &modified = 0 let &modified = 0
endfunction endfunction
@ -202,8 +197,8 @@ function! s:EditConfig()
let winnr = bufwinnr('^' . command . '$') let winnr = bufwinnr('^' . command . '$')
if winnr < 0 if winnr < 0
let lines = [] let lines = []
if filereadable(g:syntastic_java_javac_config_file) if filereadable(expand(g:syntastic_java_javac_config_file))
let lines = readfile(g:syntastic_java_javac_config_file) let lines = readfile(expand(g:syntastic_java_javac_config_file))
endif endif
execute (len(lines) + 5) . 'sp ' . fnameescape(command) execute (len(lines) + 5) . 'sp ' . fnameescape(command)
@ -223,10 +218,12 @@ endfunction
function! s:GetMavenProperties() function! s:GetMavenProperties()
let mvn_properties = {} let mvn_properties = {}
let pom = findfile("pom.xml", ".;") let pom = findfile('pom.xml', '.;')
if s:has_maven && filereadable(pom) if s:has_maven && filereadable(pom)
if !has_key(g:syntastic_java_javac_maven_pom_properties, pom) if !has_key(g:syntastic_java_javac_maven_pom_properties, pom)
let mvn_cmd = syntastic#util#shexpand(g:syntastic_java_maven_executable) . ' -f ' . pom let mvn_cmd = syntastic#util#shexpand(g:syntastic_java_maven_executable) .
\ ' -f ' . syntastic#util#shescape(pom) .
\ ' ' . g:syntastic_java_maven_options
let mvn_is_managed_tag = 1 let mvn_is_managed_tag = 1
let mvn_settings_output = split(system(mvn_cmd . ' help:effective-pom'), "\n") let mvn_settings_output = split(system(mvn_cmd . ' help:effective-pom'), "\n")
let current_path = 'project' let current_path = 'project'
@ -239,7 +236,7 @@ function! s:GetMavenProperties()
let matches = matchlist(line, '\m^\s*</\([a-zA-Z0-9\-\.]\+\)>\s*$') let matches = matchlist(line, '\m^\s*</\([a-zA-Z0-9\-\.]\+\)>\s*$')
if !empty(matches) if !empty(matches)
let mvn_is_managed_tag = index(g:syntastic_java_javac_maven_pom_tags, matches[1]) < 0 let mvn_is_managed_tag = index(g:syntastic_java_javac_maven_pom_tags, matches[1]) < 0
let current_path = substitute(current_path, '\m\.' . matches[1] . "$", '', '') let current_path = substitute(current_path, '\m\.' . matches[1] . '$', '', '')
else else
let matches = matchlist(line, '\m^\s*<\([a-zA-Z0-9\-\.]\+\)>\(.\+\)</[a-zA-Z0-9\-\.]\+>\s*$') let matches = matchlist(line, '\m^\s*<\([a-zA-Z0-9\-\.]\+\)>\(.\+\)</[a-zA-Z0-9\-\.]\+>\s*$')
if mvn_is_managed_tag && !empty(matches) if mvn_is_managed_tag && !empty(matches)
@ -262,10 +259,12 @@ if g:syntastic_java_javac_config_file_enabled
endif endif
function! s:GetMavenClasspath() function! s:GetMavenClasspath()
let pom = findfile("pom.xml", ".;") let pom = findfile('pom.xml', '.;')
if s:has_maven && filereadable(pom) if s:has_maven && filereadable(pom)
if !has_key(g:syntastic_java_javac_maven_pom_ftime, pom) || g:syntastic_java_javac_maven_pom_ftime[pom] != getftime(pom) if !has_key(g:syntastic_java_javac_maven_pom_ftime, pom) || g:syntastic_java_javac_maven_pom_ftime[pom] != getftime(pom)
let mvn_cmd = syntastic#util#shexpand(g:syntastic_java_maven_executable) . ' -f ' . pom let mvn_cmd = syntastic#util#shexpand(g:syntastic_java_maven_executable) .
\ ' -f ' . syntastic#util#shescape(pom) .
\ ' ' . g:syntastic_java_maven_options
let mvn_classpath_output = split(system(mvn_cmd . ' dependency:build-classpath'), "\n") let mvn_classpath_output = split(system(mvn_cmd . ' dependency:build-classpath'), "\n")
let mvn_classpath = '' let mvn_classpath = ''
let class_path_next = 0 let class_path_next = 0
@ -308,20 +307,20 @@ function! SyntaxCheckers_java_javac_IsAvailable() dict
endfunction endfunction
function! s:MavenOutputDirectory() function! s:MavenOutputDirectory()
let pom = findfile("pom.xml", ".;") let pom = findfile('pom.xml', '.;')
if s:has_maven && filereadable(pom) if s:has_maven && filereadable(pom)
let mvn_properties = s:GetMavenProperties() let mvn_properties = s:GetMavenProperties()
let output_dir = getcwd() let output_dir = getcwd()
if has_key(mvn_properties, 'project.properties.build.dir') if has_key(mvn_properties, 'project.properties.build.dir')
let output_dir = mvn_properties['project.properties.build.dir'] let output_dir = mvn_properties['project.properties.build.dir']
endif endif
if stridx(expand( '%:p:h' ), "src.main.java") >= 0 if stridx(expand( '%:p:h' ), 'src.main.java') >= 0
let output_dir .= '/target/classes' let output_dir .= '/target/classes'
if has_key(mvn_properties, 'project.build.outputDirectory') if has_key(mvn_properties, 'project.build.outputDirectory')
let output_dir = mvn_properties['project.build.outputDirectory'] let output_dir = mvn_properties['project.build.outputDirectory']
endif endif
endif endif
if stridx(expand( '%:p:h' ), "src.test.java") >= 0 if stridx(expand( '%:p:h' ), 'src.test.java') >= 0
let output_dir .= '/target/test-classes' let output_dir .= '/target/test-classes'
if has_key(mvn_properties, 'project.build.testOutputDirectory') if has_key(mvn_properties, 'project.build.testOutputDirectory')
let output_dir = mvn_properties['project.build.testOutputDirectory'] let output_dir = mvn_properties['project.build.testOutputDirectory']
@ -329,7 +328,7 @@ function! s:MavenOutputDirectory()
endif endif
if has('win32unix') if has('win32unix')
let output_dir=s:CygwinPath(output_dir) let output_dir = s:CygwinPath(output_dir)
endif endif
return output_dir return output_dir
endif endif
@ -337,13 +336,12 @@ function! s:MavenOutputDirectory()
endfunction endfunction
function! SyntaxCheckers_java_javac_GetLocList() dict function! SyntaxCheckers_java_javac_GetLocList() dict
let javac_opts = g:syntastic_java_javac_options let javac_opts = g:syntastic_java_javac_options
let output_dir = "" let output_dir = ''
if g:syntastic_java_javac_delete_output if g:syntastic_java_javac_delete_output
let output_dir = g:syntastic_java_javac_temp_dir let output_dir = g:syntastic_java_javac_temp_dir
let javac_opts .= ' -d ' . output_dir let javac_opts .= ' -d ' . syntastic#util#shescape(output_dir)
endif endif
" load classpath from config file " load classpath from config file
@ -354,12 +352,7 @@ function! SyntaxCheckers_java_javac_GetLocList() dict
let javac_classpath = '' let javac_classpath = ''
" add classpathes to javac_classpath " add classpathes to javac_classpath
if has('win32') || has('win32unix') || has('win64') for path in split(g:syntastic_java_javac_classpath, s:ClassSep())
let javac_classpath_split = ';'
else
let javac_classpath_split = ':'
endif
for path in split(g:syntastic_java_javac_classpath, javac_classpath_split)
if path != '' if path != ''
try try
let ps = glob(path, 0, 1) let ps = glob(path, 0, 1)
@ -378,7 +371,7 @@ function! SyntaxCheckers_java_javac_GetLocList() dict
if s:has_maven && g:syntastic_java_javac_autoload_maven_classpath if s:has_maven && g:syntastic_java_javac_autoload_maven_classpath
if !g:syntastic_java_javac_delete_output if !g:syntastic_java_javac_delete_output
let javac_opts .= ' -d ' . s:MavenOutputDirectory() let javac_opts .= ' -d ' . syntastic#util#shescape(s:MavenOutputDirectory())
endif endif
let javac_classpath = s:AddToClasspath(javac_classpath, s:GetMavenClasspath()) let javac_classpath = s:AddToClasspath(javac_classpath, s:GetMavenClasspath())
endif endif
@ -386,7 +379,7 @@ function! SyntaxCheckers_java_javac_GetLocList() dict
" load custom classpath " load custom classpath
if g:syntastic_java_javac_custom_classpath_command != '' if g:syntastic_java_javac_custom_classpath_command != ''
let lines = system(g:syntastic_java_javac_custom_classpath_command) let lines = system(g:syntastic_java_javac_custom_classpath_command)
if has('win32') || has('win32unix') || has('win64') if syntastic#util#isRunningWindows() || has('win32unix')
let lines = substitute(lines, "\r\n", "\n", 'g') let lines = substitute(lines, "\r\n", "\n", 'g')
endif endif
for l in split(lines, "\n") for l in split(lines, "\n")
@ -395,26 +388,18 @@ function! SyntaxCheckers_java_javac_GetLocList() dict
endif endif
if javac_classpath != '' if javac_classpath != ''
let javac_opts .= ' -cp "' . fnameescape(javac_classpath) . '"' let javac_opts .= ' -cp ' . syntastic#util#shexpand(javac_classpath)
endif endif
" path seperator let fname = expand('%:p:h') . syntastic#util#Slash() . expand ('%:t')
if has('win32') || has('win32unix') || has('win64')
let sep = "\\"
else
let sep = '/'
endif
let fname = fnameescape(expand ( '%:p:h' ) . sep . expand ( '%:t' ))
if has('win32unix') if has('win32unix')
let fname = s:CygwinPath(fname) let fname = s:CygwinPath(fname)
endif endif
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'args': javac_opts, \ 'args': javac_opts,
\ 'fname': fname, \ 'fname': syntastic#util#shescape(fname) })
\ 'tail': '2>&1' })
" unashamedly stolen from *errorformat-javac* (quickfix.txt) and modified to include error types " unashamedly stolen from *errorformat-javac* (quickfix.txt) and modified to include error types
let errorformat = let errorformat =

View file

@ -8,48 +8,36 @@
" Want To Public License, Version 2, as published by Sam Hocevar. " Want To Public License, Version 2, as published by Sam Hocevar.
" See http://sam.zoy.org/wtfpl/COPYING for more details. " See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================ "============================================================================
"
" To enable this plugin, edit the .vimrc like this:
"
" let g:syntastic_javascript_checker = "closurecompiler"
"
" and set the path to the Google Closure Compiler:
"
" let g:syntastic_javascript_closure_compiler_path = '/path/to/google-closure-compiler.jar'
"
" It takes additional options for Google Closure Compiler with the variable
" g:syntastic_javascript_closure_compiler_options.
"
if exists("g:loaded_syntastic_javascript_closurecompiler_checker") if exists("g:loaded_syntastic_javascript_closurecompiler_checker")
finish finish
endif endif
let g:loaded_syntastic_javascript_closurecompiler_checker = 1 let g:loaded_syntastic_javascript_closurecompiler_checker = 1
if !exists("g:syntastic_javascript_closure_compiler_options")
let g:syntastic_javascript_closure_compiler_options = ""
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_javascript_closurecompiler_IsAvailable() dict function! SyntaxCheckers_javascript_closurecompiler_IsAvailable() dict
call syntastic#log#deprecationWarn('javascript_closure_compiler_path', 'javascript_closurecompiler_path')
return return
\ executable("java") && \ executable("java") &&
\ exists("g:syntastic_javascript_closure_compiler_path") && \ exists("g:syntastic_javascript_closurecompiler_path") &&
\ filereadable(g:syntastic_javascript_closure_compiler_path) \ filereadable(g:syntastic_javascript_closurecompiler_path)
endfunction endfunction
function! SyntaxCheckers_javascript_closurecompiler_GetLocList() dict function! SyntaxCheckers_javascript_closurecompiler_GetLocList() dict
if exists("g:syntastic_javascript_closure_compiler_file_list") call syntastic#log#deprecationWarn('javascript_closure_compiler_options', 'javascript_closurecompiler_args')
let file_list = join(readfile(g:syntastic_javascript_closure_compiler_file_list)) call syntastic#log#deprecationWarn('javascript_closure_compiler_file_list', 'javascript_closurecompiler_file_list')
if exists("g:syntastic_javascript_closurecompiler_file_list")
let file_list = join(readfile(g:syntastic_javascript_closurecompiler_file_list))
else else
let file_list = syntastic#util#shexpand('%') let file_list = syntastic#util#shexpand('%')
endif endif
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'exe': 'java -jar ' . g:syntastic_javascript_closure_compiler_path, \ 'exe_after': '-jar ' . g:syntastic_javascript_closurecompiler_path,
\ 'args': g:syntastic_javascript_closure_compiler_options,
\ 'args_after': '--js' , \ 'args_after': '--js' ,
\ 'fname': file_list }) \ 'fname': file_list })

View file

@ -14,29 +14,36 @@ if exists('g:loaded_syntastic_javascript_eslint_checker')
endif endif
let g:loaded_syntastic_javascript_eslint_checker = 1 let g:loaded_syntastic_javascript_eslint_checker = 1
if !exists('g:syntastic_javascript_eslint_conf')
let g:syntastic_javascript_eslint_conf = ''
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_javascript_eslint_IsAvailable() dict
return
\ executable(self.getExec()) &&
\ syntastic#util#versionIsAtLeast(syntastic#util#getVersion(self.getExecEscaped() . ' --version'), [0, 1])
endfunction
function! SyntaxCheckers_javascript_eslint_GetLocList() dict function! SyntaxCheckers_javascript_eslint_GetLocList() dict
let makeprg = self.makeprgBuild({ call syntastic#log#deprecationWarn('javascript_eslint_conf', 'javascript_eslint_args',
\ 'args': (g:syntastic_javascript_eslint_conf != '' ? '--config ' . g:syntastic_javascript_eslint_conf : '') }) \ "'--config ' . syntastic#util#shexpand(OLD_VAR)")
let makeprg = self.makeprgBuild({ 'args_before': '-f compact' })
let errorformat = let errorformat =
\ '%E%f: line %l\, col %c\, Error - %m' \ '%E%f: line %l\, col %c\, Error - %m,' .
\ '%W%f: line %l\, col %c\, Warning - %m'
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'postprocess': ['sort'] }) \ 'postprocess': ['guards'] })
for e in loclist for e in loclist
let e['col'] += 1 let e['col'] += 1
endfor endfor
call self.setWantSort(1)
return loclist return loclist
endfunction endfunction

View file

@ -14,16 +14,13 @@ if exists("g:loaded_syntastic_javascript_gjslint_checker")
endif endif
let g:loaded_syntastic_javascript_gjslint_checker = 1 let g:loaded_syntastic_javascript_gjslint_checker = 1
if !exists("g:syntastic_javascript_gjslint_conf")
let g:syntastic_javascript_gjslint_conf = ""
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_javascript_gjslint_GetLocList() dict function! SyntaxCheckers_javascript_gjslint_GetLocList() dict
call syntastic#log#deprecationWarn('javascript_gjslint_conf', 'javascript_gjslint_args')
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'args': g:syntastic_javascript_gjslint_conf,
\ 'args_after': '--nosummary --unix_mode --nodebug_indentation --nobeep' }) \ 'args_after': '--nosummary --unix_mode --nodebug_indentation --nobeep' })
let errorformat = let errorformat =

View file

@ -19,14 +19,19 @@ set cpo&vim
function! SyntaxCheckers_javascript_jscs_GetLocList() dict function! SyntaxCheckers_javascript_jscs_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args_after': '--no-colors --reporter checkstyle' }) let makeprg = self.makeprgBuild({ 'args_after': '--no-colors --reporter checkstyle' })
let errorformat = '%f:%t:%l:%c:%m' let errorformat = '%f:%t:%l:%c:%m'
return SyntasticMake({
let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'subtype': 'Style', \ 'subtype': 'Style',
\ 'preprocess': 'checkstyle', \ 'preprocess': 'checkstyle',
\ 'postprocess': ['sort'],
\ 'returns': [0, 2] }) \ 'returns': [0, 2] })
call self.setWantSort(1)
return loclist
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -14,36 +14,34 @@ if exists('g:loaded_syntastic_javascript_jshint_checker')
endif endif
let g:loaded_syntastic_javascript_jshint_checker = 1 let g:loaded_syntastic_javascript_jshint_checker = 1
if !exists('g:syntastic_javascript_jshint_conf')
let g:syntastic_javascript_jshint_conf = ''
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_javascript_jshint_IsAvailable() dict function! SyntaxCheckers_javascript_jshint_IsAvailable() dict
if !exists('g:syntastic_jshint_exec') call syntastic#log#deprecationWarn('jshint_exec', 'javascript_jshint_exec')
let g:syntastic_jshint_exec = self.getExec() if !executable(self.getExec())
return 0
endif endif
return executable(expand(g:syntastic_jshint_exec)) let s:jshint_version = syntastic#util#getVersion(self.getExecEscaped() . ' --version')
return syntastic#util#versionIsAtLeast(s:jshint_version, [1])
endfunction endfunction
function! SyntaxCheckers_javascript_jshint_GetLocList() dict function! SyntaxCheckers_javascript_jshint_GetLocList() dict
let exe = syntastic#util#shexpand(g:syntastic_jshint_exec) call syntastic#log#deprecationWarn('javascript_jshint_conf', 'javascript_jshint_args',
\ "'--config ' . syntastic#util#shexpand(OLD_VAR)")
if !exists('s:jshint_new') if !exists('s:jshint_new')
let s:jshint_new = let s:jshint_new = syntastic#util#versionIsAtLeast(s:jshint_version, [1, 1])
\ syntastic#util#versionIsAtLeast(syntastic#util#getVersion(exe . ' --version'), [1, 1])
endif endif
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({ 'args_after': (s:jshint_new ? '--verbose ' : '') })
\ 'exe': exe,
\ 'args': (g:syntastic_javascript_jshint_conf != '' ? '--config ' . g:syntastic_javascript_jshint_conf : ''),
\ 'args_after': (s:jshint_new ? '--verbose ' : '') })
let errorformat = s:jshint_new ? let errorformat = s:jshint_new ?
\ '%A%f: line %l\, col %v\, %m \(%t%*\d\)' : \ '%A%f: line %l\, col %v\, %m \(%t%*\d\)' :
\ '%E%f: line %l\, col %v\, %m' \ '%E%f: line %l\, col %v\, %m'
call self.setWantSort(1)
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,

View file

@ -14,16 +14,14 @@ if exists("g:loaded_syntastic_javascript_jsl_checker")
endif endif
let g:loaded_syntastic_javascript_jsl_checker = 1 let g:loaded_syntastic_javascript_jsl_checker = 1
if !exists("g:syntastic_javascript_jsl_conf")
let g:syntastic_javascript_jsl_conf = ""
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_javascript_jsl_GetLocList() dict function! SyntaxCheckers_javascript_jsl_GetLocList() dict
call syntastic#log#deprecationWarn('javascript_jsl_conf', 'javascript_jsl_args',
\ "'-conf ' . syntastic#util#shexpand(OLD_VAR)")
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'args': (g:syntastic_javascript_jsl_conf != '' ? '-conf ' . g:syntastic_javascript_jsl_conf : ''),
\ 'args_after': '-nologo -nofilelisting -nosummary -nocontext -process' }) \ 'args_after': '-nologo -nofilelisting -nosummary -nocontext -process' })
let errorformat = let errorformat =

View file

@ -22,7 +22,7 @@ set cpo&vim
function! SyntaxCheckers_javascript_jslint_GetHighlightRegex(item) function! SyntaxCheckers_javascript_jslint_GetHighlightRegex(item)
let term = matchstr(a:item['text'], '\mExpected .* and instead saw ''\zs.*\ze''') let term = matchstr(a:item['text'], '\mExpected .* and instead saw ''\zs.*\ze''')
if term != '' if term != ''
let term = '\V' . escape(term, '\') let term = '\V\<' . escape(term, '\') . '\>'
endif endif
return term return term
endfunction endfunction

View file

@ -18,10 +18,6 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_javascript_jsxhint_IsAvailable() dict function! SyntaxCheckers_javascript_jsxhint_IsAvailable() dict
if !executable('jshint') || !syntastic#util#versionIsAtLeast(syntastic#util#getVersion('jshint --version'), [1, 1])
return 0
endif
let jsxhint_version = system(self.getExecEscaped() . ' --version') let jsxhint_version = system(self.getExecEscaped() . ' --version')
return return
\ v:shell_error == 0 && \ v:shell_error == 0 &&

View file

@ -58,6 +58,7 @@ function! SyntaxCheckers_less_lessc_GetLocList() dict
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'postprocess': ['guards'],
\ 'defaults': {'bufnr': bufnr(""), 'text': "Syntax error"} }) \ 'defaults': {'bufnr': bufnr(""), 'text': "Syntax error"} })
endfunction endfunction

View file

@ -20,13 +20,14 @@ set cpo&vim
function! SyntaxCheckers_lisp_clisp_GetLocList() dict function! SyntaxCheckers_lisp_clisp_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'args_after': '-q -c ' . syntastic#c#NullOutput() }) \ 'args_after': '-q',
\ 'fname_before': '-c' })
let errorformat = let errorformat =
\ '%-G;%.%#,' . \ '%-G;%.%#,' .
\ '%W%>WARNING:%.%#line %l : %m,' . \ '%W%>WARNING:%.%# line %l : %m,' .
\ '%Z %#%m,' . \ '%Z %#%m,' .
\ '%W%>WARNING:%.%#lines %l..%\d\# : %m,' . \ '%W%>WARNING:%.%# lines %l%\%.%\%.%\d%\+ : %m,' .
\ '%Z %#%m,' . \ '%Z %#%m,' .
\ '%E%>The following functions were %m,' . \ '%E%>The following functions were %m,' .
\ '%Z %m,' . \ '%Z %m,' .

View file

@ -71,7 +71,7 @@ if !exists('g:syntastic_ocaml_use_ocamlc') || !executable('ocamlc')
endif endif
if !exists('g:syntastic_ocaml_use_janestreet_core') if !exists('g:syntastic_ocaml_use_janestreet_core')
let g:syntastic_ocaml_use_ocamlc = 0 let g:syntastic_ocaml_use_janestreet_core = 0
endif endif
if !exists('g:syntastic_ocaml_use_ocamlbuild') || !executable("ocamlbuild") if !exists('g:syntastic_ocaml_use_ocamlbuild') || !executable("ocamlbuild")

View file

@ -50,25 +50,25 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_perl_perl_IsAvailable() dict function! SyntaxCheckers_perl_perl_IsAvailable() dict
if !exists('g:syntastic_perl_interpreter') if !exists('g:syntastic_perl_perl_exec') && exists('g:syntastic_perl_interpreter')
let g:syntastic_perl_interpreter = self.getExec() let g:syntastic_perl_perl_exec = g:syntastic_perl_interpreter
endif endif
" don't call executable() here, to allow things like " don't call executable() here, to allow things like
" let g:syntastic_perl_interpreter='/usr/bin/env perl' " let g:syntastic_perl_interpreter='/usr/bin/env perl'
silent! call system(syntastic#util#shexpand(g:syntastic_perl_interpreter) . ' -e ' . syntastic#util#shescape('exit(0)')) silent! call system(self.getExecEscaped() . ' -e ' . syntastic#util#shescape('exit(0)'))
return v:shell_error == 0 return v:shell_error == 0
endfunction endfunction
function! SyntaxCheckers_perl_perl_GetLocList() dict function! SyntaxCheckers_perl_perl_GetLocList() dict
if !exists('g:syntastic_enable_perl_checker') || !g:syntastic_enable_perl_checker if !exists('g:syntastic_enable_perl_checker') || !g:syntastic_enable_perl_checker
call syntastic#log#error('checker perl/perl: checks disabled for security reasons; set g:syntastic_enable_perl_checker to 1 to override') call syntastic#log#error('checker perl/perl: checks disabled for security reasons; ' .
\ 'set g:syntastic_enable_perl_checker to 1 to override')
return [] return []
endif endif
let exe = expand(g:syntastic_perl_interpreter)
if type(g:syntastic_perl_lib_path) == type('') if type(g:syntastic_perl_lib_path) == type('')
call syntastic#log#deprecationWarn('variable g:syntastic_perl_lib_path should be a list') call syntastic#log#oneTimeWarn('variable g:syntastic_perl_lib_path should be a list')
let includes = split(g:syntastic_perl_lib_path, ',') let includes = split(g:syntastic_perl_lib_path, ',')
else else
let includes = copy(syntastic#util#var('perl_lib_path')) let includes = copy(syntastic#util#var('perl_lib_path'))
@ -79,9 +79,7 @@ function! SyntaxCheckers_perl_perl_GetLocList() dict
\ (index(shebang['args'], '-t') >= 0 ? ' -t' : '') \ (index(shebang['args'], '-t') >= 0 ? ' -t' : '')
let errorformat = '%f:%l:%m' let errorformat = '%f:%l:%m'
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({ 'args_before': '-c -X ' . extra })
\ 'exe': exe,
\ 'args_before': '-c -X ' . extra })
let errors = SyntasticMake({ let errors = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
@ -92,9 +90,7 @@ function! SyntaxCheckers_perl_perl_GetLocList() dict
return errors return errors
endif endif
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({ 'args_before': '-c -Mwarnings ' . extra })
\ 'exe': exe,
\ 'args_before': '-c -Mwarnings ' . extra })
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,

View file

@ -38,7 +38,8 @@ function! SyntaxCheckers_php_php_GetLocList() dict
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat }) \ 'errorformat': errorformat,
\ 'postprocess': ['guards'] })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -27,8 +27,8 @@ function! SyntaxCheckers_php_phpcs_GetLocList() dict
\ 'args_after': '--report=csv' }) \ 'args_after': '--report=csv' })
let errorformat = let errorformat =
\ '%-GFile\,Line\,Column\,Type\,Message\,Source\,Severity,'. \ '%-GFile\,Line\,Column\,Type\,Message\,Source\,Severity%.%#,'.
\ '"%f"\,%l\,%v\,%t%*[a-zA-Z]\,"%m"\,%*[a-zA-Z0-9_.-]\,%*[0-9]' \ '"%f"\,%l\,%v\,%t%*[a-zA-Z]\,"%m"\,%*[a-zA-Z0-9_.-]\,%*[0-9]%.%#'
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,

View file

@ -32,8 +32,8 @@ function! SyntaxCheckers_puppet_puppet_GetLocList() dict
let errorformat = let errorformat =
\ '%-Gerr: Try ''puppet help parser validate'' for usage,' . \ '%-Gerr: Try ''puppet help parser validate'' for usage,' .
\ '%-GError: Try ''puppet help parser validate'' for usage,' . \ '%-GError: Try ''puppet help parser validate'' for usage,' .
\ '%Eerr: Could not parse for environment %*[a-z]: %m at %f:%l,' . \ '%A%t%*[a-zA-Z]: %m at %f:%l:%c,' .
\ '%EError: Could not parse for environment %*[a-z]: %m at %f:%l' \ '%A%t%*[a-zA-Z]: %m at %f:%l'
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,

View file

@ -18,11 +18,6 @@ let g:loaded_syntastic_puppet_puppetlint_checker = 1
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
if exists("g:syntastic_puppet_lint_arguments")
let g:syntastic_puppet_puppetlint_args = g:syntastic_puppet_lint_arguments
call syntastic#log#deprecationWarn("variable g:syntastic_puppet_lint_arguments is deprecated, please use g:syntastic_puppet_puppetlint_args instead")
endif
function! SyntaxCheckers_puppet_puppetlint_IsAvailable() dict function! SyntaxCheckers_puppet_puppetlint_IsAvailable() dict
return return
\ executable("puppet") && \ executable("puppet") &&
@ -32,6 +27,8 @@ function! SyntaxCheckers_puppet_puppetlint_IsAvailable() dict
endfunction endfunction
function! SyntaxCheckers_puppet_puppetlint_GetLocList() dict function! SyntaxCheckers_puppet_puppetlint_GetLocList() dict
call syntastic#log#deprecationWarn('puppet_lint_arguments', 'puppet_puppetlint_args')
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'args_after': '--log-format "%{KIND} [%{check}] %{message} at %{fullpath}:%{linenumber}"' }) \ 'args_after': '--log-format "%{KIND} [%{check}] %{message} at %{fullpath}:%{linenumber}"' })

View file

@ -27,9 +27,12 @@ function! SyntaxCheckers_python_flake8_GetLocList() dict
\ '%A%f:%l: %t%n %m,' . \ '%A%f:%l: %t%n %m,' .
\ '%-G%.%#' \ '%-G%.%#'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat }) \ 'errorformat': errorformat,
\ 'env': env })
for e in loclist for e in loclist
" E*** and W*** are pep8 errors " E*** and W*** are pep8 errors

View file

@ -27,9 +27,12 @@ function! SyntaxCheckers_python_frosted_GetLocList() dict
\ '%-Z%p^,' . \ '%-Z%p^,' .
\ '%-G%.%#' \ '%-G%.%#'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env,
\ 'returns': [0, 1] }) \ 'returns': [0, 1] })
for e in loclist for e in loclist
@ -39,7 +42,7 @@ function! SyntaxCheckers_python_frosted_GetLocList() dict
if len(parts) >= 4 if len(parts) >= 4
let e["type"] = parts[1][0] let e["type"] = parts[1][0]
let e["text"] = parts[3] . ' [' . parts[1] . ']' let e["text"] = parts[3] . ' [' . parts[1] . ']'
let e["hl"] = '\V' . escape(parts[2], '\') let e["hl"] = '\V\<' . escape(parts[2], '\') . '\>'
elseif e["text"] =~? '\v^I\d+:' elseif e["text"] =~? '\v^I\d+:'
let e["valid"] = 0 let e["valid"] = 0
else else

View file

@ -5,7 +5,7 @@
" "
" For details about pep257 see: https://github.com/GreenSteam/pep257 " For details about pep257 see: https://github.com/GreenSteam/pep257
if exists("g:loaded_syntastic_python_pep257_checker") if exists('g:loaded_syntastic_python_pep257_checker')
finish finish
endif endif
let g:loaded_syntastic_python_pep257_checker = 1 let g:loaded_syntastic_python_pep257_checker = 1
@ -14,24 +14,40 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_python_pep257_GetLocList() dict function! SyntaxCheckers_python_pep257_GetLocList() dict
if !exists('s:pep257_new')
let s:pep257_new = syntastic#util#versionIsAtLeast(syntastic#util#getVersion(
\ self.getExecEscaped() . ' --version'), [0, 3])
endif
let makeprg = self.makeprgBuild({}) let makeprg = self.makeprgBuild({})
let errorformat = if s:pep257_new
\ '%E%f:%l:%c%\%.%\%.%\d%\+:%\d%\+: %m,' . let errorformat =
\ '%E%f:%l:%c: %m,' . \ '%E%f:%l %.%#:,' .
\ '%+C %m' \ '%+C %m'
else
let errorformat =
\ '%E%f:%l:%c%\%.%\%.%\d%\+:%\d%\+: %m,' .
\ '%E%f:%l:%c: %m,' .
\ '%+C %m'
endif
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env,
\ 'subtype': 'Style', \ 'subtype': 'Style',
\ 'preprocess': 'killEmpty', \ 'preprocess': 'killEmpty',
\ 'postprocess': ['compressWhitespace'] }) \ 'postprocess': ['compressWhitespace'] })
" pep257 outputs byte offsets rather than column numbers if s:pep257_new == 0
for e in loclist " byte offsets rather than column numbers
let e['col'] = get(e, 'col', 0) + 1 for e in loclist
endfor let e['col'] = get(e, 'col', 0) + 1
endfor
endif
return loclist return loclist
endfunction endfunction

View file

@ -25,9 +25,12 @@ function! SyntaxCheckers_python_pep8_GetLocList() dict
let errorformat = '%f:%l:%c: %m' let errorformat = '%f:%l:%c: %m'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env,
\ 'subtype': 'Style' }) \ 'subtype': 'Style' })
for e in loclist for e in loclist

View file

@ -18,9 +18,12 @@ function! SyntaxCheckers_python_py3kwarn_GetLocList() dict
let errorformat = '%W%f:%l:%c: %m' let errorformat = '%W%f:%l:%c: %m'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat }) \ 'errorformat': errorformat,
\ 'env': env })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -26,14 +26,14 @@ function! SyntaxCheckers_python_pyflakes_GetHighlightRegex(i)
\ || stridx(a:i['text'], 'shadowed by loop variable') >= 0 \ || stridx(a:i['text'], 'shadowed by loop variable') >= 0
" fun with Python's %r: try "..." first, then '...' " fun with Python's %r: try "..." first, then '...'
let terms = split(a:i['text'], '"', 1) let term = matchstr(a:i['text'], '\m^.\{-}"\zs.\{-1,}\ze"')
if len(terms) > 2 if term != ''
return terms[1] return '\V\<' . escape(term, '\') . '\>'
endif endif
let terms = split(a:i['text'], "'", 1) let term = matchstr(a:i['text'], '\m^.\{-}''\zs.\{-1,}\ze''')
if len(terms) > 2 if term != ''
return terms[1] return '\V\<' . escape(term, '\') . '\>'
endif endif
endif endif
return '' return ''
@ -49,9 +49,12 @@ function! SyntaxCheckers_python_pyflakes_GetLocList() dict
\ '%E%f:%l: %m,'. \ '%E%f:%l: %m,'.
\ '%-G%.%#' \ '%-G%.%#'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env,
\ 'defaults': {'text': "Syntax error"} }) \ 'defaults': {'text': "Syntax error"} })
for e in loclist for e in loclist

View file

@ -30,10 +30,12 @@ function! SyntaxCheckers_python_pylama_GetLocList() dict
\ '%-GWARNING:pylama:%.%#,' . \ '%-GWARNING:pylama:%.%#,' .
\ '%A%f:%l:%c: %m' \ '%A%f:%l:%c: %m'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'postprocess': ['sort'] }) \ 'env': env })
" adjust for weirdness in each checker " adjust for weirdness in each checker
for e in loclist for e in loclist
@ -53,6 +55,8 @@ function! SyntaxCheckers_python_pylama_GetLocList() dict
endif endif
endfor endfor
call self.setWantSort(1)
return loclist return loclist
endfunction endfunction

View file

@ -32,10 +32,12 @@ function! SyntaxCheckers_python_pylint_GetLocList() dict
\ '%-Z%p^%.%#,' . \ '%-Z%p^%.%#,' .
\ '%-G%.%#' \ '%-G%.%#'
let loclist=SyntasticMake({ let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'postprocess': ['sort'], \ 'env': env,
\ 'returns': range(32) }) \ 'returns': range(32) })
for e in loclist for e in loclist
@ -55,6 +57,8 @@ function! SyntaxCheckers_python_pylint_GetLocList() dict
let e['vcol'] = 0 let e['vcol'] = 0
endfor endfor
call self.setWantSort(1)
return loclist return loclist
endfunction endfunction
@ -63,9 +67,12 @@ function! s:PylintNew(exe)
try try
" On Windows the version is shown as "pylint-script.py 1.0.0". " On Windows the version is shown as "pylint-script.py 1.0.0".
" On Gentoo Linux it's "pylint-python2.7 0.28.0". " On Gentoo Linux it's "pylint-python2.7 0.28.0".
" On NixOS, that would be ".pylint-wrapped 0.26.0", that would be. " On NixOS, that would be ".pylint-wrapped 0.26.0".
" On Arch Linux it's "pylint2 1.1.0".
" On new-ish Fedora it's "python3-pylint 1.2.0".
" Have you guys considered switching to creative writing yet? ;) " Have you guys considered switching to creative writing yet? ;)
let pylint_version = filter(split(system(exe . ' --version'), '\m, \=\|\n'), 'v:val =~# ''\m^\.\=pylint\>''')[0] let pylint_version = filter( split(system(exe . ' --version'), '\m, \=\|\n'),
\ 'v:val =~# ''\m^\(python[-0-9]*-\|\.\)\=pylint[-0-9]*\>''' )[0]
let pylint_version = substitute(pylint_version, '\v^\S+\s+', '', '') let pylint_version = substitute(pylint_version, '\v^\S+\s+', '', '')
let ret = syntastic#util#versionIsAtLeast(syntastic#util#parseVersion(pylint_version), [1]) let ret = syntastic#util#versionIsAtLeast(syntastic#util#parseVersion(pylint_version), [1])
catch /\m^Vim\%((\a\+)\)\=:E684/ catch /\m^Vim\%((\a\+)\)\=:E684/

View file

@ -30,9 +30,12 @@ function! SyntaxCheckers_python_python_GetLocList() dict
let errorformat = '%E%f:%l:%c: %m' let errorformat = '%E%f:%l:%c: %m'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env,
\ 'returns': [0] }) \ 'returns': [0] })
endfunction endfunction

View file

@ -38,13 +38,14 @@ function! SyntaxCheckers_racket_code_ayatollah_GetLocList() dict
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'subtype': 'Style', \ 'subtype': 'Style' })
\ 'postprocess': ['sort'] })
for e in loclist for e in loclist
let e['col'] += 1 let e['col'] += 1
endfor endfor
call self.setWantSort(1)
return loclist return loclist
endfunction endfunction

View file

@ -19,17 +19,8 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_ruby_jruby_GetLocList() dict function! SyntaxCheckers_ruby_jruby_GetLocList() dict
if syntastic#util#isRunningWindows()
let exe = self.getExecEscaped()
let args = '-T1'
else
let exe = 'RUBYOPT= ' . self.getExecEscaped()
let args = ''
endif
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'exe': exe, \ 'args': (syntastic#util#isRunningWindows() ? '-T1' : ''),
\ 'args': args,
\ 'args_after': '-W1 -c' }) \ 'args_after': '-W1 -c' })
let errorformat = let errorformat =
@ -41,9 +32,12 @@ function! SyntaxCheckers_ruby_jruby_GetLocList() dict
\ '%W%f:%l: %m,'. \ '%W%f:%l: %m,'.
\ '%-C%.%#' \ '%-C%.%#'
let env = syntastic#util#isRunningWindows() ? {} : { 'RUBYOPT': '' }
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat }) \ 'errorformat': errorformat,
\ 'env': env })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -18,9 +18,7 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_ruby_macruby_GetLocList() dict function! SyntaxCheckers_ruby_macruby_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({ 'args_after': '-W1 -c' })
\ 'exe': 'RUBYOPT= ' . self.getExecEscaped(),
\ 'args_after': '-W1 -c' })
let errorformat = let errorformat =
\ '%-GSyntax OK,'. \ '%-GSyntax OK,'.
@ -31,9 +29,12 @@ function! SyntaxCheckers_ruby_macruby_GetLocList() dict
\ '%W%f:%l: %m,'. \ '%W%f:%l: %m,'.
\ '%-C%.%#' \ '%-C%.%#'
let env = { 'RUBYOPT': '' }
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat }) \ 'errorformat': errorformat,
\ 'env': env })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -18,6 +18,13 @@ let g:loaded_syntastic_ruby_mri_checker = 1
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_ruby_mri_IsAvailable() dict
if !exists('g:syntastic_ruby_mri_exec') && exists('g:syntastic_ruby_exec')
let g:syntastic_ruby_mri_exec = g:syntastic_ruby_exec
endif
return executable(self.getExec())
endfunction
function! SyntaxCheckers_ruby_mri_GetHighlightRegex(i) function! SyntaxCheckers_ruby_mri_GetHighlightRegex(i)
if stridx(a:i['text'], 'assigned but unused variable') >= 0 if stridx(a:i['text'], 'assigned but unused variable') >= 0
let term = split(a:i['text'], ' - ')[1] let term = split(a:i['text'], ' - ')[1]
@ -28,18 +35,7 @@ function! SyntaxCheckers_ruby_mri_GetHighlightRegex(i)
endfunction endfunction
function! SyntaxCheckers_ruby_mri_GetLocList() dict function! SyntaxCheckers_ruby_mri_GetLocList() dict
if !exists('g:syntastic_ruby_exec') let makeprg = self.makeprgBuild({ 'args_after': '-w -T1 -c' })
let g:syntastic_ruby_exec = self.getExec()
endif
let exe = syntastic#util#shexpand(g:syntastic_ruby_exec)
if !syntastic#util#isRunningWindows()
let exe = 'RUBYOPT= ' . exe
endif
let makeprg = self.makeprgBuild({
\ 'exe': exe,
\ 'args_after': '-w -T1 -c' })
"this is a hack to filter out a repeated useless warning in rspec files "this is a hack to filter out a repeated useless warning in rspec files
"containing lines like "containing lines like
@ -48,7 +44,7 @@ function! SyntaxCheckers_ruby_mri_GetLocList() dict
" "
"Which always generate the warning below. Note that ruby >= 1.9.3 includes "Which always generate the warning below. Note that ruby >= 1.9.3 includes
"the word "possibly" in the warning "the word "possibly" in the warning
let errorformat = '%-G%.%#warning: %\(possibly %\)%\?useless use of == in void context,' let errorformat = '%-G%\m%.%#warning: %\%%(possibly %\)%\?useless use of == in void context,'
" filter out lines starting with ... " filter out lines starting with ...
" long lines are truncated and wrapped in ... %p then returns the wrong " long lines are truncated and wrapped in ... %p then returns the wrong
@ -64,9 +60,12 @@ function! SyntaxCheckers_ruby_mri_GetLocList() dict
\ '%W%f:%l: %m,'. \ '%W%f:%l: %m,'.
\ '%-C%.%#' \ '%-C%.%#'
let env = syntastic#util#isRunningWindows() ? {} : { 'RUBYOPT': '' }
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat }) \ 'errorformat': errorformat,
\ 'env': env })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -20,7 +20,11 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_ruby_rubylint_GetLocList() dict function! SyntaxCheckers_ruby_rubylint_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args': 'analyze --presenter=syntastic' }) if !exists('s:rubylint_new')
let s:rubylint_new = syntastic#util#versionIsAtLeast(syntastic#util#getVersion(
\ self.getExecEscaped() . ' --version'), [2])
endif
let makeprg = self.makeprgBuild({ 'args': (s:rubylint_new ? '' : 'analyze ') . '--presenter=syntastic' })
let errorformat = '%f:%t:%l:%c: %m' let errorformat = '%f:%t:%l:%c: %m'

View file

@ -18,6 +18,7 @@ let g:loaded_syntastic_sass_sass_checker = 1
"sass caching for large files drastically speeds up the checking, but store it "sass caching for large files drastically speeds up the checking, but store it
"in a temp location otherwise sass puts .sass_cache dirs in the users project "in a temp location otherwise sass puts .sass_cache dirs in the users project
let s:sass_cache_location = tempname() let s:sass_cache_location = tempname()
lockvar s:sass_cache_location
"By default do not check partials as unknown variables are a syntax error "By default do not check partials as unknown variables are a syntax error
if !exists("g:syntastic_sass_check_partials") if !exists("g:syntastic_sass_check_partials")
@ -42,7 +43,7 @@ function! SyntaxCheckers_sass_sass_GetLocList() dict
\ 'args_before': '--cache-location ' . s:sass_cache_location . ' ' . s:imports . ' --check' }) \ 'args_before': '--cache-location ' . s:sass_cache_location . ' ' . s:imports . ' --check' })
let errorformat = let errorformat =
\ '%ESyntax %trror: %m,' . \ '%E%\m%\%%(Syntax %\)%\?%trror: %m,' .
\ '%+C %.%#,' . \ '%+C %.%#,' .
\ '%C on line %l of %f\, %.%#,' . \ '%C on line %l of %f\, %.%#,' .
\ '%C on line %l of %f,' . \ '%C on line %l of %f,' .

View file

@ -15,19 +15,16 @@ if exists('g:loaded_syntastic_scala_fsc_checker')
endif endif
let g:loaded_syntastic_scala_fsc_checker = 1 let g:loaded_syntastic_scala_fsc_checker = 1
if !exists('g:syntastic_scala_options')
let g:syntastic_scala_options = ''
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_scala_fsc_GetLocList() dict function! SyntaxCheckers_scala_fsc_GetLocList() dict
call syntastic#log#deprecationWarn('scala_options', 'scala_fsc_args')
" fsc has some serious problems with the " fsc has some serious problems with the
" working directory changing after being started " working directory changing after being started
" that's why we better pass an absolute path " that's why we better pass an absolute path
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'args': g:syntastic_scala_options,
\ 'args_after': '-Ystop-after:parser', \ 'args_after': '-Ystop-after:parser',
\ 'fname': syntastic#util#shexpand('%:p') }) \ 'fname': syntastic#util#shexpand('%:p') })

View file

@ -15,17 +15,13 @@ if exists("g:loaded_syntastic_scala_scalac_checker")
endif endif
let g:loaded_syntastic_scala_scalac_checker = 1 let g:loaded_syntastic_scala_scalac_checker = 1
if !exists('g:syntastic_scala_options')
let g:syntastic_scala_options = ''
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_scala_scalac_GetLocList() dict function! SyntaxCheckers_scala_scalac_GetLocList() dict
let makeprg = self.makeprgBuild({ call syntastic#log#deprecationWarn('scala_options', 'scala_scalac_args')
\ 'args': g:syntastic_scala_options,
\ 'args_after': '-Ystop-after:parser' }) let makeprg = self.makeprgBuild({ 'args_after': '-Ystop-after:parser' })
let errorformat = let errorformat =
\ '%E%f:%l: %trror: %m,' . \ '%E%f:%l: %trror: %m,' .

View file

@ -1,4 +1,3 @@
"============================================================================ "============================================================================
"File: scss.vim "File: scss.vim
"Description: scss syntax checking plugin for syntastic "Description: scss syntax checking plugin for syntastic

View file

@ -31,7 +31,7 @@ function! SyntaxCheckers_scss_scss_lint_GetLocList() dict
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'subtype': 'Style', \ 'subtype': 'Style',
\ 'returns': [0, 1, 65] }) \ 'returns': [0, 1, 2, 65, 66] })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -18,41 +18,6 @@ let g:loaded_syntastic_sh_sh_checker = 1
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! s:GetShell()
if !exists('b:shell') || b:shell == ''
let b:shell = ''
let shebang = getbufline(bufnr('%'), 1)[0]
if shebang != ''
if stridx(shebang, 'bash') >= 0
let b:shell = 'bash'
elseif stridx(shebang, 'zsh') >= 0
let b:shell = 'zsh'
elseif stridx(shebang, 'sh') >= 0
let b:shell = 'sh'
endif
endif
" try to use env variable in case no shebang could be found
if b:shell == ''
let b:shell = fnamemodify(expand('$SHELL'), ':t')
endif
endif
return b:shell
endfunction
function! s:ForwardToZshChecker()
let registry = g:SyntasticRegistry.Instance()
if registry.isCheckable('zsh')
return registry.getCheckers('zsh', ['zsh'])[0].getLocListRaw()
else
return []
endif
endfunction
function! s:IsShellValid()
return len(s:GetShell()) > 0 && executable(s:GetShell())
endfunction
function! SyntaxCheckers_sh_sh_IsAvailable() dict function! SyntaxCheckers_sh_sh_IsAvailable() dict
return s:IsShellValid() return s:IsShellValid()
endfunction endfunction
@ -77,6 +42,42 @@ function! SyntaxCheckers_sh_sh_GetLocList() dict
\ 'errorformat': errorformat }) \ 'errorformat': errorformat })
endfunction endfunction
function! s:GetShell()
if !exists('b:shell') || b:shell == ''
let b:shell = ''
let shebang = syntastic#util#parseShebang()['exe']
if shebang != ''
if shebang[-strlen('bash'):-1] ==# 'bash'
let b:shell = 'bash'
elseif shebang[-strlen('zsh'):-1] ==# 'zsh'
let b:shell = 'zsh'
elseif shebang[-strlen('sh'):-1] ==# 'sh'
let b:shell = 'sh'
endif
endif
" try to use env variable in case no shebang could be found
if b:shell == ''
let b:shell = fnamemodify($SHELL, ':t')
endif
endif
return b:shell
endfunction
function! s:IsShellValid()
let shell = s:GetShell()
return shell != '' && executable(shell)
endfunction
function! s:ForwardToZshChecker()
let registry = g:SyntasticRegistry.Instance()
let zsh_checkers = registry.getCheckersAvailable('zsh', ['zsh'])
if !empty(zsh_checkers)
return zsh_checkers[0].getLocListRaw()
else
return []
endif
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'sh', \ 'filetype': 'sh',
\ 'name': 'sh' }) \ 'name': 'sh' })

View file

@ -45,11 +45,14 @@ function! SyntaxCheckers_tex_chktex_GetLocList() dict
\ '%Z%p^,' . \ '%Z%p^,' .
\ '%-G%.%#' \ '%-G%.%#'
return SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'subtype': 'Style', \ 'subtype': 'Style' })
\ 'postprocess': ['sort'] })
call self.setWantSort(1)
return loclist
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

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