diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 764ffff..378b53b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,49 +1,105 @@
-# Bug reports / Github issues
+# CONTRIBUTING
+- - -
+1\. [Bug reports / GitHub issues](#bugreps)
+2\. [Submitting a patch](#patches)
+3\. [General style notes](#generalstyle)
+4\. [Syntax checker notes](#checkerstyle)
+- - -
-When reporting a bug make sure you search the existing github issues for the
-same/similar issues. If you find one, feel free to add a `+1` comment with any
-additional information that may help us solve the issue.
+
+
+## 1. Bug reports / GitHub issues
+
+Please note that the preferred channel for posting bug reports is the
+[issue tracker at GitHub][0]. Reports posted elsewhere are less likely
+to be seen by the core team.
+
+When reporting a bug make sure you search the existing GitHub issues
+for the same/similar issues. If you find one, feel free to add a `+1`
+comment with any additional information that may help us solve the
+issue.
When creating a new issue be sure to state the following:
-* Steps to reproduce the bug.
-* The version of vim you are using.
-* The version of syntastic you are using.
+* steps to reproduce the bug;
+* the version of Vim you are using (run `:ver` to find out);
+* the version of syntastic you are using (see `:SyntasticInfo`).
+
+For syntax checker bugs also state the version of the checker executable
+that you are using. Adding debugging information is typically useful
+too:
+
+* open a file handled by your checker;
+* set `g:syntastic_debug` to 1 or 3;
+* run the checker;
+* copy the output of `:mes`.
+
+
+
+## 2. Submitting a patch
-For syntax checker bugs also state the version of the checker executable that you are using.
+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.
-# Submitting a patch
+To submit a patch:
-* Fork the repo on github
-* Make a [topic branch](https://github.com/dchelimsky/rspec/wiki/Topic-Branches#using-topic-branches-when-contributing-patches) and start hacking
-* Submit a pull request based off your topic branch
+* fork the [repo][2] on GitHub;
+* make a [topic branch][3] and start hacking;
+* submit a pull request based off your topic branch.
-Small focused patches are preferred.
+Small, focused patches are preferred.
-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.
+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.
-# General style notes
+Also make sure to update the manual whenever applicable. Nobody can use
+features that aren't documented.
-Following the coding conventions/styles used in the syntastic core:
+
-* Use 4 space indents.
-* Don't use abbreviated keywords - e.g. use `endfunction`, not `endfun` (there's always room for more fun!).
-* Don't use `l:` prefixes for variables unless actually required (i.e. almost never).
-* Code for maintainability. We would rather a function be a couple of lines longer and have (for example) some [explaining variables](http://www.refactoring.com/catalog/introduceExplainingVariable.html) to aid readability.
+## 3. General style notes
-# Syntax checker style notes
+Follow the coding conventions/styles used in the syntastic core:
-The preferred style for error format strings is one "clause" per line. E.g.
-(from the coffeelint checker):
+* use 4 space indents;
+* don't use abbreviated keywords - e.g. use `endfunction`, not `endfun`
+(there's always room for more fun!);
+* don't use `l:` prefixes for variables unless actually required (i.e.
+almost never);
+* code for maintainability; we would rather a function be a couple of
+lines longer and have (for example) some [explaining variables][4] to
+aid readability.
-```viml
-let errorformat = '%E%f:%l:%c: %trror: %m,' .
- \ 'Syntax%trror: In %f\, %m on line %l,' .
- \ '%EError: In %f\, Parse error on line %l: %m,' .
- \ '%EError: In %f\, %m on line %l,' .
- \ '%W%f(%l): lint warning: %m,' .
- \ '%W%f(%l): warning: %m,' .
- \ '%E%f(%l): SyntaxError: %m,' .
- \ '%-Z%p^,' .
- \ '%-G%.%#'
+
+
+## 4. Syntax checker notes
+
+Make sure to read the [guide][5] if you plan to add new syntax checkers.
+
+Use the existing checkers as templates, rather than writing everything
+from scratch.
+
+The preferred style for error format strings is one "clause" per line.
+E.g. (from the `coffee` checker):
+
+```vim
+let errorformat =
+ \ '%E%f:%l:%c: %trror: %m,' .
+ \ 'Syntax%trror: In %f\, %m on line %l,' .
+ \ '%EError: In %f\, Parse error on line %l: %m,' .
+ \ '%EError: In %f\, %m on line %l,' .
+ \ '%W%f(%l): lint warning: %m,' .
+ \ '%W%f(%l): warning: %m,' .
+ \ '%E%f(%l): SyntaxError: %m,' .
+ \ '%-Z%p^,' .
+ \ '%-G%.%#'
```
+
+[0]: https://github.com/scrooloose/syntastic/issues
+[1]: https://github.com/scrooloose/syntastic/blob/master/doc/syntastic.txt
+[2]: https://github.com/scrooloose/syntastic
+[3]: https://github.com/dchelimsky/rspec/wiki/Topic-Branches#using-topic-branches-when-contributing-patches
+[4]: http://www.refactoring.com/catalog/extractVariable.html
+[5]: https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide
diff --git a/README.markdown b/README.markdown
index 04effa5..d0eb41f 100644
--- a/README.markdown
+++ b/README.markdown
@@ -35,15 +35,16 @@ the user is notified and is happy because they didn't have to compile their
code or execute their script to find them.
At the time of this writing, syntax checking plugins exist for ActionScript,
-Ada, AppleScript, AsciiDoc, ASM, BEMHTML, Bourne shell, C, C++, C#, Chef,
-CoffeeScript, Coco, Coq, CSS, Cucumber, CUDA, D, Dart, DocBook, Dust, Elixir,
-Erlang, eRuby, Fortran, Gentoo metadata, GLSL, Go, Haml, Haskell, Haxe,
-Handlebars, HSS, HTML, Java, JavaScript, JSON, LESS, Lex, Limbo, LISP,
-LLVM intermediate language, Lua, MATLAB, NASM, Objective-C, Objective-C++,
-OCaml, Perl, Perl POD, PHP, gettext Portable Object, Puppet, Python, Racket,
-reStructuredText, Ruby, Rust, SASS/SCSS, Scala, Slim, Tcl, TeX, Texinfo, Twig,
-TypeScript, Vala, Verilog, VHDL, VimL, xHtml, XML, XSLT, YACC, YAML, z80, Zope
-page templates, zsh.
+Ada, AppleScript, Arduino, AsciiDoc, ASM, BEMHTML, Bro, Bourne shell, C,
+C++, C#, Cabal, Chef, CoffeeScript, Coco, Coq, CSS, Cucumber, CUDA, D, Dart,
+DocBook, Dust, Elixir, Erlang, eRuby, Fortran, Gentoo metadata, GLSL, Go,
+Haml, Haskell, Haxe, Handlebars, HSS, HTML, Java, JavaScript, JSON, JSX, LESS,
+Lex, Limbo, LISP, LLVM intermediate language, Lua, MATLAB, NASM, Objective-C,
+Objective-C++, OCaml, Perl, Perl POD, PHP, gettext Portable Object, OS X
+and iOS property lists, Puppet, Python, Racket, R, reStructuredText, Ruby,
+SASS/SCSS, Scala, Slim, Tcl, TeX, Texinfo, Twig, TypeScript, Vala, Verilog,
+VHDL, VimL, xHtml, XML, XSLT, YACC, YAML, z80, Zope page templates, and zsh.
+See the [wiki][3] for details about the corresponding supported checkers.
Below is a screenshot showing the methods that Syntastic uses to display syntax
errors. Note that, in practise, you will only have a subset of these methods
@@ -62,45 +63,47 @@ enabled.
## 2\. Installation
-Installing syntastic is easy but first you need to have the pathogen plugin installed. If you already
-have pathogen working then skip Step 1 and go to Step 2.
+Installing syntastic is easy but first you need to have the [pathogen][1]
+plugin installed. If you already have [pathogen][1] working then skip
+[Step 1](#step1) and go to [Step 2](#step2).
+
### 2.1\. Step 1: Install pathogen.vim
-First I'll show you how to install tpope's [pathogen.vim][1] so that it's
-easy to install syntastic. Do this in your Terminal so that you get the
-pathogen.vim file and the directories it needs:
-
- mkdir -p ~/.vim/autoload ~/.vim/bundle; \
- curl -so ~/.vim/autoload/pathogen.vim \
- https://raw.github.com/tpope/vim-pathogen/master/autoload/pathogen.vim
-
-Next you *need to add this* to your ~/.vimrc:
-
- execute pathogen#infect()
+First I'll show you how to install Tim Pope's [pathogen][1] so that it's easy to
+install syntastic. Do this in your terminal so that you get the `pathogen.vim`
+file and the directories it needs:
+```sh
+mkdir -p ~/.vim/autoload ~/.vim/bundle && \
+curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim
+```
+Next you *need* to add this to your `~/.vimrc`:
+```vim
+execute pathogen#infect()
+```
### 2.2\. Step 2: Install syntastic as a pathogen bundle
-You now have pathogen installed and can put syntastic into ~/.vim/bundle like this:
-
-
- cd ~/.vim/bundle
- git clone https://github.com/scrooloose/syntastic.git
-
+You now have pathogen installed and can put syntastic into `~/.vim/bundle` like
+this:
+```sh
+cd ~/.vim/bundle && \
+git clone https://github.com/scrooloose/syntastic.git
+```
Quit vim and start it back up to reload it, then type:
+```vim
+:Helptags
+```
+If you get an error when you do this, then you probably didn't install
+[pathogen][1] right. Go back to [Step 1](#step1) and make sure you did the following:
- :Helptags
-
-If you get an error when you do this, then you probably didn't install pathogen right. Go back to
-step 1 and make sure you did the following:
-
-1. Created both the ~/.vim/autoload and ~/.vim/bundle directories.
-2. Added the "call pathogen#infect()" line to your ~/.vimrc file
-3. Did the git clone of syntastic inside ~/.vim/bundle
+1. Created both the `~/.vim/autoload` and `~/.vim/bundle` directories.
+2. Added the `call pathogen#infect()` line to your `~/.vimrc` file
+3. Did the `git clone` of syntastic inside `~/.vim/bundle`
4. Have permissions to access all of these directories.
@@ -108,91 +111,130 @@ step 1 and make sure you did the following:
## 3\. FAQ
+
+
__Q. I installed syntastic but it isn't reporting any errors...__
A. The most likely reason is that none of the syntax checkers that it requires
-is installed. For example: python requires either `flake8`, `pyflakes`
-or `pylint` to be installed and in `$PATH`. To see which executables are
-supported, just look in `syntax_checkers//*.vim`. Note that aliases
-do not work; the actual executable must be available in your `$PATH`. Symbolic
-links are okay. You can see syntastic's idea of available checkers by running
-`:SyntasticInfo`.
+is installed. For example: by default, python requires either `flake8` or
+`pylint` to be installed and in your `$PATH`. To see which executables are
+supported, look at the [wiki][3]. Note that aliases do not work; the actual
+executables must be available in your `$PATH`. Symbolic links are okay though.
+You can see syntastic's idea of available checkers by running `:SyntasticInfo`.
Another reason it could fail is that either the command line options or the
error output for a syntax checker may have changed. In this case, make sure you
have the latest version of the syntax checker installed. If it still fails then
create an issue - or better yet, create a pull request.
-__Q. Recently some of my syntax checker options have stopped working...__
+
+
+__Q. The `perl` checker has stopped working...__
-A. The options are still there, they have just been renamed. Recently,
-almost all syntax checkers were refactored to use the new `makeprgBuild()`
-function. This made a lot of the old explicit options redundant - as they are
-now implied. The new implied options usually have slightly different names to
-the old options.
+A. The `perl` checker runs `perl -c` against your file, which in turn
+__executes__ any `BEGIN`, `UNITCHECK`, and `CHECK` blocks, and any `use`
+statements in your file (cf. [perlrun][10]). This is probably fine if you
+wrote the file yourself, but it's a security problem if you're checking third
+party files. Since there is currently no way to disable this behaviour while
+still producing useful results, the checker is now disabled by default. To
+(re-)enable it, make sure the `g:syntastic_perl_checkers` list includes `perl`,
+and set `g:syntastic_enable_perl_checker` to 1 in your vimrc:
+```vim
+let g:syntastic_enable_perl_checker = 1
+```
-e.g. Previously there was `g:syntastic_phpcs_conf`, now you must use
-`g:syntastic_php_phpcs_args`. This completely overrides the arguments of
-the checker, including any defaults, so you may need to look up the default
-arguments of the checker and add these in.
+
-See `:help syntastic-checker-options` for more information.
+__Q. What happened to the `rustc` checker?__
+
+A. It has been included in the [Rust compiler package][12]. If you have
+a recent version of the Rust compiler, the checker should be picked up
+automatically by syntastic.
+
+
__Q. I run a checker and the location list is not updated...__
-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
location list to always be updated when you run the checkers, add this line to
your vimrc:
```vim
-let g:syntastic_always_populate_loc_list=1
+let g:syntastic_always_populate_loc_list = 1
```
+
+
__Q. How can I pass additional arguments to a checker?__
A. Almost all syntax checkers use the `makeprgBuild()` function. Those checkers
that do can be configured using global variables. The general form of the
-global args variables are:
-```vim
-syntastic___args
-```
+global `args` variables is `syntastic___args`.
So, If you wanted to pass "--my --args --here" to the ruby mri checker you
would add this line to your vimrc:
```vim
-let g:syntastic_ruby_mri_args="--my --args --here"
+let g:syntastic_ruby_mri_args = "--my --args --here"
```
See `:help syntastic-checker-options` for more information.
+
+
__Q. Syntastic supports several checkers for my filetype - how do I tell it
which one(s) to use?__
A. Stick a line like this in your vimrc:
```vim
-let g:syntastic__checkers=['']
+let g:syntastic__checkers = ['']
```
-To see the list of checkers for your filetype, look in
-`syntax_checkers//`.
+To see the list of supported checkers for your filetype look at the
+[wiki][3].
-e.g. Python has the following checkers: `flake8`, `pyflakes`, `pylint` and a
-native `python` checker.
+e.g. Python has the following checkers, among others: `flake8`, `pyflakes`,
+`pylint` and a native `python` checker.
To tell syntastic to use `pylint`, you would use this setting:
```vim
-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
can be chained together like this:
```vim
-let g:syntastic_php_checkers=['php', 'phpcs', 'phpmd']
+let g:syntastic_php_checkers = ['php', 'phpcs', 'phpmd']
```
This is telling syntastic to run the `php` checker first, and if no errors are
found, run `phpcs`, and then `phpmd`.
+You can also run checkers explicitly by calling `:SyntasticCheck `.
+
+e.g. to run `phpcs` and `phpmd`:
+```vim
+:SyntasticCheck phpcs phpmd
+```
+
+This works for any checkers available for the current filetype, even if they
+aren't listed in `g:syntastic__checkers`. You can't run checkers for
+"foreign" filetypes though (e.g. you can't run, say, a Python checker if the
+current filetype is `php`).
+
+
+
+__Q. How can I display together the errors found by all checkers enabled for
+the current file?__
+
+A. Set `g:syntastic_aggregate_errors` to 1 in your vimrc:
+```vim
+let g:syntastic_aggregate_errors = 1
+```
+
+See `:help syntastic-aggregating-errors` for more details.
+
+
+
__Q. How can I jump between the different errors without using the location
list at the bottom of the window?__
@@ -203,6 +245,8 @@ If you use these commands a lot then you may want to add shortcut mappings to
your vimrc, or install something like [unimpaired][2], which provides such
mappings (among other things).
+
+
__Q. A syntax checker is giving me unwanted/strange style tips?__
A. Some filetypes (e.g. php) have style checkers as well as syntax
@@ -210,6 +254,15 @@ checkers. You can usually configure the options that are passed to the style
checkers, or just disable them. Take a look at the [wiki][3] to see what
options are available.
+Alternatively, you can use `g:syntastic_quiet_messages` to filter out the
+messages you don't want to see. e.g. To turn off all style messages:
+```vim
+let g:syntastic_quiet_messages = { "type": "style" }
+```
+See `:help syntastic_quiet_messages` for details.
+
+
+
__Q. The error window is closed automatically when I :quit the current buffer
but not when I :bdelete it?__
@@ -227,8 +280,10 @@ cabbrev bd lclose\|bdelete
## 4\. Other resources
The preferred place for posting suggestions, reporting bugs, and general
-discussions related to syntastic is the [issue tracker at GitHub][4]. There
-are also a [google group][5], and a [syntastic tag at StackOverflow][6].
+discussions related to syntastic is the [issue tracker at GitHub][4].
+A guide for writing syntax checkers can be found in the [wiki][11].
+There are also a dedicated [google group][5], and a
+[syntastic tag at StackOverflow][6].
Syntastic aims to provide a common interface to syntax checkers for as many
languages as possible. For particular languages, there are, of course, other
@@ -244,4 +299,7 @@ a look at [jedi-vim][7], [python-mode][8], or [YouCompleteMe][9].
[6]: http://stackoverflow.com/questions/tagged/syntastic
[7]: https://github.com/davidhalter/jedi-vim
[8]: https://github.com/klen/python-mode
-[9]: https://github.com/Valloric/YouCompleteMe
+[9]: http://valloric.github.io/YouCompleteMe/
+[10]: http://perldoc.perl.org/perlrun.html#*-c*
+[11]: https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide
+[12]: https://github.com/rust-lang/rust/
diff --git a/autoload/syntastic/c.vim b/autoload/syntastic/c.vim
index 82f4c70..5dad140 100644
--- a/autoload/syntastic/c.vim
+++ b/autoload/syntastic/c.vim
@@ -1,4 +1,4 @@
-if exists("g:loaded_syntastic_c_autoload")
+if exists("g:loaded_syntastic_c_autoload") || !exists("g:loaded_syntastic_plugin")
finish
endif
let g:loaded_syntastic_c_autoload = 1
@@ -10,14 +10,14 @@ set cpo&vim
" convenience function to determine the 'null device' parameter
" based on the current operating system
-function! syntastic#c#NullOutput()
+function! syntastic#c#NullOutput() " {{{2
let known_os = has('unix') || has('mac') || syntastic#util#isRunningWindows()
return known_os ? '-o ' . syntastic#util#DevNull() : ''
-endfunction
+endfunction " }}}2
" read additional compiler flags from the given configuration file
" the file format and its parsing mechanism is inspired by clang_complete
-function! syntastic#c#ReadConfig(file)
+function! syntastic#c#ReadConfig(file) " {{{2
" search in the current file's directory upwards
let config = findfile(a:file, '.;')
if config == '' || !filereadable(config)
@@ -30,7 +30,7 @@ function! syntastic#c#ReadConfig(file)
" try to read config file
try
let lines = readfile(config)
- catch /^Vim\%((\a\+)\)\=:E48[45]/
+ catch /\m^Vim\%((\a\+)\)\=:E48[45]/
return ''
endtry
@@ -57,12 +57,12 @@ function! syntastic#c#ReadConfig(file)
endfor
return join(map(parameters, 'syntastic#util#shescape(v:val)'))
-endfunction
+endfunction " }}}2
" GetLocList() for C-like compilers
-function! syntastic#c#GetLocList(filetype, subchecker, options)
+function! syntastic#c#GetLocList(filetype, subchecker, options) " {{{2
try
- let flags = s:GetCflags(a:filetype, a:subchecker, a:options)
+ let flags = s:_getCflags(a:filetype, a:subchecker, a:options)
catch /\m\C^Syntastic: skip checks$/
return []
endtry
@@ -70,9 +70,9 @@ function! syntastic#c#GetLocList(filetype, subchecker, options)
let makeprg = syntastic#util#shexpand(g:syntastic_{a:filetype}_compiler) .
\ ' ' . flags . ' ' . syntastic#util#shexpand('%')
- let errorformat = s:GetCheckerVar('g', a:filetype, a:subchecker, 'errorformat', a:options['errorformat'])
+ let errorformat = s:_getCheckerVar('g', a:filetype, a:subchecker, 'errorformat', a:options['errorformat'])
- let postprocess = s:GetCheckerVar('g', a:filetype, a:subchecker, 'remove_include_errors', 0) ?
+ let postprocess = s:_getCheckerVar('g', a:filetype, a:subchecker, 'remove_include_errors', 0) ?
\ ['filterForeignErrors'] : []
" process makeprg
@@ -80,34 +80,45 @@ function! syntastic#c#GetLocList(filetype, subchecker, options)
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'postprocess': postprocess })
-endfunction
+endfunction " }}}2
+
+" }}}1
" Private functions {{{1
" initialize c/cpp syntax checker handlers
-function! s:Init()
+function! s:_init() " {{{2
let s:handlers = []
let s:cflags = {}
- call s:RegHandler('\m\', 'syntastic#c#CheckPhp', [])
- call s:RegHandler('\m\', 'syntastic#c#CheckPython', [])
- call s:RegHandler('\m\', 'syntastic#c#checkPHP', [])
+ call s:_regHandler('\m\', 'syntastic#c#checkPython', [])
+ call s:_regHandler('\m\"
echohl ErrorMsg
echomsg "syntastic: error: " . a:msg
echohl None
-endfunction
+endfunction " }}}2
-function! syntastic#log#deprecationWarn(msg)
- if index(s:deprecation_notices_issued, a:msg) >= 0
+function! syntastic#log#oneTimeWarn(msg) " {{{2
+ if index(s:one_time_notices_issued, a:msg) >= 0
return
endif
- call add(s:deprecation_notices_issued, a:msg)
+ call add(s:one_time_notices_issued, a:msg)
call syntastic#log#warn(a:msg)
-endfunction
+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 '
-function! syntastic#log#debug(level, msg, ...)
+ if a:0
+ let OLD_VAR = g:syntastic_{a:old}
+ try
+ let NEW_VAR = eval(a:1)
+ let msg .= 'in its stead: let g:syntastic_' . a:new . ' = ' . string(NEW_VAR)
+ let g:syntastic_{a:new} = NEW_VAR
+ catch
+ let msg .= 'g:syntastic_' . a:new . ' instead'
+ endtry
+ else
+ let msg .= 'g:syntastic_' . a:new . ' instead'
+ let g:syntastic_{a:new} = g:syntastic_{a:old}
+ endif
+
+ call syntastic#log#oneTimeWarn(msg)
+ endif
+endfunction " }}}2
+" @vimlint(EVL102, 0, l:OLD_VAR)
+
+function! syntastic#log#debug(level, msg, ...) " {{{2
if !s:isDebugEnabled(a:level)
return
endif
- let leader = s:logTimestamp()
- call s:logRedirect(1)
+ let leader = s:_logTimestamp()
+ call s:_logRedirect(1)
if a:0 > 0
" filter out dictionary functions
@@ -83,68 +77,74 @@ function! syntastic#log#debug(level, msg, ...)
echomsg leader . a:msg
endif
- call s:logRedirect(0)
-endfunction
+ call s:_logRedirect(0)
+endfunction " }}}2
-function! syntastic#log#debugShowOptions(level, names)
+function! syntastic#log#debugShowOptions(level, names) " {{{2
if !s:isDebugEnabled(a:level)
return
endif
- let leader = s:logTimestamp()
- call s:logRedirect(1)
+ let leader = s:_logTimestamp()
+ call s:_logRedirect(1)
- let vlist = type(a:names) == type("") ? [a:names] : a:names
+ let vlist = copy(type(a:names) == type("") ? [a:names] : a:names)
if !empty(vlist)
- call map(copy(vlist), "'&' . v:val . ' = ' . strtrans(string(eval('&' . v:val)))")
+ call map(vlist, "'&' . v:val . ' = ' . strtrans(string(eval('&' . v:val)))")
echomsg leader . join(vlist, ', ')
endif
- call s:logRedirect(0)
-endfunction
+ call s:_logRedirect(0)
+endfunction " }}}2
-function! syntastic#log#debugShowVariables(level, names)
+function! syntastic#log#debugShowVariables(level, names) " {{{2
if !s:isDebugEnabled(a:level)
return
endif
- let leader = s:logTimestamp()
- call s:logRedirect(1)
+ let leader = s:_logTimestamp()
+ call s:_logRedirect(1)
let vlist = type(a:names) == type("") ? [a:names] : a:names
for name in vlist
- echomsg leader . s:formatVariable(name)
+ let msg = s:_formatVariable(name)
+ if msg != ''
+ echomsg leader . msg
+ endif
endfor
- call s:logRedirect(0)
-endfunction
+ call s:_logRedirect(0)
+endfunction " }}}2
-function! syntastic#log#debugDump(level)
+function! syntastic#log#debugDump(level) " {{{2
if !s:isDebugEnabled(a:level)
return
endif
- call syntastic#log#debugShowVariables(a:level, s:global_options)
-endfunction
+ call syntastic#log#debugShowVariables( a:level, sort(keys(g:syntastic_defaults)) )
+endfunction " }}}2
+
+" }}}1
" Private functions {{{1
-function! s:isDebugEnabled_smart(level)
+function! s:_isDebugEnabled_smart(level) " {{{2
return and(g:syntastic_debug, a:level)
-endfunction
+endfunction " }}}2
-function! s:isDebugEnabled_dumb(level)
+function! s:_isDebugEnabled_dumb(level) " {{{2
" poor man's bit test for bit N, assuming a:level == 2**N
return (g:syntastic_debug / a:level) % 2
-endfunction
+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)
+function! s:_logRedirect(on) " {{{2
if exists("g:syntastic_debug_file")
if a:on
try
execute 'redir >> ' . fnameescape(expand(g:syntastic_debug_file))
- catch /^Vim\%((\a\+)\)\=:/
+ catch /\m^Vim\%((\a\+)\)\=:/
silent! redir END
unlet g:syntastic_debug_file
endtry
@@ -152,30 +152,27 @@ function! s:logRedirect(on)
silent! redir END
endif
endif
-endfunction
+endfunction " }}}2
-function! s:logTimestamp_smart()
+function! s:_logTimestamp() " {{{2
return 'syntastic: ' . split(reltimestr(reltime(g:syntastic_start)))[0] . ': '
-endfunction
+endfunction " }}}2
-function! s:logTimestamp_dumb()
- return 'syntastic: debug: '
-endfunction
-
-let s:logTimestamp = function(has('reltime') ? 's:logTimestamp_smart' : 's:logTimestamp_dumb')
-
-function! s:formatVariable(name)
+function! s:_formatVariable(name) " {{{2
let vals = []
- if exists('g:' . a:name)
- call add(vals, 'g:' . a:name . ' = ' . strtrans(string(g:{a:name})))
+ if exists('g:syntastic_' . a:name)
+ call add(vals, 'g:syntastic_' . a:name . ' = ' . strtrans(string(g:syntastic_{a:name})))
endif
- if exists('b:' . a:name)
- call add(vals, 'b:' . a:name . ' = ' . strtrans(string(b:{a:name})))
+ if exists('b:syntastic_' . a:name)
+ call add(vals, 'b:syntastic_' . a:name . ' = ' . strtrans(string(b:syntastic_{a:name})))
endif
return join(vals, ', ')
-endfunction
+endfunction " }}}2
+
+" }}}1
let &cpo = s:save_cpo
unlet s:save_cpo
-" vim: set et sts=4 sw=4 fdm=marker:
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/autoload/syntastic/postprocess.vim b/autoload/syntastic/postprocess.vim
index 877bb50..65570d9 100644
--- a/autoload/syntastic/postprocess.vim
+++ b/autoload/syntastic/postprocess.vim
@@ -1,4 +1,4 @@
-if exists("g:loaded_syntastic_postprocess_autoload")
+if exists("g:loaded_syntastic_postprocess_autoload") || !exists("g:loaded_syntastic_plugin")
finish
endif
let g:loaded_syntastic_postprocess_autoload = 1
@@ -6,38 +6,23 @@ let g:loaded_syntastic_postprocess_autoload = 1
let s:save_cpo = &cpo
set cpo&vim
-function! s:compareErrorItems(a, b)
- 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
-
-" natural sort
-function! syntastic#postprocess#sort(errors)
- return sort(copy(a:errors), 's:compareErrorItems')
-endfunction
+" Public functions {{{1
" merge consecutive blanks
-function! syntastic#postprocess#compressWhitespace(errors)
+function! syntastic#postprocess#compressWhitespace(errors) " {{{2
for e in a:errors
let e['text'] = substitute(e['text'], "\001", '', 'g')
let e['text'] = substitute(e['text'], '\n', ' ', 'g')
let e['text'] = substitute(e['text'], '\m\s\{2,}', ' ', 'g')
+ let e['text'] = substitute(e['text'], '\m^\s\+', '', '')
+ let e['text'] = substitute(e['text'], '\m\s\+$', '', '')
endfor
return a:errors
-endfunction
+endfunction " }}}2
" remove spurious CR under Cygwin
-function! syntastic#postprocess#cygwinRemoveCR(errors)
+function! syntastic#postprocess#cygwinRemoveCR(errors) " {{{2
if has('win32unix')
for e in a:errors
let e['text'] = substitute(e['text'], '\r', '', 'g')
@@ -45,23 +30,25 @@ function! syntastic#postprocess#cygwinRemoveCR(errors)
endif
return a:errors
-endfunction
+endfunction " }}}2
" decode XML entities
-function! syntastic#postprocess#decodeXMLEntities(errors)
+function! syntastic#postprocess#decodeXMLEntities(errors) " {{{2
for e in a:errors
let e['text'] = syntastic#util#decodeXMLEntities(e['text'])
endfor
return a:errors
-endfunction
+endfunction " }}}2
" filter out errors referencing other files
-function! syntastic#postprocess#filterForeignErrors(errors)
+function! syntastic#postprocess#filterForeignErrors(errors) " {{{2
return filter(copy(a:errors), 'get(v:val, "bufnr") == ' . bufnr(''))
-endfunction
+endfunction " }}}2
+
+" }}}1
let &cpo = s:save_cpo
unlet s:save_cpo
-" vim: set et sts=4 sw=4:
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/autoload/syntastic/preprocess.vim b/autoload/syntastic/preprocess.vim
new file mode 100644
index 0000000..56998d2
--- /dev/null
+++ b/autoload/syntastic/preprocess.vim
@@ -0,0 +1,142 @@
+if exists("g:loaded_syntastic_preprocess_autoload") || !exists("g:loaded_syntastic_plugin")
+ finish
+endif
+let g:loaded_syntastic_preprocess_autoload = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+" Public functions {{{1
+
+function! syntastic#preprocess#cabal(errors) " {{{2
+ let out = []
+ let star = 0
+ for err in a:errors
+ if star
+ if err == ''
+ let star = 0
+ else
+ let out[-1] .= ' ' . err
+ endif
+ else
+ call add(out, err)
+ if err =~ '\m^*\s'
+ let star = 1
+ endif
+ endif
+ endfor
+ return out
+endfunction " }}}2
+
+function! syntastic#preprocess#checkstyle(errors) " {{{2
+ let out = []
+ let fname = expand('%')
+ for err in a:errors
+ if match(err, '\m') > -1
+ let line = str2nr(matchstr(err, '\m\ \[[^]]+\])+\ze:'', "", "")')
+endfunction " }}}2
+
+function! syntastic#preprocess#killEmpty(errors) " {{{2
+ return filter(copy(a:errors), 'v:val != ""')
+endfunction " }}}2
+
+function! syntastic#preprocess#perl(errors) " {{{2
+ let out = []
+
+ for e in a:errors
+ let parts = matchlist(e, '\v^(.*)\sat\s(.*)\sline\s(\d+)(.*)$')
+ if !empty(parts)
+ call add(out, parts[2] . ':' . parts[3] . ':' . parts[1] . parts[4])
+ endif
+ endfor
+
+ return syntastic#util#unique(out)
+endfunction " }}}2
+
+function! syntastic#preprocess#rparse(errors) " {{{2
+ let errlist = copy(a:errors)
+
+ " remove uninteresting lines and handle continuations
+ let i = 0
+ while i < len(errlist)
+ if i > 0 && errlist[i][:1] == ' ' && errlist[i] !~ '\m\s\+\^$'
+ let errlist[i-1] .= errlist[i][1:]
+ call remove(errlist, i)
+ elseif errlist[i] !~ '\m^\(Lint:\|Lint checking:\|Error in\) '
+ call remove(errlist, i)
+ else
+ let i += 1
+ endif
+ endwhile
+
+ let out = []
+ let fname = ''
+ for e in errlist
+ if match(e, '\m^Lint: ') == 0
+ let parts = matchlist(e, '\m^Lint: \(.*\): found on lines \([0-9, ]\+\)\(+\(\d\+\) more\)\=')
+ if len(parts) >= 3
+ for line in split(parts[2], '\m,\s*')
+ call add(out, 'E:' . fname . ':' . line . ': ' . parts[1])
+ endfor
+ endif
+ if len(parts) >= 5 && parts[4] != ''
+ call add(out, 'E:' . fname . ':0: ' . parts[1] . ' - ' . parts[4] . ' messages not shown')
+ endif
+ elseif match(e, '\m^Lint checking: ') == 0
+ let fname = matchstr(e, '\m^Lint checking: \zs.*')
+ elseif match(e, '\m^Error in ') == 0
+ call add(out, substitute(e, '\m^Error in .\+ : .\+\ze:\d\+:\d\+: ', 'E:' . fname, ''))
+ endif
+ endfor
+
+ return out
+endfunction " }}}2
+
+function! syntastic#preprocess#tslint(errors) " {{{2
+ return map(copy(a:errors), 'substitute(v:val, ''\m^\(([^)]\+)\)\s\(.\+\)$'', ''\2 \1'', "")')
+endfunction " }}}2
+
+function! syntastic#preprocess#validator(errors) " {{{2
+ let out = []
+ for e in a:errors
+ let parts = matchlist(e, '\v^"([^"]+)"(.+)')
+ if len(parts) >= 3
+ " URL decode, except leave alone any "+"
+ let parts[1] = substitute(parts[1], '\m%\(\x\x\)', '\=nr2char("0x".submatch(1))', 'g')
+ let parts[1] = substitute(parts[1], '\m\\"', '"', 'g')
+ let parts[1] = substitute(parts[1], '\m\\\\', '\\', 'g')
+ call add(out, '"' . parts[1] . '"' . parts[2])
+ endif
+ endfor
+ return out
+endfunction " }}}2
+
+" }}}1
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/autoload/syntastic/util.vim b/autoload/syntastic/util.vim
index 1ab837a..51831b4 100644
--- a/autoload/syntastic/util.vim
+++ b/autoload/syntastic/util.vim
@@ -1,4 +1,4 @@
-if exists('g:loaded_syntastic_util_autoload')
+if exists('g:loaded_syntastic_util_autoload') || !exists("g:loaded_syntastic_plugin")
finish
endif
let g:loaded_syntastic_util_autoload = 1
@@ -6,27 +6,23 @@ let g:loaded_syntastic_util_autoload = 1
let s:save_cpo = &cpo
set cpo&vim
-" strwidth() was added in Vim 7.3; if it doesn't exist, we use strlen()
-" and hope for the best :)
-let s:width = function(exists('*strwidth') ? 'strwidth' : 'strlen')
-
" Public functions {{{1
-function! syntastic#util#isRunningWindows()
+function! syntastic#util#isRunningWindows() " {{{2
return has('win16') || has('win32') || has('win64')
-endfunction
+endfunction " }}}2
-function! syntastic#util#DevNull()
+function! syntastic#util#DevNull() " {{{2
if syntastic#util#isRunningWindows()
return 'NUL'
endif
return '/dev/null'
-endfunction
+endfunction " }}}2
" Get directory separator
-function! syntastic#util#Slash() abort
+function! syntastic#util#Slash() abort " {{{2
return (!exists("+shellslash") || &shellslash) ? '/' : '\'
-endfunction
+endfunction " }}}2
"search the first 5 lines of the file for a magic number and return a map
"containing the args and the executable
@@ -38,37 +34,38 @@ endfunction
"returns
"
"{'exe': '/usr/bin/perl', 'args': ['-f', '-bar']}
-function! syntastic#util#parseShebang()
- for lnum in range(1,5)
+function! syntastic#util#parseShebang() " {{{2
+ for lnum in range(1, 5)
let line = getline(lnum)
-
if line =~ '^#!'
- let exe = matchstr(line, '\m^#!\s*\zs[^ \t]*')
- let args = split(matchstr(line, '\m^#!\s*[^ \t]*\zs.*'))
+ let line = substitute(line, '\v^#!\s*(\S+/env(\s+-\S+)*\s+)?', '', '')
+ let exe = matchstr(line, '\m^\S*\ze')
+ let args = split(matchstr(line, '\m^\S*\zs.*'))
return { 'exe': exe, 'args': args }
endif
endfor
return { 'exe': '', 'args': [] }
-endfunction
+endfunction " }}}2
" Get the value of a variable. Allow local variables to override global ones.
-function! syntastic#util#var(name)
+function! syntastic#util#var(name, ...) " {{{2
return
\ exists('b:syntastic_' . a:name) ? b:syntastic_{a:name} :
- \ exists('g:syntastic_' . a:name) ? g:syntastic_{a:name} : ''
-endfunction
+ \ exists('g:syntastic_' . a:name) ? g:syntastic_{a:name} :
+ \ a:0 > 0 ? a:1 : ''
+endfunction " }}}2
" Parse a version string. Return an array of version components.
-function! syntastic#util#parseVersion(version)
- return split(matchstr( a:version, '\v^\D*\zs\d+(\.\d+)+\ze' ), '\m\.')
-endfunction
+function! syntastic#util#parseVersion(version) " {{{2
+ return map(split(matchstr( a:version, '\v^\D*\zs\d+(\.\d+)+\ze' ), '\m\.'), 'str2nr(v:val)')
+endfunction " }}}2
" Run 'command' in a shell and parse output as a version string.
" Returns an array of version components.
-function! syntastic#util#getVersion(command)
+function! syntastic#util#getVersion(command) " {{{2
return syntastic#util#parseVersion(system(a:command))
-endfunction
+endfunction " }}}2
" Verify that the 'installed' version is at least the 'required' version.
"
@@ -76,20 +73,41 @@ endfunction
" the "missing" elements will be assumed to be 0 for the purposes of checking.
"
" See http://semver.org for info about version numbers.
-function! syntastic#util#versionIsAtLeast(installed, required)
- for idx in range(max([len(a:installed), len(a:required)]))
- let installed_element = get(a:installed, idx, 0)
- let required_element = get(a:required, idx, 0)
- if installed_element != required_element
- return installed_element > required_element
+function! syntastic#util#versionIsAtLeast(installed, required) " {{{2
+ return syntastic#util#compareLexi(a:installed, a:required) >= 0
+endfunction " }}}2
+
+" Almost lexicographic comparison of two lists of integers. :) If lists
+" have different lengths, the "missing" elements are assumed to be 0.
+function! syntastic#util#compareLexi(a, b) " {{{2
+ for idx in range(max([len(a:a), len(a:b)]))
+ let a_element = str2nr(get(a:a, idx, 0))
+ let b_element = str2nr(get(a:b, idx, 0))
+ if a_element != b_element
+ return a_element > b_element ? 1 : -1
endif
endfor
" Everything matched, so it is at least the required version.
- return 1
-endfunction
+ return 0
+endfunction " }}}2
+
+" strwidth() was added in Vim 7.3; if it doesn't exist, we use strlen()
+" and hope for the best :)
+let s:width = function(exists('*strwidth') ? 'strwidth' : 'strlen')
+lockvar s:width
+
+function! syntastic#util#screenWidth(str, tabstop) " {{{2
+ let chunks = split(a:str, "\t", 1)
+ let width = s:width(chunks[-1])
+ for c in chunks[:-2]
+ let cwidth = s:width(c)
+ let width += cwidth + a:tabstop - cwidth % a:tabstop
+ endfor
+ return width
+endfunction " }}}2
"print as much of a:msg as possible without "Press Enter" prompt appearing
-function! syntastic#util#wideMsg(msg)
+function! syntastic#util#wideMsg(msg) " {{{2
let old_ruler = &ruler
let old_showcmd = &showcmd
@@ -100,7 +118,7 @@ function! syntastic#util#wideMsg(msg)
"convert tabs to spaces so that the tabs count towards the window
"width as the proper amount of characters
let chunks = split(msg, "\t", 1)
- let msg = join(map(chunks[:-2], 'v:val . repeat(" ", &ts - s:width(v:val) % &ts)'), '') . chunks[-1]
+ let msg = join(map(chunks[:-2], 'v:val . repeat(" ", &tabstop - s:width(v:val) % &tabstop)'), '') . chunks[-1]
let msg = strpart(msg, 0, &columns - 1)
set noruler noshowcmd
@@ -110,10 +128,10 @@ function! syntastic#util#wideMsg(msg)
let &ruler = old_ruler
let &showcmd = old_showcmd
-endfunction
+endfunction " }}}2
" Check whether a buffer is loaded, listed, and not hidden
-function! syntastic#util#bufIsActive(buffer)
+function! syntastic#util#bufIsActive(buffer) " {{{2
" convert to number, or hell breaks loose
let buf = str2nr(a:buffer)
@@ -129,11 +147,11 @@ function! syntastic#util#bufIsActive(buffer)
endfor
return 0
-endfunction
+endfunction " }}}2
" start in directory a:where and walk up the parent folders until it
" finds a file matching a:what; return path to that file
-function! syntastic#util#findInParent(what, where)
+function! syntastic#util#findInParent(what, where) " {{{2
let here = fnamemodify(a:where, ':p')
let root = syntastic#util#Slash()
@@ -162,10 +180,10 @@ function! syntastic#util#findInParent(what, where)
endwhile
return ''
-endfunction
+endfunction " }}}2
" Returns unique elements in a list
-function! syntastic#util#unique(list)
+function! syntastic#util#unique(list) " {{{2
let seen = {}
let uniques = []
for e in a:list
@@ -175,20 +193,20 @@ function! syntastic#util#unique(list)
endif
endfor
return uniques
-endfunction
+endfunction " }}}2
" A less noisy shellescape()
-function! syntastic#util#shescape(string)
+function! syntastic#util#shescape(string) " {{{2
return a:string =~ '\m^[A-Za-z0-9_/.-]\+$' ? a:string : shellescape(a:string)
-endfunction
+endfunction " }}}2
" A less noisy shellescape(expand())
-function! syntastic#util#shexpand(string)
+function! syntastic#util#shexpand(string) " {{{2
return syntastic#util#shescape(expand(a:string))
-endfunction
+endfunction " }}}2
" decode XML entities
-function! syntastic#util#decodeXMLEntities(string)
+function! syntastic#util#decodeXMLEntities(string) " {{{2
let str = a:string
let str = substitute(str, '\m<', '<', 'g')
let str = substitute(str, '\m>', '>', 'g')
@@ -196,18 +214,18 @@ function! syntastic#util#decodeXMLEntities(string)
let str = substitute(str, '\m'', "'", 'g')
let str = substitute(str, '\m&', '\&', 'g')
return str
-endfunction
+endfunction " }}}2
-function! syntastic#util#redraw(full)
+function! syntastic#util#redraw(full) " {{{2
if a:full
redraw!
else
redraw
endif
-endfunction
+endfunction " }}}2
-function! syntastic#util#dictFilter(errors, filter)
- let rules = s:translateFilter(a:filter)
+function! syntastic#util#dictFilter(errors, filter) " {{{2
+ let rules = s:_translateFilter(a:filter)
" call syntastic#log#debug(g:SyntasticDebugFilters, "applying filter:", rules)
try
call filter(a:errors, rules)
@@ -215,23 +233,36 @@ function! syntastic#util#dictFilter(errors, filter)
let msg = matchstr(v:exception, '\m^Vim\%((\a\+)\)\=:\zs.*')
call syntastic#log#error('quiet_messages: ' . msg)
endtry
-endfunction
+endfunction " }}}2
+
+" Return a [high, low] list of integers, representing the time
+" (hopefully high resolution) since program start
+" TODO: This assumes reltime() returns a list of integers.
+function! syntastic#util#stamp() " {{{2
+ return reltime(g:syntastic_start)
+endfunction " }}}2
+
+" }}}1
" Private functions {{{1
-function! s:translateFilter(filters)
+function! s:_translateFilter(filters) " {{{2
let conditions = []
for k in keys(a:filters)
if type(a:filters[k]) == type([])
- call extend(conditions, map(copy(a:filters[k]), 's:translateElement(k, v:val)'))
+ call extend(conditions, map(copy(a:filters[k]), 's:_translateElement(k, v:val)'))
else
- call add(conditions, s:translateElement(k, a:filters[k]))
+ call add(conditions, s:_translateElement(k, a:filters[k]))
endif
endfor
+
+ if conditions == []
+ let conditions = ["1"]
+ endif
return len(conditions) == 1 ? conditions[0] : join(map(conditions, '"(" . v:val . ")"'), ' && ')
-endfunction
+endfunction " }}}2
-function! s:translateElement(key, term)
+function! s:_translateElement(key, term) " {{{2
if a:key ==? 'level'
let ret = 'v:val["type"] !=? ' . string(a:term[0])
elseif a:key ==? 'type'
@@ -241,11 +272,15 @@ function! s:translateElement(key, term)
elseif a:key ==? 'file'
let ret = 'bufname(str2nr(v:val["bufnr"])) !~# ' . string(a:term)
else
+ call syntastic#log#warn('quiet_messages: ignoring invalid key ' . strtrans(string(a:key)))
let ret = "1"
endif
return ret
-endfunction
+endfunction " }}}2
+
+" }}}1
let &cpo = s:save_cpo
unlet s:save_cpo
-" vim: set et sts=4 sw=4 fdm=marker:
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/doc/syntastic.txt b/doc/syntastic.txt
index 4d04bee..14d4b13 100644
--- a/doc/syntastic.txt
+++ b/doc/syntastic.txt
@@ -36,9 +36,14 @@ CONTENTS *syntastic-contents*
5.3.Configuring specific checkers..........|syntastic-config-makeprg|
6.Notes........................................|syntastic-notes|
6.1.Handling of composite filetypes........|syntastic-composite|
- 6.2.Interaction with python-mode...........|syntastic-pymode|
- 6.3.Interaction with the fish shell........|syntastic-fish|
- 6.4.Using syntastic with the fizsh shell...|syntastic-fizsh|
+ 6.2.Editing files over network.............|syntastic-netrw|
+ 6.3.Interaction with python-mode...........|syntastic-pymode|
+ 6.4.Interaction with YouCompleteMe.........|syntastic-ycm|
+ 6.5.Interaction with the fish shell........|syntastic-fish|
+ 6.6.Interaction with PowerShell............|syntastic-powershell|
+ 6.7.Using syntastic with the fizsh shell...|syntastic-fizsh|
+ 6.8.Interaction with Eclim.................|syntastic-eclim|
+ 6.9.Interaction with vim-virtualenv........|syntastic-vim-virtualenv|
7.About........................................|syntastic-about|
8.License......................................|syntastic-license|
@@ -81,7 +86,7 @@ see |syntastic-checker-options| for details. You can also change the arguments
passed to a specific checker as well.
Use |:SyntasticCheck| to manually check right now. Use |:SyntasticToggleMode|
-to switch between active (checking on writting the buffer) and passive (manual)
+to switch between active (checking on writing the buffer) and passive (manual)
checking.
==============================================================================
@@ -91,7 +96,7 @@ Syntax checking can be done automatically or on demand (see
|'syntastic_mode_map'| and |:SyntasticToggleMode| for configuring this).
When syntax checking is done, the features below can be used to notify the
-user of errors. See |syntastic-options| for how to configure and
+user of errors. See |syntastic-global-options| for how to configure and
activate/deactivate these features.
* A statusline flag
@@ -167,6 +172,8 @@ and the SpellCap group is used for warnings. If you wish to customize the
colors for highlighting you can use the following groups:
SyntasticError - Links to 'SpellBad' by default
SyntasticWarning - Links to 'SpellCap' by default
+ SyntasticStyleError - Links to SyntasticError by default
+ SyntasticStyleWarning - Links to SyntasticWarning by default
Example: >
highlight SyntasticError guibg=#2f0000
@@ -186,7 +193,12 @@ If |'syntastic_aggregate_errors'| is set, syntastic runs all checkers that
apply (still cf. |syntastic-filetype-checkers|), then aggregates errors found
by all checkers in a single list, and notifies you. In this mode each error
message is labeled with the name of the checker that generated it, but you can
-disable these labels by unsetting '|syntastic_id_checkers|'.
+disable generation of these labels by turning off '|syntastic_id_checkers|'.
+
+If |'syntastic_sort_aggregated_errors'| is set (which is the default), messages
+in the aggregated list are grouped by file, then sorted by line number, then
+type, then column number. Otherwise messages produced by the same checker are
+grouped together.
------------------------------------------------------------------------------
2.6 Filtering errors *syntastic-filtering-errors*
@@ -278,12 +290,35 @@ a file with a composite filetype), it might not be immediately obvious which
checker has produced a given error message. This variable instructs syntastic
to label error messages with the names of the checkers that created them. >
let g:syntastic_id_checkers = 0
+<
+ *'syntastic_sort_aggregated_errors'*
+Default: 1
+By default, when results from multiple checkers are aggregated in a single
+error list (that is either when |syntastic_aggregate_errors| is enabled, or
+when checking a file with a composite filetype), errors are grouped by file,
+then sorted by line number, then grouped by type (namely errors take precedence
+over warnings), then they are sorted by column number. If you want to leave
+messages grouped by checker output, set this variable to 0. >
+ let g:syntastic_sort_aggregated_errors = 0
<
*'syntastic_echo_current_error'*
Default: 1
-If enabled, syntastic will echo the error associated with the current line to
-the command window. If multiple errors are found, the first will be used. >
+If enabled, syntastic will echo current error to the command window. If
+multiple errors are found on the same line, |syntastic_cursor_columns| is used
+to decide which one is shown. >
let g:syntastic_echo_current_error = 1
+<
+ *'syntastic_cursor_columns'*
+Default: 1
+This option controls which errors are echoed to the command window if
+|syntastic_echo_current_error| is set and multiple errors are found on the same
+line. When the option is enabled, the first error corresponding to the current
+column is show. Otherwise, the first error on the current line is echoed,
+regardless of the cursor position on the current line.
+
+When dealing with very large lists of errors, disabling this option can speed
+up navigation significantly: >
+ let g:syntastic_cursor_column = 0
<
*'syntastic_enable_signs'*
Default: 1
@@ -301,8 +336,8 @@ error symbols can be customized:
syntastic_style_warning_symbol - For style warnings, defaults to 'S>'
Example: >
- let g:syntastic_error_symbol = '✗'
- let g:syntastic_warning_symbol = '⚠'
+ let g:syntastic_error_symbol = "✗"
+ let g:syntastic_warning_symbol = "⚠"
<
*'syntastic_enable_balloons'*
Default: 1
@@ -374,12 +409,12 @@ Default: {}
Use this option to map non-standard filetypes to standard ones. Corresponding
checkers are mapped accordingly, which allows syntastic to check files with
non-standard filetypes: >
- let g:syntastic_filetype_map = { 'latex': 'tex',
- \ 'gentoo-metadata': 'xml' }
+ let g:syntastic_filetype_map = { "latex": "tex",
+ \ "gentoo-metadata": "xml" }
<
Composite filetypes can also be mapped to simple types, which disables the
default behaviour of running both checkers against the input file: >
- let g:syntastic_filetype_map = { 'handlebars.html': 'handlebars' }
+ let g:syntastic_filetype_map = { "handlebars.html": "handlebars" }
<
*'syntastic_mode_map'*
Default: { "mode": "active",
@@ -391,43 +426,42 @@ done).
The option should be set to something like: >
- let g:syntastic_mode_map = { 'mode': 'active',
- \ 'active_filetypes': ['ruby', 'php'],
- \ 'passive_filetypes': ['puppet'] }
+ let g:syntastic_mode_map = { "mode": "active",
+ \ "active_filetypes": ["ruby", "php"],
+ \ "passive_filetypes": ["puppet"] }
<
-"mode" can be mapped to one of two values - "active" or "passive". When set to
-active, syntastic does automatic checking whenever a buffer is saved or
+"mode" can be mapped to one of two values - "active" or "passive". When set
+to "active", syntastic does automatic checking whenever a buffer is saved or
initially opened. When set to "passive" syntastic only checks when the user
calls |:SyntasticCheck|.
The exceptions to these rules are defined with "active_filetypes" and
-"passive_filetypes". In passive mode, automatic checks are still done
-for all filetypes in the "active_filetypes" array. In active mode,
-automatic checks are not done for any filetypes in the
-"passive_filetypes" array.
+"passive_filetypes". In passive mode, automatic checks are still done for
+filetypes in the "active_filetypes" array (and "passive_filetypes" is
+ignored). In active mode, automatic checks are not done for any filetypes in
+the "passive_filetypes" array ("active_filetypes" is ignored).
-At runtime, the |:SyntasticToggleMode| command can be used to switch between
-active and passive mode.
+If any of "mode", "active_filetypes", or "passive_filetypes" are left
+unspecified, they default to values above.
-If any of "mode", "active_filetypes", or "passive_filetypes" are not specified
-then they will default to their default value as above.
+At runtime, the |:SyntasticToggleMode| command can be used to switch between
+active and passive modes.
*'syntastic_quiet_messages'*
Default: {}
Use this option to filter out some of the messages produced by checkers. The
option should be set to something like: >
-
let g:syntastic_quiet_messages = { "level": "warnings",
\ "type": "style",
\ "regex": '\m\[C03\d\d\]',
\ "file": ['\m^/usr/include/', '\m\c\.h$'] }
<
-
Each element turns off messages matching the patterns specified by the
corresponding value. Values are lists, but if a list consist of a single
-element you can omit adding the brackets (e.g. you can write "style" instead of
-["style"]).
+element you can omit adding the brackets (e.g. you can write "style" instead
+of ["style"]). Elements with values [] or '' are ignored (this is useful for
+overriding filters, cf. |filter-overrides|).
"level" - takes one of two values, "warnings" or "errors"
"type" - can be either "syntax" or "style"
@@ -436,9 +470,26 @@ element you can omit adding the brackets (e.g. you can write "style" instead of
"file" - is matched against the filename the error refers to, as a case
sensitive |regular-expression|.
+If |'syntastic_id_checkers'| is set, filters are applied before error messages
+are labeled with the names of the checkers that created them.
+
There are also checker-specific variants of this option, providing finer
control. They are named |'syntastic___quiet_messages'|.
+For a particular checker, if both a |'syntastic_quiet_messages'| filter and
+a checker-specific filter are present, they are both applied (to the list of
+errors produced by the said checker). In case of conflicting values for the
+same keys, the values of the checker-specific filters take precedence.
+
+ *filter-overrides*
+Since filter elements with values [] or '' are ignored, you can disable global
+filters for particular checkers, by setting the values of the corresponding
+elements in |'syntastic___quiet_messages'| to [] or ''. For
+example, the following setting will silence all warnings, except for the
+ones produced by "pylint": >
+ let g:syntastic_quiet_messages = { "level": "warnings" }
+ let g:syntastic_python_pylint_quiet_messages = { "level" : [] }
+<
*'syntastic_stl_format'*
Default: [Syntax: line:%F (%t)]
Use this option to control what the syntastic statusline text contains. Several
@@ -504,7 +555,7 @@ List of filetypes handled by checkers external to syntastic. If you have a Vim
plugin that adds a checker for syntastic, and if the said checker deals with a
filetype that is unknown to syntastic, you might consider adding that filetype
to this list: >
- let g:syntastic_extra_filetypes = [ 'make', 'gitcommit' ]
+ let g:syntastic_extra_filetypes = [ "make", "gitcommit" ]
<
This will allow |:SyntasticInfo| to do proper tab completion for the new
filetypes.
@@ -518,14 +569,14 @@ filetypes.
*'g:syntastic__checkers'*
You can tell syntastic which checkers to run for a given filetype by setting a
variable 'g:syntastic__checkers' to a list of checkers, e.g. >
- let g:syntastic_php_checkers = ['php', 'phpcs', 'phpmd']
+ let g:syntastic_php_checkers = ["php", "phpcs", "phpmd"]
<
*'b:syntastic_checkers'*
There is also a per-buffer version of this setting, 'b:syntastic_checkers'.
When set, it takes precedence over |'g:syntastic__checkers'|. You can
use this in an autocmd to configure specific checkers for particular paths: >
- autocmd FileType python if stridx(expand('%:p'), '/some/path/') == 0 |
- \ let b:syntastic_checkers = ['pylint'] | endif
+ autocmd FileType python if stridx(expand("%:p"), "/some/path/") == 0 |
+ \ let b:syntastic_checkers = ["pylint"] | endif
<
If neither |'g:syntastic__checkers'| nor |'b:syntastic_checkers'|
is set, a default list of checker is used. Beware however that this list
@@ -541,10 +592,10 @@ Use |:SyntasticInfo| to see which checkers are available for a given filetype.
------------------------------------------------------------------------------
5.2 Choosing the executable *syntastic-config-exec*
- *'syntastic___exec'*
+ *'syntastic___exec'*
The executable used by a checker is normally defined automatically, when the
checkers is registered. You can however override it by setting the variable
-'g:syntastic___exec': >
+'g:syntastic___exec': >
let g:syntastic_ruby_mri_exec = '~/bin/ruby2'
<
------------------------------------------------------------------------------
@@ -553,24 +604,30 @@ checkers is registered. You can however override it by setting the variable
Most checkers use the 'makeprgBuild()' function and provide many options by
default - in fact you can customise every part of the command that gets called.
- *'syntastic___'*
+ *'syntastic___'*
Checkers that use 'makeprgBuild()' construct a 'makeprg' like this: >
let makeprg = self.makeprgBuild({
- \ 'exe': self.getExec(),
- \ 'args': '-a -b -c',
- \ 'post_args': '--more --args',
- \ 'tail': '> /tmp/output' })
+ \ "exe": self.getExec(),
+ \ "args": "-a -b -c",
+ \ "post_args": "--more --args",
+ \ "tail": "2>/dev/null" })
<
The result is a 'makeprg' of the form: >
-
+
<
- *'syntastic___exe'*
All arguments above are optional, and can be overridden by setting global
variables 'g:syntastic___' - even
parameters not specified in the call to makeprgBuild(). These variables also
have local versions 'b:syntastic___',
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 a space, e.g.: >
+ let g:syntastic_javascript_jslint_args = " "
+<
+(setting it to an empty string doesn't work, for implementation reasons).
+
+ *'syntastic___exe'*
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
variables or additional parameters, e.g. to tell the mri checker to use KANJI
@@ -582,7 +639,7 @@ To override the args and the tail: >
let g:syntastic_ruby_mri_tail = "> /tmp/my-output-file-biatch"
<
The general form of the override options is: >
- syntastic___
+ syntastic___
<
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
@@ -605,37 +662,65 @@ See |syntastic_quiet_messages| for the syntax.
------------------------------------------------------------------------------
6.1. Handling of composite filetypes *syntastic-composite*
-Some Vim plugins use composite filetypes, such as 'django.python' or
-'handlebars.html'. Normally, syntastic deals with this situation by splitting
+Some Vim plugins use composite filetypes, such as "django.python" or
+"handlebars.html". Normally, syntastic deals with this situation by splitting
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
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
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.
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
-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
<
------------------------------------------------------------------------------
-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/)
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
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
-'sh': >
+traditional shell, such as "zsh", "bash", "ksh", or even the original Bourne
+"sh": >
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)
is possible, but potentially problematic. In order to do it you'll need to set
@@ -643,10 +728,27 @@ is possible, but potentially problematic. In order to do it you'll need to set
set shellredir=>%s\ 2>&1
<
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',
-'bash', 'ksh', or the original Bourne 'sh' might be a better choice: >
+interactive features of 'fizsh'. Using a more traditional shell such as "zsh",
+"bash", "ksh", or the original Bourne "sh" might be a better choice: >
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*
diff --git a/plugin/syntastic.vim b/plugin/syntastic.vim
index 877d8d8..393a7cc 100644
--- a/plugin/syntastic.vim
+++ b/plugin/syntastic.vim
@@ -1,7 +1,6 @@
"============================================================================
"File: syntastic.vim
"Description: Vim plugin for on the fly syntax checking.
-"Version: 3.4.0-pre
"License: This program is free software. It comes without any warranty,
" to the extent permitted by applicable law. You can redistribute
" it and/or modify it under the terms of the Do What The Fuck You
@@ -17,84 +16,77 @@ let g:loaded_syntastic_plugin = 1
if has('reltime')
let g:syntastic_start = reltime()
+ lockvar! g:syntastic_start
endif
-runtime! plugin/syntastic/*.vim
+let g:syntastic_version = '3.4.0-117'
+lockvar g:syntastic_version
-let s:running_windows = syntastic#util#isRunningWindows()
+" 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)
call syntastic#log#error("need Vim compiled with feature " . s:feature)
finish
endif
endfor
+let s:running_windows = syntastic#util#isRunningWindows()
+lockvar s:running_windows
+
if !s:running_windows && executable('uname')
try
let s:uname = system('uname')
- catch /^Vim\%((\a\+)\)\=:E484/
+ catch /\m^Vim\%((\a\+)\)\=:E484/
call syntastic#log#error("your shell " . &shell . " doesn't use traditional UNIX syntax for redirections")
finish
endtry
+ lockvar s:uname
endif
-if !exists("g:syntastic_always_populate_loc_list")
- let g:syntastic_always_populate_loc_list = 0
-endif
-
-if !exists("g:syntastic_auto_jump")
- let g:syntastic_auto_jump = 0
-endif
-
-if !exists("g:syntastic_quiet_messages")
- let g:syntastic_quiet_messages = {}
-endif
-
-if !exists("g:syntastic_stl_format")
- let g:syntastic_stl_format = '[Syntax: line:%F (%t)]'
-endif
-
-if !exists("g:syntastic_check_on_open")
- let g:syntastic_check_on_open = 0
-endif
-
-if !exists("g:syntastic_check_on_wq")
- let g:syntastic_check_on_wq = 1
-endif
-
-if !exists("g:syntastic_aggregate_errors")
- let g:syntastic_aggregate_errors = 0
-endif
-
-if !exists("g:syntastic_id_checkers")
- let g:syntastic_id_checkers = 1
-endif
-
-if !exists("g:syntastic_loc_list_height")
- let g:syntastic_loc_list_height = 10
-endif
-
-if !exists("g:syntastic_ignore_files")
- let g:syntastic_ignore_files = []
-endif
-
-if !exists("g:syntastic_filetype_map")
- let g:syntastic_filetype_map = {}
-endif
-
-if !exists("g:syntastic_full_redraws")
- let g:syntastic_full_redraws = !(has('gui_running') || has('gui_macvim'))
-endif
-
-" TODO: not documented
-if !exists("g:syntastic_reuse_loc_lists")
- " a relevant bug has been fixed in one of the pre-releases of Vim 7.4
- let g:syntastic_reuse_loc_lists = (v:version >= 704)
-endif
+" }}}1
+
+" Defaults {{{1
+
+let g:syntastic_defaults = {
+ \ 'aggregate_errors': 0,
+ \ 'always_populate_loc_list': 0,
+ \ 'auto_jump': 0,
+ \ 'auto_loc_list': 2,
+ \ 'bash_hack': 1,
+ \ 'check_on_open': 0,
+ \ 'check_on_wq': 1,
+ \ 'cursor_columns': 1,
+ \ 'debug': 0,
+ \ 'echo_current_error': 1,
+ \ 'enable_balloons': 1,
+ \ 'enable_highlighting': 1,
+ \ 'enable_signs': 1,
+ \ 'error_symbol': '>>',
+ \ 'filetype_map': {},
+ \ 'full_redraws': !(has('gui_running') || has('gui_macvim')),
+ \ 'id_checkers': 1,
+ \ 'ignore_extensions': '\c\v^([gx]?z|lzma|bz2)$',
+ \ 'ignore_files': [],
+ \ 'loc_list_height': 10,
+ \ 'quiet_messages': {},
+ \ 'reuse_loc_lists': 0,
+ \ 'sort_aggregated_errors': 1,
+ \ 'stl_format': '[Syntax: line:%F (%t)]',
+ \ 'style_error_symbol': 'S>',
+ \ 'style_warning_symbol': 'S>',
+ \ 'warning_symbol': '>>'
+ \ }
+lockvar! g:syntastic_defaults
+
+for s:key in keys(g:syntastic_defaults)
+ if !exists('g:syntastic_' . s:key)
+ let g:syntastic_{s:key} = g:syntastic_defaults[s:key]
+ endif
+endfor
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
let s:quiet_warnings = get(g:syntastic_quiet_messages, 'type', [])
if type(s:quiet_warnings) != type([])
@@ -105,6 +97,10 @@ if exists("g:syntastic_quiet_warnings")
endif
endif
+" }}}1
+
+" Debug {{{1
+
let s:debug_dump_options = [
\ 'shell',
\ 'shellcmdflag',
@@ -118,32 +114,40 @@ let s:debug_dump_options = [
if v:version > 703 || (v:version == 703 && has('patch446'))
call add(s:debug_dump_options, 'shellxescape')
endif
-
+lockvar! s:debug_dump_options
" debug constants
-let g:SyntasticDebugTrace = 1
-let g:SyntasticDebugLoclist = 2
-let g:SyntasticDebugNotifications = 4
-let g:SyntasticDebugAutocommands = 8
-let g:SyntasticDebugVariables = 16
+let g:SyntasticDebugTrace = 1
+lockvar g:SyntasticDebugTrace
+let g:SyntasticDebugLoclist = 2
+lockvar g:SyntasticDebugLoclist
+let g:SyntasticDebugNotifications = 4
+lockvar g:SyntasticDebugNotifications
+let g:SyntasticDebugAutocommands = 8
+lockvar g:SyntasticDebugAutocommands
+let g:SyntasticDebugVariables = 16
+lockvar g:SyntasticDebugVariables
+
+" }}}1
+
+runtime! plugin/syntastic/*.vim
let s:registry = g:SyntasticRegistry.Instance()
let s:notifiers = g:SyntasticNotifiers.Instance()
let s:modemap = g:SyntasticModeMap.Instance()
+" Commands {{{1
" @vimlint(EVL103, 1, a:cursorPos)
" @vimlint(EVL103, 1, a:cmdLine)
" @vimlint(EVL103, 1, a:argLead)
-function! s:CompleteCheckerName(argLead, cmdLine, cursorPos)
+function! s:CompleteCheckerName(argLead, cmdLine, cursorPos) " {{{2
let checker_names = []
- for ft in s:ResolveFiletypes()
- for checker in s:registry.availableCheckersFor(ft)
- call add(checker_names, checker.getName())
- endfor
+ for ft in s:resolveFiletypes()
+ call extend(checker_names, s:registry.getNamesOfAvailableCheckers(ft))
endfor
return join(checker_names, "\n")
-endfunction
+endfunction " }}}2
" @vimlint(EVL103, 0, a:cursorPos)
" @vimlint(EVL103, 0, a:cmdLine)
" @vimlint(EVL103, 0, a:argLead)
@@ -152,35 +156,33 @@ endfunction
" @vimlint(EVL103, 1, a:cursorPos)
" @vimlint(EVL103, 1, a:cmdLine)
" @vimlint(EVL103, 1, a:argLead)
-function! s:CompleteFiletypes(argLead, cmdLine, cursorPos)
- return join(s:registry.knownFiletypes(), "\n")
-endfunction
+function! s:CompleteFiletypes(argLead, cmdLine, cursorPos) " {{{2
+ return join(s:registry.getKnownFiletypes(), "\n")
+endfunction " }}}2
" @vimlint(EVL103, 0, a:cursorPos)
" @vimlint(EVL103, 0, a:cmdLine)
" @vimlint(EVL103, 0, a:argLead)
-
command! SyntasticToggleMode call s:ToggleMode()
command! -nargs=* -complete=custom,s:CompleteCheckerName SyntasticCheck
\ call s:UpdateErrors(0, )
\ call syntastic#util#redraw(g:syntastic_full_redraws)
command! Errors call s:ShowLocList()
command! -nargs=? -complete=custom,s:CompleteFiletypes SyntasticInfo
- \ call s:modemap.echoMode() |
- \ call s:registry.echoInfoFor(s:ResolveFiletypes())
+ \ call s:modemap.modeInfo() |
+ \ call s:registry.echoInfoFor(s:resolveFiletypes())
command! SyntasticReset
\ call s:ClearCache() |
\ call s:notifiers.refresh(g:SyntasticLoclist.New([]))
command! SyntasticSetLoclist call g:SyntasticLoclist.current().setloclist()
+" }}}1
+
+" Autocommands and hooks {{{1
+
augroup syntastic
autocmd BufReadPost * call s:BufReadPostHook()
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()
augroup END
@@ -191,52 +193,58 @@ if v:version > 703 || (v:version == 703 && has('patch544'))
augroup END
endif
-
-function! s:BufReadPostHook()
+function! s:BufReadPostHook() " {{{2
if g:syntastic_check_on_open
call syntastic#log#debug(g:SyntasticDebugAutocommands,
\ 'autocmd: BufReadPost, buffer ' . bufnr("") . ' = ' . string(bufname(str2nr(bufnr("")))))
call s:UpdateErrors(1)
endif
-endfunction
+endfunction " }}}2
-function! s:BufWritePostHook()
+function! s:BufWritePostHook() " {{{2
call syntastic#log#debug(g:SyntasticDebugAutocommands,
\ 'autocmd: BufWritePost, buffer ' . bufnr("") . ' = ' . string(bufname(str2nr(bufnr("")))))
call s:UpdateErrors(1)
-endfunction
+endfunction " }}}2
-function! s:BufWinEnterHook()
+function! s:BufEnterHook() " {{{2
call syntastic#log#debug(g:SyntasticDebugAutocommands,
- \ 'autocmd: BufWinEnter, buffer ' . bufnr("") . ' = ' . string(bufname(str2nr(bufnr("")))) .
+ \ 'autocmd: BufEnter, buffer ' . bufnr("") . ' = ' . string(bufname(str2nr(bufnr("")))) .
\ ', &buftype = ' . string(&buftype))
if &buftype == ''
call s:notifiers.refresh(g:SyntasticLoclist.current())
+ elseif &buftype == 'quickfix'
+ " TODO: this is needed because in recent versions of Vim lclose
+ " 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
-endfunction
-
-function! s:BufEnterHook()
- call syntastic#log#debug(g:SyntasticDebugAutocommands,
- \ 'autocmd: BufEnter, buffer ' . bufnr("") . ' = ' . string(bufname(str2nr(bufnr("")))) .
- \ ', &buftype = ' . string(&buftype))
- " TODO: at this point there is no b:syntastic_loclist
- let loclist = filter(getloclist(0), 'v:val["valid"] == 1')
- let buffers = syntastic#util#unique(map( loclist, 'v:val["bufnr"]' ))
- if &buftype == 'quickfix' && !empty(loclist) && empty(filter( buffers, 'syntastic#util#bufIsActive(v:val)' ))
- call g:SyntasticLoclistHide()
- endif
-endfunction
+endfunction " }}}2
-function! s:QuitPreHook()
+function! s:QuitPreHook() " {{{2
call syntastic#log#debug(g:SyntasticDebugAutocommands,
\ 'autocmd: QuitPre, buffer ' . bufnr("") . ' = ' . string(bufname(str2nr(bufnr("")))))
let b:syntastic_skip_checks = !g:syntastic_check_on_wq
- call g:SyntasticLoclistHide()
-endfunction
+ call SyntasticLoclistHide()
+endfunction " }}}2
+
+" }}}1
+
+" Main {{{1
"refresh and redraw all the error info for this buf when saving or reading
-function! s:UpdateErrors(auto_invoked, ...)
- if s:SkipFile()
+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()
return
endif
@@ -248,15 +256,16 @@ function! s:UpdateErrors(auto_invoked, ...)
let loclist = g:SyntasticLoclist.current()
- let w:syntastic_loclist_set = 0
- let do_jump = g:syntastic_auto_jump
- if g:syntastic_auto_jump == 2
+ " populate loclist and jump {{{3
+ let do_jump = syntastic#util#var('auto_jump')
+ if do_jump == 2
let first = loclist.getFirstIssue()
let type = get(first, 'type', '')
let do_jump = type ==? 'E'
endif
- if g:syntastic_always_populate_loc_list || do_jump
+ let w:syntastic_loclist_set = 0
+ if syntastic#util#var('always_populate_loc_list') || do_jump
call syntastic#log#debug(g:SyntasticDebugNotifications, 'loclist: setloclist (new)')
call setloclist(0, loclist.getRaw())
let w:syntastic_loclist_set = 1
@@ -273,150 +282,120 @@ function! s:UpdateErrors(auto_invoked, ...)
endif
endif
endif
+ " }}}3
call s:notifiers.refresh(loclist)
-endfunction
+endfunction " }}}2
"clear the loc list for the buffer
-function! s:ClearCache()
+function! s:ClearCache() " {{{2
call s:notifiers.reset(g:SyntasticLoclist.current())
- unlet! b:syntastic_loclist
-endfunction
-
-function! s:ResolveFiletypes(...)
- let type = a:0 ? a:1 : &filetype
- return split( get(g:syntastic_filetype_map, type, type), '\m\.' )
-endfunction
+ call b:syntastic_loclist.destroy()
+endfunction " }}}2
"detect and cache all syntax errors in this buffer
-function! s:CacheErrors(checkers)
+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()
let newLoclist = g:SyntasticLoclist.New([])
- if !s:SkipFile()
- let active_checkers = 0
- let names = []
-
- call syntastic#log#debugShowOptions(g:SyntasticDebugTrace, s:debug_dump_options)
- call syntastic#log#debugDump(g:SyntasticDebugVariables)
- call syntastic#log#debugShowVariables(g:SyntasticDebugTrace, 'syntastic_aggregate_errors')
+ if !s:skipFile()
+ " debug logging {{{3
+ call syntastic#log#debugShowVariables(g:SyntasticDebugTrace, 'aggregate_errors')
call syntastic#log#debug(g:SyntasticDebugTrace, 'getcwd() = ' . getcwd())
+ " }}}3
- let filetypes = s:ResolveFiletypes()
- let aggregate_errors = syntastic#util#var('aggregate_errors')
- let decorate_errors = (aggregate_errors || len(filetypes) > 1) && syntastic#util#var('id_checkers')
+ let filetypes = s:resolveFiletypes()
+ let aggregate_errors = syntastic#util#var('aggregate_errors') || len(filetypes) > 1
+ let decorate_errors = aggregate_errors && syntastic#util#var('id_checkers')
+ let sort_aggregated_errors = aggregate_errors && syntastic#util#var('sort_aggregated_errors')
- for ft in filetypes
- let clist = empty(a:checkers) ? s:registry.getActiveCheckers(ft) : s:registry.getCheckers(ft, a:checkers)
+ let clist = []
+ for type in filetypes
+ call extend(clist, s:registry.getCheckers(type, a:checker_names))
+ endfor
- for checker in clist
- let active_checkers += 1
- call syntastic#log#debug(g:SyntasticDebugTrace, 'CacheErrors: Invoking checker: ' . checker.getName())
+ let names = []
+ let unavailable_checkers = 0
+ for checker in clist
+ 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
- let loclist = checker.getLocList()
+ call syntastic#log#debug(g:SyntasticDebugTrace, 'CacheErrors: Invoking checker: ' . cname)
- if !loclist.isEmpty()
- if decorate_errors
- call loclist.decorate(checker.getName(), checker.getFiletype())
- endif
- call add(names, [checker.getName(), checker.getFiletype()])
+ let loclist = checker.getLocList()
+
+ if !loclist.isEmpty()
+ if decorate_errors
+ call loclist.decorate(cname)
+ endif
+ 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)
- if !aggregate_errors
- break
- endif
+ if !aggregate_errors
+ break
endif
- endfor
+ endif
endfor
+ " set names {{{3
if !empty(names)
- if len(syntastic#util#unique(map(copy(names), 'v:val[1]'))) == 1
- let type = names[0][1]
- let name = join(map(names, 'v:val[0]'), ', ')
+ if len(syntastic#util#unique(map( copy(names), 'substitute(v:val, "\\m/.*", "", "")' ))) == 1
+ let type = substitute(names[0], '\m/.*', '', '')
+ let name = join(map( names, 'substitute(v:val, "\\m.\\{-}/", "", "")' ), ', ')
call newLoclist.setName( name . ' ('. type . ')' )
else
" checkers from mixed types
- call newLoclist.setName(join(map(names, 'v:val[1] . "/" . v:val[0]'), ', '))
+ call newLoclist.setName(join(names, ', '))
endif
endif
+ " }}}3
- if !active_checkers
- if !empty(a:checkers)
- if len(a:checkers) == 1
- call syntastic#log#warn('checker ' . a:checkers[0] . ' is not active for filetype ' . &filetype)
+ " issue warning about no active checkers {{{3
+ if len(clist) == unavailable_checkers
+ if !empty(a:checker_names)
+ if len(a:checker_names) == 1
+ call syntastic#log#warn('checker ' . a:checker_names[0] . ' is not available')
else
- call syntastic#log#warn('checkers ' . join(a:checkers, ', ') . ' are not active for filetype ' . &filetype)
+ call syntastic#log#warn('checkers ' . join(a:checker_names, ', ') . ' are not available')
endif
else
- call syntastic#log#debug(g:SyntasticDebugTrace, 'CacheErrors: no active checkers for filetype ' . &filetype)
+ call syntastic#log#debug(g:SyntasticDebugTrace, 'CacheErrors: no checkers available for ' . &filetype)
endif
endif
+ " }}}3
call syntastic#log#debug(g:SyntasticDebugLoclist, 'aggregated:', newLoclist)
-
- if type(g:syntastic_quiet_messages) == type({}) && !empty(g:syntastic_quiet_messages)
- call newLoclist.quietMessages(g:syntastic_quiet_messages)
- call syntastic#log#debug(g:SyntasticDebugLoclist, 'filtered by g:syntastic_quiet_messages:', newLoclist)
+ if sort_aggregated_errors
+ call newLoclist.sort()
+ call syntastic#log#debug(g:SyntasticDebugLoclist, 'sorted:', newLoclist)
endif
endif
- let b:syntastic_loclist = newLoclist
-endfunction
+ call newLoclist.deploy()
+endfunction " }}}2
-function! s:ToggleMode()
+function! s:ToggleMode() " {{{2
call s:modemap.toggleMode()
call s:ClearCache()
call s:UpdateErrors(1)
call s:modemap.echoMode()
-endfunction
+endfunction " }}}2
"display the cached errors for this buf in the location list
-function! s:ShowLocList()
+function! s:ShowLocList() " {{{2
call g:SyntasticLoclist.current().show()
-endfunction
-
-"the script changes &shellredir and &shell to stop the screen flicking when
-"shelling out to syntax checkers. Not all OSs support the hacks though
-function! s:OSSupportsShellredirHack()
- return !s:running_windows && executable('/bin/bash') && (s:uname() !~ "FreeBSD") && (s:uname() !~ "OpenBSD")
-endfunction
-
-function! s:IsRedrawRequiredAfterMake()
- return !s:running_windows && (s:uname() =~ "FreeBSD" || s:uname() =~ "OpenBSD")
-endfunction
-
-function! s:IgnoreFile(filename)
- let fname = fnamemodify(a:filename, ':p')
- for pattern in g:syntastic_ignore_files
- if fname =~# pattern
- return 1
- endif
- endfor
- return 0
-endfunction
-
-" Skip running in special buffers
-function! s:SkipFile()
- let force_skip = exists('b:syntastic_skip_checks') ? b:syntastic_skip_checks : 0
- let fname = expand('%')
- return force_skip || (&buftype != '') || !filereadable(fname) || getwinvar(0, '&diff') || s:IgnoreFile(fname)
-endfunction
-
-function! s:uname()
- if !exists('s:uname')
- let s:uname = system('uname')
- endif
- return s:uname
-endfunction
-
-"return a string representing the state of buffer according to
-"g:syntastic_stl_format
-"
-"return '' if no errors are cached for the buffer
-function! SyntasticStatuslineFlag()
- return g:SyntasticLoclist.current().getStatuslineFlag()
-endfunction
+endfunction " }}}2
"Emulates the :lmake command. Sets up the make environment according to the
"options given, runs make, resets the environment, returns the location list
@@ -434,10 +413,13 @@ endfunction
" '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
" '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
-function! SyntasticMake(options)
+" @vimlint(EVL102, 1, l:env_save)
+function! SyntasticMake(options) " {{{2
call syntastic#log#debug(g:SyntasticDebugTrace, 'SyntasticMake: called with options:', a:options)
+ " save options and locale env variables {{{3
let old_shell = &shell
let old_shellredir = &shellredir
let old_local_errorformat = &l:errorformat
@@ -445,13 +427,9 @@ function! SyntasticMake(options)
let old_cwd = getcwd()
let old_lc_messages = $LC_MESSAGES
let old_lc_all = $LC_ALL
+ " }}}3
- if s:OSSupportsShellredirHack()
- "this is a hack to stop the screen needing to be ':redraw'n when
- "when :lmake is run. Otherwise the screen flickers annoyingly
- let &shellredir = '&>'
- let &shell = '/bin/bash'
- endif
+ call s:bashHack()
if has_key(a:options, 'errorformat')
let &errorformat = a:options['errorformat']
@@ -461,33 +439,59 @@ function! SyntasticMake(options)
execute 'lcd ' . fnameescape(a:options['cwd'])
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_ALL = ''
+ " }}}3
+
let err_lines = split(system(a:options['makeprg']), "\n", 1)
+
+ " restore environment variables {{{3
let $LC_ALL = old_lc_all
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)
- if has_key(a:options, 'preprocess')
- let err_lines = call(a:options['preprocess'], [err_lines])
+ if has_key(a:options, 'Preprocess')
+ let err_lines = call(a:options['Preprocess'], [err_lines])
+ call syntastic#log#debug(g:SyntasticDebugLoclist, 'preprocess (external):', err_lines)
+ elseif has_key(a:options, 'preprocess')
+ let err_lines = call('syntastic#preprocess#' . a:options['preprocess'], [err_lines])
call syntastic#log#debug(g:SyntasticDebugLoclist, 'preprocess:', err_lines)
endif
lgetexpr err_lines
- let errors = copy(getloclist(0))
+ let errors = deepcopy(getloclist(0))
if has_key(a:options, 'cwd')
execute 'lcd ' . fnameescape(old_cwd)
endif
silent! lolder
+
+ " restore options {{{3
let &errorformat = old_errorformat
let &l:errorformat = old_local_errorformat
let &shellredir = old_shellredir
let &shell = old_shell
+ " }}}3
- if s:IsRedrawRequiredAfterMake()
+ if !s:running_windows && (s:uname() =~ "FreeBSD" || s:uname() =~ "OpenBSD")
call syntastic#util#redraw(g:syntastic_full_redraws)
endif
@@ -498,15 +502,20 @@ function! SyntasticMake(options)
endif
if has_key(a:options, 'defaults')
- call SyntasticAddToErrors(errors, a:options['defaults'])
+ call s:addToErrors(errors, a:options['defaults'])
endif
" Add subtype info if present.
if has_key(a:options, 'subtype')
- call SyntasticAddToErrors(errors, { 'subtype': a:options['subtype'] })
+ call s:addToErrors(errors, { 'subtype': a:options['subtype'] })
endif
- if has_key(a:options, 'postprocess') && !empty(a:options['postprocess'])
+ if has_key(a:options, 'Postprocess') && !empty(a:options['Postprocess'])
+ for rule in a:options['Postprocess']
+ let errors = call(rule, [errors])
+ endfor
+ call syntastic#log#debug(g:SyntasticDebugLoclist, 'postprocess (external):', errors)
+ elseif has_key(a:options, 'postprocess') && !empty(a:options['postprocess'])
for rule in a:options['postprocess']
let errors = call('syntastic#postprocess#' . rule, [errors])
endfor
@@ -514,10 +523,50 @@ function! SyntasticMake(options)
endif
return errors
-endfunction
+endfunction " }}}2
+" @vimlint(EVL102, 0, l:env_save)
-"take a list of errors and add default values to them from a:options
-function! SyntasticAddToErrors(errors, options)
+"return a string representing the state of buffer according to
+"g:syntastic_stl_format
+"
+"return '' if no errors are cached for the buffer
+function! SyntasticStatuslineFlag() " {{{2
+ return g:SyntasticLoclist.current().getStatuslineFlag()
+endfunction " }}}2
+
+" }}}1
+
+" Utilities {{{1
+
+function! s:resolveFiletypes(...) " {{{2
+ let type = a:0 ? a:1 : &filetype
+ return split( get(g:syntastic_filetype_map, type, type), '\m\.' )
+endfunction " }}}2
+
+function! s:ignoreFile(filename) " {{{2
+ let fname = fnamemodify(a:filename, ':p')
+ for pattern in g:syntastic_ignore_files
+ if fname =~# pattern
+ return 1
+ endif
+ endfor
+ return 0
+endfunction " }}}2
+
+" Skip running in special buffers
+function! s:skipFile() " {{{2
+ let fname = expand('%')
+ let skip = (exists('b:syntastic_skip_checks') ? 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
+
+" Take a list of errors and add default values to them from a:options
+function! s:addToErrors(errors, options) " {{{2
for err in a:errors
for key in keys(a:options)
if !has_key(err, key) || empty(err[key])
@@ -527,6 +576,35 @@ function! SyntasticAddToErrors(errors, options)
endfor
return a:errors
-endfunction
+endfunction " }}}2
+
+" The script changes &shellredir and &shell to stop the screen flicking when
+" shelling out to syntax checkers. Not all OSs support the hacks though.
+function! s:bashHack() " {{{2
+ if !exists('s:bash')
+ if !s:running_windows && (s:uname() !~# "FreeBSD") && (s:uname() !~# "OpenBSD")
+ let s:bash =
+ \ executable('/usr/local/bin/bash') ? '/usr/local/bin/bash' :
+ \ executable('/bin/bash') ? '/bin/bash' : ''
+ else
+ let s:bash = ''
+ endif
+ endif
+
+ if g:syntastic_bash_hack && s:bash != ''
+ let &shell = s:bash
+ let &shellredir = '&>'
+ endif
+endfunction " }}}2
+
+function! s:uname() " {{{2
+ if !exists('s:uname')
+ let s:uname = system('uname')
+ lockvar s:uname
+ endif
+ return s:uname
+endfunction " }}}2
+
+" }}}1
-" vim: set et sts=4 sw=4:
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/plugin/syntastic/autoloclist.vim b/plugin/syntastic/autoloclist.vim
index f0038e1..5362ad6 100644
--- a/plugin/syntastic/autoloclist.vim
+++ b/plugin/syntastic/autoloclist.vim
@@ -1,40 +1,38 @@
-if exists("g:loaded_syntastic_notifier_autoloclist")
+if exists("g:loaded_syntastic_notifier_autoloclist") || !exists("g:loaded_syntastic_plugin")
finish
endif
let g:loaded_syntastic_notifier_autoloclist = 1
-if !exists("g:syntastic_auto_loc_list")
- let g:syntastic_auto_loc_list = 2
-endif
-
let g:SyntasticAutoloclistNotifier = {}
" Public methods {{{1
"
-function! g:SyntasticAutoloclistNotifier.New()
+function! g:SyntasticAutoloclistNotifier.New() " {{{2
let newObj = copy(self)
return newObj
-endfunction
+endfunction " }}}2
-function! g:SyntasticAutoloclistNotifier.refresh(loclist)
+function! g:SyntasticAutoloclistNotifier.refresh(loclist) " {{{2
call syntastic#log#debug(g:SyntasticDebugNotifications, 'autoloclist: refresh')
call g:SyntasticAutoloclistNotifier.AutoToggle(a:loclist)
-endfunction
+endfunction " }}}2
-function! g:SyntasticAutoloclistNotifier.AutoToggle(loclist)
+function! g:SyntasticAutoloclistNotifier.AutoToggle(loclist) " {{{2
call syntastic#log#debug(g:SyntasticDebugNotifications, 'autoloclist: toggle')
if !a:loclist.isEmpty()
- if g:syntastic_auto_loc_list == 1
+ if syntastic#util#var('auto_loc_list') == 1
call a:loclist.show()
endif
else
- if g:syntastic_auto_loc_list > 0
+ if syntastic#util#var('auto_loc_list') > 0
"TODO: this will close the loc list window if one was opened by
"something other than syntastic
lclose
endif
endif
-endfunction
+endfunction " }}}2
+
+" }}}1
" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/plugin/syntastic/balloons.vim b/plugin/syntastic/balloons.vim
index 184a052..6bf6edb 100644
--- a/plugin/syntastic/balloons.vim
+++ b/plugin/syntastic/balloons.vim
@@ -1,12 +1,8 @@
-if exists("g:loaded_syntastic_notifier_balloons")
+if exists("g:loaded_syntastic_notifier_balloons") || !exists("g:loaded_syntastic_plugin")
finish
endif
let g:loaded_syntastic_notifier_balloons = 1
-if !exists("g:syntastic_enable_balloons")
- let g:syntastic_enable_balloons = 1
-endif
-
if !has('balloon_eval')
let g:syntastic_enable_balloons = 0
endif
@@ -15,17 +11,17 @@ let g:SyntasticBalloonsNotifier = {}
" Public methods {{{1
-function! g:SyntasticBalloonsNotifier.New()
+function! g:SyntasticBalloonsNotifier.New() " {{{2
let newObj = copy(self)
return newObj
-endfunction
+endfunction " }}}2
-function! g:SyntasticBalloonsNotifier.enabled()
+function! g:SyntasticBalloonsNotifier.enabled() " {{{2
return has('balloon_eval') && syntastic#util#var('enable_balloons')
-endfunction
+endfunction " }}}2
" Update the error balloons
-function! g:SyntasticBalloonsNotifier.refresh(loclist)
+function! g:SyntasticBalloonsNotifier.refresh(loclist) " {{{2
let b:syntastic_balloons = {}
if self.enabled() && !a:loclist.isEmpty()
call syntastic#log#debug(g:SyntasticDebugNotifications, 'balloons: refresh')
@@ -42,25 +38,30 @@ function! g:SyntasticBalloonsNotifier.refresh(loclist)
set beval bexpr=SyntasticBalloonsExprNotifier()
endif
endif
-endfunction
+endfunction " }}}2
" Reset the error balloons
" @vimlint(EVL103, 1, a:loclist)
-function! g:SyntasticBalloonsNotifier.reset(loclist)
+function! g:SyntasticBalloonsNotifier.reset(loclist) " {{{2
+ let b:syntastic_balloons = {}
if has('balloon_eval')
call syntastic#log#debug(g:SyntasticDebugNotifications, 'balloons: reset')
set nobeval
endif
-endfunction
+endfunction " }}}2
" @vimlint(EVL103, 0, a:loclist)
+" }}}1
+
" Private functions {{{1
-function! SyntasticBalloonsExprNotifier()
+function! SyntasticBalloonsExprNotifier() " {{{2
if !exists('b:syntastic_balloons')
return ''
endif
return get(b:syntastic_balloons, v:beval_lnum, '')
-endfunction
+endfunction " }}}2
+
+" }}}1
" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/plugin/syntastic/checker.vim b/plugin/syntastic/checker.vim
index 94cbdb0..273f052 100644
--- a/plugin/syntastic/checker.vim
+++ b/plugin/syntastic/checker.vim
@@ -1,4 +1,4 @@
-if exists("g:loaded_syntastic_checker")
+if exists("g:loaded_syntastic_checker") || !exists("g:loaded_syntastic_plugin")
finish
endif
let g:loaded_syntastic_checker = 1
@@ -7,12 +7,13 @@ let g:SyntasticChecker = {}
" Public methods {{{1
-function! g:SyntasticChecker.New(args)
+function! g:SyntasticChecker.New(args) " {{{2
let newObj = copy(self)
let newObj._filetype = a:args['filetype']
let newObj._name = a:args['name']
let newObj._exec = get(a:args, 'exec', newObj._name)
+ let newObj._sort = 0
if has_key(a:args, 'redirect')
let [filetype, name] = split(a:args['redirect'], '/')
@@ -34,29 +35,29 @@ function! g:SyntasticChecker.New(args)
endif
return newObj
-endfunction
+endfunction " }}}2
-function! g:SyntasticChecker.getFiletype()
+function! g:SyntasticChecker.getFiletype() " {{{2
return self._filetype
-endfunction
+endfunction " }}}2
-function! g:SyntasticChecker.getName()
+function! g:SyntasticChecker.getName() " {{{2
return self._name
-endfunction
+endfunction " }}}2
-function! g:SyntasticChecker.getExec()
+function! g:SyntasticChecker.getExec() " {{{2
if exists('g:syntastic_' . self._filetype . '_' . self._name . '_exec')
return expand(g:syntastic_{self._filetype}_{self._name}_exec)
endif
return self._exec
-endfunction
+endfunction " }}}2
-function! g:SyntasticChecker.getExecEscaped()
+function! g:SyntasticChecker.getExecEscaped() " {{{2
return syntastic#util#shescape(self.getExec())
-endfunction
+endfunction " }}}2
-function! g:SyntasticChecker.getLocListRaw()
+function! g:SyntasticChecker.getLocListRaw() " {{{2
let name = self._filetype . '/' . self._name
try
let list = self._locListFunc()
@@ -69,13 +70,21 @@ function! g:SyntasticChecker.getLocListRaw()
call syntastic#log#debug(g:SyntasticDebugLoclist, name . ' raw:', list)
call self._quietMessages(list)
return list
-endfunction
+endfunction " }}}2
-function! g:SyntasticChecker.getLocList()
+function! g:SyntasticChecker.getLocList() " {{{2
return g:SyntasticLoclist.New(self.getLocListRaw())
-endfunction
+endfunction " }}}2
-function! g:SyntasticChecker.makeprgBuild(opts)
+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
let basename = self._filetype . '_' . self._name . '_'
let parts = []
@@ -86,36 +95,58 @@ function! g:SyntasticChecker.makeprgBuild(opts)
call extend(parts, self._getOpt(a:opts, basename, 'tail', ''))
return join(parts)
-endfunction
+endfunction " }}}2
+
+function! g:SyntasticChecker.isAvailable() " {{{2
+ if !has_key(self, '_available')
+ let self._available = self._isAvailableFunc()
+ endif
+ return self._available
+endfunction " }}}2
-function! g:SyntasticChecker.isAvailable()
- return self._isAvailableFunc()
-endfunction
+" }}}1
" Private methods {{{1
-function! g:SyntasticChecker._quietMessages(errors)
- let filter = 'g:syntastic_' . self._filetype . '_' . self._name . '_quiet_messages'
- if exists(filter) && type({filter}) == type({}) && !empty({filter})
- call syntastic#util#dictFilter(a:errors, {filter})
- call syntastic#log#debug(g:SyntasticDebugLoclist, 'filtered by ' . filter . ':', a:errors)
+function! g:SyntasticChecker._quietMessages(errors) " {{{2
+ " wildcard quiet_messages
+ let quiet_filters = copy(syntastic#util#var('quiet_messages', {}))
+ if type(quiet_filters) != type({})
+ call syntastic#log#warn('ignoring invalid syntastic_quiet_messages')
+ unlet quiet_filters
+ let quiet_filters = {}
+ endif
+
+ " per checker quiet_messages
+ let name = self._filetype . '_' . self._name
+ try
+ call extend( quiet_filters, copy(syntastic#util#var(name . '_quiet_messages', {})), 'force' )
+ catch /\m^Vim\%((\a\+)\)\=:E712/
+ call syntastic#log#warn('ignoring invalid syntastic_' . name . '_quiet_messages')
+ endtry
+
+ call syntastic#log#debug(g:SyntasticDebugLoclist, 'quiet_messages filter:', quiet_filters)
+
+ if !empty(quiet_filters)
+ call syntastic#util#dictFilter(a:errors, quiet_filters)
+ call syntastic#log#debug(g:SyntasticDebugLoclist, 'filtered by quiet_messages:', a:errors)
endif
-endfunction
+endfunction " }}}2
-function! g:SyntasticChecker._populateHighlightRegexes(errors)
+function! g:SyntasticChecker._populateHighlightRegexes(errors) " {{{2
if has_key(self, '_highlightRegexFunc')
for e in a:errors
if e['valid']
let term = self._highlightRegexFunc(e)
- if len(term) > 0
+ if term != ''
let e['hl'] = term
endif
endif
endfor
endif
-endfunction
+endfunction " }}}2
-function! g:SyntasticChecker._getOpt(opts, basename, name, default)
+function! g:SyntasticChecker._getOpt(opts, basename, name, default) " {{{2
let user_val = syntastic#util#var(a:basename . a:name)
let ret = []
call extend( ret, self._shescape(get(a:opts, a:name . '_before', '')) )
@@ -123,9 +154,9 @@ function! g:SyntasticChecker._getOpt(opts, basename, name, default)
call extend( ret, self._shescape(get(a:opts, a:name . '_after', '')) )
return ret
-endfunction
+endfunction " }}}2
-function! g:SyntasticChecker._shescape(opt)
+function! g:SyntasticChecker._shescape(opt) " {{{2
if type(a:opt) == type('') && a:opt != ''
return [a:opt]
elseif type(a:opt) == type([])
@@ -133,12 +164,16 @@ function! g:SyntasticChecker._shescape(opt)
endif
return []
-endfunction
+endfunction " }}}2
+
+" }}}1
" Non-method functions {{{1
-function! SyntasticCheckerIsAvailableDefault() dict
+function! SyntasticCheckerIsAvailableDefault() dict " {{{2
return executable(self.getExec())
-endfunction
+endfunction " }}}2
+
+" }}}1
" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/plugin/syntastic/cursor.vim b/plugin/syntastic/cursor.vim
index 5e24ae1..60f0014 100644
--- a/plugin/syntastic/cursor.vim
+++ b/plugin/syntastic/cursor.vim
@@ -1,67 +1,138 @@
-if exists("g:loaded_syntastic_notifier_cursor")
+if exists("g:loaded_syntastic_notifier_cursor") || !exists("g:loaded_syntastic_plugin")
finish
endif
let g:loaded_syntastic_notifier_cursor = 1
-if !exists('g:syntastic_echo_current_error')
- let g:syntastic_echo_current_error = 1
-endif
-
let g:SyntasticCursorNotifier = {}
" Public methods {{{1
-function! g:SyntasticCursorNotifier.New()
+function! g:SyntasticCursorNotifier.New() " {{{2
let newObj = copy(self)
return newObj
-endfunction
+endfunction " }}}2
-function! g:SyntasticCursorNotifier.enabled()
+function! g:SyntasticCursorNotifier.enabled() " {{{2
return syntastic#util#var('echo_current_error')
-endfunction
+endfunction " }}}2
-function! g:SyntasticCursorNotifier.refresh(loclist)
+function! g:SyntasticCursorNotifier.refresh(loclist) " {{{2
if self.enabled() && !a:loclist.isEmpty()
call syntastic#log#debug(g:SyntasticDebugNotifications, 'cursor: refresh')
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 * call g:SyntasticRefreshCursor()
+ autocmd syntastic CursorMoved * call SyntasticRefreshCursor()
endif
-endfunction
+endfunction " }}}2
" @vimlint(EVL103, 1, a:loclist)
-function! g:SyntasticCursorNotifier.reset(loclist)
+function! g:SyntasticCursorNotifier.reset(loclist) " {{{2
call syntastic#log#debug(g:SyntasticDebugNotifications, 'cursor: reset')
autocmd! syntastic CursorMoved
unlet! b:syntastic_messages
- let b:oldLine = -1
-endfunction
+ let b:syntastic_line = -1
+endfunction " }}}2
" @vimlint(EVL103, 0, a:loclist)
+" }}}1
+
" Private methods {{{1
-" The following defensive nonsense is needed because of the nature of autocmd
-function! g:SyntasticRefreshCursor()
+function! SyntasticRefreshCursor() " {{{2
if !exists('b:syntastic_messages') || empty(b:syntastic_messages)
" file not checked
return
endif
- if !exists('b:oldLine')
- let b:oldLine = -1
+ if !exists('b:syntastic_line')
+ let b:syntastic_line = -1
endif
let l = line('.')
- if l == b:oldLine
- return
+ let current_messages = get(b:syntastic_messages, l, {})
+
+ if !exists('b:syntastic_cursor_columns')
+ let b:syntastic_cursor_columns = g:syntastic_cursor_columns
endif
- let b:oldLine = l
- if has_key(b:syntastic_messages, l)
- call syntastic#util#wideMsg(b:syntastic_messages[l])
+ 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
- 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
-endfunction
+endfunction " }}}2
+
+" }}}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
+ 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:
diff --git a/plugin/syntastic/highlighting.vim b/plugin/syntastic/highlighting.vim
index 80d31f1..afb6614 100644
--- a/plugin/syntastic/highlighting.vim
+++ b/plugin/syntastic/highlighting.vim
@@ -1,14 +1,11 @@
-if exists("g:loaded_syntastic_notifier_highlighting")
+if exists("g:loaded_syntastic_notifier_highlighting") || !exists("g:loaded_syntastic_plugin")
finish
endif
let g:loaded_syntastic_notifier_highlighting = 1
" Highlighting requires getmatches introduced in 7.1.040
let s:has_highlighting = v:version > 701 || (v:version == 701 && has('patch040'))
-
-if !exists("g:syntastic_enable_highlighting")
- let g:syntastic_enable_highlighting = 1
-endif
+lockvar s:has_highlighting
let g:SyntasticHighlightingNotifier = {}
@@ -16,30 +13,31 @@ let s:setup_done = 0
" Public methods {{{1
-function! g:SyntasticHighlightingNotifier.New()
+function! g:SyntasticHighlightingNotifier.New() " {{{2
let newObj = copy(self)
if !s:setup_done
call self._setup()
let s:setup_done = 1
+ lockvar s:setup_done
endif
return newObj
-endfunction
+endfunction " }}}2
-function! g:SyntasticHighlightingNotifier.enabled()
+function! g:SyntasticHighlightingNotifier.enabled() " {{{2
return s:has_highlighting && syntastic#util#var('enable_highlighting')
-endfunction
+endfunction " }}}2
" Sets error highlights in the cuirrent window
-function! g:SyntasticHighlightingNotifier.refresh(loclist)
+function! g:SyntasticHighlightingNotifier.refresh(loclist) " {{{2
if self.enabled()
- call self.reset(a:loclist)
call syntastic#log#debug(g:SyntasticDebugNotifications, 'highlighting: refresh')
+ call self._reset()
let buf = bufnr('')
let issues = filter(a:loclist.copyRaw(), 'v:val["bufnr"] == buf')
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
" used to override default highlighting.
@@ -59,35 +57,48 @@ function! g:SyntasticHighlightingNotifier.refresh(loclist)
endif
endfor
endif
-endfunction
+endfunction " }}}2
" Remove all error highlights from the window
" @vimlint(EVL103, 1, a:loclist)
-function! g:SyntasticHighlightingNotifier.reset(loclist)
+function! g:SyntasticHighlightingNotifier.reset(loclist) " {{{2
if s:has_highlighting
call syntastic#log#debug(g:SyntasticDebugNotifications, 'highlighting: reset')
- for match in getmatches()
- if stridx(match['group'], 'Syntastic') == 0
- call matchdelete(match['id'])
- endif
- endfor
+ call self._reset()
endif
-endfunction
+endfunction " }}}2
" @vimlint(EVL103, 0, a:loclist)
+" }}}1
+
" Private methods {{{1
" One time setup: define our own highlighting
-function! g:SyntasticHighlightingNotifier._setup()
+function! g:SyntasticHighlightingNotifier._setup() " {{{2
if s:has_highlighting
if !hlexists('SyntasticError')
highlight link SyntasticError SpellBad
-
endif
if !hlexists('SyntasticWarning')
highlight link SyntasticWarning SpellCap
endif
+ if !hlexists('SyntasticStyleError')
+ highlight link SyntasticStyleError SyntasticError
+ endif
+ if !hlexists('SyntasticStyleWarning')
+ highlight link SyntasticStyleWarning SyntasticWarning
+ endif
endif
-endfunction
+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
" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/plugin/syntastic/loclist.vim b/plugin/syntastic/loclist.vim
index 052501c..05f39a2 100644
--- a/plugin/syntastic/loclist.vim
+++ b/plugin/syntastic/loclist.vim
@@ -1,4 +1,4 @@
-if exists("g:loaded_syntastic_loclist")
+if exists("g:loaded_syntastic_loclist") || !exists("g:loaded_syntastic_plugin")
finish
endif
let g:loaded_syntastic_loclist = 1
@@ -7,7 +7,7 @@ let g:SyntasticLoclist = {}
" Public methods {{{1
-function! g:SyntasticLoclist.New(rawLoclist)
+function! g:SyntasticLoclist.New(rawLoclist) " {{{2
let newObj = copy(self)
let llist = filter(copy(a:rawLoclist), 'v:val["valid"] == 1')
@@ -20,36 +20,67 @@ function! g:SyntasticLoclist.New(rawLoclist)
let newObj._rawLoclist = llist
let newObj._name = ''
+ let newObj._owner = bufnr('')
+ let newObj._sorted = 0
+ let newObj._columns = g:syntastic_cursor_columns
return newObj
-endfunction
+endfunction " }}}2
-function! g:SyntasticLoclist.current()
- if !exists("b:syntastic_loclist")
+function! g:SyntasticLoclist.current() " {{{2
+ if !exists("b:syntastic_loclist") || empty(b:syntastic_loclist)
let b:syntastic_loclist = g:SyntasticLoclist.New([])
endif
return b:syntastic_loclist
-endfunction
+endfunction " }}}2
-function! g:SyntasticLoclist.extend(other)
+function! g:SyntasticLoclist.extend(other) " {{{2
let list = self.copyRaw()
call extend(list, a:other.copyRaw())
return g:SyntasticLoclist.New(list)
-endfunction
+endfunction " }}}2
-function! g:SyntasticLoclist.isEmpty()
+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
return empty(self._rawLoclist)
-endfunction
+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()
+function! g:SyntasticLoclist.copyRaw() " {{{2
return copy(self._rawLoclist)
-endfunction
+endfunction " }}}2
-function! g:SyntasticLoclist.getRaw()
+function! g:SyntasticLoclist.getRaw() " {{{2
return self._rawLoclist
-endfunction
+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.getStatuslineFlag()
+function! g:SyntasticLoclist.getCursorColumns() " {{{2
+ return self._columns
+endfunction " }}}2
+
+function! g:SyntasticLoclist.getStatuslineFlag() " {{{2
if !exists("self._stl_format")
let self._stl_format = ''
endif
@@ -100,56 +131,74 @@ function! g:SyntasticLoclist.getStatuslineFlag()
endif
return self._stl_flag
-endfunction
+endfunction " }}}2
-function! g:SyntasticLoclist.getFirstIssue()
+function! g:SyntasticLoclist.getFirstIssue() " {{{2
return get(self._rawLoclist, 0, {})
-endfunction
+endfunction " }}}2
-function! g:SyntasticLoclist.getName()
+function! g:SyntasticLoclist.getName() " {{{2
return len(self._name)
-endfunction
+endfunction " }}}2
-function! g:SyntasticLoclist.setName(name)
+function! g:SyntasticLoclist.setName(name) " {{{2
let self._name = a:name
-endfunction
+endfunction " }}}2
-function! g:SyntasticLoclist.decorate(name, filetype)
- for e in self._rawLoclist
- let e['text'] .= ' [' . a:filetype . '/' . a:name . ']'
+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
+endfunction " }}}2
-function! g:SyntasticLoclist.quietMessages(filters)
- call syntastic#util#dictFilter(self._rawLoclist, a:filters)
-endfunction
+function! g:SyntasticLoclist.destroy() " {{{2
+ for buf in self.getBuffers()
+ call setbufvar(buf, 'syntastic_loclist', {})
+ endfor
+endfunction " }}}2
+
+function! g:SyntasticLoclist.decorate(tag) " {{{2
+ for e in self._rawLoclist
+ let e['text'] .= ' [' . a:tag . ']'
+ endfor
+endfunction " }}}2
-function! g:SyntasticLoclist.errors()
+function! g:SyntasticLoclist.errors() " {{{2
if !exists("self._cachedErrors")
let self._cachedErrors = self.filter({'type': "E"})
endif
return self._cachedErrors
-endfunction
+endfunction " }}}2
-function! g:SyntasticLoclist.warnings()
+function! g:SyntasticLoclist.warnings() " {{{2
if !exists("self._cachedWarnings")
let self._cachedWarnings = self.filter({'type': "W"})
endif
return self._cachedWarnings
-endfunction
+endfunction " }}}2
" Legacy function. Syntastic no longer calls it, but we keep it
" around because other plugins (f.i. powerline) depend on it.
-function! g:SyntasticLoclist.hasErrorsOrWarningsToDisplay()
+function! g:SyntasticLoclist.hasErrorsOrWarningsToDisplay() " {{{2
return !self.isEmpty()
-endfunction
+endfunction " }}}2
" cache used by EchoCurrentError()
-function! g:SyntasticLoclist.messages(buf)
+function! g:SyntasticLoclist.messages(buf) " {{{2
if !exists("self._cachedMessages")
let self._cachedMessages = {}
- let errors = self.errors() + self.warnings()
+ let errors = self.errors() + self.warnings()
for e in errors
let b = e['bufnr']
let l = e['lnum']
@@ -159,13 +208,36 @@ function! g:SyntasticLoclist.messages(buf)
endif
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
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
return get(self._cachedMessages, a:buf, {})
-endfunction
+endfunction " }}}2
"Filter the list and return new native loclist
"e.g.
@@ -174,14 +246,14 @@ endfunction
"would return all errors for buffer 10.
"
"Note that all comparisons are done with ==?
-function! g:SyntasticLoclist.filter(filters)
- let conditions = values(map(copy(a:filters), 's:translate(v:key, v:val)'))
+function! g:SyntasticLoclist.filter(filters) " {{{2
+ let conditions = values(map(copy(a:filters), 's:_translate(v:key, v:val)'))
let filter = len(conditions) == 1 ?
\ conditions[0] : join(map(conditions, '"(" . v:val . ")"'), ' && ')
return filter(copy(self._rawLoclist), filter)
-endfunction
+endfunction " }}}2
-function! g:SyntasticLoclist.setloclist()
+function! g:SyntasticLoclist.setloclist() " {{{2
if !exists('w:syntastic_loclist_set')
let w:syntastic_loclist_set = 0
endif
@@ -189,16 +261,16 @@ function! g:SyntasticLoclist.setloclist()
call syntastic#log#debug(g:SyntasticDebugNotifications, 'loclist: setloclist ' . (replace ? '(replace)' : '(new)'))
call setloclist(0, self.getRaw(), replace ? 'r' : ' ')
let w:syntastic_loclist_set = 1
-endfunction
+endfunction " }}}2
"display the cached errors for this buf in the location list
-function! g:SyntasticLoclist.show()
+function! g:SyntasticLoclist.show() " {{{2
call syntastic#log#debug(g:SyntasticDebugNotifications, 'loclist: show')
call self.setloclist()
if !self.isEmpty()
let num = winnr()
- execute "lopen " . g:syntastic_loc_list_height
+ execute "lopen " . syntastic#util#var('loc_list_height')
if num != winnr()
wincmd p
endif
@@ -216,23 +288,113 @@ function! g:SyntasticLoclist.show()
if strpart(title, 0, 16) ==# ':SyntasticCheck ' ||
\ ( (title == '' || title ==# ':setloclist()') && errors == getloclist(0) )
call setwinvar(win, 'quickfix_title', ':SyntasticCheck ' . self._name)
+ call setbufvar(buf, 'syntastic_owner_buffer', self._owner)
endif
endif
endfor
endif
-endfunction
+endfunction " }}}2
+
+" }}}1
" Non-method functions {{{1
-function! g:SyntasticLoclistHide()
+function! SyntasticLoclistHide() " {{{2
call syntastic#log#debug(g:SyntasticDebugNotifications, 'loclist: hide')
silent! lclose
-endfunction
+endfunction " }}}2
+
+" }}}1
" Private functions {{{1
-function! s:translate(key, val)
+function! s:_translate(key, val) " {{{2
return 'get(v:val, ' . string(a:key) . ', "") ==? ' . string(a:val)
-endfunction
+endfunction " }}}2
+
+function! s:_setScreenColumn(item) " {{{2
+ if !has_key(a:item, 'scol')
+ let col = get(a:item, 'col', 0)
+ if col != 0 && a:item['vcol'] == 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
" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/plugin/syntastic/modemap.vim b/plugin/syntastic/modemap.vim
index 9b04235..dd131bc 100644
--- a/plugin/syntastic/modemap.vim
+++ b/plugin/syntastic/modemap.vim
@@ -1,4 +1,4 @@
-if exists("g:loaded_syntastic_modemap")
+if exists("g:loaded_syntastic_modemap") || !exists("g:loaded_syntastic_plugin")
finish
endif
let g:loaded_syntastic_modemap = 1
@@ -7,28 +7,28 @@ let g:SyntasticModeMap = {}
" Public methods {{{1
-function! g:SyntasticModeMap.Instance()
+function! g:SyntasticModeMap.Instance() " {{{2
if !exists('s:SyntasticModeMapInstance')
let s:SyntasticModeMapInstance = copy(self)
call s:SyntasticModeMapInstance.synch()
endif
return s:SyntasticModeMapInstance
-endfunction
+endfunction " }}}2
-function! g:SyntasticModeMap.synch()
+function! g:SyntasticModeMap.synch() " {{{2
if exists('g:syntastic_mode_map')
let self._mode = get(g:syntastic_mode_map, 'mode', 'active')
- let self._activeFiletypes = get(g:syntastic_mode_map, 'active_filetypes', [])
- let self._passiveFiletypes = get(g:syntastic_mode_map, 'passive_filetypes', [])
+ let self._activeFiletypes = copy(get(g:syntastic_mode_map, 'active_filetypes', []))
+ let self._passiveFiletypes = copy(get(g:syntastic_mode_map, 'passive_filetypes', []))
else
let self._mode = 'active'
let self._activeFiletypes = []
let self._passiveFiletypes = []
endif
-endfunction
+endfunction " }}}2
-function! g:SyntasticModeMap.allowsAutoChecking(filetype)
+function! g:SyntasticModeMap.allowsAutoChecking(filetype) " {{{2
let fts = split(a:filetype, '\m\.')
if self.isPassive()
@@ -36,13 +36,13 @@ function! g:SyntasticModeMap.allowsAutoChecking(filetype)
else
return self._noFiletypesArePassive(fts)
endif
-endfunction
+endfunction " }}}2
-function! g:SyntasticModeMap.isPassive()
+function! g:SyntasticModeMap.isPassive() " {{{2
return self._mode ==# 'passive'
-endfunction
+endfunction " }}}2
-function! g:SyntasticModeMap.toggleMode()
+function! g:SyntasticModeMap.toggleMode() " {{{2
call self.synch()
if self._mode ==# 'active'
@@ -56,20 +56,45 @@ function! g:SyntasticModeMap.toggleMode()
let g:syntastic_mode_map = {}
endif
let g:syntastic_mode_map['mode'] = self._mode
-endfunction
+endfunction " }}}2
-function! g:SyntasticModeMap.echoMode()
+function! g:SyntasticModeMap.echoMode() " {{{2
echo "Syntastic: " . self._mode . " mode enabled"
-endfunction
+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
" Private methods {{{1
-function! g:SyntasticModeMap._isOneFiletypeActive(filetypes)
+function! g:SyntasticModeMap._isOneFiletypeActive(filetypes) " {{{2
return !empty(filter(copy(a:filetypes), 'index(self._activeFiletypes, v:val) != -1'))
-endfunction
+endfunction " }}}2
-function! g:SyntasticModeMap._noFiletypesArePassive(filetypes)
+function! g:SyntasticModeMap._noFiletypesArePassive(filetypes) " {{{2
return empty(filter(copy(a:filetypes), 'index(self._passiveFiletypes, v:val) != -1'))
-endfunction
+endfunction " }}}2
+
+" }}}1
" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/plugin/syntastic/notifiers.vim b/plugin/syntastic/notifiers.vim
index 58f3448..49948b1 100644
--- a/plugin/syntastic/notifiers.vim
+++ b/plugin/syntastic/notifiers.vim
@@ -1,4 +1,4 @@
-if exists("g:loaded_syntastic_notifiers")
+if exists("g:loaded_syntastic_notifiers") || !exists("g:loaded_syntastic_plugin")
finish
endif
let g:loaded_syntastic_notifiers = 1
@@ -6,29 +6,49 @@ let g:loaded_syntastic_notifiers = 1
let g:SyntasticNotifiers = {}
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
-function! g:SyntasticNotifiers.Instance()
+function! g:SyntasticNotifiers.Instance() " {{{2
if !exists('s:SyntasticNotifiersInstance')
let s:SyntasticNotifiersInstance = copy(self)
call s:SyntasticNotifiersInstance._initNotifiers()
endif
return s:SyntasticNotifiersInstance
-endfunction
+endfunction " }}}2
+
+function! g:SyntasticNotifiers.refresh(loclist) " {{{2
+ if !a:loclist.isEmpty() && !a:loclist.isNewerThan([])
+ " loclist not fully constructed yet
+ return
+ endif
-function! g:SyntasticNotifiers.refresh(loclist)
call syntastic#log#debug(g:SyntasticDebugNotifications, 'notifiers: refresh')
for type in self._enabled_types
let class = substitute(type, '\m.*', 'Syntastic\u&Notifier', '')
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
endfor
-endfunction
+endfunction " }}}2
-function! g:SyntasticNotifiers.reset(loclist)
+function! g:SyntasticNotifiers.reset(loclist) " {{{2
call syntastic#log#debug(g:SyntasticDebugNotifications, 'notifiers: reset')
for type in self._enabled_types
let class = substitute(type, '\m.*', 'Syntastic\u&Notifier', '')
@@ -39,12 +59,19 @@ function! g:SyntasticNotifiers.reset(loclist)
if has_key(g:{class}, 'reset')
call self._notifier[type].reset(a:loclist)
endif
+
+ " also reset stamps
+ if index(s:persistent_notifiers, type) > -1
+ let b:syntastic_{type}_stamp = []
+ endif
endfor
-endfunction
+endfunction " }}}2
+
+" }}}1
" Private methods {{{1
-function! g:SyntasticNotifiers._initNotifiers()
+function! g:SyntasticNotifiers._initNotifiers() " {{{2
let self._notifier = {}
for type in s:notifier_types
let class = substitute(type, '\m.*', 'Syntastic\u&Notifier', '')
@@ -52,6 +79,8 @@ function! g:SyntasticNotifiers._initNotifiers()
endfor
let self._enabled_types = copy(s:notifier_types)
-endfunction
+endfunction " }}}2
+
+" }}}1
" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/plugin/syntastic/registry.vim b/plugin/syntastic/registry.vim
index 433325c..8789683 100644
--- a/plugin/syntastic/registry.vim
+++ b/plugin/syntastic/registry.vim
@@ -1,16 +1,21 @@
-if exists("g:loaded_syntastic_registry")
+if exists("g:loaded_syntastic_registry") || !exists("g:loaded_syntastic_plugin")
finish
endif
let g:loaded_syntastic_registry = 1
+" Initialisation {{{1
+
let s:defaultCheckers = {
\ 'actionscript':['mxmlc'],
\ 'ada': ['gcc'],
\ 'applescript': ['osacompile'],
+ \ 'arduino': ['avrgcc'],
\ 'asciidoc': ['asciidoc'],
\ 'asm': ['gcc'],
+ \ 'bro': ['bro'],
\ 'bemhtml': ['bemhtmllint'],
\ 'c': ['gcc'],
+ \ 'cabal': ['cabal'],
\ 'chef': ['foodcritic'],
\ 'co': ['coco'],
\ 'cobol': ['cobc'],
@@ -18,14 +23,14 @@ let s:defaultCheckers = {
\ 'coq': ['coqtop'],
\ 'cpp': ['gcc'],
\ 'cs': ['mcs'],
- \ 'css': ['csslint', 'phpcs'],
+ \ 'css': ['csslint'],
\ 'cucumber': ['cucumber'],
\ 'cuda': ['nvcc'],
\ 'd': ['dmd'],
\ 'dart': ['dartanalyzer'],
\ 'docbk': ['xmllint'],
\ 'dustjs': ['swiffer'],
- \ 'elixir': ['elixir'],
+ \ 'elixir': [],
\ 'erlang': ['escript'],
\ 'eruby': ['ruby'],
\ 'fortran': ['gfortran'],
@@ -52,16 +57,16 @@ let s:defaultCheckers = {
\ 'objc': ['gcc'],
\ 'objcpp': ['gcc'],
\ 'ocaml': ['camlp4o'],
- \ 'perl': ['perl', 'perlcritic'],
+ \ 'perl': ['perlcritic'],
\ 'php': ['php', 'phpcs', 'phpmd'],
\ 'po': ['msgfmt'],
\ 'pod': ['podchecker'],
\ 'puppet': ['puppet', 'puppetlint'],
\ 'python': ['python', 'flake8', 'pylint'],
+ \ 'r': [],
\ 'racket': ['racket'],
\ 'rst': ['rst2pseudoxml'],
\ 'ruby': ['mri'],
- \ 'rust': ['rustc'],
\ 'sass': ['sass'],
\ 'scala': ['fsc', 'scalac'],
\ 'scss': ['sass', 'scss_lint'],
@@ -86,197 +91,175 @@ let s:defaultCheckers = {
\ 'zpt': ['zptlint'],
\ 'zsh': ['zsh', 'shellcheck']
\ }
+lockvar! s:defaultCheckers
let s:defaultFiletypeMap = {
\ 'gentoo-metadata': 'xml',
\ 'lhaskell': 'haskell',
\ 'litcoffee': 'coffee'
\ }
+lockvar! s:defaultFiletypeMap
let g:SyntasticRegistry = {}
-" TODO: Handling of filetype aliases: all public methods take aliases as
-" parameters, all private methods take normalized filetypes. Public methods
-" are thus supposed to normalize filetypes before calling private methods.
+" }}}1
" Public methods {{{1
-function! g:SyntasticRegistry.Instance()
+" Note: Handling of filetype aliases: all public methods take aliases as
+" parameters, all private methods take normalized filetypes. Public methods
+" are thus supposed to normalize filetypes before calling private methods.
+
+function! g:SyntasticRegistry.Instance() " {{{2
if !exists('s:SyntasticRegistryInstance')
let s:SyntasticRegistryInstance = copy(self)
let s:SyntasticRegistryInstance._checkerMap = {}
- let s:SyntasticRegistryInstance._cachedCheckersFor = {}
endif
return s:SyntasticRegistryInstance
-endfunction
+endfunction " }}}2
-function! g:SyntasticRegistry.CreateAndRegisterChecker(args)
+function! g:SyntasticRegistry.CreateAndRegisterChecker(args) " {{{2
let checker = g:SyntasticChecker.New(a:args)
let registry = g:SyntasticRegistry.Instance()
call registry._registerChecker(checker)
-endfunction
-
-function! g:SyntasticRegistry.checkable(ftalias)
- return !empty(self.getActiveCheckers(a:ftalias))
-endfunction
-
-function! g:SyntasticRegistry.getActiveCheckers(ftalias)
- let filetype = s:SyntasticRegistryNormaliseFiletype(a:ftalias)
- let checkers = self.availableCheckersFor(a:ftalias)
-
- if self._userHasFiletypeSettings(filetype)
- return self._filterCheckersByUserSettings(checkers, filetype)
+endfunction " }}}2
+
+" Given a list of checker names hints_list, return a map name --> checker.
+" If hints_list is empty, user settings are are used instead. Checkers are
+" not checked for availability (that is, the corresponding IsAvailable() are
+" not run).
+function! g:SyntasticRegistry.getCheckers(ftalias, hints_list) " {{{2
+ let ft = s:_normaliseFiletype(a:ftalias)
+ call self._loadCheckersFor(ft)
+
+ let checkers_map = self._checkerMap[ft]
+ if empty(checkers_map)
+ return []
endif
- if has_key(s:defaultCheckers, filetype)
- return self._filterCheckersByDefaultSettings(checkers, filetype)
- endif
+ call self._checkDeprecation(ft)
- return checkers[0:0]
-endfunction
+ let names =
+ \ !empty(a:hints_list) ? syntastic#util#unique(a:hints_list) :
+ \ exists('b:syntastic_checkers') ? b:syntastic_checkers :
+ \ exists('g:syntastic_' . ft . '_checkers') ? g:syntastic_{ft}_checkers :
+ \ get(s:defaultCheckers, ft, 0)
-function! g:SyntasticRegistry.getCheckers(ftalias, list)
- return self._filterCheckersByName(self.availableCheckersFor(a:ftalias), a:list)
-endfunction
+ return type(names) == type([]) ?
+ \ self._filterCheckersByName(checkers_map, names) : [checkers_map[keys(checkers_map)[0]]]
+endfunction " }}}2
-function! g:SyntasticRegistry.availableCheckersFor(ftalias)
- if !has_key(self._cachedCheckersFor, a:ftalias)
- let filetype = s:SyntasticRegistryNormaliseFiletype(a:ftalias)
- let checkers = self._allCheckersFor(filetype)
- let self._cachedCheckersFor[a:ftalias] = self._filterCheckersByAvailability(checkers)
- endif
+" 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
- return self._cachedCheckersFor[a:ftalias]
-endfunction
-
-function! g:SyntasticRegistry.knownFiletypes()
+function! g:SyntasticRegistry.getKnownFiletypes() " {{{2
let types = keys(s:defaultCheckers)
+
call extend(types, keys(s:defaultFiletypeMap))
+
if exists('g:syntastic_filetype_map')
call extend(types, keys(g:syntastic_filetype_map))
endif
+
if exists('g:syntastic_extra_filetypes') && type(g:syntastic_extra_filetypes) == type([])
call extend(types, g:syntastic_extra_filetypes)
endif
+
return syntastic#util#unique(types)
-endfunction
+endfunction " }}}2
+
+function! g:SyntasticRegistry.getNamesOfAvailableCheckers(ftalias) " {{{2
+ let ft = s:_normaliseFiletype(a:ftalias)
+ call self._loadCheckersFor(ft)
+ return keys(filter( copy(self._checkerMap[ft]), 'v:val.isAvailable()' ))
+endfunction " }}}2
+
+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
+ let available = []
+ let active = []
+
+ for ft in ft_list
+ call extend(available, map( self.getNamesOfAvailableCheckers(ft), 'ft . "/" . v:val' ))
+ call extend(active, map( self.getCheckersAvailable(ft, []), 'ft . "/" . v:val.getName()' ))
+ endfor
+ else
+ let ft = ft_list[0]
+ let available = self.getNamesOfAvailableCheckers(ft)
+ let active = map(self.getCheckersAvailable(ft, []), 'v:val.getName()')
+ endif
-function! g:SyntasticRegistry.echoInfoFor(ftalias_list)
- echomsg "Syntastic info for filetype: " . join(a:ftalias_list, '.')
+ let cnt = len(available)
+ let plural = cnt != 1 ? 's' : ''
+ let cklist = cnt ? join(sort(available)) : '-'
+ echomsg 'Available checker' . plural . ': ' . cklist
- let available = []
- let active = []
- for ftalias in a:ftalias_list
- call extend(available, self.availableCheckersFor(ftalias))
- call extend(active, self.getActiveCheckers(ftalias))
- endfor
+ let cnt = len(active)
+ let plural = cnt != 1 ? 's' : ''
+ let cklist = cnt ? join(active) : '-'
+ echomsg 'Currently enabled checker' . plural . ': ' . cklist
+endfunction " }}}2
- echomsg "Available checker(s): " . join(syntastic#util#unique(map(available, "v:val.getName()")))
- echomsg "Currently enabled checker(s): " . join(syntastic#util#unique(map(active, "v:val.getName()")))
-endfunction
+" }}}1
" Private methods {{{1
-function! g:SyntasticRegistry._registerChecker(checker) abort
+function! g:SyntasticRegistry._registerChecker(checker) abort " {{{2
let ft = a:checker.getFiletype()
-
if !has_key(self._checkerMap, ft)
- let self._checkerMap[ft] = []
+ let self._checkerMap[ft] = {}
endif
- call self._validateUniqueName(a:checker)
-
- call add(self._checkerMap[ft], a:checker)
-endfunction
-
-function! g:SyntasticRegistry._allCheckersFor(filetype)
- call self._loadCheckers(a:filetype)
- if empty(self._checkerMap[a:filetype])
- return []
+ let name = a:checker.getName()
+ if has_key(self._checkerMap[ft], name)
+ throw 'Syntastic: Duplicate syntax checker name: ' . ft . '/' . name
endif
- return self._checkerMap[a:filetype]
-endfunction
-
-function! g:SyntasticRegistry._filterCheckersByDefaultSettings(checkers, filetype)
- if has_key(s:defaultCheckers, a:filetype)
- return self._filterCheckersByName(a:checkers, s:defaultCheckers[a:filetype])
- endif
+ let self._checkerMap[ft][name] = a:checker
+endfunction " }}}2
- return a:checkers
-endfunction
+function! g:SyntasticRegistry._filterCheckersByName(checkers_map, list) " {{{2
+ return filter( map(copy(a:list), 'get(a:checkers_map, v:val, {})'), '!empty(v:val)' )
+endfunction " }}}2
-function! g:SyntasticRegistry._filterCheckersByUserSettings(checkers, filetype)
- if exists("b:syntastic_checkers")
- let whitelist = b:syntastic_checkers
- else
- let whitelist = g:syntastic_{a:filetype}_checkers
- endif
- return self._filterCheckersByName(a:checkers, whitelist)
-endfunction
-
-function! g:SyntasticRegistry._filterCheckersByName(checkers, list)
- let checkers_by_name = {}
- for c in a:checkers
- let checkers_by_name[c.getName()] = c
- endfor
-
- let filtered = []
- for name in a:list
- if has_key(checkers_by_name, name)
- call add(filtered, checkers_by_name[name])
- endif
- endfor
-
- return filtered
-endfunction
-
-function! g:SyntasticRegistry._filterCheckersByAvailability(checkers)
- return filter(copy(a:checkers), "v:val.isAvailable()")
-endfunction
-
-function! g:SyntasticRegistry._loadCheckers(filetype)
- if self._haveLoadedCheckers(a:filetype)
+function! g:SyntasticRegistry._loadCheckersFor(filetype) " {{{2
+ if has_key(self._checkerMap, a:filetype)
return
endif
execute "runtime! syntax_checkers/" . a:filetype . "/*.vim"
if !has_key(self._checkerMap, a:filetype)
- let self._checkerMap[a:filetype] = []
+ let self._checkerMap[a:filetype] = {}
endif
-endfunction
-
-function! g:SyntasticRegistry._haveLoadedCheckers(filetype)
- return has_key(self._checkerMap, a:filetype)
-endfunction
+endfunction " }}}2
-function! g:SyntasticRegistry._userHasFiletypeSettings(filetype)
- if exists("g:syntastic_" . a:filetype . "_checker") && !exists("g:syntastic_" . a:filetype . "_checkers")
+" Check for obsolete variable g:syntastic__checker
+function! g:SyntasticRegistry._checkDeprecation(filetype) " {{{2
+ if exists('g:syntastic_' . a:filetype . '_checker') && !exists('g:syntastic_' . a:filetype . '_checkers')
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
- return exists("b:syntastic_checkers") || exists("g:syntastic_" . a:filetype . "_checkers")
-endfunction
+endfunction " }}}2
-function! g:SyntasticRegistry._validateUniqueName(checker) abort
- for checker in self._allCheckersFor(a:checker.getFiletype())
- if checker.getName() ==# a:checker.getName()
- throw "Syntastic: Duplicate syntax checker name for: " . a:checker.getName()
- endif
- endfor
-endfunction
+" }}}1
" Private functions {{{1
"resolve filetype aliases, and replace - with _ otherwise we cant name
"syntax checker functions legally for filetypes like "gentoo-metadata"
-function! s:SyntasticRegistryNormaliseFiletype(ftalias)
+function! s:_normaliseFiletype(ftalias) " {{{2
let ft = get(s:defaultFiletypeMap, a:ftalias, a:ftalias)
let ft = get(g:syntastic_filetype_map, ft, ft)
let ft = substitute(ft, '\m-', '_', 'g')
return ft
-endfunction
+endfunction " }}}2
+
+" }}}1
" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/plugin/syntastic/signs.vim b/plugin/syntastic/signs.vim
index 3b1e752..e2f4b5d 100644
--- a/plugin/syntastic/signs.vim
+++ b/plugin/syntastic/signs.vim
@@ -1,28 +1,9 @@
-if exists("g:loaded_syntastic_notifier_signs")
+if exists("g:loaded_syntastic_notifier_signs") || !exists("g:loaded_syntastic_plugin")
finish
endif
let g:loaded_syntastic_notifier_signs = 1
-if !exists("g:syntastic_enable_signs")
- let g:syntastic_enable_signs = 1
-endif
-
-if !exists("g:syntastic_error_symbol")
- let g:syntastic_error_symbol = '>>'
-endif
-
-if !exists("g:syntastic_warning_symbol")
- let g:syntastic_warning_symbol = '>>'
-endif
-
-if !exists("g:syntastic_style_error_symbol")
- let g:syntastic_style_error_symbol = 'S>'
-endif
-
-if !exists("g:syntastic_style_warning_symbol")
- let g:syntastic_style_warning_symbol = 'S>'
-endif
-
+" Initialisation {{{1
" start counting sign ids at 5000, start here to hopefully avoid conflicting
" with any other code that places signs (not sure if this precaution is
@@ -34,37 +15,41 @@ let g:SyntasticSignsNotifier = {}
let s:setup_done = 0
+" }}}1
+
" Public methods {{{1
-function! g:SyntasticSignsNotifier.New()
+function! g:SyntasticSignsNotifier.New() " {{{2
let newObj = copy(self)
if !s:setup_done
call self._setup()
let s:setup_done = 1
+ lockvar s:setup_done
endif
return newObj
-endfunction
+endfunction " }}}2
-function! g:SyntasticSignsNotifier.enabled()
+function! g:SyntasticSignsNotifier.enabled() " {{{2
return has('signs') && syntastic#util#var('enable_signs')
-endfunction
+endfunction " }}}2
-function! g:SyntasticSignsNotifier.refresh(loclist)
+function! g:SyntasticSignsNotifier.refresh(loclist) " {{{2
call syntastic#log#debug(g:SyntasticDebugNotifications, 'signs: refresh')
let old_signs = copy(self._bufSignIds())
if self.enabled()
call self._signErrors(a:loclist)
endif
call self._removeSigns(old_signs)
- let s:first_sign_id = s:next_sign_id
-endfunction
+endfunction " }}}2
+
+" }}}1
" Private methods {{{1
" One time setup: define our own sign types and highlighting
-function! g:SyntasticSignsNotifier._setup()
+function! g:SyntasticSignsNotifier._setup() " {{{2
if has('signs')
if !hlexists('SyntasticErrorSign')
highlight link SyntasticErrorSign error
@@ -95,22 +80,27 @@ function! g:SyntasticSignsNotifier._setup()
exe 'sign define SyntasticStyleWarning text=' . g:syntastic_style_warning_symbol .
\ ' texthl=SyntasticStyleWarningSign linehl=SyntasticStyleWarningLine'
endif
-endfunction
+endfunction " }}}2
" Place signs by all syntax errors in the buffer
-function! g:SyntasticSignsNotifier._signErrors(loclist)
+function! g:SyntasticSignsNotifier._signErrors(loclist) " {{{2
let loclist = a:loclist
if !loclist.isEmpty()
- " errors some first, so that they are not masked by warnings
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())
call extend(issues, loclist.warnings())
call filter(issues, 'v:val["bufnr"] == buf')
let seen = {}
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 sign_severity = i['type'] ==? 'W' ? 'Warning' : 'Error'
@@ -123,24 +113,26 @@ function! g:SyntasticSignsNotifier._signErrors(loclist)
endif
endfor
endif
-endfunction
+endfunction " }}}2
" Remove the signs with the given ids from this buffer
-function! g:SyntasticSignsNotifier._removeSigns(ids)
+function! g:SyntasticSignsNotifier._removeSigns(ids) " {{{2
if has('signs')
- for i in a:ids
- execute "sign unplace " . i
- call remove(self._bufSignIds(), index(self._bufSignIds(), i))
+ for s in reverse(copy(a:ids))
+ execute "sign unplace " . s
+ call remove(self._bufSignIds(), index(self._bufSignIds(), s))
endfor
endif
-endfunction
+endfunction " }}}2
" Get all the ids of the SyntaxError signs in the buffer
-function! g:SyntasticSignsNotifier._bufSignIds()
+function! g:SyntasticSignsNotifier._bufSignIds() " {{{2
if !exists("b:syntastic_sign_ids")
let b:syntastic_sign_ids = []
endif
return b:syntastic_sign_ids
-endfunction
+endfunction " }}}2
+
+" }}}1
" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/syntax_checkers/actionscript/mxmlc.vim b/syntax_checkers/actionscript/mxmlc.vim
index 8cfdc34..dd47287 100644
--- a/syntax_checkers/actionscript/mxmlc.vim
+++ b/syntax_checkers/actionscript/mxmlc.vim
@@ -14,10 +14,6 @@ if exists('g:loaded_syntastic_actionscript_mxmlc_checker')
endif
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
set cpo&vim
@@ -41,14 +37,14 @@ function! SyntaxCheckers_actionscript_mxmlc_GetHighlightRegex(item)
endif
- return term != '' ? '\V\<' . term . '\>' : ''
+ return term != '' ? '\V\<' . escape(term, '\') . '\>' : ''
endfunction
function! SyntaxCheckers_actionscript_mxmlc_GetLocList() dict
- let makeprg = self.makeprgBuild({
- \ 'args_before': (g:syntastic_actionscript_mxmlc_conf != '' ?
- \ ' -load-config+=' . g:syntastic_actionscript_mxmlc_conf : ''),
- \ 'args_after': '-output=' . syntastic#util#DevNull() })
+ call syntastic#log#deprecationWarn('actionscript_mxmlc_conf', 'actionscript_mxmlc_args',
+ \ "'-load-config+=' . syntastic#util#shexpand(OLD_VAR)")
+
+ let makeprg = self.makeprgBuild({ 'args_after': '-output=' . syntastic#util#DevNull() })
let errorformat =
\ '%f(%l): col: %c %trror: %m,' .
diff --git a/syntax_checkers/arduino/avrgcc.vim b/syntax_checkers/arduino/avrgcc.vim
new file mode 100644
index 0000000..9864763
--- /dev/null
+++ b/syntax_checkers/arduino/avrgcc.vim
@@ -0,0 +1,26 @@
+"============================================================================
+"File: avrgcc.vim
+"Description: Syntax checking plugin for syntastic.vim
+"Maintainer: Karel
+"License: This program is free software. It comes without any warranty,
+" to the extent permitted by applicable law. You can redistribute
+" it and/or modify it under the terms of the Do What The Fuck You
+" Want To Public License, Version 2, as published by Sam Hocevar.
+" See http://sam.zoy.org/wtfpl/COPYING for more details.
+"
+"============================================================================
+
+if exists('g:loaded_syntastic_arduino_avrgcc_checker')
+ finish
+endif
+let g:loaded_syntastic_arduino_avrgcc_checker = 1
+
+runtime! syntax_checkers/c/*.vim
+
+call g:SyntasticRegistry.CreateAndRegisterChecker({
+ \ 'filetype': 'arduino',
+ \ 'name': 'avrgcc',
+ \ 'exec': 'avr-gcc',
+ \ 'redirect': 'c/avrgcc'})
+
+" vim: set et sts=4 sw=4:
diff --git a/syntax_checkers/bemhtml/bemhtmllint.vim b/syntax_checkers/bemhtml/bemhtmllint.vim
index e658216..7f52ed3 100644
--- a/syntax_checkers/bemhtml/bemhtmllint.vim
+++ b/syntax_checkers/bemhtml/bemhtmllint.vim
@@ -8,7 +8,7 @@
" Want To Public License, Version 2, as published by Sam Hocevar.
" See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================
-"
+
if exists("g:loaded_syntastic_bemhtml_bemhtmllint_checker")
finish
endif
@@ -29,6 +29,7 @@ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'name': 'bemhtmllint',
\ 'exec': 'bemhtml-lint' })
-
let &cpo = s:save_cpo
unlet s:save_cpo
+
+" vim: set et sts=4 sw=4:
diff --git a/syntax_checkers/bro/bro.vim b/syntax_checkers/bro/bro.vim
new file mode 100644
index 0000000..5d75c8a
--- /dev/null
+++ b/syntax_checkers/bro/bro.vim
@@ -0,0 +1,45 @@
+"============================================================================
+"File: bro.vim
+"Description: Syntax checking plugin for syntastic.vim
+"Maintainer: Justin Azoff
+"License: This program is free software. It comes without any warranty,
+" to the extent permitted by applicable law. You can redistribute
+" it and/or modify it under the terms of the Do What The Fuck You
+" Want To Public License, Version 2, as published by Sam Hocevar.
+" See http://sam.zoy.org/wtfpl/COPYING for more details.
+"
+"============================================================================
+
+if exists("g:loaded_syntastic_bro_bro_checker")
+ finish
+endif
+let g:loaded_syntastic_bro_bro_checker = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+function! SyntaxCheckers_bro_bro_IsAvailable() dict
+ return system(self.getExecEscaped() . ' --help') =~# '--parse-only'
+endfunction
+
+function! SyntaxCheckers_bro_bro_GetLocList() dict
+ let makeprg = self.makeprgBuild({ 'args_before': '--parse-only' })
+
+ "example: error in ./foo.bro, line 3: unknown identifier banana, at or "near "banana"
+ let errorformat =
+ \ '%trror in %f\, line %l: %m,' .
+ \ '%tarning in %f\, line %l: %m'
+
+ return SyntasticMake({
+ \ 'makeprg': makeprg,
+ \ 'errorformat': errorformat })
+endfunction
+
+call g:SyntasticRegistry.CreateAndRegisterChecker({
+ \ 'filetype': 'bro',
+ \ 'name': 'bro'})
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set et sts=4 sw=4:
diff --git a/syntax_checkers/c/avrgcc.vim b/syntax_checkers/c/avrgcc.vim
index 0efe472..5563d61 100644
--- a/syntax_checkers/c/avrgcc.vim
+++ b/syntax_checkers/c/avrgcc.vim
@@ -53,3 +53,5 @@ call g:SyntasticRegistry.CreateAndRegisterChecker({
let &cpo = s:save_cpo
unlet s:save_cpo
+
+" vim: set et sts=4 sw=4:
diff --git a/syntax_checkers/c/checkpatch.vim b/syntax_checkers/c/checkpatch.vim
index f8601d8..957af2d 100644
--- a/syntax_checkers/c/checkpatch.vim
+++ b/syntax_checkers/c/checkpatch.vim
@@ -14,24 +14,27 @@ if exists("g:loaded_syntastic_c_checkpatch_checker")
endif
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
set cpo&vim
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
function! SyntaxCheckers_c_checkpatch_GetLocList() dict
- let makeprg = self.makeprgBuild({
- \ 'exe': g:syntastic_c_checker_checkpatch_location,
- \ 'args_after': '--no-summary --no-tree --terse --file' })
+ let makeprg = self.makeprgBuild({ 'args_after': '--no-summary --no-tree --terse --file' })
let errorformat =
\ '%f:%l: %tARNING: %m,' .
diff --git a/syntax_checkers/c/cppcheck.vim b/syntax_checkers/c/cppcheck.vim
index a028e45..e4223cb 100644
--- a/syntax_checkers/c/cppcheck.vim
+++ b/syntax_checkers/c/cppcheck.vim
@@ -28,10 +28,6 @@ endif
let s:save_cpo = &cpo
set cpo&vim
-function! SyntaxCheckers_c_cppcheck_Preprocess(errors)
- return map(copy(a:errors), 'substitute(v:val, ''\v^\[[^]]+\]\zs( -\> \[[^]]+\])+\ze:'', "", "")')
-endfunction
-
function! SyntaxCheckers_c_cppcheck_GetLocList() dict
let makeprg = self.makeprgBuild({
\ 'args': syntastic#c#ReadConfig(g:syntastic_cppcheck_config_file),
@@ -50,7 +46,7 @@ function! SyntaxCheckers_c_cppcheck_GetLocList() dict
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
- \ 'preprocess': 'SyntaxCheckers_c_cppcheck_Preprocess',
+ \ 'preprocess': 'cppcheck',
\ 'returns': [0] })
for e in loclist
diff --git a/syntax_checkers/c/make.vim b/syntax_checkers/c/make.vim
index fa27273..8b84173 100644
--- a/syntax_checkers/c/make.vim
+++ b/syntax_checkers/c/make.vim
@@ -19,7 +19,7 @@ let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_c_make_GetLocList() dict
- let makeprg = self.getExecEscaped() . ' -sk'
+ let makeprg = self.makeprgBuild({ 'args': '-sk', 'fname': '' })
let errorformat =
\ '%-G%f:%s:,' .
diff --git a/syntax_checkers/c/oclint.vim b/syntax_checkers/c/oclint.vim
index e3dd0ad..ca717c4 100644
--- a/syntax_checkers/c/oclint.vim
+++ b/syntax_checkers/c/oclint.vim
@@ -30,7 +30,6 @@ set cpo&vim
function! SyntaxCheckers_c_oclint_GetLocList() dict
let makeprg = self.makeprgBuild({
- \ 'args_after': '-text',
\ 'post_args_before': '-- -c ' . syntastic#c#ReadConfig(g:syntastic_oclint_config_file) })
let errorformat =
@@ -42,12 +41,16 @@ function! SyntaxCheckers_c_oclint_GetLocList() dict
\ '%W%f:%l:%c: warning: %m,' .
\ '%-G%.%#'
- return SyntasticMake({
+ let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'subtype': 'Style',
- \ 'postprocess': ['compressWhitespace', 'sort'],
+ \ 'postprocess': ['compressWhitespace'],
\ 'returns': [0, 3, 5] })
+
+ call self.setWantSort(1)
+
+ return loclist
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
diff --git a/syntax_checkers/c/splint.vim b/syntax_checkers/c/splint.vim
index 991a681..f56af1a 100644
--- a/syntax_checkers/c/splint.vim
+++ b/syntax_checkers/c/splint.vim
@@ -35,8 +35,11 @@ function! SyntaxCheckers_c_splint_GetLocList() dict
let errorformat =
\ '%-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: %m,' .
+ \ '%W%f(%l): %m,' .
\ '%-C %\+In file included from %.%#,' .
\ '%-C %\+from %.%#,' .
\ '%+C %.%#'
diff --git a/syntax_checkers/cabal/cabal.vim b/syntax_checkers/cabal/cabal.vim
new file mode 100644
index 0000000..191969b
--- /dev/null
+++ b/syntax_checkers/cabal/cabal.vim
@@ -0,0 +1,55 @@
+"============================================================================
+"File: cabal.vim
+"Description: Haskell package description (.cabal file) linting and syntax
+" validation via 'cabal check'
+"Maintainer: Ian D. Bollinger
+"License: This program is free software. It comes without any warranty,
+" to the extent permitted by applicable law. You can redistribute
+" it and/or modify it under the terms of the Do What The Fuck You
+" Want To Public License, Version 2, as published by Sam Hocevar.
+" See http://sam.zoy.org/wtfpl/COPYING for more details.
+"============================================================================
+
+if exists('g:loaded_syntastic_cabal_cabal_checker')
+ finish
+endif
+let g:loaded_syntastic_cabal_cabal_checker = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+function! SyntaxCheckers_cabal_cabal_GetHighlightRegex(item)
+ let field = matchstr(a:item['text'], "\\vParse of field '\\zs[^']+")
+ if field != ''
+ return '\v\c^\s*' . field . '\s*:\s*\zs.*$'
+ endif
+ let field = matchstr(a:item['text'], "\\v(^|\\s)'\\zs[^']+\\ze'")
+ if field != ''
+ return '\V\c\<' . escape(field, '\') . '\>'
+ endif
+ return ''
+endfunction
+
+function! SyntaxCheckers_cabal_cabal_GetLocList() dict
+ let makeprg = self.getExecEscaped() . ' check'
+
+ let errorformat =
+ \ '%Ecabal: %f:%l: %m,' .
+ \ '%W* %m'
+
+ return SyntasticMake({
+ \ 'makeprg': makeprg,
+ \ 'errorformat': errorformat,
+ \ 'cwd': expand('%:p:h'),
+ \ 'preprocess': 'cabal',
+ \ 'defaults': {'bufnr': bufnr('')} })
+endfunction
+
+call g:SyntasticRegistry.CreateAndRegisterChecker({
+ \ 'filetype': 'cabal',
+ \ 'name': 'cabal'})
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set et sts=4 sw=4:
diff --git a/syntax_checkers/co/coco.vim b/syntax_checkers/co/coco.vim
index 3ef5d96..1a58c45 100644
--- a/syntax_checkers/co/coco.vim
+++ b/syntax_checkers/co/coco.vim
@@ -19,7 +19,8 @@ let s:save_cpo = &cpo
set cpo&vim
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 =
\ '%EFailed at: %f,' .
diff --git a/syntax_checkers/coffee/coffeelint.vim b/syntax_checkers/coffee/coffeelint.vim
index ccc6349..99f2fad 100644
--- a/syntax_checkers/coffee/coffeelint.vim
+++ b/syntax_checkers/coffee/coffeelint.vim
@@ -19,7 +19,11 @@ let s:save_cpo = &cpo
set cpo&vim
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 =
\ '%f\,%l\,%\d%#\,%trror\,%m,' .
diff --git a/syntax_checkers/css/csslint.vim b/syntax_checkers/css/csslint.vim
index fe84aaa..0fc0626 100644
--- a/syntax_checkers/css/csslint.vim
+++ b/syntax_checkers/css/csslint.vim
@@ -19,17 +19,13 @@ if exists('g:loaded_syntastic_css_csslint_checker')
endif
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
set cpo&vim
function! SyntaxCheckers_css_csslint_GetLocList() dict
- let makeprg = self.makeprgBuild({
- \ 'args': g:syntastic_csslint_options,
- \ 'args_after': '--format=compact' })
+ call syntastic#log#deprecationWarn('csslint_options', 'css_csslint_args')
+
+ let makeprg = self.makeprgBuild({ 'args_after': '--format=compact' })
" Print CSS Lint's error/warning messages from compact format. Ignores blank lines.
let errorformat =
diff --git a/syntax_checkers/css/prettycss.vim b/syntax_checkers/css/prettycss.vim
index 536568f..06fd7e4 100644
--- a/syntax_checkers/css/prettycss.vim
+++ b/syntax_checkers/css/prettycss.vim
@@ -26,7 +26,7 @@ set cpo&vim
function! SyntaxCheckers_css_prettycss_GetHighlightRegex(item)
let term = matchstr(a:item["text"], '\m (\zs[^)]\+\ze)$')
if term != ''
- let term = '\V' . term
+ let term = '\V' . escape(term, '\')
endif
return term
endfunction
@@ -43,13 +43,14 @@ function! SyntaxCheckers_css_prettycss_GetLocList() dict
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
- \ 'defaults': {'bufnr': bufnr("")},
- \ 'postprocess': ['sort'] })
+ \ 'defaults': {'bufnr': bufnr("")} })
for e in loclist
let e["text"] .= ')'
endfor
+ call self.setWantSort(1)
+
return loclist
endfunction
diff --git a/syntax_checkers/css/recess.vim b/syntax_checkers/css/recess.vim
new file mode 100644
index 0000000..6d043e4
--- /dev/null
+++ b/syntax_checkers/css/recess.vim
@@ -0,0 +1,26 @@
+"============================================================================
+"File: recess.vim
+"Description: Syntax checking plugin for syntastic.vim using `recess`
+" (http://twitter.github.io/recess/).
+"Maintainer: Tim Carry
+"License: This program is free software. It comes without any warranty,
+" to the extent permitted by applicable law. You can redistribute
+" it and/or modify it under the terms of the Do What The Fuck You
+" Want To Public License, Version 2, as published by Sam Hocevar.
+" See http://sam.zoy.org/wtfpl/COPYING for more details.
+"
+"============================================================================
+
+if exists("g:loaded_syntastic_css_recess_checker")
+ finish
+endif
+let g:loaded_syntastic_css_recess_checker = 1
+
+runtime! syntax_checkers/less/*.vim
+
+call g:SyntasticRegistry.CreateAndRegisterChecker({
+ \ 'filetype': 'css',
+ \ 'name': 'recess',
+ \ 'redirect': 'less/recess'})
+
+" vim: set et sts=4 sw=4:
diff --git a/syntax_checkers/d/dmd.vim b/syntax_checkers/d/dmd.vim
index 4f70979..05e7b6a 100644
--- a/syntax_checkers/d/dmd.vim
+++ b/syntax_checkers/d/dmd.vim
@@ -35,6 +35,12 @@ function! SyntaxCheckers_d_dmd_IsAvailable() dict
endfunction
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', {
\ 'errorformat':
\ '%-G%f:%s:,%f(%l): %m,' .
diff --git a/syntax_checkers/elixir/elixir.vim b/syntax_checkers/elixir/elixir.vim
index 566131d..3914fa9 100644
--- a/syntax_checkers/elixir/elixir.vim
+++ b/syntax_checkers/elixir/elixir.vim
@@ -24,6 +24,11 @@ function! SyntaxCheckers_elixir_elixir_IsAvailable() dict
endfunction
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 compile_command = 'elixir'
diff --git a/syntax_checkers/erlang/erlang_check_file.erl b/syntax_checkers/erlang/erlang_check_file.erl
index 01622d9..bd94870 100755
--- a/syntax_checkers/erlang/erlang_check_file.erl
+++ b/syntax_checkers/erlang/erlang_check_file.erl
@@ -2,10 +2,11 @@
-export([main/1]).
main([FileName]) ->
- LibDirs = filelib:wildcard("{lib,deps}/*/ebin"),
+ LibDirs = (["ebin", "include", "src", "test"] ++
+ filelib:wildcard("{apps,deps,lib}/*/{ebin,include}")),
compile(FileName, LibDirs);
-main([FileName | ["-rebar" | [Path | LibDirs]]]) ->
+main([FileName, "-rebar", Path, LibDirs]) ->
{ok, L} = file:consult(Path),
P = dict:from_list(L),
Root = filename:dirname(Path),
@@ -31,23 +32,20 @@ main([FileName | ["-rebar" | [Path | LibDirs]]]) ->
%io:format("~p~n", [LibDirs1]),
compile(FileName, LibDirs1);
-main([FileName | LibDirs]) ->
+main([FileName, LibDirs]) ->
compile(FileName, LibDirs).
compile(FileName, LibDirs) ->
Root = get_root(filename:dirname(FileName)),
ok = code:add_pathsa(LibDirs),
- compile:file(FileName, [warn_obsolete_guard,
- warn_unused_import,
- warn_shadow_vars,
- warn_export_vars,
- strong_validation,
- report,
- {i, filename:join(Root, "include")},
- {i, filename:join(Root, "deps")},
- {i, filename:join(Root, "apps")},
- {i, filename:join(Root, "lib")}
- ]).
+ compile:file(FileName,
+ [warn_obsolete_guard,
+ warn_unused_import,
+ warn_shadow_vars,
+ warn_export_vars,
+ strong_validation,
+ report] ++
+ [{i, filename:join(Root, I)} || I <- LibDirs]).
get_root(Dir) ->
Path = filename:split(filename:absname(Dir)),
diff --git a/syntax_checkers/erlang/escript.vim b/syntax_checkers/erlang/escript.vim
index ed299ec..b472550 100644
--- a/syntax_checkers/erlang/escript.vim
+++ b/syntax_checkers/erlang/escript.vim
@@ -30,7 +30,7 @@ function! SyntaxCheckers_erlang_escript_GetLocList() dict
endif
let shebang = syntastic#util#parseShebang()
- if shebang['exe'] =~# '\m\%f:%l:%c:,'.
- \ '%+C\ \ %#%m,'.
- \ '%W%>%f:%l:%c:,'.
- \ '%+C\ \ %#%tarning:\ %m,'
+ \ 'exe_after': 'check',
+ \ 'fname': syntastic#util#shexpand('%:p') })
+
+ let errorformat =
+ \ '%-Z %#,'.
+ \ '%W%f:%l:%v: Warning: %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({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
+ \ 'defaults': {'vcol': 1},
\ 'postprocess': ['compressWhitespace'] })
endfunction
diff --git a/syntax_checkers/haskell/hlint.vim b/syntax_checkers/haskell/hlint.vim
index e859d29..592e4d3 100644
--- a/syntax_checkers/haskell/hlint.vim
+++ b/syntax_checkers/haskell/hlint.vim
@@ -14,16 +14,18 @@ let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_haskell_hlint_GetLocList() dict
- let makeprg = self.makeprgBuild({})
+ let makeprg = self.makeprgBuild({
+ \ 'fname': syntastic#util#shexpand('%:p')})
let errorformat =
- \ '%E%f:%l:%c: Error: %m,' .
- \ '%W%f:%l:%c: Warning: %m,' .
+ \ '%E%f:%l:%v: Error: %m,' .
+ \ '%W%f:%l:%v: Warning: %m,' .
\ '%C%m'
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
+ \ 'defaults': {'vcol': 1},
\ 'postprocess': ['compressWhitespace'] })
endfunction
diff --git a/syntax_checkers/haskell/scan.vim b/syntax_checkers/haskell/scan.vim
new file mode 100644
index 0000000..ed74a00
--- /dev/null
+++ b/syntax_checkers/haskell/scan.vim
@@ -0,0 +1,43 @@
+"============================================================================
+"File: scan.vim
+"Description: Syntax checking plugin for syntastic.vim
+"Maintainer: LCD 47
+"License: This program is free software. It comes without any warranty,
+" to the extent permitted by applicable law. You can redistribute
+" it and/or modify it under the terms of the Do What The Fuck You
+" Want To Public License, Version 2, as published by Sam Hocevar.
+" See http://sam.zoy.org/wtfpl/COPYING for more details.
+"
+"============================================================================
+
+if exists('g:loaded_syntastic_haskell_scan_checker')
+ finish
+endif
+let g:loaded_syntastic_haskell_scan_checker = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+function! SyntaxCheckers_haskell_scan_GetLocList() dict
+ let makeprg = self.makeprgBuild({})
+
+ let errorformat = '%f:%l:%v: %m'
+
+ let loclist = SyntasticMake({
+ \ 'makeprg': makeprg,
+ \ 'errorformat': errorformat,
+ \ 'subtype': 'Style' })
+
+ call self.setWantSort(1)
+
+ return loclist
+endfunction
+
+call g:SyntasticRegistry.CreateAndRegisterChecker({
+ \ 'filetype': 'haskell',
+ \ 'name': 'scan'})
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set et sts=4 sw=4:
diff --git a/syntax_checkers/html/jshint.vim b/syntax_checkers/html/jshint.vim
index f06657f..8bb0a53 100644
--- a/syntax_checkers/html/jshint.vim
+++ b/syntax_checkers/html/jshint.vim
@@ -14,35 +14,30 @@ if exists('g:loaded_syntastic_html_jshint_checker')
endif
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
set cpo&vim
function! SyntaxCheckers_html_jshint_IsAvailable() dict
- let exe = expand(g:syntastic_jshint_exec)
- return executable(exe) &&
- \ syntastic#util#versionIsAtLeast(syntastic#util#getVersion(exe . ' --version'), [2,4])
+ call syntastic#log#deprecationWarn('jshint_exec', 'html_jshint_exec')
+ return executable(self.getExec()) &&
+ \ syntastic#util#versionIsAtLeast(syntastic#util#getVersion(self.getExecEscaped() . ' --version'), [2,4])
endfunction
function! SyntaxCheckers_html_jshint_GetLocList() dict
- let makeprg = self.makeprgBuild({
- \ 'exe': expand(g:syntastic_jshint_exec),
- \ 'args': (g:syntastic_html_jshint_conf != '' ? '--config ' . g:syntastic_html_jshint_conf : ''),
- \ 'args_after': '--verbose --extract always' })
+ call syntastic#log#deprecationWarn('html_jshint_conf', 'html_jshint_args',
+ \ "'--config ' . syntastic#util#shexpand(OLD_VAR)")
+
+ let makeprg = self.makeprgBuild({ 'args_after': '--verbose --extract always' })
let errorformat = '%A%f: line %l\, col %v\, %m \(%t%*\d\)'
+ call self.setWantSort(1)
+
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
- \ 'defaults': {'bufnr': bufnr('')} })
+ \ 'defaults': {'bufnr': bufnr('')},
+ \ 'returns': [0, 2] })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
diff --git a/syntax_checkers/html/tidy.vim b/syntax_checkers/html/tidy.vim
index 9c87cf9..7dcf522 100644
--- a/syntax_checkers/html/tidy.vim
+++ b/syntax_checkers/html/tidy.vim
@@ -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: [])
" list of errors to ignore
@@ -48,108 +56,112 @@ set cpo&vim
" TODO: join this with xhtml.vim for DRY's sake?
function! s:TidyEncOptByFenc()
let tidy_opts = {
- \'utf-8': '-utf8',
- \'ascii': '-ascii',
- \'latin1': '-latin1',
- \'iso-2022-jp': '-iso-2022',
- \'cp1252': '-win1252',
- \'macroman': '-mac',
- \'utf-16le': '-utf16le',
- \'utf-16': '-utf16',
- \'big5': '-big5',
- \'cp932': '-shiftjis',
- \'sjis': '-shiftjis',
- \'cp850': '-ibm858',
- \}
+ \ 'utf-8': '-utf8',
+ \ 'ascii': '-ascii',
+ \ 'latin1': '-latin1',
+ \ 'iso-2022-jp': '-iso-2022',
+ \ 'cp1252': '-win1252',
+ \ 'macroman': '-mac',
+ \ 'utf-16le': '-utf16le',
+ \ 'utf-16': '-utf16',
+ \ 'big5': '-big5',
+ \ 'cp932': '-shiftjis',
+ \ 'sjis': '-shiftjis',
+ \ 'cp850': '-ibm858',
+ \ }
return get(tidy_opts, &fileencoding, '-utf8')
endfunction
let s:ignore_errors = [
- \ " lacks \"summary\" attribute",
- \ "not approved by W3C",
- \ " proprietary attribute \"placeholder\"",
- \ " proprietary attribute \"charset\"",
- \ " lacks \"content\" attribute",
- \ "inserting \"type\" attribute",
- \ "proprietary attribute \"data-",
- \ "missing declaration",
- \ "inserting implicit ",
- \ "inserting missing 'title' element",
- \ "unescaped & or unknown entity",
- \ " attribute \"type\" has invalid value",
- \ "proprietary attribute \"role\"",
- \ "proprietary attribute \"aria-activedescendant\"",
- \ "proprietary attribute \"aria-atomic\"",
- \ "proprietary attribute \"aria-autocomplete\"",
- \ "proprietary attribute \"aria-busy\"",
- \ "proprietary attribute \"aria-checked\"",
- \ "proprietary attribute \"aria-controls\"",
- \ "proprietary attribute \"aria-describedby\"",
- \ "proprietary attribute \"aria-disabled\"",
- \ "proprietary attribute \"aria-dropeffect\"",
- \ "proprietary attribute \"aria-expanded\"",
- \ "proprietary attribute \"aria-flowto\"",
- \ "proprietary attribute \"aria-grabbed\"",
- \ "proprietary attribute \"aria-haspopup\"",
- \ "proprietary attribute \"aria-hidden\"",
- \ "proprietary attribute \"aria-invalid\"",
- \ "proprietary attribute \"aria-label\"",
- \ "proprietary attribute \"aria-labelledby\"",
- \ "proprietary attribute \"aria-level\"",
- \ "proprietary attribute \"aria-live\"",
- \ "proprietary attribute \"aria-multiline\"",
- \ "proprietary attribute \"aria-multiselectable\"",
- \ "proprietary attribute \"aria-orientation\"",
- \ "proprietary attribute \"aria-owns\"",
- \ "proprietary attribute \"aria-posinset\"",
- \ "proprietary attribute \"aria-pressed\"",
- \ "proprietary attribute \"aria-readonly\"",
- \ "proprietary attribute \"aria-relevant\"",
- \ "proprietary attribute \"aria-relevant\"",
- \ "proprietary attribute \"aria-required\"",
- \ "proprietary attribute \"aria-selected\"",
- \ "proprietary attribute \"aria-setsize\"",
- \ "proprietary attribute \"aria-sort\"",
- \ "proprietary attribute \"aria-valuemax\"",
- \ "proprietary attribute \"aria-valuemin\"",
- \ "proprietary attribute \"aria-valuenow\"",
- \ "proprietary attribute \"aria-valuetext\""
- \ ]
+ \ " lacks \"summary\" attribute",
+ \ "not approved by W3C",
+ \ " proprietary attribute \"placeholder\"",
+ \ " proprietary attribute \"charset\"",
+ \ " lacks \"content\" attribute",
+ \ "inserting \"type\" attribute",
+ \ "proprietary attribute \"data-",
+ \ "missing declaration",
+ \ "inserting implicit ",
+ \ "inserting missing 'title' element",
+ \ "unescaped & or unknown entity",
+ \ " attribute \"type\" has invalid value",
+ \ "proprietary attribute \"role\"",
+ \ "proprietary attribute \"aria-activedescendant\"",
+ \ "proprietary attribute \"aria-atomic\"",
+ \ "proprietary attribute \"aria-autocomplete\"",
+ \ "proprietary attribute \"aria-busy\"",
+ \ "proprietary attribute \"aria-checked\"",
+ \ "proprietary attribute \"aria-controls\"",
+ \ "proprietary attribute \"aria-describedby\"",
+ \ "proprietary attribute \"aria-disabled\"",
+ \ "proprietary attribute \"aria-dropeffect\"",
+ \ "proprietary attribute \"aria-expanded\"",
+ \ "proprietary attribute \"aria-flowto\"",
+ \ "proprietary attribute \"aria-grabbed\"",
+ \ "proprietary attribute \"aria-haspopup\"",
+ \ "proprietary attribute \"aria-hidden\"",
+ \ "proprietary attribute \"aria-invalid\"",
+ \ "proprietary attribute \"aria-label\"",
+ \ "proprietary attribute \"aria-labelledby\"",
+ \ "proprietary attribute \"aria-level\"",
+ \ "proprietary attribute \"aria-live\"",
+ \ "proprietary attribute \"aria-multiline\"",
+ \ "proprietary attribute \"aria-multiselectable\"",
+ \ "proprietary attribute \"aria-orientation\"",
+ \ "proprietary attribute \"aria-owns\"",
+ \ "proprietary attribute \"aria-posinset\"",
+ \ "proprietary attribute \"aria-pressed\"",
+ \ "proprietary attribute \"aria-readonly\"",
+ \ "proprietary attribute \"aria-relevant\"",
+ \ "proprietary attribute \"aria-relevant\"",
+ \ "proprietary attribute \"aria-required\"",
+ \ "proprietary attribute \"aria-selected\"",
+ \ "proprietary attribute \"aria-setsize\"",
+ \ "proprietary attribute \"aria-sort\"",
+ \ "proprietary attribute \"aria-valuemax\"",
+ \ "proprietary attribute \"aria-valuemin\"",
+ \ "proprietary attribute \"aria-valuenow\"",
+ \ "proprietary attribute \"aria-valuetext\""
+ \ ]
+lockvar! s:ignore_errors
let s:blocklevel_tags = [
- \ "main",
- \ "section",
- \ "article",
- \ "aside",
- \ "header",
- \ "footer",
- \ "nav",
- \ "figure",
- \ "figcaption"
- \ ]
+ \ "main",
+ \ "section",
+ \ "article",
+ \ "aside",
+ \ "header",
+ \ "footer",
+ \ "nav",
+ \ "figure",
+ \ "figcaption"
+ \ ]
+lockvar! s:blocklevel_tags
let s:inline_tags = [
- \ "video",
- \ "audio",
- \ "source",
- \ "embed",
- \ "mark",
- \ "progress",
- \ "meter",
- \ "time",
- \ "ruby",
- \ "rt",
- \ "rp",
- \ "canvas",
- \ "command",
- \ "details",
- \ "datalist"
- \ ]
+ \ "video",
+ \ "audio",
+ \ "source",
+ \ "embed",
+ \ "mark",
+ \ "progress",
+ \ "meter",
+ \ "time",
+ \ "ruby",
+ \ "rt",
+ \ "rp",
+ \ "canvas",
+ \ "command",
+ \ "details",
+ \ "datalist"
+ \ ]
+lockvar! s:inline_tags
let s:empty_tags = [
- \ "wbr",
- \ "keygen"
- \ ]
+ \ "wbr",
+ \ "keygen"
+ \ ]
+lockvar! s:empty_tags
function! s:IgnoreError(text)
for i in s:ignore_errors + g:syntastic_html_tidy_ignore_errors
@@ -174,9 +186,7 @@ function! s:Args()
endfunction
function! SyntaxCheckers_html_tidy_GetLocList() dict
- let makeprg = self.makeprgBuild({
- \ 'args_after': s:Args(),
- \ 'tail': '2>&1' })
+ let makeprg = self.makeprgBuild({ 'args_after': s:Args() })
let errorformat =
\ '%Wline %l column %v - Warning: %m,' .
diff --git a/syntax_checkers/html/validator.vim b/syntax_checkers/html/validator.vim
index eb8ab0f..6a8e503 100644
--- a/syntax_checkers/html/validator.vim
+++ b/syntax_checkers/html/validator.vim
@@ -48,21 +48,6 @@ endif
let s:save_cpo = &cpo
set cpo&vim
-function! SyntaxCheckers_html_validator_Preprocess(errors)
- let out = []
- for e in a:errors
- let parts = matchlist(e, '\v^"([^"]+)"(.+)')
- if len(parts) >= 3
- " URL decode, except leave alone any "+"
- let parts[1] = substitute(parts[1], '\m%\(\x\x\)', '\=nr2char("0x".submatch(1))', 'g')
- let parts[1] = substitute(parts[1], '\m\\"', '"', 'g')
- let parts[1] = substitute(parts[1], '\m\\\\', '\\', 'g')
- call add(out, '"' . parts[1] . '"' . parts[2])
- endif
- endfor
- return out
-endfunction
-
function! SyntaxCheckers_html_validator_GetLocList() dict
let fname = syntastic#util#shexpand('%')
let makeprg = self.getExecEscaped() . ' -s --compressed -F out=gnu -F asciiquotes=yes' .
@@ -87,7 +72,7 @@ function! SyntaxCheckers_html_validator_GetLocList() dict
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
- \ 'preprocess': 'SyntaxCheckers_html_validator_Preprocess',
+ \ 'preprocess': 'validator',
\ 'returns': [0] })
endfunction
diff --git a/syntax_checkers/java/checkstyle.vim b/syntax_checkers/java/checkstyle.vim
index b388231..387c2c9 100644
--- a/syntax_checkers/java/checkstyle.vim
+++ b/syntax_checkers/java/checkstyle.vim
@@ -27,33 +27,6 @@ endif
let s:save_cpo = &cpo
set cpo&vim
-function! SyntaxCheckers_java_checkstyle_Preprocess(errors)
- let out = []
- let fname = expand('%')
- for err in a:errors
- if match(err, '\m') > -1
- let line = str2nr(matchstr(err, '\m\\s*$')
if !empty(matches)
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
let matches = matchlist(line, '\m^\s*<\([a-zA-Z0-9\-\.]\+\)>\(.\+\)[a-zA-Z0-9\-\.]\+>\s*$')
if mvn_is_managed_tag && !empty(matches)
@@ -262,10 +259,12 @@ if g:syntastic_java_javac_config_file_enabled
endif
function! s:GetMavenClasspath()
- let pom = findfile("pom.xml", ".;")
+ let pom = findfile('pom.xml', '.;')
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)
- 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 = ''
let class_path_next = 0
@@ -308,20 +307,20 @@ function! SyntaxCheckers_java_javac_IsAvailable() dict
endfunction
function! s:MavenOutputDirectory()
- let pom = findfile("pom.xml", ".;")
+ let pom = findfile('pom.xml', '.;')
if s:has_maven && filereadable(pom)
let mvn_properties = s:GetMavenProperties()
let output_dir = getcwd()
if has_key(mvn_properties, 'project.properties.build.dir')
let output_dir = mvn_properties['project.properties.build.dir']
endif
- if stridx(expand( '%:p:h' ), "src.main.java") >= 0
+ if stridx(expand( '%:p:h' ), 'src.main.java') >= 0
let output_dir .= '/target/classes'
if has_key(mvn_properties, 'project.build.outputDirectory')
let output_dir = mvn_properties['project.build.outputDirectory']
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'
if has_key(mvn_properties, 'project.build.testOutputDirectory')
let output_dir = mvn_properties['project.build.testOutputDirectory']
@@ -329,7 +328,7 @@ function! s:MavenOutputDirectory()
endif
if has('win32unix')
- let output_dir=s:CygwinPath(output_dir)
+ let output_dir = s:CygwinPath(output_dir)
endif
return output_dir
endif
@@ -337,13 +336,12 @@ function! s:MavenOutputDirectory()
endfunction
function! SyntaxCheckers_java_javac_GetLocList() dict
-
let javac_opts = g:syntastic_java_javac_options
- let output_dir = ""
+ let output_dir = ''
if g:syntastic_java_javac_delete_output
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
" load classpath from config file
@@ -354,12 +352,7 @@ function! SyntaxCheckers_java_javac_GetLocList() dict
let javac_classpath = ''
" add classpathes to javac_classpath
- if has('win32') || has('win32unix') || has('win64')
- let javac_classpath_split = ';'
- else
- let javac_classpath_split = ':'
- endif
- for path in split(g:syntastic_java_javac_classpath, javac_classpath_split)
+ for path in split(g:syntastic_java_javac_classpath, s:ClassSep())
if path != ''
try
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 !g:syntastic_java_javac_delete_output
- let javac_opts .= ' -d ' . s:MavenOutputDirectory()
+ let javac_opts .= ' -d ' . syntastic#util#shescape(s:MavenOutputDirectory())
endif
let javac_classpath = s:AddToClasspath(javac_classpath, s:GetMavenClasspath())
endif
@@ -386,7 +379,7 @@ function! SyntaxCheckers_java_javac_GetLocList() dict
" load custom classpath
if 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')
endif
for l in split(lines, "\n")
@@ -395,26 +388,18 @@ function! SyntaxCheckers_java_javac_GetLocList() dict
endif
if javac_classpath != ''
- let javac_opts .= ' -cp "' . fnameescape(javac_classpath) . '"'
- endif
-
- " path seperator
- if has('win32') || has('win32unix') || has('win64')
- let sep = "\\"
- else
- let sep = '/'
+ let javac_opts .= ' -cp ' . syntastic#util#shexpand(javac_classpath)
endif
- let fname = fnameescape(expand ( '%:p:h' ) . sep . expand ( '%:t' ))
+ let fname = expand('%:p:h') . syntastic#util#Slash() . expand ('%:t')
if has('win32unix')
- let fname = s:CygwinPath(fname)
+ let fname = s:CygwinPath(fname)
endif
let makeprg = self.makeprgBuild({
\ 'args': javac_opts,
- \ 'fname': fname,
- \ 'tail': '2>&1' })
+ \ 'fname': syntastic#util#shescape(fname) })
" unashamedly stolen from *errorformat-javac* (quickfix.txt) and modified to include error types
let errorformat =
diff --git a/syntax_checkers/javascript/closurecompiler.vim b/syntax_checkers/javascript/closurecompiler.vim
index d23fad0..5dac3ab 100644
--- a/syntax_checkers/javascript/closurecompiler.vim
+++ b/syntax_checkers/javascript/closurecompiler.vim
@@ -8,48 +8,36 @@
" Want To Public License, Version 2, as published by Sam Hocevar.
" 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")
finish
endif
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
set cpo&vim
function! SyntaxCheckers_javascript_closurecompiler_IsAvailable() dict
+ call syntastic#log#deprecationWarn('javascript_closure_compiler_path', 'javascript_closurecompiler_path')
+
return
\ executable("java") &&
- \ exists("g:syntastic_javascript_closure_compiler_path") &&
- \ filereadable(g:syntastic_javascript_closure_compiler_path)
+ \ exists("g:syntastic_javascript_closurecompiler_path") &&
+ \ filereadable(g:syntastic_javascript_closurecompiler_path)
endfunction
function! SyntaxCheckers_javascript_closurecompiler_GetLocList() dict
- if exists("g:syntastic_javascript_closure_compiler_file_list")
- let file_list = join(readfile(g:syntastic_javascript_closure_compiler_file_list))
+ call syntastic#log#deprecationWarn('javascript_closure_compiler_options', 'javascript_closurecompiler_args')
+ 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
let file_list = syntastic#util#shexpand('%')
endif
let makeprg = self.makeprgBuild({
- \ 'exe': 'java -jar ' . g:syntastic_javascript_closure_compiler_path,
- \ 'args': g:syntastic_javascript_closure_compiler_options,
+ \ 'exe_after': '-jar ' . g:syntastic_javascript_closurecompiler_path,
\ 'args_after': '--js' ,
\ 'fname': file_list })
diff --git a/syntax_checkers/javascript/eslint.vim b/syntax_checkers/javascript/eslint.vim
index c23cbbc..96919c8 100644
--- a/syntax_checkers/javascript/eslint.vim
+++ b/syntax_checkers/javascript/eslint.vim
@@ -14,29 +14,35 @@ if exists('g:loaded_syntastic_javascript_eslint_checker')
endif
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
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
- let makeprg = self.makeprgBuild({
- \ 'args': (g:syntastic_javascript_eslint_conf != '' ? '--config ' . g:syntastic_javascript_eslint_conf : '') })
+ call syntastic#log#deprecationWarn('javascript_eslint_conf', 'javascript_eslint_args',
+ \ "'--config ' . syntastic#util#shexpand(OLD_VAR)")
+
+ let makeprg = self.makeprgBuild({ 'args_before': '-f compact' })
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({
\ 'makeprg': makeprg,
- \ 'errorformat': errorformat,
- \ 'postprocess': ['sort'] })
+ \ 'errorformat': errorformat })
for e in loclist
let e['col'] += 1
endfor
+ call self.setWantSort(1)
+
return loclist
endfunction
diff --git a/syntax_checkers/javascript/gjslint.vim b/syntax_checkers/javascript/gjslint.vim
index 1b171c9..1704ac2 100644
--- a/syntax_checkers/javascript/gjslint.vim
+++ b/syntax_checkers/javascript/gjslint.vim
@@ -14,16 +14,13 @@ if exists("g:loaded_syntastic_javascript_gjslint_checker")
endif
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
set cpo&vim
function! SyntaxCheckers_javascript_gjslint_GetLocList() dict
+ call syntastic#log#deprecationWarn('javascript_gjslint_conf', 'javascript_gjslint_args')
+
let makeprg = self.makeprgBuild({
- \ 'args': g:syntastic_javascript_gjslint_conf,
\ 'args_after': '--nosummary --unix_mode --nodebug_indentation --nobeep' })
let errorformat =
diff --git a/syntax_checkers/javascript/jscs.vim b/syntax_checkers/javascript/jscs.vim
index 2c1e54f..c501752 100644
--- a/syntax_checkers/javascript/jscs.vim
+++ b/syntax_checkers/javascript/jscs.vim
@@ -17,19 +17,21 @@ let g:loaded_syntastic_javascript_jscs_checker = 1
let s:save_cpo = &cpo
set cpo&vim
-" we borrow SyntaxCheckers_java_checkstyle_Preprocess() from java/checkstyle
-runtime! syntax_checkers/java/*.vim
-
function! SyntaxCheckers_javascript_jscs_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args_after': '--no-colors --reporter checkstyle' })
+
let errorformat = '%f:%t:%l:%c:%m'
- return SyntasticMake({
+
+ let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'subtype': 'Style',
- \ 'preprocess': 'SyntaxCheckers_java_checkstyle_Preprocess',
- \ 'postprocess': ['sort'],
- \ 'returns': [0] })
+ \ 'preprocess': 'checkstyle',
+ \ 'returns': [0, 2] })
+
+ call self.setWantSort(1)
+
+ return loclist
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
diff --git a/syntax_checkers/javascript/jshint.vim b/syntax_checkers/javascript/jshint.vim
index e1c84f1..69706c0 100644
--- a/syntax_checkers/javascript/jshint.vim
+++ b/syntax_checkers/javascript/jshint.vim
@@ -14,40 +14,39 @@ if exists('g:loaded_syntastic_javascript_jshint_checker')
endif
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
set cpo&vim
function! SyntaxCheckers_javascript_jshint_IsAvailable() dict
- if !exists('g:syntastic_jshint_exec')
- let g:syntastic_jshint_exec = self.getExec()
+ call syntastic#log#deprecationWarn('jshint_exec', 'javascript_jshint_exec')
+ if !executable(self.getExec())
+ return 0
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
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')
- let s:jshint_new =
- \ syntastic#util#versionIsAtLeast(syntastic#util#getVersion(exe . ' --version'), [1, 1])
+ let s:jshint_new = syntastic#util#versionIsAtLeast(s:jshint_version, [1, 1])
endif
- let makeprg = self.makeprgBuild({
- \ 'exe': exe,
- \ 'args': (g:syntastic_javascript_jshint_conf != '' ? '--config ' . g:syntastic_javascript_jshint_conf : ''),
- \ 'args_after': (s:jshint_new ? '--verbose ' : '') })
+ let makeprg = self.makeprgBuild({ 'args_after': (s:jshint_new ? '--verbose ' : '') })
let errorformat = s:jshint_new ?
\ '%A%f: line %l\, col %v\, %m \(%t%*\d\)' :
\ '%E%f: line %l\, col %v\, %m'
+ call self.setWantSort(1)
+
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
- \ 'defaults': {'bufnr': bufnr('')} })
+ \ 'defaults': {'bufnr': bufnr('')},
+ \ 'returns': [0, 2] })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
diff --git a/syntax_checkers/javascript/jsl.vim b/syntax_checkers/javascript/jsl.vim
index 0e894bf..8f4148d 100644
--- a/syntax_checkers/javascript/jsl.vim
+++ b/syntax_checkers/javascript/jsl.vim
@@ -14,16 +14,14 @@ if exists("g:loaded_syntastic_javascript_jsl_checker")
endif
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
set cpo&vim
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({
- \ 'args': (g:syntastic_javascript_jsl_conf != '' ? '-conf ' . g:syntastic_javascript_jsl_conf : ''),
\ 'args_after': '-nologo -nofilelisting -nosummary -nocontext -process' })
let errorformat =
diff --git a/syntax_checkers/javascript/jslint.vim b/syntax_checkers/javascript/jslint.vim
index c233cf3..63bb410 100644
--- a/syntax_checkers/javascript/jslint.vim
+++ b/syntax_checkers/javascript/jslint.vim
@@ -22,7 +22,7 @@ set cpo&vim
function! SyntaxCheckers_javascript_jslint_GetHighlightRegex(item)
let term = matchstr(a:item['text'], '\mExpected .* and instead saw ''\zs.*\ze''')
if term != ''
- let term = '\V' . term
+ let term = '\V\<' . escape(term, '\') . '\>'
endif
return term
endfunction
diff --git a/syntax_checkers/javascript/jsxhint.vim b/syntax_checkers/javascript/jsxhint.vim
new file mode 100644
index 0000000..21ba6a0
--- /dev/null
+++ b/syntax_checkers/javascript/jsxhint.vim
@@ -0,0 +1,47 @@
+"============================================================================
+"File: jsxhint.vim
+"Description: Javascript syntax checker - using jsxhint
+"Maintainer: Thomas Boyt
+"License: This program is free software. It comes without any warranty,
+" to the extent permitted by applicable law. You can redistribute
+" it and/or modify it under the terms of the Do What The Fuck You
+" Want To Public License, Version 2, as published by Sam Hocevar.
+" See http://sam.zoy.org/wtfpl/COPYING for more details.
+"============================================================================
+
+if exists('g:loaded_syntastic_javascript_jsxhint_checker')
+ finish
+endif
+let g:loaded_syntastic_javascript_jsxhint_checker = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+function! SyntaxCheckers_javascript_jsxhint_IsAvailable() dict
+ let jsxhint_version = system(self.getExecEscaped() . ' --version')
+ return
+ \ v:shell_error == 0 &&
+ \ jsxhint_version =~# '\m^JSXHint\>' &&
+ \ syntastic#util#versionIsAtLeast(syntastic#util#parseVersion(jsxhint_version), [0, 4, 1])
+endfunction
+
+function! SyntaxCheckers_javascript_jsxhint_GetLocList() dict
+ let makeprg = self.makeprgBuild({
+ \ 'args_after': '--verbose' })
+
+ let errorformat = '%A%f: line %l\, col %v\, %m \(%t%*\d\)'
+
+ return SyntasticMake({
+ \ 'makeprg': makeprg,
+ \ 'errorformat': errorformat,
+ \ 'defaults': {'bufnr': bufnr('')} })
+endfunction
+
+call g:SyntasticRegistry.CreateAndRegisterChecker({
+ \ 'filetype': 'javascript',
+ \ 'name': 'jsxhint'})
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set et sts=4 sw=4:
diff --git a/syntax_checkers/less/recess.vim b/syntax_checkers/less/recess.vim
new file mode 100644
index 0000000..9294418
--- /dev/null
+++ b/syntax_checkers/less/recess.vim
@@ -0,0 +1,44 @@
+"============================================================================
+"File: recess.vim
+"Description: Syntax checking plugin for syntastic.vim using `recess`
+" (http://twitter.github.io/recess/).
+"Maintainer: Tim Carry
+"License: This program is free software. It comes without any warranty,
+" to the extent permitted by applicable law. You can redistribute
+" it and/or modify it under the terms of the Do What The Fuck You
+" Want To Public License, Version 2, as published by Sam Hocevar.
+" See http://sam.zoy.org/wtfpl/COPYING for more details.
+"
+"============================================================================
+
+if exists('g:loaded_syntastic_less_recess_checker')
+ finish
+endif
+let g:loaded_syntastic_less_recess_checker = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+function! SyntaxCheckers_less_recess_GetLocList() dict
+ let makeprg = self.makeprgBuild({
+ \ 'post_args_after': '--format=compact --stripColors' })
+
+ let errorformat =
+ \ '%E%m in %f,' .
+ \ '%Z %#%l.%.%#,' .
+ \ '%f:%l:%m,' .
+ \ '%-G%.%#'
+
+ return SyntasticMake({
+ \ 'makeprg': makeprg,
+ \ 'errorformat': errorformat })
+endfunction
+
+call g:SyntasticRegistry.CreateAndRegisterChecker({
+ \ 'filetype': 'less',
+ \ 'name': 'recess'})
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set et sts=4 sw=4:
diff --git a/syntax_checkers/lex/flex.vim b/syntax_checkers/lex/flex.vim
index c6e4834..b8bc648 100644
--- a/syntax_checkers/lex/flex.vim
+++ b/syntax_checkers/lex/flex.vim
@@ -26,7 +26,7 @@ function! SyntaxCheckers_lex_flex_GetHighlightRegex(item)
\ '\m^\(Definition value for\|undefined definition\) \zs{[^}]\+}\ze')
endif
- return term != '' ? '\V' . term : ''
+ return term != '' ? '\V' . escape(term, '\') : ''
endfunction
function! SyntaxCheckers_lex_flex_GetLocList() dict
diff --git a/syntax_checkers/lisp/clisp.vim b/syntax_checkers/lisp/clisp.vim
index 2c3876d..5e726a9 100644
--- a/syntax_checkers/lisp/clisp.vim
+++ b/syntax_checkers/lisp/clisp.vim
@@ -20,13 +20,14 @@ set cpo&vim
function! SyntaxCheckers_lisp_clisp_GetLocList() dict
let makeprg = self.makeprgBuild({
- \ 'args_after': '-q -c ' . syntastic#c#NullOutput() })
+ \ 'args_after': '-q',
+ \ 'fname_before': '-c' })
let errorformat =
\ '%-G;%.%#,' .
- \ '%W%>WARNING:%.%#line %l : %m,' .
+ \ '%W%>WARNING:%.%# line %l : %m,' .
\ '%Z %#%m,' .
- \ '%W%>WARNING:%.%#lines %l..%\d\# : %m,' .
+ \ '%W%>WARNING:%.%# lines %l%\%.%\%.%\d%\+ : %m,' .
\ '%Z %#%m,' .
\ '%E%>The following functions were %m,' .
\ '%Z %m,' .
diff --git a/syntax_checkers/lua/luac.vim b/syntax_checkers/lua/luac.vim
index b34778d..012f149 100644
--- a/syntax_checkers/lua/luac.vim
+++ b/syntax_checkers/lua/luac.vim
@@ -28,7 +28,7 @@ function! SyntaxCheckers_lua_luac_GetHighlightRegex(pos)
let a:pos['col'] = p[2]
let result = '\%' . p[2] . 'c'
else
- let result = '\V' . near
+ let result = '\V' . escape(near, '\')
endif
" XXX the following piece of code is evil, and is likely to break
@@ -38,7 +38,7 @@ function! SyntaxCheckers_lua_luac_GetHighlightRegex(pos)
"if open != ''
" let line = str2nr(matchstr(a:pos['text'], '\m(to close ''[^'']\+'' at line \zs[0-9]\+\ze)'))
" let group = a:pos['type'] ==? 'E' ? 'SyntasticError' : 'SyntasticWarning'
- " call matchadd(group, '\%' . line . 'l\V' . open)
+ " call matchadd(group, '\%' . line . 'l\V' . escape(open, '\'))
"endif
endif
return result
diff --git a/syntax_checkers/perl/perl.vim b/syntax_checkers/perl/perl.vim
index eca6501..553c55a 100644
--- a/syntax_checkers/perl/perl.vim
+++ b/syntax_checkers/perl/perl.vim
@@ -11,6 +11,22 @@
"
"============================================================================
"
+" Security:
+"
+" This checker runs 'perl -c' against your file, which in turn executes
+" any BEGIN, UNITCHECK, and CHECK blocks, and any use statements in
+" your file. This is probably fine if you wrote the file yourself,
+" but it can be a problem if you're trying to check third party files.
+" If you are 100% willing to let Vim run the code in your file, set
+" g:syntastic_enable_perl_checker to 1 in your vimrc to enable this
+" checker:
+"
+" let g:syntastic_enable_perl_checker = 1
+"
+" References:
+"
+" - http://perldoc.perl.org/perlrun.html#*-c*
+"
" Checker options:
"
" - g:syntastic_perl_interpreter (string; default: 'perl')
@@ -24,11 +40,7 @@
if exists('g:loaded_syntastic_perl_perl_checker')
finish
endif
-let g:loaded_syntastic_perl_perl_checker=1
-
-if !exists('g:syntastic_perl_interpreter')
- let g:syntastic_perl_interpreter = 'perl'
-endif
+let g:loaded_syntastic_perl_perl_checker = 1
if !exists('g:syntastic_perl_lib_path')
let g:syntastic_perl_lib_path = []
@@ -38,29 +50,25 @@ let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_perl_perl_IsAvailable() dict
+ if !exists('g:syntastic_perl_perl_exec') && exists('g:syntastic_perl_interpreter')
+ let g:syntastic_perl_perl_exec = g:syntastic_perl_interpreter
+ endif
+
" don't call executable() here, to allow things like
" 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
endfunction
-function! SyntaxCheckers_perl_perl_Preprocess(errors)
- let out = []
-
- for e in a:errors
- let parts = matchlist(e, '\v^(.*)\sat\s(.*)\sline\s(\d+)(.*)$')
- if !empty(parts)
- call add(out, parts[2] . ':' . parts[3] . ':' . parts[1] . parts[4])
- endif
- endfor
-
- return syntastic#util#unique(out)
-endfunction
-
function! SyntaxCheckers_perl_perl_GetLocList() dict
- let exe = expand(g:syntastic_perl_interpreter)
+ 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')
+ return []
+ endif
+
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, ',')
else
let includes = copy(syntastic#util#var('perl_lib_path'))
@@ -71,27 +79,23 @@ function! SyntaxCheckers_perl_perl_GetLocList() dict
\ (index(shebang['args'], '-t') >= 0 ? ' -t' : '')
let errorformat = '%f:%l:%m'
- let makeprg = self.makeprgBuild({
- \ 'exe': exe,
- \ 'args_before': '-c -X ' . extra })
+ let makeprg = self.makeprgBuild({ 'args_before': '-c -X ' . extra })
let errors = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
- \ 'preprocess': 'SyntaxCheckers_perl_perl_Preprocess',
+ \ 'preprocess': 'perl',
\ 'defaults': {'type': 'E'} })
if !empty(errors)
return errors
endif
- let makeprg = self.makeprgBuild({
- \ 'exe': exe,
- \ 'args_before': '-c -Mwarnings ' . extra })
+ let makeprg = self.makeprgBuild({ 'args_before': '-c -Mwarnings ' . extra })
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
- \ 'preprocess': 'SyntaxCheckers_perl_perl_Preprocess',
+ \ 'preprocess': 'perl',
\ 'defaults': {'type': 'W'} })
endfunction
diff --git a/syntax_checkers/php/php.vim b/syntax_checkers/php/php.vim
index 3192d7d..23c1db9 100644
--- a/syntax_checkers/php/php.vim
+++ b/syntax_checkers/php/php.vim
@@ -20,7 +20,7 @@ set cpo&vim
function! SyntaxCheckers_php_php_GetHighlightRegex(item)
let term = matchstr(a:item['text'], "\\munexpected '\\zs[^']\\+\\ze'")
- return term != '' ? '\V' . term : ''
+ return term != '' ? '\V' . escape(term, '\') : ''
endfunction
function! SyntaxCheckers_php_php_GetLocList() dict
diff --git a/syntax_checkers/php/phpcs.vim b/syntax_checkers/php/phpcs.vim
index 23d539d..e6600ac 100644
--- a/syntax_checkers/php/phpcs.vim
+++ b/syntax_checkers/php/phpcs.vim
@@ -27,8 +27,8 @@ function! SyntaxCheckers_php_phpcs_GetLocList() dict
\ 'args_after': '--report=csv' })
let errorformat =
- \ '%-GFile\,Line\,Column\,Type\,Message\,Source\,Severity,'.
- \ '"%f"\,%l\,%v\,%t%*[a-zA-Z]\,"%m"\,%*[a-zA-Z0-9_.-]\,%*[0-9]'
+ \ '%-GFile\,Line\,Column\,Type\,Message\,Source\,Severity%.%#,'.
+ \ '"%f"\,%l\,%v\,%t%*[a-zA-Z]\,"%m"\,%*[a-zA-Z0-9_.-]\,%*[0-9]%.%#'
return SyntasticMake({
\ 'makeprg': makeprg,
diff --git a/syntax_checkers/po/msgfmt.vim b/syntax_checkers/po/msgfmt.vim
index 5b714de..254aa91 100644
--- a/syntax_checkers/po/msgfmt.vim
+++ b/syntax_checkers/po/msgfmt.vim
@@ -20,7 +20,7 @@ set cpo&vim
function! SyntaxCheckers_po_msgfmt_GetHighlightRegex(item)
let term = matchstr(a:item['text'], '\mkeyword "\zs[^"]\+\ze" unknown')
- return term != '' ? '\V' . term : ''
+ return term != '' ? '\V' . escape(term, '\') : ''
endfunction
function! SyntaxCheckers_po_msgfmt_GetLocList() dict
diff --git a/syntax_checkers/puppet/puppetlint.vim b/syntax_checkers/puppet/puppetlint.vim
index 2a32a8f..ff4ba07 100644
--- a/syntax_checkers/puppet/puppetlint.vim
+++ b/syntax_checkers/puppet/puppetlint.vim
@@ -18,11 +18,6 @@ let g:loaded_syntastic_puppet_puppetlint_checker = 1
let s:save_cpo = &cpo
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
return
\ executable("puppet") &&
@@ -32,6 +27,8 @@ function! SyntaxCheckers_puppet_puppetlint_IsAvailable() dict
endfunction
function! SyntaxCheckers_puppet_puppetlint_GetLocList() dict
+ call syntastic#log#deprecationWarn('puppet_lint_arguments', 'puppet_puppetlint_args')
+
let makeprg = self.makeprgBuild({
\ 'args_after': '--log-format "%{KIND} [%{check}] %{message} at %{fullpath}:%{linenumber}"' })
diff --git a/syntax_checkers/python/flake8.vim b/syntax_checkers/python/flake8.vim
index 61d55cc..1e4f1c9 100644
--- a/syntax_checkers/python/flake8.vim
+++ b/syntax_checkers/python/flake8.vim
@@ -27,9 +27,12 @@ function! SyntaxCheckers_python_flake8_GetLocList() dict
\ '%A%f:%l: %t%n %m,' .
\ '%-G%.%#'
+ let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
+
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
- \ 'errorformat': errorformat })
+ \ 'errorformat': errorformat,
+ \ 'env': env })
for e in loclist
" E*** and W*** are pep8 errors
diff --git a/syntax_checkers/python/frosted.vim b/syntax_checkers/python/frosted.vim
index 2b6119c..e1284e4 100644
--- a/syntax_checkers/python/frosted.vim
+++ b/syntax_checkers/python/frosted.vim
@@ -27,9 +27,12 @@ function! SyntaxCheckers_python_frosted_GetLocList() dict
\ '%-Z%p^,' .
\ '%-G%.%#'
+ let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
+
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
+ \ 'env': env,
\ 'returns': [0, 1] })
for e in loclist
@@ -39,7 +42,7 @@ function! SyntaxCheckers_python_frosted_GetLocList() dict
if len(parts) >= 4
let e["type"] = parts[1][0]
let e["text"] = parts[3] . ' [' . parts[1] . ']'
- let e["hl"] = '\V' . parts[2]
+ let e["hl"] = '\V' . escape(parts[2], '\')
elseif e["text"] =~? '\v^I\d+:'
let e["valid"] = 0
else
diff --git a/syntax_checkers/python/pep257.vim b/syntax_checkers/python/pep257.vim
index 31ec162..d4b1657 100644
--- a/syntax_checkers/python/pep257.vim
+++ b/syntax_checkers/python/pep257.vim
@@ -5,7 +5,7 @@
"
" 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
endif
let g:loaded_syntastic_python_pep257_checker = 1
@@ -13,30 +13,41 @@ let g:loaded_syntastic_python_pep257_checker = 1
let s:save_cpo = &cpo
set cpo&vim
-" sanity: kill empty lines here rather than munging errorformat
-function! SyntaxCheckers_python_pep257_Preprocess(errors)
- return filter(copy(a:errors), 'v:val != ""')
-endfunction
-
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 errorformat =
- \ '%E%f:%l:%c%\%.%\%.%\d%\+:%\d%\+: %m,' .
- \ '%E%f:%l:%c: %m,' .
- \ '%+C %m'
+ if s:pep257_new
+ let errorformat =
+ \ '%E%f:%l %.%#:,' .
+ \ '%+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({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
+ \ 'env': env,
\ 'subtype': 'Style',
- \ 'preprocess': 'SyntaxCheckers_python_pep257_Preprocess',
+ \ 'preprocess': 'killEmpty',
\ 'postprocess': ['compressWhitespace'] })
- " pep257 outputs byte offsets rather than column numbers
- for e in loclist
- let e['col'] = get(e, 'col', 0) + 1
- endfor
+ if s:pep257_new == 0
+ " byte offsets rather than column numbers
+ for e in loclist
+ let e['col'] = get(e, 'col', 0) + 1
+ endfor
+ endif
return loclist
endfunction
diff --git a/syntax_checkers/python/pep8.vim b/syntax_checkers/python/pep8.vim
index 310746b..0f35c27 100644
--- a/syntax_checkers/python/pep8.vim
+++ b/syntax_checkers/python/pep8.vim
@@ -25,9 +25,12 @@ function! SyntaxCheckers_python_pep8_GetLocList() dict
let errorformat = '%f:%l:%c: %m'
+ let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
+
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
+ \ 'env': env,
\ 'subtype': 'Style' })
for e in loclist
diff --git a/syntax_checkers/python/py3kwarn.vim b/syntax_checkers/python/py3kwarn.vim
index 5ceb51a..69a3060 100644
--- a/syntax_checkers/python/py3kwarn.vim
+++ b/syntax_checkers/python/py3kwarn.vim
@@ -18,9 +18,12 @@ function! SyntaxCheckers_python_py3kwarn_GetLocList() dict
let errorformat = '%W%f:%l:%c: %m'
+ let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
+
return SyntasticMake({
\ 'makeprg': makeprg,
- \ 'errorformat': errorformat })
+ \ 'errorformat': errorformat,
+ \ 'env': env })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
diff --git a/syntax_checkers/python/pyflakes.vim b/syntax_checkers/python/pyflakes.vim
index e62965f..530a275 100644
--- a/syntax_checkers/python/pyflakes.vim
+++ b/syntax_checkers/python/pyflakes.vim
@@ -26,14 +26,14 @@ function! SyntaxCheckers_python_pyflakes_GetHighlightRegex(i)
\ || stridx(a:i['text'], 'shadowed by loop variable') >= 0
" fun with Python's %r: try "..." first, then '...'
- let terms = split(a:i['text'], '"', 1)
- if len(terms) > 2
- return terms[1]
+ let term = matchstr(a:i['text'], '\m^.\{-}"\zs.\{-1,}\ze"')
+ if term != ''
+ return '\V\<' . escape(term, '\') . '\>'
endif
- let terms = split(a:i['text'], "'", 1)
- if len(terms) > 2
- return terms[1]
+ let term = matchstr(a:i['text'], '\m^.\{-}''\zs.\{-1,}\ze''')
+ if term != ''
+ return '\V\<' . escape(term, '\') . '\>'
endif
endif
return ''
@@ -45,12 +45,16 @@ function! SyntaxCheckers_python_pyflakes_GetLocList() dict
let errorformat =
\ '%E%f:%l: could not compile,'.
\ '%-Z%p^,'.
+ \ '%E%f:%l:%c: %m,'.
\ '%E%f:%l: %m,'.
\ '%-G%.%#'
+ let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
+
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
+ \ 'env': env,
\ 'defaults': {'text': "Syntax error"} })
for e in loclist
diff --git a/syntax_checkers/python/pylama.vim b/syntax_checkers/python/pylama.vim
index 93aa4ba..01c0ab6 100644
--- a/syntax_checkers/python/pylama.vim
+++ b/syntax_checkers/python/pylama.vim
@@ -30,10 +30,12 @@ function! SyntaxCheckers_python_pylama_GetLocList() dict
\ '%-GWARNING:pylama:%.%#,' .
\ '%A%f:%l:%c: %m'
+ let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
+
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
- \ 'postprocess': ['sort'] })
+ \ 'env': env })
" adjust for weirdness in each checker
for e in loclist
@@ -53,6 +55,8 @@ function! SyntaxCheckers_python_pylama_GetLocList() dict
endif
endfor
+ call self.setWantSort(1)
+
return loclist
endfunction
diff --git a/syntax_checkers/python/pylint.vim b/syntax_checkers/python/pylint.vim
index 421b31b..88dff42 100644
--- a/syntax_checkers/python/pylint.vim
+++ b/syntax_checkers/python/pylint.vim
@@ -32,10 +32,12 @@ function! SyntaxCheckers_python_pylint_GetLocList() dict
\ '%-Z%p^%.%#,' .
\ '%-G%.%#'
- let loclist=SyntasticMake({
+ let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
+
+ let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
- \ 'postprocess': ['sort'],
+ \ 'env': env,
\ 'returns': range(32) })
for e in loclist
@@ -55,6 +57,8 @@ function! SyntaxCheckers_python_pylint_GetLocList() dict
let e['vcol'] = 0
endfor
+ call self.setWantSort(1)
+
return loclist
endfunction
@@ -63,12 +67,13 @@ function! s:PylintNew(exe)
try
" 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 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".
" 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^\.\=pylint[-0-9]*\>''')[0]
let pylint_version = substitute(pylint_version, '\v^\S+\s+', '', '')
let ret = syntastic#util#versionIsAtLeast(syntastic#util#parseVersion(pylint_version), [1])
- catch /^Vim\%((\a\+)\)\=:E684/
+ catch /\m^Vim\%((\a\+)\)\=:E684/
call syntastic#log#error("checker python/pylint: can't parse version string (abnormal termination?)")
let ret = -1
endtry
diff --git a/syntax_checkers/python/python.vim b/syntax_checkers/python/python.vim
index eced4d3..5023ee6 100644
--- a/syntax_checkers/python/python.vim
+++ b/syntax_checkers/python/python.vim
@@ -30,9 +30,12 @@ function! SyntaxCheckers_python_python_GetLocList() dict
let errorformat = '%E%f:%l:%c: %m'
+ let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
+
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
+ \ 'env': env,
\ 'returns': [0] })
endfunction
diff --git a/syntax_checkers/r/lint.vim b/syntax_checkers/r/lint.vim
new file mode 100644
index 0000000..9112905
--- /dev/null
+++ b/syntax_checkers/r/lint.vim
@@ -0,0 +1,81 @@
+"============================================================================
+"File: lint.vim
+"Description: Syntax checking plugin for syntastic.vim
+"Maintainer: LCD 47
+"License: This program is free software. It comes without any warranty,
+" to the extent permitted by applicable law. You can redistribute
+" it and/or modify it under the terms of the Do What The Fuck You
+" Want To Public License, Version 2, as published by Sam Hocevar.
+" See http://sam.zoy.org/wtfpl/COPYING for more details.
+"
+"============================================================================
+
+if exists("g:loaded_syntastic_r_lint_checker")
+ finish
+endif
+let g:loaded_syntastic_r_lint_checker = 1
+
+if !exists('g:syntastic_r_lint_styles')
+ let g:syntastic_r_lint_styles = 'lint.style'
+endif
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+function! SyntaxCheckers_r_lint_GetHighlightRegex(item)
+ let term = matchstr(a:item['text'], '\m`\zs[^`]\+\ze`')
+ if term == ''
+ let term = matchstr(a:item['text'], "\\m'\\zs[^']\\+\\ze'")
+ endif
+ return term != '' ? '\V' . escape(term, '\') : ''
+endfunction
+
+function! SyntaxCheckers_r_lint_IsAvailable() dict
+ if !executable(self.getExec())
+ return 0
+ endif
+ call system(self.getExecEscaped() . ' --slave --restore --no-save -e ' . syntastic#util#shescape('library(lint)'))
+ return v:shell_error == 0
+endfunction
+
+function! SyntaxCheckers_r_lint_GetLocList() dict
+ let setwd = syntastic#util#isRunningWindows() ? 'setwd("' . escape(getcwd(), '"\') . '"); ' : ''
+ let setwd = 'setwd("' . escape(getcwd(), '"\') . '"); '
+ let makeprg = self.getExecEscaped() . ' --slave --restore --no-save' .
+ \ ' -e ' . syntastic#util#shescape(setwd . 'library(lint); ' .
+ \ 'try(lint(commandArgs(TRUE), ' . g:syntastic_r_lint_styles . '))') .
+ \ ' --args ' . syntastic#util#shexpand('%')
+
+ let errorformat =
+ \ '%t:%f:%l:%v: %m,' .
+ \ '%t:%f:%l: %m'
+
+ let loclist = SyntasticMake({
+ \ 'makeprg': makeprg,
+ \ 'errorformat': errorformat,
+ \ 'subtype': 'Style',
+ \ 'preprocess': 'rparse',
+ \ 'returns': [0] })
+
+ for e in loclist
+ if e['type'] == 'F'
+ " parse error
+ let e['type'] = 'E'
+ call remove(e, 'subtype')
+ endif
+ endfor
+
+ call self.setWantSort(1)
+
+ return loclist
+endfunction
+
+call g:SyntasticRegistry.CreateAndRegisterChecker({
+ \ 'filetype': 'r',
+ \ 'name': 'lint',
+ \ 'exec': 'R' })
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set et sts=4 sw=4:
diff --git a/syntax_checkers/r/svtools.vim b/syntax_checkers/r/svtools.vim
new file mode 100644
index 0000000..ec924c3
--- /dev/null
+++ b/syntax_checkers/r/svtools.vim
@@ -0,0 +1,78 @@
+"============================================================================
+"File: svtools.vim
+"Description: Syntax checking plugin for syntastic.vim
+"Maintainer: LCD 47
+"License: This program is free software. It comes without any warranty,
+" to the extent permitted by applicable law. You can redistribute
+" it and/or modify it under the terms of the Do What The Fuck You
+" Want To Public License, Version 2, as published by Sam Hocevar.
+" See http://sam.zoy.org/wtfpl/COPYING for more details.
+"
+"============================================================================
+"
+" Security:
+"
+" This checker runs the code in your file. This is probably fine if you
+" wrote the file yourself, but it can be a problem if you're trying to
+" check third party files. If you are 100% willing to let Vim run the
+" code in your file, set g:syntastic_enable_r_svtools_checker to 1 in
+" your vimrc to enable this checker:
+"
+" let g:syntastic_enable_r_svtools_checker = 1
+
+if exists("g:loaded_syntastic_r_svtools_checker")
+ finish
+endif
+let g:loaded_syntastic_r_svtools_checker = 1
+
+if !exists('g:syntastic_r_svtools_styles')
+ let g:syntastic_r_svtools_styles = 'lint.style'
+endif
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+function! SyntaxCheckers_r_svtools_GetHighlightRegex(item)
+ let term = matchstr(a:item['text'], "\\m'\\zs[^']\\+\\ze'")
+ return term != '' ? '\V' . escape(term, '\') : ''
+endfunction
+
+function! SyntaxCheckers_r_svtools_IsAvailable() dict
+ if !executable(self.getExec())
+ return 0
+ endif
+ call system(self.getExecEscaped() . ' --slave --restore --no-save -e ' . syntastic#util#shescape('library(svTools)'))
+ return v:shell_error == 0
+endfunction
+
+function! SyntaxCheckers_r_svtools_GetLocList() dict
+ if !exists('g:syntastic_enable_r_svtools_checker') || !g:syntastic_enable_r_svtools_checker
+ call syntastic#log#error('checker r/svtools: checks disabled for security reasons; set g:syntastic_enable_r_svtools_checker to 1 to override')
+ return []
+ endif
+
+ let setwd = syntastic#util#isRunningWindows() ? 'setwd("' . escape(getcwd(), '"\') . '"); ' : ''
+ let makeprg = self.getExecEscaped() . ' --slave --restore --no-save' .
+ \ ' -e ' . syntastic#util#shescape(setwd . 'library(svTools); ' .
+ \ 'try(lint(commandArgs(TRUE), filename = commandArgs(TRUE), type = "flat", sep = ":"))') .
+ \ ' --args ' . syntastic#util#shexpand('%')
+
+ let errorformat =
+ \ '%trror:%f:%\s%#%l:%\s%#%v:%m,' .
+ \ '%tarning:%f:%\s%#%l:%\s%#%v:%m'
+
+ return SyntasticMake({
+ \ 'makeprg': makeprg,
+ \ 'errorformat': errorformat,
+ \ 'returns': [0] })
+endfunction
+
+call g:SyntasticRegistry.CreateAndRegisterChecker({
+ \ 'filetype': 'r',
+ \ 'name': 'svtools',
+ \ 'exec': 'R' })
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set et sts=4 sw=4:
diff --git a/syntax_checkers/racket/code-ayatollah.vim b/syntax_checkers/racket/code-ayatollah.vim
index f8002a7..ffb02f7 100644
--- a/syntax_checkers/racket/code-ayatollah.vim
+++ b/syntax_checkers/racket/code-ayatollah.vim
@@ -38,13 +38,14 @@ function! SyntaxCheckers_racket_code_ayatollah_GetLocList() dict
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
- \ 'subtype': 'Style',
- \ 'postprocess': ['sort'] })
+ \ 'subtype': 'Style' })
for e in loclist
let e['col'] += 1
endfor
+ call self.setWantSort(1)
+
return loclist
endfunction
diff --git a/syntax_checkers/ruby/jruby.vim b/syntax_checkers/ruby/jruby.vim
index fc7ea63..bf57b09 100644
--- a/syntax_checkers/ruby/jruby.vim
+++ b/syntax_checkers/ruby/jruby.vim
@@ -19,17 +19,8 @@ let s:save_cpo = &cpo
set cpo&vim
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({
- \ 'exe': exe,
- \ 'args': args,
+ \ 'args': (syntastic#util#isRunningWindows() ? '-T1' : ''),
\ 'args_after': '-W1 -c' })
let errorformat =
@@ -41,9 +32,12 @@ function! SyntaxCheckers_ruby_jruby_GetLocList() dict
\ '%W%f:%l: %m,'.
\ '%-C%.%#'
+ let env = syntastic#util#isRunningWindows() ? {} : { 'RUBYOPT': '' }
+
return SyntasticMake({
\ 'makeprg': makeprg,
- \ 'errorformat': errorformat })
+ \ 'errorformat': errorformat,
+ \ 'env': env })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
diff --git a/syntax_checkers/ruby/macruby.vim b/syntax_checkers/ruby/macruby.vim
index d66595c..54c8365 100644
--- a/syntax_checkers/ruby/macruby.vim
+++ b/syntax_checkers/ruby/macruby.vim
@@ -18,9 +18,7 @@ let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_ruby_macruby_GetLocList() dict
- let makeprg = self.makeprgBuild({
- \ 'exe': 'RUBYOPT= ' . self.getExecEscaped(),
- \ 'args_after': '-W1 -c' })
+ let makeprg = self.makeprgBuild({ 'args_after': '-W1 -c' })
let errorformat =
\ '%-GSyntax OK,'.
@@ -31,9 +29,12 @@ function! SyntaxCheckers_ruby_macruby_GetLocList() dict
\ '%W%f:%l: %m,'.
\ '%-C%.%#'
+ let env = { 'RUBYOPT': '' }
+
return SyntasticMake({
\ 'makeprg': makeprg,
- \ 'errorformat': errorformat })
+ \ 'errorformat': errorformat,
+ \ 'env': env })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
diff --git a/syntax_checkers/ruby/mri.vim b/syntax_checkers/ruby/mri.vim
index c0b0166..e55c493 100644
--- a/syntax_checkers/ruby/mri.vim
+++ b/syntax_checkers/ruby/mri.vim
@@ -18,28 +18,24 @@ let g:loaded_syntastic_ruby_mri_checker = 1
let s:save_cpo = &cpo
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)
if stridx(a:i['text'], 'assigned but unused variable') >= 0
let term = split(a:i['text'], ' - ')[1]
- return '\V\<'.term.'\>'
+ return '\V\<' . escape(term, '\') . '\>'
endif
return ''
endfunction
function! SyntaxCheckers_ruby_mri_GetLocList() dict
- if !exists('g:syntastic_ruby_exec')
- 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' })
+ let makeprg = self.makeprgBuild({ 'args_after': '-w -T1 -c' })
"this is a hack to filter out a repeated useless warning in rspec files
"containing lines like
@@ -64,9 +60,12 @@ function! SyntaxCheckers_ruby_mri_GetLocList() dict
\ '%W%f:%l: %m,'.
\ '%-C%.%#'
+ let env = syntastic#util#isRunningWindows() ? {} : { 'RUBYOPT': '' }
+
return SyntasticMake({
\ 'makeprg': makeprg,
- \ 'errorformat': errorformat })
+ \ 'errorformat': errorformat,
+ \ 'env': env })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
diff --git a/syntax_checkers/ruby/rubylint.vim b/syntax_checkers/ruby/rubylint.vim
index 02ed2f2..07f0d4f 100644
--- a/syntax_checkers/ruby/rubylint.vim
+++ b/syntax_checkers/ruby/rubylint.vim
@@ -20,7 +20,11 @@ let s:save_cpo = &cpo
set cpo&vim
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'
diff --git a/syntax_checkers/sass/sass.vim b/syntax_checkers/sass/sass.vim
index 353c1a9..a515fe5 100644
--- a/syntax_checkers/sass/sass.vim
+++ b/syntax_checkers/sass/sass.vim
@@ -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
"in a temp location otherwise sass puts .sass_cache dirs in the users project
let s:sass_cache_location = tempname()
+lockvar s:sass_cache_location
"By default do not check partials as unknown variables are a syntax error
if !exists("g:syntastic_sass_check_partials")
diff --git a/syntax_checkers/sass/sassc.vim b/syntax_checkers/sass/sassc.vim
new file mode 100644
index 0000000..731d178
--- /dev/null
+++ b/syntax_checkers/sass/sassc.vim
@@ -0,0 +1,38 @@
+"============================================================================
+"File: sassc.vim
+"Description: Syntax checking plugin for syntastic
+"Maintainer: LCD 47
+"License: This program is free software. It comes without any warranty,
+" to the extent permitted by applicable law. You can redistribute
+" it and/or modify it under the terms of the Do What The Fuck You
+" Want To Public License, Version 2, as published by Sam Hocevar.
+" See http://sam.zoy.org/wtfpl/COPYING for more details.
+"
+"============================================================================
+
+if exists("g:loaded_syntastic_sass_sassc_checker")
+ finish
+endif
+let g:loaded_syntastic_sass_sassc_checker = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+function! SyntaxCheckers_sass_sassc_GetLocList() dict
+ let makeprg = self.makeprgBuild({ 'fname_after': syntastic#util#DevNull() })
+
+ let errorformat = '%f:%l: %trror: %m'
+
+ return SyntasticMake({
+ \ 'makeprg': makeprg,
+ \ 'errorformat': errorformat })
+endfunction
+
+call g:SyntasticRegistry.CreateAndRegisterChecker({
+ \ 'filetype': 'sass',
+ \ 'name': 'sassc'})
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set et sts=4 sw=4:
diff --git a/syntax_checkers/scala/fsc.vim b/syntax_checkers/scala/fsc.vim
index 9291242..6f1fcf6 100644
--- a/syntax_checkers/scala/fsc.vim
+++ b/syntax_checkers/scala/fsc.vim
@@ -15,19 +15,16 @@ if exists('g:loaded_syntastic_scala_fsc_checker')
endif
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
set cpo&vim
function! SyntaxCheckers_scala_fsc_GetLocList() dict
+ call syntastic#log#deprecationWarn('scala_options', 'scala_fsc_args')
+
" fsc has some serious problems with the
" working directory changing after being started
" that's why we better pass an absolute path
let makeprg = self.makeprgBuild({
- \ 'args': g:syntastic_scala_options,
\ 'args_after': '-Ystop-after:parser',
\ 'fname': syntastic#util#shexpand('%:p') })
diff --git a/syntax_checkers/scala/scalac.vim b/syntax_checkers/scala/scalac.vim
index ea465f0..0d0c15a 100644
--- a/syntax_checkers/scala/scalac.vim
+++ b/syntax_checkers/scala/scalac.vim
@@ -15,17 +15,13 @@ if exists("g:loaded_syntastic_scala_scalac_checker")
endif
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
set cpo&vim
function! SyntaxCheckers_scala_scalac_GetLocList() dict
- let makeprg = self.makeprgBuild({
- \ 'args': g:syntastic_scala_options,
- \ 'args_after': '-Ystop-after:parser' })
+ call syntastic#log#deprecationWarn('scala_options', 'scala_scalac_args')
+
+ let makeprg = self.makeprgBuild({ 'args_after': '-Ystop-after:parser' })
let errorformat =
\ '%E%f:%l: %trror: %m,' .
diff --git a/syntax_checkers/scss/sass.vim b/syntax_checkers/scss/sass.vim
index 61bd6de..0f837ca 100644
--- a/syntax_checkers/scss/sass.vim
+++ b/syntax_checkers/scss/sass.vim
@@ -1,4 +1,3 @@
-
"============================================================================
"File: scss.vim
"Description: scss syntax checking plugin for syntastic
diff --git a/syntax_checkers/scss/sassc.vim b/syntax_checkers/scss/sassc.vim
new file mode 100644
index 0000000..75fdc2a
--- /dev/null
+++ b/syntax_checkers/scss/sassc.vim
@@ -0,0 +1,25 @@
+"============================================================================
+"File: sassc.vim
+"Description: Syntax checking plugin for syntastic
+"Maintainer: LCD 47
+"License: This program is free software. It comes without any warranty,
+" to the extent permitted by applicable law. You can redistribute
+" it and/or modify it under the terms of the Do What The Fuck You
+" Want To Public License, Version 2, as published by Sam Hocevar.
+" See http://sam.zoy.org/wtfpl/COPYING for more details.
+"
+"============================================================================
+
+if exists("g:loaded_syntastic_scss_sassc_checker")
+ finish
+endif
+let g:loaded_syntastic_scss_sassc_checker = 1
+
+runtime! syntax_checkers/sass/*.vim
+
+call g:SyntasticRegistry.CreateAndRegisterChecker({
+ \ 'filetype': 'scss',
+ \ 'name': 'sassc',
+ \ 'redirect': 'sass/sassc'})
+
+" vim: set et sts=4 sw=4:
diff --git a/syntax_checkers/sh/sh.vim b/syntax_checkers/sh/sh.vim
index 76182cd..d736f29 100644
--- a/syntax_checkers/sh/sh.vim
+++ b/syntax_checkers/sh/sh.vim
@@ -18,42 +18,6 @@ let g:loaded_syntastic_sh_sh_checker = 1
let s:save_cpo = &cpo
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.checkable('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
return s:IsShellValid()
endfunction
@@ -78,6 +42,42 @@ function! SyntaxCheckers_sh_sh_GetLocList() dict
\ 'errorformat': errorformat })
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(expand('$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({
\ 'filetype': 'sh',
\ 'name': 'sh' })
diff --git a/syntax_checkers/tex/chktex.vim b/syntax_checkers/tex/chktex.vim
index b55eaee..2339236 100644
--- a/syntax_checkers/tex/chktex.vim
+++ b/syntax_checkers/tex/chktex.vim
@@ -45,11 +45,14 @@ function! SyntaxCheckers_tex_chktex_GetLocList() dict
\ '%Z%p^,' .
\ '%-G%.%#'
- return SyntasticMake({
+ let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
- \ 'subtype': 'Style',
- \ 'postprocess': ['sort'] })
+ \ 'subtype': 'Style' })
+
+ call self.setWantSort(1)
+
+ return loclist
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
diff --git a/syntax_checkers/texinfo/makeinfo.vim b/syntax_checkers/texinfo/makeinfo.vim
index ccd3b2f..63cae93 100644
--- a/syntax_checkers/texinfo/makeinfo.vim
+++ b/syntax_checkers/texinfo/makeinfo.vim
@@ -20,7 +20,7 @@ set cpo&vim
function! SyntaxCheckers_texinfo_makeinfo_GetHighlightRegex(item)
let term = matchstr(a:item['text'], "\\m`\\zs[^']\\+\\ze'")
- return term != '' ? '\V' . term : ''
+ return term != '' ? '\V' . escape(term, '\') : ''
endfunction
function! SyntaxCheckers_texinfo_makeinfo_GetLocList() dict
diff --git a/syntax_checkers/text/atdtool.vim b/syntax_checkers/text/atdtool.vim
index 5a8ea0c..b0f32c1 100644
--- a/syntax_checkers/text/atdtool.vim
+++ b/syntax_checkers/text/atdtool.vim
@@ -22,7 +22,7 @@ function! SyntaxCheckers_text_atdtool_GetHighlightRegex(item)
let term = matchstr(a:item['text'], '\m "\zs[^"]\+\ze"\($\| | suggestions:\)')
if term != ''
let col = get(a:item, 'col', 0)
- let term = (col != 0 ? '\%' . col . 'c' : '') . '\V' . term
+ let term = (col != 0 ? '\%' . col . 'c' : '') . '\V' . escape(term, '\')
endif
return term
endfunction
diff --git a/syntax_checkers/typescript/tsc.vim b/syntax_checkers/typescript/tsc.vim
index 7f594e0..d2e7349 100644
--- a/syntax_checkers/typescript/tsc.vim
+++ b/syntax_checkers/typescript/tsc.vim
@@ -23,11 +23,14 @@ function! SyntaxCheckers_typescript_tsc_GetLocList() dict
\ '%Eerror %m,' .
\ '%C%\s%\+%m'
- return SyntasticMake({
+ let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
- \ 'defaults': {'bufnr': bufnr("")},
- \ 'postprocess': ['sort'] })
+ \ 'defaults': {'bufnr': bufnr("")} })
+
+ call self.setWantSort(1)
+
+ return loclist
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
diff --git a/syntax_checkers/typescript/tslint.vim b/syntax_checkers/typescript/tslint.vim
new file mode 100644
index 0000000..80ca881
--- /dev/null
+++ b/syntax_checkers/typescript/tslint.vim
@@ -0,0 +1,46 @@
+"============================================================================
+"File: typescript/tslint.vim
+"Description: TypeScript linter
+"Maintainer: Seon-Wook Park
+"============================================================================
+
+if exists("g:loaded_syntastic_typescript_tslint_checker")
+ finish
+endif
+let g:loaded_syntastic_typescript_tslint_checker = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+function! SyntaxCheckers_typescript_tslint_GetHighlightRegex(item)
+ let term = matchstr(a:item['text'], "\\m\\s'\\zs.\\{-}\\ze'\\s")
+ return term != '' ? '\V' . escape(term, '\') : ''
+endfunction
+
+function! SyntaxCheckers_typescript_tslint_GetLocList() dict
+ let makeprg = self.makeprgBuild({
+ \ 'args_after': '--format verbose',
+ \ 'fname_before': '-f' })
+
+ " (comment-format) ts/app.ts[12, 36]: comment must start with lowercase letter
+ let errorformat = '%f[%l\, %c]: %m'
+
+ let loclist = SyntasticMake({
+ \ 'makeprg': makeprg,
+ \ 'errorformat': errorformat,
+ \ 'preprocess': 'tslint',
+ \ 'returns': [0, 2] })
+
+ call self.setWantSort(1)
+
+ return loclist
+endfunction
+
+call g:SyntasticRegistry.CreateAndRegisterChecker({
+ \ 'filetype': 'typescript',
+ \ 'name': 'tslint'})
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set et sts=4 sw=4:
diff --git a/syntax_checkers/vala/valac.vim b/syntax_checkers/vala/valac.vim
index e6c1b88..912e298 100644
--- a/syntax_checkers/vala/valac.vim
+++ b/syntax_checkers/vala/valac.vim
@@ -37,7 +37,7 @@ set cpo&vim
function! SyntaxCheckers_vala_valac_GetHighlightRegex(pos)
let length = strlen(matchstr(a:pos['text'], '\m\^\+$'))
- return '\%>' . (a:pos['col'] - 1) . 'c.*\%<' . (a:pos['col'] + length + 1) . 'c'
+ return '\%>' . (a:pos['col'] - 1) . 'c\%<' . (a:pos['col'] + length) . 'c'
endfunction
function! s:GetValaModules()
diff --git a/syntax_checkers/vhdl/ghdl.vim b/syntax_checkers/vhdl/ghdl.vim
index f101d37..ff02224 100644
--- a/syntax_checkers/vhdl/ghdl.vim
+++ b/syntax_checkers/vhdl/ghdl.vim
@@ -19,7 +19,7 @@ let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_vhdl_ghdl_GetLocList() dict
- let makeprg = self.makeprgBuild({ 'args_after': '-s' })
+ let makeprg = self.makeprgBuild({ 'args_before': '-s' })
let errorformat = '%f:%l:%c: %m'
diff --git a/syntax_checkers/vim/vimlint.vim b/syntax_checkers/vim/vimlint.vim
index 552e129..7122de1 100644
--- a/syntax_checkers/vim/vimlint.vim
+++ b/syntax_checkers/vim/vimlint.vim
@@ -29,21 +29,16 @@ function! SyntaxCheckers_vim_vimlint_GetHighlightRegex(item)
endif
endif
- return '\V' . (col ? '\%' . col . 'c' : '') . term
+ return col ? '\%>' . (col - 1) . 'c\%<' . (col + strlen(term)) . 'c' : '\V' . escape(term, '\')
endif
return ''
endfunction
function! SyntaxCheckers_vim_vimlint_IsAvailable() dict
- let ret = 0
- try
- call vimlint#vimlint(syntastic#util#DevNull(), { 'output': [], 'quiet': 1 })
- let ret = 1
- catch /^Vim\%((\a\+)\)\=:E117/
- " do nothing
- endtry
- return ret
+ return
+ \ globpath(&runtimepath, 'autoload/vimlparser.vim') != '' &&
+ \ globpath(&runtimepath, 'autoload/vimlint.vim') != ''
endfunction
function! SyntaxCheckers_vim_vimlint_GetLocList() dict
@@ -58,7 +53,7 @@ function! SyntaxCheckers_vim_vimlint_GetLocList() dict
" value 3: the message is a warning
"
" References: :help vimlint-errorcode and :help vimlint-variables
- return vimlint#vimlint(expand('%'), {
+ let param = {
\ 'output': function('s:vimlintOutput'),
\ 'quiet': 1,
\ 'EVL102': 3,
@@ -68,7 +63,16 @@ function! SyntaxCheckers_vim_vimlint_GetLocList() dict
\ 'EVL106': 3,
\ 'EVL201': 3,
\ 'EVL204': 3,
- \ 'EVL205': 3 })
+ \ 'EVL205': 3 }
+
+ if exists('g:syntastic_vimlint_options')
+ if type(g:syntastic_vimlint_options) == type({})
+ let options = filter(copy(g:syntastic_vimlint_options), 'v:key =~# "\\m^EVL"')
+ call extend(param, options, 'force')
+ endif
+ endif
+
+ return vimlint#vimlint(expand('%'), param)
endfunction
" @vimlint(EVL103, 1, a:filename)
@@ -86,7 +90,8 @@ endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'vim',
- \ 'name': 'vimlint'})
+ \ 'name': 'vimlint',
+ \ 'exec': 'vim' })
let &cpo = s:save_cpo
unlet s:save_cpo
diff --git a/syntax_checkers/xhtml/tidy.vim b/syntax_checkers/xhtml/tidy.vim
index 6fa14b3..a3e2d47 100644
--- a/syntax_checkers/xhtml/tidy.vim
+++ b/syntax_checkers/xhtml/tidy.vim
@@ -30,19 +30,19 @@ set cpo&vim
" TODO: join this with html.vim DRY's sake?
function! s:TidyEncOptByFenc()
let tidy_opts = {
- \'utf-8': '-utf8',
- \'ascii': '-ascii',
- \'latin1': '-latin1',
- \'iso-2022-jp': '-iso-2022',
- \'cp1252': '-win1252',
- \'macroman': '-mac',
- \'utf-16le': '-utf16le',
- \'utf-16': '-utf16',
- \'big5': '-big5',
- \'cp932': '-shiftjis',
- \'sjis': '-shiftjis',
- \'cp850': '-ibm858',
- \}
+ \ 'utf-8': '-utf8',
+ \ 'ascii': '-ascii',
+ \ 'latin1': '-latin1',
+ \ 'iso-2022-jp': '-iso-2022',
+ \ 'cp1252': '-win1252',
+ \ 'macroman': '-mac',
+ \ 'utf-16le': '-utf16le',
+ \ 'utf-16': '-utf16',
+ \ 'big5': '-big5',
+ \ 'cp932': '-shiftjis',
+ \ 'sjis': '-shiftjis',
+ \ 'cp850': '-ibm858',
+ \ }
return get(tidy_opts, &fileencoding, '-utf8')
endfunction
diff --git a/syntax_checkers/rust/rustc.vim b/syntax_checkers/xml/plutil.vim
similarity index 58%
rename from syntax_checkers/rust/rustc.vim
rename to syntax_checkers/xml/plutil.vim
index 97ef66a..a9ad145 100644
--- a/syntax_checkers/rust/rustc.vim
+++ b/syntax_checkers/xml/plutil.vim
@@ -1,7 +1,7 @@
"============================================================================
-"File: rust.vim
+"File: plutil.vim
"Description: Syntax checking plugin for syntastic.vim
-"Maintainer: Chad Jablonski
+"Maintainer: LCD 47
"License: This program is free software. It comes without any warranty,
" to the extent permitted by applicable law. You can redistribute
" it and/or modify it under the terms of the Do What The Fuck You
@@ -10,31 +10,31 @@
"
"============================================================================
-if exists("g:loaded_syntastic_rust_rustc_checker")
+if exists("g:loaded_syntastic_xml_plutil_checker")
finish
endif
-let g:loaded_syntastic_rust_rustc_checker = 1
+let g:loaded_syntastic_xml_plutil_checker = 1
let s:save_cpo = &cpo
set cpo&vim
-function! SyntaxCheckers_rust_rustc_GetLocList() dict
- let makeprg = self.makeprgBuild({ 'args_after': '--no-trans' })
+function! SyntaxCheckers_xml_plutil_GetLocList() dict
+ let makeprg = self.makeprgBuild({
+ \ 'args_before': '-lint -s',
+ \ 'fname_before': '--' })
- let errorformat =
- \ '%E%f:%l:%c: %\d%#:%\d%# %.%\{-}error:%.%\{-} %m,' .
- \ '%W%f:%l:%c: %\d%#:%\d%# %.%\{-}warning:%.%\{-} %m,' .
- \ '%C%f:%l %m,' .
- \ '%-Z%.%#'
+ let errorformat =
+ \ '%E%f: %m at line %l'
return SyntasticMake({
\ 'makeprg': makeprg,
- \ 'errorformat': errorformat })
+ \ 'errorformat': errorformat,
+ \ 'returns': [0, 1] })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
- \ 'filetype': 'rust',
- \ 'name': 'rustc'})
+ \ 'filetype': 'xml',
+ \ 'name': 'plutil'})
let &cpo = s:save_cpo
unlet s:save_cpo
diff --git a/syntax_checkers/yaml/yamlxs.vim b/syntax_checkers/yaml/yamlxs.vim
index e9d3377..6c12a62 100644
--- a/syntax_checkers/yaml/yamlxs.vim
+++ b/syntax_checkers/yaml/yamlxs.vim
@@ -24,19 +24,18 @@ let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_yaml_yamlxs_IsAvailable() dict
- if !exists('g:syntastic_perl_interpreter')
- let g:syntastic_perl_interpreter = self.getExec()
+ if !exists('g:syntastic_yaml_yamlxs_exec') && exists('g:syntastic_perl_interpreter')
+ let g:syntastic_yaml_yamlxs_exec = g:syntastic_perl_interpreter
endif
" don't call executable() here, to allow things like
" let g:syntastic_perl_interpreter='/usr/bin/env perl'
- silent! call system(s:Exe() . ' ' . s:Modules() . ' -e ' . syntastic#util#shescape('exit(0)'))
+ silent! call system(self.getExecEscaped() . ' ' . s:Modules() . ' -e ' . syntastic#util#shescape('exit(0)'))
return v:shell_error == 0
endfunction
function! SyntaxCheckers_yaml_yamlxs_GetLocList() dict
let makeprg = self.makeprgBuild({
- \ 'exe': s:Exe(),
\ 'args_before': s:Modules() . ' -e ' . syntastic#util#shescape('YAML::XS::LoadFile($ARGV[0])') })
let errorformat =
@@ -53,13 +52,9 @@ function! SyntaxCheckers_yaml_yamlxs_GetLocList() dict
\ 'defaults': {'bufnr': bufnr("")} })
endfunction
-function! s:Exe()
- return syntastic#util#shexpand(g:syntastic_perl_interpreter)
-endfunction
-
function s:Modules()
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, ',')
else
let includes = copy(syntastic#util#var('perl_lib_path'))
diff --git a/syntax_checkers/z80/z80syntaxchecker.vim b/syntax_checkers/z80/z80syntaxchecker.vim
index bbf3e48..6a3998a 100644
--- a/syntax_checkers/z80/z80syntaxchecker.vim
+++ b/syntax_checkers/z80/z80syntaxchecker.vim
@@ -14,7 +14,7 @@
" - Install this python package:
" https://github.com/rgiot/pycpcdemotools
" - Copy/paste this script in your search path:
-" https://raw.github.com/rgiot/pycpcdemotools/master/cpcdemotools/source_checker/z80_syntax_checker.py
+" https://raw.githubusercontent.com/rgiot/pycpcdemotools/master/cpcdemotools/source_checker/z80_syntax_checker.py
if exists("g:loaded_syntastic_z80_z80syntaxchecker_checker")
finish