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

Merge branch 'master' of github.com:amix/vimrc

This commit is contained in:
Chris Sprague 2016-01-14 15:38:39 -05:00
commit d9000c9221
265 changed files with 9642 additions and 3308 deletions

View file

@ -5,7 +5,7 @@ if exists('g:ack_use_dispatch')
endif endif
else else
let g:ack_use_dispatch = 0 let g:ack_use_dispatch = 0
end endif
"----------------------------------------------------------------------------- "-----------------------------------------------------------------------------
" Public API " Public API

View file

@ -21,13 +21,13 @@ Vim has various ways of installing plugins, the standard way is in [the document
cd ~/.vim/bundle && git clone https://github.com/rking/ag.vim ag && echo "set runtimepath^=~/.vim/bundle/ag" >> ~/.vimrc cd ~/.vim/bundle && git clone https://github.com/rking/ag.vim ag && echo "set runtimepath^=~/.vim/bundle/ag" >> ~/.vimrc
``` ```
Then open vim and rum `:helptags ~/.vim/bundle/ag/doc`. Then open vim and run `:helptags ~/.vim/bundle/ag/doc`.
### Configuration ### ### Configuration ###
You can specify a custom ag name and path in your .vimrc like so: You can specify a custom ag name and path in your .vimrc like so:
let g:agprg="<custom-ag-path-goes-here> --vimgrep" let g:ag_prg="<custom-ag-path-goes-here> --vimgrep"
You can configure ag.vim to always start searching from your project root You can configure ag.vim to always start searching from your project root
instead of the cwd instead of the cwd

View file

@ -1,17 +1,26 @@
" NOTE: You must, of course, install ag / the_silver_searcher " NOTE: You must, of course, install ag / the_silver_searcher
" FIXME: Delete deprecated options below on or after 15-7 (6 months from when they were changed) {{{ " FIXME: Delete deprecated options below on or after 2016-4 (6 months from when the deprecation warning was added) {{{
if exists("g:agprg") if exists("g:agprg")
let g:ag_prg = g:agprg let g:ag_prg = g:agprg
echohl WarningMsg
call input('g:agprg is deprecated and will be removed. Please use g:ag_prg')
echohl None
endif endif
if exists("g:aghighlight") if exists("g:aghighlight")
let g:ag_highlight = g:aghighlight let g:ag_highlight = g:aghighlight
echohl WarningMsg
call input('g:aghighlight is deprecated and will be removed. Please use g:ag_highlight')
echohl None
endif endif
if exists("g:agformat") if exists("g:agformat")
let g:ag_format = g:agformat let g:ag_format = g:agformat
echohl WarningMsg
call input('g:agformat is deprecated and will be removed. Please use g:ag_format')
echohl None
endif endif
" }}} FIXME: Delete the deprecated options above on or after 15-7 (6 months from when they were changed) " }}} FIXME: Delete the deprecated options above on or after 15-7 (6 months from when they were changed)
@ -79,6 +88,11 @@ function! ag#Ag(cmd, args)
let l:grepargs = a:args . join(a:000, ' ') let l:grepargs = a:args . join(a:000, ' ')
end end
if empty(l:grepargs)
echo "Usage: ':Ag {pattern}' (or just :Ag to search for the word under the cursor). See ':help :Ag' for more information."
return
endif
" Format, used to manage column jump " Format, used to manage column jump
if a:cmd =~# '-g$' if a:cmd =~# '-g$'
let s:ag_format_backup=g:ag_format let s:ag_format_backup=g:ag_format
@ -169,8 +183,12 @@ function! ag#Ag(cmd, args)
echom "ag.vim keys: q=quit <cr>/e/t/h/v=enter/edit/tab/split/vsplit go/T/H/gv=preview versions of same" echom "ag.vim keys: q=quit <cr>/e/t/h/v=enter/edit/tab/split/vsplit go/T/H/gv=preview versions of same"
endif endif
endif endif
else else " Close the split window automatically:
cclose
lclose
echohl WarningMsg
echom 'No matches for "'.a:args.'"' echom 'No matches for "'.a:args.'"'
echohl None
endif endif
endfunction endfunction

View file

@ -1,3 +1,6 @@
#**This project is unmaintained**
**You should use [this fork](https://github.com/ctrlpvim/ctrlp.vim) instead.**
# ctrlp.vim # ctrlp.vim
Full path fuzzy __file__, __buffer__, __mru__, __tag__, __...__ finder for Vim. Full path fuzzy __file__, __buffer__, __mru__, __tag__, __...__ finder for Vim.

View file

@ -269,7 +269,9 @@ function! s:goyo_on(dim)
if exists('g:goyo_callbacks[0]') if exists('g:goyo_callbacks[0]')
call g:goyo_callbacks[0]() call g:goyo_callbacks[0]()
endif endif
silent! doautocmd User GoyoEnter if exists('#User#GoyoEnter')
doautocmd User GoyoEnter
endif
endfunction endfunction
function! s:goyo_off() function! s:goyo_off()
@ -344,6 +346,9 @@ function! s:goyo_off()
if goyo_disabled_airline && !exists("#airline") if goyo_disabled_airline && !exists("#airline")
AirlineToggle AirlineToggle
" For some reason, Airline requires two refreshes to avoid display
" artifacts
silent! AirlineRefresh
silent! AirlineRefresh silent! AirlineRefresh
endif endif
@ -363,7 +368,9 @@ function! s:goyo_off()
if exists('g:goyo_callbacks[1]') if exists('g:goyo_callbacks[1]')
call g:goyo_callbacks[1]() call g:goyo_callbacks[1]()
endif endif
silent! doautocmd User GoyoLeave if exists('#User#GoyoLeave')
doautocmd User GoyoLeave
endif
endfunction endfunction
function! s:relsz(expr, limit) function! s:relsz(expr, limit)
@ -414,6 +421,10 @@ function! goyo#execute(bang, dim)
if exists('#goyo') == 0 if exists('#goyo') == 0
call s:goyo_on(a:dim) call s:goyo_on(a:dim)
elseif !empty(a:dim) elseif !empty(a:dim)
if winnr('$') < 5
call s:goyo_off()
return goyo#execute(a:bang, a:dim)
endif
let dim = s:parse_arg(a:dim) let dim = s:parse_arg(a:dim)
if !empty(dim) if !empty(dim)
let t:goyo_dim = dim let t:goyo_dim = dim

View file

@ -0,0 +1,153 @@
Next
- Rename "primary" and "secondary" trees to "tab" and "window" trees.
- Move a bunch of buffer level variables into the NERDTree and UI classes.
- Display cascading dirs on one line to save vertical/horizontal space (@matt-gardner: brainstorming/testing)
- Remove the old style UI - Remove 'NERDTreeDirArrows' option.
- On windows default to + and ~ for expand/collapse directory symbols.
- Lots more refactoring. Move a bunch of b: level vars into b:NERDTree and friends.
5.0.0
- Refactor the code significantly:
* Break the classes out into their own files.
* Make the majority of the code OO - previously large parts were
effectively a tangle of "global" methods.
- Add an API to assign flags to nodes. This allows VCS plugins like
https://github.com/Xuyuanp/nerdtree-git-plugin to exist. Thanks to
Xuyuanp for helping design/test/build said API.
- add 'scope' argument to the key map API see :help NERDTreeAddKeyMap()
- add magic [[dir]] and [[file]] flags to NERDTreeIgnore
- add support for custom path filters. See :help NERDTreeAddPathFilter()
- add path listener API. See :help NERDTreePathListenerAPI.
- expand the fs menu functionality to list file properties (PhilRunninger,
apbarrero, JESii)
- make bookmarks work with `~` home shortcuts (hiberabyss)
- show OSX specific fsmenu options in regular vim on mac (evindor)
- make dir arrow icons configurable (PickRelated)
- optimise node sorting performance when opening large dirs (vtsang)
- make the root note render prettier by truncating it at a path slash (gcmt)
- remove NERDChristmasTree option - its always christmas now
- add "cascade" open and closing for dirs containing only another single
dir. See :help NERDTreeCascadeOpenSingleChildDir (pendulm)
Many other fixes, doc updates and contributions from:
actionshrimp
SchDen
egalpin
cperl82 - many small fixes
toiffel
WoLpH
handcraftedbits
devmanhinton
xiaodili
zhangoose
gastropoda
mixvin
alvan
lucascaton
kelaban
shanesmith
staeff
pendulm
stephenprater
franksort
agrussellknives
AndrewRadev
Twinside
4.2.0
- Add NERDTreeDirArrows option to make the UI use pretty arrow chars
instead of the old +~| chars to define the tree structure (sickill)
- shift the syntax highlighting out into its own syntax file (gnap)
- add some mac specific options to the filesystem menu - for macvim
only (andersonfreitas)
- Add NERDTreeMinimalUI option to remove some non functional parts of the
nerdtree ui (camthompson)
- tweak the behaviour of :NERDTreeFind - see :help :NERDTreeFind for the
new behaviour (benjamingeiger)
- if no name is given to :Bookmark, make it default to the name of the
target file/dir (minyoung)
- use 'file' completion when doing copying, create, and move
operations (EvanDotPro)
- lots of misc bug fixes (paddyoloughlin, sdewald, camthompson, Vitaly
Bogdanov, AndrewRadev, mathias, scottstvnsn, kml, wycats, me RAWR!)
4.1.0
features:
- NERDTreeFind to reveal the node for the current buffer in the tree,
see |NERDTreeFind|. This effectively merges the FindInNERDTree plugin (by
Doug McInnes) into the script.
- make NERDTreeQuitOnOpen apply to the t/T keymaps too. Thanks to Stefan
Ritter and Rémi Prévost.
- truncate the root node if wider than the tree window. Thanks to Victor
Gonzalez.
bugfixes:
- really fix window state restoring
- fix some win32 path escaping issues. Thanks to Stephan Baumeister, Ricky,
jfilip1024, and Chris Chambers
4.0.0
- add a new programmable menu system (see :help NERDTreeMenu).
- add new APIs to add menus/menu-items to the menu system as well as
custom key mappings to the NERD tree buffer (see :help NERDTreeAPI).
- removed the old API functions
- added a mapping to maximize/restore the size of nerd tree window, thanks
to Guillaume Duranceau for the patch. See :help NERDTree-A for details.
- fix a bug where secondary nerd trees (netrw hijacked trees) and
NERDTreeQuitOnOpen didnt play nicely, thanks to Curtis Harvey.
- fix a bug where the script ignored directories whose name ended in a dot,
thanks to Aggelos Orfanakos for the patch.
- fix a bug when using the x mapping on the tree root, thanks to Bryan
Venteicher for the patch.
- fix a bug where the cursor position/window size of the nerd tree buffer
wasnt being stored on closing the window, thanks to Richard Hart.
- fix a bug where NERDTreeMirror would mirror the wrong tree
3.1.1
- fix a bug where a non-listed no-name buffer was getting created every
time the tree windows was created, thanks to Derek Wyatt and owen1
- make <CR> behave the same as the 'o' mapping
- some helptag fixes in the doc, thanks strull
- fix a bug when using :set nohidden and opening a file where the previous
buf was modified. Thanks iElectric
- other minor fixes
3.1.0
New features:
- add mappings to open files in a vsplit, see :help NERDTree-s and :help
NERDTree-gs
- make the statusline for the nerd tree window default to something
hopefully more useful. See :help 'NERDTreeStatusline'
Bugfixes:
- make the hijack netrw functionality work when vim is started with "vim
<some dir>" (thanks to Alf Mikula for the patch).
- fix a bug where the CWD wasnt being changed for some operations even when
NERDTreeChDirMode==2 (thanks to Lucas S. Buchala)
- add -bar to all the nerd tree :commands so they can chain with other
:commands (thanks to tpope)
- fix bugs when ignorecase was set (thanks to nach)
- fix a bug with the relative path code (thanks to nach)
- fix a bug where doing a :cd would cause :NERDTreeToggle to fail (thanks nach)
3.0.1
Bugfixes:
- fix bugs with :NERDTreeToggle and :NERDTreeMirror when 'hidden
was not set
- fix a bug where :NERDTree <path> would fail if <path> was relative and
didnt start with a ./ or ../ Thanks to James Kanze.
- make the q mapping work with secondary (:e <dir> style) trees,
thanks to jamessan
- fix a bunch of small bugs with secondary trees
More insane refactoring.
3.0.0
- hijack netrw so that doing an :edit <directory> will put a NERD tree in
the window rather than a netrw browser. See :help 'NERDTreeHijackNetrw'
- allow sharing of trees across tabs, see :help :NERDTreeMirror
- remove "top" and "bottom" as valid settings for NERDTreeWinPos
- change the '<tab>' mapping to 'i'
- change the 'H' mapping to 'I'
- lots of refactoring

View file

@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

View file

@ -55,7 +55,7 @@ The following features and functionality are provided by the NERD tree:
Installation Installation
------------ ------------
[pathogen.vim](https://github.com/tpope/vim-pathogen) is the recommended way to install nerdtree. ####[pathogen.vim](https://github.com/tpope/vim-pathogen)
cd ~/.vim/bundle cd ~/.vim/bundle
git clone https://github.com/scrooloose/nerdtree.git git clone https://github.com/scrooloose/nerdtree.git
@ -63,6 +63,12 @@ Installation
Then reload vim, run `:Helptags`, and check out `:help NERD_tree.txt`. Then reload vim, run `:Helptags`, and check out `:help NERD_tree.txt`.
####[apt-vim](https://github.com/egalpin/apt-vim)
apt-vim install -y https://github.com/scrooloose/nerdtree.git
Faq Faq
--- ---
@ -85,11 +91,13 @@ Stick this in your vimrc: `autocmd vimenter * NERDTree`
> How can I open a NERDTree automatically when vim starts up if no files were specified? > How can I open a NERDTree automatically when vim starts up if no files were specified?
Stick this in your vimrc Stick this in your vimrc:
autocmd StdinReadPre * let s:std_in=1 autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
Note: Now start vim with plain `vim`, not `vim .`
> How can I map a specific key or shortcut to open NERDTree? > How can I map a specific key or shortcut to open NERDTree?
Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever key you want): Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever key you want):
@ -100,8 +108,15 @@ Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever ke
Stick this in your vimrc: Stick this in your vimrc:
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
> Can I have different highlighting for different file extensions? > Can I have different highlighting for different file extensions?
See here: https://github.com/scrooloose/nerdtree/issues/433#issuecomment-92590696 See here: https://github.com/scrooloose/nerdtree/issues/433#issuecomment-92590696
> How can I change default arrows?
Use these variables in your vimrc. Note that below are default arrow symbols
let g:NERDTreeDirArrowExpandable = '▸'
let g:NERDTreeDirArrowCollapsible = '▾'

View file

@ -4,17 +4,17 @@ endif
let g:loaded_nerdtree_autoload = 1 let g:loaded_nerdtree_autoload = 1
function! nerdtree#version() function! nerdtree#version()
return '4.2.0' return '5.0.0'
endfunction endfunction
" SECTION: General Functions {{{1 " SECTION: General Functions {{{1
"============================================================ "============================================================
"FUNCTION: nerdtree#checkForBrowse(dir) {{{2 "FUNCTION: nerdtree#checkForBrowse(dir) {{{2
"inits a secondary nerd tree in the current buffer if appropriate "inits a window tree in the current buffer if appropriate
function! nerdtree#checkForBrowse(dir) function! nerdtree#checkForBrowse(dir)
if a:dir != '' && isdirectory(a:dir) if a:dir != '' && isdirectory(a:dir)
call g:NERDTreeCreator.CreateSecondary(a:dir) call g:NERDTreeCreator.CreateWindowTree(a:dir)
endif endif
endfunction endfunction
@ -94,7 +94,7 @@ endfunction
" FUNCTION: nerdtree#postSourceActions() {{{2 " FUNCTION: nerdtree#postSourceActions() {{{2
function! nerdtree#postSourceActions() function! nerdtree#postSourceActions()
call g:NERDTreeBookmark.CacheBookmarks(0) call g:NERDTreeBookmark.CacheBookmarks(1)
call nerdtree#ui_glue#createDefaultBindings() call nerdtree#ui_glue#createDefaultBindings()
"load all nerdtree plugins "load all nerdtree plugins

View file

@ -105,7 +105,7 @@ endfunction
"FUNCTION: s:activateBookmark() {{{1 "FUNCTION: s:activateBookmark() {{{1
"handle the user activating a bookmark "handle the user activating a bookmark
function! s:activateBookmark(bm) function! s:activateBookmark(bm)
call a:bm.activate(!a:bm.path.isDirectory ? {'where': 'p'} : {}) call a:bm.activate(b:NERDTree, !a:bm.path.isDirectory ? {'where': 'p'} : {})
endfunction endfunction
" FUNCTION: nerdtree#ui_glue#bookmarkNode(name) {{{1 " FUNCTION: nerdtree#ui_glue#bookmarkNode(name) {{{1
@ -140,9 +140,7 @@ endfunction
" FUNCTION: s:chRoot(node) {{{1 " FUNCTION: s:chRoot(node) {{{1
" changes the current root to the selected one " changes the current root to the selected one
function! s:chRoot(node) function! s:chRoot(node)
call a:node.makeRoot() call b:NERDTree.changeRoot(a:node)
call b:NERDTree.render()
call b:NERDTreeRoot.putCursorHere(0, 0)
endfunction endfunction
" FUNCTION: s:nerdtree#ui_glue#chRootCwd() {{{1 " FUNCTION: s:nerdtree#ui_glue#chRootCwd() {{{1
@ -157,7 +155,7 @@ function! nerdtree#ui_glue#chRootCwd()
if cwd.str() == g:NERDTreeFileNode.GetRootForTab().path.str() if cwd.str() == g:NERDTreeFileNode.GetRootForTab().path.str()
return return
endif endif
call s:chRoot(g:NERDTreeDirNode.New(cwd)) call s:chRoot(g:NERDTreeDirNode.New(cwd, b:NERDTree))
endfunction endfunction
" FUNCTION: nnerdtree#ui_glue#clearBookmarks(bookmarks) {{{1 " FUNCTION: nnerdtree#ui_glue#clearBookmarks(bookmarks) {{{1
@ -173,6 +171,7 @@ function! nerdtree#ui_glue#clearBookmarks(bookmarks)
call bookmark.delete() call bookmark.delete()
endfor endfor
endif endif
call b:NERDTree.root.refresh()
call b:NERDTree.render() call b:NERDTree.render()
endfunction endfunction
@ -208,8 +207,8 @@ endfunction
" FUNCTION: s:closeTreeWindow() {{{1 " FUNCTION: s:closeTreeWindow() {{{1
" close the tree window " close the tree window
function! s:closeTreeWindow() function! s:closeTreeWindow()
if b:NERDTreeType ==# "secondary" && b:NERDTreePreviousBuf != -1 if b:NERDTree.isWinTree() && b:NERDTree.previousBuf() != -1
exec "buffer " . b:NERDTreePreviousBuf exec "buffer " . b:NERDTree.previousBuf()
else else
if winnr("$") > 1 if winnr("$") > 1
call g:NERDTree.Close() call g:NERDTree.Close()
@ -227,6 +226,7 @@ function! s:deleteBookmark(bm)
if nr2char(getchar()) ==# 'y' if nr2char(getchar()) ==# 'y'
try try
call a:bm.delete() call a:bm.delete()
call b:NERDTree.root.refresh()
call b:NERDTree.render() call b:NERDTree.render()
redraw redraw
catch /^NERDTree/ catch /^NERDTree/
@ -241,7 +241,7 @@ endfunction
" FUNCTION: s:displayHelp() {{{1 " FUNCTION: s:displayHelp() {{{1
" toggles the help display " toggles the help display
function! s:displayHelp() function! s:displayHelp()
let b:treeShowHelp = b:treeShowHelp ? 0 : 1 call b:NERDTree.ui.toggleHelp()
call b:NERDTree.render() call b:NERDTree.render()
call b:NERDTree.ui.centerView() call b:NERDTree.ui.centerView()
endfunction endfunction
@ -269,27 +269,29 @@ function! s:findAndRevealPath()
endtry endtry
if p.isUnder(cwd) if p.isUnder(cwd)
call g:NERDTreeCreator.CreatePrimary(cwd.str()) call g:NERDTreeCreator.CreateTabTree(cwd.str())
else else
call g:NERDTreeCreator.CreatePrimary(p.getParent().str()) call g:NERDTreeCreator.CreateTabTree(p.getParent().str())
endif endif
else else
if !p.isUnder(g:NERDTreeFileNode.GetRootForTab().path) if !p.isUnder(g:NERDTreeFileNode.GetRootForTab().path)
if !g:NERDTree.IsOpen() if !g:NERDTree.IsOpen()
call g:NERDTreeCreator.TogglePrimary('') call g:NERDTreeCreator.ToggleTabTree('')
else else
call g:NERDTree.CursorToTreeWin() call g:NERDTree.CursorToTreeWin()
endif endif
let b:NERDTreeShowHidden = g:NERDTreeShowHidden call b:NERDTree.setShowHidden(g:NERDTreeShowHidden)
call s:chRoot(g:NERDTreeDirNode.New(p.getParent())) call s:chRoot(g:NERDTreeDirNode.New(p.getParent(), b:NERDTree))
else else
if !g:NERDTree.IsOpen() if !g:NERDTree.IsOpen()
call g:NERDTreeCreator.TogglePrimary("") call g:NERDTreeCreator.ToggleTabTree("")
endif endif
endif endif
endif endif
call g:NERDTree.CursorToTreeWin() call g:NERDTree.CursorToTreeWin()
call b:NERDTreeRoot.reveal(p) let node = b:NERDTree.root.reveal(p)
call b:NERDTree.render()
call node.putCursorHere(1,0)
if p.isUnixHiddenFile() if p.isUnixHiddenFile()
let g:NERDTreeShowHidden = showhidden let g:NERDTreeShowHidden = showhidden
@ -312,7 +314,7 @@ function! s:handleLeftClick()
endfor endfor
if currentNode.path.isDirectory if currentNode.path.isDirectory
if startToCur =~# g:NERDTreeUI.MarkupReg() && startToCur =~# '[+~▾▸] \?$' if startToCur =~# g:NERDTreeUI.MarkupReg() && startToCur =~# '[+~'.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.'] \?$'
call currentNode.activate() call currentNode.activate()
return return
endif endif
@ -409,7 +411,7 @@ endfunction
" FUNCTION: s:jumpToRoot() {{{1 " FUNCTION: s:jumpToRoot() {{{1
" moves the cursor to the root node " moves the cursor to the root node
function! s:jumpToRoot() function! s:jumpToRoot()
call b:NERDTreeRoot.putCursorHere(1, 0) call b:NERDTree.root.putCursorHere(1, 0)
call b:NERDTree.ui.centerView() call b:NERDTree.ui.centerView()
endfunction endfunction
@ -442,13 +444,13 @@ endfunction
" put the cursor on the given bookmark and, if its a file, open it " put the cursor on the given bookmark and, if its a file, open it
function! nerdtree#ui_glue#openBookmark(name) function! nerdtree#ui_glue#openBookmark(name)
try try
let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0) let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0, b:NERDTree)
call targetNode.putCursorHere(0, 1) call targetNode.putCursorHere(0, 1)
redraw! redraw!
catch /^NERDTree.BookmarkedNodeNotFoundError/ catch /^NERDTree.BookmarkedNodeNotFoundError/
call nerdtree#echo("note - target node is not cached") call nerdtree#echo("note - target node is not cached")
let bookmark = g:NERDTreeBookmark.BookmarkFor(a:name) let bookmark = g:NERDTreeBookmark.BookmarkFor(a:name)
let targetNode = g:NERDTreeFileNode.New(bookmark.path) let targetNode = g:NERDTreeFileNode.New(bookmark.path, b:NERDTree)
endtry endtry
if targetNode.path.isDirectory if targetNode.path.isDirectory
call targetNode.openExplorer() call targetNode.openExplorer()
@ -510,7 +512,7 @@ endfunction
" put the cursor on the node associate with the given name " put the cursor on the node associate with the given name
function! nerdtree#ui_glue#revealBookmark(name) function! nerdtree#ui_glue#revealBookmark(name)
try try
let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0) let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0, b:NERDTree)
call targetNode.putCursorHere(0, 1) call targetNode.putCursorHere(0, 1)
catch /^NERDTree.BookmarkNotFoundError/ catch /^NERDTree.BookmarkNotFoundError/
call nerdtree#echo("Bookmark isnt cached under the current root") call nerdtree#echo("Bookmark isnt cached under the current root")
@ -522,7 +524,7 @@ endfunction
" will be reloaded. " will be reloaded.
function! s:refreshRoot() function! s:refreshRoot()
call nerdtree#echo("Refreshing the root node. This could take a while...") call nerdtree#echo("Refreshing the root node. This could take a while...")
call b:NERDTreeRoot.refresh() call b:NERDTree.root.refresh()
call b:NERDTree.render() call b:NERDTree.render()
redraw redraw
call nerdtree#echo("Refreshing the root node. This could take a while... DONE") call nerdtree#echo("Refreshing the root node. This could take a while... DONE")
@ -545,10 +547,10 @@ endfunction
" FUNCTION: nerdtree#ui_glue#setupCommands() {{{1 " FUNCTION: nerdtree#ui_glue#setupCommands() {{{1
function! nerdtree#ui_glue#setupCommands() function! nerdtree#ui_glue#setupCommands()
command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreatePrimary('<args>') command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreateTabTree('<args>')
command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.TogglePrimary('<args>') command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.ToggleTabTree('<args>')
command! -n=0 -bar NERDTreeClose :call g:NERDTree.Close() command! -n=0 -bar NERDTreeClose :call g:NERDTree.Close()
command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreatePrimary('<args>') command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreateTabTree('<args>')
command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror() command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror()
command! -n=0 -bar NERDTreeFind call s:findAndRevealPath() command! -n=0 -bar NERDTreeFind call s:findAndRevealPath()
command! -n=0 -bar NERDTreeFocus call NERDTreeFocus() command! -n=0 -bar NERDTreeFocus call NERDTreeFocus()
@ -602,28 +604,28 @@ endfunction
"keepState: 1 if the current root should be left open when the tree is "keepState: 1 if the current root should be left open when the tree is
"re-rendered "re-rendered
function! nerdtree#ui_glue#upDir(keepState) function! nerdtree#ui_glue#upDir(keepState)
let cwd = b:NERDTreeRoot.path.str({'format': 'UI'}) let cwd = b:NERDTree.root.path.str({'format': 'UI'})
if cwd ==# "/" || cwd =~# '^[^/]..$' if cwd ==# "/" || cwd =~# '^[^/]..$'
call nerdtree#echo("already at top dir") call nerdtree#echo("already at top dir")
else else
if !a:keepState if !a:keepState
call b:NERDTreeRoot.close() call b:NERDTree.root.close()
endif endif
let oldRoot = b:NERDTreeRoot let oldRoot = b:NERDTree.root
if empty(b:NERDTreeRoot.parent) if empty(b:NERDTree.root.parent)
let path = b:NERDTreeRoot.path.getParent() let path = b:NERDTree.root.path.getParent()
let newRoot = g:NERDTreeDirNode.New(path) let newRoot = g:NERDTreeDirNode.New(path, b:NERDTree)
call newRoot.open() call newRoot.open()
call newRoot.transplantChild(b:NERDTreeRoot) call newRoot.transplantChild(b:NERDTree.root)
let b:NERDTreeRoot = newRoot let b:NERDTree.root = newRoot
else else
let b:NERDTreeRoot = b:NERDTreeRoot.parent let b:NERDTree.root = b:NERDTree.root.parent
endif endif
if g:NERDTreeChDirMode ==# 2 if g:NERDTreeChDirMode ==# 2
call b:NERDTreeRoot.path.changeToDir() call b:NERDTree.root.path.changeToDir()
endif endif
call b:NERDTree.render() call b:NERDTree.render()

View file

@ -37,9 +37,7 @@ CONTENTS *NERDTree-contents*
4.3.Menu API..........................|NERDTreeAddPathFilter()| 4.3.Menu API..........................|NERDTreeAddPathFilter()|
4.4.Path Listener API.................|NERDTreePathListenerAPI| 4.4.Path Listener API.................|NERDTreePathListenerAPI|
5.About...................................|NERDTreeAbout| 5.About...................................|NERDTreeAbout|
6.Changelog...............................|NERDTreeChangelog| 6.License.................................|NERDTreeLicense|
7.Credits.................................|NERDTreeCredits|
8.License.................................|NERDTreeLicense|
============================================================================== ==============================================================================
1. Intro *NERDTree* 1. Intro *NERDTree*
@ -673,9 +671,6 @@ NERD tree. These options should be set in your vimrc.
|'NERDTreeMinimalUI'| Disables display of the 'Bookmarks' label and |'NERDTreeMinimalUI'| Disables display of the 'Bookmarks' label and
'Press ? for help' text. 'Press ? for help' text.
|'NERDTreeDirArrows'| Tells the NERD tree to use arrows instead of
+ ~ chars when displaying directories.
|'NERDTreeCascadeOpenSingleChildDir'| |'NERDTreeCascadeOpenSingleChildDir'|
Cascade open while selected directory has only Cascade open while selected directory has only
one child that also is a directory. one child that also is a directory.
@ -778,13 +773,13 @@ Default: 1.
If set to 1, doing a > If set to 1, doing a >
:edit <some directory> :edit <some directory>
< <
will open up a "secondary" NERD tree instead of a netrw in the target window. will open up a window level NERD tree instead of a netrw in the target window.
Secondary NERD trees behaves slightly different from a regular trees in the Window level trees behaves slightly different from a regular trees in the
following respects: following respects:
1. 'o' will open the selected file in the same window as the tree, 1. 'o' will open the selected file in the same window as the tree,
replacing it. replacing it.
2. you can have as many secondary tree as you want in the same tab. 2. you can have one tree per window - instead of per tab.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*'NERDTreeIgnore'* *'NERDTreeIgnore'*
@ -947,7 +942,7 @@ Other examples: >
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*'NERDTreeStatusline'* *'NERDTreeStatusline'*
Values: Any valid statusline setting. Values: Any valid statusline setting.
Default: %{b:NERDTreeRoot.path.strForOS(0)} Default: %{b:NERDTree.root.path.strForOS(0)}
Tells the script what to use as the |'statusline'| setting for NERD tree Tells the script what to use as the |'statusline'| setting for NERD tree
windows. windows.
@ -988,19 +983,6 @@ of the following lines to set this option: >
let NERDTreeMinimalUI=1 let NERDTreeMinimalUI=1
< <
------------------------------------------------------------------------------
*'NERDTreeDirArrows'*
Values: 0 or 1
Default: 0.
This option is used to change the default look of directory nodes displayed in
the tree. When set to 0 it shows old-school bars (|), + and ~ chars. If set to
1 it shows right and down arrows. Use one of the follow lines to set this
option: >
let NERDTreeDirArrows=0
let NERDTreeDirArrows=1
<
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*'NERDTreeCascadeOpenSingleChildDir'* *'NERDTreeCascadeOpenSingleChildDir'*
Values: 0 or 1 Values: 0 or 1
@ -1205,7 +1187,7 @@ Use this API if you want to run a callback for events on Path objects. E.G >
"This function will be called whenever a Path object is created. "This function will be called whenever a Path object is created.
"a:event is an object that contains a bunch of relevant info - "a:event is an object that contains a bunch of relevant info -
"including the path in question. See lib/event.vim for details. "including the path in question. See lib/nerdtree/event.vim for details.
endfunction endfunction
< <
Current events supported: Current events supported:
@ -1235,187 +1217,8 @@ The latest stable versions can be found at
The latest dev versions are on github The latest dev versions are on github
http://github.com/scrooloose/nerdtree http://github.com/scrooloose/nerdtree
============================================================================== ==============================================================================
6. Changelog *NERDTreeChangelog* 6. License *NERDTreeLicense*
Next
- add 'scope' argument to the key map API
- add NERDTreeCustomIgnoreFilter hook - needs doc
- add magic [[dir]] and [[file]] flags to NERDTreeIgnore
- add support for custom path filters. See :help NERDTreeAddPathFilter()
- add path listener API. See :help NERDTreePathListenerAPI.
4.2.0
- Add NERDTreeDirArrows option to make the UI use pretty arrow chars
instead of the old +~| chars to define the tree structure (sickill)
- shift the syntax highlighting out into its own syntax file (gnap)
- add some mac specific options to the filesystem menu - for macvim
only (andersonfreitas)
- Add NERDTreeMinimalUI option to remove some non functional parts of the
nerdtree ui (camthompson)
- tweak the behaviour of :NERDTreeFind - see :help :NERDTreeFind for the
new behaviour (benjamingeiger)
- if no name is given to :Bookmark, make it default to the name of the
target file/dir (minyoung)
- use 'file' completion when doing copying, create, and move
operations (EvanDotPro)
- lots of misc bug fixes (paddyoloughlin, sdewald, camthompson, Vitaly
Bogdanov, AndrewRadev, mathias, scottstvnsn, kml, wycats, me RAWR!)
4.1.0
features:
- NERDTreeFind to reveal the node for the current buffer in the tree,
see |NERDTreeFind|. This effectively merges the FindInNERDTree plugin (by
Doug McInnes) into the script.
- make NERDTreeQuitOnOpen apply to the t/T keymaps too. Thanks to Stefan
Ritter and Rémi Prévost.
- truncate the root node if wider than the tree window. Thanks to Victor
Gonzalez.
bugfixes:
- really fix window state restoring
- fix some win32 path escaping issues. Thanks to Stephan Baumeister, Ricky,
jfilip1024, and Chris Chambers
4.0.0
- add a new programmable menu system (see :help NERDTreeMenu).
- add new APIs to add menus/menu-items to the menu system as well as
custom key mappings to the NERD tree buffer (see :help NERDTreeAPI).
- removed the old API functions
- added a mapping to maximize/restore the size of nerd tree window, thanks
to Guillaume Duranceau for the patch. See :help NERDTree-A for details.
- fix a bug where secondary nerd trees (netrw hijacked trees) and
NERDTreeQuitOnOpen didnt play nicely, thanks to Curtis Harvey.
- fix a bug where the script ignored directories whose name ended in a dot,
thanks to Aggelos Orfanakos for the patch.
- fix a bug when using the x mapping on the tree root, thanks to Bryan
Venteicher for the patch.
- fix a bug where the cursor position/window size of the nerd tree buffer
wasnt being stored on closing the window, thanks to Richard Hart.
- fix a bug where NERDTreeMirror would mirror the wrong tree
3.1.1
- fix a bug where a non-listed no-name buffer was getting created every
time the tree windows was created, thanks to Derek Wyatt and owen1
- make <CR> behave the same as the 'o' mapping
- some helptag fixes in the doc, thanks strull
- fix a bug when using :set nohidden and opening a file where the previous
buf was modified. Thanks iElectric
- other minor fixes
3.1.0
New features:
- add mappings to open files in a vsplit, see :help NERDTree-s and :help
NERDTree-gs
- make the statusline for the nerd tree window default to something
hopefully more useful. See :help 'NERDTreeStatusline'
Bugfixes:
- make the hijack netrw functionality work when vim is started with "vim
<some dir>" (thanks to Alf Mikula for the patch).
- fix a bug where the CWD wasnt being changed for some operations even when
NERDTreeChDirMode==2 (thanks to Lucas S. Buchala)
- add -bar to all the nerd tree :commands so they can chain with other
:commands (thanks to tpope)
- fix bugs when ignorecase was set (thanks to nach)
- fix a bug with the relative path code (thanks to nach)
- fix a bug where doing a :cd would cause :NERDTreeToggle to fail (thanks nach)
3.0.1
Bugfixes:
- fix bugs with :NERDTreeToggle and :NERDTreeMirror when 'hidden
was not set
- fix a bug where :NERDTree <path> would fail if <path> was relative and
didnt start with a ./ or ../ Thanks to James Kanze.
- make the q mapping work with secondary (:e <dir> style) trees,
thanks to jamessan
- fix a bunch of small bugs with secondary trees
More insane refactoring.
3.0.0
- hijack netrw so that doing an :edit <directory> will put a NERD tree in
the window rather than a netrw browser. See :help 'NERDTreeHijackNetrw'
- allow sharing of trees across tabs, see :help :NERDTreeMirror
- remove "top" and "bottom" as valid settings for NERDTreeWinPos
- change the '<tab>' mapping to 'i'
- change the 'H' mapping to 'I'
- lots of refactoring
==============================================================================
7. Credits *NERDTreeCredits*
Thanks to the following people for testing, bug reports, ideas etc. Without
you I probably would have got bored of the hacking the NERD tree and
just downloaded pr0n instead.
Tim Carey-Smith (halorgium)
Vigil
Nick Brettell
Thomas Scott Urban
Terrance Cohen
Yegappan Lakshmanan
Jason Mills
Michael Geddes (frogonwheels)
Yu Jun
Michael Madsen
AOYAMA Shotaro
Zhang Weiwu
Niels Aan de Brugh
Olivier Yiptong
Zhang Shuhan
Cory Echols
Piotr Czachur
Yuan Jiang
Matan Nassau
Maxim Kim
Charlton Wang
Matt Wozniski (godlygeek)
knekk
Sean Chou
Ryan Penn
Simon Peter Nicholls
Michael Foobar
Tomasz Chomiuk
Denis Pokataev
Tim Pope (tpope)
James Kanze
James Vega (jamessan)
Frederic Chanal (nach)
Alf Mikula
Lucas S. Buchala
Curtis Harvey
Guillaume Duranceau
Richard Hart (hates)
Doug McInnes
Stefan Ritter
Rémi Prévost
Victor Gonzalez
Stephan Baumeister
Ricky
jfilip1024
Chris Chambers
Vitaly Bogdanov
Patrick O'Loughlin (paddyoloughlin)
Cam Thompson (camthompson)
Marcin Kulik (sickill)
Steve DeWald (sdewald)
Ivan Necas (iNecas)
George Ang (gnap)
Evan Coury (EvanDotPro)
Andrew Radev (AndrewRadev)
Matt Gauger (mathias)
Scott Stevenson (scottstvnsn)
Anderson Freitas (andersonfreitas)
Kamil K. Lemański (kml)
Yehuda Katz (wycats)
Min-Young Wu (minyoung)
Benjamin Geiger (benjamingeiger)
==============================================================================
8. License *NERDTreeLicense*
The NERD tree is released under the wtfpl. The NERD tree is released under the wtfpl.
See http://sam.zoy.org/wtfpl/COPYING. See http://sam.zoy.org/wtfpl/COPYING.

View file

@ -3,9 +3,9 @@
let s:Bookmark = {} let s:Bookmark = {}
let g:NERDTreeBookmark = s:Bookmark let g:NERDTreeBookmark = s:Bookmark
" FUNCTION: Bookmark.activate() {{{1 " FUNCTION: Bookmark.activate(nerdtree) {{{1
function! s:Bookmark.activate(...) function! s:Bookmark.activate(nerdtree, ...)
call self.open(a:0 ? a:1 : {}) call self.open(a:nerdtree, a:0 ? a:1 : {})
endfunction endfunction
" FUNCTION: Bookmark.AddBookmark(name, path) {{{1 " FUNCTION: Bookmark.AddBookmark(name, path) {{{1
@ -87,6 +87,7 @@ function! s:Bookmark.CacheBookmarks(silent)
let name = substitute(i, '^\(.\{-}\) .*$', '\1', '') let name = substitute(i, '^\(.\{-}\) .*$', '\1', '')
let path = substitute(i, '^.\{-} \(.*\)$', '\1', '') let path = substitute(i, '^.\{-} \(.*\)$', '\1', '')
let path = fnamemodify(path, ':p')
try try
let bookmark = s:Bookmark.New(name, g:NERDTreePath.New(path)) let bookmark = s:Bookmark.New(name, g:NERDTreePath.New(path))
@ -127,26 +128,18 @@ endfunction
" Delete this bookmark. If the node for this bookmark is under the current " Delete this bookmark. If the node for this bookmark is under the current
" root, then recache bookmarks for its Path object " root, then recache bookmarks for its Path object
function! s:Bookmark.delete() function! s:Bookmark.delete()
let node = {}
try
let node = self.getNode(1)
catch /^NERDTree.BookmarkedNodeNotFoundError/
endtry
call remove(s:Bookmark.Bookmarks(), index(s:Bookmark.Bookmarks(), self)) call remove(s:Bookmark.Bookmarks(), index(s:Bookmark.Bookmarks(), self))
if !empty(node)
call node.path.cacheDisplayString()
endif
call s:Bookmark.Write() call s:Bookmark.Write()
endfunction endfunction
" FUNCTION: Bookmark.getNode(searchFromAbsoluteRoot) {{{1 " FUNCTION: Bookmark.getNode(nerdtree, searchFromAbsoluteRoot) {{{1
" Gets the treenode for this bookmark " Gets the treenode for this bookmark
" "
" Args: " Args:
" searchFromAbsoluteRoot: specifies whether we should search from the current " searchFromAbsoluteRoot: specifies whether we should search from the current
" tree root, or the highest cached node " tree root, or the highest cached node
function! s:Bookmark.getNode(searchFromAbsoluteRoot) function! s:Bookmark.getNode(nerdtree, searchFromAbsoluteRoot)
let searchRoot = a:searchFromAbsoluteRoot ? g:NERDTreeDirNode.AbsoluteTreeRoot() : b:NERDTreeRoot let searchRoot = a:searchFromAbsoluteRoot ? a:nerdtree.root.AbsoluteTreeRoot() : a:nerdtree.root
let targetNode = searchRoot.findNode(self.path) let targetNode = searchRoot.findNode(self.path)
if empty(targetNode) if empty(targetNode)
throw "NERDTree.BookmarkedNodeNotFoundError: no node was found for bookmark: " . self.name throw "NERDTree.BookmarkedNodeNotFoundError: no node was found for bookmark: " . self.name
@ -154,12 +147,12 @@ function! s:Bookmark.getNode(searchFromAbsoluteRoot)
return targetNode return targetNode
endfunction endfunction
" FUNCTION: Bookmark.GetNodeForName(name, searchFromAbsoluteRoot) {{{1 " FUNCTION: Bookmark.GetNodeForName(name, searchFromAbsoluteRoot, nerdtree) {{{1
" Class method that finds the bookmark with the given name and returns the " Class method that finds the bookmark with the given name and returns the
" treenode for it. " treenode for it.
function! s:Bookmark.GetNodeForName(name, searchFromAbsoluteRoot) function! s:Bookmark.GetNodeForName(name, searchFromAbsoluteRoot, nerdtree)
let bookmark = s:Bookmark.BookmarkFor(a:name) let bookmark = s:Bookmark.BookmarkFor(a:name)
return bookmark.getNode(a:searchFromAbsoluteRoot) return bookmark.getNode(nerdtree, a:searchFromAbsoluteRoot)
endfunction endfunction
" FUNCTION: Bookmark.GetSelected() {{{1 " FUNCTION: Bookmark.GetSelected() {{{1
@ -209,8 +202,11 @@ function! s:Bookmark.New(name, path)
return newBookmark return newBookmark
endfunction endfunction
" FUNCTION: Bookmark.open([options]) {{{1 " FUNCTION: Bookmark.open(nerdtree, [options]) {{{1
"Args: "Args:
"
"nerdtree: the tree to load open the bookmark in
"
"A dictionary containing the following keys (all optional): "A dictionary containing the following keys (all optional):
" 'where': Specifies whether the node should be opened in new split/tab or in " 'where': Specifies whether the node should be opened in new split/tab or in
" the previous window. Can be either 'v' (vertical split), 'h' " the previous window. Can be either 'v' (vertical split), 'h'
@ -219,11 +215,11 @@ endfunction
" 'keepopen': dont close the tree window " 'keepopen': dont close the tree window
" 'stay': open the file, but keep the cursor in the tree win " 'stay': open the file, but keep the cursor in the tree win
" "
function! s:Bookmark.open(...) function! s:Bookmark.open(nerdtree, ...)
let opts = a:0 ? a:1 : {} let opts = a:0 ? a:1 : {}
if self.path.isDirectory && !has_key(opts, 'where') if self.path.isDirectory && !has_key(opts, 'where')
call self.toRoot() call self.toRoot(a:nerdtree)
else else
let opener = g:NERDTreeOpener.New(self.path, opts) let opener = g:NERDTreeOpener.New(self.path, opts)
call opener.open(self) call opener.open(self)
@ -265,26 +261,24 @@ function! s:Bookmark.str()
return '>' . self.name . ' ' . pathStr return '>' . self.name . ' ' . pathStr
endfunction endfunction
" FUNCTION: Bookmark.toRoot() {{{1 " FUNCTION: Bookmark.toRoot(nerdtree) {{{1
" Make the node for this bookmark the new tree root " Make the node for this bookmark the new tree root
function! s:Bookmark.toRoot() function! s:Bookmark.toRoot(nerdtree)
if self.validate() if self.validate()
try try
let targetNode = self.getNode(1) let targetNode = self.getNode(a:nerdtree, 1)
catch /^NERDTree.BookmarkedNodeNotFoundError/ catch /^NERDTree.BookmarkedNodeNotFoundError/
let targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path) let targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path, a:nerdtree)
endtry endtry
call targetNode.makeRoot() call a:nerdtree.changeRoot(targetNode)
call b:NERDTree.render()
call targetNode.putCursorHere(0, 0)
endif endif
endfunction endfunction
" FUNCTION: Bookmark.ToRoot(name) {{{1 " FUNCTION: Bookmark.ToRoot(name, nerdtree) {{{1
" Make the node for this bookmark the new tree root " Make the node for this bookmark the new tree root
function! s:Bookmark.ToRoot(name) function! s:Bookmark.ToRoot(name, nerdtree)
let bookmark = s:Bookmark.BookmarkFor(a:name) let bookmark = s:Bookmark.BookmarkFor(a:name)
call bookmark.toRoot() call bookmark.toRoot(a:nerdtree)
endfunction endfunction
" FUNCTION: Bookmark.validate() {{{1 " FUNCTION: Bookmark.validate() {{{1
@ -293,7 +287,6 @@ function! s:Bookmark.validate()
return 1 return 1
else else
call s:Bookmark.CacheBookmarks(1) call s:Bookmark.CacheBookmarks(1)
call b:NERDTree.render()
call nerdtree#echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.") call nerdtree#echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.")
return 0 return 0
endif endif
@ -304,7 +297,7 @@ endfunction
function! s:Bookmark.Write() function! s:Bookmark.Write()
let bookmarkStrings = [] let bookmarkStrings = []
for i in s:Bookmark.Bookmarks() for i in s:Bookmark.Bookmarks()
call add(bookmarkStrings, i.name . ' ' . i.path.str()) call add(bookmarkStrings, i.name . ' ' . fnamemodify(i.path.str(), ':~'))
endfor endfor
"add a blank line before the invalid ones "add a blank line before the invalid ones

View file

@ -1,5 +1,5 @@
"CLASS: Creator "CLASS: Creator
"Creates primary/secondary/mirror nerdtree windows. Sets up all the window and "Creates tab/window/mirror nerdtree windows. Sets up all the window and
"buffer options and key mappings etc. "buffer options and key mappings etc.
"============================================================ "============================================================
let s:Creator = {} let s:Creator = {}
@ -16,7 +16,7 @@ function! s:Creator._bindMappings()
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#ui_glue#revealBookmark('<args>') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#ui_glue#revealBookmark('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#ui_glue#openBookmark('<args>') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#ui_glue#openBookmark('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#ui_glue#clearBookmarks('<args>') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#ui_glue#clearBookmarks('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=+ BookmarkToRoot call g:NERDTreeBookmark.ToRoot('<args>') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=+ BookmarkToRoot call g:NERDTreeBookmark.ToRoot('<args>', b:NERDTree)
command! -buffer -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() <bar> call b:NERDTree.render() command! -buffer -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() <bar> call b:NERDTree.render()
command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) <bar> call b:NERDTree.render() command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) <bar> call b:NERDTree.render()
command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write() command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write()
@ -32,22 +32,26 @@ function! s:Creator.BufNamePrefix()
return 'NERD_tree_' return 'NERD_tree_'
endfunction endfunction
"FUNCTION: s:Creator.CreatePrimary(a:name) {{{1 "FUNCTION: s:Creator.CreateTabTree(a:name) {{{1
function! s:Creator.CreatePrimary(name) function! s:Creator.CreateTabTree(name)
let creator = s:Creator.New() let creator = s:Creator.New()
call creator.createPrimary(a:name) call creator.createTabTree(a:name)
endfunction endfunction
"FUNCTION: s:Creator.createPrimary(a:name) {{{1 "FUNCTION: s:Creator.createTabTree(a:name) {{{1
"name: the name of a bookmark or a directory "name: the name of a bookmark or a directory
function! s:Creator.createPrimary(name) function! s:Creator.createTabTree(name)
let path = self._pathForString(a:name) let path = self._pathForString(a:name)
"abort if exception was thrown (bookmark/dir doesn't exist) "abort if exception was thrown (bookmark/dir doesn't exist)
if empty(path) if empty(path)
return return
endif endif
if path == {}
return
endif
"if instructed to, then change the vim CWD to the dir the NERDTree is "if instructed to, then change the vim CWD to the dir the NERDTree is
"inited in "inited in
if g:NERDTreeChDirMode != 0 if g:NERDTreeChDirMode != 0
@ -58,32 +62,26 @@ function! s:Creator.createPrimary(name)
if g:NERDTree.IsOpen() if g:NERDTree.IsOpen()
call g:NERDTree.Close() call g:NERDTree.Close()
endif endif
unlet t:NERDTreeBufName
call self._removeTreeBufForTab()
endif endif
call self._createTreeWin() call self._createTreeWin()
call self._createNERDTree(path) call self._createNERDTree(path, "tab")
let b:NERDTreeType = "primary"
let b:treeShowHelp = 0
let b:NERDTreeIgnoreEnabled = 1
let b:NERDTreeShowFiles = g:NERDTreeShowFiles
let b:NERDTreeShowHidden = g:NERDTreeShowHidden
let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks
call b:NERDTree.render() call b:NERDTree.render()
call b:NERDTreeRoot.putCursorHere(0, 0) call b:NERDTree.root.putCursorHere(0, 0)
call self._broadcastInitEvent() call self._broadcastInitEvent()
endfunction endfunction
"FUNCTION: s:Creator.CreateSecondary(dir) {{{1 "FUNCTION: s:Creator.CreateWindowTree(dir) {{{1
function! s:Creator.CreateSecondary(dir) function! s:Creator.CreateWindowTree(dir)
let creator = s:Creator.New() let creator = s:Creator.New()
call creator.createSecondary(a:dir) call creator.createWindowTree(a:dir)
endfunction endfunction
"FUNCTION: s:Creator.createSecondary(dir) {{{1 "FUNCTION: s:Creator.createWindowTree(dir) {{{1
function! s:Creator.createSecondary(dir) function! s:Creator.createWindowTree(dir)
try try
let path = g:NERDTreePath.New(a:dir) let path = g:NERDTreePath.New(a:dir)
catch /^NERDTree.InvalidArgumentsError/ catch /^NERDTree.InvalidArgumentsError/
@ -96,14 +94,13 @@ function! s:Creator.createSecondary(dir)
let previousBuf = expand("#") let previousBuf = expand("#")
"we need a unique name for each secondary tree buffer to ensure they are "we need a unique name for each window tree buffer to ensure they are
"all independent "all independent
exec "silent edit " . self._nextBufferName() exec "silent edit " . self._nextBufferName()
let b:NERDTreePreviousBuf = bufnr(previousBuf) call self._createNERDTree(path, "window")
call self._createNERDTree(path) let b:NERDTree._previousBuf = bufnr(previousBuf)
call self._setCommonBufOptions() call self._setCommonBufOptions()
let b:NERDTreeType = "secondary"
call b:NERDTree.render() call b:NERDTree.render()
@ -111,8 +108,8 @@ function! s:Creator.createSecondary(dir)
endfunction endfunction
" FUNCTION: s:Creator._createNERDTree(path) {{{1 " FUNCTION: s:Creator._createNERDTree(path) {{{1
function! s:Creator._createNERDTree(path) function! s:Creator._createNERDTree(path, type)
let b:NERDTree = g:NERDTree.New(a:path) let b:NERDTree = g:NERDTree.New(a:path, a:type)
"TODO: This is kept for compatability only since many things use "TODO: This is kept for compatability only since many things use
"b:NERDTreeRoot instead of the new NERDTree.root "b:NERDTreeRoot instead of the new NERDTree.root
"Remove this one day "Remove this one day
@ -145,7 +142,7 @@ function! s:Creator.createMirror()
let i = 0 let i = 0
while i < len(treeBufNames) while i < len(treeBufNames)
let bufName = treeBufNames[i] let bufName = treeBufNames[i]
let treeRoot = getbufvar(bufName, "NERDTreeRoot") let treeRoot = getbufvar(bufName, "NERDTree").root
let options[i+1 . '. ' . treeRoot.path.str() . ' (buf name: ' . bufName . ')'] = bufName let options[i+1 . '. ' . treeRoot.path.str() . ' (buf name: ' . bufName . ')'] = bufName
let i = i + 1 let i = i + 1
endwhile endwhile
@ -201,6 +198,15 @@ function! s:Creator._createTreeWin()
call self._setCommonBufOptions() call self._setCommonBufOptions()
endfunction endfunction
"FUNCTION: s:Creator._isBufHidden(nr) {{{1
function! s:Creator._isBufHidden(nr)
redir => bufs
silent ls!
redir END
return bufs =~ a:nr . '..h'
endfunction
"FUNCTION: s:Creator.New() {{{1 "FUNCTION: s:Creator.New() {{{1
function! s:Creator.New() function! s:Creator.New()
let newCreator = copy(self) let newCreator = copy(self)
@ -245,7 +251,7 @@ function! s:Creator._pathForString(str)
let path = g:NERDTreePath.New(dir) let path = g:NERDTreePath.New(dir)
catch /^NERDTree.InvalidArgumentsError/ catch /^NERDTree.InvalidArgumentsError/
call nerdtree#echo("No bookmark or directory found for: " . a:str) call nerdtree#echo("No bookmark or directory found for: " . a:str)
return return {}
endtry endtry
endif endif
if !path.isDirectory if !path.isDirectory
@ -255,6 +261,23 @@ function! s:Creator._pathForString(str)
return path return path
endfunction endfunction
" Function: s:Creator._removeTreeBufForTab() {{{1
function! s:Creator._removeTreeBufForTab()
let buf = bufnr(t:NERDTreeBufName)
"if &hidden is not set then it will already be gone
if buf != -1
"nerdtree buf may be mirrored/displayed elsewhere
if self._isBufHidden(buf)
exec "bwipeout " . buf
endif
endif
unlet t:NERDTreeBufName
endfunction
"FUNCTION: s:Creator._setCommonBufOptions() {{{1 "FUNCTION: s:Creator._setCommonBufOptions() {{{1
function! s:Creator._setCommonBufOptions() function! s:Creator._setCommonBufOptions()
"throwaway buffer options "throwaway buffer options
@ -283,12 +306,6 @@ function! s:Creator._setCommonBufOptions()
endif endif
call self._setupStatusline() call self._setupStatusline()
let b:treeShowHelp = 0
let b:NERDTreeIgnoreEnabled = 1
let b:NERDTreeShowFiles = g:NERDTreeShowFiles
let b:NERDTreeShowHidden = g:NERDTreeShowHidden
let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks
call self._bindMappings() call self._bindMappings()
setlocal filetype=nerdtree setlocal filetype=nerdtree
endfunction endfunction
@ -318,20 +335,20 @@ function! s:Creator._tabpagevar(tabnr, var)
return v return v
endfunction endfunction
"FUNCTION: s:Creator.TogglePrimary(dir) {{{1 "FUNCTION: s:Creator.ToggleTabTree(dir) {{{1
function! s:Creator.TogglePrimary(dir) function! s:Creator.ToggleTabTree(dir)
let creator = s:Creator.New() let creator = s:Creator.New()
call creator.togglePrimary(a:dir) call creator.toggleTabTree(a:dir)
endfunction endfunction
"FUNCTION: s:Creator.togglePrimary(dir) {{{1 "FUNCTION: s:Creator.toggleTabTree(dir) {{{1
"Toggles the NERD tree. I.e the NERD tree is open, it is closed, if it is "Toggles the NERD tree. I.e the NERD tree is open, it is closed, if it is
"closed it is restored or initialized (if it doesnt exist) "closed it is restored or initialized (if it doesnt exist)
" "
"Args: "Args:
"dir: the full path for the root node (is only used if the NERD tree is being "dir: the full path for the root node (is only used if the NERD tree is being
"initialized. "initialized.
function! s:Creator.togglePrimary(dir) function! s:Creator.toggleTabTree(dir)
if g:NERDTree.ExistsForTab() if g:NERDTree.ExistsForTab()
if !g:NERDTree.IsOpen() if !g:NERDTree.IsOpen()
call self._createTreeWin() call self._createTreeWin()
@ -343,7 +360,7 @@ function! s:Creator.togglePrimary(dir)
call g:NERDTree.Close() call g:NERDTree.Close()
endif endif
else else
call self.createPrimary(a:dir) call self.createTabTree(a:dir)
endif endif
endfunction endfunction

View file

@ -8,8 +8,30 @@ function! s:NERDTree.AddPathFilter(callback)
call add(s:NERDTree.PathFilters(), a:callback) call add(s:NERDTree.PathFilters(), a:callback)
endfunction endfunction
"FUNCTION: s:NERDTree.changeRoot(node) {{{1
function! s:NERDTree.changeRoot(node)
if a:node.path.isDirectory
let self.root = a:node
else
call a:node.cacheParent()
let self.root = a:node.parent
endif
call self.root.open()
"change dir to the dir of the new root if instructed to
if g:NERDTreeChDirMode ==# 2
exec "cd " . self.root.path.str({'format': 'Edit'})
endif
call self.render()
call self.root.putCursorHere(0, 0)
silent doautocmd User NERDTreeNewRoot
endfunction
"FUNCTION: s:NERDTree.Close() {{{1 "FUNCTION: s:NERDTree.Close() {{{1
"Closes the primary NERD tree window for this tab "Closes the tab tree window for this tab
function! s:NERDTree.Close() function! s:NERDTree.Close()
if !s:NERDTree.IsOpen() if !s:NERDTree.IsOpen()
return return
@ -43,7 +65,7 @@ endfunction
"FUNCTION: s:NERDTree.CursorToBookmarkTable(){{{1 "FUNCTION: s:NERDTree.CursorToBookmarkTable(){{{1
"Places the cursor at the top of the bookmarks table "Places the cursor at the top of the bookmarks table
function! s:NERDTree.CursorToBookmarkTable() function! s:NERDTree.CursorToBookmarkTable()
if !b:NERDTreeShowBookmarks if !b:NERDTree.ui.getShowBookmarks()
throw "NERDTree.IllegalOperationError: cant find bookmark table, bookmarks arent active" throw "NERDTree.IllegalOperationError: cant find bookmark table, bookmarks arent active"
endif endif
@ -73,13 +95,18 @@ endfunction
" Function: s:NERDTree.ExistsForBuffer() {{{1 " Function: s:NERDTree.ExistsForBuffer() {{{1
" Returns 1 if a nerd tree root exists in the current buffer " Returns 1 if a nerd tree root exists in the current buffer
function! s:NERDTree.ExistsForBuf() function! s:NERDTree.ExistsForBuf()
return exists("b:NERDTreeRoot") return exists("b:NERDTree")
endfunction endfunction
" Function: s:NERDTree.ExistsForTab() {{{1 " Function: s:NERDTree.ExistsForTab() {{{1
" Returns 1 if a nerd tree root exists in the current tab " Returns 1 if a nerd tree root exists in the current tab
function! s:NERDTree.ExistsForTab() function! s:NERDTree.ExistsForTab()
return exists("t:NERDTreeBufName") if !exists("t:NERDTreeBufName")
return
end
"check b:NERDTree is still there and hasn't been e.g. :bdeleted
return !empty(getbufvar(bufnr(t:NERDTreeBufName), 'NERDTree'))
endfunction endfunction
function! s:NERDTree.ForCurrentBuf() function! s:NERDTree.ForCurrentBuf()
@ -90,14 +117,29 @@ function! s:NERDTree.ForCurrentBuf()
endif endif
endfunction endfunction
"FUNCTION: s:NERDTree.ForCurrentTab() {{{1
function! s:NERDTree.ForCurrentTab()
if !s:NERDTree.ExistsForTab()
return
endif
let bufnr = bufnr(t:NERDTreeBufName)
return getbufvar(bufnr, "NERDTree")
endfunction
"FUNCTION: s:NERDTree.getRoot() {{{1
function! s:NERDTree.getRoot()
return self.root
endfunction
"FUNCTION: s:NERDTree.GetWinNum() {{{1 "FUNCTION: s:NERDTree.GetWinNum() {{{1
"gets the nerd tree window number for this tab "gets the nerd tree window number for this tab
function! s:NERDTree.GetWinNum() function! s:NERDTree.GetWinNum()
if exists("t:NERDTreeBufName") if exists("t:NERDTreeBufName")
return bufwinnr(t:NERDTreeBufName) return bufwinnr(t:NERDTreeBufName)
else
return -1
endif endif
return -1
endfunction endfunction
"FUNCTION: s:NERDTree.IsOpen() {{{1 "FUNCTION: s:NERDTree.IsOpen() {{{1
@ -105,6 +147,16 @@ function! s:NERDTree.IsOpen()
return s:NERDTree.GetWinNum() != -1 return s:NERDTree.GetWinNum() != -1
endfunction endfunction
"FUNCTION: s:NERDTree.isTabTree() {{{1
function! s:NERDTree.isTabTree()
return self._type == "tab"
endfunction
"FUNCTION: s:NERDTree.isWinTree() {{{1
function! s:NERDTree.isWinTree()
return self._type == "window"
endfunction
"FUNCTION: s:NERDTree.MustBeOpen() {{{1 "FUNCTION: s:NERDTree.MustBeOpen() {{{1
function! s:NERDTree.MustBeOpen() function! s:NERDTree.MustBeOpen()
if !s:NERDTree.IsOpen() if !s:NERDTree.IsOpen()
@ -113,11 +165,11 @@ function! s:NERDTree.MustBeOpen()
endfunction endfunction
"FUNCTION: s:NERDTree.New() {{{1 "FUNCTION: s:NERDTree.New() {{{1
function! s:NERDTree.New(path) function! s:NERDTree.New(path, type)
let newObj = copy(self) let newObj = copy(self)
let newObj.ui = g:NERDTreeUI.New(newObj) let newObj.ui = g:NERDTreeUI.New(newObj)
let newObj.root = g:NERDTreeDirNode.New(a:path) let newObj.root = g:NERDTreeDirNode.New(a:path, newObj)
let newObj._type = a:type
return newObj return newObj
endfunction endfunction
@ -129,6 +181,10 @@ function! s:NERDTree.PathFilters()
return s:NERDTree._PathFilters return s:NERDTree._PathFilters
endfunction endfunction
"FUNCTION: s:NERDTree.previousBuf() {{{1
function! s:NERDTree.previousBuf()
return self._previousBuf
endfunction
"FUNCTION: s:NERDTree.render() {{{1 "FUNCTION: s:NERDTree.render() {{{1
"A convenience function - since this is called often "A convenience function - since this is called often

View file

@ -11,8 +11,8 @@ function! s:Notifier.AddListener(event, funcname)
call add(listeners, a:funcname) call add(listeners, a:funcname)
endfunction endfunction
function! s:Notifier.NotifyListeners(event, path, params) function! s:Notifier.NotifyListeners(event, path, nerdtree, params)
let event = g:NERDTreeEvent.New(b:NERDTree, a:path, a:event, a:params) let event = g:NERDTreeEvent.New(a:nerdtree, a:path, a:event, a:params)
for listener in s:Notifier.GetListenersForEvent(a:event) for listener in s:Notifier.GetListenersForEvent(a:event)
call {listener}(event) call {listener}(event)

View file

@ -64,7 +64,7 @@ endfunction
"FUNCTION: Opener._gotoTargetWin() {{{1 "FUNCTION: Opener._gotoTargetWin() {{{1
function! s:Opener._gotoTargetWin() function! s:Opener._gotoTargetWin()
if b:NERDTreeType ==# "secondary" if b:NERDTree.isWinTree()
if self._where == 'v' if self._where == 'v'
vsplit vsplit
elseif self._where == 'h' elseif self._where == 'h'
@ -149,7 +149,7 @@ function! s:Opener.New(path, opts)
let newObj._keepopen = nerdtree#has_opt(a:opts, 'keepopen') let newObj._keepopen = nerdtree#has_opt(a:opts, 'keepopen')
let newObj._where = has_key(a:opts, 'where') ? a:opts['where'] : '' let newObj._where = has_key(a:opts, 'where') ? a:opts['where'] : ''
let newObj._treetype = b:NERDTreeType let newObj._nerdtree = b:NERDTree
call newObj._saveCursorPos() call newObj._saveCursorPos()
return newObj return newObj
@ -247,34 +247,25 @@ function! s:Opener._openFile()
endif endif
call self._gotoTargetWin() call self._gotoTargetWin()
call self._path.edit()
if self._treetype ==# "secondary" if self._stay
call self._path.edit() call self._restoreCursorPos()
else
call self._path.edit()
if self._stay
call self._restoreCursorPos()
endif
endif endif
endfunction endfunction
"FUNCTION: Opener._openDirectory(node) {{{1 "FUNCTION: Opener._openDirectory(node) {{{1
function! s:Opener._openDirectory(node) function! s:Opener._openDirectory(node)
if self._treetype ==# "secondary" if self._nerdtree.isWinTree()
call self._gotoTargetWin() call self._gotoTargetWin()
call g:NERDTreeCreator.CreateSecondary(a:node.path.str()) call g:NERDTreeCreator.CreateWindow(a:node.path.str())
else else
call self._gotoTargetWin() call self._gotoTargetWin()
if empty(self._where) if empty(self._where)
call a:node.makeRoot() call b:NERDTree.changeRoot(a:node)
call b:NERDTree.render()
call a:node.putCursorHere(0, 0)
elseif self._where == 't' elseif self._where == 't'
call g:NERDTreeCreator.CreatePrimary(a:node.path.str()) call g:NERDTreeCreator.CreateTabTree(a:node.path.str())
else else
call g:NERDTreeCreator.CreateSecondary(a:node.path.str()) call g:NERDTreeCreator.CreateWindowTree(a:node.path.str())
endif endif
endif endif

View file

@ -40,9 +40,7 @@ endfunction
"FUNCTION: Path.cacheDisplayString() {{{1 "FUNCTION: Path.cacheDisplayString() {{{1
function! s:Path.cacheDisplayString() abort function! s:Path.cacheDisplayString() abort
let self.cachedDisplayString = self.flagSet.renderToString() let self.cachedDisplayString = self.getLastPathComponent(1)
let self.cachedDisplayString .= self.getLastPathComponent(1)
if self.isExecutable if self.isExecutable
let self.cachedDisplayString = self.cachedDisplayString . '*' let self.cachedDisplayString = self.cachedDisplayString . '*'
@ -406,11 +404,11 @@ function! s:Path.isUnixHiddenPath()
endif endif
endfunction endfunction
"FUNCTION: Path.ignore() {{{1 "FUNCTION: Path.ignore(nerdtree) {{{1
"returns true if this path should be ignored "returns true if this path should be ignored
function! s:Path.ignore() function! s:Path.ignore(nerdtree)
"filter out the user specified paths to ignore "filter out the user specified paths to ignore
if b:NERDTreeIgnoreEnabled if a:nerdtree.ui.isIgnoreFilterEnabled()
for i in g:NERDTreeIgnore for i in g:NERDTreeIgnore
if self._ignorePatternMatches(i) if self._ignorePatternMatches(i)
return 1 return 1
@ -418,18 +416,18 @@ function! s:Path.ignore()
endfor endfor
for callback in g:NERDTree.PathFilters() for callback in g:NERDTree.PathFilters()
if {callback}({'path': self, 'nerdtree': b:NERDTree}) if {callback}({'path': self, 'nerdtree': a:nerdtree})
return 1 return 1
endif endif
endfor endfor
endif endif
"dont show hidden files unless instructed to "dont show hidden files unless instructed to
if b:NERDTreeShowHidden ==# 0 && self.isUnixHiddenFile() if !a:nerdtree.ui.getShowHidden() && self.isUnixHiddenFile()
return 1 return 1
endif endif
if b:NERDTreeShowFiles ==# 0 && self.isDirectory ==# 0 if a:nerdtree.ui.getShowFiles() ==# 0 && self.isDirectory ==# 0
return 1 return 1
endif endif
@ -455,10 +453,22 @@ function! s:Path._ignorePatternMatches(pattern)
return self.getLastPathComponent(0) =~# pat return self.getLastPathComponent(0) =~# pat
endfunction endfunction
"FUNCTION: Path.isUnder(path) {{{1 "FUNCTION: Path.isAncestor(path) {{{1
"return 1 if this path is somewhere under the given path in the filesystem. "return 1 if this path is somewhere above the given path in the filesystem.
" "
"a:path should be a dir "a:path should be a dir
function! s:Path.isAncestor(path)
if !self.isDirectory
return 0
endif
let this = self.str()
let that = a:path.str()
return stridx(that, this) == 0
endfunction
"FUNCTION: Path.isUnder(path) {{{1
"return 1 if this path is somewhere under the given path in the filesystem.
function! s:Path.isUnder(path) function! s:Path.isUnder(path)
if a:path.isDirectory == 0 if a:path.isDirectory == 0
return 0 return 0
@ -572,16 +582,16 @@ function! s:Path.readInfoFromDisk(fullpath)
endif endif
endfunction endfunction
"FUNCTION: Path.refresh() {{{1 "FUNCTION: Path.refresh(nerdtree) {{{1
function! s:Path.refresh() function! s:Path.refresh(nerdtree)
call self.readInfoFromDisk(self.str()) call self.readInfoFromDisk(self.str())
call g:NERDTreePathNotifier.NotifyListeners('refresh', self, {}) call g:NERDTreePathNotifier.NotifyListeners('refresh', self, a:nerdtree, {})
call self.cacheDisplayString() call self.cacheDisplayString()
endfunction endfunction
"FUNCTION: Path.refreshFlags() {{{1 "FUNCTION: Path.refreshFlags(nerdtree) {{{1
function! s:Path.refreshFlags() function! s:Path.refreshFlags(nerdtree)
call g:NERDTreePathNotifier.NotifyListeners('refreshFlags', self, {}) call g:NERDTreePathNotifier.NotifyListeners('refreshFlags', self, a:nerdtree, {})
call self.cacheDisplayString() call self.cacheDisplayString()
endfunction endfunction

View file

@ -9,7 +9,7 @@ let g:NERDTreeDirNode = s:TreeDirNode
"FUNCTION: TreeDirNode.AbsoluteTreeRoot(){{{1 "FUNCTION: TreeDirNode.AbsoluteTreeRoot(){{{1
"class method that returns the highest cached ancestor of the current root "class method that returns the highest cached ancestor of the current root
function! s:TreeDirNode.AbsoluteTreeRoot() function! s:TreeDirNode.AbsoluteTreeRoot()
let currentNode = b:NERDTreeRoot let currentNode = b:NERDTree.root
while currentNode.parent != {} while currentNode.parent != {}
let currentNode = currentNode.parent let currentNode = currentNode.parent
endwhile endwhile
@ -21,7 +21,7 @@ unlet s:TreeDirNode.activate
function! s:TreeDirNode.activate(...) function! s:TreeDirNode.activate(...)
let opts = a:0 ? a:1 : {} let opts = a:0 ? a:1 : {}
call self.toggleOpen(opts) call self.toggleOpen(opts)
call b:NERDTree.render() call self.getNerdtree().render()
call self.putCursorHere(0, 0) call self.putCursorHere(0, 0)
endfunction endfunction
@ -68,11 +68,27 @@ endfunction
"Returns: "Returns:
"the newly created node "the newly created node
function! s:TreeDirNode.createChild(path, inOrder) function! s:TreeDirNode.createChild(path, inOrder)
let newTreeNode = g:NERDTreeFileNode.New(a:path) let newTreeNode = g:NERDTreeFileNode.New(a:path, self.getNerdtree())
call self.addChild(newTreeNode, a:inOrder) call self.addChild(newTreeNode, a:inOrder)
return newTreeNode return newTreeNode
endfunction endfunction
"FUNCTION: TreeDirNode.displayString() {{{1
unlet s:TreeDirNode.displayString
function! s:TreeDirNode.displayString()
let cascade = self.getCascade()
let rv = ""
for node in cascade
let rv = rv . node.path.displayString()
endfor
let sym = cascade[-1].isOpen ? g:NERDTreeDirArrowCollapsible : g:NERDTreeDirArrowExpandable
let flags = cascade[-1].path.flagSet.renderToString()
return sym . ' ' . flags . rv
endfunction
"FUNCTION: TreeDirNode.findNode(path) {{{1 "FUNCTION: TreeDirNode.findNode(path) {{{1
"Will find one of the children (recursively) that has the given path "Will find one of the children (recursively) that has the given path
" "
@ -98,6 +114,33 @@ function! s:TreeDirNode.findNode(path)
return {} return {}
endfunction endfunction
"FUNCTION: TreeDirNode.getCascade() {{{1
"Return an array of dir nodes (starting from self) that can be cascade opened.
function! s:TreeDirNode.getCascade()
let rv = [self]
let node = self
while 1
let vc = node.getVisibleChildren()
if len(vc) != 1
break
endif
let visChild = vc[0]
"TODO: optimize
if !visChild.path.isDirectory
break
endif
call add(rv, visChild)
let node = visChild
endwhile
return rv
endfunction
"FUNCTION: TreeDirNode.getChildCount() {{{1 "FUNCTION: TreeDirNode.getChildCount() {{{1
"Returns the number of children this node has "Returns the number of children this node has
function! s:TreeDirNode.getChildCount() function! s:TreeDirNode.getChildCount()
@ -171,6 +214,12 @@ function! s:TreeDirNode.getChildIndex(path)
return -1 return -1
endfunction endfunction
"FUNCTION: TreeDirNode.getDirChildren() {{{1
"Get all children that are directories
function! s:TreeDirNode.getDirChildren()
return filter(self.children, 'v:val.path.isDirectory == 1')
endfunction
"FUNCTION: TreeDirNode.GetSelected() {{{1 "FUNCTION: TreeDirNode.GetSelected() {{{1
"Returns the current node if it is a dir node, or else returns the current "Returns the current node if it is a dir node, or else returns the current
"nodes parent "nodes parent
@ -199,7 +248,7 @@ endfunction
function! s:TreeDirNode.getVisibleChildren() function! s:TreeDirNode.getVisibleChildren()
let toReturn = [] let toReturn = []
for i in self.children for i in self.children
if i.path.ignore() ==# 0 if i.path.ignore(self.getNerdtree()) ==# 0
call add(toReturn, i) call add(toReturn, i)
endif endif
endfor endfor
@ -212,6 +261,13 @@ function! s:TreeDirNode.hasVisibleChildren()
return self.getVisibleChildCount() != 0 return self.getVisibleChildCount() != 0
endfunction endfunction
"FUNCTION: TreeDirNode.isCascadable() {{{1
"true if this dir has only one visible child - which is also a dir
function! s:TreeDirNode.isCascadable()
let c = self.getVisibleChildren()
return len(c) == 1 && c[0].path.isDirectory
endfunction
"FUNCTION: TreeDirNode._initChildren() {{{1 "FUNCTION: TreeDirNode._initChildren() {{{1
"Removes all childen from this node and re-reads them "Removes all childen from this node and re-reads them
" "
@ -244,19 +300,15 @@ function! s:TreeDirNode._initChildren(silent)
for i in files for i in files
"filter out the .. and . directories "filter out the .. and . directories
"Note: we must match .. AND ../ cos sometimes the globpath returns "Note: we must match .. AND ../ since sometimes the globpath returns
"../ for path with strange chars (eg $) "../ for path with strange chars (eg $)
" if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$' if i[len(i)-3:2] != ".." && i[len(i)-2:2] != ".." &&
"
" Regular expression is too expensive. Use simply string comparison
" instead
if i[len(i)-3:2] != ".." && i[len(i)-2:2] != ".." &&
\ i[len(i)-2:1] != "." && i[len(i)-1] != "." \ i[len(i)-2:1] != "." && i[len(i)-1] != "."
"put the next file in a new node and attach it "put the next file in a new node and attach it
try try
let path = g:NERDTreePath.New(i) let path = g:NERDTreePath.New(i)
call self.createChild(path, 0) call self.createChild(path, 0)
call g:NERDTreePathNotifier.NotifyListeners('init', path, {}) call g:NERDTreePathNotifier.NotifyListeners('init', path, self.getNerdtree(), {})
catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/ catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/
let invalidFilesFound += 1 let invalidFilesFound += 1
endtry endtry
@ -275,13 +327,13 @@ function! s:TreeDirNode._initChildren(silent)
return self.getChildCount() return self.getChildCount()
endfunction endfunction
"FUNCTION: TreeDirNode.New(path) {{{1 "FUNCTION: TreeDirNode.New(path, nerdtree) {{{1
"Returns a new TreeNode object with the given path and parent "Returns a new TreeNode object with the given path and parent
" "
"Args: "Args:
"path: a path object representing the full filesystem path to the file/dir that the node represents "path: dir that the node represents
unlet s:TreeDirNode.New "nerdtree: the tree the node belongs to
function! s:TreeDirNode.New(path) function! s:TreeDirNode.New(path, nerdtree)
if a:path.isDirectory != 1 if a:path.isDirectory != 1
throw "NERDTree.InvalidArgumentsError: A TreeDirNode object must be instantiated with a directory Path object." throw "NERDTree.InvalidArgumentsError: A TreeDirNode object must be instantiated with a directory Path object."
endif endif
@ -293,6 +345,7 @@ function! s:TreeDirNode.New(path)
let newTreeNode.children = [] let newTreeNode.children = []
let newTreeNode.parent = {} let newTreeNode.parent = {}
let newTreeNode._nerdtree = a:nerdtree
return newTreeNode return newTreeNode
endfunction endfunction
@ -356,7 +409,7 @@ endfunction
"FUNCTION: TreeDirNode._openInNewTab() {{{1 "FUNCTION: TreeDirNode._openInNewTab() {{{1
function! s:TreeDirNode._openInNewTab() function! s:TreeDirNode._openInNewTab()
tabnew tabnew
call g:NERDTreeCreator.CreatePrimary(self.path.str()) call g:NERDTreeCreator.CreateTabTree(self.path.str())
endfunction endfunction
"FUNCTION: TreeDirNode.openRecursively() {{{1 "FUNCTION: TreeDirNode.openRecursively() {{{1
@ -377,7 +430,7 @@ endfunction
"Args: "Args:
"forceOpen: 1 if this node should be opened regardless of file filters "forceOpen: 1 if this node should be opened regardless of file filters
function! s:TreeDirNode._openRecursively2(forceOpen) function! s:TreeDirNode._openRecursively2(forceOpen)
if self.path.ignore() ==# 0 || a:forceOpen if self.path.ignore(self.getNerdtree()) ==# 0 || a:forceOpen
let self.isOpen = 1 let self.isOpen = 1
if self.children ==# [] if self.children ==# []
call self._initChildren(1) call self._initChildren(1)
@ -394,7 +447,7 @@ endfunction
"FUNCTION: TreeDirNode.refresh() {{{1 "FUNCTION: TreeDirNode.refresh() {{{1
unlet s:TreeDirNode.refresh unlet s:TreeDirNode.refresh
function! s:TreeDirNode.refresh() function! s:TreeDirNode.refresh()
call self.path.refresh() call self.path.refresh(self.getNerdtree())
"if this node was ever opened, refresh its children "if this node was ever opened, refresh its children
if self.isOpen || !empty(self.children) if self.isOpen || !empty(self.children)
@ -425,7 +478,7 @@ function! s:TreeDirNode.refresh()
"the node doesnt exist so create it "the node doesnt exist so create it
else else
let newNode = g:NERDTreeFileNode.New(path) let newNode = g:NERDTreeFileNode.New(path, self.getNerdtree())
let newNode.parent = self let newNode.parent = self
call add(newChildNodes, newNode) call add(newChildNodes, newNode)
endif endif
@ -450,7 +503,7 @@ endfunction
"FUNCTION: TreeDirNode.refreshFlags() {{{1 "FUNCTION: TreeDirNode.refreshFlags() {{{1
unlet s:TreeDirNode.refreshFlags unlet s:TreeDirNode.refreshFlags
function! s:TreeDirNode.refreshFlags() function! s:TreeDirNode.refreshFlags()
call self.path.refreshFlags() call self.path.refreshFlags(self.getNerdtree())
for i in self.children for i in self.children
call i.refreshFlags() call i.refreshFlags()
endfor endfor
@ -458,13 +511,16 @@ endfunction
"FUNCTION: TreeDirNode.refreshDirFlags() {{{1 "FUNCTION: TreeDirNode.refreshDirFlags() {{{1
function! s:TreeDirNode.refreshDirFlags() function! s:TreeDirNode.refreshDirFlags()
call self.path.refreshFlags() call self.path.refreshFlags(self.getNerdtree())
endfunction endfunction
"FUNCTION: TreeDirNode.reveal(path) {{{1 "FUNCTION: TreeDirNode.reveal(path) {{{1
"reveal the given path, i.e. cache and open all treenodes needed to display it "reveal the given path, i.e. cache and open all treenodes needed to display it
"in the UI "in the UI
function! s:TreeDirNode.reveal(path) "Returns the revealed node
function! s:TreeDirNode.reveal(path, ...)
let opts = a:0 ? a:1 : {}
if !a:path.isUnder(self.path) if !a:path.isUnder(self.path)
throw "NERDTree.InvalidArgumentsError: " . a:path.str() . " should be under " . self.path.str() throw "NERDTree.InvalidArgumentsError: " . a:path.str() . " should be under " . self.path.str()
endif endif
@ -473,9 +529,10 @@ function! s:TreeDirNode.reveal(path)
if self.path.equals(a:path.getParent()) if self.path.equals(a:path.getParent())
let n = self.findNode(a:path) let n = self.findNode(a:path)
call b:NERDTree.render() if has_key(opts, "open")
call n.putCursorHere(1,0) call n.open()
return endif
return n
endif endif
let p = a:path let p = a:path
@ -484,7 +541,7 @@ function! s:TreeDirNode.reveal(path)
endwhile endwhile
let n = self.findNode(p) let n = self.findNode(p)
call n.reveal(a:path) return n.reveal(a:path, opts)
endfunction endfunction
"FUNCTION: TreeDirNode.removeChild(treenode) {{{1 "FUNCTION: TreeDirNode.removeChild(treenode) {{{1

View file

@ -19,7 +19,7 @@ function! s:TreeFileNode.bookmark(name)
"it so we can update its display string "it so we can update its display string
let oldMarkedNode = {} let oldMarkedNode = {}
try try
let oldMarkedNode = g:NERDTreeBookmark.GetNodeForName(a:name, 1) let oldMarkedNode = g:NERDTreeBookmark.GetNodeForName(a:name, 1, self.getNerdtree())
catch /^NERDTree.BookmarkNotFoundError/ catch /^NERDTree.BookmarkNotFoundError/
catch /^NERDTree.BookmarkedNodeNotFoundError/ catch /^NERDTree.BookmarkedNodeNotFoundError/
endtry endtry
@ -41,7 +41,7 @@ function! s:TreeFileNode.cacheParent()
if parentPath.equals(self.path) if parentPath.equals(self.path)
throw "NERDTree.CannotCacheParentError: already at root" throw "NERDTree.CannotCacheParentError: already at root"
endif endif
let self.parent = s:TreeFileNode.New(parentPath) let self.parent = s:TreeFileNode.New(parentPath, self.getNerdtree())
endif endif
endfunction endfunction
@ -59,7 +59,7 @@ endfunction
function! s:TreeFileNode.copy(dest) function! s:TreeFileNode.copy(dest)
call self.path.copy(a:dest) call self.path.copy(a:dest)
let newPath = g:NERDTreePath.New(a:dest) let newPath = g:NERDTreePath.New(a:dest)
let parent = b:NERDTreeRoot.findNode(newPath.getParent()) let parent = self.getNerdtree().root.findNode(newPath.getParent())
if !empty(parent) if !empty(parent)
call parent.refresh() call parent.refresh()
return parent.findNode(newPath) return parent.findNode(newPath)
@ -83,7 +83,7 @@ endfunction
"Return: "Return:
"a string that can be used in the view to represent this node "a string that can be used in the view to represent this node
function! s:TreeFileNode.displayString() function! s:TreeFileNode.displayString()
return self.path.displayString() return self.path.flagSet.renderToString() . self.path.displayString()
endfunction endfunction
"FUNCTION: TreeFileNode.equals(treenode) {{{1 "FUNCTION: TreeFileNode.equals(treenode) {{{1
@ -165,7 +165,7 @@ function! s:TreeFileNode.findSibling(direction)
"if the next node is not an ignored node (i.e. wont show up in the "if the next node is not an ignored node (i.e. wont show up in the
"view) then return it "view) then return it
if self.parent.children[siblingIndx].path.ignore() ==# 0 if self.parent.children[siblingIndx].path.ignore(self.getNerdtree()) ==# 0
return self.parent.children[siblingIndx] return self.parent.children[siblingIndx]
endif endif
@ -178,11 +178,16 @@ function! s:TreeFileNode.findSibling(direction)
return {} return {}
endfunction endfunction
"FUNCTION: TreeFileNode.getNerdtree(){{{1
function! s:TreeFileNode.getNerdtree()
return self._nerdtree
endfunction
"FUNCTION: TreeFileNode.GetRootForTab(){{{1 "FUNCTION: TreeFileNode.GetRootForTab(){{{1
"get the root node for this tab "get the root node for this tab
function! s:TreeFileNode.GetRootForTab() function! s:TreeFileNode.GetRootForTab()
if g:NERDTree.ExistsForTab() if g:NERDTree.ExistsForTab()
return getbufvar(t:NERDTreeBufName, 'NERDTreeRoot') return getbufvar(t:NERDTreeBufName, 'NERDTree').root
end end
return {} return {}
endfunction endfunction
@ -195,7 +200,7 @@ function! s:TreeFileNode.GetSelected()
if path ==# {} if path ==# {}
return {} return {}
endif endif
return b:NERDTreeRoot.findNode(path) return b:NERDTree.root.findNode(path)
catch /^NERDTree/ catch /^NERDTree/
return {} return {}
endtry endtry
@ -205,51 +210,32 @@ endfunction
"returns 1 if this node should be visible according to the tree filters and "returns 1 if this node should be visible according to the tree filters and
"hidden file filters (and their on/off status) "hidden file filters (and their on/off status)
function! s:TreeFileNode.isVisible() function! s:TreeFileNode.isVisible()
return !self.path.ignore() return !self.path.ignore(self.getNerdtree())
endfunction endfunction
"FUNCTION: TreeFileNode.isRoot() {{{1 "FUNCTION: TreeFileNode.isRoot() {{{1
"returns 1 if this node is b:NERDTreeRoot
function! s:TreeFileNode.isRoot() function! s:TreeFileNode.isRoot()
if !g:NERDTree.ExistsForBuf() if !g:NERDTree.ExistsForBuf()
throw "NERDTree.NoTreeError: No tree exists for the current buffer" throw "NERDTree.NoTreeError: No tree exists for the current buffer"
endif endif
return self.equals(b:NERDTreeRoot) return self.equals(self.getNerdtree().root)
endfunction endfunction
"FUNCTION: TreeFileNode.makeRoot() {{{1 "FUNCTION: TreeFileNode.New(path, nerdtree) {{{1
"Make this node the root of the tree
function! s:TreeFileNode.makeRoot()
if self.path.isDirectory
let b:NERDTreeRoot = self
else
call self.cacheParent()
let b:NERDTreeRoot = self.parent
endif
call b:NERDTreeRoot.open()
"change dir to the dir of the new root if instructed to
if g:NERDTreeChDirMode ==# 2
exec "cd " . b:NERDTreeRoot.path.str({'format': 'Edit'})
endif
silent doautocmd User NERDTreeNewRoot
endfunction
"FUNCTION: TreeFileNode.New(path) {{{1
"Returns a new TreeNode object with the given path and parent "Returns a new TreeNode object with the given path and parent
" "
"Args: "Args:
"path: a path object representing the full filesystem path to the file/dir that the node represents "path: file/dir that the node represents
function! s:TreeFileNode.New(path) "nerdtree: the tree the node belongs to
function! s:TreeFileNode.New(path, nerdtree)
if a:path.isDirectory if a:path.isDirectory
return g:NERDTreeDirNode.New(a:path) return g:NERDTreeDirNode.New(a:path, a:nerdtree)
else else
let newTreeNode = copy(self) let newTreeNode = copy(self)
let newTreeNode.path = a:path let newTreeNode.path = a:path
let newTreeNode.parent = {} let newTreeNode.parent = {}
let newTreeNode._nerdtree = a:nerdtree
return newTreeNode return newTreeNode
endif endif
endfunction endfunction
@ -289,7 +275,7 @@ endfunction
"recurseUpward: try to put the cursor on the parent if the this node isnt "recurseUpward: try to put the cursor on the parent if the this node isnt
"visible "visible
function! s:TreeFileNode.putCursorHere(isJump, recurseUpward) function! s:TreeFileNode.putCursorHere(isJump, recurseUpward)
let ln = b:NERDTree.ui.getLineNum(self) let ln = self.getNerdtree().ui.getLineNum(self)
if ln != -1 if ln != -1
if a:isJump if a:isJump
mark ' mark '
@ -298,11 +284,11 @@ function! s:TreeFileNode.putCursorHere(isJump, recurseUpward)
else else
if a:recurseUpward if a:recurseUpward
let node = self let node = self
while node != {} && b:NERDTree.ui.getLineNum(node) ==# -1 while node != {} && self.getNerdtree().ui.getLineNum(node) ==# -1
let node = node.parent let node = node.parent
call node.open() call node.open()
endwhile endwhile
call b:NERDTree.render() call self._nerdtree.render()
call node.putCursorHere(a:isJump, 0) call node.putCursorHere(a:isJump, 0)
endif endif
endif endif
@ -310,12 +296,12 @@ endfunction
"FUNCTION: TreeFileNode.refresh() {{{1 "FUNCTION: TreeFileNode.refresh() {{{1
function! s:TreeFileNode.refresh() function! s:TreeFileNode.refresh()
call self.path.refresh() call self.path.refresh(self.getNerdtree())
endfunction endfunction
"FUNCTION: TreeFileNode.refreshFlags() {{{1 "FUNCTION: TreeFileNode.refreshFlags() {{{1
function! s:TreeFileNode.refreshFlags() function! s:TreeFileNode.refreshFlags()
call self.path.refreshFlags() call self.path.refreshFlags(self.getNerdtree())
endfunction endfunction
"FUNCTION: TreeFileNode.rename() {{{1 "FUNCTION: TreeFileNode.rename() {{{1
@ -326,7 +312,7 @@ function! s:TreeFileNode.rename(newName)
call self.parent.removeChild(self) call self.parent.removeChild(self)
let parentPath = self.path.getParent() let parentPath = self.path.getParent()
let newParent = b:NERDTreeRoot.findNode(parentPath) let newParent = self.getNerdtree().root.findNode(parentPath)
if newParent != {} if newParent != {}
call newParent.createChild(self.path, 1) call newParent.createChild(self.path, 1)
@ -337,70 +323,24 @@ endfunction
"FUNCTION: TreeFileNode.renderToString {{{1 "FUNCTION: TreeFileNode.renderToString {{{1
"returns a string representation for this tree to be rendered in the view "returns a string representation for this tree to be rendered in the view
function! s:TreeFileNode.renderToString() function! s:TreeFileNode.renderToString()
return self._renderToString(0, 0, [], self.getChildCount() ==# 1) return self._renderToString(0, 0)
endfunction endfunction
"Args: "Args:
"depth: the current depth in the tree for this call "depth: the current depth in the tree for this call
"drawText: 1 if we should actually draw the line for this node (if 0 then the "drawText: 1 if we should actually draw the line for this node (if 0 then the
"child nodes are rendered only) "child nodes are rendered only)
"vertMap: a binary array that indicates whether a vertical bar should be draw
"for each depth in the tree "for each depth in the tree
"isLastChild:true if this curNode is the last child of its parent function! s:TreeFileNode._renderToString(depth, drawText)
function! s:TreeFileNode._renderToString(depth, drawText, vertMap, isLastChild)
let output = "" let output = ""
if a:drawText ==# 1 if a:drawText ==# 1
let treeParts = '' let treeParts = repeat(' ', a:depth - 1)
"get all the leading spaces and vertical tree parts for this line if !self.path.isDirectory
if a:depth > 1 let treeParts = treeParts . ' '
for j in a:vertMap[0:-2]
if g:NERDTreeDirArrows
let treeParts = treeParts . ' '
else
if j ==# 1
let treeParts = treeParts . '| '
else
let treeParts = treeParts . ' '
endif
endif
endfor
endif endif
"get the last vertical tree part for this line which will be different
"if this node is the last child of its parent
if !g:NERDTreeDirArrows
if a:isLastChild
let treeParts = treeParts . '`'
else
let treeParts = treeParts . '|'
endif
endif
"smack the appropriate dir/file symbol on the line before the file/dir
"name itself
if self.path.isDirectory
if self.isOpen
if g:NERDTreeDirArrows
let treeParts = treeParts . '▾ '
else
let treeParts = treeParts . '~'
endif
else
if g:NERDTreeDirArrows
let treeParts = treeParts . '▸ '
else
let treeParts = treeParts . '+'
endif
endif
else
if g:NERDTreeDirArrows
let treeParts = treeParts . ' '
else
let treeParts = treeParts . '-'
endif
endif
let line = treeParts . self.displayString() let line = treeParts . self.displayString()
let output = output . line . "\n" let output = output . line . "\n"
@ -410,18 +350,15 @@ function! s:TreeFileNode._renderToString(depth, drawText, vertMap, isLastChild)
if self.path.isDirectory ==# 1 && self.isOpen ==# 1 if self.path.isDirectory ==# 1 && self.isOpen ==# 1
let childNodesToDraw = self.getVisibleChildren() let childNodesToDraw = self.getVisibleChildren()
if len(childNodesToDraw) > 0
"draw all the nodes children except the last if self.isCascadable() && a:depth > 0
let lastIndx = len(childNodesToDraw)-1
if lastIndx > 0
for i in childNodesToDraw[0:lastIndx-1]
let output = output . i._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 1), 0)
endfor
endif
"draw the last child, indicating that it IS the last let output = output . childNodesToDraw[0]._renderToString(a:depth, 0)
let output = output . childNodesToDraw[lastIndx]._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 0), 1)
elseif len(childNodesToDraw) > 0
for i in childNodesToDraw
let output = output . i._renderToString(a:depth + 1, 1)
endfor
endif endif
endif endif

View file

@ -21,18 +21,18 @@ endfunction
"prints out the quick help "prints out the quick help
function! s:UI._dumpHelp() function! s:UI._dumpHelp()
let old_h = @h let old_h = @h
if b:treeShowHelp ==# 1 if self.getShowHelp()
let @h= "\" NERD tree (" . nerdtree#version() . ") quickhelp~\n" let @h= "\" NERD tree (" . nerdtree#version() . ") quickhelp~\n"
let @h=@h."\" ============================\n" let @h=@h."\" ============================\n"
let @h=@h."\" File node mappings~\n" let @h=@h."\" File node mappings~\n"
let @h=@h."\" ". (g:NERDTreeMouseMode ==# 3 ? "single" : "double") ."-click,\n" let @h=@h."\" ". (g:NERDTreeMouseMode ==# 3 ? "single" : "double") ."-click,\n"
let @h=@h."\" <CR>,\n" let @h=@h."\" <CR>,\n"
if b:NERDTreeType ==# "primary" if self.nerdtree.isTabTree()
let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in prev window\n" let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in prev window\n"
else else
let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in current window\n" let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in current window\n"
endif endif
if b:NERDTreeType ==# "primary" if self.nerdtree.isTabTree()
let @h=@h."\" ". g:NERDTreeMapPreview .": preview\n" let @h=@h."\" ". g:NERDTreeMapPreview .": preview\n"
endif endif
let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n" let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n"
@ -87,10 +87,10 @@ function! s:UI._dumpHelp()
let @h=@h."\"\n\" ----------------------------\n" let @h=@h."\"\n\" ----------------------------\n"
let @h=@h."\" Tree filtering mappings~\n" let @h=@h."\" Tree filtering mappings~\n"
let @h=@h."\" ". g:NERDTreeMapToggleHidden .": hidden files (" . (b:NERDTreeShowHidden ? "on" : "off") . ")\n" let @h=@h."\" ". g:NERDTreeMapToggleHidden .": hidden files (" . (self.getShowHidden() ? "on" : "off") . ")\n"
let @h=@h."\" ". g:NERDTreeMapToggleFilters .": file filters (" . (b:NERDTreeIgnoreEnabled ? "on" : "off") . ")\n" let @h=@h."\" ". g:NERDTreeMapToggleFilters .": file filters (" . (self.isIgnoreFilterEnabled() ? "on" : "off") . ")\n"
let @h=@h."\" ". g:NERDTreeMapToggleFiles .": files (" . (b:NERDTreeShowFiles ? "on" : "off") . ")\n" let @h=@h."\" ". g:NERDTreeMapToggleFiles .": files (" . (self.getShowFiles() ? "on" : "off") . ")\n"
let @h=@h."\" ". g:NERDTreeMapToggleBookmarks .": bookmarks (" . (b:NERDTreeShowBookmarks ? "on" : "off") . ")\n" let @h=@h."\" ". g:NERDTreeMapToggleBookmarks .": bookmarks (" . (self.getShowBookmarks() ? "on" : "off") . ")\n"
"add quickhelp entries for each custom key map "add quickhelp entries for each custom key map
let @h=@h."\"\n\" ----------------------------\n" let @h=@h."\"\n\" ----------------------------\n"
@ -116,7 +116,7 @@ function! s:UI._dumpHelp()
let @h=@h."\" :ClearBookmarks [<names>]\n" let @h=@h."\" :ClearBookmarks [<names>]\n"
let @h=@h."\" :ClearAllBookmarks\n" let @h=@h."\" :ClearAllBookmarks\n"
silent! put h silent! put h
elseif g:NERDTreeMinimalUI == 0 elseif !self.isMinimal()
let @h="\" Press ". g:NERDTreeMapHelp ." for help\n" let @h="\" Press ". g:NERDTreeMapHelp ." for help\n"
silent! put h silent! put h
endif endif
@ -129,6 +129,12 @@ endfunction
function! s:UI.New(nerdtree) function! s:UI.New(nerdtree)
let newObj = copy(self) let newObj = copy(self)
let newObj.nerdtree = a:nerdtree let newObj.nerdtree = a:nerdtree
let newObj._showHelp = 0
let newObj._ignoreEnabled = 1
let newObj._showFiles = g:NERDTreeShowFiles
let newObj._showHidden = g:NERDTreeShowHidden
let newObj._showBookmarks = g:NERDTreeShowBookmarks
return newObj return newObj
endfunction endfunction
@ -149,18 +155,11 @@ function! s:UI.getPath(ln)
"check to see if we have the root node "check to see if we have the root node
if a:ln == rootLine if a:ln == rootLine
return b:NERDTreeRoot.path return self.nerdtree.root.path
endif
if !g:NERDTreeDirArrows
" in case called from outside the tree
if line !~# '^ *[|`▸▾ ]' || line =~# '^$'
return {}
endif
endif endif
if line ==# s:UI.UpDirLine() if line ==# s:UI.UpDirLine()
return b:NERDTreeRoot.path.getParent() return self.nerdtree.root.path.getParent()
endif endif
let indent = self._indentLevelFor(line) let indent = self._indentLevelFor(line)
@ -183,7 +182,7 @@ function! s:UI.getPath(ln)
"have we reached the top of the tree? "have we reached the top of the tree?
if lnum == rootLine if lnum == rootLine
let dir = b:NERDTreeRoot.path.str({'format': 'UI'}) . dir let dir = self.nerdtree.root.path.str({'format': 'UI'}) . dir
break break
endif endif
if curLineStripped =~# '/$' if curLineStripped =~# '/$'
@ -196,7 +195,7 @@ function! s:UI.getPath(ln)
endif endif
endif endif
endwhile endwhile
let curFile = b:NERDTreeRoot.path.drive . dir . curFile let curFile = self.nerdtree.root.path.drive . dir . curFile
let toReturn = g:NERDTreePath.New(curFile) let toReturn = g:NERDTreePath.New(curFile)
return toReturn return toReturn
endfunction endfunction
@ -206,19 +205,19 @@ endfunction
function! s:UI.getLineNum(file_node) function! s:UI.getLineNum(file_node)
"if the node is the root then return the root line no. "if the node is the root then return the root line no.
if a:file_node.isRoot() if a:file_node.isRoot()
return b:NERDTree.ui.getRootLineNum() return self.getRootLineNum()
endif endif
let totalLines = line("$") let totalLines = line("$")
"the path components we have matched so far "the path components we have matched so far
let pathcomponents = [substitute(b:NERDTreeRoot.path.str({'format': 'UI'}), '/ *$', '', '')] let pathcomponents = [substitute(self.nerdtree.root.path.str({'format': 'UI'}), '/ *$', '', '')]
"the index of the component we are searching for "the index of the component we are searching for
let curPathComponent = 1 let curPathComponent = 1
let fullpath = a:file_node.path.str({'format': 'UI'}) let fullpath = a:file_node.path.str({'format': 'UI'})
let lnum = b:NERDTree.ui.getRootLineNum() let lnum = self.getRootLineNum()
while lnum > 0 while lnum > 0
let lnum = lnum + 1 let lnum = lnum + 1
"have we reached the bottom of the tree? "have we reached the bottom of the tree?
@ -259,15 +258,33 @@ function! s:UI.getRootLineNum()
return rootLine return rootLine
endfunction endfunction
"FUNCTION: s:UI.getShowBookmarks() {{{1
function! s:UI.getShowBookmarks()
return self._showBookmarks
endfunction
"FUNCTION: s:UI.getShowFiles() {{{1
function! s:UI.getShowFiles()
return self._showFiles
endfunction
"FUNCTION: s:UI.getShowHelp() {{{1
function! s:UI.getShowHelp()
return self._showHelp
endfunction
"FUNCTION: s:UI.getShowHidden() {{{1
function! s:UI.getShowHidden()
return self._showHidden
endfunction
"FUNCTION: s:UI._indentLevelFor(line) {{{1 "FUNCTION: s:UI._indentLevelFor(line) {{{1
function! s:UI._indentLevelFor(line) function! s:UI._indentLevelFor(line)
let level = match(a:line, '[^ \-+~▸▾`|]') / s:UI.IndentWid() "have to do this work around because match() returns bytes, not chars
" check if line includes arrows let numLeadBytes = match(a:line, '\M\[^ '.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.']')
if match(a:line, '[▸▾]') > -1 let leadChars = strchars(a:line[0:numLeadBytes-1])
" decrement level as arrow uses 3 ascii chars
let level = level - 1 return leadChars / s:UI.IndentWid()
endif
return level
endfunction endfunction
"FUNCTION: s:UI.IndentWid() {{{1 "FUNCTION: s:UI.IndentWid() {{{1
@ -275,19 +292,25 @@ function! s:UI.IndentWid()
return 2 return 2
endfunction endfunction
"FUNCTION: s:UI.isIgnoreFilterEnabled() {{{1
function! s:UI.isIgnoreFilterEnabled()
return self._ignoreEnabled == 1
endfunction
"FUNCTION: s:UI.isMinimal() {{{1
function! s:UI.isMinimal()
return g:NERDTreeMinimalUI
endfunction
"FUNCTION: s:UI.MarkupReg() {{{1 "FUNCTION: s:UI.MarkupReg() {{{1
function! s:UI.MarkupReg() function! s:UI.MarkupReg()
if g:NERDTreeDirArrows return '^\(['.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.'] \| \+['.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.'] \| \+\)'
return '^\([▾▸] \| \+[▾▸] \| \+\)'
endif
return '^[ `|]*[\-+~]'
endfunction endfunction
"FUNCTION: s:UI._renderBookmarks {{{1 "FUNCTION: s:UI._renderBookmarks {{{1
function! s:UI._renderBookmarks() function! s:UI._renderBookmarks()
if g:NERDTreeMinimalUI == 0 if !self.isMinimal()
call setline(line(".")+1, ">----------Bookmarks----------") call setline(line(".")+1, ">----------Bookmarks----------")
call cursor(line(".")+1, col(".")) call cursor(line(".")+1, col("."))
endif endif
@ -334,6 +357,11 @@ function! s:UI.saveScreenState()
call nerdtree#exec(win . "wincmd w") call nerdtree#exec(win . "wincmd w")
endfunction endfunction
"FUNCTION: s:UI.setShowHidden(val) {{{1
function! s:UI.setShowHidden(val)
let self._showHidden = a:val
endfunction
"FUNCTION: s:UI._stripMarkup(line, removeLeadingSpaces){{{1 "FUNCTION: s:UI._stripMarkup(line, removeLeadingSpaces){{{1
"returns the given line with all the tree parts stripped off "returns the given line with all the tree parts stripped off
" "
@ -390,29 +418,29 @@ function! s:UI.render()
call self._dumpHelp() call self._dumpHelp()
"delete the blank line before the help and add one after it "delete the blank line before the help and add one after it
if g:NERDTreeMinimalUI == 0 if !self.isMinimal()
call setline(line(".")+1, "") call setline(line(".")+1, "")
call cursor(line(".")+1, col(".")) call cursor(line(".")+1, col("."))
endif endif
if b:NERDTreeShowBookmarks if self.getShowBookmarks()
call self._renderBookmarks() call self._renderBookmarks()
endif endif
"add the 'up a dir' line "add the 'up a dir' line
if !g:NERDTreeMinimalUI if !self.isMinimal()
call setline(line(".")+1, s:UI.UpDirLine()) call setline(line(".")+1, s:UI.UpDirLine())
call cursor(line(".")+1, col(".")) call cursor(line(".")+1, col("."))
endif endif
"draw the header line "draw the header line
let header = b:NERDTreeRoot.path.str({'format': 'UI', 'truncateTo': winwidth(0)}) let header = self.nerdtree.root.path.str({'format': 'UI', 'truncateTo': winwidth(0)})
call setline(line(".")+1, header) call setline(line(".")+1, header)
call cursor(line(".")+1, col(".")) call cursor(line(".")+1, col("."))
"draw the tree "draw the tree
let old_o = @o let old_o = @o
let @o = b:NERDTreeRoot.renderToString() let @o = self.nerdtree.root.renderToString()
silent put o silent put o
let @o = old_o let @o = old_o
@ -443,47 +471,52 @@ function! s:UI.renderViewSavingPosition()
let currentNode = currentNode.parent let currentNode = currentNode.parent
endwhile endwhile
call b:NERDTree.render() call self.render()
if currentNode != {} if currentNode != {}
call currentNode.putCursorHere(0, 0) call currentNode.putCursorHere(0, 0)
endif endif
endfunction endfunction
"FUNCTION: s:UI.toggleHelp() {{{1
function! s:UI.toggleHelp()
let self._showHelp = !self._showHelp
endfunction
" FUNCTION: s:UI.toggleIgnoreFilter() {{{1 " FUNCTION: s:UI.toggleIgnoreFilter() {{{1
" toggles the use of the NERDTreeIgnore option " toggles the use of the NERDTreeIgnore option
function! s:UI.toggleIgnoreFilter() function! s:UI.toggleIgnoreFilter()
let b:NERDTreeIgnoreEnabled = !b:NERDTreeIgnoreEnabled let self._ignoreEnabled = !self._ignoreEnabled
call b:NERDTree.ui.renderViewSavingPosition() call self.renderViewSavingPosition()
call b:NERDTree.ui.centerView() call self.centerView()
endfunction endfunction
" FUNCTION: s:UI.toggleShowBookmarks() {{{1 " FUNCTION: s:UI.toggleShowBookmarks() {{{1
" toggles the display of bookmarks " toggles the display of bookmarks
function! s:UI.toggleShowBookmarks() function! s:UI.toggleShowBookmarks()
let b:NERDTreeShowBookmarks = !b:NERDTreeShowBookmarks let self._showBookmarks = !self._showBookmarks
if b:NERDTreeShowBookmarks if self.getShowBookmarks()
call b:NERDTree.render() call self.nerdtree.render()
call g:NERDTree.CursorToBookmarkTable() call g:NERDTree.CursorToBookmarkTable()
else else
call b:NERDTree.ui.renderViewSavingPosition() call self.renderViewSavingPosition()
endif endif
call b:NERDTree.ui.centerView() call self.centerView()
endfunction endfunction
" FUNCTION: s:UI.toggleShowFiles() {{{1 " FUNCTION: s:UI.toggleShowFiles() {{{1
" toggles the display of hidden files " toggles the display of hidden files
function! s:UI.toggleShowFiles() function! s:UI.toggleShowFiles()
let b:NERDTreeShowFiles = !b:NERDTreeShowFiles let self._showFiles = !self._showFiles
call b:NERDTree.ui.renderViewSavingPosition() call self.renderViewSavingPosition()
call b:NERDTree.ui.centerView() call self.centerView()
endfunction endfunction
" FUNCTION: s:UI.toggleShowHidden() {{{1 " FUNCTION: s:UI.toggleShowHidden() {{{1
" toggles the display of hidden files " toggles the display of hidden files
function! s:UI.toggleShowHidden() function! s:UI.toggleShowHidden()
let b:NERDTreeShowHidden = !b:NERDTreeShowHidden let self._showHidden = !self._showHidden
call b:NERDTree.ui.renderViewSavingPosition() call self.renderViewSavingPosition()
call self.centerView() call self.centerView()
endfunction endfunction

View file

@ -2,7 +2,6 @@
" File: exec_menuitem.vim " File: exec_menuitem.vim
" Description: plugin for NERD Tree that provides an execute file menu item " Description: plugin for NERD Tree that provides an execute file menu item
" Maintainer: Martin Grenfell <martin.grenfell at gmail dot com> " Maintainer: Martin Grenfell <martin.grenfell at gmail dot com>
" Last Change: 22 July, 2009
" License: This program is free software. It comes without any warranty, " License: This program is free software. It comes without any warranty,
" to the extent permitted by applicable law. You can redistribute " 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 " it and/or modify it under the terms of the Do What The Fuck You

View file

@ -2,7 +2,6 @@
" File: fs_menu.vim " File: fs_menu.vim
" Description: plugin for the NERD Tree that provides a file system menu " Description: plugin for the NERD Tree that provides a file system menu
" Maintainer: Martin Grenfell <martin.grenfell at gmail dot com> " Maintainer: Martin Grenfell <martin.grenfell at gmail dot com>
" Last Change: 17 July, 2009
" License: This program is free software. It comes without any warranty, " License: This program is free software. It comes without any warranty,
" to the extent permitted by applicable law. You can redistribute " 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 " it and/or modify it under the terms of the Do What The Fuck You
@ -24,7 +23,7 @@ call NERDTreeAddMenuItem({'text': '(a)dd a childnode', 'shortcut': 'a', 'callbac
call NERDTreeAddMenuItem({'text': '(m)ove the current node', 'shortcut': 'm', 'callback': 'NERDTreeMoveNode'}) call NERDTreeAddMenuItem({'text': '(m)ove the current node', 'shortcut': 'm', 'callback': 'NERDTreeMoveNode'})
call NERDTreeAddMenuItem({'text': '(d)elete the current node', 'shortcut': 'd', 'callback': 'NERDTreeDeleteNode'}) call NERDTreeAddMenuItem({'text': '(d)elete the current node', 'shortcut': 'd', 'callback': 'NERDTreeDeleteNode'})
if has("gui_mac") || has("gui_macvim") if has("gui_mac") || has("gui_macvim") || has("mac")
call NERDTreeAddMenuItem({'text': '(r)eveal in Finder the current node', 'shortcut': 'r', 'callback': 'NERDTreeRevealInFinder'}) call NERDTreeAddMenuItem({'text': '(r)eveal in Finder the current node', 'shortcut': 'r', 'callback': 'NERDTreeRevealInFinder'})
call NERDTreeAddMenuItem({'text': '(o)pen the current node with system editor', 'shortcut': 'o', 'callback': 'NERDTreeExecuteFile'}) call NERDTreeAddMenuItem({'text': '(o)pen the current node with system editor', 'shortcut': 'o', 'callback': 'NERDTreeExecuteFile'})
call NERDTreeAddMenuItem({'text': '(q)uicklook the current node', 'shortcut': 'q', 'callback': 'NERDTreeQuickLook'}) call NERDTreeAddMenuItem({'text': '(q)uicklook the current node', 'shortcut': 'q', 'callback': 'NERDTreeQuickLook'})
@ -34,18 +33,11 @@ if g:NERDTreePath.CopyingSupported()
call NERDTreeAddMenuItem({'text': '(c)opy the current node', 'shortcut': 'c', 'callback': 'NERDTreeCopyNode'}) call NERDTreeAddMenuItem({'text': '(c)opy the current node', 'shortcut': 'c', 'callback': 'NERDTreeCopyNode'})
endif endif
"FUNCTION: s:echo(msg){{{1 if has("unix") || has("osx")
function! s:echo(msg) call NERDTreeAddMenuItem({'text': '(l)ist the current node', 'shortcut': 'l', 'callback': 'NERDTreeListNode'})
redraw else
echomsg "NERDTree: " . a:msg call NERDTreeAddMenuItem({'text': '(l)ist the current node', 'shortcut': 'l', 'callback': 'NERDTreeListNodeWin32'})
endfunction endif
"FUNCTION: s:echoWarning(msg){{{1
function! s:echoWarning(msg)
echohl warningmsg
call s:echo(a:msg)
echohl normal
endfunction
"FUNCTION: s:promptToDelBuffer(bufnum, msg){{{1 "FUNCTION: s:promptToDelBuffer(bufnum, msg){{{1
"prints out the given msg and, if the user responds by pushing 'y' then the "prints out the given msg and, if the user responds by pushing 'y' then the
@ -107,17 +99,17 @@ function! NERDTreeAddNode()
\ "", curDirNode.path.str() . g:NERDTreePath.Slash(), "file") \ "", curDirNode.path.str() . g:NERDTreePath.Slash(), "file")
if newNodeName ==# '' if newNodeName ==# ''
call s:echo("Node Creation Aborted.") call nerdtree#echo("Node Creation Aborted.")
return return
endif endif
try try
let newPath = g:NERDTreePath.Create(newNodeName) let newPath = g:NERDTreePath.Create(newNodeName)
let parentNode = b:NERDTreeRoot.findNode(newPath.getParent()) let parentNode = b:NERDTree.root.findNode(newPath.getParent())
let newTreeNode = g:NERDTreeFileNode.New(newPath) let newTreeNode = g:NERDTreeFileNode.New(newPath, b:NERDTree)
if empty(parentNode) if empty(parentNode)
call b:NERDTreeRoot.refresh() call b:NERDTree.root.refresh()
call b:NERDTree.render() call b:NERDTree.render()
elseif parentNode.isOpen || !empty(parentNode.children) elseif parentNode.isOpen || !empty(parentNode.children)
call parentNode.addChild(newTreeNode, 1) call parentNode.addChild(newTreeNode, 1)
@ -125,7 +117,7 @@ function! NERDTreeAddNode()
call newTreeNode.putCursorHere(1, 0) call newTreeNode.putCursorHere(1, 0)
endif endif
catch /^NERDTree/ catch /^NERDTree/
call s:echoWarning("Node Not Created.") call nerdtree#echoWarning("Node Not Created.")
endtry endtry
endfunction endfunction
@ -138,7 +130,7 @@ function! NERDTreeMoveNode()
\ "", curNode.path.str(), "file") \ "", curNode.path.str(), "file")
if newNodePath ==# '' if newNodePath ==# ''
call s:echo("Node Renaming Aborted.") call nerdtree#echo("Node Renaming Aborted.")
return return
endif endif
@ -159,7 +151,7 @@ function! NERDTreeMoveNode()
redraw redraw
catch /^NERDTree/ catch /^NERDTree/
call s:echoWarning("Node Not Renamed.") call nerdtree#echoWarning("Node Not Renamed.")
endtry endtry
endfunction endfunction
@ -199,10 +191,33 @@ function! NERDTreeDeleteNode()
redraw redraw
catch /^NERDTree/ catch /^NERDTree/
call s:echoWarning("Could not remove node") call nerdtree#echoWarning("Could not remove node")
endtry endtry
else else
call s:echo("delete aborted") call nerdtree#echo("delete aborted")
endif
endfunction
" FUNCTION: NERDTreeListNode() {{{1
function! NERDTreeListNode()
let treenode = g:NERDTreeFileNode.GetSelected()
if treenode != {}
let metadata = split(system('ls -ld ' . shellescape(treenode.path.str())), '\n')
call nerdtree#echo(metadata[0])
else
call nerdtree#echo("No information avaialable")
endif
endfunction
" FUNCTION: NERDTreeListNodeWin32() {{{1
function! NERDTreeListNodeWin32()
let treenode = g:NERDTreeFileNode.GetSelected()
if treenode != {}
let metadata = split(system('DIR /Q ' . shellescape(treenode.path.str()) . ' | FINDSTR "^[012][0-9]/[0-3][0-9]/[12][0-9][0-9][0-9]"'), '\n')
call nerdtree#echo(metadata[0])
else
call nerdtree#echo("No information avaialable")
endif endif
endfunction endfunction
@ -221,7 +236,7 @@ function! NERDTreeCopyNode()
let confirmed = 1 let confirmed = 1
if currentNode.path.copyingWillOverwrite(newNodePath) if currentNode.path.copyingWillOverwrite(newNodePath)
call s:echo("Warning: copying may overwrite files! Continue? (yN)") call nerdtree#echo("Warning: copying may overwrite files! Continue? (yN)")
let choice = nr2char(getchar()) let choice = nr2char(getchar())
let confirmed = choice ==# 'y' let confirmed = choice ==# 'y'
endif endif
@ -230,22 +245,23 @@ function! NERDTreeCopyNode()
try try
let newNode = currentNode.copy(newNodePath) let newNode = currentNode.copy(newNodePath)
if empty(newNode) if empty(newNode)
call b:NERDTreeRoot.refresh() call b:NERDTree.root.refresh()
call b:NERDTree.render() call b:NERDTree.render()
else else
call NERDTreeRender() call NERDTreeRender()
call newNode.putCursorHere(0, 0) call newNode.putCursorHere(0, 0)
endif endif
catch /^NERDTree/ catch /^NERDTree/
call s:echoWarning("Could not copy node") call nerdtree#echoWarning("Could not copy node")
endtry endtry
endif endif
else else
call s:echo("Copy aborted.") call nerdtree#echo("Copy aborted.")
endif endif
redraw redraw
endfunction endfunction
" FUNCTION: NERDTreeQuickLook() {{{1
function! NERDTreeQuickLook() function! NERDTreeQuickLook()
let treenode = g:NERDTreeFileNode.GetSelected() let treenode = g:NERDTreeFileNode.GetSelected()
if treenode != {} if treenode != {}
@ -253,18 +269,19 @@ function! NERDTreeQuickLook()
endif endif
endfunction endfunction
" FUNCTION: NERDTreeRevealInFinder() {{{1
function! NERDTreeRevealInFinder() function! NERDTreeRevealInFinder()
let treenode = g:NERDTreeFileNode.GetSelected() let treenode = g:NERDTreeFileNode.GetSelected()
if treenode != {} if treenode != {}
let x = system("open -R '" . treenode.path.str() . "'") call system("open -R '" . treenode.path.str() . "'")
endif endif
endfunction endfunction
" FUNCTION: NERDTreeExecuteFile() {{{1
function! NERDTreeExecuteFile() function! NERDTreeExecuteFile()
let treenode = g:NERDTreeFileNode.GetSelected() let treenode = g:NERDTreeFileNode.GetSelected()
if treenode != {} if treenode != {}
let x = system("open '" . treenode.path.str() . "'") call system("open '" . treenode.path.str() . "'")
endif endif
endfunction endfunction
" vim: set sw=4 sts=4 et fdm=marker: " vim: set sw=4 sts=4 et fdm=marker:

View file

@ -1,8 +1,6 @@
" ============================================================================ " ============================================================================
" File: NERD_tree.vim " File: NERD_tree.vim
" Description: vim global plugin that provides a nice tree explorer
" Maintainer: Martin Grenfell <martin.grenfell at gmail dot com> " Maintainer: Martin Grenfell <martin.grenfell at gmail dot com>
" Last Change: 28 December, 2011
" License: This program is free software. It comes without any warranty, " License: This program is free software. It comes without any warranty,
" to the extent permitted by applicable law. You can redistribute " 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 " it and/or modify it under the terms of the Do What The Fuck You
@ -67,7 +65,14 @@ call s:initVariable("g:NERDTreeShowFiles", 1)
call s:initVariable("g:NERDTreeShowHidden", 0) call s:initVariable("g:NERDTreeShowHidden", 0)
call s:initVariable("g:NERDTreeShowLineNumbers", 0) call s:initVariable("g:NERDTreeShowLineNumbers", 0)
call s:initVariable("g:NERDTreeSortDirs", 1) call s:initVariable("g:NERDTreeSortDirs", 1)
call s:initVariable("g:NERDTreeDirArrows", !nerdtree#runningWindows())
if !nerdtree#runningWindows()
call s:initVariable("g:NERDTreeDirArrowExpandable", "▸")
call s:initVariable("g:NERDTreeDirArrowCollapsible", "▾")
else
call s:initVariable("g:NERDTreeDirArrowExpandable", "+")
call s:initVariable("g:NERDTreeDirArrowCollapsible", "~")
endif
call s:initVariable("g:NERDTreeCascadeOpenSingleChildDir", 1) call s:initVariable("g:NERDTreeCascadeOpenSingleChildDir", 1)
if !exists("g:NERDTreeSortOrder") if !exists("g:NERDTreeSortOrder")
@ -83,8 +88,8 @@ if !exists('g:NERDTreeStatusline')
"the exists() crap here is a hack to stop vim spazzing out when "the exists() crap here is a hack to stop vim spazzing out when
"loading a session that was created with an open nerd tree. It spazzes "loading a session that was created with an open nerd tree. It spazzes
"because it doesnt store b:NERDTreeRoot (its a b: var, and its a hash) "because it doesnt store b:NERDTree(its a b: var, and its a hash)
let g:NERDTreeStatusline = "%{exists('b:NERDTreeRoot')?b:NERDTreeRoot.path.str():''}" let g:NERDTreeStatusline = "%{exists('b:NERDTree')?b:NERDTree.root.path.str():''}"
endif endif
call s:initVariable("g:NERDTreeWinPos", "left") call s:initVariable("g:NERDTreeWinPos", "left")
@ -188,7 +193,7 @@ function! NERDTreeFocus()
if g:NERDTree.IsOpen() if g:NERDTree.IsOpen()
call g:NERDTree.CursorToTreeWin() call g:NERDTree.CursorToTreeWin()
else else
call g:NERDTreeCreator.TogglePrimary("") call g:NERDTreeCreator.ToggleTabTree("")
endif endif
endfunction endfunction

View file

@ -22,42 +22,19 @@ syn match NERDTreeLinkDir #.*/ ->#me=e-3 containedin=NERDTreeDir
"highlighing for directory nodes and file nodes "highlighing for directory nodes and file nodes
syn match NERDTreeDirSlash #/# containedin=NERDTreeDir syn match NERDTreeDirSlash #/# containedin=NERDTreeDir
if g:NERDTreeDirArrows exec 'syn match NERDTreeClosable #'.escape(g:NERDTreeDirArrowCollapsible, '~').'# containedin=NERDTreeDir,NERDTreeFile'
syn match NERDTreeClosable #▾# containedin=NERDTreeDir,NERDTreeFile exec 'syn match NERDTreeOpenable #'.escape(g:NERDTreeDirArrowExpandable, '~').'# containedin=NERDTreeDir,NERDTreeFile'
syn match NERDTreeOpenable #▸# containedin=NERDTreeDir,NERDTreeFile
syn match NERDTreeDir #[^▾▸ ].*/# let s:dirArrows = escape(g:NERDTreeDirArrowCollapsible, '~').escape(g:NERDTreeDirArrowExpandable, '~')
syn match NERDTreeExecFile #^ .*\*\($\| \)# contains=NERDTreeRO,NERDTreeBookmark exec 'syn match NERDTreeDir #[^'.s:dirArrows.' ].*/#'
syn match NERDTreeFile #^[^"\.▾▸] *[^▾▸]*# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmark,NERDTreeExecFile syn match NERDTreeExecFile #^ .*\*\($\| \)# contains=NERDTreeRO,NERDTreeBookmark
exec 'syn match NERDTreeFile #^[^"\.'.s:dirArrows.'] *[^'.s:dirArrows.']*# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmark,NERDTreeExecFile'
"highlighting for readonly files "highlighting for readonly files
syn match NERDTreeRO # *\zs.*\ze \[RO\]# contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreeFile syn match NERDTreeRO # *\zs.*\ze \[RO\]# contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreeFile
syn match NERDTreeFlags #^ *\zs\[.\]# containedin=NERDTreeFile syn match NERDTreeFlags #^ *\zs\[.\]# containedin=NERDTreeFile,NERDTreeExecFile
syn match NERDTreeFlags #\[.\]# containedin=NERDTreeDir syn match NERDTreeFlags #\[.\]# containedin=NERDTreeDir
else
"highlighting for the ~/+ symbols for the directory nodes
syn match NERDTreeClosable #\~\<#
syn match NERDTreeClosable #\~\.#
syn match NERDTreeOpenable #+\<#
syn match NERDTreeOpenable #+\.#he=e-1
"highlighting for the tree structural parts
syn match NERDTreePart #|#
syn match NERDTreePart #`#
syn match NERDTreePartFile #[|`]-#hs=s+1 contains=NERDTreePart
syn match NERDTreeDir #[^-| `].*/# contains=NERDTreeLink,NERDTreeOpenable,NERDTreeClosable
syn match NERDTreeExecFile #[|` ].*\*\($\| \)# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark
syn match NERDTreeFile #|-.*# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile
syn match NERDTreeFile #`-.*# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile
"highlighting for readonly files
syn match NERDTreeRO #|-.*\[RO\]#he=e-5 contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreePart,NERDTreePartFile
syn match NERDTreeFlags #-\[.\]# containedin=NERDTreeFile,NERDTreePartFile
syn match NERDTreeFlags #[+~]\zs\[.\]# containedin=NERDTreeDir
endif
syn match NERDTreeCWD #^[</].*$# syn match NERDTreeCWD #^[</].*$#

View file

@ -40,8 +40,8 @@ too:
Before you consider adding features to syntastic, _please_ spend a few Before you consider adding features to syntastic, _please_ spend a few
minutes (re-)reading the latest version of the [manual][1]. Syntastic 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 is changing rapidly at times, and it's quite possible that some features
features you want to add exist already. you want to add exist already.
To submit a patch: To submit a patch:
@ -54,7 +54,7 @@ Small, focused patches are preferred.
Large changes to the code should be discussed with the core team first. 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. Create an issue and explain your plan and see what we say.
Also make sure to update the manual whenever applicable. Nobody can use Also, make sure to update the manual whenever applicable. Nobody can use
features that aren't documented. features that aren't documented.
<a name="generalstyle"></a> <a name="generalstyle"></a>

View file

@ -35,7 +35,7 @@
4.8. [How can I pass additional arguments to a checker?](#faqargs) 4.8. [How can I pass additional arguments to a checker?](#faqargs)
4.9. [Syntastic supports several checkers for my filetype - how do I tell which one(s) to use?](#faqcheckers) 4.9. [Syntastic supports several checkers for my filetype - how do I tell which one(s) to use?](#faqcheckers)
4.10. [What is the difference between syntax checkers and style checkers?](#faqstyle) 4.10. [What is the difference between syntax checkers and style checkers?](#faqstyle)
4.11. [I have enabled multiple checkers for the current filetype. How can I display all of the errors from all of the checkers together?](#faqaggregate) 4.11. [I have enabled multiple checkers for the current filetype. How can I display all errors from all checkers together?](#faqaggregate)
4.12. [How can I jump between the different errors without using the location list at the bottom of the window?](#faqlnext) 4.12. [How can I jump between the different errors without using the location list at the bottom of the window?](#faqlnext)
4.13. [The error window is closed automatically when I :quit the current buffer but not when I :bdelete it?](#faqbdelete) 4.13. [The error window is closed automatically when I :quit the current buffer but not when I :bdelete it?](#faqbdelete)
5. [Resources](#otherresources) 5. [Resources](#otherresources)
@ -53,22 +53,23 @@ are detected, the user is notified and is happy because they didn't have to
compile their code or execute their script to find them. compile their code or execute their script to find them.
At the time of this writing, syntastic has checking plugins for ActionScript, At the time of this writing, syntastic has checking plugins for ActionScript,
Ada, API Blueprint, AppleScript, AsciiDoc, ASM, BEMHTML, Bro, Bourne shell, C, Ada, Ansible configurations, API Blueprint, AppleScript, AsciiDoc, ASM,
C++, C#, Cabal, Chef, CoffeeScript, Coco, Coq, CSS, Cucumber, CUDA, D, Dart, BEMHTML, Bro, Bourne shell, C, C++, C#, Cabal, Chef, CoffeeScript, Coco, Coq,
DocBook, Dust, Elixir, Erlang, eRuby, Fortran, Gentoo metadata, GLSL, Go, Haml, CSS, Cucumber, CUDA, D, Dart, DocBook, Dockerfile, Dust, Elixir, Erlang,
Haskell, Haxe, Handlebars, HSS, HTML, Java, JavaScript, JSON, JSX, LESS, Lex, eRuby, Fortran, Gentoo metadata, GLSL, Go, Haml, Haskell, Haxe, Handlebars,
Limbo, LISP, LLVM intermediate language, Lua, Markdown, MATLAB, Mercury, NASM, HSS, HTML, Jade, Java, JavaScript, JSON, JSX, LESS, Lex, Limbo, LISP, LLVM
Nix, Objective-C, Objective-C++, OCaml, Perl, Perl POD, PHP, gettext Portable intermediate language, Lua, Markdown, MATLAB, Mercury, NASM, Nix, Objective-C,
Object, OS X and iOS property lists, Puppet, Python, R, Racket, Relax NG, Objective-C++, OCaml, Perl, Perl POD, PHP, gettext Portable Object, OS X and
reStructuredText, RPM spec, Ruby, SASS/SCSS, Scala, Slim, SML, Sphinx, Tcl, iOS property lists, Puppet, Python, QML, R, Racket, Relax NG, reStructuredText,
TeX, Texinfo, Twig, TypeScript, Vala, Verilog, VHDL, VimL, xHtml, XML, XSLT, RPM spec, Ruby, SASS/SCSS, Scala, Slim, SML, Sphinx, SQL, Stylus, Tcl, TeX,
Texinfo, Twig, TypeScript, Vala, Verilog, VHDL, VimL, xHtml, XML, XSLT, XQuery,
YACC, YAML, z80, Zope page templates, and zsh. See the [wiki][3] for details YACC, YAML, z80, Zope page templates, and zsh. See the [wiki][3] for details
about the corresponding supported checkers. about the corresponding supported checkers.
A number of third-party Vim plugins also provide checkers for syntastic, A number of third-party Vim plugins also provide checkers for syntastic,
for example: [omnisharp-vim][25], [rust.vim][12], [syntastic-extras][26], for example: [merlin][30], [omnisharp-vim][25], [rust.vim][12],
[syntastic-more][27], [vim-crystal][29], [vim-eastwood][28], and [syntastic-extras][26], [syntastic-more][27], [vim-crystal][29],
[vim-swift][24]. [vim-eastwood][28], and [vim-swift][24].
Below is a screenshot showing the methods that Syntastic uses to display syntax Below is a screenshot showing the methods that Syntastic uses to display syntax
errors. Note that, in practise, you will only have a subset of these methods errors. Note that, in practise, you will only have a subset of these methods
@ -159,10 +160,10 @@ following:
## 3\. Recommended settings ## 3\. Recommended settings
Syntastic has a large number of options that can be configured, and the Syntastic has numerous options that can be configured, and the defaults
defaults are not particularly well suitable for new users. It is recommended are not particularly well suitable for new users. It is recommended
that you start by adding the following lines to your `vimrc` file, and return that you start by adding the following lines to your `vimrc` file, and
to them after reading the manual (see `:help syntastic` in Vim): return to them after reading the manual (see `:help syntastic` in Vim):
```vim ```vim
set statusline+=%#warningmsg# set statusline+=%#warningmsg#
set statusline+=%{SyntasticStatuslineFlag()} set statusline+=%{SyntasticStatuslineFlag()}
@ -380,7 +381,7 @@ See `:help syntastic_quiet_messages` for details.
<a name="faqaggregate"></a> <a name="faqaggregate"></a>
__4.11. Q. I have enabled multiple checkers for the current filetype. How can I __4.11. Q. I have enabled multiple checkers for the current filetype. How can I
display all of the errors from all of the checkers together?__ display all errors from all checkers together?__
A. Set `g:syntastic_aggregate_errors` to 1 in your `vimrc`: A. Set `g:syntastic_aggregate_errors` to 1 in your `vimrc`:
```vim ```vim
@ -427,7 +428,8 @@ There are also a dedicated [google group][5], and a
Syntastic aims to provide a common interface to syntax checkers for as many Syntastic aims to provide a common interface to syntax checkers for as many
languages as possible. For particular languages, there are, of course, other languages as possible. For particular languages, there are, of course, other
plugins that provide more functionality than syntastic. You might want to take plugins that provide more functionality than syntastic. You might want to take
a look at [jedi-vim][7], [python-mode][8], or [YouCompleteMe][9]. a look at [ghcmod-vim][31], [jedi-vim][7], [python-mode][8], [vim-go][32], or
[YouCompleteMe][9].
[0]: https://github.com/scrooloose/syntastic/raw/master/_assets/screenshot_1.png [0]: https://github.com/scrooloose/syntastic/raw/master/_assets/screenshot_1.png
[1]: https://github.com/tpope/vim-pathogen [1]: https://github.com/tpope/vim-pathogen
@ -459,6 +461,9 @@ a look at [jedi-vim][7], [python-mode][8], or [YouCompleteMe][9].
[27]: https://github.com/roktas/syntastic-more [27]: https://github.com/roktas/syntastic-more
[28]: https://github.com/venantius/vim-eastwood [28]: https://github.com/venantius/vim-eastwood
[29]: https://github.com/rhysd/vim-crystal [29]: https://github.com/rhysd/vim-crystal
[30]: https://github.com/the-lambda-church/merlin
[31]: https://github.com/eagletmt/ghcmod-vim
[32]: https://github.com/fatih/vim-go
<!-- <!--
vim:tw=79:sw=4: vim:tw=79:sw=4:

View file

@ -223,24 +223,7 @@ function! s:_get_cflags(ft, ck, opts) abort " {{{2
" check if the user manually set some cflags " check if the user manually set some cflags
let b_cflags = s:_get_checker_var('b', a:ft, a:ck, 'cflags', '') let b_cflags = s:_get_checker_var('b', a:ft, a:ck, 'cflags', '')
if b_cflags ==# '' if b_cflags !=# ''
if a:ft ==# 'c' || a:ft ==# 'cpp'
" check whether to search for include files at all
if !s:_get_checker_var('g', a:ft, a:ck, 'no_include_search', 0)
" refresh the include file search if desired
if s:_get_checker_var('g', a:ft, a:ck, 'auto_refresh_includes', 0)
let flags .= ' ' . s:_search_headers()
else
" search for header includes if not cached already
if !exists('b:syntastic_' . a:ft . '_includes')
let b:syntastic_{a:ft}_includes = s:_search_headers()
endif
let flags .= ' ' . b:syntastic_{a:ft}_includes
endif
endif
endif
else
" user-defined cflags
let flags .= ' ' . b_cflags let flags .= ' ' . b_cflags
endif endif
@ -248,6 +231,19 @@ function! s:_get_cflags(ft, ck, opts) abort " {{{2
let config_file = s:_get_checker_var('g', a:ft, a:ck, 'config_file', '.syntastic_' . a:ft . '_config') let config_file = s:_get_checker_var('g', a:ft, a:ck, 'config_file', '.syntastic_' . a:ft . '_config')
let flags .= ' ' . syntastic#c#ReadConfig(config_file) let flags .= ' ' . syntastic#c#ReadConfig(config_file)
if b_cflags ==# '' && (a:ft ==# 'c' || a:ft ==# 'cpp') && !s:_get_checker_var('g', a:ft, a:ck, 'no_include_search', 0)
" refresh the include file search if desired
if s:_get_checker_var('g', a:ft, a:ck, 'auto_refresh_includes', 0)
let flags .= ' ' . s:_search_headers()
else
" search for header includes if not cached already
if !exists('b:syntastic_' . a:ft . '_includes')
let b:syntastic_{a:ft}_includes = s:_search_headers()
endif
let flags .= ' ' . b:syntastic_{a:ft}_includes
endif
endif
return flags return flags
endfunction " }}}2 endfunction " }}}2

View file

@ -59,27 +59,51 @@ function! syntastic#preprocess#cppcheck(errors) abort " {{{2
return map(copy(a:errors), 'substitute(v:val, ''\v^\[[^]]+\]\zs( -\> \[[^]]+\])+\ze:'', "", "")') return map(copy(a:errors), 'substitute(v:val, ''\v^\[[^]]+\]\zs( -\> \[[^]]+\])+\ze:'', "", "")')
endfunction " }}}2 endfunction " }}}2
" @vimlint(EVL102, 1, l:true) function! syntastic#preprocess#dockerfile_lint(errors) abort " {{{2
" @vimlint(EVL102, 1, l:false) let out = []
" @vimlint(EVL102, 1, l:null) let json = s:_decode_JSON(join(a:errors, ''))
function! syntastic#preprocess#flow(errors) abort " {{{2
" JSON artifacts
let true = 1
let false = 0
let null = ''
if type(json) == type({})
try
let data = json['error']['data'] + json['warn']['data'] + json['info']['data']
for e in data
let type = toupper(e['level'][0])
if type ==# 'I'
let type = 'W'
let style = 1
else
let style = 0
endif
let line = get(e, 'line', 1)
let message = e['message']
if has_key(e, 'description') && e['description'] !=# 'None'
let message = message . '. ' . e['description']
endif
let msg =
\ type . ':' .
\ style . ':' .
\ line . ':' .
\ message
call add(out, msg)
endfor
catch /\m^Vim\%((\a\+)\)\=:E716/
call syntastic#log#warn('checker dockerfile/dockerfile_lint: unrecognized error format')
let out = []
endtry
else
call syntastic#log#warn('checker dockerfile/dockerfile_lint: unrecognized error format')
endif
return out
endfunction " }}}2
function! syntastic#preprocess#flow(errors) abort " {{{2
let idx = 0 let idx = 0
while idx < len(a:errors) && a:errors[idx][0] != '{' while idx < len(a:errors) && a:errors[idx][0] !=# '{'
let idx += 1 let idx += 1
endwhile endwhile
let errs = s:_decode_JSON(join(a:errors[idx :], ''))
" A hat tip to Marc Weber for this trick
" http://stackoverflow.com/questions/17751186/iterating-over-a-string-in-vimscript-or-parse-a-json-file/19105763#19105763
try
let errs = eval(join(a:errors[idx :], ''))
catch
let errs = {}
endtry
let out = [] let out = []
if type(errs) == type({}) && has_key(errs, 'errors') && type(errs['errors']) == type([]) if type(errs) == type({}) && has_key(errs, 'errors') && type(errs['errors']) == type([])
@ -108,33 +132,61 @@ function! syntastic#preprocess#flow(errors) abort " {{{2
call add(out, msg) call add(out, msg)
catch /\m^Vim\%((\a\+)\)\=:E716/ catch /\m^Vim\%((\a\+)\)\=:E716/
call syntastic#log#warn('checker javascript/flow: unknown error format') call syntastic#log#warn('checker javascript/flow: unrecognized error format')
let out = [] let out = []
break break
endtry endtry
else else
call syntastic#log#warn('checker javascript/flow: unknown error format') call syntastic#log#warn('checker javascript/flow: unrecognized error format')
let out = [] let out = []
break break
endif endif
endfor endfor
else else
call syntastic#log#warn('checker javascript/flow: unknown error format') call syntastic#log#warn('checker javascript/flow: unrecognized error format')
endif endif
return out return out
endfunction " }}}2 endfunction " }}}2
" @vimlint(EVL102, 0, l:true)
" @vimlint(EVL102, 0, l:false)
" @vimlint(EVL102, 0, l:null)
function! syntastic#preprocess#iconv(errors) abort " {{{2 function! syntastic#preprocess#iconv(errors) abort " {{{2
return return
\ (has('iconv') || has('iconv/dyn')) && &encoding !=# '' && &encoding !=# 'utf-8' ? \ has('iconv') && &encoding !=# '' && &encoding !=# 'utf-8' ?
\ map(a:errors, 'iconv(v:val, "utf-8", &encoding)') : \ map(a:errors, 'iconv(v:val, "utf-8", &encoding)') :
\ a:errors \ a:errors
endfunction " }}}2 endfunction " }}}2
function! syntastic#preprocess#jscs(errors) abort " {{{2
let errs = join(a:errors, '')
if errs ==# ''
return []
endif
let json = s:_decode_JSON(errs)
let out = []
if type(json) == type({})
for fname in keys(json)
if type(json[fname]) == type([])
for e in json[fname]
try
let e['message'] = substitute(e['message'], "\n", ' ', 'g')
cal add(out, fname . ':' . e['line'] . ':' . e['column'] . ':' . e['message'])
catch /\m^Vim\%((\a\+)\)\=:E716/
call syntastic#log#warn('checker javascript/jscs: unrecognized error item ' . string(e))
let out = []
endtry
endfor
else
call syntastic#log#warn('checker javascript/jscs: unrecognized error format')
endif
endfor
else
call syntastic#log#warn('checker javascript/jscs: unrecognized error format')
endif
return out
endfunction " }}}2
function! syntastic#preprocess#killEmpty(errors) abort " {{{2 function! syntastic#preprocess#killEmpty(errors) abort " {{{2
return filter(copy(a:errors), 'v:val !=# ""') return filter(copy(a:errors), 'v:val !=# ""')
endfunction " }}}2 endfunction " }}}2
@ -152,22 +204,8 @@ function! syntastic#preprocess#perl(errors) abort " {{{2
return syntastic#util#unique(out) return syntastic#util#unique(out)
endfunction " }}}2 endfunction " }}}2
" @vimlint(EVL102, 1, l:true)
" @vimlint(EVL102, 1, l:false)
" @vimlint(EVL102, 1, l:null)
function! syntastic#preprocess#prospector(errors) abort " {{{2 function! syntastic#preprocess#prospector(errors) abort " {{{2
" JSON artifacts let errs = s:_decode_JSON(join(a:errors, ''))
let true = 1
let false = 0
let null = ''
" A hat tip to Marc Weber for this trick
" http://stackoverflow.com/questions/17751186/iterating-over-a-string-in-vimscript-or-parse-a-json-file/19105763#19105763
try
let errs = eval(join(a:errors, ''))
catch
let errs = {}
endtry
let out = [] let out = []
if type(errs) == type({}) && has_key(errs, 'messages') if type(errs) == type({}) && has_key(errs, 'messages')
@ -189,26 +227,23 @@ function! syntastic#preprocess#prospector(errors) abort " {{{2
call add(out, msg) call add(out, msg)
catch /\m^Vim\%((\a\+)\)\=:E716/ catch /\m^Vim\%((\a\+)\)\=:E716/
call syntastic#log#warn('checker python/prospector: unknown error format') call syntastic#log#warn('checker python/prospector: unrecognized error format')
let out = [] let out = []
break break
endtry endtry
else else
call syntastic#log#warn('checker python/prospector: unknown error format') call syntastic#log#warn('checker python/prospector: unrecognized error format')
let out = [] let out = []
break break
endif endif
endfor endfor
else else
call syntastic#log#warn('checker python/prospector: unknown error format') call syntastic#log#warn('checker python/prospector: unrecognized error format')
endif endif
endif endif
return out return out
endfunction " }}}2 endfunction " }}}2
" @vimlint(EVL102, 0, l:true)
" @vimlint(EVL102, 0, l:false)
" @vimlint(EVL102, 0, l:null)
function! syntastic#preprocess#rparse(errors) abort " {{{2 function! syntastic#preprocess#rparse(errors) abort " {{{2
let errlist = copy(a:errors) let errlist = copy(a:errors)
@ -249,6 +284,43 @@ function! syntastic#preprocess#rparse(errors) abort " {{{2
return out return out
endfunction " }}}2 endfunction " }}}2
function! syntastic#preprocess#stylelint(errors) abort " {{{2
let out = []
" CssSyntaxError: /path/to/file.css:2:11: Missed semicolon
let parts = matchlist(a:errors[0], '\v^CssSyntaxError: (.{-1,}):(\d+):(\d+): (.+)')
if len(parts) > 4
call add(out, 'E:' . join(parts[1:4], ':'))
else
let errs = s:_decode_JSON(join(a:errors, ''))
let out = []
if type(errs) == type([]) && len(errs) == 1 && type(errs[0]) == type({}) &&
\ has_key(errs[0], 'source') && has_key(errs[0], 'warnings') && type(errs[0]['warnings']) == type([])
for e in errs[0]['warnings']
try
let severity = type(e['severity']) == type(0) ? ['W', 'E'][e['severity']-1] : e['severity'][0]
let msg =
\ severity . ':' .
\ errs[0]['source'] . ':' .
\ e['line'] . ':' .
\ e['column'] . ':' .
\ e['text']
call add(out, msg)
catch /\m^Vim\%((\a\+)\)\=:E716/
call syntastic#log#warn('checker css/stylelint: unrecognized error item ' . string(e))
let out = []
break
endtry
endfor
else
call syntastic#log#warn('checker css/stylelint: unrecognized error format')
endif
endif
return out
endfunction " }}}2
function! syntastic#preprocess#tslint(errors) abort " {{{2 function! syntastic#preprocess#tslint(errors) abort " {{{2
return map(copy(a:errors), 'substitute(v:val, ''\m^\(([^)]\+)\)\s\(.\+\)$'', ''\2 \1'', "")') return map(copy(a:errors), 'substitute(v:val, ''\m^\(([^)]\+)\)\s\(.\+\)$'', ''\2 \1'', "")')
endfunction " }}}2 endfunction " }}}2
@ -268,22 +340,8 @@ function! syntastic#preprocess#validator(errors) abort " {{{2
return out return out
endfunction " }}}2 endfunction " }}}2
" @vimlint(EVL102, 1, l:true)
" @vimlint(EVL102, 1, l:false)
" @vimlint(EVL102, 1, l:null)
function! syntastic#preprocess#vint(errors) abort " {{{2 function! syntastic#preprocess#vint(errors) abort " {{{2
" JSON artifacts let errs = s:_decode_JSON(join(a:errors, ''))
let true = 1
let false = 0
let null = ''
" A hat tip to Marc Weber for this trick
" http://stackoverflow.com/questions/17751186/iterating-over-a-string-in-vimscript-or-parse-a-json-file/19105763#19105763
try
let errs = eval(join(a:errors, ''))
catch
let errs = []
endtry
let out = [] let out = []
if type(errs) == type([]) if type(errs) == type([])
@ -300,22 +358,166 @@ function! syntastic#preprocess#vint(errors) abort " {{{2
call add(out, msg) call add(out, msg)
catch /\m^Vim\%((\a\+)\)\=:E716/ catch /\m^Vim\%((\a\+)\)\=:E716/
call syntastic#log#warn('checker vim/vint: unknown error format') call syntastic#log#warn('checker vim/vint: unrecognized error format')
let out = [] let out = []
break break
endtry endtry
else else
call syntastic#log#warn('checker vim/vint: unknown error format') call syntastic#log#warn('checker vim/vint: unrecognized error format')
let out = [] let out = []
break break
endif endif
endfor endfor
else else
call syntastic#log#warn('checker vim/vint: unknown error format') call syntastic#log#warn('checker vim/vint: unrecognized error format')
endif endif
return out return out
endfunction " }}}2 endfunction " }}}2
" }}}1
" Workarounds {{{1
" In errorformat, \ or % following %f make it depend on isfname. The default
" setting of isfname is crafted to work with completion, rather than general
" filename matching. The result for syntastic is that filenames containing
" spaces (or a few other special characters) can't be matched.
"
" Fixing isfname to address this problem would depend on the set of legal
" characters for filenames on the filesystem the project's files lives on.
" Inferring the kind of filesystem a file lives on, in advance to parsing the
" file's name, is an interesting problem (think f.i. a file loaded from a VFAT
" partition, mounted on Linux). A problem syntastic is not prepared to solve.
"
" As a result, the functions below exist for the only reason to avoid using
" things like %f\, in errorformat.
"
" References:
" https://groups.google.com/forum/#!topic/vim_dev/pTKmZmouhio
" https://vimhelp.appspot.com/quickfix.txt.html#error-file-format
function! syntastic#preprocess#basex(errors) abort " {{{2
let out = []
let idx = 0
while idx < len(a:errors)
let parts = matchlist(a:errors[idx], '\v^\[\S+\] Stopped at (.+), (\d+)/(\d+):')
if len(parts) > 3
let err = parts[1] . ':' . parts[2] . ':' . parts[3] . ':'
let parts = matchlist(a:errors[idx+1], '\v^\[(.)\D+(\d+)\] (.+)')
if len(parts) > 3
let err .= (parts[1] ==? 'W' || parts[1] ==? 'E' ? parts[1] : 'E') . ':' . parts[2] . ':' . parts[3]
call add(out, err)
let idx +=1
endif
elseif a:errors[idx] =~# '\m^\['
" unparseable errors
call add(out, a:errors[idx])
endif
let idx +=1
endwhile
return out
endfunction " }}}2
function! syntastic#preprocess#bro(errors) abort " {{{2
let out = []
for e in a:errors
let parts = matchlist(e, '\v^%(fatal )?(error|warning) in (.{-1,}), line (\d+): (.+)')
if len(parts) > 4
let parts[1] = parts[1][0]
call add(out, join(parts[1:4], ':'))
endif
endfor
return out
endfunction " }}}2
function! syntastic#preprocess#coffeelint(errors) abort " {{{2
let out = []
for e in a:errors
let parts = matchlist(e, '\v^(.{-1,}),(\d+)%(,\d*)?,(error|warn),(.+)')
if len(parts) > 4
let parts[3] = parts[3][0]
call add(out, join(parts[1:4], ':'))
endif
endfor
return out
endfunction " }}}2
function! syntastic#preprocess#mypy(errors) abort " {{{2
let out = []
for e in a:errors
" new format
let parts = matchlist(e, '\v^(.{-1,}):(\d+): error: (.+)')
if len(parts) > 3
call add(out, join(parts[1:3], ':'))
continue
endif
" old format
let parts = matchlist(e, '\v^(.{-1,}), line (\d+): (.+)')
if len(parts) > 3
call add(out, join(parts[1:3], ':'))
endif
endfor
return out
endfunction " }}}2
function! syntastic#preprocess#nix(errors) abort " {{{2
let out = []
for e in a:errors
let parts = matchlist(e, '\v^(.{-1,}), at (.{-1,}):(\d+):(\d+)$')
if len(parts) > 4
call add(out, join(parts[2:4], ':') . ':' . parts[1])
continue
endif
let parts = matchlist(e, '\v^(.{-1,}) at (.{-1,}), line (\d+):')
if len(parts) > 3
call add(out, parts[2] . ':' . parts[3] . ':' . parts[1])
continue
endif
let parts = matchlist(e, '\v^error: (.{-1,}), in (.{-1,})$')
if len(parts) > 2
call add(out, parts[2] . ':' . parts[1])
endif
endfor
return out
endfunction " }}}2
" }}}1
" Private functions {{{1
" @vimlint(EVL102, 1, l:true)
" @vimlint(EVL102, 1, l:false)
" @vimlint(EVL102, 1, l:null)
function! s:_decode_JSON(json) abort " {{{2
if a:json ==# ''
return []
endif
" The following is inspired by https://github.com/MarcWeber/vim-addon-manager and
" http://stackoverflow.com/questions/17751186/iterating-over-a-string-in-vimscript-or-parse-a-json-file/19105763#19105763
" A hat tip to Marc Weber for this trick
if substitute(a:json, '\v\"%(\\.|[^"\\])*\"|true|false|null|[+-]?\d+%(\.\d+%([Ee][+-]?\d+)?)?', '', 'g') !~# "[^,:{}[\\] \t]"
" JSON artifacts
let true = 1
let false = 0
let null = ''
try
let object = eval(a:json)
catch
" malformed JSON
let object = ''
endtry
else
let object = ''
endif
return object
endfunction " }}}2
" @vimlint(EVL102, 0, l:true) " @vimlint(EVL102, 0, l:true)
" @vimlint(EVL102, 0, l:false) " @vimlint(EVL102, 0, l:false)
" @vimlint(EVL102, 0, l:null) " @vimlint(EVL102, 0, l:null)

View file

@ -107,16 +107,16 @@ function! syntastic#util#rmrf(what) abort " {{{2
endif endif
endfunction " }}}2 endfunction " }}}2
"search the first 5 lines of the file for a magic number and return a map " Search the first 5 lines of the file for a magic number and return a map
"containing the args and the executable " containing the args and the executable
" "
"e.g. " e.g.
" "
"#!/usr/bin/perl -f -bar " #!/usr/bin/perl -f -bar
" "
"returns " returns
" "
"{'exe': '/usr/bin/perl', 'args': ['-f', '-bar']} " {'exe': '/usr/bin/perl', 'args': ['-f', '-bar']}
function! syntastic#util#parseShebang() abort " {{{2 function! syntastic#util#parseShebang() abort " {{{2
for lnum in range(1, 5) for lnum in range(1, 5)
let line = getline(lnum) let line = getline(lnum)
@ -183,7 +183,7 @@ function! syntastic#util#screenWidth(str, tabstop) abort " {{{2
return width return width
endfunction " }}}2 endfunction " }}}2
"print as much of a:msg as possible without "Press Enter" prompt appearing " Print as much of a:msg as possible without "Press Enter" prompt appearing
function! syntastic#util#wideMsg(msg) abort " {{{2 function! syntastic#util#wideMsg(msg) abort " {{{2
let old_ruler = &ruler let old_ruler = &ruler
let old_showcmd = &showcmd let old_showcmd = &showcmd
@ -226,7 +226,7 @@ function! syntastic#util#bufIsActive(buffer) abort " {{{2
return 0 return 0
endfunction " }}}2 endfunction " }}}2
" start in directory a:where and walk up the parent folders until it finds a " Start in directory a:where and walk up the parent folders until it finds a
" file named a:what; return path to that file " file named a:what; return path to that file
function! syntastic#util#findFileInParent(what, where) abort " {{{2 function! syntastic#util#findFileInParent(what, where) abort " {{{2
let old_suffixesadd = &suffixesadd let old_suffixesadd = &suffixesadd
@ -236,7 +236,7 @@ function! syntastic#util#findFileInParent(what, where) abort " {{{2
return file return file
endfunction " }}}2 endfunction " }}}2
" start in directory a:where and walk up the parent folders until it finds a " Start in directory a:where and walk up the parent folders until it finds a
" file matching a:what; return path to that file " file matching a:what; return path to that file
function! syntastic#util#findGlobInParent(what, where) abort " {{{2 function! syntastic#util#findGlobInParent(what, where) abort " {{{2
let here = fnamemodify(a:where, ':p') let here = fnamemodify(a:where, ':p')
@ -303,7 +303,7 @@ function! syntastic#util#argsescape(opt) abort " {{{2
return [] return []
endfunction " }}}2 endfunction " }}}2
" decode XML entities " Decode XML entities
function! syntastic#util#decodeXMLEntities(string) abort " {{{2 function! syntastic#util#decodeXMLEntities(string) abort " {{{2
let str = a:string let str = a:string
let str = substitute(str, '\m&lt;', '<', 'g') let str = substitute(str, '\m&lt;', '<', 'g')
@ -339,6 +339,87 @@ function! syntastic#util#stamp() abort " {{{2
return split( split(reltimestr(reltime(g:_SYNTASTIC_START)))[0], '\.' ) return split( split(reltimestr(reltime(g:_SYNTASTIC_START)))[0], '\.' )
endfunction " }}}2 endfunction " }}}2
let s:_wid_base = 'syntastic_' . getpid() . '_' . reltimestr(g:_SYNTASTIC_START) . '_'
let s:_wid_pool = 0
" Add unique IDs to windows
function! syntastic#util#setWids() abort " {{{2
for tab in range(1, tabpagenr('$'))
for win in range(1, tabpagewinnr(tab, '$'))
if gettabwinvar(tab, win, 'syntastic_wid') ==# ''
call settabwinvar(tab, win, 'syntastic_wid', s:_wid_base . s:_wid_pool)
let s:_wid_pool += 1
endif
endfor
endfor
endfunction " }}}2
let s:_str2float = function(exists('*str2float') ? 'str2float' : 'str2nr')
lockvar s:_str2float
function! syntastic#util#str2float(val) abort " {{{2
return s:_str2float(a:val)
endfunction " }}}2
function! syntastic#util#float2str(val) abort " {{{2
return s:_float2str(a:val)
endfunction " }}}2
" Crude printf()-like width formatter. Handles wide characters.
function! syntastic#util#wformat(format, str) abort " {{{2
if a:format ==# ''
return a:str
endif
echomsg string(a:format) . ', ' . string(a:str)
let specs = matchlist(a:format, '\v^(-?)(0?)(%([1-9]\d*))?%(\.(\d+))?$')
if len(specs) < 5
return a:str
endif
let flushleft = specs[1] ==# '-'
let lpad = specs[2] ==# '0' ? '0' : ' '
let minlen = str2nr(specs[3])
let maxlen = str2nr(specs[4])
let out = substitute(a:str, "\t", ' ', 'g')
if maxlen && s:_width(out) > maxlen
let chars = filter(split(out, '\zs\ze', 1), 'v:val !=# ""')
let out = ''
if flushleft
for c in chars
if s:_width(out . c) < maxlen
let out .= c
else
let out .= &encoding ==# 'utf-8' && &termencoding ==# 'utf-8' ? "\u2026" : '>'
break
endif
endfor
else
call reverse(chars)
for c in chars
if s:_width(c . out) < maxlen
let out = c . out
else
let out = (&encoding ==# 'utf-8' && &termencoding ==# 'utf-8' ? "\u2026" : '<') . out
break
endif
endfor
endif
endif
if minlen && s:_width(out) < minlen
if flushleft
let out .= repeat(' ', minlen - s:_width(out))
else
let out = repeat(lpad, minlen - s:_width(out)) . out
endif
endif
return out
endfunction " }}}2
" }}}1 " }}}1
" Private functions {{{1 " Private functions {{{1
@ -416,6 +497,17 @@ function! s:_rmrf(what) abort " {{{2
endif endif
endfunction " }}}2 endfunction " }}}2
function! s:_float2str_smart(val) abort " {{{2
return printf('%.1f', a:val)
endfunction " }}}2
function! s:_float2str_dumb(val) abort " {{{2
return a:val
endfunction " }}}2
let s:_float2str = function(has('float') ? 's:_float2str_smart' : 's:_float2str_dumb')
lockvar s:_float2str
" }}}1 " }}}1
let &cpo = s:save_cpo let &cpo = s:save_cpo

View file

@ -54,7 +54,7 @@ CONTENTS *syntastic-contents*
7.10.vim-go................................|syntastic-vim-go| 7.10.vim-go................................|syntastic-vim-go|
7.11.vim-virtualenv........................|syntastic-vim-virtualenv| 7.11.vim-virtualenv........................|syntastic-vim-virtualenv|
7.12.YouCompleteMe.........................|syntastic-ycm| 7.12.YouCompleteMe.........................|syntastic-ycm|
7.13.The zsh shell and rvm.................|syntastic-zsh| 7.13.The zsh shell and MacVim..............|syntastic-zsh|
8.About........................................|syntastic-about| 8.About........................................|syntastic-about|
9.License......................................|syntastic-license| 9.License......................................|syntastic-license|
@ -86,7 +86,7 @@ checker integrations, see the guide on the GitHub wiki:
1.1. Quick start *syntastic-quickstart* 1.1. Quick start *syntastic-quickstart*
Syntastic comes preconfigured with a default list of enabled checkers per Syntastic comes preconfigured with a default list of enabled checkers per
filetype. This list is kept reasonably short to prevent slowing down Vim or |filetype|. This list is kept reasonably short to prevent slowing down Vim or
trying to use conflicting checkers. trying to use conflicting checkers.
You can see the list of checkers available for the current filetype with the You can see the list of checkers available for the current filetype with the
@ -110,10 +110,10 @@ these commands, or perhaps install a plugin such as Tim Pope's 'unimpaired'
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
1.2. Recommended settings *syntastic-recommended* 1.2. Recommended settings *syntastic-recommended*
Syntastic has a large number of options that can be configured, and the Syntastic has numerous options that can be configured, and the defaults are
defaults are not particularly well suitable for new users. It is recommended not particularly well suitable for new users. It is recommended that you start
that you start by adding the following lines to your vimrc, and return to them by adding the following lines to your vimrc, and return to them later as
later as needed: > needed: >
set statusline+=%#warningmsg# set statusline+=%#warningmsg#
set statusline+=%{SyntasticStatuslineFlag()} set statusline+=%{SyntasticStatuslineFlag()}
set statusline+=%* set statusline+=%*
@ -161,13 +161,13 @@ is derived from the |syntastic_stl_format| option.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
2.2. Error signs *syntastic-error-signs* 2.2. Error signs *syntastic-error-signs*
Syntastic uses the |:sign| commands to mark lines with errors and warnings in Syntastic uses the |:sign| commands (provided that the |+signs| feature is
the sign column. To enable this feature, use the |'syntastic_enable_signs'| compiled in) to mark lines with errors and warnings in the sign column. To
option. enable this feature, use the |'syntastic_enable_signs'| option.
Signs are colored using the Error and Todo syntax highlight groups by default. Signs are colored using the Error and Todo syntax highlight groups by default
If you wish to customize the colors for the signs, you can use the following (see |group-name|). If you wish to customize the colors for the signs, you
groups: can use the following groups:
SyntasticErrorSign - For syntax errors, links to 'error' by default SyntasticErrorSign - For syntax errors, links to 'error' by default
SyntasticWarningSign - For syntax warnings, links to 'todo' by default SyntasticWarningSign - For syntax warnings, links to 'todo' by default
SyntasticStyleErrorSign - For style errors, links to 'SyntasticErrorSign' SyntasticStyleErrorSign - For style errors, links to 'SyntasticErrorSign'
@ -194,17 +194,13 @@ Example: >
You can use the |:Errors| command to display the errors for the current buffer You can use the |:Errors| command to display the errors for the current buffer
in the |location-list|. in the |location-list|.
Note that when you use |:Errors| the current location list is overwritten with
Syntastic's own location list. The location list is also overwritten when
|syntastic_auto_jump| is non-zero and the cursor has to jump to an issue.
By default syntastic doesn't fill the |location-list| with the errors found by By default syntastic doesn't fill the |location-list| with the errors found by
the checkers, in order to reduce clashes with other plugins. Consequently, if the checkers, in order to reduce clashes with other plugins. Consequently, if
you run |:lopen| or |:lwindow| rather than |:Errors| to open the error window you you run |:lopen| or |:lwindow| rather than |:Errors| to open the error window
wouldn't see syntastic's list of errors. If you insist on using |:lopen| or you wouldn't see syntastic's list of errors. If you insist on using |:lopen|
|:lwindow| you should either run |:SyntasticSetLoclist| after running the checks, or |:lwindow| you should either run |:SyntasticSetLoclist| after running the
or set |syntastic_always_populate_loc_list| which tells syntastic to update the checks, or set |syntastic_always_populate_loc_list| which tells syntastic to
|location-list| automatically. update the |location-list| automatically.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
2.4. Error highlighting *syntastic-highlighting* 2.4. Error highlighting *syntastic-highlighting*
@ -251,7 +247,8 @@ You can selectively disable some of the errors found by checkers either
using |'syntastic_quiet_messages'|, or by specifying a list of patterns in using |'syntastic_quiet_messages'|, or by specifying a list of patterns in
|'syntastic_ignore_files'|. |'syntastic_ignore_files'|.
See also: |'syntastic_<filetype>_<checker>_quiet_messages'|. See also: |'syntastic_<filetype>_<checker>_quiet_messages'| and
|'b:syntastic_skip_checks'|.
============================================================================== ==============================================================================
3. Commands *syntastic-commands* 3. Commands *syntastic-commands*
@ -273,15 +270,15 @@ for more info.
Manually cause a syntax check to be done. By default the checkers in the Manually cause a syntax check to be done. By default the checkers in the
|'g:syntastic_<filetype>_checkers'| or |'b:syntastic_checkers'| lists are run, |'g:syntastic_<filetype>_checkers'| or |'b:syntastic_checkers'| lists are run,
cf. |syntastic-filetype-checkers|. If |syntastic_aggregate_errors| is unset cf. |syntastic-filetype-checkers|. If |'syntastic_aggregate_errors'| is unset
(which is the default), checking stops the first time a checker reports any (which is the default), checking stops the first time a checker reports any
errors; if |syntastic_aggregate_errors| is set, all checkers that apply are run errors; if |'syntastic_aggregate_errors'| is set, all checkers that apply are
in turn, and all errors found are aggregated in a single list. run in turn, and all errors found are aggregated in a single list.
The command may be followed by a (space separated) list of checkers. In this The command may be followed by a (space separated) list of checkers. In this
case |'g:syntastic_<filetype>_checkers'| and |'b:syntastic_checkers'| are case |'g:syntastic_<filetype>_checkers'| and |'b:syntastic_checkers'| are
ignored, and the checkers named by the command's arguments are run instead, in ignored, and the checkers named by the command's arguments are run instead, in
the order specified. The rules of |syntastic_aggregate_errors| still apply. the order specified. The set by |'syntastic_aggregate_errors'| still apply.
Example: > Example: >
:SyntasticCheck flake8 pylint :SyntasticCheck flake8 pylint
@ -301,24 +298,23 @@ Resets the list of errors and turns off all error notifiers.
If |'syntastic_always_populate_loc_list'| is not set, the |location-list| is If |'syntastic_always_populate_loc_list'| is not set, the |location-list| is
not filled in automatically with the list of errors detected by the checkers. not filled in automatically with the list of errors detected by the checkers.
This is useful if you run syntastic along with other plugins that use location This is useful if you run syntastic along with other plugins that use location
lists. The |:SyntasticSetLoclist| command allows you to stick the errors into lists. The |:SyntasticSetLoclist| command allows you to stick the errors into
the location list explicitly. the location list explicitly.
============================================================================== ==============================================================================
4. Global Options *syntastic-global-options* 4. Global Options *syntastic-global-options*
*'syntastic_check_on_open'* *'syntastic_check_on_open'*
Default: 0 Default: 0
If enabled, syntastic will do syntax checks when buffers are first loaded as If this variable is enabled, syntastic in active mode will run syntax checks
well as on saving > when buffers are first loaded, as well as on saving: >
let g:syntastic_check_on_open = 1 let g:syntastic_check_on_open = 1
< <
*'syntastic_check_on_wq'* *'syntastic_check_on_wq'*
Default: 1 Default: 1
Normally syntastic runs syntax checks whenever buffers are written to disk. In active mode syntax checks are normally run whenever buffers are written to
If you want to skip these checks when you issue |:wq|, |:x|, and |:ZZ|, set this disk, even when the writes happen just before quitting Vim. If you want to
variable to 0. > skip checks when you issue |:wq|, |:x|, and |:ZZ|, set this variable to 0: >
let g:syntastic_check_on_wq = 0 let g:syntastic_check_on_wq = 0
< <
*'syntastic_aggregate_errors'* *'syntastic_aggregate_errors'*
@ -332,36 +328,37 @@ time a checker finds any errors. >
*'syntastic_id_checkers'* *'syntastic_id_checkers'*
Default: 1 Default: 1
When results from multiple checkers are aggregated in a single error list When results from multiple checkers are aggregated in a single error list
(that is either when |syntastic_aggregate_errors| is enabled, or when checking (that is either when |'syntastic_aggregate_errors'| is enabled, or when
a file with a composite filetype), it might not be immediately obvious which checking a file with a composite filetype), it might not be immediately
checker has produced a given error message. This variable instructs syntastic obvious which checker has produced a given error message. This variable
to label error messages with the names of the checkers that created them. > instructs syntastic to label error messages with the names of the checkers
that created them. >
let g:syntastic_id_checkers = 0 let g:syntastic_id_checkers = 0
< <
*'syntastic_sort_aggregated_errors'* *'syntastic_sort_aggregated_errors'*
Default: 1 Default: 1
By default, when results from multiple checkers are aggregated in a single By default, when results from multiple checkers are aggregated in a single
error list (that is either when |syntastic_aggregate_errors| is enabled, or error list (that is either when |'syntastic_aggregate_errors'| is enabled,
when checking a file with a composite filetype), errors are grouped by file, or when checking a file with a composite filetype), errors are grouped by
then sorted by line number, then grouped by type (namely errors take precedence file, then sorted by line number, then grouped by type (namely errors take
over warnings), then they are sorted by column number. If you want to leave precedence over warnings), then they are sorted by column number. If you want
messages grouped by checker output, set this variable to 0. > to leave messages grouped by checker output, set this variable to 0: >
let g:syntastic_sort_aggregated_errors = 0 let g:syntastic_sort_aggregated_errors = 0
< <
*'syntastic_echo_current_error'* *'syntastic_echo_current_error'*
Default: 1 Default: 1
If enabled, syntastic will echo current error to the command window. If 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 multiple errors are found on the same line, |'syntastic_cursor_columns'| is
to decide which one is shown. > used to decide which one is shown. >
let g:syntastic_echo_current_error = 1 let g:syntastic_echo_current_error = 1
< <
*'syntastic_cursor_columns'* *'syntastic_cursor_columns'*
Default: 1 Default: 1
This option controls which errors are echoed to the command window if 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 |'syntastic_echo_current_error'| is set and multiple errors are found on the
line. When the option is enabled, the first error corresponding to the current same line. When the option is enabled, the first error corresponding to the
column is show. Otherwise, the first error on the current line is echoed, current column is shown. Otherwise, the first error on the current line is
regardless of the cursor position on the current line. echoed, regardless of the cursor position on the current line.
When dealing with very large lists of errors, disabling this option can speed When dealing with very large lists of errors, disabling this option can speed
up navigation significantly: > up navigation significantly: >
@ -402,10 +399,17 @@ errors (where possible). Highlighting can be turned off with the following >
< <
*'syntastic_always_populate_loc_list'* *'syntastic_always_populate_loc_list'*
Default: 0 Default: 0
Enable this option to tell syntastic to always stick any detected errors into By default syntastic doesn't fill the |location-list| with the errors found
the |location-list|: > by the checkers, in order to reduce clashes with other plugins. Enable this
option to tell syntastic to always stick any detected errors into the
|location-list|: >
let g:syntastic_always_populate_loc_list = 1 let g:syntastic_always_populate_loc_list = 1
< <
Please note that if |'syntastic_auto_jump'| is set to a non-zero value the
location list is overwritten with Syntastic's own list when taking a jump,
regardless of the value of |'syntastic_always_populate_loc_list'|. The
location list is also overwritten when running the |:Errors| command.
*'syntastic_auto_jump'* *'syntastic_auto_jump'*
Default: 0 Default: 0
Enable this option if you want the cursor to jump to the first detected issue Enable this option if you want the cursor to jump to the first detected issue
@ -426,12 +430,17 @@ When set to 3 the cursor will jump to the first error detected, if any. If
all issues detected are warnings, the cursor won't jump. > all issues detected are warnings, the cursor won't jump. >
let g:syntastic_auto_jump = 3 let g:syntastic_auto_jump = 3
< <
Please note that in either situation taking the jump also has the side effect
of the location list being overwritten with Syntastic's own location list,
regardless of the value of |'syntastic_always_populate_loc_list'|.
*'syntastic_auto_loc_list'* *'syntastic_auto_loc_list'*
Default: 2 Default: 2
Use this option to tell syntastic to automatically open and/or close the Use this option to tell syntastic to automatically open and/or close the
|location-list| (see |syntastic-error-window|). |location-list| (see |syntastic-error-window|).
When set to 0 the error window will not be opened or closed automatically. > When set to 0 the error window will be neither opened nor closed
automatically. >
let g:syntastic_auto_loc_list = 0 let g:syntastic_auto_loc_list = 0
< <
When set to 1 the error window will be automatically opened when errors are When set to 1 the error window will be automatically opened when errors are
@ -441,6 +450,10 @@ detected, and closed when none are detected. >
When set to 2 the error window will be automatically closed when no errors are When set to 2 the error window will be automatically closed when no errors are
detected, but not opened automatically. > detected, but not opened automatically. >
let g:syntastic_auto_loc_list = 2 let g:syntastic_auto_loc_list = 2
<
When set to 3 the error window will be automatically opened when errors are
detected, but not closed automatically. >
let g:syntastic_auto_loc_list = 3
< <
*'syntastic_loc_list_height'* *'syntastic_loc_list_height'*
Default: 10 Default: 10
@ -452,8 +465,8 @@ opens. >
Default: [] Default: []
Use this option to specify files that syntastic should never check. It's a Use this option to specify files that syntastic should never check. It's a
list of |regular-expression| patterns. The full paths of files (see |::p|) are list of |regular-expression| patterns. The full paths of files (see |::p|) are
matched against these patterns, and the matches are case sensitive. Use |\c| matched against these patterns, and the matches are case-sensitive. Use |\c|
to specify case insensitive patterns. Example: > to specify case-insensitive patterns. Example: >
let g:syntastic_ignore_files = ['\m^/usr/include/', '\m\c\.h$'] let g:syntastic_ignore_files = ['\m^/usr/include/', '\m\c\.h$']
< <
*'syntastic_filetype_map'* *'syntastic_filetype_map'*
@ -528,10 +541,10 @@ overriding filters, cf. |filter-overrides|).
"level" - takes one of two values, "warnings" or "errors" "level" - takes one of two values, "warnings" or "errors"
"type" - can be either "syntax" or "style" "type" - can be either "syntax" or "style"
"regex" - is matched against the messages' text as a case insensitive "regex" - is matched against the messages' text as a case-insensitive
|regular-expression| |regular-expression|
"file" - is matched against the filenames the messages refer to, as a "file" - is matched against the filenames the messages refer to, as a
case sensitive |regular-expression|. case-sensitive |regular-expression|.
If a key is prefixed by an exclamation mark "!", the corresponding filter is If a key is prefixed by an exclamation mark "!", the corresponding filter is
negated (i.e. the above example silences all messages that are NOT errors). negated (i.e. the above example silences all messages that are NOT errors).
@ -565,12 +578,25 @@ ones produced by "pylint": >
Default: [Syntax: line:%F (%t)] Default: [Syntax: line:%F (%t)]
Use this option to control what the syntastic statusline text contains. Several Use this option to control what the syntastic statusline text contains. Several
magic flags are available to insert information: magic flags are available to insert information:
%e - number of errors %e - number of errors
%w - number of warnings %w - number of warnings
%t - total number of warnings and errors %t - total number of warnings and errors
%ne - filename of file containing first error
%nw - filename of file containing first warning
%N - filename of file containing first warning or error
%pe - filename with path of file containing first error
%pw - filename with path of file containing first warning
%P - filename with path of file containing first warning or error
%fe - line number of first error %fe - line number of first error
%fw - line number of first warning %fw - line number of first warning
%F - line number of first warning or error %F - line number of first warning or error
These flags accept width and alignment controls similar to the ones used by
|'statusline'| flags:
%-0{minwid}.{maxwid}{flag}
All fields except {flag} are optional. A single percent sign can be given as
"%%".
Several additional flags are available to hide text under certain conditions: Several additional flags are available to hide text under certain conditions:
%E{...} - hide the text in the brackets unless there are errors %E{...} - hide the text in the brackets unless there are errors
@ -612,7 +638,6 @@ The above variable can be used to disable exit code checks in syntastic.
*'syntastic_shell'* *'syntastic_shell'*
Default: Vim's 'shell' Default: Vim's 'shell'
This is the (full path to) the shell syntastic will use to run the checkers. This is the (full path to) the shell syntastic will use to run the checkers.
On UNIX and Mac OS-X this shell must accept Bourne-compatible syntax for On UNIX and Mac OS-X this shell must accept Bourne-compatible syntax for
file "stdout" and "stderr" redirections ">file" and "2>file". Examples of file "stdout" and "stderr" redirections ">file" and "2>file". Examples of
@ -624,6 +649,13 @@ operations. It must take care to initialize all environment variables needed
by the checkers you're using. Example: > by the checkers you're using. Example: >
let g:syntastic_shell = "/bin/sh" let g:syntastic_shell = "/bin/sh"
< <
*'syntastic_nested_autocommands'*
Default: 0
Controls whether syntastic's autocommands |BufReadPost| and |BufWritePost|
are called from other |BufReadPost| and |BufWritePost| autocommands (see
|autocmd-nested|). This is known to trigger interoperability problems with
other plugins, so only enable it if you actually need that functionality.
*'syntastic_debug'* *'syntastic_debug'*
Default: 0 Default: 0
Set this to the sum of one or more of the following flags to enable Set this to the sum of one or more of the following flags to enable
@ -780,7 +812,7 @@ this variable, that takes precedence over it in the buffers where it is
defined. defined.
For aggregated lists (see |syntastic-aggregating-errors|) these variables are For aggregated lists (see |syntastic-aggregating-errors|) these variables are
ignored if |syntastic_sort_aggregated_errors| is set (which is the default). ignored if |'syntastic_sort_aggregated_errors'| is set (which is the default).
============================================================================== ==============================================================================
6. Notes *syntastic-notes* 6. Notes *syntastic-notes*
@ -792,7 +824,7 @@ Some Vim plugins use composite filetypes, such as "django.python" or
"handlebars.html". Normally, syntastic deals with this situation by splitting "handlebars.html". Normally, syntastic deals with this situation by splitting
the filetype in its simple components, and calling all checkers that apply. the filetype in its simple components, and calling all checkers that apply.
If this behaviour is not desirable, you can disable it by mapping the If this behaviour is not desirable, you can disable it by mapping the
composite filetypes to a simple ones using |syntastic_filetype_map|, e.g.: > composite filetypes to simple ones using |'syntastic_filetype_map'|, e.g.: >
let g:syntastic_filetype_map = { "handlebars.html": "handlebars" } let g:syntastic_filetype_map = { "handlebars.html": "handlebars" }
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
@ -809,7 +841,7 @@ checkers, without any translation or conversion.
The 'shellslash' option is relevant only on Windows systems. This option The 'shellslash' option is relevant only on Windows systems. This option
determines (among other things) the rules for quoting command lines, and there determines (among other things) the rules for quoting command lines, and there
is no easy way for syntastic to make sure its state is appropriate for your is no easy way for syntastic to make sure its state is appropriate for your
shell. It should be turned off if your 'shell' (or |g:syntastic_shell|) is shell. It should be turned off if your 'shell' (or |'syntastic_shell'|) is
"cmd.exe", and on for shells that expect an UNIX-like syntax, such as Cygwin's "cmd.exe", and on for shells that expect an UNIX-like syntax, such as Cygwin's
"sh". Most checkers will stop working if 'shellslash' is set to the wrong "sh". Most checkers will stop working if 'shellslash' is set to the wrong
value. value.
@ -832,7 +864,7 @@ quickfix windows.
The "csh" and "tcsh" shells are mostly compatible with syntastic. However, The "csh" and "tcsh" shells are mostly compatible with syntastic. However,
some checkers assume Bourne shell syntax for redirecting "stderr". For this some checkers assume Bourne shell syntax for redirecting "stderr". For this
reason, you should point |g:syntastic_shell| to a Bourne-compatible shell, reason, you should point |'syntastic_shell'| to a Bourne-compatible shell,
such as "zsh", "bash", "ksh", or even the original Bourne "sh": > such as "zsh", "bash", "ksh", or even the original Bourne "sh": >
let g:syntastic_shell = "/bin/sh" let g:syntastic_shell = "/bin/sh"
< <
@ -854,7 +886,7 @@ details.
At the time of this writing the "fish" shell (see http://fishshell.com/) At the time of this writing the "fish" shell (see http://fishshell.com/)
doesn't support the standard UNIX syntax for file redirections, and thus it doesn't support the standard UNIX syntax for file redirections, and thus it
can't be used together with syntastic. You can however set |g:syntastic_shell| can't be used together with syntastic. You can however set |'syntastic_shell'|
to a more traditional shell, such as "zsh", "bash", "ksh", or even the to a more traditional shell, such as "zsh", "bash", "ksh", or even the
original Bourne "sh": > original Bourne "sh": >
let g:syntastic_shell = "/bin/sh" let g:syntastic_shell = "/bin/sh"
@ -915,9 +947,9 @@ Syntastic can be used along with the "python-mode" Vim plugin (see
https://github.com/klen/python-mode). However, they both run syntax checks by https://github.com/klen/python-mode). However, they both run syntax checks by
default when you save buffers to disk, and this is probably not what you want. default when you save buffers to disk, and this is probably not what you want.
To avoid both plugins opening error windows, you can either set passive mode To avoid both plugins opening error windows, you can either set passive mode
for python in syntastic (see |syntastic_mode_map|), or disable lint checks in for python in syntastic (see |'syntastic_mode_map'|), or disable lint checks in
"python-mode", by setting |pymode_lint_write| to 0. E.g.: > "python-mode", by setting |pymode_lint_on_write| to 0. E.g.: >
let g:pymode_lint_write = 0 let g:pymode_lint_on_write = 0
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
7.9. vim-auto-save *syntastic-vim-auto-save* 7.9. vim-auto-save *syntastic-vim-auto-save*
@ -929,14 +961,12 @@ mode only work with "vim-auto-save" version 0.1.7 or later.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
7.10. vim-go *syntastic-vim-go* 7.10. vim-go *syntastic-vim-go*
The "vim-go" Vim plugin (https://github.com/fatih/vim-go) uses |quickfix| Syntastic can be used along with the "vim-go" Vim plugin (see
lists, and thus doesn't conflict with syntastic (which uses |location-list| https://github.com/fatih/vim-go). However, both "vim-go" and syntastic run
lists). However, both "vim-go" and syntastic run syntax checks by default syntax checks by default when you save buffers to disk. To avoid conflicts,
when you save buffers to disk, and this can have confusing results. To you have to either set passive mode in syntastic for the go filetype (see
avoid both plugins opening error windows, you can either set passive |syntastic_mode_map|), or prevent "vim-go" from showing a quickfix window when
mode for go in syntastic (see |syntastic_mode_map|), or prevent "vim-go" |g:go_fmt_command| fails, by setting |g:go_fmt_fail_silently| to 1. E.g.: >
from showing a quickfix window when |g:go_fmt_command| fails, by setting
|g:go_fmt_fail_silently| to 1. E.g.: >
let g:go_fmt_fail_silently = 1 let g:go_fmt_fail_silently = 1
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
@ -955,20 +985,19 @@ http://valloric.github.io/YouCompleteMe/). However, by default "YouCompleteMe"
disables syntastic's checkers for the "c", "cpp", "objc", and "objcpp" 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 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 identifier completer but still run syntastic's checkers for those filetypes you
have to set |ycm_show_diagnostics_ui| to 0. E.g.: > have to set |g:ycm_show_diagnostics_ui| to 0. E.g.: >
let g:ycm_show_diagnostics_ui = 0 let g:ycm_show_diagnostics_ui = 0
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
7.13 The zsh shell and rvm *syntastic-zsh* 7.13 The zsh shell and MacVim *syntastic-zsh*
If you're running MacVim together with the "zsh" shell (http://www.zsh.org/) If you're running MacVim together with the "zsh" shell (http://www.zsh.org/)
and "rvm" (https://rvm.io/), you need to be aware that MacVim does not source you need to be aware that MacVim does not source your .zshrc file, but will
the .zshrc file, but will source a .zshenv file. Consequently you have to source a .zshenv file. Consequently you have to move any setup steps relevant
either source the "rvm" scripts from within .zshenv, or just change your shell to the checkers you're using from .zshrc to .zshenv, otherwise your checkers
to something else: > will misbehave when run by syntastic. This is particularly important for
set shell=/bin/sh programs such as "rvm" (https://rvm.io/) or "rbenv" (http://rbenv.org/), that
< rely on setting environment variables.
Of course, you'll have to make sure "rvm" still works in the new shell.
============================================================================== ==============================================================================
8. About *syntastic-about* 8. About *syntastic-about*

View file

@ -9,7 +9,7 @@
" "
"============================================================================ "============================================================================
if exists('g:loaded_syntastic_plugin') if exists('g:loaded_syntastic_plugin') || &compatible
finish finish
endif endif
let g:loaded_syntastic_plugin = 1 let g:loaded_syntastic_plugin = 1
@ -19,11 +19,16 @@ if has('reltime')
lockvar! g:_SYNTASTIC_START lockvar! g:_SYNTASTIC_START
endif endif
let g:_SYNTASTIC_VERSION = '3.6.0-122' let g:_SYNTASTIC_VERSION = '3.7.0-69'
lockvar g:_SYNTASTIC_VERSION lockvar g:_SYNTASTIC_VERSION
" Sanity checks {{{1 " Sanity checks {{{1
if v:version < 700 || (v:version == 700 && !has('patch175'))
call syntastic#log#error('need Vim version 7.0.175 or later')
finish
endif
for s:feature in [ for s:feature in [
\ 'autocmd', \ 'autocmd',
\ 'eval', \ 'eval',
@ -87,6 +92,7 @@ let g:_SYNTASTIC_DEFAULTS = {
\ 'ignore_extensions': '\c\v^([gx]?z|lzma|bz2)$', \ 'ignore_extensions': '\c\v^([gx]?z|lzma|bz2)$',
\ 'ignore_files': [], \ 'ignore_files': [],
\ 'loc_list_height': 10, \ 'loc_list_height': 10,
\ 'nested_autocommands': 0,
\ 'quiet_messages': {}, \ 'quiet_messages': {},
\ 'reuse_loc_lists': 0, \ 'reuse_loc_lists': 0,
\ 'shell': &shell, \ 'shell': &shell,
@ -130,7 +136,7 @@ let s:_DEBUG_DUMP_OPTIONS = [
\ 'shelltemp', \ 'shelltemp',
\ 'shellxquote' \ 'shellxquote'
\ ] \ ]
if v:version > 703 || (v:version == 703 && has('patch446')) if exists('+shellxescape')
call add(s:_DEBUG_DUMP_OPTIONS, 'shellxescape') call add(s:_DEBUG_DUMP_OPTIONS, 'shellxescape')
endif endif
lockvar! s:_DEBUG_DUMP_OPTIONS lockvar! s:_DEBUG_DUMP_OPTIONS
@ -157,6 +163,8 @@ let s:registry = g:SyntasticRegistry.Instance()
let s:notifiers = g:SyntasticNotifiers.Instance() let s:notifiers = g:SyntasticNotifiers.Instance()
let s:modemap = g:SyntasticModeMap.Instance() let s:modemap = g:SyntasticModeMap.Instance()
let s:_quit_pre = []
" Commands {{{1 " Commands {{{1
" @vimlint(EVL103, 1, a:cursorPos) " @vimlint(EVL103, 1, a:cursorPos)
@ -184,12 +192,15 @@ endfunction " }}}2
" @vimlint(EVL103, 0, a:cmdLine) " @vimlint(EVL103, 0, a:cmdLine)
" @vimlint(EVL103, 0, a:argLead) " @vimlint(EVL103, 0, a:argLead)
command! -nargs=* -complete=custom,s:CompleteCheckerName SyntasticCheck call SyntasticCheck(<f-args>) command! -bar -nargs=* -complete=custom,s:CompleteCheckerName SyntasticCheck call SyntasticCheck(<f-args>)
command! -nargs=? -complete=custom,s:CompleteFiletypes SyntasticInfo call SyntasticInfo(<f-args>) command! -bar -nargs=? -complete=custom,s:CompleteFiletypes SyntasticInfo call SyntasticInfo(<f-args>)
command! Errors call SyntasticErrors() command! -bar Errors call SyntasticErrors()
command! SyntasticReset call SyntasticReset() command! -bar SyntasticReset call SyntasticReset()
command! SyntasticToggleMode call SyntasticToggleMode() command! -bar SyntasticToggleMode call SyntasticToggleMode()
command! SyntasticSetLoclist call SyntasticSetLoclist() command! -bar SyntasticSetLoclist call SyntasticSetLoclist()
command! SyntasticJavacEditClasspath runtime! syntax_checkers/java/*.vim | SyntasticJavacEditClasspath
command! SyntasticJavacEditConfig runtime! syntax_checkers/java/*.vim | SyntasticJavacEditConfig
" }}}1 " }}}1
@ -231,15 +242,26 @@ endfunction " }}}2
" Autocommands {{{1 " Autocommands {{{1
augroup syntastic augroup syntastic
autocmd BufReadPost * call s:BufReadPostHook() autocmd!
autocmd BufWritePost * call s:BufWritePostHook() autocmd BufEnter * call s:BufEnterHook()
autocmd BufEnter * call s:BufEnterHook()
augroup END augroup END
if v:version > 703 || (v:version == 703 && has('patch544')) if g:syntastic_nested_autocommands
augroup syntastic
autocmd BufReadPost * nested call s:BufReadPostHook()
autocmd BufWritePost * nested call s:BufWritePostHook()
augroup END
else
augroup syntastic
autocmd BufReadPost * call s:BufReadPostHook()
autocmd BufWritePost * call s:BufWritePostHook()
augroup END
endif
if exists('##QuitPre')
" QuitPre was added in Vim 7.3.544 " QuitPre was added in Vim 7.3.544
augroup syntastic augroup syntastic
autocmd QuitPre * call s:QuitPreHook() autocmd QuitPre * call s:QuitPreHook(expand('<amatch>', 1))
augroup END augroup END
endif endif
@ -276,10 +298,15 @@ function! s:BufEnterHook() abort " {{{2
endif endif
endfunction " }}}2 endfunction " }}}2
function! s:QuitPreHook() abort " {{{2 function! s:QuitPreHook(fname) abort " {{{2
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_AUTOCOMMANDS, let buf = bufnr(fnameescape(a:fname))
\ 'autocmd: QuitPre, buffer ' . bufnr('') . ' = ' . string(bufname(str2nr(bufnr(''))))) call syntastic#log#debug(g:_SYNTASTIC_DEBUG_AUTOCOMMANDS, 'autocmd: QuitPre, buffer ' . buf . ' = ' . string(a:fname))
let b:syntastic_skip_checks = get(b:, 'syntastic_skip_checks', 0) || !syntastic#util#var('check_on_wq')
if !syntastic#util#var('check_on_wq')
call syntastic#util#setWids()
call add(s:_quit_pre, buf . '_' . getbufvar(buf, 'changetick') . '_' . w:syntastic_wid)
endif
if get(w:, 'syntastic_loclist_set', 0) if get(w:, 'syntastic_loclist_set', 0)
call SyntasticLoclistHide() call SyntasticLoclistHide()
endif endif
@ -296,17 +323,23 @@ function! s:UpdateErrors(auto_invoked, checker_names) abort " {{{2
call syntastic#log#debugDump(g:_SYNTASTIC_DEBUG_VARIABLES) call syntastic#log#debugDump(g:_SYNTASTIC_DEBUG_VARIABLES)
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_TRACE, 'UpdateErrors' . (a:auto_invoked ? ' (auto)' : '') . call syntastic#log#debug(g:_SYNTASTIC_DEBUG_TRACE, 'UpdateErrors' . (a:auto_invoked ? ' (auto)' : '') .
\ ': ' . (len(a:checker_names) ? join(a:checker_names) : 'default checkers')) \ ': ' . (len(a:checker_names) ? join(a:checker_names) : 'default checkers'))
call s:modemap.synch()
if s:_skip_file() if s:_skip_file()
return return
endif endif
call s:modemap.synch()
let run_checks = !a:auto_invoked || s:modemap.doAutoChecking() let run_checks = !a:auto_invoked || s:modemap.doAutoChecking()
if run_checks if run_checks
call s:CacheErrors(a:checker_names) call s:CacheErrors(a:checker_names)
unlockvar! b:syntastic_changedtick unlockvar! b:syntastic_changedtick
let b:syntastic_changedtick = b:changedtick let b:syntastic_changedtick = b:changedtick
lockvar! b:syntastic_changedtick lockvar! b:syntastic_changedtick
else
if a:auto_invoked
return
endif
endif endif
let loclist = g:SyntasticLoclist.current() let loclist = g:SyntasticLoclist.current()
@ -477,6 +510,7 @@ function! SyntasticMake(options) abort " {{{2
if has_key(a:options, 'errorformat') if has_key(a:options, 'errorformat')
let &errorformat = a:options['errorformat'] let &errorformat = a:options['errorformat']
set errorformat<
endif endif
if has_key(a:options, 'cwd') if has_key(a:options, 'cwd')
@ -610,11 +644,26 @@ function! s:_ignore_file(filename) abort " {{{2
return 0 return 0
endfunction " }}}2 endfunction " }}}2
function! s:_is_quitting(buf) abort " {{{2
let quitting = 0
if exists('w:syntastic_wid')
let key = a:buf . '_' . getbufvar(a:buf, 'changetick') . '_' . w:syntastic_wid
let idx = index(s:_quit_pre, key)
if idx >= 0
call remove(s:_quit_pre, idx)
let quitting = 1
endif
endif
return quitting
endfunction " }}}2
" Skip running in special buffers " Skip running in special buffers
function! s:_skip_file() abort " {{{2 function! s:_skip_file() abort " {{{2
let fname = expand('%', 1) let fname = expand('%', 1)
let skip = get(b:, 'syntastic_skip_checks', 0) || (&buftype !=# '') || let skip = s:_is_quitting(bufnr('%')) || get(b:, 'syntastic_skip_checks', 0) ||
\ !filereadable(fname) || getwinvar(0, '&diff') || s:_ignore_file(fname) || \ (&buftype !=# '') || !filereadable(fname) || getwinvar(0, '&diff') ||
\ getwinvar(0, '&previewwindow') || s:_ignore_file(fname) ||
\ fnamemodify(fname, ':e') =~? g:syntastic_ignore_extensions \ fnamemodify(fname, ':e') =~? g:syntastic_ignore_extensions
if skip if skip
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_TRACE, '_skip_file: skipping checks') call syntastic#log#debug(g:_SYNTASTIC_DEBUG_TRACE, '_skip_file: skipping checks')
@ -628,6 +677,9 @@ function! s:_explain_skip(filetypes) abort " {{{2
let why = [] let why = []
let fname = expand('%', 1) let fname = expand('%', 1)
if s:_is_quitting(bufnr('%'))
call add(why, 'quitting buffer')
endif
if get(b:, 'syntastic_skip_checks', 0) if get(b:, 'syntastic_skip_checks', 0)
call add(why, 'b:syntastic_skip_checks set') call add(why, 'b:syntastic_skip_checks set')
endif endif
@ -640,6 +692,9 @@ function! s:_explain_skip(filetypes) abort " {{{2
if getwinvar(0, '&diff') if getwinvar(0, '&diff')
call add(why, 'diff mode') call add(why, 'diff mode')
endif endif
if getwinvar(0, '&previewwindow')
call add(why, 'preview window')
endif
if s:_ignore_file(fname) if s:_ignore_file(fname)
call add(why, 'filename matching g:syntastic_ignore_files') call add(why, 'filename matching g:syntastic_ignore_files')
endif endif

View file

@ -19,13 +19,13 @@ endfunction " }}}2
function! g:SyntasticAutoloclistNotifier.AutoToggle(loclist) abort " {{{2 function! g:SyntasticAutoloclistNotifier.AutoToggle(loclist) abort " {{{2
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_NOTIFICATIONS, 'autoloclist: toggle') call syntastic#log#debug(g:_SYNTASTIC_DEBUG_NOTIFICATIONS, 'autoloclist: toggle')
let auto_loc_list = syntastic#util#var('auto_loc_list')
if !a:loclist.isEmpty() if !a:loclist.isEmpty()
if syntastic#util#var('auto_loc_list') == 1 if auto_loc_list == 1 || auto_loc_list == 3
call a:loclist.show() call a:loclist.show()
endif endif
else else
if syntastic#util#var('auto_loc_list') > 0 if auto_loc_list == 1 || auto_loc_list == 2
"TODO: this will close the loc list window if one was opened by "TODO: this will close the loc list window if one was opened by
"something other than syntastic "something other than syntastic
lclose lclose

View file

@ -7,26 +7,36 @@ let g:SyntasticChecker = {}
" Public methods {{{1 " Public methods {{{1
function! g:SyntasticChecker.New(args) abort " {{{2 function! g:SyntasticChecker.New(args, ...) abort " {{{2
let newObj = copy(self) let newObj = copy(self)
let newObj._filetype = a:args['filetype'] let newObj._filetype = a:args['filetype']
let newObj._name = a:args['name'] let newObj._name = a:args['name']
let newObj._exec = get(a:args, 'exec', newObj._name)
if has_key(a:args, 'redirect') if a:0
let [filetype, name] = split(a:args['redirect'], '/') " redirected checker
let newObj._exec = get(a:args, 'exec', a:1['_exec'])
let filetype = a:1['_filetype']
let name = a:1['_name']
let prefix = 'SyntaxCheckers_' . filetype . '_' . name . '_' let prefix = 'SyntaxCheckers_' . filetype . '_' . name . '_'
if exists('g:syntastic_' . filetype . '_' . name . '_sort') && !exists('g:syntastic_' . newObj._filetype . '_' . newObj._name . '_sort') if exists('g:syntastic_' . filetype . '_' . name . '_sort') && !exists('g:syntastic_' . newObj._filetype . '_' . newObj._name . '_sort')
let g:syntastic_{newObj._filetype}_{newObj._name}_sort = g:syntastic_{filetype}_{name}_sort let g:syntastic_{newObj._filetype}_{newObj._name}_sort = g:syntastic_{filetype}_{name}_sort
endif endif
else
let prefix = 'SyntaxCheckers_' . newObj._filetype . '_' . newObj._name . '_'
endif
if has_key(a:args, 'enable') if has_key(a:args, 'enable')
let newObj._enable = a:args['enable'] let newObj._enable = a:args['enable']
elseif has_key(a:1, '_enable')
let newObj._enable = a:1['_enable']
endif
else
let newObj._exec = get(a:args, 'exec', newObj._name)
let prefix = 'SyntaxCheckers_' . newObj._filetype . '_' . newObj._name . '_'
if has_key(a:args, 'enable')
let newObj._enable = a:args['enable']
endif
endif endif
let newObj._locListFunc = function(prefix . 'GetLocList') let newObj._locListFunc = function(prefix . 'GetLocList')
@ -85,6 +95,11 @@ function! g:SyntasticChecker.getLocListRaw() abort " {{{2
if has_key(self, '_enable') if has_key(self, '_enable')
let status = syntastic#util#var(self._enable, -1) let status = syntastic#util#var(self._enable, -1)
if type(status) != type(0)
call syntastic#log#error('checker ' . name . ': invalid value ' . strtrans(string(status)) .
\ ' for g:syntastic_' . self._enable . '; try 0 or 1 instead')
return []
endif
if status < 0 if status < 0
call syntastic#log#error('checker ' . name . ': checks disabled for security reasons; ' . call syntastic#log#error('checker ' . name . ': checks disabled for security reasons; ' .
\ 'set g:syntastic_' . self._enable . ' to 1 to override') \ 'set g:syntastic_' . self._enable . ' to 1 to override')

View file

@ -110,19 +110,21 @@ function! g:SyntasticLoclist.getStatuslineFlag() abort " {{{2
"hide stuff wrapped in %B(...) unless there are both errors and warnings "hide stuff wrapped in %B(...) unless there are both errors and warnings
let output = substitute(output, '\m\C%B{\([^}]*\)}', (num_warnings && num_errors) ? '\1' : '' , 'g') let output = substitute(output, '\m\C%B{\([^}]*\)}', (num_warnings && num_errors) ? '\1' : '' , 'g')
"sub in the total errors/warnings/both let flags = {
let output = substitute(output, '\m\C%w', num_warnings, 'g') \ '%': '%',
let output = substitute(output, '\m\C%e', num_errors, 'g') \ 't': num_issues,
let output = substitute(output, '\m\C%t', num_issues, 'g') \ 'e': num_errors,
\ 'w': num_warnings,
"first error/warning line num \ 'N': (num_issues ? fnamemodify( bufname(self._rawLoclist[0]['bufnr']), ':t') : ''),
let output = substitute(output, '\m\C%F', num_issues ? self._rawLoclist[0]['lnum'] : '', 'g') \ 'P': (num_issues ? fnamemodify( bufname(self._rawLoclist[0]['bufnr']), ':p:~:.') : ''),
\ 'F': (num_issues ? self._rawLoclist[0]['lnum'] : ''),
"first error line num \ 'ne': (num_errors ? fnamemodify( bufname(errors[0]['bufnr']), ':t') : ''),
let output = substitute(output, '\m\C%fe', num_errors ? errors[0]['lnum'] : '', 'g') \ 'pe': (num_errors ? fnamemodify( bufname(errors[0]['bufnr']), ':p:~:.') : ''),
\ 'fe': (num_errors ? errors[0]['lnum'] : ''),
"first warning line num \ 'nw': (num_warnings ? fnamemodify( bufname(warnings[0]['bufnr']), ':t') : ''),
let output = substitute(output, '\m\C%fw', num_warnings ? warnings[0]['lnum'] : '', 'g') \ 'pw': (num_warnings ? fnamemodify( bufname(warnings[0]['bufnr']), ':p:~:.') : ''),
\ 'fw': (num_warnings ? warnings[0]['lnum'] : '') }
let output = substitute(output, '\v\C\%(-?\d*%(\.\d+)?)([npf][ew]|[NPFtew%])', '\=syntastic#util#wformat(submatch(1), flags[submatch(2)])', 'g')
let self._stl_flag = output let self._stl_flag = output
else else

View file

@ -8,7 +8,8 @@ let g:loaded_syntastic_registry = 1
let s:_DEFAULT_CHECKERS = { let s:_DEFAULT_CHECKERS = {
\ 'actionscript': ['mxmlc'], \ 'actionscript': ['mxmlc'],
\ 'ada': ['gcc'], \ 'ada': ['gcc'],
\ 'apiblueprint': ['snowcrash'], \ 'ansible': ['ansible_lint'],
\ 'apiblueprint': ['drafter'],
\ 'applescript': ['osacompile'], \ 'applescript': ['osacompile'],
\ 'asciidoc': ['asciidoc'], \ 'asciidoc': ['asciidoc'],
\ 'asm': ['gcc'], \ 'asm': ['gcc'],
@ -29,6 +30,7 @@ let s:_DEFAULT_CHECKERS = {
\ 'd': ['dmd'], \ 'd': ['dmd'],
\ 'dart': ['dartanalyzer'], \ 'dart': ['dartanalyzer'],
\ 'docbk': ['xmllint'], \ 'docbk': ['xmllint'],
\ 'dockerfile': ['dockerfile_lint'],
\ 'dustjs': ['swiffer'], \ 'dustjs': ['swiffer'],
\ 'elixir': [], \ 'elixir': [],
\ 'erlang': ['escript'], \ 'erlang': ['escript'],
@ -42,6 +44,7 @@ let s:_DEFAULT_CHECKERS = {
\ 'haxe': ['haxe'], \ 'haxe': ['haxe'],
\ 'hss': ['hss'], \ 'hss': ['hss'],
\ 'html': ['tidy'], \ 'html': ['tidy'],
\ 'jade': ['jade_lint'],
\ 'java': ['javac'], \ 'java': ['javac'],
\ 'javascript': ['jshint', 'jslint'], \ 'javascript': ['jshint', 'jslint'],
\ 'json': ['jsonlint', 'jsonval'], \ 'json': ['jsonlint', 'jsonval'],
@ -66,7 +69,9 @@ let s:_DEFAULT_CHECKERS = {
\ 'pod': ['podchecker'], \ 'pod': ['podchecker'],
\ 'puppet': ['puppet', 'puppetlint'], \ 'puppet': ['puppet', 'puppetlint'],
\ 'python': ['python', 'flake8', 'pylint'], \ 'python': ['python', 'flake8', 'pylint'],
\ 'qml': ['qmllint'],
\ 'r': [], \ 'r': [],
\ 'rmd': [],
\ 'racket': ['racket'], \ 'racket': ['racket'],
\ 'rnc': ['rnv'], \ 'rnc': ['rnv'],
\ 'rst': ['rst2pseudoxml'], \ 'rst': ['rst2pseudoxml'],
@ -78,6 +83,8 @@ let s:_DEFAULT_CHECKERS = {
\ 'slim': ['slimrb'], \ 'slim': ['slimrb'],
\ 'sml': ['smlnj'], \ 'sml': ['smlnj'],
\ 'spec': ['rpmlint'], \ 'spec': ['rpmlint'],
\ 'sql': ['sqlint'],
\ 'stylus': ['stylint'],
\ 'tcl': ['nagelfar'], \ 'tcl': ['nagelfar'],
\ 'tex': ['lacheck', 'chktex'], \ 'tex': ['lacheck', 'chktex'],
\ 'texinfo': ['makeinfo'], \ 'texinfo': ['makeinfo'],
@ -91,6 +98,7 @@ let s:_DEFAULT_CHECKERS = {
\ 'xhtml': ['tidy'], \ 'xhtml': ['tidy'],
\ 'xml': ['xmllint'], \ 'xml': ['xmllint'],
\ 'xslt': ['xmllint'], \ 'xslt': ['xmllint'],
\ 'xquery': ['basex'],
\ 'yacc': ['bison'], \ 'yacc': ['bison'],
\ 'yaml': ['jsyaml'], \ 'yaml': ['jsyaml'],
\ 'z80': ['z80syntaxchecker'], \ 'z80': ['z80syntaxchecker'],
@ -151,8 +159,21 @@ function! g:SyntasticRegistry.Instance() abort " {{{2
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticRegistry.CreateAndRegisterChecker(args) abort " {{{2 function! g:SyntasticRegistry.CreateAndRegisterChecker(args) abort " {{{2
let checker = g:SyntasticChecker.New(a:args)
let registry = g:SyntasticRegistry.Instance() let registry = g:SyntasticRegistry.Instance()
if has_key(a:args, 'redirect')
let [ft, name] = split(a:args['redirect'], '/')
call registry._loadCheckersFor(ft)
let clone = get(registry._checkerMap[ft], name, {})
if empty(clone)
throw 'Syntastic: Checker ' . a:args['redirect'] . ' redirects to unregistered checker ' . ft . '/' . name
endif
let checker = g:SyntasticChecker.New(a:args, clone)
else
let checker = g:SyntasticChecker.New(a:args)
endif
call registry._registerChecker(checker) call registry._registerChecker(checker)
endfunction " }}}2 endfunction " }}}2
@ -187,7 +208,7 @@ function! g:SyntasticRegistry.getCheckersAvailable(ftalias, hints_list) abort "
return filter(self.getCheckers(a:ftalias, a:hints_list), 'v:val.isAvailable()') return filter(self.getCheckers(a:ftalias, a:hints_list), 'v:val.isAvailable()')
endfunction " }}}2 endfunction " }}}2
" Same as getCheckers(), but keep only the checkers tyhat are available and " Same as getCheckers(), but keep only the checkers that are available and
" disabled. This runs the corresponding IsAvailable() functions for all checkers. " disabled. This runs the corresponding IsAvailable() functions for all checkers.
function! g:SyntasticRegistry.getCheckersDisabled(ftalias, hints_list) abort " {{{2 function! g:SyntasticRegistry.getCheckersDisabled(ftalias, hints_list) abort " {{{2
return filter(self.getCheckers(a:ftalias, a:hints_list), 'v:val.isDisabled() && v:val.isAvailable()') return filter(self.getCheckers(a:ftalias, a:hints_list), 'v:val.isDisabled() && v:val.isAvailable()')

View file

@ -0,0 +1,52 @@
"============================================================================
"File: ansible_lint.vim
"Description: Syntax checking plugin for syntastic.vim
"Maintainer: Erik Zaadi <erik.zaadi at gmail dot com>
"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_ansible_ansible_lint_checker')
finish
endif
let g:loaded_syntastic_ansible_ansible_lint_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_ansible_ansible_lint_IsAvailable() dict
if !executable(self.getExec())
return 0
endif
return syntastic#util#versionIsAtLeast(self.getVersion(), [2, 0, 4])
endfunction
function! SyntaxCheckers_ansible_ansible_lint_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args_after': '-p' })
let errorformat = '%f:%l: [ANSIBLE%n] %m'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'env': env,
\ 'defaults': {'type': 'E'},
\ 'subtype': 'Style',
\ 'returns': [0, 2] })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'ansible',
\ 'name': 'ansible_lint',
\ 'exec': 'ansible-lint'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -1,5 +1,5 @@
"============================================================================ "============================================================================
"File: snowcrash.vim "File: drafter.vim
"Description: Syntax checking plugin for syntastic.vim "Description: Syntax checking plugin for syntastic.vim
"Maintainer: LCD 47 <lcd047 at gmail dot com> "Maintainer: LCD 47 <lcd047 at gmail dot com>
"License: This program is free software. It comes without any warranty, "License: This program is free software. It comes without any warranty,
@ -10,19 +10,19 @@
" "
"============================================================================ "============================================================================
if exists('g:loaded_syntastic_apiblueprint_snowcrash_checker') if exists('g:loaded_syntastic_apiblueprint_drafter_checker')
finish finish
endif endif
let g:loaded_syntastic_apiblueprint_snowcrash_checker = 1 let g:loaded_syntastic_apiblueprint_drafter_checker = 1
if !exists('g:syntastic_apiblueprint_snowcrash_sort') if !exists('g:syntastic_apiblueprint_drafter_sort')
let g:syntastic_apiblueprint_snowcrash_sort = 1 let g:syntastic_apiblueprint_drafter_sort = 1
endif endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_apiblueprint_snowcrash_GetLocList() dict function! SyntaxCheckers_apiblueprint_drafter_GetLocList() dict
let makeprg = self.makeprgBuild({ 'post_args': '-u -l' }) let makeprg = self.makeprgBuild({ 'post_args': '-u -l' })
let errorformat = let errorformat =
@ -34,7 +34,7 @@ function! SyntaxCheckers_apiblueprint_snowcrash_GetLocList() dict
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'defaults': {'bufnr': bufnr('')}, \ 'defaults': {'bufnr': bufnr('')},
\ 'returns': [0, 2] }) \ 'returns': [0, 2, 3, 4] })
for e in loclist for e in loclist
let matches = matchlist(e['text'], '\v^(.+); line (\d+), column (\d+) - line (\d+), column (\d+)$') let matches = matchlist(e['text'], '\v^(.+); line (\d+), column (\d+) - line (\d+), column (\d+)$')
@ -58,7 +58,7 @@ endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'apiblueprint', \ 'filetype': 'apiblueprint',
\ 'name': 'snowcrash'}) \ 'name': 'drafter'})
let &cpo = s:save_cpo let &cpo = s:save_cpo
unlet s:save_cpo unlet s:save_cpo

View file

@ -19,6 +19,10 @@ if !exists('g:syntastic_asm_compiler_options')
let g:syntastic_asm_compiler_options = '' let g:syntastic_asm_compiler_options = ''
endif endif
if !exists('g:syntastic_asm_generic')
let g:syntastic_asm_generic = 0
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
@ -36,14 +40,13 @@ function! SyntaxCheckers_asm_gcc_GetLocList() dict " {{{1
\ '%f:%l:%c: %trror: %m,' . \ '%f:%l:%c: %trror: %m,' .
\ '%f:%l:%c: %tarning: %m,' . \ '%f:%l:%c: %tarning: %m,' .
\ '%f:%l: %m', \ '%f:%l: %m',
\ 'main_flags': '-x assembler -fsyntax-only -masm=' . s:GetDialect() }) \ 'main_flags': '-x assembler -fsyntax-only' . (g:syntastic_asm_generic ? '' : ' -masm=' . s:GetDialect()) })
endfunction " }}}1 endfunction " }}}1
" Utilities {{{1 " Utilities {{{1
function! s:GetDialect() " {{{2 function! s:GetDialect() " {{{2
return exists('g:syntastic_asm_dialect') ? g:syntastic_asm_dialect : return syntastic#util#var('asm_dialect', expand('%:e', 1) ==? 'asm' ? 'intel' : 'att')
\ expand('%:e', 1) ==? 'asm' ? 'intel' : 'att'
endfunction " }}}2 endfunction " }}}2
" }}}1 " }}}1

View file

@ -40,14 +40,12 @@ function! SyntaxCheckers_bro_bro_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args_before': '--parse-only' }) let makeprg = self.makeprgBuild({ 'args_before': '--parse-only' })
"example: error in ./foo.bro, line 3: unknown identifier banana, at or near "banana" "example: error in ./foo.bro, line 3: unknown identifier banana, at or near "banana"
let errorformat = let errorformat = '%t:%f:%l:%m'
\ 'fatal %trror in %f\, line %l: %m,' .
\ '%trror in %f\, line %l: %m,' .
\ '%tarning in %f\, line %l: %m'
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat }) \ 'errorformat': errorformat,
\ 'preprocess': 'bro' })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -43,9 +43,12 @@ function! SyntaxCheckers_c_clang_check_GetLocList() dict
\ '%-G%\m%\%%(LLVM ERROR:%\|No compilation database found%\)%\@!%.%#,' . \ '%-G%\m%\%%(LLVM ERROR:%\|No compilation database found%\)%\@!%.%#,' .
\ '%E%m' \ '%E%m'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env,
\ 'defaults': {'bufnr': bufnr('')}, \ 'defaults': {'bufnr': bufnr('')},
\ 'returns': [0, 1] }) \ 'returns': [0, 1] })
endfunction endfunction

View file

@ -43,9 +43,12 @@ function! SyntaxCheckers_c_clang_tidy_GetLocList() dict
\ '%-G%\m%\%%(LLVM ERROR:%\|No compilation database found%\)%\@!%.%#,' . \ '%-G%\m%\%%(LLVM ERROR:%\|No compilation database found%\)%\@!%.%#,' .
\ '%E%m' \ '%E%m'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env,
\ 'defaults': {'bufnr': bufnr('')}, \ 'defaults': {'bufnr': bufnr('')},
\ 'returns': [0, 1] }) \ 'returns': [0, 1] })
endfunction endfunction

View file

@ -24,17 +24,14 @@ function! SyntaxCheckers_coffee_coffeelint_GetLocList() dict
endif endif
let makeprg = self.makeprgBuild({ 'args_after': (s:coffeelint_new ? '--reporter csv' : '--csv') }) let makeprg = self.makeprgBuild({ 'args_after': (s:coffeelint_new ? '--reporter csv' : '--csv') })
let errorformat = let errorformat = '%f:%l:%t:%m'
\ '%f\,%l\,%\d%#\,%trror\,%m,' .
\ '%f\,%l\,%trror\,%m,' .
\ '%f\,%l\,%\d%#\,%tarn\,%m,' .
\ '%f\,%l\,%tarn\,%m'
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'subtype': 'Style', \ 'subtype': 'Style',
\ 'returns': [0, 1] }) \ 'returns': [0, 1],
\ 'preprocess': 'coffeelint' })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -22,7 +22,7 @@ function! SyntaxCheckers_coq_coqtop_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args_after': '-noglob -batch -load-vernac-source' }) let makeprg = self.makeprgBuild({ 'args_after': '-noglob -batch -load-vernac-source' })
let errorformat = let errorformat =
\ '%AFile \"%f\"\, line %l\, characters %c\-%.%#\:,'. \ '%AFile "%f"\, line %l\, characters %c-%.%#\:,'.
\ '%C%m' \ '%C%m'
return SyntasticMake({ return SyntasticMake({

View file

@ -14,8 +14,6 @@ if exists('g:loaded_syntastic_cpp_clang_check_checker')
endif endif
let g:loaded_syntastic_cpp_clang_check_checker = 1 let g:loaded_syntastic_cpp_clang_check_checker = 1
runtime! syntax_checkers/c/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'cpp', \ 'filetype': 'cpp',
\ 'name': 'clang_check', \ 'name': 'clang_check',

View file

@ -14,8 +14,6 @@ if exists('g:loaded_syntastic_cpp_clang_tidy_checker')
endif endif
let g:loaded_syntastic_cpp_clang_tidy_checker = 1 let g:loaded_syntastic_cpp_clang_tidy_checker = 1
runtime! syntax_checkers/c/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'cpp', \ 'filetype': 'cpp',
\ 'name': 'clang_tidy', \ 'name': 'clang_tidy',

View file

@ -14,8 +14,6 @@ if exists('g:loaded_syntastic_cpp_cppcheck_checker')
endif endif
let g:loaded_syntastic_cpp_cppcheck_checker = 1 let g:loaded_syntastic_cpp_cppcheck_checker = 1
runtime! syntax_checkers/c/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'cpp', \ 'filetype': 'cpp',
\ 'name': 'cppcheck', \ 'name': 'cppcheck',

View file

@ -14,8 +14,6 @@ if exists('g:loaded_syntastic_cpp_oclint_checker')
endif endif
let g:loaded_syntastic_cpp_oclint_checker = 1 let g:loaded_syntastic_cpp_oclint_checker = 1
runtime! syntax_checkers/c/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'cpp', \ 'filetype': 'cpp',
\ 'name': 'oclint', \ 'name': 'oclint',

View file

@ -15,8 +15,6 @@ if exists('g:loaded_syntastic_cpp_pc_lint_checker')
endif endif
let g:loaded_syntastic_cpp_pc_lint_checker = 1 let g:loaded_syntastic_cpp_pc_lint_checker = 1
runtime! syntax_checkers/c/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'cpp', \ 'filetype': 'cpp',
\ 'name': 'pc_lint', \ 'name': 'pc_lint',

View file

@ -0,0 +1,22 @@
"============================================================================
"File: mixedindentlint.vim
"Description: Mixed indentation linter for vim
"Maintainer: Payton Swick <payton@foolord.com>
"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_mixedindentlint_checker')
finish
endif
let g:loaded_syntastic_css_mixedindentlint_checker = 1
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'css',
\ 'name': 'mixedindentlint',
\ 'redirect': 'javascript/mixedindentlint'})
" vim: set et sts=4 sw=4:

View file

@ -15,8 +15,6 @@ if exists('g:loaded_syntastic_css_phpcs_checker')
endif endif
let g:loaded_syntastic_css_phpcs_checker = 1 let g:loaded_syntastic_css_phpcs_checker = 1
runtime! syntax_checkers/php/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'css', \ 'filetype': 'css',
\ 'name': 'phpcs', \ 'name': 'phpcs',

View file

@ -16,8 +16,6 @@ if exists('g:loaded_syntastic_css_recess_checker')
endif endif
let g:loaded_syntastic_css_recess_checker = 1 let g:loaded_syntastic_css_recess_checker = 1
runtime! syntax_checkers/less/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'css', \ 'filetype': 'css',
\ 'name': 'recess', \ 'name': 'recess',

View file

@ -0,0 +1,43 @@
"============================================================================
"File: stylelint.vim
"Description: Syntax checking plugin for syntastic.vim using `stylelint`
" (https://github.com/stylelint/stylelint).
"Maintainer: Tim Carry <tim at pixelastic dot com>
"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_stylelint_checker')
finish
endif
let g:loaded_syntastic_css_stylelint_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_css_stylelint_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args_after': '-f json' })
let errorformat = '%t:%f:%l:%c:%m'
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'subtype': 'Style',
\ 'preprocess': 'stylelint',
\ 'returns': [0, 1, 2] })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'css',
\ 'name': 'stylelint'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -15,8 +15,6 @@ if exists('g:loaded_syntastic_docbk_xmllint_checker')
endif endif
let g:loaded_syntastic_docbk_xmllint_checker = 1 let g:loaded_syntastic_docbk_xmllint_checker = 1
runtime! syntax_checkers/xml/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'docbk', \ 'filetype': 'docbk',
\ 'name': 'xmllint', \ 'name': 'xmllint',

View file

@ -0,0 +1,53 @@
"============================================================================
"File: dockerfile_lint.vim
"Description: Syntax checking plugin for syntastic.vim using dockerfile-lint
" (https://github.com/projectatomic/dockerfile-lint).
"Maintainer: Tim Carry <tim at pixelastic dot com>
"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_dockerfile_dockerfile_lint_checker')
finish
endif
let g:loaded_syntastic_dockerfile_dockerfile_lint_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_dockerfile_dockerfile_lint_GetLocList() dict
let makeprg = self.makeprgBuild({
\ 'args_after': '-j',
\ 'fname_before': '-f' })
let errorformat = '%t:%n:%l:%m'
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'preprocess': 'dockerfile_lint',
\ 'defaults': {'bufnr': bufnr('')},
\ 'returns': [0, 1] })
for e in loclist
if e['nr']
let e['subtype'] = 'Style'
endif
call remove(e, 'nr')
endfor
return loclist
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'dockerfile',
\ 'name': 'dockerfile_lint'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -27,6 +27,10 @@ function! SyntaxCheckers_go_go_IsAvailable() dict
endfunction endfunction
function! SyntaxCheckers_go_go_GetLocList() dict function! SyntaxCheckers_go_go_GetLocList() dict
if !exists('s:go_new')
let s:go_new = syntastic#util#versionIsAtLeast(self.getVersion(self.getExecEscaped() . ' version'), [1, 5])
endif
" Check with gofmt first, since `go build` and `go test` might not report " Check with gofmt first, since `go build` and `go test` might not report
" syntax errors in the current file if another file with syntax error is " syntax errors in the current file if another file with syntax error is
" compiled first. " compiled first.
@ -51,15 +55,15 @@ function! SyntaxCheckers_go_go_GetLocList() dict
" compiled by `go build`, therefore `go test` must be called for those. " compiled by `go build`, therefore `go test` must be called for those.
if match(expand('%', 1), '\m_test\.go$') == -1 if match(expand('%', 1), '\m_test\.go$') == -1
let cmd = 'build' let cmd = 'build'
let opts = syntastic#util#var('go_go_build_args') let opts = syntastic#util#var('go_go_build_args', s:go_new ? '-buildmode=archive' : '')
let cleanup = 0 let cleanup = 0
else else
let cmd = 'test -c' let cmd = 'test -c'
let opts = syntastic#util#var('go_go_test_args') let opts = syntastic#util#var('go_go_test_args', s:go_new ? '-buildmode=archive' : '')
let cleanup = 1 let cleanup = 1
endif endif
let opt_str = (type(opts) != type('') || opts !=# '') ? join(syntastic#util#argsescape(opts)) : opts let opt_str = (type(opts) != type('') || opts !=# '') ? join(syntastic#util#argsescape(opts)) : opts
let makeprg = self.getExec() . ' ' . cmd . ' ' . opt_str let makeprg = self.getExecEscaped() . ' ' . cmd . ' ' . opt_str
" The first pattern is for warnings from C compilers. " The first pattern is for warnings from C compilers.
let errorformat = let errorformat =
@ -67,6 +71,8 @@ function! SyntaxCheckers_go_go_GetLocList() dict
\ '%E%f:%l:%c:%m,' . \ '%E%f:%l:%c:%m,' .
\ '%E%f:%l:%m,' . \ '%E%f:%l:%m,' .
\ '%C%\s%\+%m,' . \ '%C%\s%\+%m,' .
\ '%+Ecan''t load package: %m,' .
\ '%+Einternal error: %m,' .
\ '%-G#%.%#' \ '%-G#%.%#'
" The go compiler needs to either be run with an import path as an " The go compiler needs to either be run with an import path as an
@ -77,6 +83,7 @@ function! SyntaxCheckers_go_go_GetLocList() dict
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'cwd': expand('%:p:h', 1), \ 'cwd': expand('%:p:h', 1),
\ 'env': {'GOGC': 'off'},
\ 'defaults': {'type': 'e'} }) \ 'defaults': {'type': 'e'} })
if cleanup if cleanup

View file

@ -0,0 +1,53 @@
"============================================================================
"File: gometalinter.vim
"Description: Check go syntax using 'gometalint'
"Maintainer: Joshua Rubin <joshua@rubixconsulting.com>
"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_go_gometalinter_checker')
finish
endif
let g:loaded_syntastic_go_gometalinter_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_go_gometalinter_GetLocList() dict
let makeprg = self.makeprgBuild({
\ 'args': '-t',
\ 'fname': syntastic#util#shexpand('%:p:h') })
let errorformat =
\ '%f:%l:%c:%trror: %m,' .
\ '%f:%l:%c:%tarning: %m,' .
\ '%f:%l::%trror: %m,' .
\ '%f:%l::%tarning: %m'
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'returns': [0, 1] })
for e in loclist
if e['text'] =~# '\v\(%(deadcode|gocyclo|golint|defercheck|varcheck|structcheck|errcheck|dupl)\)$'
let e['subtype'] = 'Style'
endif
endfor
return loclist
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'go',
\ 'name': 'gometalinter'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -19,7 +19,9 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_go_gotype_GetLocList() dict function! SyntaxCheckers_go_gotype_GetLocList() dict
let makeprg = self.getExecEscaped() . ' .' let makeprg = self.makeprgBuild({
\ 'args': (expand('%', 1) =~# '\m_test\.go$' ? '-a' : ''),
\ 'fname': '.' })
let errorformat = let errorformat =
\ '%f:%l:%c: %m,' . \ '%f:%l:%c: %m,' .

View file

@ -23,7 +23,7 @@ function! SyntaxCheckers_go_govet_IsAvailable() dict
endfunction endfunction
function! SyntaxCheckers_go_govet_GetLocList() dict function! SyntaxCheckers_go_govet_GetLocList() dict
let makeprg = self.getExec() . ' vet' let makeprg = self.getExecEscaped() . ' vet'
let errorformat = let errorformat =
\ '%Evet: %.%\+: %f:%l:%c: %m,' . \ '%Evet: %.%\+: %f:%l:%c: %m,' .

View file

@ -51,7 +51,14 @@ function! SyntaxCheckers_haskell_ghc_mod_IsAvailable() dict
let s:ghc_mod_new = -1 let s:ghc_mod_new = -1
endif endif
return (s:ghc_mod_new >= 0) && (v:version >= 704 || s:ghc_mod_new) " ghc-mod 5.4.0 wants to run in the root directory of the project;
" syntastic can't cope with the resulting complications
"
" References:
" https://hackage.haskell.org/package/ghc-mod-5.4.0.0/changelog
let s:ghc_mod_bailout = syntastic#util#versionIsAtLeast(parsed_ver, [5, 4])
return (s:ghc_mod_new >= 0) && (v:version >= 704 || s:ghc_mod_new) && !s:ghc_mod_bailout
endfunction endfunction
function! SyntaxCheckers_haskell_ghc_mod_GetLocList() dict function! SyntaxCheckers_haskell_ghc_mod_GetLocList() dict

View file

@ -18,6 +18,7 @@ function! SyntaxCheckers_haskell_hlint_GetLocList() dict
\ 'fname': syntastic#util#shexpand('%:p')}) \ 'fname': syntastic#util#shexpand('%:p')})
let errorformat = let errorformat =
\ '%E%f:%l:%v: Error while reading hint file\, %m,' .
\ '%E%f:%l:%v: Error: %m,' . \ '%E%f:%l:%v: Error: %m,' .
\ '%W%f:%l:%v: Warning: %m,' . \ '%W%f:%l:%v: Warning: %m,' .
\ '%C%m' \ '%C%m'

View file

@ -0,0 +1,40 @@
"============================================================================
"File: jade_lint.vim
"Description: Syntax checking plugin for syntastic.vim
"Maintainer: Ben Parnell <benjaminparnell.94@gmail.com>
"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_jade_jade_lint_checker')
finish
endif
let g:loaded_syntastic_jade_jade_lint_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_jade_jade_lint_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args_after': '-r inline' })
let errorformat = '%f:%l:%c %m'
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'returns': [0, 2] })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'jade',
\ 'name': 'jade_lint',
\ 'exec': 'jade-lint' })
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -17,7 +17,7 @@ endif
let g:loaded_syntastic_java_checkstyle_checker = 1 let g:loaded_syntastic_java_checkstyle_checker = 1
if !exists('g:syntastic_java_checkstyle_classpath') if !exists('g:syntastic_java_checkstyle_classpath')
let g:syntastic_java_checkstyle_classpath = 'checkstyle-5.5-all.jar' let g:syntastic_java_checkstyle_classpath = 'checkstyle-6.10.1-all.jar'
endif endif
if !exists('g:syntastic_java_checkstyle_conf_file') if !exists('g:syntastic_java_checkstyle_conf_file')
@ -32,30 +32,38 @@ function! SyntaxCheckers_java_checkstyle_IsAvailable() dict
return 0 return 0
endif endif
let classpath = expand(g:syntastic_java_checkstyle_classpath, 1)
let conf_file = expand(g:syntastic_java_checkstyle_conf_file, 1) let conf_file = expand(g:syntastic_java_checkstyle_conf_file, 1)
call self.log( call self.log('filereadable(' . string(conf_file) . ') = ' . filereadable(conf_file))
\ 'filereadable(' . string(classpath) . ') = ' . filereadable(classpath) . ', ' .
\ 'filereadable(' . string(conf_file) . ') = ' . filereadable(conf_file))
return filereadable(classpath) && filereadable(conf_file) return filereadable(conf_file)
endfunction endfunction
function! SyntaxCheckers_java_checkstyle_GetLocList() dict function! SyntaxCheckers_java_checkstyle_GetLocList() dict
let fname = syntastic#util#shescape( expand('%:p:h', 1) . syntastic#util#Slash() . expand('%:t', 1) ) " classpath
if !exists('s:sep')
let s:sep = syntastic#util#isRunningWindows() || has('win32unix') ? ';' : ':'
endif
let classpath = join(map( split(g:syntastic_java_checkstyle_classpath, s:sep, 1), 'expand(v:val, 1)' ), s:sep)
call self.log('classpath =', classpath)
" forced options
let opts = []
if classpath !=# ''
call extend(opts, ['-cp', classpath])
endif
call extend(opts, [
\ 'com.puppycrawl.tools.checkstyle.Main',
\ '-c', expand(g:syntastic_java_checkstyle_conf_file, 1),
\ '-f', 'xml' ])
" filename
let fname = syntastic#util#shescape( expand('%:p:h', 1) . syntastic#util#Slash() . expand('%:t', 1) )
if has('win32unix') if has('win32unix')
let fname = substitute(syntastic#util#system('cygpath -m ' . fname), '\m\%x00', '', 'g') let fname = substitute(syntastic#util#system('cygpath -m ' . fname), '\m\%x00', '', 'g')
endif endif
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({ 'args_after': opts, 'fname': fname })
\ 'args_after': [
\ '-cp', expand(g:syntastic_java_checkstyle_classpath, 1),
\ 'com.puppycrawl.tools.checkstyle.Main',
\ '-c', expand(g:syntastic_java_checkstyle_conf_file, 1),
\ '-f', 'xml'],
\ 'fname': fname })
let errorformat = '%f:%t:%l:%c:%m' let errorformat = '%f:%t:%l:%c:%m'

View file

@ -84,11 +84,12 @@ lockvar! s:_FILE_SHORTCUTS
" }}}1 " }}}1
command! SyntasticJavacEditClasspath call s:EditClasspath() " Commands {{{1
if g:syntastic_java_javac_config_file_enabled command! SyntasticJavacEditClasspath call s:EditClasspath()
command! SyntasticJavacEditConfig call s:EditConfig() command! SyntasticJavacEditConfig call s:EditConfig()
endif
" }}}1
function! SyntaxCheckers_java_javac_IsAvailable() dict " {{{1 function! SyntaxCheckers_java_javac_IsAvailable() dict " {{{1
let s:has_maven = executable(expand(g:syntastic_java_maven_executable, 1)) let s:has_maven = executable(expand(g:syntastic_java_maven_executable, 1))
@ -173,9 +174,8 @@ function! SyntaxCheckers_java_javac_GetLocList() dict " {{{1
let errorformat = let errorformat =
\ '%E%f:%l: error: %m,'. \ '%E%f:%l: error: %m,'.
\ '%W%f:%l: warning: %m,'. \ '%W%f:%l: warning: %m,'.
\ '%A%f:%l: %m,'. \ '%E%f:%l: %m,'.
\ '%+Z%p^,'. \ '%Z%p^,'.
\ '%+C%.%#,'.
\ '%-G%.%#' \ '%-G%.%#'
if output_dir !=# '' if output_dir !=# ''
@ -290,6 +290,10 @@ function! s:SaveConfig() " {{{2
endfunction " }}}2 endfunction " }}}2
function! s:EditConfig() " {{{2 function! s:EditConfig() " {{{2
if !g:syntastic_java_javac_config_file_enabled
return
endif
let command = 'syntastic javac config' let command = 'syntastic javac config'
let winnr = bufwinnr('^' . command . '$') let winnr = bufwinnr('^' . command . '$')
if winnr < 0 if winnr < 0
@ -356,7 +360,7 @@ function! s:GetMavenClasspath() " {{{2
let mvn_cmd = syntastic#util#shexpand(g:syntastic_java_maven_executable) . let mvn_cmd = syntastic#util#shexpand(g:syntastic_java_maven_executable) .
\ ' -f ' . syntastic#util#shescape(pom) . \ ' -f ' . syntastic#util#shescape(pom) .
\ ' ' . g:syntastic_java_maven_options \ ' ' . g:syntastic_java_maven_options
let mvn_classpath_output = split(syntastic#util#system(mvn_cmd . ' dependency:build-classpath'), "\n") let mvn_classpath_output = split(syntastic#util#system(mvn_cmd . ' dependency:build-classpath -DincludeScope=test'), "\n")
let mvn_classpath = '' let mvn_classpath = ''
let class_path_next = 0 let class_path_next = 0
@ -373,16 +377,10 @@ function! s:GetMavenClasspath() " {{{2
let mvn_properties = s:GetMavenProperties() let mvn_properties = s:GetMavenProperties()
let sep = syntastic#util#Slash() let sep = syntastic#util#Slash()
let output_dir = join(['target', 'classes'], sep) let output_dir = get(mvn_properties, 'project.build.outputDirectory', join(['target', 'classes'], sep))
if has_key(mvn_properties, 'project.build.outputDirectory')
let output_dir = mvn_properties['project.build.outputDirectory']
endif
let mvn_classpath = s:AddToClasspath(mvn_classpath, output_dir) let mvn_classpath = s:AddToClasspath(mvn_classpath, output_dir)
let test_output_dir = join(['target', 'test-classes'], sep) let test_output_dir = get(mvn_properties, 'project.build.testOutputDirectory', join(['target', 'test-classes'], sep))
if has_key(mvn_properties, 'project.build.testOutputDirectory')
let test_output_dir = mvn_properties['project.build.testOutputDirectory']
endif
let mvn_classpath = s:AddToClasspath(mvn_classpath, test_output_dir) let mvn_classpath = s:AddToClasspath(mvn_classpath, test_output_dir)
let g:syntastic_java_javac_maven_pom_ftime[pom] = getftime(pom) let g:syntastic_java_javac_maven_pom_ftime[pom] = getftime(pom)
@ -397,23 +395,16 @@ function! s:MavenOutputDirectory() " {{{2
let pom = syntastic#util#findFileInParent('pom.xml', expand('%:p:h', 1)) let pom = syntastic#util#findFileInParent('pom.xml', expand('%:p:h', 1))
if s:has_maven && filereadable(pom) if s:has_maven && filereadable(pom)
let mvn_properties = s:GetMavenProperties() let mvn_properties = s:GetMavenProperties()
let output_dir = getcwd() let output_dir = get(mvn_properties, 'project.properties.build.dir', getcwd())
if has_key(mvn_properties, 'project.properties.build.dir')
let output_dir = mvn_properties['project.properties.build.dir']
endif
let sep = syntastic#util#Slash() let sep = syntastic#util#Slash()
if stridx(expand('%:p:h', 1), join(['src', 'main', 'java'], sep)) >= 0 let src_main_dir = get(mvn_properties, 'project.build.sourceDirectory', join(['src', 'main', 'java'], sep))
let output_dir = join ([output_dir, 'target', 'classes'], sep) let src_test_dir = get(mvn_properties, 'project.build.testsourceDirectory', join(['src', 'test', 'java'], sep))
if has_key(mvn_properties, 'project.build.outputDirectory') if stridx(expand('%:p:h', 1), src_main_dir) >= 0
let output_dir = mvn_properties['project.build.outputDirectory'] let output_dir = get(mvn_properties, 'project.build.outputDirectory', join ([output_dir, 'target', 'classes'], sep))
endif
endif endif
if stridx(expand('%:p:h', 1), join(['src', 'test', 'java'], sep)) >= 0 if stridx(expand('%:p:h', 1), src_test_dir) >= 0
let output_dir = join([output_dir, 'target', 'test-classes'], sep) let output_dir = get(mvn_properties, 'project.build.testOutputDirectory', join([output_dir, 'target', 'test-classes'], sep))
if has_key(mvn_properties, 'project.build.testOutputDirectory')
let output_dir = mvn_properties['project.build.testOutputDirectory']
endif
endif endif
if has('win32unix') if has('win32unix')

View file

@ -18,21 +18,31 @@ if !exists('g:syntastic_javascript_eslint_sort')
let g:syntastic_javascript_eslint_sort = 1 let g:syntastic_javascript_eslint_sort = 1
endif endif
if !exists('g:syntastic_javascript_eslint_generic')
let g:syntastic_javascript_eslint_generic = 0
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_javascript_eslint_IsAvailable() dict function! SyntaxCheckers_javascript_eslint_IsAvailable() dict
if g:syntastic_javascript_eslint_generic
call self.log('generic eslint, exec =', self.getExec())
endif
if !executable(self.getExec()) if !executable(self.getExec())
return 0 return 0
endif endif
return syntastic#util#versionIsAtLeast(self.getVersion(), [0, 1]) return g:syntastic_javascript_eslint_generic || syntastic#util#versionIsAtLeast(self.getVersion(), [0, 1])
endfunction endfunction
function! SyntaxCheckers_javascript_eslint_GetLocList() dict function! SyntaxCheckers_javascript_eslint_GetLocList() dict
call syntastic#log#deprecationWarn('javascript_eslint_conf', 'javascript_eslint_args', if !g:syntastic_javascript_eslint_generic
\ "'--config ' . syntastic#util#shexpand(OLD_VAR)") call syntastic#log#deprecationWarn('javascript_eslint_conf', 'javascript_eslint_args',
\ "'--config ' . syntastic#util#shexpand(OLD_VAR)")
endif
let makeprg = self.makeprgBuild({ 'args_before': '-f compact' }) let makeprg = self.makeprgBuild({ 'args_before': (g:syntastic_javascript_eslint_generic ? '' : '-f compact') })
let errorformat = let errorformat =
\ '%E%f: line %l\, col %c\, Error - %m,' . \ '%E%f: line %l\, col %c\, Error - %m,' .
@ -43,9 +53,17 @@ function! SyntaxCheckers_javascript_eslint_GetLocList() dict
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'postprocess': ['guards'] }) \ 'postprocess': ['guards'] })
for e in loclist if !g:syntastic_javascript_eslint_generic
let e['col'] += 1 if !exists('s:eslint_new')
endfor let s:eslint_new = syntastic#util#versionIsAtLeast(self.getVersion(), [1])
endif
if !s:eslint_new
for e in loclist
let e['col'] += 1
endfor
endif
endif
return loclist return loclist
endfunction endfunction

View file

@ -21,16 +21,24 @@ endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_javascript_jscs_GetLocList() dict function! SyntaxCheckers_javascript_jscs_IsAvailable() dict
let makeprg = self.makeprgBuild({ 'args_after': '--no-colors --reporter checkstyle' }) if !executable(self.getExec())
return 0
endif
return syntastic#util#versionIsAtLeast(self.getVersion(), [2, 1])
endfunction
let errorformat = '%f:%t:%l:%c:%m' function! SyntaxCheckers_javascript_jscs_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args_after': '--no-colors --reporter json' })
let errorformat = '%f:%l:%c:%m'
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'subtype': 'Style', \ 'subtype': 'Style',
\ 'preprocess': 'checkstyle', \ 'preprocess': 'jscs',
\ 'defaults': {'type': 'E'},
\ 'returns': [0, 2] }) \ 'returns': [0, 2] })
endfunction endfunction

View file

@ -18,6 +18,10 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_javascript_jsxhint_IsAvailable() dict function! SyntaxCheckers_javascript_jsxhint_IsAvailable() dict
if !executable(self.getExec())
return 0
endif
let version_output = syntastic#util#system(self.getExecEscaped() . ' --version') let version_output = syntastic#util#system(self.getExecEscaped() . ' --version')
let parsed_ver = !v:shell_error && (version_output =~# '\m^JSXHint\>') ? syntastic#util#parseVersion(version_output) : [] let parsed_ver = !v:shell_error && (version_output =~# '\m^JSXHint\>') ? syntastic#util#parseVersion(version_output) : []
if len(parsed_ver) if len(parsed_ver)

View file

@ -0,0 +1,40 @@
"============================================================================
"File: mixedindentlint.vim
"Description: Mixed indentation linter for vim
"Maintainer: Payton Swick <payton@foolord.com>
"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_mixedindentlint_checker')
finish
endif
let g:loaded_syntastic_javascript_mixedindentlint_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_javascript_mixedindentlint_GetLocList() dict
let makeprg = self.makeprgBuild({})
let errorformat = 'Line %l in "%f" %.%#'
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'subtype': 'Style',
\ 'defaults': { 'text': 'Indentation differs from rest of file' },
\ 'returns': [0, 1] })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'javascript',
\ 'name': 'mixedindentlint'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -14,14 +14,22 @@ if exists('g:loaded_syntastic_javascript_standard_checker')
endif endif
let g:loaded_syntastic_javascript_standard_checker = 1 let g:loaded_syntastic_javascript_standard_checker = 1
if !exists('g:syntastic_javascript_standard_generic')
let g:syntastic_javascript_standard_generic = 0
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_javascript_standard_IsAvailable() dict function! SyntaxCheckers_javascript_standard_IsAvailable() dict
if g:syntastic_javascript_standard_generic
call self.log('generic standard, exec =', self.getExec())
endif
if !executable(self.getExec()) if !executable(self.getExec())
return 0 return 0
endif endif
return syntastic#util#versionIsAtLeast(self.getVersion(), [2, 6, 1]) return g:syntastic_javascript_standard_generic || syntastic#util#versionIsAtLeast(self.getVersion(), [2, 6, 1])
endfunction endfunction
function! SyntaxCheckers_javascript_standard_GetLocList() dict function! SyntaxCheckers_javascript_standard_GetLocList() dict

View file

@ -23,14 +23,15 @@ function! SyntaxCheckers_nix_nix_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args_after': '--parse-only' }) let makeprg = self.makeprgBuild({ 'args_after': '--parse-only' })
let errorformat = let errorformat =
\ '%m\, at %f:%l:%c,' . \ '%f:%l:%c:%m,' .
\ '%m at %f\, line %l:,' . \ '%f:%l:%m,' .
\ 'error: %m\, in %f' \ '%f:%m'
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'defaults': {'type': 'e'} }) \ 'defaults': {'type': 'e'},
\ 'preprocess': 'nix' })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -15,8 +15,6 @@ if exists('g:loaded_syntastic_nroff_igor_checker')
endif endif
let g:loaded_syntastic_nroff_igor_checker = 1 let g:loaded_syntastic_nroff_igor_checker = 1
runtime! syntax_checkers/docbk/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'nroff', \ 'filetype': 'nroff',
\ 'name': 'igor', \ 'name': 'igor',

View file

@ -14,8 +14,6 @@ if exists('g:loaded_syntastic_objc_oclint_checker')
endif endif
let g:loaded_syntastic_objc_oclint_checker = 1 let g:loaded_syntastic_objc_oclint_checker = 1
runtime! syntax_checkers/c/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'objc', \ 'filetype': 'objc',
\ 'name': 'oclint', \ 'name': 'oclint',

View file

@ -14,8 +14,6 @@ if exists('g:loaded_syntastic_objcpp_oclint_checker')
endif endif
let g:loaded_syntastic_objcpp_oclint_checker = 1 let g:loaded_syntastic_objcpp_oclint_checker = 1
runtime! syntax_checkers/c/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'objcpp', \ 'filetype': 'objcpp',
\ 'name': 'oclint', \ 'name': 'oclint',

View file

@ -15,8 +15,6 @@ if exists('g:loaded_syntastic_perl_podchecker_checker')
endif endif
let g:loaded_syntastic_perl_podchecker_checker = 1 let g:loaded_syntastic_perl_podchecker_checker = 1
runtime! syntax_checkers/pod/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'perl', \ 'filetype': 'perl',
\ 'name': 'podchecker', \ 'name': 'podchecker',

View file

@ -16,13 +16,14 @@ set cpo&vim
function! SyntaxCheckers_python_mypy_GetLocList() dict function! SyntaxCheckers_python_mypy_GetLocList() dict
let makeprg = self.makeprgBuild({}) let makeprg = self.makeprgBuild({})
let errorformat = '%f\, line %l: %m' let errorformat = '%f:%l:%m'
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'defaults': { 'type': 'E' }, \ 'defaults': { 'type': 'E' },
\ 'returns': [0, 1] }) \ 'returns': [0, 1],
\ 'preprocess': 'mypy' })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -0,0 +1,39 @@
"============================================================================
"File: qmllint.vim
"Description: Syntax checking plugin for syntastic.vim using qmllint
"Maintainer: Peter Wu <peter@lekensteyn.nl>
"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_qml_qmllint_checker')
finish
endif
let g:loaded_syntastic_qml_qmllint_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_qml_qmllint_GetLocList() dict
let makeprg = self.makeprgBuild({})
let errorformat = '%f:%l : %m'
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'postprocess': ['guards'],
\ 'returns': [0, 255] })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'qml',
\ 'name': 'qmllint'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -44,7 +44,6 @@ endfunction
function! SyntaxCheckers_r_lint_GetLocList() dict function! SyntaxCheckers_r_lint_GetLocList() dict
let setwd = syntastic#util#isRunningWindows() ? 'setwd("' . escape(getcwd(), '"\') . '"); ' : '' let setwd = syntastic#util#isRunningWindows() ? 'setwd("' . escape(getcwd(), '"\') . '"); ' : ''
let setwd = 'setwd("' . escape(getcwd(), '"\') . '"); '
let makeprg = self.getExecEscaped() . ' --slave --restore --no-save' . let makeprg = self.getExecEscaped() . ' --slave --restore --no-save' .
\ ' -e ' . syntastic#util#shescape(setwd . 'library(lint); ' . \ ' -e ' . syntastic#util#shescape(setwd . 'library(lint); ' .
\ 'try(lint(commandArgs(TRUE), ' . g:syntastic_r_lint_styles . '))') . \ 'try(lint(commandArgs(TRUE), ' . g:syntastic_r_lint_styles . '))') .

View file

@ -0,0 +1,81 @@
"============================================================================
"File: lintr.vim
"Description: Syntax checking plugin for syntastic.vim
"Maintainer: Jim Hester <james.f.hester at gmail dot com>
"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_lintr_checker to 1 in
" your vimrc to enable this checker:
"
" let g:syntastic_enable_r_lintr_checker = 1
if exists("g:loaded_syntastic_r_lintr_checker")
finish
endif
let g:loaded_syntastic_r_lintr_checker = 1
if !exists('g:syntastic_r_lintr_linters')
let g:syntastic_r_lintr_linters = 'default_linters'
endif
if !exists('g:syntastic_r_lintr_cache')
let g:syntastic_r_lintr_cache = 'FALSE'
endif
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_r_lintr_GetHighlightRegex(item)
let term = matchstr(a:item['text'], "\\m'\\zs[^']\\+\\ze'")
return term != '' ? '\V' . escape(term, '\') : ''
endfunction
function! SyntaxCheckers_r_lintr_IsAvailable() dict
if !executable(self.getExec())
return 0
endif
call system(self.getExecEscaped() . ' --slave --no-restore --no-save -e ' . syntastic#util#shescape('library(lintr)'))
return v:shell_error == 0
endfunction
function! SyntaxCheckers_r_lintr_GetLocList() dict
let setwd = syntastic#util#isRunningWindows() ? 'setwd("' . escape(getcwd(), '"\') . '"); ' : ''
let makeprg = self.getExecEscaped() . ' --slave --no-restore --no-save' .
\ ' -e ' . syntastic#util#shescape(setwd . 'suppressPackageStartupMessages(library(lintr)); ' .
\ 'lint(cache = ' . g:syntastic_r_lintr_cache . ', commandArgs(TRUE), ' . g:syntastic_r_lintr_linters . ')') .
\ ' --args ' . syntastic#util#shexpand('%')
let errorformat =
\ '%W%f:%l:%c: style: %m,' .
\ '%W%f:%l:%c: warning: %m,' .
\ '%E%f:%l:%c: error: %m,'
call self.setWantSort(1)
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'returns': [0] })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'r',
\ 'name': 'lintr',
\ 'exec': 'R',
\ 'enable': 'enable_r_lintr_checker'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,23 @@
"============================================================================
"File: lintr.vim
"Description: Syntax checking plugin for syntastic.vim
"Maintainer: Jim Hester <james.f.hester at gmail dot com>
"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_rmd_lintr_checker')
finish
endif
let g:loaded_syntastic_rmd_lintr_checker = 1
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'rmd',
\ 'name': 'lintr',
\ 'redirect': 'r/lintr'})
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -29,9 +29,9 @@ function! SyntaxCheckers_rst_sphinx_GetLocList() dict
let srcdir = syntastic#util#var('rst_sphinx_source_dir') let srcdir = syntastic#util#var('rst_sphinx_source_dir')
call self.log('g:syntastic_rst_sphinx_source_dir =', srcdir) call self.log('g:syntastic_rst_sphinx_source_dir =', srcdir)
if srcdir == '' if srcdir ==# ''
let config = syntastic#util#findFileInParent('conf.py', expand('%:p:h', 1)) let config = syntastic#util#findFileInParent('conf.py', expand('%:p:h', 1))
if config == '' || !filereadable(config) if config ==# '' || !filereadable(config)
call self.log('conf.py file not found') call self.log('conf.py file not found')
return [] return []
endif endif
@ -40,9 +40,9 @@ function! SyntaxCheckers_rst_sphinx_GetLocList() dict
let confdir = syntastic#util#var('rst_sphinx_config_dir') let confdir = syntastic#util#var('rst_sphinx_config_dir')
call self.log('g:syntastic_rst_sphinx_config_dir =', confdir) call self.log('g:syntastic_rst_sphinx_config_dir =', confdir)
if confdir == '' if confdir ==# ''
let config = syntastic#util#findFileInParent('conf.py', expand('%:p:h', 1)) let config = syntastic#util#findFileInParent('conf.py', expand('%:p:h', 1))
let confdir = (config != '' && filereadable(config)) ? fnamemodify(config, ':p:h') : srcdir let confdir = (config !=# '' && filereadable(config)) ? fnamemodify(config, ':p:h') : srcdir
endif endif
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({

View file

@ -0,0 +1,72 @@
"============================================================================
"File: flog.vim
"Description: Syntax checking plugin for syntastic.vim
"Maintainer: Tim Carry <tim at pixelastic dot com>
"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_ruby_flog_checker')
finish
endif
let g:loaded_syntastic_ruby_flog_checker = 1
if !exists('g:syntastic_ruby_flog_threshold_warning')
let g:syntastic_ruby_flog_threshold_warning = 45
endif
if !exists('g:syntastic_ruby_flog_threshold_error')
let g:syntastic_ruby_flog_threshold_error = 90
endif
if !exists('g:syntastic_ruby_flog_sort')
let g:syntastic_ruby_flog_sort = 1
endif
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_ruby_flog_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args': '-a' })
" Example output:
" 93.25: MyClass::my_method my_file:42
let errorformat = '%\m%\s%#%m: %.%# %f:%l'
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'subtype': 'Style' })
let trail_w = syntastic#util#float2str(g:syntastic_ruby_flog_threshold_warning) . ')'
let trail_e = syntastic#util#float2str(g:syntastic_ruby_flog_threshold_error) . ')'
for e in loclist
let score = syntastic#util#str2float(e['text'])
let e['text'] = 'Complexity is too high (' . syntastic#util#float2str(score) . '/'
if score < g:syntastic_ruby_flog_threshold_warning
let e['valid'] = 0
elseif score < g:syntastic_ruby_flog_threshold_error
let e['type'] = 'W'
let e['text'] .= trail_w
else
let e['type'] = 'E'
let e['text'] .= trail_e
endif
endfor
return loclist
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'ruby',
\ 'name': 'flog'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,22 @@
"============================================================================
"File: mixedindentlint.vim
"Description: Mixed indentation linter for vim
"Maintainer: Payton Swick <payton@foolord.com>
"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_mixedindentlint_checker')
finish
endif
let g:loaded_syntastic_scss_mixedindentlint_checker = 1
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'scss',
\ 'name': 'mixedindentlint',
\ 'redirect': 'javascript/mixedindentlint'})
" vim: set et sts=4 sw=4:

View file

@ -15,8 +15,6 @@ if exists('g:loaded_syntastic_scss_sass_checker')
endif endif
let g:loaded_syntastic_scss_sass_checker = 1 let g:loaded_syntastic_scss_sass_checker = 1
runtime! syntax_checkers/sass/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'scss', \ 'filetype': 'scss',
\ 'name': 'sass', \ 'name': 'sass',

View file

@ -15,8 +15,6 @@ if exists('g:loaded_syntastic_scss_sassc_checker')
endif endif
let g:loaded_syntastic_scss_sassc_checker = 1 let g:loaded_syntastic_scss_sassc_checker = 1
runtime! syntax_checkers/sass/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'scss', \ 'filetype': 'scss',
\ 'name': 'sassc', \ 'name': 'sassc',

View file

@ -0,0 +1,39 @@
"============================================================================
"File: slim_lint.vim
"Description: Slim style and syntax checker plugin for Syntastic
"Maintainer: Vasily Kolesnikov <re.vkolesnikov@gmail.com>
"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_slim_slim_lint_checker')
finish
endif
let g:loaded_syntastic_slim_slim_lint_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_slim_slim_lint_GetLocList() dict
let makeprg = self.makeprgBuild({})
let errorformat = '%f:%l [%t] %m'
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'subtype': 'Style'})
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'slim',
\ 'name': 'slim_lint',
\ 'exec': 'slim-lint' })
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,50 @@
"============================================================================
"File: sqlint.vim
"Description: Syntax checking plugin for syntastic.vim
"Maintainer: Steve Purcell <steve@sanityinc.com>
"License: MIT
"============================================================================
if exists('g:loaded_syntastic_sql_sqlint_checker')
finish
endif
let g:loaded_syntastic_sql_sqlint_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_sql_sqlint_GetHighlightRegex(i)
let term = matchstr(a:i['text'], '\m at or near "\zs[^"]\+\ze"')
return term !=# '' ? '\V\<' . escape(term, '\') . '\>' : ''
endfunction
function! SyntaxCheckers_sql_sqlint_IsAvailable() dict
if !executable(self.getExec())
return 0
endif
return syntastic#util#versionIsAtLeast(self.getVersion(), [0, 0, 3])
endfunction
function! SyntaxCheckers_sql_sqlint_GetLocList() dict
let makeprg = self.makeprgBuild({})
let errorformat =
\ '%E%f:%l:%c:ERROR %m,' .
\ '%W%f:%l:%c:WARNING %m,' .
\ '%C %m'
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'subtype': 'Style',
\ 'returns': [0, 1] })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'sql',
\ 'name': 'sqlint'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,43 @@
"============================================================================
"File: stylint.vim
"Description: Syntax checking plugin for syntastic.vim
"Maintainer: LCD 47 <lcd047 at gmail dot com>
"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_stylus_stylint_checker')
finish
endif
let g:loaded_syntastic_stylus_stylint_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_stylus_stylint_GetLocList() dict
let makeprg = self.makeprgBuild({})
let errorformat =
\ '%WWarning: %m,' .
\ '%EError: %m,' .
\ '%CFile: %f,' .
\ '%CLine: %l:%.%#'
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'subtype': 'Style' })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'stylus',
\ 'name': 'stylint'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -15,8 +15,6 @@ if exists('g:loaded_syntastic_text_igor_checker')
endif endif
let g:loaded_syntastic_text_igor_checker = 1 let g:loaded_syntastic_text_igor_checker = 1
runtime! syntax_checkers/docbk/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'text', \ 'filetype': 'text',
\ 'name': 'igor', \ 'name': 'igor',

View file

@ -0,0 +1,23 @@
"============================================================================
"File: eslint.vim
"Description: Syntax checking plugin for syntastic
"Maintainer: LCD 47 <lcd047 at gmail dot com>
"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_typescript_eslint_checker')
finish
endif
let g:loaded_syntastic_typescript_eslint_checker = 1
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'typescript',
\ 'name': 'eslint',
\ 'redirect': 'javascript/eslint'})
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -18,6 +18,10 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_typescript_tsc_IsAvailable() dict function! SyntaxCheckers_typescript_tsc_IsAvailable() dict
if !executable(self.getExec())
return 0
endif
let version_output = split(syntastic#util#system(self.getExecEscaped() . ' --version'), '\n', 1) let version_output = split(syntastic#util#system(self.getExecEscaped() . ' --version'), '\n', 1)
let ver = filter(copy(version_output), 'v:val =~# ''\m\<Version ''') let ver = filter(copy(version_output), 'v:val =~# ''\m\<Version ''')
let parsed_ver = len(ver) ? syntastic#util#parseVersion(ver[0], '\v<Version \zs\d+(\.\d+)\ze') : [] let parsed_ver = len(ver) ? syntastic#util#parseVersion(ver[0], '\v<Version \zs\d+(\.\d+)\ze') : []
@ -48,6 +52,7 @@ function! SyntaxCheckers_typescript_tsc_GetLocList() dict
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'postprocess': ['guards'],
\ 'defaults': {'bufnr': bufnr('')} }) \ 'defaults': {'bufnr': bufnr('')} })
endfunction endfunction

View file

@ -22,9 +22,13 @@ function! SyntaxCheckers_typescript_tslint_GetHighlightRegex(item)
endfunction endfunction
function! SyntaxCheckers_typescript_tslint_GetLocList() dict function! SyntaxCheckers_typescript_tslint_GetLocList() dict
if !exists('s:tslint_new')
let s:tslint_new = syntastic#util#versionIsAtLeast(self.getVersion(), [2, 4])
endif
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'args_after': '--format verbose', \ 'args_after': '--format verbose',
\ 'fname_before': '-f' }) \ 'fname_before': (s:tslint_new ? '' : '-f') })
" (comment-format) ts/app.ts[12, 36]: comment must start with lowercase letter " (comment-format) ts/app.ts[12, 36]: comment must start with lowercase letter
let errorformat = '%f[%l\, %c]: %m' let errorformat = '%f[%l\, %c]: %m'

View file

@ -0,0 +1,38 @@
"============================================================================
"File: iverilog.vim
"Description: Syntax checking plugin for syntastic.vim
"Maintainer: Psidium <psiidium at gmail dot com>
"License: The MIT License
"============================================================================
if exists('g:loaded_syntastic_verilog_iverilog_checker')
finish
endif
let g:loaded_syntastic_verilog_iverilog_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_verilog_iverilog_GetLocList() dict
let makeprg = self.makeprgBuild({
\ 'args_before': '-t null',
\ 'args': '-Wall' })
let errorformat =
\ '%f:%l: %trror: %m,' .
\ '%f:%l: %tarning: %m,' .
\ '%E%f:%l: : %m,' .
\ '%W%f:%l: : %m,' .
\ '%f:%l: %m'
return SyntasticMake({'makeprg': makeprg, 'errorformat': errorformat})
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'verilog',
\ 'name': 'iverilog'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,55 @@
"============================================================================
"File: vcom.vim
"Description: Syntax checking plugin for syntastic.vim
"Maintainer: Jim Vogel <jim dot e dot vogel at gmail dot com>
"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_vhdl_vcom_checker')
finish
endif
let g:loaded_syntastic_vhdl_vcom_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_vhdl_vcom_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args_before': '-lint' })
let errorformat =
\ '** %tRROR: %f(%l): %m,' .
\ '** %tRROR: %m,' .
\ '** %tARNING: %f(%l): %m,' .
\ '** %tARNING: %m,' .
\ '** %tOTE: %m,' .
\ '%tRROR: %f(%l): %m,' .
\ '%tARNING[%*[0-9]]: %f(%l): %m,' .
\ '%tRROR: %m,' .
\ '%tARNING[%*[0-9]]: %m'
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat })
for e in loclist
if e['type'] !=? 'E' && e['type'] !=? 'W'
let e['type'] = 'W'
endif
endfor
return loclist
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'vhdl',
\ 'name': 'vcom'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -74,6 +74,8 @@ function! SyntaxCheckers_vim_vimlint_GetLocList() dict " {{{1
endif endif
endif endif
call self.log('options =', param)
return vimlint#vimlint(expand('%', 1), param) return vimlint#vimlint(expand('%', 1), param)
endfunction " }}}1 endfunction " }}}1

View file

@ -15,8 +15,6 @@ if exists('g:loaded_syntastic_xhtml_jshint_checker')
endif endif
let g:loaded_syntastic_xhtml_jshint_checker = 1 let g:loaded_syntastic_xhtml_jshint_checker = 1
runtime! syntax_checkers/html/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'xhtml', \ 'filetype': 'xhtml',
\ 'name': 'jshint', \ 'name': 'jshint',

View file

@ -0,0 +1,51 @@
"============================================================================
"File: basex.vim
"Description: Syntax checking plugin for syntastic.vim
"Maintainer: James Wright <james dot jw at hotmail dot com>
"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.
"
"============================================================================
if exists('g:loaded_syntastic_xquery_basex_checker')
finish
endif
let g:loaded_syntastic_xquery_basex_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_xquery_basex_GetLocList() dict
let makeprg = self.makeprgBuild({
\ 'args_after': '-z',
\ 'fname_before': '-q',
\ 'fname': syntastic#util#shescape('inspect:module("' . escape(expand('%:p', 1), '"') . '")') })
let errorformat =
\ '%f:%l:%c:%t:%n:%m,' .
\ '%m'
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'preprocess': 'basex' })
for e in loclist
if e['type'] !=# 'W' && e['type'] !=# 'E'
let e['type'] = 'E'
endif
endfor
return loclist
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'xquery',
\ 'name': 'basex'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -15,8 +15,6 @@ if exists('g:loaded_syntastic_xslt_xmllint_checker')
endif endif
let g:loaded_syntastic_xslt_xmllint_checker = 1 let g:loaded_syntastic_xslt_xmllint_checker = 1
runtime! syntax_checkers/xml/*.vim
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'xslt', \ 'filetype': 'xslt',
\ 'name': 'xmllint', \ 'name': 'xmllint',

View file

@ -28,6 +28,7 @@ function! SyntaxCheckers_yaml_jsyaml_GetLocList() dict
let errorformat = let errorformat =
\ 'Error on line %l\, col %c:%m,' . \ 'Error on line %l\, col %c:%m,' .
\ 'JS-YAML: %m at line %l\, column %c:,' . \ 'JS-YAML: %m at line %l\, column %c:,' .
\ 'YAMLException: %m at line %l\, column %c:,' .
\ '%-G%.%#' \ '%-G%.%#'
return SyntasticMake({ return SyntasticMake({

View file

@ -1,10 +1,7 @@
" tlib.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim]) " @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037 " @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-07-17. " @Revision: 13
" @Last Change: 2013-09-25.
" @Revision: 0.0.12
" :nodefault: " :nodefault:
TLet g:tlib#debug = 0 TLet g:tlib#debug = 0

View file

@ -3,8 +3,8 @@
" @Website: http://www.vim.org/account/profile.php?user_id=4037 " @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2008-11-25. " @Created: 2008-11-25.
" @Last Change: 2014-06-02. " @Last Change: 2014-11-18.
" @Revision: 0.0.109 " @Revision: 0.0.114
let s:prototype = tlib#Object#New({'_class': ['Filter_cnf'], 'name': 'cnf'}) "{{{2 let s:prototype = tlib#Object#New({'_class': ['Filter_cnf'], 'name': 'cnf'}) "{{{2
let s:prototype.highlight = g:tlib#input#higroup let s:prototype.highlight = g:tlib#input#higroup

View file

@ -2,8 +2,8 @@
" @Website: http://www.vim.org/account/profile.php?user_id=4037 " @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2008-11-25. " @Created: 2008-11-25.
" @Last Change: 2014-01-23. " @Last Change: 2014-11-18.
" @Revision: 0.0.80 " @Revision: 0.0.82
let s:prototype = tlib#Filter_cnf#New({'_class': ['Filter_glob'], 'name': 'glob'}) "{{{2 let s:prototype = tlib#Filter_cnf#New({'_class': ['Filter_glob'], 'name': 'glob'}) "{{{2
let s:prototype.highlight = g:tlib#input#higroup let s:prototype.highlight = g:tlib#input#higroup
@ -61,8 +61,8 @@ endf
" :nodoc: " :nodoc:
function! s:prototype.CleanFilter(filter) dict "{{{3 function! s:prototype.CleanFilter(filter) dict "{{{3
let filter = substitute(a:filter, '\\.\\{-}', g:tlib#Filter_glob#seq, 'g') let filter = substitute(a:filter, '\\\.\\{-}', g:tlib#Filter_glob#seq, 'g')
let filter = substitute(filter, '\\.', g:tlib#Filter_glob#char, 'g') let filter = substitute(filter, '\\\.', g:tlib#Filter_glob#char, 'g')
return filter return filter
endf endf

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