diff --git a/Dockerfile b/Dockerfile
index 2571714..f374e25 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -46,7 +46,7 @@ RUN curl --location --silent --output /opt/phantom-1.9.8.tar.bz2 \
RUN gem install compass --version 1.0.1
# Node
-ENV NODE_VERSION 0.10.35
+ENV NODE_VERSION 0.12.2
RUN mkdir -p /opt/node && \
curl --silent --output /opt/node.tar.gz \
https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz && \
@@ -55,22 +55,51 @@ RUN mkdir -p /opt/node && \
RUN cd /usr/local/bin/ && ln -s phantomjs-1.9.8 phantomjs
-ENV PATH /opt/node/bin:$PATH
+ENV PATH /opt/node/bin:/opt/phantom-talk/node_modules/.bin:$PATH
ENV PHANTOMJS_BIN /usr/local/bin/phantomjs
+RUN apt-get update \
+ && apt-get upgrade -y \
+ && apt-get install -y \
+ vim \
+ git \
+ && rm -r /var/lib/apt/lists
+
+RUN adduser \
+ --disabled-password \
+ --home /home/demo \
+ --shell /bin/bash \
+ --gecos "Demo" \
+ demo \
+ && mkdir /opt/phantom-talk
+
+ADD ./config/home/bashrc /home/demo/.bashrc
+ADD ./config/home/vimrc /home/demo/.vimrc
+ADD ./config/home/vim /home/demo/.vim
+
+RUN chown -R demo:demo /home/demo \
+ && chown demo:demo /opt/phantom-talk
+
+USER demo
+ENV EDITOR vim
+ENV HOME /home/demo
+ENV TERM screen-256color
WORKDIR /opt/phantom-talk
-COPY ./package.json /opt/phantom-talk/package.json
-COPY ./README.md /opt/phantom-talk/README.md
-RUN ["npm", "install"]
+ADD ./package.json /opt/phantom-talk/package.json
+ADD ./README.md /opt/phantom-talk/README.md
+RUN npm install
ADD . /opt/phantom-talk
+USER root
+RUN chown demo:demo -R /opt/phantom-talk
+USER demo
-ENV TERM screen-256color
+RUN npm run build
-RUN ["npm", "run", "build"]
EXPOSE 8000
EXPOSE 8001
EXPOSE 8002
EXPOSE 35729
+
ENTRYPOINT ["npm"]
CMD ["run", "deck"]
diff --git a/config/home/bashrc b/config/home/bashrc
new file mode 100644
index 0000000..988d698
--- /dev/null
+++ b/config/home/bashrc
@@ -0,0 +1,114 @@
+# ~/.bashrc: executed by bash(1) for non-login shells.
+# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
+# for examples
+
+# If not running interactively, don't do anything
+case $- in
+ *i*) ;;
+ *) return;;
+esac
+
+# don't put duplicate lines or lines starting with space in the history.
+# See bash(1) for more options
+HISTCONTROL=ignoreboth
+
+# append to the history file, don't overwrite it
+shopt -s histappend
+
+# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
+HISTSIZE=1000
+HISTFILESIZE=2000
+
+# check the window size after each command and, if necessary,
+# update the values of LINES and COLUMNS.
+shopt -s checkwinsize
+
+# If set, the pattern "**" used in a pathname expansion context will
+# match all files and zero or more directories and subdirectories.
+#shopt -s globstar
+
+# make less more friendly for non-text input files, see lesspipe(1)
+[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
+
+# set variable identifying the chroot you work in (used in the prompt below)
+if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
+ debian_chroot=$(cat /etc/debian_chroot)
+fi
+
+# set a fancy prompt (non-color, unless we know we "want" color)
+case "$TERM" in
+ xterm-color) color_prompt=yes;;
+esac
+
+# uncomment for a colored prompt, if the terminal has the capability; turned
+# off by default to not distract the user: the focus in a terminal window
+# should be on the output of commands, not on the prompt
+force_color_prompt=yes
+
+if [ -n "$force_color_prompt" ]; then
+ if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
+ # We have color support; assume it's compliant with Ecma-48
+ # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
+ # a case would tend to support setf rather than setaf.)
+ color_prompt=yes
+ else
+ color_prompt=
+ fi
+fi
+
+if [ "$color_prompt" = yes ]; then
+ PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\n\$ '
+else
+ PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\n\$ '
+fi
+unset color_prompt force_color_prompt
+
+# If this is an xterm set the title to user@host:dir
+case "$TERM" in
+xterm*|rxvt*)
+ PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
+ ;;
+*)
+ ;;
+esac
+
+# enable color support of ls and also add handy aliases
+if [ -x /usr/bin/dircolors ]; then
+ test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
+ alias ls='ls --color=auto'
+ #alias dir='dir --color=auto'
+ #alias vdir='vdir --color=auto'
+
+ alias grep='grep --color=auto'
+ alias fgrep='fgrep --color=auto'
+ alias egrep='egrep --color=auto'
+fi
+
+# some more ls aliases
+alias ll='ls -alF'
+alias la='ls -A'
+alias l='ls -CF'
+
+# Add an "alert" alias for long running commands. Use like so:
+# sleep 10; alert
+alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
+
+# Alias definitions.
+# You may want to put all your additions into a separate file like
+# ~/.bash_aliases, instead of adding them here directly.
+# See /usr/share/doc/bash-doc/examples in the bash-doc package.
+
+if [ -f ~/.bash_aliases ]; then
+ . ~/.bash_aliases
+fi
+
+# enable programmable completion features (you don't need to enable
+# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
+# sources /etc/bash.bashrc).
+if ! shopt -oq posix; then
+ if [ -f /usr/share/bash-completion/bash_completion ]; then
+ . /usr/share/bash-completion/bash_completion
+ elif [ -f /etc/bash_completion ]; then
+ . /etc/bash_completion
+ fi
+fi
diff --git a/config/home/vim/autoload/pathogen.vim b/config/home/vim/autoload/pathogen.vim
new file mode 100644
index 0000000..a13ae08
--- /dev/null
+++ b/config/home/vim/autoload/pathogen.vim
@@ -0,0 +1,347 @@
+" pathogen.vim - path option manipulation
+" Maintainer: Tim Pope
+" Version: 2.3
+
+" Install in ~/.vim/autoload (or ~\vimfiles\autoload).
+"
+" For management of individually installed plugins in ~/.vim/bundle (or
+" ~\vimfiles\bundle), adding `execute pathogen#infect()` to the top of your
+" .vimrc is the only other setup necessary.
+"
+" The API is documented inline below.
+
+if exists("g:loaded_pathogen") || &cp
+ finish
+endif
+let g:loaded_pathogen = 1
+
+" Point of entry for basic default usage. Give a relative path to invoke
+" pathogen#interpose() (defaults to "bundle/{}"), or an absolute path to invoke
+" pathogen#surround(). Curly braces are expanded with pathogen#expand():
+" "bundle/{}" finds all subdirectories inside "bundle" inside all directories
+" in the runtime path.
+function! pathogen#infect(...) abort
+ for path in a:0 ? filter(reverse(copy(a:000)), 'type(v:val) == type("")') : ['bundle/{}']
+ if path =~# '^\%({\=[$~\\/]\|{\=\w:[\\/]\).*[{}*]'
+ call pathogen#surround(path)
+ elseif path =~# '^\%([$~\\/]\|\w:[\\/]\)'
+ call s:warn('Change pathogen#infect('.string(path).') to pathogen#infect('.string(path.'/{}').')')
+ call pathogen#surround(path . '/{}')
+ elseif path =~# '[{}*]'
+ call pathogen#interpose(path)
+ else
+ call s:warn('Change pathogen#infect('.string(path).') to pathogen#infect('.string(path.'/{}').')')
+ call pathogen#interpose(path . '/{}')
+ endif
+ endfor
+ call pathogen#cycle_filetype()
+ if pathogen#is_disabled($MYVIMRC)
+ return 'finish'
+ endif
+ return ''
+endfunction
+
+" Split a path into a list.
+function! pathogen#split(path) abort
+ if type(a:path) == type([]) | return a:path | endif
+ if empty(a:path) | return [] | endif
+ let split = split(a:path,'\\\@]','\\&','')
+ endif
+endfunction
+
+" Like findfile(), but hardcoded to use the runtimepath.
+function! pathogen#runtime_findfile(file,count) abort "{{{1
+ let rtp = pathogen#join(1,pathogen#split(&rtp))
+ let file = findfile(a:file,rtp,a:count)
+ if file ==# ''
+ return ''
+ else
+ return fnamemodify(file,':p')
+ endif
+endfunction
+
+" Section: Deprecated
+
+function! s:warn(msg) abort
+ echohl WarningMsg
+ echomsg a:msg
+ echohl NONE
+endfunction
+
+" Prepend all subdirectories of path to the rtp, and append all 'after'
+" directories in those subdirectories. Deprecated.
+function! pathogen#runtime_prepend_subdirectories(path) abort
+ call s:warn('Change pathogen#runtime_prepend_subdirectories('.string(a:path).') to pathogen#infect('.string(a:path.'/{}').')')
+ return pathogen#surround(a:path . pathogen#slash() . '{}')
+endfunction
+
+function! pathogen#incubate(...) abort
+ let name = a:0 ? a:1 : 'bundle/{}'
+ call s:warn('Change pathogen#incubate('.(a:0 ? string(a:1) : '').') to pathogen#infect('.string(name).')')
+ return pathogen#interpose(name)
+endfunction
+
+" Deprecated alias for pathogen#interpose().
+function! pathogen#runtime_append_all_bundles(...) abort
+ if a:0
+ call s:warn('Change pathogen#runtime_append_all_bundles('.string(a:1).') to pathogen#infect('.string(a:1.'/{}').')')
+ else
+ call s:warn('Change pathogen#runtime_append_all_bundles() to pathogen#infect()')
+ endif
+ return pathogen#interpose(a:0 ? a:1 . '/{}' : 'bundle/{}')
+endfunction
+
+if exists(':Vedit')
+ finish
+endif
+
+let s:vopen_warning = 0
+
+function! s:find(count,cmd,file,lcd)
+ let rtp = pathogen#join(1,pathogen#split(&runtimepath))
+ let file = pathogen#runtime_findfile(a:file,a:count)
+ if file ==# ''
+ return "echoerr 'E345: Can''t find file \"".a:file."\" in runtimepath'"
+ endif
+ if !s:vopen_warning
+ let s:vopen_warning = 1
+ let warning = '|echohl WarningMsg|echo "Install scriptease.vim to continue using :V'.a:cmd.'"|echohl NONE'
+ else
+ let warning = ''
+ endif
+ if a:lcd
+ let path = file[0:-strlen(a:file)-2]
+ execute 'lcd `=path`'
+ return a:cmd.' '.pathogen#fnameescape(a:file) . warning
+ else
+ return a:cmd.' '.pathogen#fnameescape(file) . warning
+ endif
+endfunction
+
+function! s:Findcomplete(A,L,P)
+ let sep = pathogen#slash()
+ let cheats = {
+ \'a': 'autoload',
+ \'d': 'doc',
+ \'f': 'ftplugin',
+ \'i': 'indent',
+ \'p': 'plugin',
+ \'s': 'syntax'}
+ if a:A =~# '^\w[\\/]' && has_key(cheats,a:A[0])
+ let request = cheats[a:A[0]].a:A[1:-1]
+ else
+ let request = a:A
+ endif
+ let pattern = substitute(request,'/\|\'.sep,'*'.sep,'g').'*'
+ let found = {}
+ for path in pathogen#split(&runtimepath)
+ let path = expand(path, ':p')
+ let matches = split(glob(path.sep.pattern),"\n")
+ call map(matches,'isdirectory(v:val) ? v:val.sep : v:val')
+ call map(matches,'expand(v:val, ":p")[strlen(path)+1:-1]')
+ for match in matches
+ let found[match] = 1
+ endfor
+ endfor
+ return sort(keys(found))
+endfunction
+
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Ve :execute s:find(,'edit',,0)
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vedit :execute s:find(,'edit',,0)
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vopen :execute s:find(,'edit',,1)
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vsplit :execute s:find(,'split',,1)
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vvsplit :execute s:find(,'vsplit',,1)
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vtabedit :execute s:find(,'tabedit',,1)
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vpedit :execute s:find(,'pedit',,1)
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vread :execute s:find(,'read',,1)
+
+" vim:set et sw=2 foldmethod=expr foldexpr=getline(v\:lnum)=~'^\"\ Section\:'?'>1'\:getline(v\:lnum)=~#'^fu'?'a1'\:getline(v\:lnum)=~#'^endf'?'s1'\:'=':
diff --git a/config/home/vim/bundle/nerdtree/.gitignore b/config/home/vim/bundle/nerdtree/.gitignore
new file mode 100644
index 0000000..3698c0e
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/.gitignore
@@ -0,0 +1,3 @@
+*~
+*.swp
+tags
diff --git a/config/home/vim/bundle/nerdtree/README.markdown b/config/home/vim/bundle/nerdtree/README.markdown
new file mode 100644
index 0000000..880079a
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/README.markdown
@@ -0,0 +1,103 @@
+The NERD Tree
+=============
+
+Intro
+-----
+
+The NERD tree allows you to explore your filesystem and to open files and
+directories. It presents the filesystem to you in the form of a tree which you
+manipulate with the keyboard and/or mouse. It also allows you to perform
+simple filesystem operations.
+
+The following features and functionality are provided by the NERD tree:
+
+ * Files and directories are displayed in a hierarchical tree structure
+ * Different highlighting is provided for the following types of nodes:
+ * files
+ * directories
+ * sym-links
+ * windows .lnk files
+ * read-only files
+ * executable files
+ * Many (customisable) mappings are provided to manipulate the tree:
+ * Mappings to open/close/explore directory nodes
+ * Mappings to open files in new/existing windows/tabs
+ * Mappings to change the current root of the tree
+ * Mappings to navigate around the tree
+ * ...
+ * Directories and files can be bookmarked.
+ * Most NERD tree navigation can also be done with the mouse
+ * Filtering of tree content (can be toggled at runtime)
+ * custom file filters to prevent e.g. vim backup files being displayed
+ * optional displaying of hidden files (. files)
+ * files can be "turned off" so that only directories are displayed
+ * The position and size of the NERD tree window can be customised
+ * The order in which the nodes in the tree are listed can be customised.
+ * A model of your filesystem is created/maintained as you explore it. This
+ has several advantages:
+ * All filesystem information is cached and is only re-read on demand
+ * If you revisit a part of the tree that you left earlier in your
+ session, the directory nodes will be opened/closed as you left them
+ * The script remembers the cursor position and window position in the NERD
+ tree so you can toggle it off (or just close the tree window) and then
+ reopen it (with NERDTreeToggle) the NERD tree window will appear exactly
+ as you left it
+ * You can have a separate NERD tree for each tab, share trees across tabs,
+ or a mix of both.
+ * By default the script overrides the default file browser (netrw), so if
+ you :edit a directory a (slightly modified) NERD tree will appear in the
+ current window
+ * A programmable menu system is provided (simulates right clicking on a node)
+ * one default menu plugin is provided to perform basic filesystem
+ operations (create/delete/move/copy files/directories)
+ * There's an API for adding your own keymappings
+
+Installation
+------------
+
+[pathogen.vim](https://github.com/tpope/vim-pathogen) is the recommended way to install nerdtree.
+
+ cd ~/.vim/bundle
+ git clone https://github.com/scrooloose/nerdtree.git
+
+Then reload vim, run `:Helptags`, and check out `:help NERD_tree.txt`.
+
+
+Faq
+---
+
+> Is there any support for `git` flags?
+
+Yes, install [nerdtree-git-plugin](https://github.com/Xuyuanp/nerdtree-git-plugin).
+
+
+> Can I have the nerdtree on every tab automatically?
+
+Nope. If this is something you want then chances are you aren't using tabs and
+buffers as they were intended to be used. Read this
+http://stackoverflow.com/questions/102384/using-vims-tabs-like-buffers
+
+If you are interested in this behaviour then consider [vim-nerdtree-tabs](https://github.com/jistr/vim-nerdtree-tabs)
+
+> How can I open a NERDTree automatically when vim starts up?
+
+Stick this in your vimrc: `autocmd vimenter * NERDTree`
+
+> How can I open a NERDTree automatically when vim starts up if no files were specified?
+
+Stick this in your vimrc
+
+ autocmd StdinReadPre * let s:std_in=1
+ autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
+
+> 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):
+
+`map :NERDTreeToggle`
+
+> How can I close vim if the only window left open is a NERDTree?
+
+Stick this in your vimrc:
+
+ `autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif`
diff --git a/config/home/vim/bundle/nerdtree/autoload/nerdtree.vim b/config/home/vim/bundle/nerdtree/autoload/nerdtree.vim
new file mode 100644
index 0000000..22283aa
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/autoload/nerdtree.vim
@@ -0,0 +1,136 @@
+if exists("g:loaded_nerdtree_autoload")
+ finish
+endif
+let g:loaded_nerdtree_autoload = 1
+
+function! nerdtree#version()
+ return '4.2.0'
+endfunction
+
+" SECTION: General Functions {{{1
+"============================================================
+
+"FUNCTION: nerdtree#checkForBrowse(dir) {{{2
+"inits a secondary nerd tree in the current buffer if appropriate
+function! nerdtree#checkForBrowse(dir)
+ if a:dir != '' && isdirectory(a:dir)
+ call g:NERDTreeCreator.CreateSecondary(a:dir)
+ endif
+endfunction
+
+" FUNCTION: nerdtree#completeBookmarks(A,L,P) {{{2
+" completion function for the bookmark commands
+function! nerdtree#completeBookmarks(A,L,P)
+ return filter(g:NERDTreeBookmark.BookmarkNames(), 'v:val =~# "^' . a:A . '"')
+endfunction
+
+"FUNCTION: nerdtree#compareBookmarks(dir) {{{2
+function! nerdtree#compareBookmarks(first, second)
+ return a:first.compareTo(a:second)
+endfunction
+
+"FUNCTION: nerdtree#compareNodes(dir) {{{2
+function! nerdtree#compareNodes(n1, n2)
+ return a:n1.path.compareTo(a:n2.path)
+endfunction
+
+" FUNCTION: nerdtree#deprecated(func, [msg]) {{{2
+" Issue a deprecation warning for a:func. If a second arg is given, use this
+" as the deprecation message
+function! nerdtree#deprecated(func, ...)
+ let msg = a:0 ? a:func . ' ' . a:1 : a:func . ' is deprecated'
+
+ if !exists('s:deprecationWarnings')
+ let s:deprecationWarnings = {}
+ endif
+ if !has_key(s:deprecationWarnings, a:func)
+ let s:deprecationWarnings[a:func] = 1
+ echomsg msg
+ endif
+endfunction
+
+" FUNCTION: nerdtree#exec(cmd) {{{2
+" same as :exec cmd but eventignore=all is set for the duration
+function! nerdtree#exec(cmd)
+ let old_ei = &ei
+ set ei=all
+ exec a:cmd
+ let &ei = old_ei
+endfunction
+
+" FUNCTION: nerdtree#has_opt(options, name) {{{2
+function! nerdtree#has_opt(options, name)
+ return has_key(a:options, a:name) && a:options[a:name] == 1
+endfunction
+
+" FUNCTION: nerdtree#loadClassFiles() {{{2
+function! nerdtree#loadClassFiles()
+ runtime lib/nerdtree/path.vim
+ runtime lib/nerdtree/menu_controller.vim
+ runtime lib/nerdtree/menu_item.vim
+ runtime lib/nerdtree/key_map.vim
+ runtime lib/nerdtree/bookmark.vim
+ runtime lib/nerdtree/tree_file_node.vim
+ runtime lib/nerdtree/tree_dir_node.vim
+ runtime lib/nerdtree/opener.vim
+ runtime lib/nerdtree/creator.vim
+ runtime lib/nerdtree/flag_set.vim
+ runtime lib/nerdtree/nerdtree.vim
+ runtime lib/nerdtree/ui.vim
+ runtime lib/nerdtree/event.vim
+ runtime lib/nerdtree/notifier.vim
+endfunction
+
+" FUNCTION: nerdtree#postSourceActions() {{{2
+function! nerdtree#postSourceActions()
+ call g:NERDTreeBookmark.CacheBookmarks(0)
+ call nerdtree#ui_glue#createDefaultBindings()
+
+ "load all nerdtree plugins
+ runtime! nerdtree_plugin/**/*.vim
+endfunction
+
+"FUNCTION: nerdtree#runningWindows(dir) {{{2
+function! nerdtree#runningWindows()
+ return has("win16") || has("win32") || has("win64")
+endfunction
+
+" SECTION: View Functions {{{1
+"============================================================
+
+"FUNCTION: nerdtree#echo {{{2
+"A wrapper for :echo. Appends 'NERDTree:' on the front of all messages
+"
+"Args:
+"msg: the message to echo
+function! nerdtree#echo(msg)
+ redraw
+ echomsg "NERDTree: " . a:msg
+endfunction
+
+"FUNCTION: nerdtree#echoError {{{2
+"Wrapper for nerdtree#echo, sets the message type to errormsg for this message
+"Args:
+"msg: the message to echo
+function! nerdtree#echoError(msg)
+ echohl errormsg
+ call nerdtree#echo(a:msg)
+ echohl normal
+endfunction
+
+"FUNCTION: nerdtree#echoWarning {{{2
+"Wrapper for nerdtree#echo, sets the message type to warningmsg for this message
+"Args:
+"msg: the message to echo
+function! nerdtree#echoWarning(msg)
+ echohl warningmsg
+ call nerdtree#echo(a:msg)
+ echohl normal
+endfunction
+
+"FUNCTION: nerdtree#renderView {{{2
+function! nerdtree#renderView()
+ call b:NERDTree.render()
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/nerdtree/autoload/nerdtree/ui_glue.vim b/config/home/vim/bundle/nerdtree/autoload/nerdtree/ui_glue.vim
new file mode 100644
index 0000000..1f922df
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/autoload/nerdtree/ui_glue.vim
@@ -0,0 +1,644 @@
+if exists("g:loaded_nerdtree_ui_glue_autoload")
+ finish
+endif
+let g:loaded_nerdtree_ui_glue_autoload = 1
+
+" FUNCTION: nerdtree#ui_glue#createDefaultBindings() {{{1
+function! nerdtree#ui_glue#createDefaultBindings()
+ let s = '' . s:SID() . '_'
+
+ call NERDTreeAddKeyMap({ 'key': '', 'scope': "all", 'callback': s."handleMiddleMouse" })
+ call NERDTreeAddKeyMap({ 'key': '', 'scope': "all", 'callback': s."handleLeftClick" })
+ call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "DirNode", 'callback': s."activateDirNode" })
+ call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "FileNode", 'callback': s."activateFileNode" })
+ call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "Bookmark", 'callback': s."activateBookmark" })
+ call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "all", 'callback': s."activateAll" })
+
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "DirNode", 'callback': s."activateDirNode" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "FileNode", 'callback': s."activateFileNode" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "Bookmark", 'callback': s."activateBookmark" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "all", 'callback': s."activateAll" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': "Node", 'callback': s."openHSplit" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': "Node", 'callback': s."openVSplit" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': "Bookmark", 'callback': s."openHSplit" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': "Bookmark", 'callback': s."openVSplit" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': "Node", 'callback': s."previewNodeCurrent" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': "Node", 'callback': s."previewNodeVSplit" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': "Node", 'callback': s."previewNodeHSplit" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': "Bookmark", 'callback': s."previewNodeCurrent" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': "Bookmark", 'callback': s."previewNodeVSplit" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': "Bookmark", 'callback': s."previewNodeHSplit" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenRecursively, 'scope': "DirNode", 'callback': s."openNodeRecursively" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdir, 'scope': "all", 'callback': s."upDirCurrentRootClosed" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdirKeepOpen, 'scope': "all", 'callback': s."upDirCurrentRootOpen" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChangeRoot, 'scope': "Node", 'callback': s."chRoot" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChdir, 'scope': "Node", 'callback': s."chCwd" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapQuit, 'scope': "all", 'callback': s."closeTreeWindow" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCWD, 'scope': "all", 'callback': "nerdtree#ui_glue#chRootCwd" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefreshRoot, 'scope': "all", 'callback': s."refreshRoot" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefresh, 'scope': "Node", 'callback': s."refreshCurrent" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapHelp, 'scope': "all", 'callback': s."displayHelp" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleZoom, 'scope': "all", 'callback': s."toggleZoom" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleHidden, 'scope': "all", 'callback': s."toggleShowHidden" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFilters, 'scope': "all", 'callback': s."toggleIgnoreFilter" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFiles, 'scope': "all", 'callback': s."toggleShowFiles" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleBookmarks, 'scope': "all", 'callback': s."toggleShowBookmarks" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseDir, 'scope': "Node", 'callback': s."closeCurrentDir" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseChildren, 'scope': "DirNode", 'callback': s."closeChildren" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapMenu, 'scope': "Node", 'callback': s."showMenu" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpParent, 'scope': "Node", 'callback': s."jumpToParent" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpFirstChild, 'scope': "Node", 'callback': s."jumpToFirstChild" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpLastChild, 'scope': "Node", 'callback': s."jumpToLastChild" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpRoot, 'scope': "all", 'callback': s."jumpToRoot" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpNextSibling, 'scope': "Node", 'callback': s."jumpToNextSibling" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpPrevSibling, 'scope': "Node", 'callback': s."jumpToPrevSibling" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': "Node", 'callback': s."openInNewTab" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': "Node", 'callback': s."openInNewTabSilent" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': "Bookmark", 'callback': s."openInNewTab" })
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': "Bookmark", 'callback': s."openInNewTabSilent" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenExpl, 'scope': "DirNode", 'callback': s."openExplorer" })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapDeleteBookmark, 'scope': "Bookmark", 'callback': s."deleteBookmark" })
+endfunction
+
+
+"SECTION: Interface bindings {{{1
+"============================================================
+
+"FUNCTION: s:activateAll() {{{1
+"handle the user activating the updir line
+function! s:activateAll()
+ if getline(".") ==# g:NERDTreeUI.UpDirLine()
+ return nerdtree#ui_glue#upDir(0)
+ endif
+endfunction
+
+"FUNCTION: s:activateDirNode() {{{1
+"handle the user activating a tree node
+function! s:activateDirNode(node)
+ call a:node.activate()
+endfunction
+
+"FUNCTION: s:activateFileNode() {{{1
+"handle the user activating a tree node
+function! s:activateFileNode(node)
+ call a:node.activate({'reuse': 'all', 'where': 'p'})
+endfunction
+
+"FUNCTION: s:activateBookmark() {{{1
+"handle the user activating a bookmark
+function! s:activateBookmark(bm)
+ call a:bm.activate(!a:bm.path.isDirectory ? {'where': 'p'} : {})
+endfunction
+
+" FUNCTION: nerdtree#ui_glue#bookmarkNode(name) {{{1
+" Associate the current node with the given name
+function! nerdtree#ui_glue#bookmarkNode(...)
+ let currentNode = g:NERDTreeFileNode.GetSelected()
+ if currentNode != {}
+ let name = a:1
+ if empty(name)
+ let name = currentNode.path.getLastPathComponent(0)
+ endif
+ try
+ call currentNode.bookmark(name)
+ call b:NERDTree.render()
+ catch /^NERDTree.IllegalBookmarkNameError/
+ call nerdtree#echo("bookmark names must not contain spaces")
+ endtry
+ else
+ call nerdtree#echo("select a node first")
+ endif
+endfunction
+
+" FUNCTION: s:chCwd(node) {{{1
+function! s:chCwd(node)
+ try
+ call a:node.path.changeToDir()
+ catch /^NERDTree.PathChangeError/
+ call nerdtree#echoWarning("could not change cwd")
+ endtry
+endfunction
+
+" FUNCTION: s:chRoot(node) {{{1
+" changes the current root to the selected one
+function! s:chRoot(node)
+ call a:node.makeRoot()
+ call b:NERDTree.render()
+ call b:NERDTreeRoot.putCursorHere(0, 0)
+endfunction
+
+" FUNCTION: s:nerdtree#ui_glue#chRootCwd() {{{1
+" changes the current root to CWD
+function! nerdtree#ui_glue#chRootCwd()
+ try
+ let cwd = g:NERDTreePath.New(getcwd())
+ catch /^NERDTree.InvalidArgumentsError/
+ call nerdtree#echo("current directory does not exist.")
+ return
+ endtry
+ if cwd.str() == g:NERDTreeFileNode.GetRootForTab().path.str()
+ return
+ endif
+ call s:chRoot(g:NERDTreeDirNode.New(cwd))
+endfunction
+
+" FUNCTION: nnerdtree#ui_glue#clearBookmarks(bookmarks) {{{1
+function! nerdtree#ui_glue#clearBookmarks(bookmarks)
+ if a:bookmarks ==# ''
+ let currentNode = g:NERDTreeFileNode.GetSelected()
+ if currentNode != {}
+ call currentNode.clearBookmarks()
+ endif
+ else
+ for name in split(a:bookmarks, ' ')
+ let bookmark = g:NERDTreeBookmark.BookmarkFor(name)
+ call bookmark.delete()
+ endfor
+ endif
+ call b:NERDTree.render()
+endfunction
+
+" FUNCTION: s:closeChildren(node) {{{1
+" closes all childnodes of the current node
+function! s:closeChildren(node)
+ call a:node.closeChildren()
+ call b:NERDTree.render()
+ call a:node.putCursorHere(0, 0)
+endfunction
+
+" FUNCTION: s:closeCurrentDir(node) {{{1
+" closes the parent dir of the current node
+function! s:closeCurrentDir(node)
+ let parent = a:node.parent
+ if parent ==# {} || parent.isRoot()
+ call nerdtree#echo("cannot close tree root")
+ else
+ while g:NERDTreeCascadeOpenSingleChildDir && !parent.parent.isRoot()
+ if parent.parent.getVisibleChildCount() == 1
+ call parent.close()
+ let parent = parent.parent
+ else
+ break
+ endif
+ endwhile
+ call parent.close()
+ call b:NERDTree.render()
+ call parent.putCursorHere(0, 0)
+ endif
+endfunction
+
+" FUNCTION: s:closeTreeWindow() {{{1
+" close the tree window
+function! s:closeTreeWindow()
+ if b:NERDTreeType ==# "secondary" && b:NERDTreePreviousBuf != -1
+ exec "buffer " . b:NERDTreePreviousBuf
+ else
+ if winnr("$") > 1
+ call g:NERDTree.Close()
+ else
+ call nerdtree#echo("Cannot close last window")
+ endif
+ endif
+endfunction
+
+" FUNCTION: s:deleteBookmark(bm) {{{1
+" if the cursor is on a bookmark, prompt to delete
+function! s:deleteBookmark(bm)
+ echo "Are you sure you wish to delete the bookmark:\n\"" . a:bm.name . "\" (yN):"
+
+ if nr2char(getchar()) ==# 'y'
+ try
+ call a:bm.delete()
+ call b:NERDTree.render()
+ redraw
+ catch /^NERDTree/
+ call nerdtree#echoWarning("Could not remove bookmark")
+ endtry
+ else
+ call nerdtree#echo("delete aborted" )
+ endif
+
+endfunction
+
+" FUNCTION: s:displayHelp() {{{1
+" toggles the help display
+function! s:displayHelp()
+ let b:treeShowHelp = b:treeShowHelp ? 0 : 1
+ call b:NERDTree.render()
+ call b:NERDTree.ui.centerView()
+endfunction
+
+" FUNCTION: s:findAndRevealPath() {{{1
+function! s:findAndRevealPath()
+ try
+ let p = g:NERDTreePath.New(expand("%:p"))
+ catch /^NERDTree.InvalidArgumentsError/
+ call nerdtree#echo("no file for the current buffer")
+ return
+ endtry
+
+ if p.isUnixHiddenPath()
+ let showhidden=g:NERDTreeShowHidden
+ let g:NERDTreeShowHidden = 1
+ endif
+
+ if !g:NERDTree.ExistsForTab()
+ try
+ let cwd = g:NERDTreePath.New(getcwd())
+ catch /^NERDTree.InvalidArgumentsError/
+ call nerdtree#echo("current directory does not exist.")
+ let cwd = p.getParent()
+ endtry
+
+ if p.isUnder(cwd)
+ call g:NERDTreeCreator.CreatePrimary(cwd.str())
+ else
+ call g:NERDTreeCreator.CreatePrimary(p.getParent().str())
+ endif
+ else
+ if !p.isUnder(g:NERDTreeFileNode.GetRootForTab().path)
+ if !g:NERDTree.IsOpen()
+ call g:NERDTreeCreator.TogglePrimary('')
+ else
+ call g:NERDTree.CursorToTreeWin()
+ endif
+ let b:NERDTreeShowHidden = g:NERDTreeShowHidden
+ call s:chRoot(g:NERDTreeDirNode.New(p.getParent()))
+ else
+ if !g:NERDTree.IsOpen()
+ call g:NERDTreeCreator.TogglePrimary("")
+ endif
+ endif
+ endif
+ call g:NERDTree.CursorToTreeWin()
+ call b:NERDTreeRoot.reveal(p)
+
+ if p.isUnixHiddenFile()
+ let g:NERDTreeShowHidden = showhidden
+ endif
+endfunction
+
+"FUNCTION: s:handleLeftClick() {{{1
+"Checks if the click should open the current node
+function! s:handleLeftClick()
+ let currentNode = g:NERDTreeFileNode.GetSelected()
+ if currentNode != {}
+
+ "the dir arrows are multibyte chars, and vim's string functions only
+ "deal with single bytes - so split the line up with the hack below and
+ "take the line substring manually
+ let line = split(getline(line(".")), '\zs')
+ let startToCur = ""
+ for i in range(0,len(line)-1)
+ let startToCur .= line[i]
+ endfor
+
+ if currentNode.path.isDirectory
+ if startToCur =~# g:NERDTreeUI.MarkupReg() && startToCur =~# '[+~▾▸] \?$'
+ call currentNode.activate()
+ return
+ endif
+ endif
+
+ if (g:NERDTreeMouseMode ==# 2 && currentNode.path.isDirectory) || g:NERDTreeMouseMode ==# 3
+ let char = strpart(startToCur, strlen(startToCur)-1, 1)
+ if char !~# g:NERDTreeUI.MarkupReg()
+ if currentNode.path.isDirectory
+ call currentNode.activate()
+ else
+ call currentNode.activate({'reuse': 'all', 'where': 'p'})
+ endif
+ return
+ endif
+ endif
+ endif
+endfunction
+
+" FUNCTION: s:handleMiddleMouse() {{{1
+function! s:handleMiddleMouse()
+ let curNode = g:NERDTreeFileNode.GetSelected()
+ if curNode ==# {}
+ call nerdtree#echo("Put the cursor on a node first" )
+ return
+ endif
+
+ if curNode.path.isDirectory
+ call nerdtree#openExplorer(curNode)
+ else
+ call curNode.open({'where': 'h'})
+ endif
+endfunction
+
+" FUNCTION: s:jumpToChild(direction) {{{2
+" Args:
+" direction: 0 if going to first child, 1 if going to last
+function! s:jumpToChild(currentNode, direction)
+ if a:currentNode.isRoot()
+ return nerdtree#echo("cannot jump to " . (a:direction ? "last" : "first") . " child")
+ end
+ let dirNode = a:currentNode.parent
+ let childNodes = dirNode.getVisibleChildren()
+
+ let targetNode = childNodes[0]
+ if a:direction
+ let targetNode = childNodes[len(childNodes) - 1]
+ endif
+
+ if targetNode.equals(a:currentNode)
+ let siblingDir = a:currentNode.parent.findOpenDirSiblingWithVisibleChildren(a:direction)
+ if siblingDir != {}
+ let indx = a:direction ? siblingDir.getVisibleChildCount()-1 : 0
+ let targetNode = siblingDir.getChildByIndex(indx, 1)
+ endif
+ endif
+
+ call targetNode.putCursorHere(1, 0)
+
+ call b:NERDTree.ui.centerView()
+endfunction
+
+
+" FUNCTION: nerdtree#ui_glue#invokeKeyMap(key) {{{1
+"this is needed since I cant figure out how to invoke dict functions from a
+"key map
+function! nerdtree#ui_glue#invokeKeyMap(key)
+ call g:NERDTreeKeyMap.Invoke(a:key)
+endfunction
+
+" FUNCTION: s:jumpToFirstChild() {{{1
+" wrapper for the jump to child method
+function! s:jumpToFirstChild(node)
+ call s:jumpToChild(a:node, 0)
+endfunction
+
+" FUNCTION: s:jumpToLastChild() {{{1
+" wrapper for the jump to child method
+function! s:jumpToLastChild(node)
+ call s:jumpToChild(a:node, 1)
+endfunction
+
+" FUNCTION: s:jumpToParent(node) {{{1
+" moves the cursor to the parent of the current node
+function! s:jumpToParent(node)
+ if !empty(a:node.parent)
+ call a:node.parent.putCursorHere(1, 0)
+ call b:NERDTree.ui.centerView()
+ else
+ call nerdtree#echo("cannot jump to parent")
+ endif
+endfunction
+
+" FUNCTION: s:jumpToRoot() {{{1
+" moves the cursor to the root node
+function! s:jumpToRoot()
+ call b:NERDTreeRoot.putCursorHere(1, 0)
+ call b:NERDTree.ui.centerView()
+endfunction
+
+" FUNCTION: s:jumpToNextSibling(node) {{{1
+function! s:jumpToNextSibling(node)
+ call s:jumpToSibling(a:node, 1)
+endfunction
+
+" FUNCTION: s:jumpToPrevSibling(node) {{{1
+function! s:jumpToPrevSibling(node)
+ call s:jumpToSibling(a:node, 0)
+endfunction
+
+" FUNCTION: s:jumpToSibling(currentNode, forward) {{{2
+" moves the cursor to the sibling of the current node in the given direction
+"
+" Args:
+" forward: 1 if the cursor should move to the next sibling, 0 if it should
+" move back to the previous sibling
+function! s:jumpToSibling(currentNode, forward)
+ let sibling = a:currentNode.findSibling(a:forward)
+
+ if !empty(sibling)
+ call sibling.putCursorHere(1, 0)
+ call b:NERDTree.ui.centerView()
+ endif
+endfunction
+
+" FUNCTION: nerdtree#ui_glue#openBookmark(name) {{{1
+" put the cursor on the given bookmark and, if its a file, open it
+function! nerdtree#ui_glue#openBookmark(name)
+ try
+ let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0)
+ call targetNode.putCursorHere(0, 1)
+ redraw!
+ catch /^NERDTree.BookmarkedNodeNotFoundError/
+ call nerdtree#echo("note - target node is not cached")
+ let bookmark = g:NERDTreeBookmark.BookmarkFor(a:name)
+ let targetNode = g:NERDTreeFileNode.New(bookmark.path)
+ endtry
+ if targetNode.path.isDirectory
+ call targetNode.openExplorer()
+ else
+ call targetNode.open({'where': 'p'})
+ endif
+endfunction
+
+" FUNCTION: s:openHSplit(target) {{{1
+function! s:openHSplit(target)
+ call a:target.activate({'where': 'h'})
+endfunction
+
+" FUNCTION: s:openVSplit(target) {{{1
+function! s:openVSplit(target)
+ call a:target.activate({'where': 'v'})
+endfunction
+
+" FUNCTION: s:openExplorer(node) {{{1
+function! s:openExplorer(node)
+ call a:node.openExplorer()
+endfunction
+
+" FUNCTION: s:openInNewTab(target) {{{1
+function! s:openInNewTab(target)
+ call a:target.activate({'where': 't'})
+endfunction
+
+" FUNCTION: s:openInNewTabSilent(target) {{{1
+function! s:openInNewTabSilent(target)
+ call a:target.activate({'where': 't', 'stay': 1})
+endfunction
+
+" FUNCTION: s:openNodeRecursively(node) {{{1
+function! s:openNodeRecursively(node)
+ call nerdtree#echo("Recursively opening node. Please wait...")
+ call a:node.openRecursively()
+ call b:NERDTree.render()
+ redraw
+ call nerdtree#echo("Recursively opening node. Please wait... DONE")
+endfunction
+
+"FUNCTION: s:previewNodeCurrent(node) {{{1
+function! s:previewNodeCurrent(node)
+ call a:node.open({'stay': 1, 'where': 'p', 'keepopen': 1})
+endfunction
+
+"FUNCTION: s:previewNodeHSplit(node) {{{1
+function! s:previewNodeHSplit(node)
+ call a:node.open({'stay': 1, 'where': 'h', 'keepopen': 1})
+endfunction
+
+"FUNCTION: s:previewNodeVSplit(node) {{{1
+function! s:previewNodeVSplit(node)
+ call a:node.open({'stay': 1, 'where': 'v', 'keepopen': 1})
+endfunction
+
+" FUNCTION: nerdtree#ui_glue#revealBookmark(name) {{{1
+" put the cursor on the node associate with the given name
+function! nerdtree#ui_glue#revealBookmark(name)
+ try
+ let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0)
+ call targetNode.putCursorHere(0, 1)
+ catch /^NERDTree.BookmarkNotFoundError/
+ call nerdtree#echo("Bookmark isnt cached under the current root")
+ endtry
+endfunction
+
+" FUNCTION: s:refreshRoot() {{{1
+" Reloads the current root. All nodes below this will be lost and the root dir
+" will be reloaded.
+function! s:refreshRoot()
+ call nerdtree#echo("Refreshing the root node. This could take a while...")
+ call b:NERDTreeRoot.refresh()
+ call b:NERDTree.render()
+ redraw
+ call nerdtree#echo("Refreshing the root node. This could take a while... DONE")
+endfunction
+
+" FUNCTION: s:refreshCurrent(node) {{{1
+" refreshes the root for the current node
+function! s:refreshCurrent(node)
+ let node = a:node
+ if !node.path.isDirectory
+ let node = node.parent
+ endif
+
+ call nerdtree#echo("Refreshing node. This could take a while...")
+ call node.refresh()
+ call b:NERDTree.render()
+ redraw
+ call nerdtree#echo("Refreshing node. This could take a while... DONE")
+endfunction
+
+" FUNCTION: nerdtree#ui_glue#setupCommands() {{{1
+function! nerdtree#ui_glue#setupCommands()
+ command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreatePrimary('')
+ command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.TogglePrimary('')
+ command! -n=0 -bar NERDTreeClose :call g:NERDTree.Close()
+ command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreatePrimary('')
+ command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror()
+ command! -n=0 -bar NERDTreeFind call s:findAndRevealPath()
+ command! -n=0 -bar NERDTreeFocus call NERDTreeFocus()
+ command! -n=0 -bar NERDTreeCWD call NERDTreeCWD()
+endfunction
+
+" Function: s:SID() {{{1
+function s:SID()
+ if !exists("s:sid")
+ let s:sid = matchstr(expand(''), '\zs\d\+\ze_SID$')
+ endif
+ return s:sid
+endfun
+
+" FUNCTION: s:showMenu(node) {{{1
+function! s:showMenu(node)
+ let mc = g:NERDTreeMenuController.New(g:NERDTreeMenuItem.AllEnabled())
+ call mc.showMenu()
+endfunction
+
+" FUNCTION: s:toggleIgnoreFilter() {{{1
+function! s:toggleIgnoreFilter()
+ call b:NERDTree.ui.toggleIgnoreFilter()
+endfunction
+
+" FUNCTION: s:toggleShowBookmarks() {{{1
+function! s:toggleShowBookmarks()
+ call b:NERDTree.ui.toggleShowBookmarks()
+endfunction
+
+" FUNCTION: s:toggleShowFiles() {{{1
+function! s:toggleShowFiles()
+ call b:NERDTree.ui.toggleShowFiles()
+endfunction
+
+" FUNCTION: s:toggleShowHidden() {{{1
+" toggles the display of hidden files
+function! s:toggleShowHidden()
+ call b:NERDTree.ui.toggleShowHidden()
+endfunction
+
+" FUNCTION: s:toggleZoom() {{{1
+function! s:toggleZoom()
+ call b:NERDTree.ui.toggleZoom()
+endfunction
+
+"FUNCTION: nerdtree#ui_glue#upDir(keepState) {{{1
+"moves the tree up a level
+"
+"Args:
+"keepState: 1 if the current root should be left open when the tree is
+"re-rendered
+function! nerdtree#ui_glue#upDir(keepState)
+ let cwd = b:NERDTreeRoot.path.str({'format': 'UI'})
+ if cwd ==# "/" || cwd =~# '^[^/]..$'
+ call nerdtree#echo("already at top dir")
+ else
+ if !a:keepState
+ call b:NERDTreeRoot.close()
+ endif
+
+ let oldRoot = b:NERDTreeRoot
+
+ if empty(b:NERDTreeRoot.parent)
+ let path = b:NERDTreeRoot.path.getParent()
+ let newRoot = g:NERDTreeDirNode.New(path)
+ call newRoot.open()
+ call newRoot.transplantChild(b:NERDTreeRoot)
+ let b:NERDTreeRoot = newRoot
+ else
+ let b:NERDTreeRoot = b:NERDTreeRoot.parent
+ endif
+
+ if g:NERDTreeChDirMode ==# 2
+ call b:NERDTreeRoot.path.changeToDir()
+ endif
+
+ call b:NERDTree.render()
+ call oldRoot.putCursorHere(0, 0)
+ endif
+endfunction
+
+" FUNCTION: s:upDirCurrentRootOpen() {{{1
+function! s:upDirCurrentRootOpen()
+ call nerdtree#ui_glue#upDir(1)
+endfunction
+
+" FUNCTION: s:upDirCurrentRootClosed() {{{1
+function! s:upDirCurrentRootClosed()
+ call nerdtree#ui_glue#upDir(0)
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/nerdtree/doc/NERD_tree.txt b/config/home/vim/bundle/nerdtree/doc/NERD_tree.txt
new file mode 100644
index 0000000..6418b57
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/doc/NERD_tree.txt
@@ -0,0 +1,1399 @@
+*NERD_tree.txt* A tree explorer plugin that owns your momma!
+
+
+
+ omg its ... ~
+
+ ________ ________ _ ____________ ____ __________ ____________~
+ /_ __/ / / / ____/ / | / / ____/ __ \/ __ \ /_ __/ __ \/ ____/ ____/~
+ / / / /_/ / __/ / |/ / __/ / /_/ / / / / / / / /_/ / __/ / __/ ~
+ / / / __ / /___ / /| / /___/ _, _/ /_/ / / / / _, _/ /___/ /___ ~
+ /_/ /_/ /_/_____/ /_/ |_/_____/_/ |_/_____/ /_/ /_/ |_/_____/_____/ ~
+
+
+ Reference Manual~
+
+
+
+
+==============================================================================
+CONTENTS *NERDTree-contents*
+
+ 1.Intro...................................|NERDTree|
+ 2.Functionality provided..................|NERDTreeFunctionality|
+ 2.1.Global commands...................|NERDTreeGlobalCommands|
+ 2.2.Bookmarks.........................|NERDTreeBookmarks|
+ 2.2.1.The bookmark table..........|NERDTreeBookmarkTable|
+ 2.2.2.Bookmark commands...........|NERDTreeBookmarkCommands|
+ 2.2.3.Invalid bookmarks...........|NERDTreeInvalidBookmarks|
+ 2.3.NERD tree mappings................|NERDTreeMappings|
+ 2.4.The NERD tree menu................|NERDTreeMenu|
+ 3.Options.................................|NERDTreeOptions|
+ 3.1.Option summary....................|NERDTreeOptionSummary|
+ 3.2.Option details....................|NERDTreeOptionDetails|
+ 4.The NERD tree API.......................|NERDTreeAPI|
+ 4.1.Key map API.......................|NERDTreeKeymapAPI|
+ 4.2.Menu API..........................|NERDTreeMenuAPI|
+ 4.3.Menu API..........................|NERDTreeAddPathFilter()|
+ 5.About...................................|NERDTreeAbout|
+ 6.Changelog...............................|NERDTreeChangelog|
+ 7.Credits.................................|NERDTreeCredits|
+ 8.License.................................|NERDTreeLicense|
+
+==============================================================================
+1. Intro *NERDTree*
+
+What is this "NERD tree"??
+
+The NERD tree allows you to explore your filesystem and to open files and
+directories. It presents the filesystem to you in the form of a tree which you
+manipulate with the keyboard and/or mouse. It also allows you to perform
+simple filesystem operations.
+
+The following features and functionality are provided by the NERD tree:
+ * Files and directories are displayed in a hierarchical tree structure
+ * Different highlighting is provided for the following types of nodes:
+ * files
+ * directories
+ * sym-links
+ * windows .lnk files
+ * read-only files
+ * executable files
+ * Many (customisable) mappings are provided to manipulate the tree:
+ * Mappings to open/close/explore directory nodes
+ * Mappings to open files in new/existing windows/tabs
+ * Mappings to change the current root of the tree
+ * Mappings to navigate around the tree
+ * ...
+ * Directories and files can be bookmarked.
+ * Most NERD tree navigation can also be done with the mouse
+ * Filtering of tree content (can be toggled at runtime)
+ * custom file filters to prevent e.g. vim backup files being displayed
+ * optional displaying of hidden files (. files)
+ * files can be "turned off" so that only directories are displayed
+ * The position and size of the NERD tree window can be customised
+ * The order in which the nodes in the tree are listed can be customised.
+ * A model of your filesystem is created/maintained as you explore it. This
+ has several advantages:
+ * All filesystem information is cached and is only re-read on demand
+ * If you revisit a part of the tree that you left earlier in your
+ session, the directory nodes will be opened/closed as you left them
+ * The script remembers the cursor position and window position in the NERD
+ tree so you can toggle it off (or just close the tree window) and then
+ reopen it (with NERDTreeToggle) the NERD tree window will appear exactly
+ as you left it
+ * You can have a separate NERD tree for each tab, share trees across tabs,
+ or a mix of both.
+ * By default the script overrides the default file browser (netrw), so if
+ you :edit a directory a (slightly modified) NERD tree will appear in the
+ current window
+ * A programmable menu system is provided (simulates right clicking on a
+ node)
+ * one default menu plugin is provided to perform basic filesystem
+ operations (create/delete/move/copy files/directories)
+ * There's an API for adding your own keymappings
+
+
+==============================================================================
+2. Functionality provided *NERDTreeFunctionality*
+
+------------------------------------------------------------------------------
+2.1. Global Commands *NERDTreeGlobalCommands*
+
+:NERDTree [ | ] *:NERDTree*
+ Opens a fresh NERD tree. The root of the tree depends on the argument
+ given. There are 3 cases: If no argument is given, the current directory
+ will be used. If a directory is given, that will be used. If a bookmark
+ name is given, the corresponding directory will be used. For example: >
+ :NERDTree /home/marty/vim7/src
+ :NERDTree foo (foo is the name of a bookmark)
+<
+:NERDTreeFromBookmark *:NERDTreeFromBookmark*
+ Opens a fresh NERD tree with the root initialized to the dir for
+ . The only reason to use this command over :NERDTree is for
+ the completion (which is for bookmarks rather than directories).
+
+:NERDTreeToggle [ | ] *:NERDTreeToggle*
+ If a NERD tree already exists for this tab, it is reopened and rendered
+ again. If no NERD tree exists for this tab then this command acts the
+ same as the |:NERDTree| command.
+
+:NERDTreeMirror *:NERDTreeMirror*
+ Shares an existing NERD tree, from another tab, in the current tab.
+ Changes made to one tree are reflected in both as they are actually the
+ same buffer.
+
+ If only one other NERD tree exists, that tree is automatically mirrored. If
+ more than one exists, the script will ask which tree to mirror.
+
+:NERDTreeClose *:NERDTreeClose*
+ Close the NERD tree in this tab.
+
+:NERDTreeFind *:NERDTreeFind*
+ Find the current file in the tree.
+
+ If no tree exists and the current file is under vim's CWD, then init a
+ tree at the CWD and reveal the file. Otherwise init a tree in the current
+ file's directory.
+
+ In any case, the current file is revealed and the cursor is placed on it.
+
+:NERDTreeCWD *:NERDTreeCWD*
+ Change tree root to current directory. If no NERD tree exists for this
+ tab, a new tree will be opened.
+
+------------------------------------------------------------------------------
+2.2. Bookmarks *NERDTreeBookmarks*
+
+Bookmarks in the NERD tree are a way to tag files or directories of interest.
+For example, you could use bookmarks to tag all of your project directories.
+
+------------------------------------------------------------------------------
+2.2.1. The Bookmark Table *NERDTreeBookmarkTable*
+
+If the bookmark table is active (see |NERDTree-B| and
+|'NERDTreeShowBookmarks'|), it will be rendered above the tree. You can double
+click bookmarks or use the |NERDTree-o| mapping to activate them. See also,
+|NERDTree-t| and |NERDTree-T|
+
+------------------------------------------------------------------------------
+2.2.2. Bookmark commands *NERDTreeBookmarkCommands*
+
+Note that the following commands are only available in the NERD tree buffer.
+
+:Bookmark []
+ Bookmark the current node as . If there is already a
+ bookmark, it is overwritten. must not contain spaces.
+ If is not provided, it defaults to the file or directory name.
+ For directories, a trailing slash is present.
+
+:BookmarkToRoot
+ Make the directory corresponding to the new root. If a treenode
+ corresponding to is already cached somewhere in the tree then
+ the current tree will be used, otherwise a fresh tree will be opened.
+ Note that if points to a file then its parent will be used
+ instead.
+
+:RevealBookmark
+ If the node is cached under the current root then it will be revealed
+ (i.e. directory nodes above it will be opened) and the cursor will be
+ placed on it.
+
+:OpenBookmark
+ must point to a file. The file is opened as though |NERDTree-o|
+ was applied. If the node is cached under the current root then it will be
+ revealed and the cursor will be placed on it.
+
+:ClearBookmarks []
+ Remove all the given bookmarks. If no bookmarks are given then remove all
+ bookmarks on the current node.
+
+:ClearAllBookmarks
+ Remove all bookmarks.
+
+:ReadBookmarks
+ Re-read the bookmarks in the |'NERDTreeBookmarksFile'|.
+
+See also |:NERDTree| and |:NERDTreeFromBookmark|.
+
+------------------------------------------------------------------------------
+2.2.3. Invalid Bookmarks *NERDTreeInvalidBookmarks*
+
+If invalid bookmarks are detected, the script will issue an error message and
+the invalid bookmarks will become unavailable for use.
+
+These bookmarks will still be stored in the bookmarks file (see
+|'NERDTreeBookmarksFile'|), down the bottom. There will always be a blank line
+after the valid bookmarks but before the invalid ones.
+
+Each line in the bookmarks file represents one bookmark. The proper format is:
+
+
+After you have corrected any invalid bookmarks, either restart vim, or go
+:ReadBookmarks from the NERD tree window.
+
+------------------------------------------------------------------------------
+2.3. NERD tree Mappings *NERDTreeMappings*
+
+Default Description~ help-tag~
+Key~
+
+o.......Open files, directories and bookmarks....................|NERDTree-o|
+go......Open selected file, but leave cursor in the NERDTree.....|NERDTree-go|
+t.......Open selected node/bookmark in a new tab.................|NERDTree-t|
+T.......Same as 't' but keep the focus on the current tab........|NERDTree-T|
+i.......Open selected file in a split window.....................|NERDTree-i|
+gi......Same as i, but leave the cursor on the NERDTree..........|NERDTree-gi|
+s.......Open selected file in a new vsplit.......................|NERDTree-s|
+gs......Same as s, but leave the cursor on the NERDTree..........|NERDTree-gs|
+O.......Recursively open the selected directory..................|NERDTree-O|
+x.......Close the current nodes parent...........................|NERDTree-x|
+X.......Recursively close all children of the current node.......|NERDTree-X|
+e.......Edit the current dir.....................................|NERDTree-e|
+
+...............same as |NERDTree-o|.
+double-click.......same as the |NERDTree-o| map.
+middle-click.......same as |NERDTree-i| for files, same as
+ |NERDTree-e| for dirs.
+
+D.......Delete the current bookmark .............................|NERDTree-D|
+
+P.......Jump to the root node....................................|NERDTree-P|
+p.......Jump to current nodes parent.............................|NERDTree-p|
+K.......Jump up inside directories at the current tree depth.....|NERDTree-K|
+J.......Jump down inside directories at the current tree depth...|NERDTree-J|
+...Jump down to the next sibling of the current directory...|NERDTree-C-J|
+...Jump up to the previous sibling of the current directory.|NERDTree-C-K|
+
+C.......Change the tree root to the selected dir.................|NERDTree-C|
+u.......Move the tree root up one directory......................|NERDTree-u|
+U.......Same as 'u' except the old root node is left open........|NERDTree-U|
+r.......Recursively refresh the current directory................|NERDTree-r|
+R.......Recursively refresh the current root.....................|NERDTree-R|
+m.......Display the NERD tree menu...............................|NERDTree-m|
+cd......Change the CWD to the dir of the selected node...........|NERDTree-cd|
+CD......Change tree root to the CWD..............................|NERDTree-CD|
+
+I.......Toggle whether hidden files displayed....................|NERDTree-I|
+f.......Toggle whether the file filters are used.................|NERDTree-f|
+F.......Toggle whether files are displayed.......................|NERDTree-F|
+B.......Toggle whether the bookmark table is displayed...........|NERDTree-B|
+
+q.......Close the NERDTree window................................|NERDTree-q|
+A.......Zoom (maximize/minimize) the NERDTree window.............|NERDTree-A|
+?.......Toggle the display of the quick help.....................|NERDTree-?|
+
+------------------------------------------------------------------------------
+ *NERDTree-o*
+Default key: o
+Map option: NERDTreeMapActivateNode
+Applies to: files and directories.
+
+If a file node is selected, it is opened in the previous window.
+
+If a directory is selected it is opened or closed depending on its current
+state.
+
+If a bookmark that links to a directory is selected then that directory
+becomes the new root.
+
+If a bookmark that links to a file is selected then that file is opened in the
+previous window.
+
+------------------------------------------------------------------------------
+ *NERDTree-go*
+Default key: go
+Map option: None
+Applies to: files.
+
+If a file node is selected, it is opened in the previous window, but the
+cursor does not move.
+
+The key combo for this mapping is always "g" + NERDTreeMapActivateNode (see
+|NERDTree-o|).
+
+------------------------------------------------------------------------------
+ *NERDTree-t*
+Default key: t
+Map option: NERDTreeMapOpenInTab
+Applies to: files and directories.
+
+Opens the selected file in a new tab. If a directory is selected, a fresh
+NERD Tree for that directory is opened in a new tab.
+
+If a bookmark which points to a directory is selected, open a NERD tree for
+that directory in a new tab. If the bookmark points to a file, open that file
+in a new tab.
+
+------------------------------------------------------------------------------
+ *NERDTree-T*
+Default key: T
+Map option: NERDTreeMapOpenInTabSilent
+Applies to: files and directories.
+
+The same as |NERDTree-t| except that the focus is kept in the current tab.
+
+------------------------------------------------------------------------------
+ *NERDTree-i*
+Default key: i
+Map option: NERDTreeMapOpenSplit
+Applies to: files.
+
+Opens the selected file in a new split window and puts the cursor in the new
+window.
+
+------------------------------------------------------------------------------
+ *NERDTree-gi*
+Default key: gi
+Map option: None
+Applies to: files.
+
+The same as |NERDTree-i| except that the cursor is not moved.
+
+The key combo for this mapping is always "g" + NERDTreeMapOpenSplit (see
+|NERDTree-i|).
+
+------------------------------------------------------------------------------
+ *NERDTree-s*
+Default key: s
+Map option: NERDTreeMapOpenVSplit
+Applies to: files.
+
+Opens the selected file in a new vertically split window and puts the cursor in
+the new window.
+
+------------------------------------------------------------------------------
+ *NERDTree-gs*
+Default key: gs
+Map option: None
+Applies to: files.
+
+The same as |NERDTree-s| except that the cursor is not moved.
+
+The key combo for this mapping is always "g" + NERDTreeMapOpenVSplit (see
+|NERDTree-s|).
+
+------------------------------------------------------------------------------
+ *NERDTree-O*
+Default key: O
+Map option: NERDTreeMapOpenRecursively
+Applies to: directories.
+
+Recursively opens the selected directory.
+
+All files and directories are cached, but if a directory would not be
+displayed due to file filters (see |'NERDTreeIgnore'| |NERDTree-f|) or the
+hidden file filter (see |'NERDTreeShowHidden'|) then its contents are not
+cached. This is handy, especially if you have .svn directories.
+
+------------------------------------------------------------------------------
+ *NERDTree-x*
+Default key: x
+Map option: NERDTreeMapCloseDir
+Applies to: files and directories.
+
+Closes the parent of the selected node.
+
+------------------------------------------------------------------------------
+ *NERDTree-X*
+Default key: X
+Map option: NERDTreeMapCloseChildren
+Applies to: directories.
+
+Recursively closes all children of the selected directory.
+
+Tip: To quickly "reset" the tree, use |NERDTree-P| with this mapping.
+
+------------------------------------------------------------------------------
+ *NERDTree-e*
+Default key: e
+Map option: NERDTreeMapOpenExpl
+Applies to: files and directories.
+
+|:edit|s the selected directory, or the selected file's directory. This could
+result in a NERD tree or a netrw being opened, depending on
+|'NERDTreeHijackNetrw'|.
+
+------------------------------------------------------------------------------
+ *NERDTree-D*
+Default key: D
+Map option: NERDTreeMapDeleteBookmark
+Applies to: lines in the bookmarks table
+
+Deletes the currently selected bookmark.
+
+------------------------------------------------------------------------------
+ *NERDTree-P*
+Default key: P
+Map option: NERDTreeMapJumpRoot
+Applies to: no restrictions.
+
+Jump to the tree root.
+
+------------------------------------------------------------------------------
+ *NERDTree-p*
+Default key: p
+Map option: NERDTreeMapJumpParent
+Applies to: files and directories.
+
+Jump to the parent node of the selected node.
+
+------------------------------------------------------------------------------
+ *NERDTree-K*
+Default key: K
+Map option: NERDTreeMapJumpFirstChild
+Applies to: files and directories.
+
+Jump to the first child of the current nodes parent.
+
+If the cursor is already on the first node then do the following:
+ * loop back thru the siblings of the current nodes parent until we find an
+ open dir with children
+ * go to the first child of that node
+
+------------------------------------------------------------------------------
+ *NERDTree-J*
+Default key: J
+Map option: NERDTreeMapJumpLastChild
+Applies to: files and directories.
+
+Jump to the last child of the current nodes parent.
+
+If the cursor is already on the last node then do the following:
+ * loop forward thru the siblings of the current nodes parent until we find
+ an open dir with children
+ * go to the last child of that node
+
+------------------------------------------------------------------------------
+ *NERDTree-C-J*
+Default key:
+Map option: NERDTreeMapJumpNextSibling
+Applies to: files and directories.
+
+Jump to the next sibling of the selected node.
+
+------------------------------------------------------------------------------
+ *NERDTree-C-K*
+Default key:
+Map option: NERDTreeMapJumpPrevSibling
+Applies to: files and directories.
+
+Jump to the previous sibling of the selected node.
+
+------------------------------------------------------------------------------
+ *NERDTree-C*
+Default key: C
+Map option: NERDTreeMapChangeRoot
+Applies to: files and directories.
+
+Make the selected directory node the new tree root. If a file is selected, its
+parent is used.
+
+------------------------------------------------------------------------------
+ *NERDTree-u*
+Default key: u
+Map option: NERDTreeMapUpdir
+Applies to: no restrictions.
+
+Move the tree root up a dir (like doing a "cd ..").
+
+------------------------------------------------------------------------------
+ *NERDTree-U*
+Default key: U
+Map option: NERDTreeMapUpdirKeepOpen
+Applies to: no restrictions.
+
+Like |NERDTree-u| except that the old tree root is kept open.
+
+------------------------------------------------------------------------------
+ *NERDTree-r*
+Default key: r
+Map option: NERDTreeMapRefresh
+Applies to: files and directories.
+
+If a dir is selected, recursively refresh that dir, i.e. scan the filesystem
+for changes and represent them in the tree.
+
+If a file node is selected then the above is done on it's parent.
+
+------------------------------------------------------------------------------
+ *NERDTree-R*
+Default key: R
+Map option: NERDTreeMapRefreshRoot
+Applies to: no restrictions.
+
+Recursively refresh the tree root.
+
+------------------------------------------------------------------------------
+ *NERDTree-m*
+Default key: m
+Map option: NERDTreeMapMenu
+Applies to: files and directories.
+
+Display the NERD tree menu. See |NERDTreeMenu| for details.
+
+------------------------------------------------------------------------------
+ *NERDTree-cd*
+Default key: cd
+Map option: NERDTreeMapChdir
+Applies to: files and directories.
+
+Change vims current working directory to that of the selected node.
+
+------------------------------------------------------------------------------
+ *NERDTree-CD*
+Default key: CD
+Map option: NERDTreeMapCWD
+Applies to: no restrictions.
+
+Change tree root to vims current working directory.
+
+------------------------------------------------------------------------------
+ *NERDTree-I*
+Default key: I
+Map option: NERDTreeMapToggleHidden
+Applies to: no restrictions.
+
+Toggles whether hidden files (i.e. "dot files") are displayed.
+
+------------------------------------------------------------------------------
+ *NERDTree-f*
+Default key: f
+Map option: NERDTreeMapToggleFilters
+Applies to: no restrictions.
+
+Toggles whether file filters are used. See |'NERDTreeIgnore'| for details.
+
+------------------------------------------------------------------------------
+ *NERDTree-F*
+Default key: F
+Map option: NERDTreeMapToggleFiles
+Applies to: no restrictions.
+
+Toggles whether file nodes are displayed.
+
+------------------------------------------------------------------------------
+ *NERDTree-B*
+Default key: B
+Map option: NERDTreeMapToggleBookmarks
+Applies to: no restrictions.
+
+Toggles whether the bookmarks table is displayed.
+
+------------------------------------------------------------------------------
+ *NERDTree-q*
+Default key: q
+Map option: NERDTreeMapQuit
+Applies to: no restrictions.
+
+Closes the NERDtree window.
+
+------------------------------------------------------------------------------
+ *NERDTree-A*
+Default key: A
+Map option: NERDTreeMapToggleZoom
+Applies to: no restrictions.
+
+Maximize (zoom) and minimize the NERDtree window.
+
+------------------------------------------------------------------------------
+ *NERDTree-?*
+Default key: ?
+Map option: NERDTreeMapHelp
+Applies to: no restrictions.
+
+Toggles whether the quickhelp is displayed.
+
+------------------------------------------------------------------------------
+2.3. The NERD tree menu *NERDTreeMenu*
+
+The NERD tree has a menu that can be programmed via the an API (see
+|NERDTreeMenuAPI|). The idea is to simulate the "right click" menus that most
+file explorers have.
+
+The script comes with two default menu plugins: exec_menuitem.vim and
+fs_menu.vim. fs_menu.vim adds some basic filesystem operations to the menu for
+creating/deleting/moving/copying files and dirs. exec_menuitem.vim provides a
+menu item to execute executable files.
+
+Related tags: |NERDTree-m| |NERDTreeApi|
+
+==============================================================================
+3. Customisation *NERDTreeOptions*
+
+
+------------------------------------------------------------------------------
+3.1. Customisation summary *NERDTreeOptionSummary*
+
+The script provides the following options that can customise the behaviour the
+NERD tree. These options should be set in your vimrc.
+
+|'loaded_nerd_tree'| Turns off the script.
+
+|'NERDTreeAutoCenter'| Controls whether the NERD tree window centers
+ when the cursor moves within a specified
+ distance to the top/bottom of the window.
+
+|'NERDTreeAutoCenterThreshold'| Controls the sensitivity of autocentering.
+
+|'NERDTreeCaseSensitiveSort'| Tells the NERD tree whether to be case
+ sensitive or not when sorting nodes.
+
+|'NERDTreeSortHiddenFirst'| Tells the NERD tree whether to take the dot
+ at the beginning of the hidden file names
+ into account when sorting nodes.
+
+|'NERDTreeChDirMode'| Tells the NERD tree if/when it should change
+ vim's current working directory.
+
+|'NERDTreeHighlightCursorline'| Tell the NERD tree whether to highlight the
+ current cursor line.
+
+|'NERDTreeHijackNetrw'| Tell the NERD tree whether to replace the netrw
+ autocommands for exploring local directories.
+
+|'NERDTreeIgnore'| Tells the NERD tree which files to ignore.
+
+|'NERDTreeRespectWildIgnore'| Tells the NERD tree to respect |'wildignore'|.
+
+|'NERDTreeBookmarksFile'| Where the bookmarks are stored.
+
+|'NERDTreeBookmarksSort'| Whether the bookmarks list is sorted on
+ display.
+
+|'NERDTreeMouseMode'| Tells the NERD tree how to handle mouse
+ clicks.
+
+|'NERDTreeQuitOnOpen'| Closes the tree window after opening a file.
+
+|'NERDTreeShowBookmarks'| Tells the NERD tree whether to display the
+ bookmarks table on startup.
+
+|'NERDTreeShowFiles'| Tells the NERD tree whether to display files
+ in the tree on startup.
+
+|'NERDTreeShowHidden'| Tells the NERD tree whether to display hidden
+ files on startup.
+
+|'NERDTreeShowLineNumbers'| Tells the NERD tree whether to display line
+ numbers in the tree window.
+
+|'NERDTreeSortOrder'| Tell the NERD tree how to sort the nodes in
+ the tree.
+
+|'NERDTreeStatusline'| Set a statusline for NERD tree windows.
+
+|'NERDTreeWinPos'| Tells the script where to put the NERD tree
+ window.
+
+|'NERDTreeWinSize'| Sets the window size when the NERD tree is
+ opened.
+
+|'NERDTreeMinimalUI'| Disables display of the 'Bookmarks' label and
+ 'Press ? for help' text.
+
+|'NERDTreeDirArrows'| Tells the NERD tree to use arrows instead of
+ + ~ chars when displaying directories.
+
+|'NERDTreeCascadeOpenSingleChildDir'|
+ Cascade open while selected directory has only
+ one child that also is a directory.
+
+|'NERDTreeAutoDeleteBuffer'| Tells the NERD tree to automatically remove
+ a buffer when a file is being deleted or renamed
+ via a context menu command.
+
+------------------------------------------------------------------------------
+3.2. Customisation details *NERDTreeOptionDetails*
+
+To enable any of the below options you should put the given line in your
+~/.vimrc
+
+ *'loaded_nerd_tree'*
+If this plugin is making you feel homicidal, it may be a good idea to turn it
+off with this line in your vimrc: >
+ let loaded_nerd_tree=1
+<
+
+------------------------------------------------------------------------------
+ *'NERDTreeAutoCenter'*
+Values: 0 or 1.
+Default: 1
+
+If set to 1, the NERD tree window will center around the cursor if it moves to
+within |'NERDTreeAutoCenterThreshold'| lines of the top/bottom of the window.
+
+This is ONLY done in response to tree navigation mappings,
+i.e. |NERDTree-J| |NERDTree-K| |NERDTree-C-J| |NERDTree-C-K| |NERDTree-p|
+|NERDTree-P|
+
+The centering is done with a |zz| operation.
+
+------------------------------------------------------------------------------
+ *'NERDTreeAutoCenterThreshold'*
+Values: Any natural number.
+Default: 3
+
+This option controls the "sensitivity" of the NERD tree auto centering. See
+|'NERDTreeAutoCenter'| for details.
+
+------------------------------------------------------------------------------
+ *'NERDTreeCaseSensitiveSort'*
+Values: 0 or 1.
+Default: 0.
+
+By default the NERD tree does not sort nodes case sensitively, i.e. nodes
+could appear like this: >
+ bar.c
+ Baz.c
+ blarg.c
+ boner.c
+ Foo.c
+<
+But, if you set this option to 1 then the case of the nodes will be taken into
+account. The above nodes would then be sorted like this: >
+ Baz.c
+ Foo.c
+ bar.c
+ blarg.c
+ boner.c
+<
+------------------------------------------------------------------------------
+ *'NERDTreeChDirMode'*
+
+Values: 0, 1 or 2.
+Default: 0.
+
+Use this option to tell the script when (if at all) to change the current
+working directory (CWD) for vim.
+
+If it is set to 0 then the CWD is never changed by the NERD tree.
+
+If set to 1 then the CWD is changed when the NERD tree is first loaded to the
+directory it is initialized in. For example, if you start the NERD tree with >
+ :NERDTree /home/marty/foobar
+<
+then the CWD will be changed to /home/marty/foobar and will not be changed
+again unless you init another NERD tree with a similar command.
+
+If the option is set to 2 then it behaves the same as if set to 1 except that
+the CWD is changed whenever the tree root is changed. For example, if the CWD
+is /home/marty/foobar and you make the node for /home/marty/foobar/baz the new
+root then the CWD will become /home/marty/foobar/baz.
+
+------------------------------------------------------------------------------
+ *'NERDTreeHighlightCursorline'*
+Values: 0 or 1.
+Default: 1.
+
+If set to 1, the current cursor line in the NERD tree buffer will be
+highlighted. This is done using the |'cursorline'| option.
+
+------------------------------------------------------------------------------
+ *'NERDTreeHijackNetrw'*
+Values: 0 or 1.
+Default: 1.
+
+If set to 1, doing a >
+ :edit
+<
+will open up a "secondary" NERD tree instead of a netrw in the target window.
+
+Secondary NERD trees behaves slightly different from a regular trees in the
+following respects:
+ 1. 'o' will open the selected file in the same window as the tree,
+ replacing it.
+ 2. you can have as many secondary tree as you want in the same tab.
+
+------------------------------------------------------------------------------
+ *'NERDTreeIgnore'*
+Values: a list of regular expressions.
+Default: ['\~$'].
+
+This option is used to specify which files the NERD tree should ignore. It
+must be a list of regular expressions. When the NERD tree is rendered, any
+files/dirs that match any of the regex's in 'NERDTreeIgnore' wont be
+displayed.
+
+For example if you put the following line in your vimrc: >
+ let NERDTreeIgnore=['\.vim$', '\~$']
+<
+then all files ending in .vim or ~ will be ignored.
+
+There are 2 magic flags that can be appended to the end of each regular
+expression to specify that the regex should match only files or only dirs.
+These flags are "[[dir]]" and "[[file]]". Example: >
+ let NERDTreeIgnore=['.d$[[dir]]', '.o$[[file]]']
+<
+This will cause all dirs ending in ".d" to be ignored and all files ending in
+".o" to be ignored.
+
+Note: to tell the NERD tree not to ignore any files you must use the following
+line: >
+ let NERDTreeIgnore=[]
+<
+
+The file filters can be turned on and off dynamically with the |NERDTree-f|
+mapping.
+
+------------------------------------------------------------------------------
+ *'NERDTreeRespectWildIgnore'*
+Values: 0 or 1.
+Default: 0.
+
+If set to 1, the |'wildignore'| setting is respected.
+
+------------------------------------------------------------------------------
+ *'NERDTreeBookmarksFile'*
+Values: a path
+Default: $HOME/.NERDTreeBookmarks
+
+This is where bookmarks are saved. See |NERDTreeBookmarkCommands|.
+
+------------------------------------------------------------------------------
+ *'NERDTreeBookmarksSort'*
+Values: 0 or 1
+Default: 1
+
+If set to 0 then the bookmarks list is not sorted.
+If set to 1 the bookmarks list is sorted.
+
+------------------------------------------------------------------------------
+ *'NERDTreeMouseMode'*
+Values: 1, 2 or 3.
+Default: 1.
+
+If set to 1 then a double click on a node is required to open it.
+If set to 2 then a single click will open directory nodes, while a double
+click will still be required for file nodes.
+If set to 3 then a single click will open any node.
+
+Note: a double click anywhere on a line that a tree node is on will
+activate it, but all single-click activations must be done on name of the node
+itself. For example, if you have the following node: >
+ | | |-application.rb
+<
+then (to single click activate it) you must click somewhere in
+'application.rb'.
+
+------------------------------------------------------------------------------
+ *'NERDTreeQuitOnOpen'*
+
+Values: 0 or 1.
+Default: 0
+
+If set to 1, the NERD tree window will close after opening a file with the
+|NERDTree-o|, |NERDTree-i|, |NERDTree-t| and |NERDTree-T| mappings.
+
+------------------------------------------------------------------------------
+ *'NERDTreeShowBookmarks'*
+Values: 0 or 1.
+Default: 0.
+
+If this option is set to 1 then the bookmarks table will be displayed.
+
+This option can be toggled dynamically, per tree, with the |NERDTree-B|
+mapping.
+
+------------------------------------------------------------------------------
+ *'NERDTreeShowFiles'*
+Values: 0 or 1.
+Default: 1.
+
+If this option is set to 1 then files are displayed in the NERD tree. If it is
+set to 0 then only directories are displayed.
+
+This option can be toggled dynamically, per tree, with the |NERDTree-F|
+mapping and is useful for drastically shrinking the tree when you are
+navigating to a different part of the tree.
+
+------------------------------------------------------------------------------
+ *'NERDTreeShowHidden'*
+Values: 0 or 1.
+Default: 0.
+
+This option tells vim whether to display hidden files by default. This option
+can be dynamically toggled, per tree, with the |NERDTree-I| mapping. Use one
+of the follow lines to set this option: >
+ let NERDTreeShowHidden=0
+ let NERDTreeShowHidden=1
+<
+
+------------------------------------------------------------------------------
+ *'NERDTreeShowLineNumbers'*
+Values: 0 or 1.
+Default: 0.
+
+This option tells vim whether to display line numbers for the NERD tree
+window. Use one of the follow lines to set this option: >
+ let NERDTreeShowLineNumbers=0
+ let NERDTreeShowLineNumbers=1
+<
+
+------------------------------------------------------------------------------
+ *'NERDTreeSortOrder'*
+Values: a list of regular expressions.
+Default: ['\/$', '*', '\.swp$', '\.bak$', '\~$']
+
+This option is set to a list of regular expressions which are used to
+specify the order of nodes under their parent.
+
+For example, if the option is set to: >
+ ['\.vim$', '\.c$', '\.h$', '*', 'foobar']
+<
+then all .vim files will be placed at the top, followed by all .c files then
+all .h files. All files containing the string 'foobar' will be placed at the
+end. The star is a special flag: it tells the script that every node that
+doesnt match any of the other regexps should be placed here.
+
+If no star is present in 'NERDTreeSortOrder' then one is automatically
+appended to the array.
+
+The regex '\/$' should be used to match directory nodes.
+
+After this sorting is done, the files in each group are sorted alphabetically.
+
+Other examples: >
+ (1) ['*', '\/$']
+ (2) []
+ (3) ['\/$', '\.rb$', '\.php$', '*', '\.swp$', '\.bak$', '\~$']
+<
+1. Directories will appear last, everything else will appear above.
+2. Everything will simply appear in alphabetical order.
+3. Dirs will appear first, then ruby and php. Swap files, bak files and vim
+ backup files will appear last with everything else preceding them.
+
+------------------------------------------------------------------------------
+ *'NERDTreeStatusline'*
+Values: Any valid statusline setting.
+Default: %{b:NERDTreeRoot.path.strForOS(0)}
+
+Tells the script what to use as the |'statusline'| setting for NERD tree
+windows.
+
+Note that the statusline is set using |:let-&| not |:set| so escaping spaces
+isn't necessary.
+
+Setting this option to -1 will will deactivate it so that your global
+statusline setting is used instead.
+
+------------------------------------------------------------------------------
+ *'NERDTreeWinPos'*
+Values: "left" or "right"
+Default: "left".
+
+This option is used to determine where NERD tree window is placed on the
+screen.
+
+This option makes it possible to use two different explorer plugins
+simultaneously. For example, you could have the taglist plugin on the left of
+the window and the NERD tree on the right.
+
+------------------------------------------------------------------------------
+ *'NERDTreeWinSize'*
+Values: a positive integer.
+Default: 31.
+
+This option is used to change the size of the NERD tree when it is loaded.
+
+------------------------------------------------------------------------------
+ *'NERDTreeMinimalUI'*
+Values: 0 or 1
+Default: 0
+
+This options disables the 'Bookmarks' label 'Press ? for help' text. Use one
+of the following lines to set this option: >
+ let NERDTreeMinimalUI=0
+ 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'*
+Values: 0 or 1
+Default: 1.
+
+When opening dir nodes, this option tells NERDTree to recursively open dirs
+that have only one child which is also a dir. NERDTree will stop when it finds
+a dir that contains anything but another single dir. This option also causes
+the |NERDTree-x| mapping to close dirs in the same manner. This option may be
+useful for Java projects. Use one of the follow lines to set this option: >
+ let NERDTreeCascadeOpenSingleChildDir=0
+ let NERDTreeCascadeOpenSingleChildDir=1
+<
+
+------------------------------------------------------------------------------
+ *'NERDTreeAutoDeleteBuffer'*
+Values: 0 or 1
+Default: 0.
+
+When using a context menu to delete or rename a file you may also want to delete
+the buffer which is no more valid. If the option is not set you will see a
+confirmation if you really want to delete an old buffer. If you always press 'y'
+then it worths to set this option to 1. Use one of the follow lines to set this
+option: >
+ let NERDTreeAutoDeleteBuffer=0
+ let NERDTreeAutoDeleteBuffer=1
+<
+
+==============================================================================
+4. The NERD tree API *NERDTreeAPI*
+
+The NERD tree script allows you to add custom key mappings and menu items via
+a set of API calls. Any scripts that use this API should be placed in
+~/.vim/nerdtree_plugin/ (*nix) or ~/vimfiles/nerdtree_plugin (windows).
+
+The script exposes some prototype objects that can be used to manipulate the
+tree and/or get information from it: >
+ g:NERDTreePath
+ g:NERDTreeDirNode
+ g:NERDTreeFileNode
+ g:NERDTreeBookmark
+<
+See the code/comments in NERD_tree.vim to find how to use these objects. The
+following code conventions are used:
+ * class members start with a capital letter
+ * instance members start with a lower case letter
+ * private members start with an underscore
+
+See this blog post for more details:
+ http://got-ravings.blogspot.com/2008/09/vim-pr0n-prototype-based-objects.html
+
+------------------------------------------------------------------------------
+4.1. Key map API *NERDTreeKeymapAPI*
+
+NERDTreeAddKeyMap({options}) *NERDTreeAddKeyMap()*
+ Adds a new keymapping for all NERD tree buffers.
+ {options} must be a dictionary, and must contain the following keys:
+ "key" - the trigger key for the new mapping
+ "callback" - the function the new mapping will be bound to
+ "quickhelpText" - the text that will appear in the quickhelp (see
+ |NERDTree-?|)
+ "override" - if 1 then this new mapping will override whatever previous
+ mapping was defined for the key/scope combo. Useful for overriding the
+ default mappings.
+
+ Additionally, a "scope" argument may be supplied. This constrains the
+ mapping so that it is only activated if the cursor is on a certain object.
+ That object is then passed into the handling method. Possible values are:
+ "FileNode" - a file node
+ "DirNode" - a directory node
+ "Node" - a file or directory node
+ "Bookmark" - A bookmark
+ "all" - the keymap is not constrained to any scope (default). When
+ thei is used, the handling function is not passed any arguments.
+
+
+ Example: >
+ call NERDTreeAddKeyMap({
+ \ 'key': 'foo',
+ \ 'callback': 'NERDTreeCDHandler',
+ \ 'quickhelpText': 'echo full path of current node',
+ \ 'scope': 'DirNode' })
+
+ function! NERDTreeCDHandler(dirnode)
+ call a:dirnode.changeToDir()
+ endfunction
+<
+ This code should sit in a file like ~/.vim/nerdtree_plugin/mymapping.vim.
+ It adds a (redundant) mapping on 'foo' which changes vim's CWD to that of
+ the current dir node. Note this mapping will only fire when the cursor is
+ on a directory node.
+
+------------------------------------------------------------------------------
+4.2. Menu API *NERDTreeMenuAPI*
+
+NERDTreeAddSubmenu({options}) *NERDTreeAddSubmenu()*
+ Creates and returns a new submenu.
+
+ {options} must be a dictionary and must contain the following keys:
+ "text" - the text of the submenu that the user will see
+ "shortcut" - a shortcut key for the submenu (need not be unique)
+
+ The following keys are optional:
+ "isActiveCallback" - a function that will be called to determine whether
+ this submenu item will be displayed or not. The callback function must return
+ 0 or 1.
+ "parent" - the parent submenu of the new submenu (returned from a previous
+ invocation of NERDTreeAddSubmenu()). If this key is left out then the new
+ submenu will sit under the top level menu.
+
+ See below for an example.
+
+NERDTreeAddMenuItem({options}) *NERDTreeAddMenuItem()*
+ Adds a new menu item to the NERD tree menu (see |NERDTreeMenu|).
+
+ {options} must be a dictionary and must contain the
+ following keys:
+ "text" - the text of the menu item which the user will see
+ "shortcut" - a shortcut key for the menu item (need not be unique)
+ "callback" - the function that will be called when the user activates the
+ menu item.
+
+ The following keys are optional:
+ "isActiveCallback" - a function that will be called to determine whether
+ this menu item will be displayed or not. The callback function must return
+ 0 or 1.
+ "parent" - if the menu item belongs under a submenu then this key must be
+ specified. This value for this key will be the object that
+ was returned when the submenu was created with |NERDTreeAddSubmenu()|.
+
+ See below for an example.
+
+NERDTreeAddMenuSeparator([{options}]) *NERDTreeAddMenuSeparator()*
+ Adds a menu separator (a row of dashes).
+
+ {options} is an optional dictionary that may contain the following keys:
+ "isActiveCallback" - see description in |NERDTreeAddMenuItem()|.
+
+Below is an example of the menu API in action. >
+ call NERDTreeAddMenuSeparator()
+
+ call NERDTreeAddMenuItem({
+ \ 'text': 'a (t)op level menu item',
+ \ 'shortcut': 't',
+ \ 'callback': 'SomeFunction' })
+
+ let submenu = NERDTreeAddSubmenu({
+ \ 'text': 'a (s)ub menu',
+ \ 'shortcut': 's' })
+
+ call NERDTreeAddMenuItem({
+ \ 'text': '(n)ested item 1',
+ \ 'shortcut': 'n',
+ \ 'callback': 'SomeFunction',
+ \ 'parent': submenu })
+
+ call NERDTreeAddMenuItem({
+ \ 'text': '(n)ested item 2',
+ \ 'shortcut': 'n',
+ \ 'callback': 'SomeFunction',
+ \ 'parent': submenu })
+<
+This will create the following menu: >
+ --------------------
+ a (t)op level menu item
+ a (s)ub menu
+<
+Where selecting "a (s)ub menu" will lead to a second menu: >
+ (n)ested item 1
+ (n)ested item 2
+<
+When any of the 3 concrete menu items are selected the function "SomeFunction"
+will be called.
+
+------------------------------------------------------------------------------
+4.3 NERDTreeAddPathFilter(callback) *NERDTreeAddPathFilter()*
+
+Path filters are essentially a more powerful version of |NERDTreeIgnore|.
+If the simple regex matching in |NERDTreeIgnore| is not enough then use
+|NERDTreeAddPathFilter()| to add a callback function that paths will be
+checked against when the decision to ignore them is made. Example >
+
+ call NERDTreeAddPathFilter('MyFilter')
+
+ function! MyFilter(params)
+ "params is a dict containing keys: 'nerdtree' and 'path' which are
+ "g:NERDTree and g:NERDTreePath objects
+
+ "return 1 to ignore params['path'] or 0 otherwise
+ endfunction
+<
+
+------------------------------------------------------------------------------
+NERDTreeRender() *NERDTreeRender()*
+ Re-renders the NERD tree buffer. Useful if you change the state of the
+ tree and you want to it to be reflected in the UI.
+
+==============================================================================
+5. About *NERDTreeAbout*
+
+The author of the NERD tree is a terrible terrible monster called Martyzilla
+who gobbles up small children with milk and sugar for breakfast.
+
+He can be reached at martin.grenfell at gmail dot com. He would love to hear
+from you, so feel free to send him suggestions and/or comments about this
+plugin. Don't be shy --- the worst he can do is slaughter you and stuff you in
+the fridge for later ;)
+
+The latest stable versions can be found at
+ http://www.vim.org/scripts/script.php?script_id=1658
+
+The latest dev versions are on github
+ http://github.com/scrooloose/nerdtree
+
+
+==============================================================================
+6. Changelog *NERDTreeChangelog*
+
+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()
+
+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 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
+ " (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 would fail if was relative and
+ didnt start with a ./ or ../ Thanks to James Kanze.
+ - make the q mapping work with secondary (:e 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 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 '' 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.
+See http://sam.zoy.org/wtfpl/COPYING.
diff --git a/config/home/vim/bundle/nerdtree/lib/nerdtree/bookmark.vim b/config/home/vim/bundle/nerdtree/lib/nerdtree/bookmark.vim
new file mode 100644
index 0000000..8a94b25
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/lib/nerdtree/bookmark.vim
@@ -0,0 +1,319 @@
+"CLASS: Bookmark
+"============================================================
+let s:Bookmark = {}
+let g:NERDTreeBookmark = s:Bookmark
+
+" FUNCTION: Bookmark.activate() {{{1
+function! s:Bookmark.activate(...)
+ call self.open(a:0 ? a:1 : {})
+endfunction
+
+" FUNCTION: Bookmark.AddBookmark(name, path) {{{1
+" Class method to add a new bookmark to the list, if a previous bookmark exists
+" with the same name, just update the path for that bookmark
+function! s:Bookmark.AddBookmark(name, path)
+ for i in s:Bookmark.Bookmarks()
+ if i.name ==# a:name
+ let i.path = a:path
+ return
+ endif
+ endfor
+ call add(s:Bookmark.Bookmarks(), s:Bookmark.New(a:name, a:path))
+ if g:NERDTreeBookmarksSort ==# 1
+ call s:Bookmark.Sort()
+ endif
+endfunction
+
+" FUNCTION: Bookmark.Bookmarks() {{{1
+" Class method to get all bookmarks. Lazily initializes the bookmarks global
+" variable
+function! s:Bookmark.Bookmarks()
+ if !exists("g:NERDTreeBookmarks")
+ let g:NERDTreeBookmarks = []
+ endif
+ return g:NERDTreeBookmarks
+endfunction
+
+" FUNCTION: Bookmark.BookmarkExistsFor(name) {{{1
+" class method that returns 1 if a bookmark with the given name is found, 0
+" otherwise
+function! s:Bookmark.BookmarkExistsFor(name)
+ try
+ call s:Bookmark.BookmarkFor(a:name)
+ return 1
+ catch /^NERDTree.BookmarkNotFoundError/
+ return 0
+ endtry
+endfunction
+
+" FUNCTION: Bookmark.BookmarkFor(name) {{{1
+" Class method to get the bookmark that has the given name. {} is return if no
+" bookmark is found
+function! s:Bookmark.BookmarkFor(name)
+ for i in s:Bookmark.Bookmarks()
+ if i.name ==# a:name
+ return i
+ endif
+ endfor
+ throw "NERDTree.BookmarkNotFoundError: no bookmark found for name: \"". a:name .'"'
+endfunction
+
+" FUNCTION: Bookmark.BookmarkNames() {{{1
+" Class method to return an array of all bookmark names
+function! s:Bookmark.BookmarkNames()
+ let names = []
+ for i in s:Bookmark.Bookmarks()
+ call add(names, i.name)
+ endfor
+ return names
+endfunction
+
+" FUNCTION: Bookmark.CacheBookmarks(silent) {{{1
+" Class method to read all bookmarks from the bookmarks file initialize
+" bookmark objects for each one.
+"
+" Args:
+" silent - dont echo an error msg if invalid bookmarks are found
+function! s:Bookmark.CacheBookmarks(silent)
+ if filereadable(g:NERDTreeBookmarksFile)
+ let g:NERDTreeBookmarks = []
+ let g:NERDTreeInvalidBookmarks = []
+ let bookmarkStrings = readfile(g:NERDTreeBookmarksFile)
+ let invalidBookmarksFound = 0
+ for i in bookmarkStrings
+
+ "ignore blank lines
+ if i != ''
+
+ let name = substitute(i, '^\(.\{-}\) .*$', '\1', '')
+ let path = substitute(i, '^.\{-} \(.*\)$', '\1', '')
+
+ try
+ let bookmark = s:Bookmark.New(name, g:NERDTreePath.New(path))
+ call add(g:NERDTreeBookmarks, bookmark)
+ catch /^NERDTree.InvalidArgumentsError/
+ call add(g:NERDTreeInvalidBookmarks, i)
+ let invalidBookmarksFound += 1
+ endtry
+ endif
+ endfor
+ if invalidBookmarksFound
+ call s:Bookmark.Write()
+ if !a:silent
+ call nerdtree#echo(invalidBookmarksFound . " invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.")
+ endif
+ endif
+ if g:NERDTreeBookmarksSort ==# 1
+ call s:Bookmark.Sort()
+ endif
+ endif
+endfunction
+
+" FUNCTION: Bookmark.compareTo(otherbookmark) {{{1
+" Compare these two bookmarks for sorting purposes
+function! s:Bookmark.compareTo(otherbookmark)
+ return a:otherbookmark.name < self.name
+endfunction
+" FUNCTION: Bookmark.ClearAll() {{{1
+" Class method to delete all bookmarks.
+function! s:Bookmark.ClearAll()
+ for i in s:Bookmark.Bookmarks()
+ call i.delete()
+ endfor
+ call s:Bookmark.Write()
+endfunction
+
+" FUNCTION: Bookmark.delete() {{{1
+" Delete this bookmark. If the node for this bookmark is under the current
+" root, then recache bookmarks for its Path object
+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))
+ if !empty(node)
+ call node.path.cacheDisplayString()
+ endif
+ call s:Bookmark.Write()
+endfunction
+
+" FUNCTION: Bookmark.getNode(searchFromAbsoluteRoot) {{{1
+" Gets the treenode for this bookmark
+"
+" Args:
+" searchFromAbsoluteRoot: specifies whether we should search from the current
+" tree root, or the highest cached node
+function! s:Bookmark.getNode(searchFromAbsoluteRoot)
+ let searchRoot = a:searchFromAbsoluteRoot ? g:NERDTreeDirNode.AbsoluteTreeRoot() : b:NERDTreeRoot
+ let targetNode = searchRoot.findNode(self.path)
+ if empty(targetNode)
+ throw "NERDTree.BookmarkedNodeNotFoundError: no node was found for bookmark: " . self.name
+ endif
+ return targetNode
+endfunction
+
+" FUNCTION: Bookmark.GetNodeForName(name, searchFromAbsoluteRoot) {{{1
+" Class method that finds the bookmark with the given name and returns the
+" treenode for it.
+function! s:Bookmark.GetNodeForName(name, searchFromAbsoluteRoot)
+ let bookmark = s:Bookmark.BookmarkFor(a:name)
+ return bookmark.getNode(a:searchFromAbsoluteRoot)
+endfunction
+
+" FUNCTION: Bookmark.GetSelected() {{{1
+" returns the Bookmark the cursor is over, or {}
+function! s:Bookmark.GetSelected()
+ let line = getline(".")
+ let name = substitute(line, '^>\(.\{-}\) .\+$', '\1', '')
+ if name != line
+ try
+ return s:Bookmark.BookmarkFor(name)
+ catch /^NERDTree.BookmarkNotFoundError/
+ return {}
+ endtry
+ endif
+ return {}
+endfunction
+
+" FUNCTION: Bookmark.InvalidBookmarks() {{{1
+" Class method to get all invalid bookmark strings read from the bookmarks
+" file
+function! s:Bookmark.InvalidBookmarks()
+ if !exists("g:NERDTreeInvalidBookmarks")
+ let g:NERDTreeInvalidBookmarks = []
+ endif
+ return g:NERDTreeInvalidBookmarks
+endfunction
+
+" FUNCTION: Bookmark.mustExist() {{{1
+function! s:Bookmark.mustExist()
+ if !self.path.exists()
+ call s:Bookmark.CacheBookmarks(1)
+ throw "NERDTree.BookmarkPointsToInvalidLocationError: the bookmark \"".
+ \ self.name ."\" points to a non existing location: \"". self.path.str()
+ endif
+endfunction
+
+" FUNCTION: Bookmark.New(name, path) {{{1
+" Create a new bookmark object with the given name and path object
+function! s:Bookmark.New(name, path)
+ if a:name =~# ' '
+ throw "NERDTree.IllegalBookmarkNameError: illegal name:" . a:name
+ endif
+
+ let newBookmark = copy(self)
+ let newBookmark.name = a:name
+ let newBookmark.path = a:path
+ return newBookmark
+endfunction
+
+" FUNCTION: Bookmark.open([options]) {{{1
+"Args:
+"A dictionary containing the following keys (all optional):
+" 'where': Specifies whether the node should be opened in new split/tab or in
+" the previous window. Can be either 'v' (vertical split), 'h'
+" (horizontal split), 't' (new tab) or 'p' (previous window).
+" 'reuse': if a window is displaying the file then jump the cursor there
+" 'keepopen': dont close the tree window
+" 'stay': open the file, but keep the cursor in the tree win
+"
+function! s:Bookmark.open(...)
+ let opts = a:0 ? a:1 : {}
+
+ if self.path.isDirectory && !has_key(opts, 'where')
+ call self.toRoot()
+ else
+ let opener = g:NERDTreeOpener.New(self.path, opts)
+ call opener.open(self)
+ endif
+endfunction
+
+" FUNCTION: Bookmark.openInNewTab(options) {{{1
+" Create a new bookmark object with the given name and path object
+function! s:Bookmark.openInNewTab(options)
+ call nerdtree#deprecated('Bookmark.openInNewTab', 'is deprecated, use open() instead')
+ call self.open(a:options)
+endfunction
+
+" FUNCTION: Bookmark.setPath(path) {{{1
+" makes this bookmark point to the given path
+function! s:Bookmark.setPath(path)
+ let self.path = a:path
+endfunction
+
+" FUNCTION: Bookmark.Sort() {{{1
+" Class method that sorts all bookmarks
+function! s:Bookmark.Sort()
+ let CompareFunc = function("nerdtree#compareBookmarks")
+ call sort(s:Bookmark.Bookmarks(), CompareFunc)
+endfunction
+
+" FUNCTION: Bookmark.str() {{{1
+" Get the string that should be rendered in the view for this bookmark
+function! s:Bookmark.str()
+ let pathStrMaxLen = winwidth(g:NERDTree.GetWinNum()) - 4 - len(self.name)
+ if &nu
+ let pathStrMaxLen = pathStrMaxLen - &numberwidth
+ endif
+
+ let pathStr = self.path.str({'format': 'UI'})
+ if len(pathStr) > pathStrMaxLen
+ let pathStr = '<' . strpart(pathStr, len(pathStr) - pathStrMaxLen)
+ endif
+ return '>' . self.name . ' ' . pathStr
+endfunction
+
+" FUNCTION: Bookmark.toRoot() {{{1
+" Make the node for this bookmark the new tree root
+function! s:Bookmark.toRoot()
+ if self.validate()
+ try
+ let targetNode = self.getNode(1)
+ catch /^NERDTree.BookmarkedNodeNotFoundError/
+ let targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path)
+ endtry
+ call targetNode.makeRoot()
+ call b:NERDTree.render()
+ call targetNode.putCursorHere(0, 0)
+ endif
+endfunction
+
+" FUNCTION: Bookmark.ToRoot(name) {{{1
+" Make the node for this bookmark the new tree root
+function! s:Bookmark.ToRoot(name)
+ let bookmark = s:Bookmark.BookmarkFor(a:name)
+ call bookmark.toRoot()
+endfunction
+
+" FUNCTION: Bookmark.validate() {{{1
+function! s:Bookmark.validate()
+ if self.path.exists()
+ return 1
+ else
+ 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.")
+ return 0
+ endif
+endfunction
+
+" FUNCTION: Bookmark.Write() {{{1
+" Class method to write all bookmarks to the bookmarks file
+function! s:Bookmark.Write()
+ let bookmarkStrings = []
+ for i in s:Bookmark.Bookmarks()
+ call add(bookmarkStrings, i.name . ' ' . i.path.str())
+ endfor
+
+ "add a blank line before the invalid ones
+ call add(bookmarkStrings, "")
+
+ for j in s:Bookmark.InvalidBookmarks()
+ call add(bookmarkStrings, j)
+ endfor
+ call writefile(bookmarkStrings, g:NERDTreeBookmarksFile)
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/nerdtree/lib/nerdtree/creator.vim b/config/home/vim/bundle/nerdtree/lib/nerdtree/creator.vim
new file mode 100644
index 0000000..2d6a5c2
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/lib/nerdtree/creator.vim
@@ -0,0 +1,362 @@
+"CLASS: Creator
+"Creates primary/secondary/mirror nerdtree windows. Sets up all the window and
+"buffer options and key mappings etc.
+"============================================================
+let s:Creator = {}
+let g:NERDTreeCreator = s:Creator
+
+"FUNCTION: s:Creator._bindMappings() {{{1
+function! s:Creator._bindMappings()
+ "make do the same as the activate node mapping
+ nnoremap :call nerdtree#ui_glue#invokeKeyMap(g:NERDTreeMapActivateNode)
+
+ call g:NERDTreeKeyMap.BindAll()
+
+ command! -buffer -nargs=? Bookmark :call nerdtree#ui_glue#bookmarkNode('')
+ command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#ui_glue#revealBookmark('')
+ command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#ui_glue#openBookmark('')
+ command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#ui_glue#clearBookmarks('')
+ command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=+ BookmarkToRoot call g:NERDTreeBookmark.ToRoot('')
+ command! -buffer -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() call b:NERDTree.render()
+ command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) call b:NERDTree.render()
+ command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write()
+endfunction
+
+"FUNCTION: s:Creator._broadcastInitEvent() {{{1
+function! s:Creator._broadcastInitEvent()
+ silent doautocmd User NERDTreeInit
+endfunction
+
+" FUNCTION: s:Creator.BufNamePrefix() {{{2
+function! s:Creator.BufNamePrefix()
+ return 'NERD_tree_'
+endfunction
+
+"FUNCTION: s:Creator.CreatePrimary(a:name) {{{1
+function! s:Creator.CreatePrimary(name)
+ let creator = s:Creator.New()
+ call creator.createPrimary(a:name)
+endfunction
+
+"FUNCTION: s:Creator.createPrimary(a:name) {{{1
+"name: the name of a bookmark or a directory
+function! s:Creator.createPrimary(name)
+ let path = self._pathForString(a:name)
+
+ "abort if exception was thrown (bookmark/dir doesn't exist)
+ if empty(path)
+ return
+ endif
+
+ "if instructed to, then change the vim CWD to the dir the NERDTree is
+ "inited in
+ if g:NERDTreeChDirMode != 0
+ call path.changeToDir()
+ endif
+
+ if g:NERDTree.ExistsForTab()
+ if g:NERDTree.IsOpen()
+ call g:NERDTree.Close()
+ endif
+ unlet t:NERDTreeBufName
+ endif
+
+ call self._createTreeWin()
+ call self._createNERDTree(path)
+ let b:NERDTreeType = "primary"
+ let b:treeShowHelp = 0
+ let b:NERDTreeIgnoreEnabled = 1
+ let b:NERDTreeShowFiles = g:NERDTreeShowFiles
+ let b:NERDTreeShowHidden = g:NERDTreeShowHidden
+ let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks
+
+ call b:NERDTree.render()
+ call b:NERDTreeRoot.putCursorHere(0, 0)
+
+ call self._broadcastInitEvent()
+endfunction
+
+"FUNCTION: s:Creator.CreateSecondary(dir) {{{1
+function! s:Creator.CreateSecondary(dir)
+ let creator = s:Creator.New()
+ call creator.createSecondary(a:dir)
+endfunction
+
+"FUNCTION: s:Creator.createSecondary(dir) {{{1
+function! s:Creator.createSecondary(dir)
+ try
+ let path = g:NERDTreePath.New(a:dir)
+ catch /^NERDTree.InvalidArgumentsError/
+ call nerdtree#echo("Invalid directory name:" . a:name)
+ return
+ endtry
+
+ "we want the directory buffer to disappear when we do the :edit below
+ setlocal bufhidden=wipe
+
+ let previousBuf = expand("#")
+
+ "we need a unique name for each secondary tree buffer to ensure they are
+ "all independent
+ exec "silent edit " . self._nextBufferName()
+
+ let b:NERDTreePreviousBuf = bufnr(previousBuf)
+ call self._createNERDTree(path)
+ call self._setCommonBufOptions()
+ let b:NERDTreeType = "secondary"
+
+ call b:NERDTree.render()
+
+ call self._broadcastInitEvent()
+endfunction
+
+" FUNCTION: s:Creator._createNERDTree(path) {{{1
+function! s:Creator._createNERDTree(path)
+ let b:NERDTree = g:NERDTree.New(a:path)
+ "TODO: This is kept for compatability only since many things use
+ "b:NERDTreeRoot instead of the new NERDTree.root
+ "Remove this one day
+ let b:NERDTreeRoot = b:NERDTree.root
+
+ call b:NERDTree.root.open()
+endfunction
+
+" FUNCTION: s:Creator.CreateMirror() {{{1
+function! s:Creator.CreateMirror()
+ let creator = s:Creator.New()
+ call creator.createMirror()
+endfunction
+
+" FUNCTION: s:Creator.createMirror() {{{1
+function! s:Creator.createMirror()
+ "get the names off all the nerd tree buffers
+ let treeBufNames = []
+ for i in range(1, tabpagenr("$"))
+ let nextName = self._tabpagevar(i, 'NERDTreeBufName')
+ if nextName != -1 && (!exists("t:NERDTreeBufName") || nextName != t:NERDTreeBufName)
+ call add(treeBufNames, nextName)
+ endif
+ endfor
+ let treeBufNames = self._uniq(treeBufNames)
+
+ "map the option names (that the user will be prompted with) to the nerd
+ "tree buffer names
+ let options = {}
+ let i = 0
+ while i < len(treeBufNames)
+ let bufName = treeBufNames[i]
+ let treeRoot = getbufvar(bufName, "NERDTreeRoot")
+ let options[i+1 . '. ' . treeRoot.path.str() . ' (buf name: ' . bufName . ')'] = bufName
+ let i = i + 1
+ endwhile
+
+ "work out which tree to mirror, if there is more than 1 then ask the user
+ let bufferName = ''
+ if len(keys(options)) > 1
+ let choices = ["Choose a tree to mirror"]
+ let choices = extend(choices, sort(keys(options)))
+ let choice = inputlist(choices)
+ if choice < 1 || choice > len(options) || choice ==# ''
+ return
+ endif
+
+ let bufferName = options[sort(keys(options))[choice-1]]
+ elseif len(keys(options)) ==# 1
+ let bufferName = values(options)[0]
+ else
+ call nerdtree#echo("No trees to mirror")
+ return
+ endif
+
+ if g:NERDTree.ExistsForTab() && g:NERDTree.IsOpen()
+ call g:NERDTree.Close()
+ endif
+
+ let t:NERDTreeBufName = bufferName
+ call self._createTreeWin()
+ exec 'buffer ' . bufferName
+ if !&hidden
+ call b:NERDTree.render()
+ endif
+endfunction
+
+"FUNCTION: s:Creator._createTreeWin() {{{1
+"Inits the NERD tree window. ie. opens it, sizes it, sets all the local
+"options etc
+function! s:Creator._createTreeWin()
+ "create the nerd tree window
+ let splitLocation = g:NERDTreeWinPos ==# "left" ? "topleft " : "botright "
+ let splitSize = g:NERDTreeWinSize
+
+ if !exists('t:NERDTreeBufName')
+ let t:NERDTreeBufName = self._nextBufferName()
+ silent! exec splitLocation . 'vertical ' . splitSize . ' new'
+ silent! exec "edit " . t:NERDTreeBufName
+ else
+ silent! exec splitLocation . 'vertical ' . splitSize . ' split'
+ silent! exec "buffer " . t:NERDTreeBufName
+ endif
+
+ setlocal winfixwidth
+ call self._setCommonBufOptions()
+endfunction
+
+"FUNCTION: s:Creator.New() {{{1
+function! s:Creator.New()
+ let newCreator = copy(self)
+ return newCreator
+endfunction
+
+" FUNCTION: s:Creator._nextBufferName() {{{2
+" returns the buffer name for the next nerd tree
+function! s:Creator._nextBufferName()
+ let name = s:Creator.BufNamePrefix() . self._nextBufferNumber()
+ return name
+endfunction
+
+" FUNCTION: s:Creator._nextBufferNumber() {{{2
+" the number to add to the nerd tree buffer name to make the buf name unique
+function! s:Creator._nextBufferNumber()
+ if !exists("s:Creator._NextBufNum")
+ let s:Creator._NextBufNum = 1
+ else
+ let s:Creator._NextBufNum += 1
+ endif
+
+ return s:Creator._NextBufNum
+endfunction
+
+"FUNCTION: s:Creator._pathForString(str) {{{1
+"find a bookmark or adirectory for the given string
+function! s:Creator._pathForString(str)
+ let path = {}
+ if g:NERDTreeBookmark.BookmarkExistsFor(a:str)
+ let path = g:NERDTreeBookmark.BookmarkFor(a:str).path
+ else
+ let dir = a:str ==# '' ? getcwd() : a:str
+
+ "hack to get an absolute path if a relative path is given
+ if dir =~# '^\.'
+ let dir = getcwd() . g:NERDTreePath.Slash() . dir
+ endif
+ let dir = g:NERDTreePath.Resolve(dir)
+
+ try
+ let path = g:NERDTreePath.New(dir)
+ catch /^NERDTree.InvalidArgumentsError/
+ call nerdtree#echo("No bookmark or directory found for: " . a:str)
+ return
+ endtry
+ endif
+ if !path.isDirectory
+ let path = path.getParent()
+ endif
+
+ return path
+endfunction
+
+"FUNCTION: s:Creator._setCommonBufOptions() {{{1
+function! s:Creator._setCommonBufOptions()
+ "throwaway buffer options
+ setlocal noswapfile
+ setlocal buftype=nofile
+ setlocal bufhidden=hide
+ setlocal nowrap
+ setlocal foldcolumn=0
+ setlocal foldmethod=manual
+ setlocal nofoldenable
+ setlocal nobuflisted
+ setlocal nospell
+ if g:NERDTreeShowLineNumbers
+ setlocal nu
+ else
+ setlocal nonu
+ if v:version >= 703
+ setlocal nornu
+ endif
+ endif
+
+ iabc
+
+ if g:NERDTreeHighlightCursorline
+ setlocal cursorline
+ endif
+
+ 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()
+ setlocal filetype=nerdtree
+endfunction
+
+"FUNCTION: s:Creator._setupStatusline() {{{1
+function! s:Creator._setupStatusline()
+ if g:NERDTreeStatusline != -1
+ let &l:statusline = g:NERDTreeStatusline
+ endif
+endfunction
+
+" FUNCTION: s:Creator._tabpagevar(tabnr, var) {{{1
+function! s:Creator._tabpagevar(tabnr, var)
+ let currentTab = tabpagenr()
+ let old_ei = &ei
+ set ei=all
+
+ exec "tabnext " . a:tabnr
+ let v = -1
+ if exists('t:' . a:var)
+ exec 'let v = t:' . a:var
+ endif
+ exec "tabnext " . currentTab
+
+ let &ei = old_ei
+
+ return v
+endfunction
+
+"FUNCTION: s:Creator.TogglePrimary(dir) {{{1
+function! s:Creator.TogglePrimary(dir)
+ let creator = s:Creator.New()
+ call creator.togglePrimary(a:dir)
+endfunction
+
+"FUNCTION: s:Creator.togglePrimary(dir) {{{1
+"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)
+"
+"Args:
+"dir: the full path for the root node (is only used if the NERD tree is being
+"initialized.
+function! s:Creator.togglePrimary(dir)
+ if g:NERDTree.ExistsForTab()
+ if !g:NERDTree.IsOpen()
+ call self._createTreeWin()
+ if !&hidden
+ call b:NERDTree.render()
+ endif
+ call b:NERDTree.ui.restoreScreenState()
+ else
+ call g:NERDTree.Close()
+ endif
+ else
+ call self.createPrimary(a:dir)
+ endif
+endfunction
+
+" Function: s:Creator._uniq(list) {{{1
+" returns a:list without duplicates
+function! s:Creator._uniq(list)
+ let uniqlist = []
+ for elem in a:list
+ if index(uniqlist, elem) ==# -1
+ let uniqlist += [elem]
+ endif
+ endfor
+ return uniqlist
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/nerdtree/lib/nerdtree/event.vim b/config/home/vim/bundle/nerdtree/lib/nerdtree/event.vim
new file mode 100644
index 0000000..964e8ff
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/lib/nerdtree/event.vim
@@ -0,0 +1,13 @@
+"CLASS: Event
+"============================================================
+let s:Event = {}
+let g:NERDTreeEvent = s:Event
+
+function! s:Event.New(nerdtree, subject, action, params) abort
+ let newObj = copy(self)
+ let newObj.nerdtree = a:nerdtree
+ let newObj.subject = a:subject
+ let newObj.action = a:action
+ let newObj.params = a:params
+ return newObj
+endfunction
diff --git a/config/home/vim/bundle/nerdtree/lib/nerdtree/flag_set.vim b/config/home/vim/bundle/nerdtree/lib/nerdtree/flag_set.vim
new file mode 100644
index 0000000..9d8d335
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/lib/nerdtree/flag_set.vim
@@ -0,0 +1,56 @@
+"CLASS: FlagSet
+"============================================================
+let s:FlagSet = {}
+let g:NERDTreeFlagSet = s:FlagSet
+
+"FUNCTION: FlagSet.addFlag(scope, flag) {{{1
+function! s:FlagSet.addFlag(scope, flag)
+ let flags = self._flagsForScope(a:scope)
+ if index(flags, a:flag) == -1
+ call add(flags, a:flag)
+ end
+endfunction
+
+"FUNCTION: FlagSet.clearFlags(scope) {{{1
+function! s:FlagSet.clearFlags(scope)
+ let self._flags[a:scope] = []
+endfunction
+
+"FUNCTION: FlagSet._flagsForScope(scope) {{{1
+function! s:FlagSet._flagsForScope(scope)
+ if !has_key(self._flags, a:scope)
+ let self._flags[a:scope] = []
+ endif
+ return self._flags[a:scope]
+endfunction
+
+"FUNCTION: FlagSet.New() {{{1
+function! s:FlagSet.New()
+ let newObj = copy(self)
+ let newObj._flags = {}
+ return newObj
+endfunction
+
+"FUNCTION: FlagSet.removeFlag(scope, flag) {{{1
+function! s:FlagSet.removeFlag(scope, flag)
+ let flags = self._flagsForScope(a:scope)
+
+ let i = index(flags, a:flag)
+ if i >= 0
+ call remove(flags, i)
+ endif
+endfunction
+
+"FUNCTION: FlagSet.renderToString() {{{1
+function! s:FlagSet.renderToString()
+ let flagstring = ""
+ for i in values(self._flags)
+ let flagstring .= join(i)
+ endfor
+
+ if len(flagstring) == 0
+ return ""
+ endif
+
+ return '[' . flagstring . ']'
+endfunction
diff --git a/config/home/vim/bundle/nerdtree/lib/nerdtree/key_map.vim b/config/home/vim/bundle/nerdtree/lib/nerdtree/key_map.vim
new file mode 100644
index 0000000..2411406
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/lib/nerdtree/key_map.vim
@@ -0,0 +1,159 @@
+"CLASS: KeyMap
+"============================================================
+let s:KeyMap = {}
+let g:NERDTreeKeyMap = s:KeyMap
+
+"FUNCTION: KeyMap.All() {{{1
+function! s:KeyMap.All()
+ if !exists("s:keyMaps")
+ let s:keyMaps = []
+ endif
+ return s:keyMaps
+endfunction
+
+"FUNCTION: KeyMap.FindFor(key, scope) {{{1
+function! s:KeyMap.FindFor(key, scope)
+ for i in s:KeyMap.All()
+ if i.key ==# a:key && i.scope ==# a:scope
+ return i
+ endif
+ endfor
+ return {}
+endfunction
+
+"FUNCTION: KeyMap.BindAll() {{{1
+function! s:KeyMap.BindAll()
+ for i in s:KeyMap.All()
+ call i.bind()
+ endfor
+endfunction
+
+"FUNCTION: KeyMap.bind() {{{1
+function! s:KeyMap.bind()
+ " If the key sequence we're trying to map contains any '<>' notation, we
+ " must replace each of the '<' characters with '' to ensure the string
+ " is not translated into its corresponding keycode during the later part
+ " of the map command below
+ " :he <>
+ let specialNotationRegex = '\m<\([[:alnum:]_-]\+>\)'
+ if self.key =~# specialNotationRegex
+ let keymapInvokeString = substitute(self.key, specialNotationRegex, '\1', 'g')
+ else
+ let keymapInvokeString = self.key
+ endif
+
+ let premap = self.key == "" ? " " : " "
+
+ exec 'nnoremap '. self.key . premap . ':call nerdtree#ui_glue#invokeKeyMap("'. keymapInvokeString .'")'
+endfunction
+
+"FUNCTION: KeyMap.Remove(key, scope) {{{1
+function! s:KeyMap.Remove(key, scope)
+ let maps = s:KeyMap.All()
+ for i in range(len(maps))
+ if maps[i].key ==# a:key && maps[i].scope ==# a:scope
+ return remove(maps, i)
+ endif
+ endfor
+endfunction
+
+"FUNCTION: KeyMap.invoke() {{{1
+"Call the KeyMaps callback function
+function! s:KeyMap.invoke(...)
+ let Callback = function(self.callback)
+ if a:0
+ call Callback(a:1)
+ else
+ call Callback()
+ endif
+endfunction
+
+"FUNCTION: KeyMap.Invoke() {{{1
+"Find a keymapping for a:key and the current scope invoke it.
+"
+"Scope is determined as follows:
+" * if the cursor is on a dir node then "DirNode"
+" * if the cursor is on a file node then "FileNode"
+" * if the cursor is on a bookmark then "Bookmark"
+"
+"If a keymap has the scope of "all" then it will be called if no other keymap
+"is found for a:key and the scope.
+function! s:KeyMap.Invoke(key)
+
+ "required because clicking the command window below another window still
+ "invokes the mapping - but changes the window cursor
+ "is in first
+ "
+ "TODO: remove this check when the vim bug is fixed
+ if !g:NERDTree.ExistsForBuf()
+ return {}
+ endif
+
+ let node = g:NERDTreeFileNode.GetSelected()
+ if !empty(node)
+
+ "try file node
+ if !node.path.isDirectory
+ let km = s:KeyMap.FindFor(a:key, "FileNode")
+ if !empty(km)
+ return km.invoke(node)
+ endif
+ endif
+
+ "try dir node
+ if node.path.isDirectory
+ let km = s:KeyMap.FindFor(a:key, "DirNode")
+ if !empty(km)
+ return km.invoke(node)
+ endif
+ endif
+
+ "try generic node
+ let km = s:KeyMap.FindFor(a:key, "Node")
+ if !empty(km)
+ return km.invoke(node)
+ endif
+
+ endif
+
+ "try bookmark
+ let bm = g:NERDTreeBookmark.GetSelected()
+ if !empty(bm)
+ let km = s:KeyMap.FindFor(a:key, "Bookmark")
+ if !empty(km)
+ return km.invoke(bm)
+ endif
+ endif
+
+ "try all
+ let km = s:KeyMap.FindFor(a:key, "all")
+ if !empty(km)
+ return km.invoke()
+ endif
+endfunction
+
+"FUNCTION: KeyMap.Create(options) {{{1
+function! s:KeyMap.Create(options)
+ let opts = extend({'scope': 'all', 'quickhelpText': ''}, copy(a:options))
+
+ "dont override other mappings unless the 'override' option is given
+ if get(opts, 'override', 0) == 0 && !empty(s:KeyMap.FindFor(opts['key'], opts['scope']))
+ return
+ end
+
+ let newKeyMap = copy(self)
+ let newKeyMap.key = opts['key']
+ let newKeyMap.quickhelpText = opts['quickhelpText']
+ let newKeyMap.callback = opts['callback']
+ let newKeyMap.scope = opts['scope']
+
+ call s:KeyMap.Add(newKeyMap)
+endfunction
+
+"FUNCTION: KeyMap.Add(keymap) {{{1
+function! s:KeyMap.Add(keymap)
+ call s:KeyMap.Remove(a:keymap.key, a:keymap.scope)
+ call add(s:KeyMap.All(), a:keymap)
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/nerdtree/lib/nerdtree/menu_controller.vim b/config/home/vim/bundle/nerdtree/lib/nerdtree/menu_controller.vim
new file mode 100644
index 0000000..ae0ee84
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/lib/nerdtree/menu_controller.vim
@@ -0,0 +1,180 @@
+"CLASS: MenuController
+"============================================================
+let s:MenuController = {}
+let g:NERDTreeMenuController = s:MenuController
+
+"FUNCTION: MenuController.New(menuItems) {{{1
+"create a new menu controller that operates on the given menu items
+function! s:MenuController.New(menuItems)
+ let newMenuController = copy(self)
+ if a:menuItems[0].isSeparator()
+ let newMenuController.menuItems = a:menuItems[1:-1]
+ else
+ let newMenuController.menuItems = a:menuItems
+ endif
+ return newMenuController
+endfunction
+
+"FUNCTION: MenuController.showMenu() {{{1
+"start the main loop of the menu and get the user to choose/execute a menu
+"item
+function! s:MenuController.showMenu()
+ call self._saveOptions()
+
+ try
+ let self.selection = 0
+
+ let done = 0
+ while !done
+ redraw!
+ call self._echoPrompt()
+ let key = nr2char(getchar())
+ let done = self._handleKeypress(key)
+ endwhile
+ finally
+ call self._restoreOptions()
+ endtry
+
+ if self.selection != -1
+ let m = self._current()
+ call m.execute()
+ endif
+endfunction
+
+"FUNCTION: MenuController._echoPrompt() {{{1
+function! s:MenuController._echoPrompt()
+ echo "NERDTree Menu. Use j/k/enter and the shortcuts indicated"
+ echo "=========================================================="
+
+ for i in range(0, len(self.menuItems)-1)
+ if self.selection == i
+ echo "> " . self.menuItems[i].text
+ else
+ echo " " . self.menuItems[i].text
+ endif
+ endfor
+endfunction
+
+"FUNCTION: MenuController._current(key) {{{1
+"get the MenuItem that is currently selected
+function! s:MenuController._current()
+ return self.menuItems[self.selection]
+endfunction
+
+"FUNCTION: MenuController._handleKeypress(key) {{{1
+"change the selection (if appropriate) and return 1 if the user has made
+"their choice, 0 otherwise
+function! s:MenuController._handleKeypress(key)
+ if a:key == 'j'
+ call self._cursorDown()
+ elseif a:key == 'k'
+ call self._cursorUp()
+ elseif a:key == nr2char(27) "escape
+ let self.selection = -1
+ return 1
+ elseif a:key == "\r" || a:key == "\n" "enter and ctrl-j
+ return 1
+ else
+ let index = self._nextIndexFor(a:key)
+ if index != -1
+ let self.selection = index
+ if len(self._allIndexesFor(a:key)) == 1
+ return 1
+ endif
+ endif
+ endif
+
+ return 0
+endfunction
+
+"FUNCTION: MenuController._allIndexesFor(shortcut) {{{1
+"get indexes to all menu items with the given shortcut
+function! s:MenuController._allIndexesFor(shortcut)
+ let toReturn = []
+
+ for i in range(0, len(self.menuItems)-1)
+ if self.menuItems[i].shortcut == a:shortcut
+ call add(toReturn, i)
+ endif
+ endfor
+
+ return toReturn
+endfunction
+
+"FUNCTION: MenuController._nextIndexFor(shortcut) {{{1
+"get the index to the next menu item with the given shortcut, starts from the
+"current cursor location and wraps around to the top again if need be
+function! s:MenuController._nextIndexFor(shortcut)
+ for i in range(self.selection+1, len(self.menuItems)-1)
+ if self.menuItems[i].shortcut == a:shortcut
+ return i
+ endif
+ endfor
+
+ for i in range(0, self.selection)
+ if self.menuItems[i].shortcut == a:shortcut
+ return i
+ endif
+ endfor
+
+ return -1
+endfunction
+
+"FUNCTION: MenuController._setCmdheight() {{{1
+"sets &cmdheight to whatever is needed to display the menu
+function! s:MenuController._setCmdheight()
+ let &cmdheight = len(self.menuItems) + 3
+endfunction
+
+"FUNCTION: MenuController._saveOptions() {{{1
+"set any vim options that are required to make the menu work (saving their old
+"values)
+function! s:MenuController._saveOptions()
+ let self._oldLazyredraw = &lazyredraw
+ let self._oldCmdheight = &cmdheight
+ set nolazyredraw
+ call self._setCmdheight()
+endfunction
+
+"FUNCTION: MenuController._restoreOptions() {{{1
+"restore the options we saved in _saveOptions()
+function! s:MenuController._restoreOptions()
+ let &cmdheight = self._oldCmdheight
+ let &lazyredraw = self._oldLazyredraw
+endfunction
+
+"FUNCTION: MenuController._cursorDown() {{{1
+"move the cursor to the next menu item, skipping separators
+function! s:MenuController._cursorDown()
+ let done = 0
+ while !done
+ if self.selection < len(self.menuItems)-1
+ let self.selection += 1
+ else
+ let self.selection = 0
+ endif
+
+ if !self._current().isSeparator()
+ let done = 1
+ endif
+ endwhile
+endfunction
+
+"FUNCTION: MenuController._cursorUp() {{{1
+"move the cursor to the previous menu item, skipping separators
+function! s:MenuController._cursorUp()
+ let done = 0
+ while !done
+ if self.selection > 0
+ let self.selection -= 1
+ else
+ let self.selection = len(self.menuItems)-1
+ endif
+
+ if !self._current().isSeparator()
+ let done = 1
+ endif
+ endwhile
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/nerdtree/lib/nerdtree/menu_item.vim b/config/home/vim/bundle/nerdtree/lib/nerdtree/menu_item.vim
new file mode 100644
index 0000000..92c1bbb
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/lib/nerdtree/menu_item.vim
@@ -0,0 +1,114 @@
+"CLASS: MenuItem
+"============================================================
+let s:MenuItem = {}
+let g:NERDTreeMenuItem = s:MenuItem
+
+"FUNCTION: MenuItem.All() {{{1
+"get all top level menu items
+function! s:MenuItem.All()
+ if !exists("s:menuItems")
+ let s:menuItems = []
+ endif
+ return s:menuItems
+endfunction
+
+"FUNCTION: MenuItem.AllEnabled() {{{1
+"get all top level menu items that are currently enabled
+function! s:MenuItem.AllEnabled()
+ let toReturn = []
+ for i in s:MenuItem.All()
+ if i.enabled()
+ call add(toReturn, i)
+ endif
+ endfor
+ return toReturn
+endfunction
+
+"FUNCTION: MenuItem.Create(options) {{{1
+"make a new menu item and add it to the global list
+function! s:MenuItem.Create(options)
+ let newMenuItem = copy(self)
+
+ let newMenuItem.text = a:options['text']
+ let newMenuItem.shortcut = a:options['shortcut']
+ let newMenuItem.children = []
+
+ let newMenuItem.isActiveCallback = -1
+ if has_key(a:options, 'isActiveCallback')
+ let newMenuItem.isActiveCallback = a:options['isActiveCallback']
+ endif
+
+ let newMenuItem.callback = -1
+ if has_key(a:options, 'callback')
+ let newMenuItem.callback = a:options['callback']
+ endif
+
+ if has_key(a:options, 'parent')
+ call add(a:options['parent'].children, newMenuItem)
+ else
+ call add(s:MenuItem.All(), newMenuItem)
+ endif
+
+ return newMenuItem
+endfunction
+
+"FUNCTION: MenuItem.CreateSeparator(options) {{{1
+"make a new separator menu item and add it to the global list
+function! s:MenuItem.CreateSeparator(options)
+ let standard_options = { 'text': '--------------------',
+ \ 'shortcut': -1,
+ \ 'callback': -1 }
+ let options = extend(a:options, standard_options, "force")
+
+ return s:MenuItem.Create(options)
+endfunction
+
+"FUNCTION: MenuItem.CreateSubmenu(options) {{{1
+"make a new submenu and add it to global list
+function! s:MenuItem.CreateSubmenu(options)
+ let standard_options = { 'callback': -1 }
+ let options = extend(a:options, standard_options, "force")
+
+ return s:MenuItem.Create(options)
+endfunction
+
+"FUNCTION: MenuItem.enabled() {{{1
+"return 1 if this menu item should be displayed
+"
+"delegates off to the isActiveCallback, and defaults to 1 if no callback was
+"specified
+function! s:MenuItem.enabled()
+ if self.isActiveCallback != -1
+ return {self.isActiveCallback}()
+ endif
+ return 1
+endfunction
+
+"FUNCTION: MenuItem.execute() {{{1
+"perform the action behind this menu item, if this menuitem has children then
+"display a new menu for them, otherwise deletegate off to the menuitem's
+"callback
+function! s:MenuItem.execute()
+ if len(self.children)
+ let mc = g:NERDTreeMenuController.New(self.children)
+ call mc.showMenu()
+ else
+ if self.callback != -1
+ call {self.callback}()
+ endif
+ endif
+endfunction
+
+"FUNCTION: MenuItem.isSeparator() {{{1
+"return 1 if this menuitem is a separator
+function! s:MenuItem.isSeparator()
+ return self.callback == -1 && self.children == []
+endfunction
+
+"FUNCTION: MenuItem.isSubmenu() {{{1
+"return 1 if this menuitem is a submenu
+function! s:MenuItem.isSubmenu()
+ return self.callback == -1 && !empty(self.children)
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/nerdtree/lib/nerdtree/nerdtree.vim b/config/home/vim/bundle/nerdtree/lib/nerdtree/nerdtree.vim
new file mode 100644
index 0000000..55f3dd7
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/lib/nerdtree/nerdtree.vim
@@ -0,0 +1,137 @@
+"CLASS: NERDTree
+"============================================================
+let s:NERDTree = {}
+let g:NERDTree = s:NERDTree
+
+"FUNCTION: s:NERDTree.AddPathFilter() {{{1
+function! s:NERDTree.AddPathFilter(callback)
+ call add(s:NERDTree.PathFilters(), a:callback)
+endfunction
+
+"FUNCTION: s:NERDTree.Close() {{{1
+"Closes the primary NERD tree window for this tab
+function! s:NERDTree.Close()
+ if !s:NERDTree.IsOpen()
+ return
+ endif
+
+ if winnr("$") != 1
+ if winnr() == s:NERDTree.GetWinNum()
+ call nerdtree#exec("wincmd p")
+ let bufnr = bufnr("")
+ call nerdtree#exec("wincmd p")
+ else
+ let bufnr = bufnr("")
+ endif
+
+ call nerdtree#exec(s:NERDTree.GetWinNum() . " wincmd w")
+ close
+ call nerdtree#exec(bufwinnr(bufnr) . " wincmd w")
+ else
+ close
+ endif
+endfunction
+
+"FUNCTION: s:NERDTree.CloseIfQuitOnOpen() {{{1
+"Closes the NERD tree window if the close on open option is set
+function! s:NERDTree.CloseIfQuitOnOpen()
+ if g:NERDTreeQuitOnOpen && s:NERDTree.IsOpen()
+ call s:NERDTree.Close()
+ endif
+endfunction
+
+"FUNCTION: s:NERDTree.CursorToBookmarkTable(){{{1
+"Places the cursor at the top of the bookmarks table
+function! s:NERDTree.CursorToBookmarkTable()
+ if !b:NERDTreeShowBookmarks
+ throw "NERDTree.IllegalOperationError: cant find bookmark table, bookmarks arent active"
+ endif
+
+ if g:NERDTreeMinimalUI
+ return cursor(1, 2)
+ endif
+
+ let rootNodeLine = b:NERDTree.ui.getRootLineNum()
+
+ let line = 1
+ while getline(line) !~# '^>-\+Bookmarks-\+$'
+ let line = line + 1
+ if line >= rootNodeLine
+ throw "NERDTree.BookmarkTableNotFoundError: didnt find the bookmarks table"
+ endif
+ endwhile
+ call cursor(line, 2)
+endfunction
+
+"FUNCTION: s:NERDTree.CursorToTreeWin(){{{1
+"Places the cursor in the nerd tree window
+function! s:NERDTree.CursorToTreeWin()
+ call g:NERDTree.MustBeOpen()
+ call nerdtree#exec(g:NERDTree.GetWinNum() . "wincmd w")
+endfunction
+
+" Function: s:NERDTree.ExistsForBuffer() {{{1
+" Returns 1 if a nerd tree root exists in the current buffer
+function! s:NERDTree.ExistsForBuf()
+ return exists("b:NERDTreeRoot")
+endfunction
+
+" Function: s:NERDTree.ExistsForTab() {{{1
+" Returns 1 if a nerd tree root exists in the current tab
+function! s:NERDTree.ExistsForTab()
+ return exists("t:NERDTreeBufName")
+endfunction
+
+function! s:NERDTree.ForCurrentBuf()
+ if s:NERDTree.ExistsForBuf()
+ return b:NERDTree
+ else
+ return {}
+ endif
+endfunction
+
+"FUNCTION: s:NERDTree.GetWinNum() {{{1
+"gets the nerd tree window number for this tab
+function! s:NERDTree.GetWinNum()
+ if exists("t:NERDTreeBufName")
+ return bufwinnr(t:NERDTreeBufName)
+ else
+ return -1
+ endif
+endfunction
+
+"FUNCTION: s:NERDTree.IsOpen() {{{1
+function! s:NERDTree.IsOpen()
+ return s:NERDTree.GetWinNum() != -1
+endfunction
+
+"FUNCTION: s:NERDTree.MustBeOpen() {{{1
+function! s:NERDTree.MustBeOpen()
+ if !s:NERDTree.IsOpen()
+ throw "NERDTree.TreeNotOpen"
+ endif
+endfunction
+
+"FUNCTION: s:NERDTree.New() {{{1
+function! s:NERDTree.New(path)
+ let newObj = copy(self)
+ let newObj.ui = g:NERDTreeUI.New(newObj)
+ let newObj.root = g:NERDTreeDirNode.New(a:path)
+
+ return newObj
+endfunction
+
+"FUNCTION: s:NERDTree.PathFilters() {{{1
+function! s:NERDTree.PathFilters()
+ if !exists('s:NERDTree._PathFilters')
+ let s:NERDTree._PathFilters = []
+ endif
+ return s:NERDTree._PathFilters
+endfunction
+
+
+"FUNCTION: s:NERDTree.render() {{{1
+"A convenience function - since this is called often
+function! s:NERDTree.render()
+ call self.ui.render()
+endfunction
diff --git a/config/home/vim/bundle/nerdtree/lib/nerdtree/notifier.vim b/config/home/vim/bundle/nerdtree/lib/nerdtree/notifier.vim
new file mode 100644
index 0000000..b445f8a
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/lib/nerdtree/notifier.vim
@@ -0,0 +1,35 @@
+"CLASS: Notifier
+"============================================================
+let s:Notifier = {}
+
+function! s:Notifier.AddListener(event, funcname)
+ let listeners = s:Notifier.GetListenersForEvent(a:event)
+ if listeners == []
+ let listenersMap = s:Notifier.GetListenersMap()
+ let listenersMap[a:event] = listeners
+ endif
+ call add(listeners, a:funcname)
+endfunction
+
+function! s:Notifier.NotifyListeners(event, path, params)
+ let event = g:NERDTreeEvent.New(b:NERDTree, a:path, a:event, a:params)
+
+ for listener in s:Notifier.GetListenersForEvent(a:event)
+ call {listener}(event)
+ endfor
+endfunction
+
+function! s:Notifier.GetListenersMap()
+ if !exists("s:refreshListenersMap")
+ let s:refreshListenersMap = {}
+ endif
+ return s:refreshListenersMap
+endfunction
+
+function! s:Notifier.GetListenersForEvent(name)
+ let listenersMap = s:Notifier.GetListenersMap()
+ return get(listenersMap, a:name, [])
+endfunction
+
+let g:NERDTreePathNotifier = deepcopy(s:Notifier)
+
diff --git a/config/home/vim/bundle/nerdtree/lib/nerdtree/opener.vim b/config/home/vim/bundle/nerdtree/lib/nerdtree/opener.vim
new file mode 100644
index 0000000..3a6b392
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/lib/nerdtree/opener.vim
@@ -0,0 +1,352 @@
+"CLASS: Opener
+"============================================================
+let s:Opener = {}
+let g:NERDTreeOpener = s:Opener
+
+"FUNCTION: s:Opener._bufInWindows(bnum){{{1
+"[[STOLEN FROM VTREEEXPLORER.VIM]]
+"Determine the number of windows open to this buffer number.
+"Care of Yegappan Lakshman. Thanks!
+"
+"Args:
+"bnum: the subject buffers buffer number
+function! s:Opener._bufInWindows(bnum)
+ let cnt = 0
+ let winnum = 1
+ while 1
+ let bufnum = winbufnr(winnum)
+ if bufnum < 0
+ break
+ endif
+ if bufnum ==# a:bnum
+ let cnt = cnt + 1
+ endif
+ let winnum = winnum + 1
+ endwhile
+
+ return cnt
+endfunction
+"FUNCTION: Opener._checkToCloseTree(newtab) {{{1
+"Check the class options and global options (i.e. NERDTreeQuitOnOpen) to see
+"if the tree should be closed now.
+"
+"Args:
+"a:newtab - boolean. If set, only close the tree now if we are opening the
+"target in a new tab. This is needed because we have to close tree before we
+"leave the tab
+function! s:Opener._checkToCloseTree(newtab)
+ if self._keepopen
+ return
+ endif
+
+ if (a:newtab && self._where == 't') || !a:newtab
+ call g:NERDTree.CloseIfQuitOnOpen()
+ endif
+endfunction
+
+
+"FUNCTION: s:Opener._firstUsableWindow(){{{1
+"find the window number of the first normal window
+function! s:Opener._firstUsableWindow()
+ let i = 1
+ while i <= winnr("$")
+ let bnum = winbufnr(i)
+ if bnum != -1 && getbufvar(bnum, '&buftype') ==# ''
+ \ && !getwinvar(i, '&previewwindow')
+ \ && (!getbufvar(bnum, '&modified') || &hidden)
+ return i
+ endif
+
+ let i += 1
+ endwhile
+ return -1
+endfunction
+
+"FUNCTION: Opener._gotoTargetWin() {{{1
+function! s:Opener._gotoTargetWin()
+ if b:NERDTreeType ==# "secondary"
+ if self._where == 'v'
+ vsplit
+ elseif self._where == 'h'
+ split
+ elseif self._where == 't'
+ tabnew
+ endif
+ else
+ call self._checkToCloseTree(1)
+
+ if self._where == 'v'
+ call self._newVSplit()
+ elseif self._where == 'h'
+ call self._newSplit()
+ elseif self._where == 't'
+ tabnew
+ elseif self._where == 'p'
+ call self._previousWindow()
+ endif
+
+ call self._checkToCloseTree(0)
+ endif
+endfunction
+
+"FUNCTION: s:Opener._isWindowUsable(winnumber) {{{1
+"Returns 0 if opening a file from the tree in the given window requires it to
+"be split, 1 otherwise
+"
+"Args:
+"winnumber: the number of the window in question
+function! s:Opener._isWindowUsable(winnumber)
+ "gotta split if theres only one window (i.e. the NERD tree)
+ if winnr("$") ==# 1
+ return 0
+ endif
+
+ let oldwinnr = winnr()
+ call nerdtree#exec(a:winnumber . "wincmd p")
+ let specialWindow = getbufvar("%", '&buftype') != '' || getwinvar('%', '&previewwindow')
+ let modified = &modified
+ call nerdtree#exec(oldwinnr . "wincmd p")
+
+ "if its a special window e.g. quickfix or another explorer plugin then we
+ "have to split
+ if specialWindow
+ return 0
+ endif
+
+ if &hidden
+ return 1
+ endif
+
+ return !modified || self._bufInWindows(winbufnr(a:winnumber)) >= 2
+endfunction
+
+"FUNCTION: Opener.New(path, opts) {{{1
+"Args:
+"
+"a:path: The path object that is to be opened.
+"
+"a:opts:
+"
+"A dictionary containing the following keys (all optional):
+" 'where': Specifies whether the node should be opened in new split/tab or in
+" the previous window. Can be either 'v' or 'h' or 't' (for open in
+" new tab)
+" 'reuse': if a window is displaying the file then jump the cursor there. Can
+" 'all', 'currenttab' or empty to not reuse.
+" 'keepopen': dont close the tree window
+" 'stay': open the file, but keep the cursor in the tree win
+function! s:Opener.New(path, opts)
+ let newObj = copy(self)
+
+ let newObj._path = a:path
+ let newObj._stay = nerdtree#has_opt(a:opts, 'stay')
+
+ if has_key(a:opts, 'reuse')
+ let newObj._reuse = a:opts['reuse']
+ else
+ let newObj._reuse = ''
+ endif
+
+ let newObj._keepopen = nerdtree#has_opt(a:opts, 'keepopen')
+ let newObj._where = has_key(a:opts, 'where') ? a:opts['where'] : ''
+ let newObj._treetype = b:NERDTreeType
+ call newObj._saveCursorPos()
+
+ return newObj
+endfunction
+
+"FUNCTION: Opener._newSplit() {{{1
+function! s:Opener._newSplit()
+ " Save the user's settings for splitbelow and splitright
+ let savesplitbelow=&splitbelow
+ let savesplitright=&splitright
+
+ " 'there' will be set to a command to move from the split window
+ " back to the explorer window
+ "
+ " 'back' will be set to a command to move from the explorer window
+ " back to the newly split window
+ "
+ " 'right' and 'below' will be set to the settings needed for
+ " splitbelow and splitright IF the explorer is the only window.
+ "
+ let there= g:NERDTreeWinPos ==# "left" ? "wincmd h" : "wincmd l"
+ let back = g:NERDTreeWinPos ==# "left" ? "wincmd l" : "wincmd h"
+ let right= g:NERDTreeWinPos ==# "left"
+ let below=0
+
+ " Attempt to go to adjacent window
+ call nerdtree#exec(back)
+
+ let onlyOneWin = (winnr("$") ==# 1)
+
+ " If no adjacent window, set splitright and splitbelow appropriately
+ if onlyOneWin
+ let &splitright=right
+ let &splitbelow=below
+ else
+ " found adjacent window - invert split direction
+ let &splitright=!right
+ let &splitbelow=!below
+ endif
+
+ let splitMode = onlyOneWin ? "vertical" : ""
+
+ " Open the new window
+ try
+ exec(splitMode." sp ")
+ catch /^Vim\%((\a\+)\)\=:E37/
+ call g:NERDTree.CursorToTreeWin()
+ throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified."
+ catch /^Vim\%((\a\+)\)\=:/
+ "do nothing
+ endtry
+
+ "resize the tree window if no other window was open before
+ if onlyOneWin
+ let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize
+ call nerdtree#exec(there)
+ exec("silent ". splitMode ." resize ". size)
+ call nerdtree#exec('wincmd p')
+ endif
+
+ " Restore splitmode settings
+ let &splitbelow=savesplitbelow
+ let &splitright=savesplitright
+endfunction
+
+"FUNCTION: Opener._newVSplit() {{{1
+function! s:Opener._newVSplit()
+ let winwidth = winwidth(".")
+ if winnr("$")==#1
+ let winwidth = g:NERDTreeWinSize
+ endif
+
+ call nerdtree#exec("wincmd p")
+ vnew
+
+ "resize the nerd tree back to the original size
+ call g:NERDTree.CursorToTreeWin()
+ exec("silent vertical resize ". winwidth)
+ call nerdtree#exec('wincmd p')
+endfunction
+
+"FUNCTION: Opener.open(target) {{{1
+function! s:Opener.open(target)
+ if self._path.isDirectory
+ call self._openDirectory(a:target)
+ else
+ call self._openFile()
+ endif
+endfunction
+
+"FUNCTION: Opener._openFile() {{{1
+function! s:Opener._openFile()
+ if self._reuseWindow()
+ return
+ endif
+
+ call self._gotoTargetWin()
+
+ if self._treetype ==# "secondary"
+ call self._path.edit()
+ else
+ call self._path.edit()
+
+
+ if self._stay
+ call self._restoreCursorPos()
+ endif
+ endif
+endfunction
+
+"FUNCTION: Opener._openDirectory(node) {{{1
+function! s:Opener._openDirectory(node)
+ if self._treetype ==# "secondary"
+ call self._gotoTargetWin()
+ call g:NERDTreeCreator.CreateSecondary(a:node.path.str())
+ else
+ call self._gotoTargetWin()
+ if empty(self._where)
+ call a:node.makeRoot()
+ call b:NERDTree.render()
+ call a:node.putCursorHere(0, 0)
+ elseif self._where == 't'
+ call g:NERDTreeCreator.CreatePrimary(a:node.path.str())
+ else
+ call g:NERDTreeCreator.CreateSecondary(a:node.path.str())
+ endif
+ endif
+
+ if self._stay
+ call self._restoreCursorPos()
+ endif
+endfunction
+
+"FUNCTION: Opener._previousWindow() {{{1
+function! s:Opener._previousWindow()
+ if !self._isWindowUsable(winnr("#")) && self._firstUsableWindow() ==# -1
+ call self._newSplit()
+ else
+ try
+ if !self._isWindowUsable(winnr("#"))
+ call nerdtree#exec(self._firstUsableWindow() . "wincmd w")
+ else
+ call nerdtree#exec('wincmd p')
+ endif
+ catch /^Vim\%((\a\+)\)\=:E37/
+ call g:NERDTree.CursorToTreeWin()
+ throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified."
+ catch /^Vim\%((\a\+)\)\=:/
+ echo v:exception
+ endtry
+ endif
+endfunction
+
+"FUNCTION: Opener._restoreCursorPos(){{{1
+function! s:Opener._restoreCursorPos()
+ call nerdtree#exec('normal ' . self._tabnr . 'gt')
+ call nerdtree#exec(bufwinnr(self._bufnr) . 'wincmd w')
+endfunction
+
+"FUNCTION: Opener._reuseWindow(){{{1
+"put the cursor in the first window we find for this file
+"
+"return 1 if we were successful
+function! s:Opener._reuseWindow()
+ if empty(self._reuse)
+ return 0
+ endif
+
+ "check the current tab for the window
+ let winnr = bufwinnr('^' . self._path.str() . '$')
+ if winnr != -1
+ call nerdtree#exec(winnr . "wincmd w")
+ call self._checkToCloseTree(0)
+ return 1
+ endif
+
+ if self._reuse == 'currenttab'
+ return 0
+ endif
+
+ "check other tabs
+ let tabnr = self._path.tabnr()
+ if tabnr
+ call self._checkToCloseTree(1)
+ call nerdtree#exec('normal! ' . tabnr . 'gt')
+ let winnr = bufwinnr('^' . self._path.str() . '$')
+ call nerdtree#exec(winnr . "wincmd w")
+ return 1
+ endif
+
+ return 0
+endfunction
+
+"FUNCTION: Opener._saveCursorPos(){{{1
+function! s:Opener._saveCursorPos()
+ let self._bufnr = bufnr("")
+ let self._tabnr = tabpagenr()
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/nerdtree/lib/nerdtree/path.vim b/config/home/vim/bundle/nerdtree/lib/nerdtree/path.vim
new file mode 100644
index 0000000..48793eb
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/lib/nerdtree/path.vim
@@ -0,0 +1,761 @@
+"we need to use this number many times for sorting... so we calculate it only
+"once here
+let s:NERDTreeSortStarIndex = index(g:NERDTreeSortOrder, '*')
+
+"CLASS: Path
+"============================================================
+let s:Path = {}
+let g:NERDTreePath = s:Path
+
+"FUNCTION: Path.AbsolutePathFor(str) {{{1
+function! s:Path.AbsolutePathFor(str)
+ let prependCWD = 0
+ if nerdtree#runningWindows()
+ let prependCWD = a:str !~# '^.:\(\\\|\/\)' && a:str !~# '^\(\\\\\|\/\/\)'
+ else
+ let prependCWD = a:str !~# '^/'
+ endif
+
+ let toReturn = a:str
+ if prependCWD
+ let toReturn = getcwd() . s:Path.Slash() . a:str
+ endif
+
+ return toReturn
+endfunction
+
+"FUNCTION: Path.bookmarkNames() {{{1
+function! s:Path.bookmarkNames()
+ if !exists("self._bookmarkNames")
+ call self.cacheDisplayString()
+ endif
+ return self._bookmarkNames
+endfunction
+
+"FUNCTION: Path.cacheDisplayString() {{{1
+function! s:Path.cacheDisplayString() abort
+ let self.cachedDisplayString = self.flagSet.renderToString()
+
+ let self.cachedDisplayString .= self.getLastPathComponent(1)
+
+ if self.isExecutable
+ let self.cachedDisplayString = self.cachedDisplayString . '*'
+ endif
+
+ let self._bookmarkNames = []
+ for i in g:NERDTreeBookmark.Bookmarks()
+ if i.path.equals(self)
+ call add(self._bookmarkNames, i.name)
+ endif
+ endfor
+ if !empty(self._bookmarkNames)
+ let self.cachedDisplayString .= ' {' . join(self._bookmarkNames) . '}'
+ endif
+
+ if self.isSymLink
+ let self.cachedDisplayString .= ' -> ' . self.symLinkDest
+ endif
+
+ if self.isReadOnly
+ let self.cachedDisplayString .= ' [RO]'
+ endif
+endfunction
+
+"FUNCTION: Path.changeToDir() {{{1
+function! s:Path.changeToDir()
+ let dir = self.str({'format': 'Cd'})
+ if self.isDirectory ==# 0
+ let dir = self.getParent().str({'format': 'Cd'})
+ endif
+
+ try
+ execute "cd " . dir
+ call nerdtree#echo("CWD is now: " . getcwd())
+ catch
+ throw "NERDTree.PathChangeError: cannot change CWD to " . dir
+ endtry
+endfunction
+
+"FUNCTION: Path.compareTo() {{{1
+"
+"Compares this Path to the given path and returns 0 if they are equal, -1 if
+"this Path is "less than" the given path, or 1 if it is "greater".
+"
+"Args:
+"path: the path object to compare this to
+"
+"Return:
+"1, -1 or 0
+function! s:Path.compareTo(path)
+ let thisPath = self.getLastPathComponent(1)
+ let thatPath = a:path.getLastPathComponent(1)
+
+ "if the paths are the same then clearly we return 0
+ if thisPath ==# thatPath
+ return 0
+ endif
+
+ let thisSS = self.getSortOrderIndex()
+ let thatSS = a:path.getSortOrderIndex()
+
+ "compare the sort sequences, if they are different then the return
+ "value is easy
+ if thisSS < thatSS
+ return -1
+ elseif thisSS > thatSS
+ return 1
+ else
+ if !g:NERDTreeSortHiddenFirst
+ let thisPath = substitute(thisPath, '^[._]', '', '')
+ let thatPath = substitute(thatPath, '^[._]', '', '')
+ endif
+ "if the sort sequences are the same then compare the paths
+ "alphabetically
+ let pathCompare = g:NERDTreeCaseSensitiveSort ? thisPath <# thatPath : thisPath thatPath
+ if pathCompare
+ return -1
+ else
+ return 1
+ endif
+ endif
+endfunction
+
+"FUNCTION: Path.Create(fullpath) {{{1
+"
+"Factory method.
+"
+"Creates a path object with the given path. The path is also created on the
+"filesystem. If the path already exists, a NERDTree.Path.Exists exception is
+"thrown. If any other errors occur, a NERDTree.Path exception is thrown.
+"
+"Args:
+"fullpath: the full filesystem path to the file/dir to create
+function! s:Path.Create(fullpath)
+ "bail if the a:fullpath already exists
+ if isdirectory(a:fullpath) || filereadable(a:fullpath)
+ throw "NERDTree.CreatePathError: Directory Exists: '" . a:fullpath . "'"
+ endif
+
+ try
+
+ "if it ends with a slash, assume its a dir create it
+ if a:fullpath =~# '\(\\\|\/\)$'
+ "whack the trailing slash off the end if it exists
+ let fullpath = substitute(a:fullpath, '\(\\\|\/\)$', '', '')
+
+ call mkdir(fullpath, 'p')
+
+ "assume its a file and create
+ else
+ call s:Path.createParentDirectories(a:fullpath)
+ call writefile([], a:fullpath)
+ endif
+ catch
+ throw "NERDTree.CreatePathError: Could not create path: '" . a:fullpath . "'"
+ endtry
+
+ return s:Path.New(a:fullpath)
+endfunction
+
+"FUNCTION: Path.copy(dest) {{{1
+"
+"Copies the file/dir represented by this Path to the given location
+"
+"Args:
+"dest: the location to copy this dir/file to
+function! s:Path.copy(dest)
+ if !s:Path.CopyingSupported()
+ throw "NERDTree.CopyingNotSupportedError: Copying is not supported on this OS"
+ endif
+
+ call s:Path.createParentDirectories(a:dest)
+
+ let dest = s:Path.WinToUnixPath(a:dest)
+
+ let cmd = g:NERDTreeCopyCmd . " " . escape(self.str(), self._escChars()) . " " . escape(dest, self._escChars())
+ let success = system(cmd)
+ if success != 0
+ throw "NERDTree.CopyError: Could not copy ''". self.str() ."'' to: '" . a:dest . "'"
+ endif
+endfunction
+
+"FUNCTION: Path.CopyingSupported() {{{1
+"
+"returns 1 if copying is supported for this OS
+function! s:Path.CopyingSupported()
+ return exists('g:NERDTreeCopyCmd')
+endfunction
+
+"FUNCTION: Path.copyingWillOverwrite(dest) {{{1
+"
+"returns 1 if copy this path to the given location will cause files to
+"overwritten
+"
+"Args:
+"dest: the location this path will be copied to
+function! s:Path.copyingWillOverwrite(dest)
+ if filereadable(a:dest)
+ return 1
+ endif
+
+ if isdirectory(a:dest)
+ let path = s:Path.JoinPathStrings(a:dest, self.getLastPathComponent(0))
+ if filereadable(path)
+ return 1
+ endif
+ endif
+endfunction
+
+"FUNCTION: Path.createParentDirectories(path) {{{1
+"
+"create parent directories for this path if needed
+"without throwing any errors is those directories already exist
+"
+"Args:
+"path: full path of the node whose parent directories may need to be created
+function! s:Path.createParentDirectories(path)
+ let dir_path = fnamemodify(a:path, ':h')
+ if !isdirectory(dir_path)
+ call mkdir(dir_path, 'p')
+ endif
+endfunction
+
+"FUNCTION: Path.delete() {{{1
+"
+"Deletes the file represented by this path.
+"Deletion of directories is not supported
+"
+"Throws NERDTree.Path.Deletion exceptions
+function! s:Path.delete()
+ if self.isDirectory
+
+ let cmd = g:NERDTreeRemoveDirCmd . self.str({'escape': 1})
+ let success = system(cmd)
+
+ if v:shell_error != 0
+ throw "NERDTree.PathDeletionError: Could not delete directory: '" . self.str() . "'"
+ endif
+ else
+ let success = delete(self.str())
+ if success != 0
+ throw "NERDTree.PathDeletionError: Could not delete file: '" . self.str() . "'"
+ endif
+ endif
+
+ "delete all bookmarks for this path
+ for i in self.bookmarkNames()
+ let bookmark = g:NERDTreeBookmark.BookmarkFor(i)
+ call bookmark.delete()
+ endfor
+endfunction
+
+"FUNCTION: Path.displayString() {{{1
+"
+"Returns a string that specifies how the path should be represented as a
+"string
+function! s:Path.displayString()
+ if self.cachedDisplayString ==# ""
+ call self.cacheDisplayString()
+ endif
+
+ return self.cachedDisplayString
+endfunction
+
+"FUNCTION: Path.edit() {{{1
+function! s:Path.edit()
+ exec "edit " . self.str({'format': 'Edit'})
+endfunction
+
+"FUNCTION: Path.extractDriveLetter(fullpath) {{{1
+"
+"If running windows, cache the drive letter for this path
+function! s:Path.extractDriveLetter(fullpath)
+ if nerdtree#runningWindows()
+ if a:fullpath =~ '^\(\\\\\|\/\/\)'
+ "For network shares, the 'drive' consists of the first two parts of the path, i.e. \\boxname\share
+ let self.drive = substitute(a:fullpath, '^\(\(\\\\\|\/\/\)[^\\\/]*\(\\\|\/\)[^\\\/]*\).*', '\1', '')
+ let self.drive = substitute(self.drive, '/', '\', "g")
+ else
+ let self.drive = substitute(a:fullpath, '\(^[a-zA-Z]:\).*', '\1', '')
+ endif
+ else
+ let self.drive = ''
+ endif
+
+endfunction
+
+"FUNCTION: Path.exists() {{{1
+"return 1 if this path points to a location that is readable or is a directory
+function! s:Path.exists()
+ let p = self.str()
+ return filereadable(p) || isdirectory(p)
+endfunction
+
+"FUNCTION: Path._escChars() {{{1
+function! s:Path._escChars()
+ if nerdtree#runningWindows()
+ return " `\|\"#%&,?()\*^<>"
+ endif
+
+ return " \\`\|\"#%&,?()\*^<>[]"
+endfunction
+
+"FUNCTION: Path.getDir() {{{1
+"
+"Returns this path if it is a directory, else this paths parent.
+"
+"Return:
+"a Path object
+function! s:Path.getDir()
+ if self.isDirectory
+ return self
+ else
+ return self.getParent()
+ endif
+endfunction
+
+"FUNCTION: Path.getParent() {{{1
+"
+"Returns a new path object for this paths parent
+"
+"Return:
+"a new Path object
+function! s:Path.getParent()
+ if nerdtree#runningWindows()
+ let path = self.drive . '\' . join(self.pathSegments[0:-2], '\')
+ else
+ let path = '/'. join(self.pathSegments[0:-2], '/')
+ endif
+
+ return s:Path.New(path)
+endfunction
+
+"FUNCTION: Path.getLastPathComponent(dirSlash) {{{1
+"
+"Gets the last part of this path.
+"
+"Args:
+"dirSlash: if 1 then a trailing slash will be added to the returned value for
+"directory nodes.
+function! s:Path.getLastPathComponent(dirSlash)
+ if empty(self.pathSegments)
+ return ''
+ endif
+ let toReturn = self.pathSegments[-1]
+ if a:dirSlash && self.isDirectory
+ let toReturn = toReturn . '/'
+ endif
+ return toReturn
+endfunction
+
+"FUNCTION: Path.getSortOrderIndex() {{{1
+"returns the index of the pattern in g:NERDTreeSortOrder that this path matches
+function! s:Path.getSortOrderIndex()
+ let i = 0
+ while i < len(g:NERDTreeSortOrder)
+ if self.getLastPathComponent(1) =~# g:NERDTreeSortOrder[i]
+ return i
+ endif
+ let i = i + 1
+ endwhile
+ return s:NERDTreeSortStarIndex
+endfunction
+
+"FUNCTION: Path.isUnixHiddenFile() {{{1
+"check for unix hidden files
+function! s:Path.isUnixHiddenFile()
+ return self.getLastPathComponent(0) =~# '^\.'
+endfunction
+
+"FUNCTION: Path.isUnixHiddenPath() {{{1
+"check for unix path with hidden components
+function! s:Path.isUnixHiddenPath()
+ if self.getLastPathComponent(0) =~# '^\.'
+ return 1
+ else
+ for segment in self.pathSegments
+ if segment =~# '^\.'
+ return 1
+ endif
+ endfor
+ return 0
+ endif
+endfunction
+
+"FUNCTION: Path.ignore() {{{1
+"returns true if this path should be ignored
+function! s:Path.ignore()
+ "filter out the user specified paths to ignore
+ if b:NERDTreeIgnoreEnabled
+ for i in g:NERDTreeIgnore
+ if self._ignorePatternMatches(i)
+ return 1
+ endif
+ endfor
+
+ for callback in g:NERDTree.PathFilters()
+ if {callback}({'path': self, 'nerdtree': b:NERDTree})
+ return 1
+ endif
+ endfor
+ endif
+
+ "dont show hidden files unless instructed to
+ if b:NERDTreeShowHidden ==# 0 && self.isUnixHiddenFile()
+ return 1
+ endif
+
+ if b:NERDTreeShowFiles ==# 0 && self.isDirectory ==# 0
+ return 1
+ endif
+
+ return 0
+endfunction
+
+"FUNCTION: Path._ignorePatternMatches(pattern) {{{1
+"returns true if this path matches the given ignore pattern
+function! s:Path._ignorePatternMatches(pattern)
+ let pat = a:pattern
+ if strpart(pat,len(pat)-7) == '[[dir]]'
+ if !self.isDirectory
+ return 0
+ endif
+ let pat = strpart(pat,0, len(pat)-7)
+ elseif strpart(pat,len(pat)-8) == '[[file]]'
+ if self.isDirectory
+ return 0
+ endif
+ let pat = strpart(pat,0, len(pat)-8)
+ endif
+
+ return self.getLastPathComponent(0) =~# pat
+endfunction
+
+"FUNCTION: Path.isUnder(path) {{{1
+"return 1 if this path is somewhere under the given path in the filesystem.
+"
+"a:path should be a dir
+function! s:Path.isUnder(path)
+ if a:path.isDirectory == 0
+ return 0
+ endif
+
+ let this = self.str()
+ let that = a:path.str()
+ return stridx(this, that . s:Path.Slash()) == 0
+endfunction
+
+"FUNCTION: Path.JoinPathStrings(...) {{{1
+function! s:Path.JoinPathStrings(...)
+ let components = []
+ for i in a:000
+ let components = extend(components, split(i, '/'))
+ endfor
+ return '/' . join(components, '/')
+endfunction
+
+"FUNCTION: Path.equals() {{{1
+"
+"Determines whether 2 path objects are "equal".
+"They are equal if the paths they represent are the same
+"
+"Args:
+"path: the other path obj to compare this with
+function! s:Path.equals(path)
+ return self.str() ==# a:path.str()
+endfunction
+
+"FUNCTION: Path.New() {{{1
+"The Constructor for the Path object
+function! s:Path.New(path)
+ let newPath = copy(self)
+
+ call newPath.readInfoFromDisk(s:Path.AbsolutePathFor(a:path))
+
+ let newPath.cachedDisplayString = ""
+ let newPath.flagSet = g:NERDTreeFlagSet.New()
+
+ return newPath
+endfunction
+
+"FUNCTION: Path.Slash() {{{1
+"return the slash to use for the current OS
+function! s:Path.Slash()
+ return nerdtree#runningWindows() ? '\' : '/'
+endfunction
+
+"FUNCTION: Path.Resolve() {{{1
+"Invoke the vim resolve() function and return the result
+"This is necessary because in some versions of vim resolve() removes trailing
+"slashes while in other versions it doesn't. This always removes the trailing
+"slash
+function! s:Path.Resolve(path)
+ let tmp = resolve(a:path)
+ return tmp =~# '.\+/$' ? substitute(tmp, '/$', '', '') : tmp
+endfunction
+
+"FUNCTION: Path.readInfoFromDisk(fullpath) {{{1
+"
+"
+"Throws NERDTree.Path.InvalidArguments exception.
+function! s:Path.readInfoFromDisk(fullpath)
+ call self.extractDriveLetter(a:fullpath)
+
+ let fullpath = s:Path.WinToUnixPath(a:fullpath)
+
+ if getftype(fullpath) ==# "fifo"
+ throw "NERDTree.InvalidFiletypeError: Cant handle FIFO files: " . a:fullpath
+ endif
+
+ let self.pathSegments = split(fullpath, '/')
+
+ let self.isReadOnly = 0
+ if isdirectory(a:fullpath)
+ let self.isDirectory = 1
+ elseif filereadable(a:fullpath)
+ let self.isDirectory = 0
+ let self.isReadOnly = filewritable(a:fullpath) ==# 0
+ else
+ throw "NERDTree.InvalidArgumentsError: Invalid path = " . a:fullpath
+ endif
+
+ let self.isExecutable = 0
+ if !self.isDirectory
+ let self.isExecutable = getfperm(a:fullpath) =~# 'x'
+ endif
+
+ "grab the last part of the path (minus the trailing slash)
+ let lastPathComponent = self.getLastPathComponent(0)
+
+ "get the path to the new node with the parent dir fully resolved
+ let hardPath = s:Path.Resolve(self.strTrunk()) . '/' . lastPathComponent
+
+ "if the last part of the path is a symlink then flag it as such
+ let self.isSymLink = (s:Path.Resolve(hardPath) != hardPath)
+ if self.isSymLink
+ let self.symLinkDest = s:Path.Resolve(fullpath)
+
+ "if the link is a dir then slap a / on the end of its dest
+ if isdirectory(self.symLinkDest)
+
+ "we always wanna treat MS windows shortcuts as files for
+ "simplicity
+ if hardPath !~# '\.lnk$'
+
+ let self.symLinkDest = self.symLinkDest . '/'
+ endif
+ endif
+ endif
+endfunction
+
+"FUNCTION: Path.refresh() {{{1
+function! s:Path.refresh()
+ call self.readInfoFromDisk(self.str())
+ call g:NERDTreePathNotifier.NotifyListeners('refresh', self, {})
+ call self.cacheDisplayString()
+endfunction
+
+"FUNCTION: Path.refreshFlags() {{{1
+function! s:Path.refreshFlags()
+ call g:NERDTreePathNotifier.NotifyListeners('refreshFlags', self, {})
+ call self.cacheDisplayString()
+endfunction
+
+"FUNCTION: Path.rename() {{{1
+"
+"Renames this node on the filesystem
+function! s:Path.rename(newPath)
+ if a:newPath ==# ''
+ throw "NERDTree.InvalidArgumentsError: Invalid newPath for renaming = ". a:newPath
+ endif
+
+ let success = rename(self.str(), a:newPath)
+ if success != 0
+ throw "NERDTree.PathRenameError: Could not rename: '" . self.str() . "'" . 'to:' . a:newPath
+ endif
+ call self.readInfoFromDisk(a:newPath)
+
+ for i in self.bookmarkNames()
+ let b = g:NERDTreeBookmark.BookmarkFor(i)
+ call b.setPath(copy(self))
+ endfor
+ call g:NERDTreeBookmark.Write()
+endfunction
+
+"FUNCTION: Path.str() {{{1
+"
+"Returns a string representation of this Path
+"
+"Takes an optional dictionary param to specify how the output should be
+"formatted.
+"
+"The dict may have the following keys:
+" 'format'
+" 'escape'
+" 'truncateTo'
+"
+"The 'format' key may have a value of:
+" 'Cd' - a string to be used with the :cd command
+" 'Edit' - a string to be used with :e :sp :new :tabedit etc
+" 'UI' - a string used in the NERD tree UI
+"
+"The 'escape' key, if specified will cause the output to be escaped with
+"shellescape()
+"
+"The 'truncateTo' key causes the resulting string to be truncated to the value
+"'truncateTo' maps to. A '<' char will be prepended.
+function! s:Path.str(...)
+ let options = a:0 ? a:1 : {}
+ let toReturn = ""
+
+ if has_key(options, 'format')
+ let format = options['format']
+ if has_key(self, '_strFor' . format)
+ exec 'let toReturn = self._strFor' . format . '()'
+ else
+ raise 'NERDTree.UnknownFormatError: unknown format "'. format .'"'
+ endif
+ else
+ let toReturn = self._str()
+ endif
+
+ if nerdtree#has_opt(options, 'escape')
+ let toReturn = shellescape(toReturn)
+ endif
+
+ if has_key(options, 'truncateTo')
+ let limit = options['truncateTo']
+ if len(toReturn) > limit-1
+ let toReturn = toReturn[(len(toReturn)-limit+1):]
+ if len(split(toReturn, '/')) > 1
+ let toReturn = '' . join(split(toReturn, '/')[1:], '/') . '/'
+ else
+ let toReturn = '<' . toReturn
+ endif
+ endif
+ endif
+
+ return toReturn
+endfunction
+
+"FUNCTION: Path._strForUI() {{{1
+function! s:Path._strForUI()
+ let toReturn = '/' . join(self.pathSegments, '/')
+ if self.isDirectory && toReturn != '/'
+ let toReturn = toReturn . '/'
+ endif
+ return toReturn
+endfunction
+
+"FUNCTION: Path._strForCd() {{{1
+"
+" returns a string that can be used with :cd
+function! s:Path._strForCd()
+ return escape(self.str(), self._escChars())
+endfunction
+
+"FUNCTION: Path._strForEdit() {{{1
+"
+"Return: the string for this path that is suitable to be used with the :edit
+"command
+function! s:Path._strForEdit()
+ let p = escape(self.str(), self._escChars())
+
+ "make it relative
+ let p = fnamemodify(p, ':.')
+
+ "handle the edge case where the file begins with a + (vim interprets
+ "the +foo in `:e +foo` as an option to :edit)
+ if p[0] == "+"
+ let p = '\' . p
+ endif
+
+ if p ==# ''
+ let p = '.'
+ endif
+
+ return p
+endfunction
+
+"FUNCTION: Path._strForGlob() {{{1
+function! s:Path._strForGlob()
+ let lead = s:Path.Slash()
+
+ "if we are running windows then slap a drive letter on the front
+ if nerdtree#runningWindows()
+ let lead = self.drive . '\'
+ endif
+
+ let toReturn = lead . join(self.pathSegments, s:Path.Slash())
+
+ if !nerdtree#runningWindows()
+ let toReturn = escape(toReturn, self._escChars())
+ endif
+ return toReturn
+endfunction
+
+"FUNCTION: Path._str() {{{1
+"
+"Gets the string path for this path object that is appropriate for the OS.
+"EG, in windows c:\foo\bar
+" in *nix /foo/bar
+function! s:Path._str()
+ let lead = s:Path.Slash()
+
+ "if we are running windows then slap a drive letter on the front
+ if nerdtree#runningWindows()
+ let lead = self.drive . '\'
+ endif
+
+ return lead . join(self.pathSegments, s:Path.Slash())
+endfunction
+
+"FUNCTION: Path.strTrunk() {{{1
+"Gets the path without the last segment on the end.
+function! s:Path.strTrunk()
+ return self.drive . '/' . join(self.pathSegments[0:-2], '/')
+endfunction
+
+" FUNCTION: Path.tabnr() {{{1
+" return the number of the first tab that is displaying this file
+"
+" return 0 if no tab was found
+function! s:Path.tabnr()
+ let str = self.str()
+ for t in range(tabpagenr('$'))
+ for b in tabpagebuflist(t+1)
+ if str == expand('#' . b . ':p')
+ return t+1
+ endif
+ endfor
+ endfor
+ return 0
+endfunction
+
+"FUNCTION: Path.WinToUnixPath(pathstr){{{1
+"Takes in a windows path and returns the unix equiv
+"
+"A class level method
+"
+"Args:
+"pathstr: the windows path to convert
+function! s:Path.WinToUnixPath(pathstr)
+ if !nerdtree#runningWindows()
+ return a:pathstr
+ endif
+
+ let toReturn = a:pathstr
+
+ "remove the x:\ of the front
+ let toReturn = substitute(toReturn, '^.*:\(\\\|/\)\?', '/', "")
+
+ "remove the \\ network share from the front
+ let toReturn = substitute(toReturn, '^\(\\\\\|\/\/\)[^\\\/]*\(\\\|\/\)[^\\\/]*\(\\\|\/\)\?', '/', "")
+
+ "convert all \ chars to /
+ let toReturn = substitute(toReturn, '\', '/', "g")
+
+ return toReturn
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/nerdtree/lib/nerdtree/tree_dir_node.vim b/config/home/vim/bundle/nerdtree/lib/nerdtree/tree_dir_node.vim
new file mode 100644
index 0000000..a24c270
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/lib/nerdtree/tree_dir_node.vim
@@ -0,0 +1,543 @@
+"CLASS: TreeDirNode
+"A subclass of NERDTreeFileNode.
+"
+"The 'composite' part of the file/dir composite.
+"============================================================
+let s:TreeDirNode = copy(g:NERDTreeFileNode)
+let g:NERDTreeDirNode = s:TreeDirNode
+
+"FUNCTION: TreeDirNode.AbsoluteTreeRoot(){{{1
+"class method that returns the highest cached ancestor of the current root
+function! s:TreeDirNode.AbsoluteTreeRoot()
+ let currentNode = b:NERDTreeRoot
+ while currentNode.parent != {}
+ let currentNode = currentNode.parent
+ endwhile
+ return currentNode
+endfunction
+
+"FUNCTION: TreeDirNode.activate([options]) {{{1
+unlet s:TreeDirNode.activate
+function! s:TreeDirNode.activate(...)
+ let opts = a:0 ? a:1 : {}
+ call self.toggleOpen(opts)
+ call b:NERDTree.render()
+ call self.putCursorHere(0, 0)
+endfunction
+
+"FUNCTION: TreeDirNode.addChild(treenode, inOrder) {{{1
+"Adds the given treenode to the list of children for this node
+"
+"Args:
+"-treenode: the node to add
+"-inOrder: 1 if the new node should be inserted in sorted order
+function! s:TreeDirNode.addChild(treenode, inOrder)
+ call add(self.children, a:treenode)
+ let a:treenode.parent = self
+
+ if a:inOrder
+ call self.sortChildren()
+ endif
+endfunction
+
+"FUNCTION: TreeDirNode.close() {{{1
+"Closes this directory
+function! s:TreeDirNode.close()
+ let self.isOpen = 0
+endfunction
+
+"FUNCTION: TreeDirNode.closeChildren() {{{1
+"Closes all the child dir nodes of this node
+function! s:TreeDirNode.closeChildren()
+ for i in self.children
+ if i.path.isDirectory
+ call i.close()
+ call i.closeChildren()
+ endif
+ endfor
+endfunction
+
+"FUNCTION: TreeDirNode.createChild(path, inOrder) {{{1
+"Instantiates a new child node for this node with the given path. The new
+"nodes parent is set to this node.
+"
+"Args:
+"path: a Path object that this node will represent/contain
+"inOrder: 1 if the new node should be inserted in sorted order
+"
+"Returns:
+"the newly created node
+function! s:TreeDirNode.createChild(path, inOrder)
+ let newTreeNode = g:NERDTreeFileNode.New(a:path)
+ call self.addChild(newTreeNode, a:inOrder)
+ return newTreeNode
+endfunction
+
+"FUNCTION: TreeDirNode.findNode(path) {{{1
+"Will find one of the children (recursively) that has the given path
+"
+"Args:
+"path: a path object
+unlet s:TreeDirNode.findNode
+function! s:TreeDirNode.findNode(path)
+ if a:path.equals(self.path)
+ return self
+ endif
+ if stridx(a:path.str(), self.path.str(), 0) ==# -1
+ return {}
+ endif
+
+ if self.path.isDirectory
+ for i in self.children
+ let retVal = i.findNode(a:path)
+ if retVal != {}
+ return retVal
+ endif
+ endfor
+ endif
+ return {}
+endfunction
+
+"FUNCTION: TreeDirNode.getChildCount() {{{1
+"Returns the number of children this node has
+function! s:TreeDirNode.getChildCount()
+ return len(self.children)
+endfunction
+
+"FUNCTION: TreeDirNode.getChild(path) {{{1
+"Returns child node of this node that has the given path or {} if no such node
+"exists.
+"
+"This function doesnt not recurse into child dir nodes
+"
+"Args:
+"path: a path object
+function! s:TreeDirNode.getChild(path)
+ if stridx(a:path.str(), self.path.str(), 0) ==# -1
+ return {}
+ endif
+
+ let index = self.getChildIndex(a:path)
+ if index ==# -1
+ return {}
+ else
+ return self.children[index]
+ endif
+
+endfunction
+
+"FUNCTION: TreeDirNode.getChildByIndex(indx, visible) {{{1
+"returns the child at the given index
+"Args:
+"indx: the index to get the child from
+"visible: 1 if only the visible children array should be used, 0 if all the
+"children should be searched.
+function! s:TreeDirNode.getChildByIndex(indx, visible)
+ let array_to_search = a:visible? self.getVisibleChildren() : self.children
+ if a:indx > len(array_to_search)
+ throw "NERDTree.InvalidArgumentsError: Index is out of bounds."
+ endif
+ return array_to_search[a:indx]
+endfunction
+
+"FUNCTION: TreeDirNode.getChildIndex(path) {{{1
+"Returns the index of the child node of this node that has the given path or
+"-1 if no such node exists.
+"
+"This function doesnt not recurse into child dir nodes
+"
+"Args:
+"path: a path object
+function! s:TreeDirNode.getChildIndex(path)
+ if stridx(a:path.str(), self.path.str(), 0) ==# -1
+ return -1
+ endif
+
+ "do a binary search for the child
+ let a = 0
+ let z = self.getChildCount()
+ while a < z
+ let mid = (a+z)/2
+ let diff = a:path.compareTo(self.children[mid].path)
+
+ if diff ==# -1
+ let z = mid
+ elseif diff ==# 1
+ let a = mid+1
+ else
+ return mid
+ endif
+ endwhile
+ return -1
+endfunction
+
+"FUNCTION: TreeDirNode.GetSelected() {{{1
+"Returns the current node if it is a dir node, or else returns the current
+"nodes parent
+unlet s:TreeDirNode.GetSelected
+function! s:TreeDirNode.GetSelected()
+ let currentDir = g:NERDTreeFileNode.GetSelected()
+ if currentDir != {} && !currentDir.isRoot()
+ if currentDir.path.isDirectory ==# 0
+ let currentDir = currentDir.parent
+ endif
+ endif
+ return currentDir
+endfunction
+
+"FUNCTION: TreeDirNode.getVisibleChildCount() {{{1
+"Returns the number of visible children this node has
+function! s:TreeDirNode.getVisibleChildCount()
+ return len(self.getVisibleChildren())
+endfunction
+
+"FUNCTION: TreeDirNode.getVisibleChildren() {{{1
+"Returns a list of children to display for this node, in the correct order
+"
+"Return:
+"an array of treenodes
+function! s:TreeDirNode.getVisibleChildren()
+ let toReturn = []
+ for i in self.children
+ if i.path.ignore() ==# 0
+ call add(toReturn, i)
+ endif
+ endfor
+ return toReturn
+endfunction
+
+"FUNCTION: TreeDirNode.hasVisibleChildren() {{{1
+"returns 1 if this node has any childre, 0 otherwise..
+function! s:TreeDirNode.hasVisibleChildren()
+ return self.getVisibleChildCount() != 0
+endfunction
+
+"FUNCTION: TreeDirNode._initChildren() {{{1
+"Removes all childen from this node and re-reads them
+"
+"Args:
+"silent: 1 if the function should not echo any "please wait" messages for
+"large directories
+"
+"Return: the number of child nodes read
+function! s:TreeDirNode._initChildren(silent)
+ "remove all the current child nodes
+ let self.children = []
+
+ "get an array of all the files in the nodes dir
+ let dir = self.path
+ let globDir = dir.str({'format': 'Glob'})
+
+ if version >= 703
+ let filesStr = globpath(globDir, '*', !g:NERDTreeRespectWildIgnore) . "\n" . globpath(globDir, '.*', !g:NERDTreeRespectWildIgnore)
+ else
+ let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*')
+ endif
+
+ let files = split(filesStr, "\n")
+
+ if !a:silent && len(files) > g:NERDTreeNotificationThreshold
+ call nerdtree#echo("Please wait, caching a large dir ...")
+ endif
+
+ let invalidFilesFound = 0
+ for i in files
+
+ "filter out the .. and . directories
+ "Note: we must match .. AND ../ cos sometimes the globpath returns
+ "../ for path with strange chars (eg $)
+ if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$'
+
+ "put the next file in a new node and attach it
+ try
+ let path = g:NERDTreePath.New(i)
+ call self.createChild(path, 0)
+ call g:NERDTreePathNotifier.NotifyListeners('init', path, {})
+ catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/
+ let invalidFilesFound += 1
+ endtry
+ endif
+ endfor
+
+ call self.sortChildren()
+
+ if !a:silent && len(files) > g:NERDTreeNotificationThreshold
+ call nerdtree#echo("Please wait, caching a large dir ... DONE (". self.getChildCount() ." nodes cached).")
+ endif
+
+ if invalidFilesFound
+ call nerdtree#echoWarning(invalidFilesFound . " file(s) could not be loaded into the NERD tree")
+ endif
+ return self.getChildCount()
+endfunction
+
+"FUNCTION: TreeDirNode.New(path) {{{1
+"Returns a new TreeNode object with the given path and parent
+"
+"Args:
+"path: a path object representing the full filesystem path to the file/dir that the node represents
+unlet s:TreeDirNode.New
+function! s:TreeDirNode.New(path)
+ if a:path.isDirectory != 1
+ throw "NERDTree.InvalidArgumentsError: A TreeDirNode object must be instantiated with a directory Path object."
+ endif
+
+ let newTreeNode = copy(self)
+ let newTreeNode.path = a:path
+
+ let newTreeNode.isOpen = 0
+ let newTreeNode.children = []
+
+ let newTreeNode.parent = {}
+
+ return newTreeNode
+endfunction
+
+"FUNCTION: TreeDirNode.open([opts]) {{{1
+"Open the dir in the current tree or in a new tree elsewhere.
+"
+"If opening in the current tree, return the number of cached nodes.
+unlet s:TreeDirNode.open
+function! s:TreeDirNode.open(...)
+ let opts = a:0 ? a:1 : {}
+
+ if has_key(opts, 'where') && !empty(opts['where'])
+ let opener = g:NERDTreeOpener.New(self.path, opts)
+ call opener.open(self)
+ else
+ let self.isOpen = 1
+ if self.children ==# []
+ return self._initChildren(0)
+ else
+ return 0
+ endif
+ endif
+endfunction
+
+"FUNCTION: TreeDirNode.openAlong([opts]) {{{1
+"recursive open the dir if it has only one directory child.
+"
+"return the level of opened directories.
+function! s:TreeDirNode.openAlong(...)
+ let opts = a:0 ? a:1 : {}
+ let level = 0
+
+ let node = self
+ while node.path.isDirectory
+ call node.open(opts)
+ let level += 1
+ if node.getVisibleChildCount() == 1
+ let node = node.getChildByIndex(0, 1)
+ else
+ break
+ endif
+ endwhile
+ return level
+endfunction
+
+" FUNCTION: TreeDirNode.openExplorer() {{{1
+" opens an explorer window for this node in the previous window (could be a
+" nerd tree or a netrw)
+function! s:TreeDirNode.openExplorer()
+ call self.open({'where': 'p'})
+endfunction
+
+"FUNCTION: TreeDirNode.openInNewTab(options) {{{1
+unlet s:TreeDirNode.openInNewTab
+function! s:TreeDirNode.openInNewTab(options)
+ call nerdtree#deprecated('TreeDirNode.openInNewTab', 'is deprecated, use open() instead')
+ call self.open({'where': 't'})
+endfunction
+
+"FUNCTION: TreeDirNode._openInNewTab() {{{1
+function! s:TreeDirNode._openInNewTab()
+ tabnew
+ call g:NERDTreeCreator.CreatePrimary(self.path.str())
+endfunction
+
+"FUNCTION: TreeDirNode.openRecursively() {{{1
+"Opens this treenode and all of its children whose paths arent 'ignored'
+"because of the file filters.
+"
+"This method is actually a wrapper for the OpenRecursively2 method which does
+"the work.
+function! s:TreeDirNode.openRecursively()
+ call self._openRecursively2(1)
+endfunction
+
+"FUNCTION: TreeDirNode._openRecursively2() {{{1
+"Opens this all children of this treenode recursively if either:
+" *they arent filtered by file filters
+" *a:forceOpen is 1
+"
+"Args:
+"forceOpen: 1 if this node should be opened regardless of file filters
+function! s:TreeDirNode._openRecursively2(forceOpen)
+ if self.path.ignore() ==# 0 || a:forceOpen
+ let self.isOpen = 1
+ if self.children ==# []
+ call self._initChildren(1)
+ endif
+
+ for i in self.children
+ if i.path.isDirectory ==# 1
+ call i._openRecursively2(0)
+ endif
+ endfor
+ endif
+endfunction
+
+"FUNCTION: TreeDirNode.refresh() {{{1
+unlet s:TreeDirNode.refresh
+function! s:TreeDirNode.refresh()
+ call self.path.refresh()
+
+ "if this node was ever opened, refresh its children
+ if self.isOpen || !empty(self.children)
+ "go thru all the files/dirs under this node
+ let newChildNodes = []
+ let invalidFilesFound = 0
+ let dir = self.path
+ let globDir = dir.str({'format': 'Glob'})
+ let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*')
+ let files = split(filesStr, "\n")
+ for i in files
+ "filter out the .. and . directories
+ "Note: we must match .. AND ../ cos sometimes the globpath returns
+ "../ for path with strange chars (eg $)
+ if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$'
+
+ try
+ "create a new path and see if it exists in this nodes children
+ let path = g:NERDTreePath.New(i)
+ let newNode = self.getChild(path)
+ if newNode != {}
+ call newNode.refresh()
+ call add(newChildNodes, newNode)
+
+ "the node doesnt exist so create it
+ else
+ let newNode = g:NERDTreeFileNode.New(path)
+ let newNode.parent = self
+ call add(newChildNodes, newNode)
+ endif
+
+
+ catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/
+ let invalidFilesFound = 1
+ endtry
+ endif
+ endfor
+
+ "swap this nodes children out for the children we just read/refreshed
+ let self.children = newChildNodes
+ call self.sortChildren()
+
+ if invalidFilesFound
+ call nerdtree#echoWarning("some files could not be loaded into the NERD tree")
+ endif
+ endif
+endfunction
+
+"FUNCTION: TreeDirNode.refreshFlags() {{{1
+unlet s:TreeDirNode.refreshFlags
+function! s:TreeDirNode.refreshFlags()
+ call self.path.refreshFlags()
+ for i in self.children
+ call i.refreshFlags()
+ endfor
+endfunction
+
+"FUNCTION: TreeDirNode.refreshDirFlags() {{{1
+function! s:TreeDirNode.refreshDirFlags()
+ call self.path.refreshFlags()
+endfunction
+
+"FUNCTION: TreeDirNode.reveal(path) {{{1
+"reveal the given path, i.e. cache and open all treenodes needed to display it
+"in the UI
+function! s:TreeDirNode.reveal(path)
+ if !a:path.isUnder(self.path)
+ throw "NERDTree.InvalidArgumentsError: " . a:path.str() . " should be under " . self.path.str()
+ endif
+
+ call self.open()
+
+ if self.path.equals(a:path.getParent())
+ let n = self.findNode(a:path)
+ call b:NERDTree.render()
+ call n.putCursorHere(1,0)
+ return
+ endif
+
+ let p = a:path
+ while !p.getParent().equals(self.path)
+ let p = p.getParent()
+ endwhile
+
+ let n = self.findNode(p)
+ call n.reveal(a:path)
+endfunction
+
+"FUNCTION: TreeDirNode.removeChild(treenode) {{{1
+"
+"Removes the given treenode from this nodes set of children
+"
+"Args:
+"treenode: the node to remove
+"
+"Throws a NERDTree.ChildNotFoundError if the given treenode is not found
+function! s:TreeDirNode.removeChild(treenode)
+ for i in range(0, self.getChildCount()-1)
+ if self.children[i].equals(a:treenode)
+ call remove(self.children, i)
+ return
+ endif
+ endfor
+
+ throw "NERDTree.ChildNotFoundError: child node was not found"
+endfunction
+
+"FUNCTION: TreeDirNode.sortChildren() {{{1
+"
+"Sorts the children of this node according to alphabetical order and the
+"directory priority.
+"
+function! s:TreeDirNode.sortChildren()
+ let CompareFunc = function("nerdtree#compareNodes")
+ call sort(self.children, CompareFunc)
+endfunction
+
+"FUNCTION: TreeDirNode.toggleOpen([options]) {{{1
+"Opens this directory if it is closed and vice versa
+function! s:TreeDirNode.toggleOpen(...)
+ let opts = a:0 ? a:1 : {}
+ if self.isOpen ==# 1
+ call self.close()
+ else
+ if g:NERDTreeCascadeOpenSingleChildDir == 0
+ call self.open(opts)
+ else
+ call self.openAlong(opts)
+ endif
+ endif
+endfunction
+
+"FUNCTION: TreeDirNode.transplantChild(newNode) {{{1
+"Replaces the child of this with the given node (where the child node's full
+"path matches a:newNode's fullpath). The search for the matching node is
+"non-recursive
+"
+"Arg:
+"newNode: the node to graft into the tree
+function! s:TreeDirNode.transplantChild(newNode)
+ for i in range(0, self.getChildCount()-1)
+ if self.children[i].equals(a:newNode)
+ let self.children[i] = a:newNode
+ let a:newNode.parent = self
+ break
+ endif
+ endfor
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/nerdtree/lib/nerdtree/tree_file_node.vim b/config/home/vim/bundle/nerdtree/lib/nerdtree/tree_file_node.vim
new file mode 100644
index 0000000..b4924d7
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/lib/nerdtree/tree_file_node.vim
@@ -0,0 +1,431 @@
+"CLASS: TreeFileNode
+"This class is the parent of the TreeDirNode class and is the
+"'Component' part of the composite design pattern between the treenode
+"classes.
+"============================================================
+let s:TreeFileNode = {}
+let g:NERDTreeFileNode = s:TreeFileNode
+
+"FUNCTION: TreeFileNode.activate(...) {{{1
+function! s:TreeFileNode.activate(...)
+ call self.open(a:0 ? a:1 : {})
+endfunction
+
+"FUNCTION: TreeFileNode.bookmark(name) {{{1
+"bookmark this node with a:name
+function! s:TreeFileNode.bookmark(name)
+
+ "if a bookmark exists with the same name and the node is cached then save
+ "it so we can update its display string
+ let oldMarkedNode = {}
+ try
+ let oldMarkedNode = g:NERDTreeBookmark.GetNodeForName(a:name, 1)
+ catch /^NERDTree.BookmarkNotFoundError/
+ catch /^NERDTree.BookmarkedNodeNotFoundError/
+ endtry
+
+ call g:NERDTreeBookmark.AddBookmark(a:name, self.path)
+ call self.path.cacheDisplayString()
+ call g:NERDTreeBookmark.Write()
+
+ if !empty(oldMarkedNode)
+ call oldMarkedNode.path.cacheDisplayString()
+ endif
+endfunction
+
+"FUNCTION: TreeFileNode.cacheParent() {{{1
+"initializes self.parent if it isnt already
+function! s:TreeFileNode.cacheParent()
+ if empty(self.parent)
+ let parentPath = self.path.getParent()
+ if parentPath.equals(self.path)
+ throw "NERDTree.CannotCacheParentError: already at root"
+ endif
+ let self.parent = s:TreeFileNode.New(parentPath)
+ endif
+endfunction
+
+"FUNCTION: TreeFileNode.clearBookmarks() {{{1
+function! s:TreeFileNode.clearBookmarks()
+ for i in g:NERDTreeBookmark.Bookmarks()
+ if i.path.equals(self.path)
+ call i.delete()
+ end
+ endfor
+ call self.path.cacheDisplayString()
+endfunction
+
+"FUNCTION: TreeFileNode.copy(dest) {{{1
+function! s:TreeFileNode.copy(dest)
+ call self.path.copy(a:dest)
+ let newPath = g:NERDTreePath.New(a:dest)
+ let parent = b:NERDTreeRoot.findNode(newPath.getParent())
+ if !empty(parent)
+ call parent.refresh()
+ return parent.findNode(newPath)
+ else
+ return {}
+ endif
+endfunction
+
+"FUNCTION: TreeFileNode.delete {{{1
+"Removes this node from the tree and calls the Delete method for its path obj
+function! s:TreeFileNode.delete()
+ call self.path.delete()
+ call self.parent.removeChild(self)
+endfunction
+
+"FUNCTION: TreeFileNode.displayString() {{{1
+"
+"Returns a string that specifies how the node should be represented as a
+"string
+"
+"Return:
+"a string that can be used in the view to represent this node
+function! s:TreeFileNode.displayString()
+ return self.path.displayString()
+endfunction
+
+"FUNCTION: TreeFileNode.equals(treenode) {{{1
+"
+"Compares this treenode to the input treenode and returns 1 if they are the
+"same node.
+"
+"Use this method instead of == because sometimes when the treenodes contain
+"many children, vim seg faults when doing ==
+"
+"Args:
+"treenode: the other treenode to compare to
+function! s:TreeFileNode.equals(treenode)
+ return self.path.str() ==# a:treenode.path.str()
+endfunction
+
+"FUNCTION: TreeFileNode.findNode(path) {{{1
+"Returns self if this node.path.Equals the given path.
+"Returns {} if not equal.
+"
+"Args:
+"path: the path object to compare against
+function! s:TreeFileNode.findNode(path)
+ if a:path.equals(self.path)
+ return self
+ endif
+ return {}
+endfunction
+
+"FUNCTION: TreeFileNode.findOpenDirSiblingWithVisibleChildren(direction) {{{1
+"
+"Finds the next sibling for this node in the indicated direction. This sibling
+"must be a directory and may/may not have children as specified.
+"
+"Args:
+"direction: 0 if you want to find the previous sibling, 1 for the next sibling
+"
+"Return:
+"a treenode object or {} if no appropriate sibling could be found
+function! s:TreeFileNode.findOpenDirSiblingWithVisibleChildren(direction)
+ "if we have no parent then we can have no siblings
+ if self.parent != {}
+ let nextSibling = self.findSibling(a:direction)
+
+ while nextSibling != {}
+ if nextSibling.path.isDirectory && nextSibling.hasVisibleChildren() && nextSibling.isOpen
+ return nextSibling
+ endif
+ let nextSibling = nextSibling.findSibling(a:direction)
+ endwhile
+ endif
+
+ return {}
+endfunction
+
+"FUNCTION: TreeFileNode.findSibling(direction) {{{1
+"
+"Finds the next sibling for this node in the indicated direction
+"
+"Args:
+"direction: 0 if you want to find the previous sibling, 1 for the next sibling
+"
+"Return:
+"a treenode object or {} if no sibling could be found
+function! s:TreeFileNode.findSibling(direction)
+ "if we have no parent then we can have no siblings
+ if self.parent != {}
+
+ "get the index of this node in its parents children
+ let siblingIndx = self.parent.getChildIndex(self.path)
+
+ if siblingIndx != -1
+ "move a long to the next potential sibling node
+ let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1
+
+ "keep moving along to the next sibling till we find one that is valid
+ let numSiblings = self.parent.getChildCount()
+ while siblingIndx >= 0 && siblingIndx < numSiblings
+
+ "if the next node is not an ignored node (i.e. wont show up in the
+ "view) then return it
+ if self.parent.children[siblingIndx].path.ignore() ==# 0
+ return self.parent.children[siblingIndx]
+ endif
+
+ "go to next node
+ let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1
+ endwhile
+ endif
+ endif
+
+ return {}
+endfunction
+
+"FUNCTION: TreeFileNode.GetRootForTab(){{{1
+"get the root node for this tab
+function! s:TreeFileNode.GetRootForTab()
+ if g:NERDTree.ExistsForTab()
+ return getbufvar(t:NERDTreeBufName, 'NERDTreeRoot')
+ end
+ return {}
+endfunction
+
+"FUNCTION: TreeFileNode.GetSelected() {{{1
+"gets the treenode that the cursor is currently over
+function! s:TreeFileNode.GetSelected()
+ try
+ let path = b:NERDTree.ui.getPath(line("."))
+ if path ==# {}
+ return {}
+ endif
+ return b:NERDTreeRoot.findNode(path)
+ catch /^NERDTree/
+ return {}
+ endtry
+endfunction
+
+"FUNCTION: TreeFileNode.isVisible() {{{1
+"returns 1 if this node should be visible according to the tree filters and
+"hidden file filters (and their on/off status)
+function! s:TreeFileNode.isVisible()
+ return !self.path.ignore()
+endfunction
+
+"FUNCTION: TreeFileNode.isRoot() {{{1
+"returns 1 if this node is b:NERDTreeRoot
+function! s:TreeFileNode.isRoot()
+ if !g:NERDTree.ExistsForBuf()
+ throw "NERDTree.NoTreeError: No tree exists for the current buffer"
+ endif
+
+ return self.equals(b:NERDTreeRoot)
+endfunction
+
+"FUNCTION: TreeFileNode.makeRoot() {{{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
+"
+"Args:
+"path: a path object representing the full filesystem path to the file/dir that the node represents
+function! s:TreeFileNode.New(path)
+ if a:path.isDirectory
+ return g:NERDTreeDirNode.New(a:path)
+ else
+ let newTreeNode = copy(self)
+ let newTreeNode.path = a:path
+ let newTreeNode.parent = {}
+ return newTreeNode
+ endif
+endfunction
+
+"FUNCTION: TreeFileNode.open() {{{1
+function! s:TreeFileNode.open(...)
+ let opts = a:0 ? a:1 : {}
+ let opener = g:NERDTreeOpener.New(self.path, opts)
+ call opener.open(self)
+endfunction
+
+"FUNCTION: TreeFileNode.openSplit() {{{1
+"Open this node in a new window
+function! s:TreeFileNode.openSplit()
+ call nerdtree#deprecated('TreeFileNode.openSplit', 'is deprecated, use .open() instead.')
+ call self.open({'where': 'h'})
+endfunction
+
+"FUNCTION: TreeFileNode.openVSplit() {{{1
+"Open this node in a new vertical window
+function! s:TreeFileNode.openVSplit()
+ call nerdtree#deprecated('TreeFileNode.openVSplit', 'is deprecated, use .open() instead.')
+ call self.open({'where': 'v'})
+endfunction
+
+"FUNCTION: TreeFileNode.openInNewTab(options) {{{1
+function! s:TreeFileNode.openInNewTab(options)
+ echomsg 'TreeFileNode.openInNewTab is deprecated'
+ call self.open(extend({'where': 't'}, a:options))
+endfunction
+
+"FUNCTION: TreeFileNode.putCursorHere(isJump, recurseUpward){{{1
+"Places the cursor on the line number this node is rendered on
+"
+"Args:
+"isJump: 1 if this cursor movement should be counted as a jump by vim
+"recurseUpward: try to put the cursor on the parent if the this node isnt
+"visible
+function! s:TreeFileNode.putCursorHere(isJump, recurseUpward)
+ let ln = b:NERDTree.ui.getLineNum(self)
+ if ln != -1
+ if a:isJump
+ mark '
+ endif
+ call cursor(ln, col("."))
+ else
+ if a:recurseUpward
+ let node = self
+ while node != {} && b:NERDTree.ui.getLineNum(node) ==# -1
+ let node = node.parent
+ call node.open()
+ endwhile
+ call b:NERDTree.render()
+ call node.putCursorHere(a:isJump, 0)
+ endif
+ endif
+endfunction
+
+"FUNCTION: TreeFileNode.refresh() {{{1
+function! s:TreeFileNode.refresh()
+ call self.path.refresh()
+endfunction
+
+"FUNCTION: TreeFileNode.refreshFlags() {{{1
+function! s:TreeFileNode.refreshFlags()
+ call self.path.refreshFlags()
+endfunction
+
+"FUNCTION: TreeFileNode.rename() {{{1
+"Calls the rename method for this nodes path obj
+function! s:TreeFileNode.rename(newName)
+ let newName = substitute(a:newName, '\(\\\|\/\)$', '', '')
+ call self.path.rename(newName)
+ call self.parent.removeChild(self)
+
+ let parentPath = self.path.getParent()
+ let newParent = b:NERDTreeRoot.findNode(parentPath)
+
+ if newParent != {}
+ call newParent.createChild(self.path, 1)
+ call newParent.refresh()
+ endif
+endfunction
+
+"FUNCTION: TreeFileNode.renderToString {{{1
+"returns a string representation for this tree to be rendered in the view
+function! s:TreeFileNode.renderToString()
+ return self._renderToString(0, 0, [], self.getChildCount() ==# 1)
+endfunction
+
+"Args:
+"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
+"child nodes are rendered only)
+"vertMap: a binary array that indicates whether a vertical bar should be draw
+"for each depth in the tree
+"isLastChild:true if this curNode is the last child of its parent
+function! s:TreeFileNode._renderToString(depth, drawText, vertMap, isLastChild)
+ let output = ""
+ if a:drawText ==# 1
+
+ let treeParts = ''
+
+ "get all the leading spaces and vertical tree parts for this line
+ if a:depth > 1
+ 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
+
+ "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 output = output . line . "\n"
+ endif
+
+ "if the node is an open dir, draw its children
+ if self.path.isDirectory ==# 1 && self.isOpen ==# 1
+
+ let childNodesToDraw = self.getVisibleChildren()
+ if len(childNodesToDraw) > 0
+
+ "draw all the nodes children except the last
+ 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[lastIndx]._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 0), 1)
+ endif
+ endif
+
+ return output
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/nerdtree/lib/nerdtree/ui.vim b/config/home/vim/bundle/nerdtree/lib/nerdtree/ui.vim
new file mode 100644
index 0000000..22e450c
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/lib/nerdtree/ui.vim
@@ -0,0 +1,506 @@
+"CLASS: UI
+"============================================================
+let s:UI = {}
+let g:NERDTreeUI = s:UI
+
+"FUNCTION: s:UI.centerView() {{{2
+"centers the nerd tree window around the cursor (provided the nerd tree
+"options permit)
+function! s:UI.centerView()
+ if g:NERDTreeAutoCenter
+ let current_line = winline()
+ let lines_to_top = current_line
+ let lines_to_bottom = winheight(g:NERDTree.GetWinNum()) - current_line
+ if lines_to_top < g:NERDTreeAutoCenterThreshold || lines_to_bottom < g:NERDTreeAutoCenterThreshold
+ normal! zz
+ endif
+ endif
+endfunction
+
+"FUNCTION: s:UI._dumpHelp {{{1
+"prints out the quick help
+function! s:UI._dumpHelp()
+ let old_h = @h
+ if b:treeShowHelp ==# 1
+ let @h= "\" NERD tree (" . nerdtree#version() . ") quickhelp~\n"
+ let @h=@h."\" ============================\n"
+ let @h=@h."\" File node mappings~\n"
+ let @h=@h."\" ". (g:NERDTreeMouseMode ==# 3 ? "single" : "double") ."-click,\n"
+ let @h=@h."\" ,\n"
+ if b:NERDTreeType ==# "primary"
+ let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in prev window\n"
+ else
+ let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in current window\n"
+ endif
+ if b:NERDTreeType ==# "primary"
+ let @h=@h."\" ". g:NERDTreeMapPreview .": preview\n"
+ endif
+ let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n"
+ let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n"
+ let @h=@h."\" middle-click,\n"
+ let @h=@h."\" ". g:NERDTreeMapOpenSplit .": open split\n"
+ let @h=@h."\" ". g:NERDTreeMapPreviewSplit .": preview split\n"
+ let @h=@h."\" ". g:NERDTreeMapOpenVSplit .": open vsplit\n"
+ let @h=@h."\" ". g:NERDTreeMapPreviewVSplit .": preview vsplit\n"
+
+ let @h=@h."\"\n\" ----------------------------\n"
+ let @h=@h."\" Directory node mappings~\n"
+ let @h=@h."\" ". (g:NERDTreeMouseMode ==# 1 ? "double" : "single") ."-click,\n"
+ let @h=@h."\" ". g:NERDTreeMapActivateNode .": open & close node\n"
+ let @h=@h."\" ". g:NERDTreeMapOpenRecursively .": recursively open node\n"
+ let @h=@h."\" ". g:NERDTreeMapCloseDir .": close parent of node\n"
+ let @h=@h."\" ". g:NERDTreeMapCloseChildren .": close all child nodes of\n"
+ let @h=@h."\" current node recursively\n"
+ let @h=@h."\" middle-click,\n"
+ let @h=@h."\" ". g:NERDTreeMapOpenExpl.": explore selected dir\n"
+
+ let @h=@h."\"\n\" ----------------------------\n"
+ let @h=@h."\" Bookmark table mappings~\n"
+ let @h=@h."\" double-click,\n"
+ let @h=@h."\" ". g:NERDTreeMapActivateNode .": open bookmark\n"
+ let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n"
+ let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n"
+ let @h=@h."\" ". g:NERDTreeMapDeleteBookmark .": delete bookmark\n"
+
+ let @h=@h."\"\n\" ----------------------------\n"
+ let @h=@h."\" Tree navigation mappings~\n"
+ let @h=@h."\" ". g:NERDTreeMapJumpRoot .": go to root\n"
+ let @h=@h."\" ". g:NERDTreeMapJumpParent .": go to parent\n"
+ let @h=@h."\" ". g:NERDTreeMapJumpFirstChild .": go to first child\n"
+ let @h=@h."\" ". g:NERDTreeMapJumpLastChild .": go to last child\n"
+ let @h=@h."\" ". g:NERDTreeMapJumpNextSibling .": go to next sibling\n"
+ let @h=@h."\" ". g:NERDTreeMapJumpPrevSibling .": go to prev sibling\n"
+
+ let @h=@h."\"\n\" ----------------------------\n"
+ let @h=@h."\" Filesystem mappings~\n"
+ let @h=@h."\" ". g:NERDTreeMapChangeRoot .": change tree root to the\n"
+ let @h=@h."\" selected dir\n"
+ let @h=@h."\" ". g:NERDTreeMapUpdir .": move tree root up a dir\n"
+ let @h=@h."\" ". g:NERDTreeMapUpdirKeepOpen .": move tree root up a dir\n"
+ let @h=@h."\" but leave old root open\n"
+ let @h=@h."\" ". g:NERDTreeMapRefresh .": refresh cursor dir\n"
+ let @h=@h."\" ". g:NERDTreeMapRefreshRoot .": refresh current root\n"
+ let @h=@h."\" ". g:NERDTreeMapMenu .": Show menu\n"
+ let @h=@h."\" ". g:NERDTreeMapChdir .":change the CWD to the\n"
+ let @h=@h."\" selected dir\n"
+ let @h=@h."\" ". g:NERDTreeMapCWD .":change tree root to CWD\n"
+
+ let @h=@h."\"\n\" ----------------------------\n"
+ let @h=@h."\" Tree filtering mappings~\n"
+ let @h=@h."\" ". g:NERDTreeMapToggleHidden .": hidden files (" . (b:NERDTreeShowHidden ? "on" : "off") . ")\n"
+ let @h=@h."\" ". g:NERDTreeMapToggleFilters .": file filters (" . (b:NERDTreeIgnoreEnabled ? "on" : "off") . ")\n"
+ let @h=@h."\" ". g:NERDTreeMapToggleFiles .": files (" . (b:NERDTreeShowFiles ? "on" : "off") . ")\n"
+ let @h=@h."\" ". g:NERDTreeMapToggleBookmarks .": bookmarks (" . (b:NERDTreeShowBookmarks ? "on" : "off") . ")\n"
+
+ "add quickhelp entries for each custom key map
+ let @h=@h."\"\n\" ----------------------------\n"
+ let @h=@h."\" Custom mappings~\n"
+ for i in g:NERDTreeKeyMap.All()
+ if !empty(i.quickhelpText)
+ let @h=@h."\" ". i.key .": ". i.quickhelpText ."\n"
+ endif
+ endfor
+
+ let @h=@h."\"\n\" ----------------------------\n"
+ let @h=@h."\" Other mappings~\n"
+ let @h=@h."\" ". g:NERDTreeMapQuit .": Close the NERDTree window\n"
+ let @h=@h."\" ". g:NERDTreeMapToggleZoom .": Zoom (maximize-minimize)\n"
+ let @h=@h."\" the NERDTree window\n"
+ let @h=@h."\" ". g:NERDTreeMapHelp .": toggle help\n"
+ let @h=@h."\"\n\" ----------------------------\n"
+ let @h=@h."\" Bookmark commands~\n"
+ let @h=@h."\" :Bookmark []\n"
+ let @h=@h."\" :BookmarkToRoot \n"
+ let @h=@h."\" :RevealBookmark \n"
+ let @h=@h."\" :OpenBookmark \n"
+ let @h=@h."\" :ClearBookmarks []\n"
+ let @h=@h."\" :ClearAllBookmarks\n"
+ silent! put h
+ elseif g:NERDTreeMinimalUI == 0
+ let @h="\" Press ". g:NERDTreeMapHelp ." for help\n"
+ silent! put h
+ endif
+
+ let @h = old_h
+endfunction
+
+
+"FUNCTION: s:UI.new(nerdtree) {{{1
+function! s:UI.New(nerdtree)
+ let newObj = copy(self)
+ let newObj.nerdtree = a:nerdtree
+ return newObj
+endfunction
+
+"FUNCTION: s:UI.getPath(ln) {{{1
+"Gets the full path to the node that is rendered on the given line number
+"
+"Args:
+"ln: the line number to get the path for
+"
+"Return:
+"A path if a node was selected, {} if nothing is selected.
+"If the 'up a dir' line was selected then the path to the parent of the
+"current root is returned
+function! s:UI.getPath(ln)
+ let line = getline(a:ln)
+
+ let rootLine = self.getRootLineNum()
+
+ "check to see if we have the root node
+ if a:ln == rootLine
+ return b:NERDTreeRoot.path
+ endif
+
+ if !g:NERDTreeDirArrows
+ " in case called from outside the tree
+ if line !~# '^ *[|`▸▾ ]' || line =~# '^$'
+ return {}
+ endif
+ endif
+
+ if line ==# s:UI.UpDirLine()
+ return b:NERDTreeRoot.path.getParent()
+ endif
+
+ let indent = self._indentLevelFor(line)
+
+ "remove the tree parts and the leading space
+ let curFile = self._stripMarkup(line, 0)
+
+ let wasdir = 0
+ if curFile =~# '/$'
+ let wasdir = 1
+ let curFile = substitute(curFile, '/\?$', '/', "")
+ endif
+
+ let dir = ""
+ let lnum = a:ln
+ while lnum > 0
+ let lnum = lnum - 1
+ let curLine = getline(lnum)
+ let curLineStripped = self._stripMarkup(curLine, 1)
+
+ "have we reached the top of the tree?
+ if lnum == rootLine
+ let dir = b:NERDTreeRoot.path.str({'format': 'UI'}) . dir
+ break
+ endif
+ if curLineStripped =~# '/$'
+ let lpindent = self._indentLevelFor(curLine)
+ if lpindent < indent
+ let indent = indent - 1
+
+ let dir = substitute (curLineStripped,'^\\', "", "") . dir
+ continue
+ endif
+ endif
+ endwhile
+ let curFile = b:NERDTreeRoot.path.drive . dir . curFile
+ let toReturn = g:NERDTreePath.New(curFile)
+ return toReturn
+endfunction
+
+"FUNCTION: s:UI.getLineNum(file_node){{{1
+"returns the line number this node is rendered on, or -1 if it isnt rendered
+function! s:UI.getLineNum(file_node)
+ "if the node is the root then return the root line no.
+ if a:file_node.isRoot()
+ return b:NERDTree.ui.getRootLineNum()
+ endif
+
+ let totalLines = line("$")
+
+ "the path components we have matched so far
+ let pathcomponents = [substitute(b:NERDTreeRoot.path.str({'format': 'UI'}), '/ *$', '', '')]
+ "the index of the component we are searching for
+ let curPathComponent = 1
+
+ let fullpath = a:file_node.path.str({'format': 'UI'})
+
+ let lnum = b:NERDTree.ui.getRootLineNum()
+ while lnum > 0
+ let lnum = lnum + 1
+ "have we reached the bottom of the tree?
+ if lnum ==# totalLines+1
+ return -1
+ endif
+
+ let curLine = getline(lnum)
+
+ let indent = self._indentLevelFor(curLine)
+ if indent ==# curPathComponent
+ let curLine = self._stripMarkup(curLine, 1)
+
+ let curPath = join(pathcomponents, '/') . '/' . curLine
+ if stridx(fullpath, curPath, 0) ==# 0
+ if fullpath ==# curPath || strpart(fullpath, len(curPath)-1,1) ==# '/'
+ let curLine = substitute(curLine, '/ *$', '', '')
+ call add(pathcomponents, curLine)
+ let curPathComponent = curPathComponent + 1
+
+ if fullpath ==# curPath
+ return lnum
+ endif
+ endif
+ endif
+ endif
+ endwhile
+ return -1
+endfunction
+
+"FUNCTION: s:UI.getRootLineNum(){{{1
+"gets the line number of the root node
+function! s:UI.getRootLineNum()
+ let rootLine = 1
+ while getline(rootLine) !~# '^\(/\|<\)'
+ let rootLine = rootLine + 1
+ endwhile
+ return rootLine
+endfunction
+
+"FUNCTION: s:UI._indentLevelFor(line) {{{1
+function! s:UI._indentLevelFor(line)
+ let level = match(a:line, '[^ \-+~▸▾`|]') / s:UI.IndentWid()
+ " check if line includes arrows
+ if match(a:line, '[▸▾]') > -1
+ " decrement level as arrow uses 3 ascii chars
+ let level = level - 1
+ endif
+ return level
+endfunction
+
+"FUNCTION: s:UI.IndentWid() {{{1
+function! s:UI.IndentWid()
+ return 2
+endfunction
+
+"FUNCTION: s:UI.MarkupReg() {{{1
+function! s:UI.MarkupReg()
+ if g:NERDTreeDirArrows
+ return '^\([▾▸] \| \+[▾▸] \| \+\)'
+ endif
+
+ return '^[ `|]*[\-+~]'
+endfunction
+
+"FUNCTION: s:UI._renderBookmarks {{{1
+function! s:UI._renderBookmarks()
+
+ if g:NERDTreeMinimalUI == 0
+ call setline(line(".")+1, ">----------Bookmarks----------")
+ call cursor(line(".")+1, col("."))
+ endif
+
+ for i in g:NERDTreeBookmark.Bookmarks()
+ call setline(line(".")+1, i.str())
+ call cursor(line(".")+1, col("."))
+ endfor
+
+ call setline(line(".")+1, '')
+ call cursor(line(".")+1, col("."))
+endfunction
+
+"FUNCTION: s:UI.restoreScreenState() {{{1
+"
+"Sets the screen state back to what it was when nerdtree#saveScreenState was last
+"called.
+"
+"Assumes the cursor is in the NERDTree window
+function! s:UI.restoreScreenState()
+ if !has_key(self, '_screenState')
+ return
+ endif
+ exec("silent vertical resize " . self._screenState['oldWindowSize'])
+
+ let old_scrolloff=&scrolloff
+ let &scrolloff=0
+ call cursor(self._screenState['oldTopLine'], 0)
+ normal! zt
+ call setpos(".", self._screenState['oldPos'])
+ let &scrolloff=old_scrolloff
+endfunction
+
+"FUNCTION: s:UI.saveScreenState() {{{1
+"Saves the current cursor position in the current buffer and the window
+"scroll position
+function! s:UI.saveScreenState()
+ let win = winnr()
+ call g:NERDTree.CursorToTreeWin()
+ let self._screenState = {}
+ let self._screenState['oldPos'] = getpos(".")
+ let self._screenState['oldTopLine'] = line("w0")
+ let self._screenState['oldWindowSize']= winwidth("")
+ call nerdtree#exec(win . "wincmd w")
+endfunction
+
+"FUNCTION: s:UI._stripMarkup(line, removeLeadingSpaces){{{1
+"returns the given line with all the tree parts stripped off
+"
+"Args:
+"line: the subject line
+"removeLeadingSpaces: 1 if leading spaces are to be removed (leading spaces =
+"any spaces before the actual text of the node)
+function! s:UI._stripMarkup(line, removeLeadingSpaces)
+ let line = a:line
+ "remove the tree parts and the leading space
+ let line = substitute (line, g:NERDTreeUI.MarkupReg(),"","")
+
+ "strip off any read only flag
+ let line = substitute (line, ' \[RO\]', "","")
+
+ "strip off any bookmark flags
+ let line = substitute (line, ' {[^}]*}', "","")
+
+ "strip off any executable flags
+ let line = substitute (line, '*\ze\($\| \)', "","")
+
+ "strip off any generic flags
+ let line = substitute (line, '\[[^]]*\]', "","")
+
+ let wasdir = 0
+ if line =~# '/$'
+ let wasdir = 1
+ endif
+ let line = substitute (line,' -> .*',"","") " remove link to
+ if wasdir ==# 1
+ let line = substitute (line, '/\?$', '/', "")
+ endif
+
+ if a:removeLeadingSpaces
+ let line = substitute (line, '^ *', '', '')
+ endif
+
+ return line
+endfunction
+
+"FUNCTION: s:UI.render() {{{1
+function! s:UI.render()
+ setlocal modifiable
+
+ "remember the top line of the buffer and the current line so we can
+ "restore the view exactly how it was
+ let curLine = line(".")
+ let curCol = col(".")
+ let topLine = line("w0")
+
+ "delete all lines in the buffer (being careful not to clobber a register)
+ silent 1,$delete _
+
+ call self._dumpHelp()
+
+ "delete the blank line before the help and add one after it
+ if g:NERDTreeMinimalUI == 0
+ call setline(line(".")+1, "")
+ call cursor(line(".")+1, col("."))
+ endif
+
+ if b:NERDTreeShowBookmarks
+ call self._renderBookmarks()
+ endif
+
+ "add the 'up a dir' line
+ if !g:NERDTreeMinimalUI
+ call setline(line(".")+1, s:UI.UpDirLine())
+ call cursor(line(".")+1, col("."))
+ endif
+
+ "draw the header line
+ let header = b:NERDTreeRoot.path.str({'format': 'UI', 'truncateTo': winwidth(0)})
+ call setline(line(".")+1, header)
+ call cursor(line(".")+1, col("."))
+
+ "draw the tree
+ let old_o = @o
+ let @o = b:NERDTreeRoot.renderToString()
+ silent put o
+ let @o = old_o
+
+ "delete the blank line at the top of the buffer
+ silent 1,1delete _
+
+ "restore the view
+ let old_scrolloff=&scrolloff
+ let &scrolloff=0
+ call cursor(topLine, 1)
+ normal! zt
+ call cursor(curLine, curCol)
+ let &scrolloff = old_scrolloff
+
+ setlocal nomodifiable
+endfunction
+
+
+"FUNCTION: UI.renderViewSavingPosition {{{1
+"Renders the tree and ensures the cursor stays on the current node or the
+"current nodes parent if it is no longer available upon re-rendering
+function! s:UI.renderViewSavingPosition()
+ let currentNode = g:NERDTreeFileNode.GetSelected()
+
+ "go up the tree till we find a node that will be visible or till we run
+ "out of nodes
+ while currentNode != {} && !currentNode.isVisible() && !currentNode.isRoot()
+ let currentNode = currentNode.parent
+ endwhile
+
+ call b:NERDTree.render()
+
+ if currentNode != {}
+ call currentNode.putCursorHere(0, 0)
+ endif
+endfunction
+
+" FUNCTION: s:UI.toggleIgnoreFilter() {{{1
+" toggles the use of the NERDTreeIgnore option
+function! s:UI.toggleIgnoreFilter()
+ let b:NERDTreeIgnoreEnabled = !b:NERDTreeIgnoreEnabled
+ call b:NERDTree.ui.renderViewSavingPosition()
+ call b:NERDTree.ui.centerView()
+endfunction
+
+" FUNCTION: s:UI.toggleShowBookmarks() {{{1
+" toggles the display of bookmarks
+function! s:UI.toggleShowBookmarks()
+ let b:NERDTreeShowBookmarks = !b:NERDTreeShowBookmarks
+ if b:NERDTreeShowBookmarks
+ call b:NERDTree.render()
+ call g:NERDTree.CursorToBookmarkTable()
+ else
+ call b:NERDTree.ui.renderViewSavingPosition()
+ endif
+ call b:NERDTree.ui.centerView()
+endfunction
+
+" FUNCTION: s:UI.toggleShowFiles() {{{1
+" toggles the display of hidden files
+function! s:UI.toggleShowFiles()
+ let b:NERDTreeShowFiles = !b:NERDTreeShowFiles
+ call b:NERDTree.ui.renderViewSavingPosition()
+ call b:NERDTree.ui.centerView()
+endfunction
+
+" FUNCTION: s:UI.toggleShowHidden() {{{1
+" toggles the display of hidden files
+function! s:UI.toggleShowHidden()
+ let b:NERDTreeShowHidden = !b:NERDTreeShowHidden
+ call b:NERDTree.ui.renderViewSavingPosition()
+ call self.centerView()
+endfunction
+
+" FUNCTION: s:UI.toggleZoom() {{{1
+" zoom (maximize/minimize) the NERDTree window
+function! s:UI.toggleZoom()
+ if exists("b:NERDTreeZoomed") && b:NERDTreeZoomed
+ let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize
+ exec "silent vertical resize ". size
+ let b:NERDTreeZoomed = 0
+ else
+ exec "vertical resize"
+ let b:NERDTreeZoomed = 1
+ endif
+endfunction
+
+"FUNCTION: s:UI.UpDirLine() {{{1
+function! s:UI.UpDirLine()
+ return '.. (up a dir)'
+endfunction
diff --git a/config/home/vim/bundle/nerdtree/nerdtree_plugin/exec_menuitem.vim b/config/home/vim/bundle/nerdtree/nerdtree_plugin/exec_menuitem.vim
new file mode 100644
index 0000000..e7a7c53
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/nerdtree_plugin/exec_menuitem.vim
@@ -0,0 +1,41 @@
+" ============================================================================
+" File: exec_menuitem.vim
+" Description: plugin for NERD Tree that provides an execute file menu item
+" Maintainer: Martin Grenfell
+" Last Change: 22 July, 2009
+" 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_nerdtree_exec_menuitem")
+ finish
+endif
+let g:loaded_nerdtree_exec_menuitem = 1
+
+call NERDTreeAddMenuItem({
+ \ 'text': '(!)Execute file',
+ \ 'shortcut': '!',
+ \ 'callback': 'NERDTreeExecFile',
+ \ 'isActiveCallback': 'NERDTreeExecFileActive' })
+
+function! NERDTreeExecFileActive()
+ let node = g:NERDTreeFileNode.GetSelected()
+ return !node.path.isDirectory && node.path.isExecutable
+endfunction
+
+function! NERDTreeExecFile()
+ let treenode = g:NERDTreeFileNode.GetSelected()
+ echo "==========================================================\n"
+ echo "Complete the command to execute (add arguments etc):\n"
+ let cmd = treenode.path.str({'escape': 1})
+ let cmd = input(':!', cmd . ' ')
+
+ if cmd != ''
+ exec ':!' . cmd
+ else
+ echo "Aborted"
+ endif
+endfunction
diff --git a/config/home/vim/bundle/nerdtree/nerdtree_plugin/fs_menu.vim b/config/home/vim/bundle/nerdtree/nerdtree_plugin/fs_menu.vim
new file mode 100644
index 0000000..e99a85b
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/nerdtree_plugin/fs_menu.vim
@@ -0,0 +1,270 @@
+" ============================================================================
+" File: fs_menu.vim
+" Description: plugin for the NERD Tree that provides a file system menu
+" Maintainer: Martin Grenfell
+" Last Change: 17 July, 2009
+" 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_nerdtree_fs_menu")
+ finish
+endif
+let g:loaded_nerdtree_fs_menu = 1
+
+"Automatically delete the buffer after deleting or renaming a file
+if !exists("g:NERDTreeAutoDeleteBuffer")
+ let g:NERDTreeAutoDeleteBuffer = 0
+endif
+
+call NERDTreeAddMenuItem({'text': '(a)dd a childnode', 'shortcut': 'a', 'callback': 'NERDTreeAddNode'})
+call NERDTreeAddMenuItem({'text': '(m)ove the current node', 'shortcut': 'm', 'callback': 'NERDTreeMoveNode'})
+call NERDTreeAddMenuItem({'text': '(d)elete the current node', 'shortcut': 'd', 'callback': 'NERDTreeDeleteNode'})
+
+if has("gui_mac") || has("gui_macvim")
+ 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': '(q)uicklook the current node', 'shortcut': 'q', 'callback': 'NERDTreeQuickLook'})
+endif
+
+if g:NERDTreePath.CopyingSupported()
+ call NERDTreeAddMenuItem({'text': '(c)opy the current node', 'shortcut': 'c', 'callback': 'NERDTreeCopyNode'})
+endif
+
+"FUNCTION: s:echo(msg){{{1
+function! s:echo(msg)
+ redraw
+ echomsg "NERDTree: " . a:msg
+endfunction
+
+"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
+"prints out the given msg and, if the user responds by pushing 'y' then the
+"buffer with the given bufnum is deleted
+"
+"Args:
+"bufnum: the buffer that may be deleted
+"msg: a message that will be echoed to the user asking them if they wish to
+" del the buffer
+function! s:promptToDelBuffer(bufnum, msg)
+ echo a:msg
+ if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y'
+ " 1. ensure that all windows which display the just deleted filename
+ " now display an empty buffer (so a layout is preserved).
+ " Is not it better to close single tabs with this file only ?
+ let s:originalTabNumber = tabpagenr()
+ let s:originalWindowNumber = winnr()
+ exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':enew! ' | endif"
+ exec "tabnext " . s:originalTabNumber
+ exec s:originalWindowNumber . "wincmd w"
+ " 3. We don't need a previous buffer anymore
+ exec "bwipeout! " . a:bufnum
+ endif
+endfunction
+
+"FUNCTION: s:promptToRenameBuffer(bufnum, msg){{{1
+"prints out the given msg and, if the user responds by pushing 'y' then the
+"buffer with the given bufnum is replaced with a new one
+"
+"Args:
+"bufnum: the buffer that may be deleted
+"msg: a message that will be echoed to the user asking them if they wish to
+" del the buffer
+function! s:promptToRenameBuffer(bufnum, msg, newFileName)
+ echo a:msg
+ if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y'
+ let quotedFileName = "'" . a:newFileName . "'"
+ " 1. ensure that a new buffer is loaded
+ exec "badd " . quotedFileName
+ " 2. ensure that all windows which display the just deleted filename
+ " display a buffer for a new filename.
+ let s:originalTabNumber = tabpagenr()
+ let s:originalWindowNumber = winnr()
+ let editStr = g:NERDTreePath.New(a:newFileName).str({'format': 'Edit'})
+ exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':e! " . editStr . "' | endif"
+ exec "tabnext " . s:originalTabNumber
+ exec s:originalWindowNumber . "wincmd w"
+ " 3. We don't need a previous buffer anymore
+ exec "bwipeout! " . a:bufnum
+ endif
+endfunction
+"FUNCTION: NERDTreeAddNode(){{{1
+function! NERDTreeAddNode()
+ let curDirNode = g:NERDTreeDirNode.GetSelected()
+
+ let newNodeName = input("Add a childnode\n".
+ \ "==========================================================\n".
+ \ "Enter the dir/file name to be created. Dirs end with a '/'\n" .
+ \ "", curDirNode.path.str() . g:NERDTreePath.Slash(), "file")
+
+ if newNodeName ==# ''
+ call s:echo("Node Creation Aborted.")
+ return
+ endif
+
+ try
+ let newPath = g:NERDTreePath.Create(newNodeName)
+ let parentNode = b:NERDTreeRoot.findNode(newPath.getParent())
+
+ let newTreeNode = g:NERDTreeFileNode.New(newPath)
+ if empty(parentNode)
+ call b:NERDTreeRoot.refresh()
+ call b:NERDTree.render()
+ elseif parentNode.isOpen || !empty(parentNode.children)
+ call parentNode.addChild(newTreeNode, 1)
+ call NERDTreeRender()
+ call newTreeNode.putCursorHere(1, 0)
+ endif
+ catch /^NERDTree/
+ call s:echoWarning("Node Not Created.")
+ endtry
+endfunction
+
+"FUNCTION: NERDTreeMoveNode(){{{1
+function! NERDTreeMoveNode()
+ let curNode = g:NERDTreeFileNode.GetSelected()
+ let newNodePath = input("Rename the current node\n" .
+ \ "==========================================================\n" .
+ \ "Enter the new path for the node: \n" .
+ \ "", curNode.path.str(), "file")
+
+ if newNodePath ==# ''
+ call s:echo("Node Renaming Aborted.")
+ return
+ endif
+
+ try
+ let bufnum = bufnr("^".curNode.path.str()."$")
+
+ call curNode.rename(newNodePath)
+ call NERDTreeRender()
+
+ "if the node is open in a buffer, ask the user if they want to
+ "close that buffer
+ if bufnum != -1
+ let prompt = "\nNode renamed.\n\nThe old file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Replace this buffer with a new file? (yN)"
+ call s:promptToRenameBuffer(bufnum, prompt, newNodePath)
+ endif
+
+ call curNode.putCursorHere(1, 0)
+
+ redraw
+ catch /^NERDTree/
+ call s:echoWarning("Node Not Renamed.")
+ endtry
+endfunction
+
+" FUNCTION: NERDTreeDeleteNode() {{{1
+function! NERDTreeDeleteNode()
+ let currentNode = g:NERDTreeFileNode.GetSelected()
+ let confirmed = 0
+
+ if currentNode.path.isDirectory
+ let choice =input("Delete the current node\n" .
+ \ "==========================================================\n" .
+ \ "STOP! To delete this entire directory, type 'yes'\n" .
+ \ "" . currentNode.path.str() . ": ")
+ let confirmed = choice ==# 'yes'
+ else
+ echo "Delete the current node\n" .
+ \ "==========================================================\n".
+ \ "Are you sure you wish to delete the node:\n" .
+ \ "" . currentNode.path.str() . " (yN):"
+ let choice = nr2char(getchar())
+ let confirmed = choice ==# 'y'
+ endif
+
+
+ if confirmed
+ try
+ call currentNode.delete()
+ call NERDTreeRender()
+
+ "if the node is open in a buffer, ask the user if they want to
+ "close that buffer
+ let bufnum = bufnr("^".currentNode.path.str()."$")
+ if buflisted(bufnum)
+ let prompt = "\nNode deleted.\n\nThe file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Delete this buffer? (yN)"
+ call s:promptToDelBuffer(bufnum, prompt)
+ endif
+
+ redraw
+ catch /^NERDTree/
+ call s:echoWarning("Could not remove node")
+ endtry
+ else
+ call s:echo("delete aborted")
+ endif
+
+endfunction
+
+" FUNCTION: NERDTreeCopyNode() {{{1
+function! NERDTreeCopyNode()
+ let currentNode = g:NERDTreeFileNode.GetSelected()
+ let newNodePath = input("Copy the current node\n" .
+ \ "==========================================================\n" .
+ \ "Enter the new path to copy the node to: \n" .
+ \ "", currentNode.path.str(), "file")
+
+ if newNodePath != ""
+ "strip trailing slash
+ let newNodePath = substitute(newNodePath, '\/$', '', '')
+
+ let confirmed = 1
+ if currentNode.path.copyingWillOverwrite(newNodePath)
+ call s:echo("Warning: copying may overwrite files! Continue? (yN)")
+ let choice = nr2char(getchar())
+ let confirmed = choice ==# 'y'
+ endif
+
+ if confirmed
+ try
+ let newNode = currentNode.copy(newNodePath)
+ if empty(newNode)
+ call b:NERDTreeRoot.refresh()
+ call b:NERDTree.render()
+ else
+ call NERDTreeRender()
+ call newNode.putCursorHere(0, 0)
+ endif
+ catch /^NERDTree/
+ call s:echoWarning("Could not copy node")
+ endtry
+ endif
+ else
+ call s:echo("Copy aborted.")
+ endif
+ redraw
+endfunction
+
+function! NERDTreeQuickLook()
+ let treenode = g:NERDTreeFileNode.GetSelected()
+ if treenode != {}
+ call system("qlmanage -p 2>/dev/null '" . treenode.path.str() . "'")
+ endif
+endfunction
+
+function! NERDTreeRevealInFinder()
+ let treenode = g:NERDTreeFileNode.GetSelected()
+ if treenode != {}
+ let x = system("open -R '" . treenode.path.str() . "'")
+ endif
+endfunction
+
+function! NERDTreeExecuteFile()
+ let treenode = g:NERDTreeFileNode.GetSelected()
+ if treenode != {}
+ let x = system("open '" . treenode.path.str() . "'")
+ endif
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/nerdtree/plugin/NERD_tree.vim b/config/home/vim/bundle/nerdtree/plugin/NERD_tree.vim
new file mode 100644
index 0000000..966838c
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/plugin/NERD_tree.vim
@@ -0,0 +1,210 @@
+" ============================================================================
+" File: NERD_tree.vim
+" Description: vim global plugin that provides a nice tree explorer
+" Maintainer: Martin Grenfell
+" Last Change: 28 December, 2011
+" 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.
+"
+" ============================================================================
+"
+" SECTION: Script init stuff {{{1
+"============================================================
+if exists("loaded_nerd_tree")
+ finish
+endif
+if v:version < 700
+ echoerr "NERDTree: this plugin requires vim >= 7. DOWNLOAD IT! You'll thank me later!"
+ finish
+endif
+let loaded_nerd_tree = 1
+
+"for line continuation - i.e dont want C in &cpo
+let s:old_cpo = &cpo
+set cpo&vim
+
+"Function: s:initVariable() function {{{2
+"This function is used to initialise a given variable to a given value. The
+"variable is only initialised if it does not exist prior
+"
+"Args:
+"var: the name of the var to be initialised
+"value: the value to initialise var to
+"
+"Returns:
+"1 if the var is set, 0 otherwise
+function! s:initVariable(var, value)
+ if !exists(a:var)
+ exec 'let ' . a:var . ' = ' . "'" . substitute(a:value, "'", "''", "g") . "'"
+ return 1
+ endif
+ return 0
+endfunction
+
+"SECTION: Init variable calls and other random constants {{{2
+call s:initVariable("g:NERDTreeAutoCenter", 1)
+call s:initVariable("g:NERDTreeAutoCenterThreshold", 3)
+call s:initVariable("g:NERDTreeCaseSensitiveSort", 0)
+call s:initVariable("g:NERDTreeSortHiddenFirst", 1)
+call s:initVariable("g:NERDTreeChDirMode", 0)
+call s:initVariable("g:NERDTreeMinimalUI", 0)
+if !exists("g:NERDTreeIgnore")
+ let g:NERDTreeIgnore = ['\~$']
+endif
+call s:initVariable("g:NERDTreeBookmarksFile", expand('$HOME') . '/.NERDTreeBookmarks')
+call s:initVariable("g:NERDTreeBookmarksSort", 1)
+call s:initVariable("g:NERDTreeHighlightCursorline", 1)
+call s:initVariable("g:NERDTreeHijackNetrw", 1)
+call s:initVariable("g:NERDTreeMouseMode", 1)
+call s:initVariable("g:NERDTreeNotificationThreshold", 100)
+call s:initVariable("g:NERDTreeQuitOnOpen", 0)
+call s:initVariable("g:NERDTreeRespectWildIgnore", 0)
+call s:initVariable("g:NERDTreeShowBookmarks", 0)
+call s:initVariable("g:NERDTreeShowFiles", 1)
+call s:initVariable("g:NERDTreeShowHidden", 0)
+call s:initVariable("g:NERDTreeShowLineNumbers", 0)
+call s:initVariable("g:NERDTreeSortDirs", 1)
+call s:initVariable("g:NERDTreeDirArrows", !nerdtree#runningWindows())
+call s:initVariable("g:NERDTreeCascadeOpenSingleChildDir", 1)
+
+if !exists("g:NERDTreeSortOrder")
+ let g:NERDTreeSortOrder = ['\/$', '*', '\.swp$', '\.bak$', '\~$']
+else
+ "if there isnt a * in the sort sequence then add one
+ if count(g:NERDTreeSortOrder, '*') < 1
+ call add(g:NERDTreeSortOrder, '*')
+ endif
+endif
+
+if !exists('g:NERDTreeStatusline')
+
+ "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
+ "because it doesnt store b:NERDTreeRoot (its a b: var, and its a hash)
+ let g:NERDTreeStatusline = "%{exists('b:NERDTreeRoot')?b:NERDTreeRoot.path.str():''}"
+
+endif
+call s:initVariable("g:NERDTreeWinPos", "left")
+call s:initVariable("g:NERDTreeWinSize", 31)
+
+"init the shell commands that will be used to copy nodes, and remove dir trees
+"
+"Note: the space after the command is important
+if nerdtree#runningWindows()
+ call s:initVariable("g:NERDTreeRemoveDirCmd", 'rmdir /s /q ')
+else
+ call s:initVariable("g:NERDTreeRemoveDirCmd", 'rm -rf ')
+ call s:initVariable("g:NERDTreeCopyCmd", 'cp -r ')
+endif
+
+
+"SECTION: Init variable calls for key mappings {{{2
+call s:initVariable("g:NERDTreeMapActivateNode", "o")
+call s:initVariable("g:NERDTreeMapChangeRoot", "C")
+call s:initVariable("g:NERDTreeMapChdir", "cd")
+call s:initVariable("g:NERDTreeMapCloseChildren", "X")
+call s:initVariable("g:NERDTreeMapCloseDir", "x")
+call s:initVariable("g:NERDTreeMapDeleteBookmark", "D")
+call s:initVariable("g:NERDTreeMapMenu", "m")
+call s:initVariable("g:NERDTreeMapHelp", "?")
+call s:initVariable("g:NERDTreeMapJumpFirstChild", "K")
+call s:initVariable("g:NERDTreeMapJumpLastChild", "J")
+call s:initVariable("g:NERDTreeMapJumpNextSibling", "")
+call s:initVariable("g:NERDTreeMapJumpParent", "p")
+call s:initVariable("g:NERDTreeMapJumpPrevSibling", "")
+call s:initVariable("g:NERDTreeMapJumpRoot", "P")
+call s:initVariable("g:NERDTreeMapOpenExpl", "e")
+call s:initVariable("g:NERDTreeMapOpenInTab", "t")
+call s:initVariable("g:NERDTreeMapOpenInTabSilent", "T")
+call s:initVariable("g:NERDTreeMapOpenRecursively", "O")
+call s:initVariable("g:NERDTreeMapOpenSplit", "i")
+call s:initVariable("g:NERDTreeMapOpenVSplit", "s")
+call s:initVariable("g:NERDTreeMapPreview", "g" . NERDTreeMapActivateNode)
+call s:initVariable("g:NERDTreeMapPreviewSplit", "g" . NERDTreeMapOpenSplit)
+call s:initVariable("g:NERDTreeMapPreviewVSplit", "g" . NERDTreeMapOpenVSplit)
+call s:initVariable("g:NERDTreeMapQuit", "q")
+call s:initVariable("g:NERDTreeMapRefresh", "r")
+call s:initVariable("g:NERDTreeMapRefreshRoot", "R")
+call s:initVariable("g:NERDTreeMapToggleBookmarks", "B")
+call s:initVariable("g:NERDTreeMapToggleFiles", "F")
+call s:initVariable("g:NERDTreeMapToggleFilters", "f")
+call s:initVariable("g:NERDTreeMapToggleHidden", "I")
+call s:initVariable("g:NERDTreeMapToggleZoom", "A")
+call s:initVariable("g:NERDTreeMapUpdir", "u")
+call s:initVariable("g:NERDTreeMapUpdirKeepOpen", "U")
+call s:initVariable("g:NERDTreeMapCWD", "CD")
+
+"SECTION: Load class files{{{2
+call nerdtree#loadClassFiles()
+
+" SECTION: Commands {{{1
+"============================================================
+call nerdtree#ui_glue#setupCommands()
+
+" SECTION: Auto commands {{{1
+"============================================================
+augroup NERDTree
+ "Save the cursor position whenever we close the nerd tree
+ exec "autocmd BufLeave ". g:NERDTreeCreator.BufNamePrefix() ."* if g:NERDTree.IsOpen() | call b:NERDTree.ui.saveScreenState() | endif"
+
+ "disallow insert mode in the NERDTree
+ exec "autocmd BufEnter ". g:NERDTreeCreator.BufNamePrefix() ."* stopinsert"
+augroup END
+
+if g:NERDTreeHijackNetrw
+ augroup NERDTreeHijackNetrw
+ autocmd VimEnter * silent! autocmd! FileExplorer
+ au BufEnter,VimEnter * call nerdtree#checkForBrowse(expand(""))
+ augroup END
+endif
+
+" SECTION: Public API {{{1
+"============================================================
+function! NERDTreeAddMenuItem(options)
+ call g:NERDTreeMenuItem.Create(a:options)
+endfunction
+
+function! NERDTreeAddMenuSeparator(...)
+ let opts = a:0 ? a:1 : {}
+ call g:NERDTreeMenuItem.CreateSeparator(opts)
+endfunction
+
+function! NERDTreeAddSubmenu(options)
+ return g:NERDTreeMenuItem.Create(a:options)
+endfunction
+
+function! NERDTreeAddKeyMap(options)
+ call g:NERDTreeKeyMap.Create(a:options)
+endfunction
+
+function! NERDTreeRender()
+ call nerdtree#renderView()
+endfunction
+
+function! NERDTreeFocus()
+ if g:NERDTree.IsOpen()
+ call g:NERDTree.CursorToTreeWin()
+ else
+ call g:NERDTreeCreator.TogglePrimary("")
+ endif
+endfunction
+
+function! NERDTreeCWD()
+ call NERDTreeFocus()
+ call nerdtree#ui_glue#chRootCwd()
+endfunction
+
+function! NERDTreeAddPathFilter(callback)
+ call g:NERDTree.AddPathFilter(a:callback)
+endfunction
+
+" SECTION: Post Source Actions {{{1
+call nerdtree#postSourceActions()
+
+"reset &cpo back to users setting
+let &cpo = s:old_cpo
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/nerdtree/syntax/nerdtree.vim b/config/home/vim/bundle/nerdtree/syntax/nerdtree.vim
new file mode 100644
index 0000000..5f7b49c
--- /dev/null
+++ b/config/home/vim/bundle/nerdtree/syntax/nerdtree.vim
@@ -0,0 +1,105 @@
+let s:tree_up_dir_line = '.. (up a dir)'
+syn match NERDTreeIgnore #\~#
+syn match NERDTreeIgnore #\[RO\]#
+
+"highlighting for the .. (up dir) line at the top of the tree
+execute "syn match NERDTreeUp #\\V". s:tree_up_dir_line ."#"
+
+"quickhelp syntax elements
+syn match NERDTreeHelpKey #" \{1,2\}[^ ]*:#ms=s+2,me=e-1
+syn match NERDTreeHelpKey #" \{1,2\}[^ ]*,#ms=s+2,me=e-1
+syn match NERDTreeHelpTitle #" .*\~#ms=s+2,me=e-1
+syn match NERDTreeToggleOn #(on)#ms=s+1,he=e-1
+syn match NERDTreeToggleOff #(off)#ms=e-3,me=e-1
+syn match NERDTreeHelpCommand #" :.\{-}\>#hs=s+3
+syn match NERDTreeHelp #^".*# contains=NERDTreeHelpKey,NERDTreeHelpTitle,NERDTreeIgnore,NERDTreeToggleOff,NERDTreeToggleOn,NERDTreeHelpCommand
+
+"highlighting for sym links
+syn match NERDTreeLinkTarget #->.*# containedin=NERDTreeDir,NERDTreeFile
+syn match NERDTreeLinkFile #.* ->#me=e-3 containedin=NERDTreeFile
+syn match NERDTreeLinkDir #.*/ ->#me=e-3 containedin=NERDTreeDir
+
+"highlighing for directory nodes and file nodes
+syn match NERDTreeDirSlash #/# containedin=NERDTreeDir
+
+if g:NERDTreeDirArrows
+ syn match NERDTreeClosable #▾# containedin=NERDTreeDir,NERDTreeFile
+ syn match NERDTreeOpenable #▸# containedin=NERDTreeDir,NERDTreeFile
+
+ syn match NERDTreeDir #[^▾▸ ].*/#
+ syn match NERDTreeExecFile #^ .*\*\($\| \)# contains=NERDTreeRO,NERDTreeBookmark
+ syn match NERDTreeFile #^[^"\.▾▸] *[^▾▸]*# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmark,NERDTreeExecFile
+
+ "highlighting for readonly files
+ syn match NERDTreeRO # *\zs.*\ze \[RO\]# contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreeFile
+
+ syn match NERDTreeFlags #^ *\zs\[.\]# containedin=NERDTreeFile
+ syn match NERDTreeFlags #\[.\]# containedin=NERDTreeDir
+else
+ "highlighting for the ~/+ symbols for the directory nodes
+ syn match NERDTreeClosable #\~\<#
+ syn match NERDTreeClosable #\~\.#
+ syn match NERDTreeOpenable #+\<#
+ syn match NERDTreeOpenable #+\.#he=e-1
+
+ "highlighting for the tree structural parts
+ syn match NERDTreePart #|#
+ syn match NERDTreePart #`#
+ syn match NERDTreePartFile #[|`]-#hs=s+1 contains=NERDTreePart
+
+ syn match NERDTreeDir #[^-| `].*/# contains=NERDTreeLink,NERDTreeOpenable,NERDTreeClosable
+ syn match NERDTreeExecFile #[|` ].*\*\($\| \)# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark
+ syn match NERDTreeFile #|-.*# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile
+ syn match NERDTreeFile #`-.*# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile
+
+ "highlighting for readonly files
+ syn match NERDTreeRO #|-.*\[RO\]#he=e-5 contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreePart,NERDTreePartFile
+
+ syn match NERDTreeFlags #-\[.\]# containedin=NERDTreeFile,NERDTreePartFile
+ syn match NERDTreeFlags #[+~]\zs\[.\]# containedin=NERDTreeDir
+endif
+
+syn match NERDTreeCWD #^[].*$#
+
+"highlighting for bookmarks
+syn match NERDTreeBookmark # {.*}#hs=s+1
+
+"highlighting for the bookmarks table
+syn match NERDTreeBookmarksLeader #^>#
+syn match NERDTreeBookmarksHeader #^>-\+Bookmarks-\+$# contains=NERDTreeBookmarksLeader
+syn match NERDTreeBookmarkName #^>.\{-} #he=e-1 contains=NERDTreeBookmarksLeader
+syn match NERDTreeBookmark #^>.*$# contains=NERDTreeBookmarksLeader,NERDTreeBookmarkName,NERDTreeBookmarksHeader
+
+hi def link NERDTreePart Special
+hi def link NERDTreePartFile Type
+hi def link NERDTreeExecFile Title
+hi def link NERDTreeDirSlash Identifier
+
+hi def link NERDTreeBookmarksHeader statement
+hi def link NERDTreeBookmarksLeader ignore
+hi def link NERDTreeBookmarkName Identifier
+hi def link NERDTreeBookmark normal
+
+hi def link NERDTreeHelp String
+hi def link NERDTreeHelpKey Identifier
+hi def link NERDTreeHelpCommand Identifier
+hi def link NERDTreeHelpTitle Macro
+hi def link NERDTreeToggleOn Question
+hi def link NERDTreeToggleOff WarningMsg
+
+hi def link NERDTreeLinkTarget Type
+hi def link NERDTreeLinkFile Macro
+hi def link NERDTreeLinkDir Macro
+
+hi def link NERDTreeDir Directory
+hi def link NERDTreeUp Directory
+hi def link NERDTreeFile Normal
+hi def link NERDTreeCWD Statement
+hi def link NERDTreeOpenable Title
+hi def link NERDTreeClosable Title
+hi def link NERDTreeIgnore ignore
+hi def link NERDTreeRO WarningMsg
+hi def link NERDTreeBookmark Statement
+hi def link NERDTreeFlags Number
+
+hi def link NERDTreeCurrentNode Search
diff --git a/config/home/vim/bundle/syntastic/.gitignore b/config/home/vim/bundle/syntastic/.gitignore
new file mode 100644
index 0000000..cc07c93
--- /dev/null
+++ b/config/home/vim/bundle/syntastic/.gitignore
@@ -0,0 +1,4 @@
+*~
+*.swp
+tags
+.DS_Store
diff --git a/config/home/vim/bundle/syntastic/CONTRIBUTING.md b/config/home/vim/bundle/syntastic/CONTRIBUTING.md
new file mode 100644
index 0000000..378b53b
--- /dev/null
+++ b/config/home/vim/bundle/syntastic/CONTRIBUTING.md
@@ -0,0 +1,105 @@
+# CONTRIBUTING
+- - -
+1\. [Bug reports / GitHub issues](#bugreps)
+2\. [Submitting a patch](#patches)
+3\. [General style notes](#generalstyle)
+4\. [Syntax checker notes](#checkerstyle)
+- - -
+
+
+
+## 1. Bug reports / GitHub issues
+
+Please note that the preferred channel for posting bug reports is the
+[issue tracker at GitHub][0]. Reports posted elsewhere are less likely
+to be seen by the core team.
+
+When reporting a bug make sure you search the existing GitHub issues
+for the same/similar issues. If you find one, feel free to add a `+1`
+comment with any additional information that may help us solve the
+issue.
+
+When creating a new issue be sure to state the following:
+
+* steps to reproduce the bug;
+* the version of Vim you are using (run `:ver` to find out);
+* the version of syntastic you are using (see `:SyntasticInfo`).
+
+For syntax checker bugs also state the version of the checker executable
+that you are using. Adding debugging information is typically useful
+too:
+
+* open a file handled by your checker;
+* set `g:syntastic_debug` to 1 or 3;
+* run the checker;
+* copy the output of `:mes`.
+
+
+
+## 2. Submitting a patch
+
+Before you consider adding features to syntastic, _please_ spend a few
+minutes (re-)reading the latest version of the [manual][1]. Syntastic
+is changing rapidly at times, and it's quite possible that some of the
+features you want to add exist already.
+
+To submit a patch:
+
+* fork the [repo][2] on GitHub;
+* make a [topic branch][3] and start hacking;
+* submit a pull request based off your topic branch.
+
+Small, focused patches are preferred.
+
+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.
+
+Also make sure to update the manual whenever applicable. Nobody can use
+features that aren't documented.
+
+
+
+## 3. General style notes
+
+Follow the coding conventions/styles used in the syntastic core:
+
+* use 4 space indents;
+* don't use abbreviated keywords - e.g. use `endfunction`, not `endfun`
+(there's always room for more fun!);
+* don't use `l:` prefixes for variables unless actually required (i.e.
+almost never);
+* code for maintainability; we would rather a function be a couple of
+lines longer and have (for example) some [explaining variables][4] to
+aid readability.
+
+
+
+## 4. Syntax checker notes
+
+Make sure to read the [guide][5] if you plan to add new syntax checkers.
+
+Use the existing checkers as templates, rather than writing everything
+from scratch.
+
+The preferred style for error format strings is one "clause" per line.
+E.g. (from the `coffee` checker):
+
+```vim
+let errorformat =
+ \ '%E%f:%l:%c: %trror: %m,' .
+ \ 'Syntax%trror: In %f\, %m on line %l,' .
+ \ '%EError: In %f\, Parse error on line %l: %m,' .
+ \ '%EError: In %f\, %m on line %l,' .
+ \ '%W%f(%l): lint warning: %m,' .
+ \ '%W%f(%l): warning: %m,' .
+ \ '%E%f(%l): SyntaxError: %m,' .
+ \ '%-Z%p^,' .
+ \ '%-G%.%#'
+```
+
+[0]: https://github.com/scrooloose/syntastic/issues
+[1]: https://github.com/scrooloose/syntastic/blob/master/doc/syntastic.txt
+[2]: https://github.com/scrooloose/syntastic
+[3]: https://github.com/dchelimsky/rspec/wiki/Topic-Branches#using-topic-branches-when-contributing-patches
+[4]: http://www.refactoring.com/catalog/extractVariable.html
+[5]: https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide
diff --git a/config/home/vim/bundle/syntastic/LICENCE b/config/home/vim/bundle/syntastic/LICENCE
new file mode 100644
index 0000000..8b1a9d8
--- /dev/null
+++ b/config/home/vim/bundle/syntastic/LICENCE
@@ -0,0 +1,13 @@
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
+
+Copyright (C) 2004 Sam Hocevar
+
+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.
diff --git a/config/home/vim/bundle/syntastic/README.markdown b/config/home/vim/bundle/syntastic/README.markdown
new file mode 100644
index 0000000..72d54e8
--- /dev/null
+++ b/config/home/vim/bundle/syntastic/README.markdown
@@ -0,0 +1,462 @@
+ ,
+ / \,,_ .'|
+ ,{{| /}}}}/_.' _____________________________________________
+ }}}}` '{{' '. / \
+ {{{{{ _ ;, \ / Ladies and Gentlemen, \
+ ,}}}}}} /o`\ ` ;) | |
+ {{{{{{ / ( | this is ... |
+ }}}}}} | \ | |
+ {{{{{{{{ \ \ | |
+ }}}}}}}}} '.__ _ | | _____ __ __ _ |
+ {{{{{{{{ /`._ (_\ / | / ___/__ ______ / /_____ ______/ /_(_)____ |
+ }}}}}}' | //___/ --=: \__ \/ / / / __ \/ __/ __ `/ ___/ __/ / ___/ |
+ jgs `{{{{` | '--' | ___/ / /_/ / / / / /_/ /_/ (__ ) /_/ / /__ |
+ }}}` | /____/\__, /_/ /_/\__/\__,_/____/\__/_/\___/ |
+ | /____/ |
+ | /
+ \_____________________________________________/
+
+
+- - -
+1. [Introduction](#introduction)
+2. [Installation](#installation)
+2.1. [Requirements](#requirements)
+2.2. [Installing syntastic with Pathogen](#installpathogen)
+3. [Recommended settings](#settings)
+4. [FAQ](#faq)
+4.1. [I installed syntastic but it isn't reporting any errors...](#faqinfo)
+4.2. [The `python` checker complains about syntactically valid Python 3 constructs...](#faqpython3)
+4.3. [Are there any local checkers for HTML5 that I can use with syntastic?](#faqhtml5)
+4.4. [The `perl` checker has stopped working...](#faqperl)
+4.5. [What happened to the `rustc` checker?](#faqrust)
+4.6. [What happened to the `xcrun` checker?](#faqxcrun)
+4.7. [I run a checker and the location list is not updated...](#faqloclist)
+4.7. [I run`:lopen` or `:lwindow` and the error window is empty...](#faqloclist)
+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.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.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)
+5. [Resources](#otherresources)
+
+- - -
+
+
+
+## 1\. Introduction
+
+Syntastic is a syntax checking plugin for [Vim][13] that runs files through
+external syntax checkers and displays any resulting errors to the user. This
+can be done on demand, or automatically as files are saved. If syntax errors
+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.
+
+At the time of this writing, syntastic has checking plugins for ActionScript,
+Ada, API Blueprint, AppleScript, AsciiDoc, ASM, BEMHTML, Bro, Bourne shell,
+C, C++, C#, Cabal, Chef, CoffeeScript, Coco, Coq, CSS, Cucumber, CUDA, D,
+Dart, DocBook, Dust, Elixir, Erlang, eRuby, Fortran, Gentoo metadata, GLSL,
+Go, Haml, Haskell, Haxe, Handlebars, HSS, HTML, Java, JavaScript, JSON, JSX,
+LESS, Lex, Limbo, LISP, LLVM intermediate language, Lua, Markdown, MATLAB,
+Mercury, NASM, Objective-C, Objective-C++, OCaml, Perl, Perl POD, PHP, gettext
+Portable Object, OS X and iOS property lists, Puppet, Python, R, Racket, Relax
+NG, reStructuredText, RPM spec, Ruby, SASS/SCSS, Scala, Slim, SML, Tcl, TeX,
+Texinfo, Twig, TypeScript, Vala, Verilog, VHDL, VimL, xHtml, XML, XSLT, YACC,
+YAML, z80, Zope page templates, and zsh. See the [wiki][3] for details about
+the corresponding supported checkers.
+
+A number of third-party Vim plugins also provide checkers for syntastic,
+for example: [omnisharp-vim][25], [rust.vim][12], [syntastic-extras][26],
+[syntastic-more][27], and [vim-swift][24].
+
+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
+enabled.
+
+![Screenshot 1][0]
+
+1. Errors are loaded into the location list for the corresponding window.
+2. When the cursor is on a line containing an error, the error message is echoed in the command window.
+3. Signs are placed beside lines with errors - note that warnings are displayed in a different color.
+4. There is a configurable statusline flag you can include in your statusline config.
+5. Hover the mouse over a line containing an error and the error message is displayed as a balloon.
+6. (not shown) Highlighting errors with syntax highlighting. Erroneous parts of lines can be highlighted.
+
+
+
+## 2\. Installation
+
+
+
+### 2.1\. Requirements
+
+Syntastic itself has rather relaxed requirements: it doesn't have any external
+dependencies, and it needs a version of [Vim][13] compiled with a few common
+features: `autocmd`, `eval`, `file_in_path`, `modify_fname`, `quickfix`,
+`reltime`, and `user_commands`. Not all possible combinations of features that
+include the ones above make equal sense on all operating systems, but Vim
+version 7 or later with the "normal", "big", or "huge" feature sets should be
+fine.
+
+Syntastic should work with any modern plugin managers for Vim, such as
+[NeoBundle][14], [Pathogen][1], [Vim-Addon-Manager][15], [Vim-Plug][16], or
+[Vundle][17]. Instructions for installing syntastic with [Pathogen][1] are
+included below for completeness.
+
+Last but not least: syntastic doesn't know how to do any syntax checks by
+itself. In order to get meaningful results you need to install external
+checkers corresponding to the types of files you use. Please consult the
+[wiki][3] for a list of supported checkers.
+
+
+
+### 2.2\. Installing syntastic with Pathogen
+
+If you already have [Pathogen][1] working then skip [Step 1](#step1) and go to
+[Step 2](#step2).
+
+
+
+#### 2.2.1\. Step 1: Install pathogen.vim
+
+First I'll show you how to install Tim Pope's [Pathogen][1] so that it's easy to
+install syntastic. Do this in your terminal so that you get the `pathogen.vim`
+file and the directories it needs:
+```sh
+mkdir -p ~/.vim/autoload ~/.vim/bundle && \
+curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim
+```
+Next you *need* to add this to your `~/.vimrc`:
+```vim
+execute pathogen#infect()
+```
+
+
+
+#### 2.2.2\. Step 2: Install syntastic as a Pathogen bundle
+
+You now have pathogen installed and can put syntastic into `~/.vim/bundle` like
+this:
+```sh
+cd ~/.vim/bundle && \
+git clone https://github.com/scrooloose/syntastic.git
+```
+Quit vim and start it back up to reload it, then type:
+```vim
+:Helptags
+```
+If you get an error when you do this, then you probably didn't install
+[Pathogen][1] right. Go back to [Step 1](#step1) and make sure you did the
+following:
+
+1. Created both the `~/.vim/autoload` and `~/.vim/bundle` directories.
+2. Added the `execute pathogen#infect()` line to your `~/.vimrc` file
+3. Did the `git clone` of syntastic inside `~/.vim/bundle`
+4. Have permissions to access all of these directories.
+
+
+
+## 3\. Recommended settings
+
+Syntastic has a large number of options that can be configured, and the
+defaults 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
+to them after reading the manual (see `:help syntastic` in Vim):
+```vim
+set statusline+=%#warningmsg#
+set statusline+=%{SyntasticStatuslineFlag()}
+set statusline+=%*
+
+let g:syntastic_always_populate_loc_list = 1
+let g:syntastic_auto_loc_list = 1
+let g:syntastic_check_on_open = 1
+let g:syntastic_check_on_wq = 0
+```
+
+
+
+## 4\. FAQ
+
+
+
+__4.1. Q. I installed syntastic but it isn't reporting any errors...__
+
+A. The most likely reason is that none of the syntax checkers that it requires
+is installed. For example: by default, python requires either `flake8` or
+`pylint` to be installed and in your `$PATH`. To see which executables are
+supported, look at the [wiki][3]. Note that aliases do not work; the actual
+executables must be available in your `$PATH`. Symbolic links are okay though.
+You can see syntastic's idea of available checkers by running `:SyntasticInfo`.
+
+A second probable reason is that none of the available checkers are
+enabled. Syntastic comes preconfigured with a default list of enabled checkers
+per filetype, but this list is kept short in order to prevent slowing down Vim
+or trying to run conflicting checks. The command `:SyntasticInfo` will show you
+which checkers are enabled. You can tell syntastic which checkers (among the
+available ones) you want to run by setting `g:syntastic__checkers` in
+your `vimrc` (see [below](#faqcheckers)).
+
+A third possible reason is that the `$PATH` seen by syntastic might not be same
+as the `$PATH` in your login shell. Syntastic runs checkers using the shell
+pointed to by Vim's `shell` (or by `g:syntastic_shell`, if set), and that's the
+shell you need to configure to set the proper `$PATH` and environment variables
+for your checkers. You can see syntastic's idea of `$PATH` by running
+```vim
+:echo syntastic#util#system('echo "$PATH"')
+```
+on UNIX and Mac OS-X systems, or
+```vim
+:echo syntastic#util#system('echo %PATH%')
+```
+on Windows.
+
+Finally, another reason it could fail is that either the command line options
+or the error output for a syntax checker may have changed. In this case, make
+sure you have the latest version of the syntax checker installed. If it still
+fails then post an [issue][4] - or better yet, create a pull request.
+
+
+
+__4.2. Q. The `python` checker complains about syntactically valid Python 3 constructs...__
+
+A. Configure the `python` checker to call a Python 3 interpreter rather than
+Python 2, e.g:
+```vim
+let g:syntastic_python_python_exec = '/path/to/python3'
+```
+
+
+
+__4.3. Q. Are there any local checkers for HTML5 that I can use with syntastic?__
+
+[HTML Tidy][18] has a fork named [HTML Tidy for HTML5][19]. It's a drop
+in replacement, and syntastic can use it without changes. Just install it
+somewhere and point `g:syntastic_html_tidy_exec` to its executable:
+```vim
+let g:syntastic_html_tidy_exec = 'tidy5'
+```
+Alternatively, you can install [vnu.jar][21] from the [validator.nu][20]
+project and run it as a [HTTP server][23]:
+```sh
+$ java -Xss512k -cp /path/to/vnu.jar nu.validator.servlet.Main 8888
+```
+Then you can [configure][22] syntastic to use it:
+```vim
+let g:syntastic_html_validator_api = 'http://localhost:8888/'
+```
+
+
+
+__4.4. Q. The `perl` checker has stopped working...__
+
+A. The `perl` checker runs `perl -c` against your file, which in turn
+__executes__ any `BEGIN`, `UNITCHECK`, and `CHECK` blocks, and any `use`
+statements in your file (cf. [perlrun][10]). This is probably fine if you
+wrote the file yourself, but it's a security problem if you're checking third
+party files. Since there is currently no way to disable this behaviour while
+still producing useful results, the checker is now disabled by default. To
+(re-)enable it, make sure the `g:syntastic_perl_checkers` list includes `perl`,
+and set `g:syntastic_enable_perl_checker` to 1 in your `vimrc`:
+```vim
+let g:syntastic_enable_perl_checker = 1
+```
+
+
+
+__4.5. Q. What happened to the `rustc` checker?__
+
+A. It is now part of the [rust.vim][12] plugin. If you install this plugin the
+checker should be picked up automatically by syntastic.
+
+
+
+__4.6. Q. What happened to the `xcrun` checker?__
+
+A. The `xcrun` checker used to have a security problem and it has been removed.
+A better checker for __Swift__ is part of the [vim-swift][24] plugin. If you
+install this plugin the checker should be picked up automatically by syntastic.
+
+
+
+__4.7. Q. I run a checker and the location list is not updated...__
+__4.7. Q. I run`:lopen` or `:lwindow` and the error window is empty...__
+
+A. By default the location list is changed only when you run the `:Errors`
+command, in order to minimise conflicts with other plugins. If you want the
+location list to always be updated when you run the checkers, add this line to
+your `vimrc`:
+```vim
+let g:syntastic_always_populate_loc_list = 1
+```
+
+
+
+__4.8. Q. How can I pass additional arguments to a checker?__
+
+A. Almost all syntax checkers use the `makeprgBuild()` function. Those checkers
+that do can be configured using global variables. The general form of the
+global `args` variables is `syntastic___args`.
+
+So, If you wanted to pass `--my --args --here` to the ruby mri checker you
+would add this line to your `vimrc`:
+```vim
+let g:syntastic_ruby_mri_args = "--my --args --here"
+```
+
+See `:help syntastic-checker-options` for more information.
+
+
+
+__4.9. Q. Syntastic supports several checkers for my filetype - how do I tell it
+which one(s) to use?__
+
+A. Stick a line like this in your `vimrc`:
+```vim
+let g:syntastic__checkers = ['']
+```
+
+To see the list of supported checkers for your filetype look at the
+[wiki][3].
+
+e.g. Python has the following checkers, among others: `flake8`, `pyflakes`,
+`pylint` and a native `python` checker.
+
+To tell syntastic to use `pylint`, you would use this setting:
+```vim
+let g:syntastic_python_checkers = ['pylint']
+```
+
+Checkers can be chained together like this:
+```vim
+let g:syntastic_php_checkers = ['php', 'phpcs', 'phpmd']
+```
+
+This is telling syntastic to run the `php` checker first, and if no errors are
+found, run `phpcs`, and then `phpmd`.
+
+You can also run checkers explicitly by calling `:SyntasticCheck `.
+
+e.g. to run `phpcs` and `phpmd`:
+```vim
+:SyntasticCheck phpcs phpmd
+```
+
+This works for any checkers available for the current filetype, even if they
+aren't listed in `g:syntastic__checkers`. You can't run checkers for
+"foreign" filetypes though (e.g. you can't run, say, a Python checker if the
+filetype of the current file is `php`).
+
+
+
+__4.10. Q. What is the difference between syntax checkers and style checkers?__
+
+A. The errors and warnings they produce are highlighted differently and can
+be filtered by different rules, but otherwise the distinction is pretty much
+arbitrary. There is an ongoing effort to keep things consistent, so you can
+_generally_ expect messages produced by syntax checkers to be _mostly_ related
+to syntax, and messages produced by style checkers to be _mostly_ about style.
+But there can be no formal guarantee that, say, a style checker that runs into
+a syntax error wouldn't die with a fatal message, nor that a syntax checker
+wouldn't give you warnings against using some constructs as being bad practice.
+There is also no guarantee that messages marked as "style" are less severe than
+the ones marked as "syntax" (whatever that might mean). And there are even a
+few Frankenstein checkers (for example `flake8` and `pylama`) that, by their
+nature, produce both kinds of messages. Syntastic is not smart enough to be
+able to sort out these things by itself.
+
+In fact it's more useful to look at this from the perspective of filtering
+unwanted messages, rather than as an indicator of severity levels. The
+distinction between syntax and style is orthogonal to the distinction between
+errors and warnings, and thus you can turn off messages based on level, on
+type, or both.
+
+e.g. To disable all style messages:
+```vim
+let g:syntastic_quiet_messages = { "type": "style" }
+```
+See `:help syntastic_quiet_messages` for details.
+
+
+
+__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?__
+
+A. Set `g:syntastic_aggregate_errors` to 1 in your `vimrc`:
+```vim
+let g:syntastic_aggregate_errors = 1
+```
+
+See `:help syntastic-aggregating-errors` for more details.
+
+
+
+__4.12. Q. How can I jump between the different errors without using the location
+list at the bottom of the window?__
+
+A. Vim provides several built-in commands for this. See `:help :lnext` and
+`:help :lprevious`.
+
+If you use these commands a lot then you may want to add shortcut mappings to
+your `vimrc`, or install something like [unimpaired][2], which provides such
+mappings (among other things).
+
+
+
+__4.13. Q. The error window is closed automatically when I :quit the current buffer
+but not when I :bdelete it?__
+
+A. There is no safe way to handle that situation automatically, but you can
+work around it:
+
+```vim
+nnoremap :lclose:bdelete
+cabbrev bd lclose\|bdelete
+```
+
+
+
+## 5\. Resources
+
+The preferred place for posting suggestions, reporting bugs, and general
+discussions related to syntastic is the [issue tracker at GitHub][4].
+A guide for writing syntax checkers can be found in the [wiki][11].
+There are also a dedicated [google group][5], and a
+[syntastic tag at StackOverflow][6].
+
+Syntastic aims to provide a common interface to syntax checkers for as many
+languages as possible. For particular languages, there are, of course, other
+plugins that provide more functionality than syntastic. You might want to take
+a look at [jedi-vim][7], [python-mode][8], or [YouCompleteMe][9].
+
+[0]: https://github.com/scrooloose/syntastic/raw/master/_assets/screenshot_1.png
+[1]: https://github.com/tpope/vim-pathogen
+[2]: https://github.com/tpope/vim-unimpaired
+[3]: https://github.com/scrooloose/syntastic/wiki/Syntax-Checkers
+[4]: https://github.com/scrooloose/syntastic/issues
+[5]: https://groups.google.com/group/vim-syntastic
+[6]: http://stackoverflow.com/questions/tagged/syntastic
+[7]: https://github.com/davidhalter/jedi-vim
+[8]: https://github.com/klen/python-mode
+[9]: http://valloric.github.io/YouCompleteMe/
+[10]: http://perldoc.perl.org/perlrun.html#*-c*
+[11]: https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide
+[12]: https://github.com/rust-lang/rust.vim
+[13]: http://www.vim.org/
+[14]: https://github.com/Shougo/neobundle.vim
+[15]: https://github.com/MarcWeber/vim-addon-manager
+[16]: https://github.com/junegunn/vim-plug/
+[17]: https://github.com/gmarik/Vundle.vim
+[18]: http://tidy.sourceforge.net/
+[19]: http://www.htacg.org/tidy-html5/
+[20]: http://about.validator.nu/
+[21]: https://github.com/validator/validator/releases/latest
+[22]: https://github.com/scrooloose/syntastic/wiki/HTML%3A---validator
+[23]: http://validator.github.io/validator/#standalone
+[24]: https://github.com/kballard/vim-swift
+[25]: https://github.com/OmniSharp/omnisharp-vim
+[26]: https://github.com/myint/syntastic-extras
+[27]: https://github.com/roktas/syntastic-more
+
+
diff --git a/config/home/vim/bundle/syntastic/_assets/screenshot_1.png b/config/home/vim/bundle/syntastic/_assets/screenshot_1.png
new file mode 100644
index 0000000..c1b69f4
Binary files /dev/null and b/config/home/vim/bundle/syntastic/_assets/screenshot_1.png differ
diff --git a/config/home/vim/bundle/syntastic/autoload/syntastic/c.vim b/config/home/vim/bundle/syntastic/autoload/syntastic/c.vim
new file mode 100644
index 0000000..716585d
--- /dev/null
+++ b/config/home/vim/bundle/syntastic/autoload/syntastic/c.vim
@@ -0,0 +1,345 @@
+if exists('g:loaded_syntastic_c_autoload') || !exists('g:loaded_syntastic_plugin')
+ finish
+endif
+let g:loaded_syntastic_c_autoload = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+" Public functions {{{1
+
+" convenience function to determine the 'null device' parameter
+" based on the current operating system
+function! syntastic#c#NullOutput() abort " {{{2
+ let known_os = has('unix') || has('mac') || syntastic#util#isRunningWindows()
+ return known_os ? '-o ' . syntastic#util#DevNull() : ''
+endfunction " }}}2
+
+" read additional compiler flags from the given configuration file
+" the file format and its parsing mechanism is inspired by clang_complete
+function! syntastic#c#ReadConfig(file) abort " {{{2
+ call syntastic#log#debug(g:_SYNTASTIC_DEBUG_CHECKERS, 'ReadConfig: looking for', a:file)
+
+ " search upwards from the current file's directory
+ let config = findfile(a:file, '.;')
+ if config ==# ''
+ call syntastic#log#debug(g:_SYNTASTIC_DEBUG_CHECKERS, 'ReadConfig: file not found')
+ return ''
+ endif
+ call syntastic#log#debug(g:_SYNTASTIC_DEBUG_CHECKERS, 'ReadConfig: config file:', config)
+ if !filereadable(config)
+ call syntastic#log#debug(g:_SYNTASTIC_DEBUG_CHECKERS, 'ReadConfig: file unreadable')
+ return ''
+ endif
+
+ " convert filename into absolute path
+ let filepath = fnamemodify(config, ':p:h')
+
+ " try to read config file
+ try
+ let lines = readfile(config)
+ catch /\m^Vim\%((\a\+)\)\=:E48[45]/
+ call syntastic#log#debug(g:_SYNTASTIC_DEBUG_CHECKERS, 'ReadConfig: error reading file')
+ return ''
+ endtry
+
+ " filter out empty lines and comments
+ call filter(lines, 'v:val !~# ''\v^(\s*#|$)''')
+
+ " remove leading and trailing spaces
+ call map(lines, 'substitute(v:val, ''\m^\s\+'', "", "")')
+ call map(lines, 'substitute(v:val, ''\m\s\+$'', "", "")')
+
+ let parameters = []
+ for line in lines
+ let matches = matchstr(line, '\m\C^\s*-I\s*\zs.\+')
+ if matches !=# ''
+ " this one looks like an absolute path
+ if match(matches, '\m^\%(/\|\a:\)') != -1
+ call add(parameters, '-I' . matches)
+ else
+ call add(parameters, '-I' . filepath . syntastic#util#Slash() . matches)
+ endif
+ else
+ call add(parameters, line)
+ endif
+ endfor
+
+ return join(map(parameters, 'syntastic#util#shescape(v:val)'))
+endfunction " }}}2
+
+" GetLocList() for C-like compilers
+function! syntastic#c#GetLocList(filetype, subchecker, options) abort " {{{2
+ try
+ let flags = s:_get_cflags(a:filetype, a:subchecker, a:options)
+ catch /\m\C^Syntastic: skip checks$/
+ return []
+ endtry
+
+ let makeprg = syntastic#util#shexpand(g:syntastic_{a:filetype}_compiler) .
+ \ ' ' . flags . ' ' . syntastic#util#shexpand('%')
+
+ let errorformat = s:_get_checker_var('g', a:filetype, a:subchecker, 'errorformat', a:options['errorformat'])
+
+ let postprocess = s:_get_checker_var('g', a:filetype, a:subchecker, 'remove_include_errors', 0) ?
+ \ ['filterForeignErrors'] : []
+
+ " process makeprg
+ return SyntasticMake({
+ \ 'makeprg': makeprg,
+ \ 'errorformat': errorformat,
+ \ 'postprocess': postprocess })
+endfunction " }}}2
+
+" }}}1
+
+" Private functions {{{1
+
+" initialize c/cpp syntax checker handlers
+function! s:_init() abort " {{{2
+ let s:handlers = []
+ let s:cflags = {}
+
+ call s:_registerHandler('\m\', 's:_checkPhp', [])
+ call s:_registerHandler('\m\', 's:_checkPython', [])
+ call s:_registerHandler('\m\"
+ echohl ErrorMsg
+ echomsg 'syntastic: error: ' . a:msg
+ echohl None
+endfunction " }}}2
+
+function! syntastic#log#oneTimeWarn(msg) abort " {{{2
+ if index(s:one_time_notices_issued, a:msg) >= 0
+ return
+ endif
+
+ call add(s:one_time_notices_issued, a:msg)
+ call syntastic#log#warn(a:msg)
+endfunction " }}}2
+
+" @vimlint(EVL102, 1, l:OLD_VAR)
+function! syntastic#log#deprecationWarn(old, new, ...) abort " {{{2
+ if exists('g:syntastic_' . a:old) && !exists('g:syntastic_' . a:new)
+ let msg = 'variable g:syntastic_' . a:old . ' is deprecated, please use '
+
+ if a:0
+ let OLD_VAR = g:syntastic_{a:old}
+ try
+ let NEW_VAR = eval(a:1)
+ let msg .= 'in its stead: let g:syntastic_' . a:new . ' = ' . string(NEW_VAR)
+ let g:syntastic_{a:new} = NEW_VAR
+ catch
+ let msg .= 'g:syntastic_' . a:new . ' instead'
+ endtry
+ else
+ let msg .= 'g:syntastic_' . a:new . ' instead'
+ let g:syntastic_{a:new} = g:syntastic_{a:old}
+ endif
+
+ call syntastic#log#oneTimeWarn(msg)
+ endif
+endfunction " }}}2
+" @vimlint(EVL102, 0, l:OLD_VAR)
+
+function! syntastic#log#debug(level, msg, ...) abort " {{{2
+ if !s:_isDebugEnabled(a:level)
+ return
+ endif
+
+ let leader = s:_log_timestamp()
+ call s:_logRedirect(1)
+
+ if a:0 > 0
+ " filter out dictionary functions
+ echomsg leader . a:msg . ' ' .
+ \ strtrans(string(type(a:1) == type({}) || type(a:1) == type([]) ?
+ \ filter(copy(a:1), 'type(v:val) != type(function("tr"))') : a:1))
+ else
+ echomsg leader . a:msg
+ endif
+
+ call s:_logRedirect(0)
+endfunction " }}}2
+
+function! syntastic#log#debugShowOptions(level, names) abort " {{{2
+ if !s:_isDebugEnabled(a:level)
+ return
+ endif
+
+ let leader = s:_log_timestamp()
+ call s:_logRedirect(1)
+
+ let vlist = copy(type(a:names) == type('') ? [a:names] : a:names)
+ if !empty(vlist)
+ call map(vlist, "'&' . v:val . ' = ' . strtrans(string(eval('&' . v:val)))")
+ echomsg leader . join(vlist, ', ')
+ endif
+ call s:_logRedirect(0)
+endfunction " }}}2
+
+function! syntastic#log#debugShowVariables(level, names) abort " {{{2
+ if !s:_isDebugEnabled(a:level)
+ return
+ endif
+
+ let leader = s:_log_timestamp()
+ call s:_logRedirect(1)
+
+ let vlist = type(a:names) == type('') ? [a:names] : a:names
+ for name in vlist
+ let msg = s:_format_variable(name)
+ if msg !=# ''
+ echomsg leader . msg
+ endif
+ endfor
+
+ call s:_logRedirect(0)
+endfunction " }}}2
+
+function! syntastic#log#debugDump(level) abort " {{{2
+ if !s:_isDebugEnabled(a:level)
+ return
+ endif
+
+ call syntastic#log#debugShowVariables( a:level, sort(keys(g:_SYNTASTIC_DEFAULTS)) )
+endfunction " }}}2
+
+" }}}1
+
+" Private functions {{{1
+
+function! s:_isDebugEnabled_smart(level) abort " {{{2
+ return and(g:syntastic_debug, a:level)
+endfunction " }}}2
+
+function! s:_isDebugEnabled_dumb(level) abort " {{{2
+ " poor man's bit test for bit N, assuming a:level == 2**N
+ return (g:syntastic_debug / a:level) % 2
+endfunction " }}}2
+
+let s:_isDebugEnabled = function(exists('*and') ? 's:_isDebugEnabled_smart' : 's:_isDebugEnabled_dumb')
+lockvar s:_isDebugEnabled
+
+function! s:_logRedirect(on) abort " {{{2
+ if exists('g:syntastic_debug_file')
+ if a:on
+ try
+ execute 'redir >> ' . fnameescape(expand(g:syntastic_debug_file, 1))
+ catch /\m^Vim\%((\a\+)\)\=:/
+ silent! redir END
+ unlet g:syntastic_debug_file
+ endtry
+ else
+ silent! redir END
+ endif
+ endif
+endfunction " }}}2
+
+" }}}1
+
+" Utilities {{{1
+
+function! s:_log_timestamp() abort " {{{2
+ return 'syntastic: ' . split(reltimestr(reltime(g:_SYNTASTIC_START)))[0] . ': '
+endfunction " }}}2
+
+function! s:_format_variable(name) abort " {{{2
+ let vals = []
+ if exists('g:syntastic_' . a:name)
+ call add(vals, 'g:syntastic_' . a:name . ' = ' . strtrans(string(g:syntastic_{a:name})))
+ endif
+ if exists('b:syntastic_' . a:name)
+ call add(vals, 'b:syntastic_' . a:name . ' = ' . strtrans(string(b:syntastic_{a:name})))
+ endif
+
+ return join(vals, ', ')
+endfunction " }}}2
+
+" }}}1
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/syntastic/autoload/syntastic/postprocess.vim b/config/home/vim/bundle/syntastic/autoload/syntastic/postprocess.vim
new file mode 100644
index 0000000..136fa58
--- /dev/null
+++ b/config/home/vim/bundle/syntastic/autoload/syntastic/postprocess.vim
@@ -0,0 +1,73 @@
+if exists('g:loaded_syntastic_postprocess_autoload') || !exists('g:loaded_syntastic_plugin')
+ finish
+endif
+let g:loaded_syntastic_postprocess_autoload = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+" Public functions {{{1
+
+" merge consecutive blanks
+function! syntastic#postprocess#compressWhitespace(errors) abort " {{{2
+ for e in a:errors
+ let e['text'] = substitute(e['text'], "\001", '', 'g')
+ let e['text'] = substitute(e['text'], '\n', ' ', 'g')
+ let e['text'] = substitute(e['text'], '\m\s\{2,}', ' ', 'g')
+ let e['text'] = substitute(e['text'], '\m^\s\+', '', '')
+ let e['text'] = substitute(e['text'], '\m\s\+$', '', '')
+ endfor
+
+ return a:errors
+endfunction " }}}2
+
+" remove spurious CR under Cygwin
+function! syntastic#postprocess#cygwinRemoveCR(errors) abort " {{{2
+ if has('win32unix')
+ for e in a:errors
+ let e['text'] = substitute(e['text'], '\r', '', 'g')
+ endfor
+ endif
+
+ return a:errors
+endfunction " }}}2
+
+" decode XML entities
+function! syntastic#postprocess#decodeXMLEntities(errors) abort " {{{2
+ for e in a:errors
+ let e['text'] = syntastic#util#decodeXMLEntities(e['text'])
+ endfor
+
+ return a:errors
+endfunction " }}}2
+
+" filter out errors referencing other files
+function! syntastic#postprocess#filterForeignErrors(errors) abort " {{{2
+ return filter(copy(a:errors), 'get(v:val, "bufnr") == ' . bufnr(''))
+endfunction " }}}2
+
+" make sure line numbers are not past end of buffers
+" XXX: this loads all referenced buffers in memory
+function! syntastic#postprocess#guards(errors) abort " {{{2
+ let buffers = syntastic#util#unique(map(filter(copy(a:errors), 'v:val["valid"]'), 'str2nr(v:val["bufnr"])'))
+
+ let guards = {}
+ for b in buffers
+ let guards[b] = len(getbufline(b, 1, '$'))
+ endfor
+
+ for e in a:errors
+ if e['valid'] && e['lnum'] > guards[e['bufnr']]
+ let e['lnum'] = guards[e['bufnr']]
+ endif
+ endfor
+
+ return a:errors
+endfunction " }}}2
+
+" }}}1
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/syntastic/autoload/syntastic/preprocess.vim b/config/home/vim/bundle/syntastic/autoload/syntastic/preprocess.vim
new file mode 100644
index 0000000..6800295
--- /dev/null
+++ b/config/home/vim/bundle/syntastic/autoload/syntastic/preprocess.vim
@@ -0,0 +1,316 @@
+if exists('g:loaded_syntastic_preprocess_autoload') || !exists('g:loaded_syntastic_plugin')
+ finish
+endif
+let g:loaded_syntastic_preprocess_autoload = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+" Public functions {{{1
+
+function! syntastic#preprocess#cabal(errors) abort " {{{2
+ let out = []
+ let star = 0
+ for err in a:errors
+ if star
+ if err ==# ''
+ let star = 0
+ else
+ let out[-1] .= ' ' . err
+ endif
+ else
+ call add(out, err)
+ if err =~# '\m^*\s'
+ let star = 1
+ endif
+ endif
+ endfor
+ return out
+endfunction " }}}2
+
+function! syntastic#preprocess#checkstyle(errors) abort " {{{2
+ let out = []
+ let fname = expand('%', 1)
+ for err in a:errors
+ if match(err, '\m') > -1
+ let line = str2nr(matchstr(err, '\m\ \[[^]]+\])+\ze:'', "", "")')
+endfunction " }}}2
+
+" @vimlint(EVL102, 1, l:true)
+" @vimlint(EVL102, 1, l:false)
+" @vimlint(EVL102, 1, l:null)
+function! syntastic#preprocess#flow(errors) abort " {{{2
+ " JSON artifacts
+ 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 = []
+ if type(errs) == type({}) && has_key(errs, 'errors') && type(errs['errors']) == type([])
+ for e in errs['errors']
+ if type(e) == type({}) && has_key(e, 'message') && type(e['message']) == type([]) && len(e['message'])
+ let m = e['message'][0]
+ let t = e['message'][1:]
+
+ try
+ let msg =
+ \ m['path'] . ':' .
+ \ m['line'] . ':' .
+ \ m['start'] . ':' .
+ \ (m['line'] ==# m['endline'] && str2nr(m['end']) > 0 ? m['end'] . ':' : '') .
+ \ ' ' . m['descr']
+
+ if len(t)
+ let msg .= ' ' . join(map(t,
+ \ 'v:val["descr"] . " (" . v:val["path"] . ":" . v:val["line"] . ":" . v:val["start"] . ' .
+ \ '"," . (v:val["line"] !=# v:val["endline"] ? v:val["endline"] . ":" : "") . ' .
+ \ 'v:val["end"] . ")"'))
+ endif
+
+ let msg = substitute(msg, '\r', '', 'g')
+ let msg = substitute(msg, '\n', ' ', 'g')
+
+ call add(out, msg)
+ catch /\m^Vim\%((\a\+)\)\=:E716/
+ call syntastic#log#warn('checker javascript/flow: unknown error format')
+ let out = []
+ break
+ endtry
+ else
+ call syntastic#log#warn('checker javascript/flow: unknown error format')
+ let out = []
+ break
+ endif
+ endfor
+ else
+ call syntastic#log#warn('checker javascript/flow: unknown error format')
+ endif
+
+ return out
+endfunction " }}}2
+" @vimlint(EVL102, 0, l:true)
+" @vimlint(EVL102, 0, l:false)
+" @vimlint(EVL102, 0, l:null)
+
+function! syntastic#preprocess#killEmpty(errors) abort " {{{2
+ return filter(copy(a:errors), 'v:val !=# ""')
+endfunction " }}}2
+
+function! syntastic#preprocess#perl(errors) abort " {{{2
+ let out = []
+
+ for e in a:errors
+ let parts = matchlist(e, '\v^(.*)\sat\s(.{-})\sline\s(\d+)(.*)$')
+ if !empty(parts)
+ call add(out, parts[2] . ':' . parts[3] . ':' . parts[1] . parts[4])
+ endif
+ endfor
+
+ return syntastic#util#unique(out)
+endfunction " }}}2
+
+" @vimlint(EVL102, 1, l:true)
+" @vimlint(EVL102, 1, l:false)
+" @vimlint(EVL102, 1, l:null)
+function! syntastic#preprocess#prospector(errors) abort " {{{2
+ " JSON artifacts
+ 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 = []
+ if type(errs) == type({}) && has_key(errs, 'messages')
+ if type(errs['messages']) == type([])
+ for e in errs['messages']
+ if type(e) == type({})
+ try
+ if e['source'] ==# 'pylint'
+ let e['location']['character'] += 1
+ endif
+
+ let msg =
+ \ e['location']['path'] . ':' .
+ \ e['location']['line'] . ':' .
+ \ e['location']['character'] . ': ' .
+ \ e['code'] . ' ' .
+ \ e['message'] . ' ' .
+ \ '[' . e['source'] . ']'
+
+ call add(out, msg)
+ catch /\m^Vim\%((\a\+)\)\=:E716/
+ call syntastic#log#warn('checker python/prospector: unknown error format')
+ let out = []
+ break
+ endtry
+ else
+ call syntastic#log#warn('checker python/prospector: unknown error format')
+ let out = []
+ break
+ endif
+ endfor
+ else
+ call syntastic#log#warn('checker python/prospector: unknown error format')
+ endif
+ endif
+
+ return out
+endfunction " }}}2
+" @vimlint(EVL102, 0, l:true)
+" @vimlint(EVL102, 0, l:false)
+" @vimlint(EVL102, 0, l:null)
+
+function! syntastic#preprocess#rparse(errors) abort " {{{2
+ let errlist = copy(a:errors)
+
+ " remove uninteresting lines and handle continuations
+ let i = 0
+ while i < len(errlist)
+ if i > 0 && errlist[i][:1] ==# ' ' && errlist[i] !~# '\m\s\+\^$'
+ let errlist[i-1] .= errlist[i][1:]
+ call remove(errlist, i)
+ elseif errlist[i] !~# '\m^\(Lint:\|Lint checking:\|Error in\) '
+ call remove(errlist, i)
+ else
+ let i += 1
+ endif
+ endwhile
+
+ let out = []
+ let fname = ''
+ for e in errlist
+ if match(e, '\m^Lint: ') == 0
+ let parts = matchlist(e, '\m^Lint: \(.*\): found on lines \([0-9, ]\+\)\(+\(\d\+\) more\)\=')
+ if len(parts) >= 3
+ for line in split(parts[2], '\m,\s*')
+ call add(out, 'E:' . fname . ':' . line . ': ' . parts[1])
+ endfor
+ endif
+ if len(parts) >= 5 && parts[4] !=# ''
+ call add(out, 'E:' . fname . ':0: ' . parts[1] . ' - ' . parts[4] . ' messages not shown')
+ endif
+ elseif match(e, '\m^Lint checking: ') == 0
+ let fname = matchstr(e, '\m^Lint checking: \zs.*')
+ elseif match(e, '\m^Error in ') == 0
+ call add(out, substitute(e, '\m^Error in .\+ : .\+\ze:\d\+:\d\+: ', 'E:' . fname, ''))
+ endif
+ endfor
+
+ return out
+endfunction " }}}2
+
+function! syntastic#preprocess#tslint(errors) abort " {{{2
+ return map(copy(a:errors), 'substitute(v:val, ''\m^\(([^)]\+)\)\s\(.\+\)$'', ''\2 \1'', "")')
+endfunction " }}}2
+
+function! syntastic#preprocess#validator(errors) abort " {{{2
+ let out = []
+ for e in a:errors
+ let parts = matchlist(e, '\v^"([^"]+)"(.+)')
+ if len(parts) >= 3
+ " URL decode, except leave alone any "+"
+ let parts[1] = substitute(parts[1], '\m%\(\x\x\)', '\=nr2char("0x".submatch(1))', 'g')
+ let parts[1] = substitute(parts[1], '\m\\"', '"', 'g')
+ let parts[1] = substitute(parts[1], '\m\\\\', '\\', 'g')
+ call add(out, '"' . parts[1] . '"' . parts[2])
+ endif
+ endfor
+ return out
+endfunction " }}}2
+
+" @vimlint(EVL102, 1, l:true)
+" @vimlint(EVL102, 1, l:false)
+" @vimlint(EVL102, 1, l:null)
+function! syntastic#preprocess#vint(errors) abort " {{{2
+ " JSON artifacts
+ 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 = []
+ if type(errs) == type([])
+ for e in errs
+ if type(e) == type({})
+ try
+ let msg =
+ \ e['file_path'] . ':' .
+ \ e['line_number'] . ':' .
+ \ e['column_number'] . ':' .
+ \ e['severity'][0] . ': ' .
+ \ e['description'] . ' (' .
+ \ e['policy_name'] . ')'
+
+ call add(out, msg)
+ catch /\m^Vim\%((\a\+)\)\=:E716/
+ call syntastic#log#warn('checker vim/vint: unknown error format')
+ let out = []
+ break
+ endtry
+ else
+ call syntastic#log#warn('checker vim/vint: unknown error format')
+ let out = []
+ break
+ endif
+ endfor
+ else
+ call syntastic#log#warn('checker vim/vint: unknown error format')
+ endif
+
+ return out
+endfunction " }}}2
+" @vimlint(EVL102, 0, l:true)
+" @vimlint(EVL102, 0, l:false)
+" @vimlint(EVL102, 0, l:null)
+
+" }}}1
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/syntastic/autoload/syntastic/util.vim b/config/home/vim/bundle/syntastic/autoload/syntastic/util.vim
new file mode 100644
index 0000000..4b652d2
--- /dev/null
+++ b/config/home/vim/bundle/syntastic/autoload/syntastic/util.vim
@@ -0,0 +1,414 @@
+if exists('g:loaded_syntastic_util_autoload') || !exists('g:loaded_syntastic_plugin')
+ finish
+endif
+let g:loaded_syntastic_util_autoload = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+" Public functions {{{1
+
+function! syntastic#util#isRunningWindows() abort " {{{2
+ return has('win16') || has('win32') || has('win64')
+endfunction " }}}2
+
+function! syntastic#util#DevNull() abort " {{{2
+ if syntastic#util#isRunningWindows()
+ return 'NUL'
+ endif
+ return '/dev/null'
+endfunction " }}}2
+
+" Get directory separator
+function! syntastic#util#Slash() abort " {{{2
+ return (!exists('+shellslash') || &shellslash) ? '/' : '\'
+endfunction " }}}2
+
+function! syntastic#util#CygwinPath(path) abort " {{{2
+ return substitute(syntastic#util#system('cygpath -m ' . syntastic#util#shescape(a:path)), "\n", '', 'g')
+endfunction " }}}2
+
+function! syntastic#util#system(command) abort " {{{2
+ let old_shell = &shell
+ let old_lc_messages = $LC_MESSAGES
+ let old_lc_all = $LC_ALL
+
+ let &shell = syntastic#util#var('shell')
+ let $LC_MESSAGES = 'C'
+ let $LC_ALL = ''
+
+ let out = system(a:command)
+
+ let $LC_ALL = old_lc_all
+ let $LC_MESSAGES = old_lc_messages
+
+ let &shell = old_shell
+
+ return out
+endfunction " }}}2
+
+" Create a temporary directory
+function! syntastic#util#tmpdir() abort " {{{2
+ let tempdir = ''
+
+ if (has('unix') || has('mac')) && executable('mktemp')
+ " TODO: option "-t" to mktemp(1) is not portable
+ let tmp = $TMPDIR !=# '' ? $TMPDIR : $TMP !=# '' ? $TMP : '/tmp'
+ let out = split(syntastic#util#system('mktemp -q -d ' . tmp . '/vim-syntastic-' . getpid() . '-XXXXXXXX'), "\n")
+ if v:shell_error == 0 && len(out) == 1
+ let tempdir = out[0]
+ endif
+ endif
+
+ if tempdir ==# ''
+ if has('win32') || has('win64')
+ let tempdir = $TEMP . syntastic#util#Slash() . 'vim-syntastic-' . getpid()
+ elseif has('win32unix')
+ let tempdir = syntastic#util#CygwinPath('/tmp/vim-syntastic-' . getpid())
+ elseif $TMPDIR !=# ''
+ let tempdir = $TMPDIR . '/vim-syntastic-' . getpid()
+ else
+ let tempdir = '/tmp/vim-syntastic-' . getpid()
+ endif
+
+ try
+ call mkdir(tempdir, 'p', 0700)
+ catch /\m^Vim\%((\a\+)\)\=:E739/
+ call syntastic#log#error(v:exception)
+ let tempdir = '.'
+ endtry
+ endif
+
+ return tempdir
+endfunction " }}}2
+
+" Recursively remove a directory
+function! syntastic#util#rmrf(what) abort " {{{2
+ " try to make sure we don't delete directories we didn't create
+ if a:what !~? 'vim-syntastic-'
+ return
+ endif
+
+ if getftype(a:what) ==# 'dir'
+ if !exists('s:rmrf')
+ let s:rmrf =
+ \ has('unix') || has('mac') ? 'rm -rf' :
+ \ has('win32') || has('win64') ? 'rmdir /S /Q' :
+ \ has('win16') || has('win95') || has('dos16') || has('dos32') ? 'deltree /Y' : ''
+ endif
+
+ if s:rmrf !=# ''
+ silent! call syntastic#util#system(s:rmrf . ' ' . syntastic#util#shescape(a:what))
+ else
+ call s:_rmrf(a:what)
+ endif
+ else
+ silent! call delete(a:what)
+ endif
+endfunction " }}}2
+
+"search the first 5 lines of the file for a magic number and return a map
+"containing the args and the executable
+"
+"e.g.
+"
+"#!/usr/bin/perl -f -bar
+"
+"returns
+"
+"{'exe': '/usr/bin/perl', 'args': ['-f', '-bar']}
+function! syntastic#util#parseShebang() abort " {{{2
+ for lnum in range(1, 5)
+ let line = getline(lnum)
+ if line =~# '^#!'
+ let line = substitute(line, '\v^#!\s*(\S+/env(\s+-\S+)*\s+)?', '', '')
+ let exe = matchstr(line, '\m^\S*\ze')
+ let args = split(matchstr(line, '\m^\S*\zs.*'))
+ return { 'exe': exe, 'args': args }
+ endif
+ endfor
+
+ return { 'exe': '', 'args': [] }
+endfunction " }}}2
+
+" Get the value of a variable. Allow local variables to override global ones.
+function! syntastic#util#var(name, ...) abort " {{{2
+ return
+ \ exists('b:syntastic_' . a:name) ? b:syntastic_{a:name} :
+ \ exists('g:syntastic_' . a:name) ? g:syntastic_{a:name} :
+ \ a:0 > 0 ? a:1 : ''
+endfunction " }}}2
+
+" Parse a version string. Return an array of version components.
+function! syntastic#util#parseVersion(version, ...) abort " {{{2
+ return map(split(matchstr( a:version, a:0 ? a:1 : '\v^\D*\zs\d+(\.\d+)+\ze' ), '\m\.'), 'str2nr(v:val)')
+endfunction " }}}2
+
+" Verify that the 'installed' version is at least the 'required' version.
+"
+" 'installed' and 'required' must be arrays. If they have different lengths,
+" the "missing" elements will be assumed to be 0 for the purposes of checking.
+"
+" See http://semver.org for info about version numbers.
+function! syntastic#util#versionIsAtLeast(installed, required) abort " {{{2
+ return syntastic#util#compareLexi(a:installed, a:required) >= 0
+endfunction " }}}2
+
+" Almost lexicographic comparison of two lists of integers. :) If lists
+" have different lengths, the "missing" elements are assumed to be 0.
+function! syntastic#util#compareLexi(a, b) abort " {{{2
+ for idx in range(max([len(a:a), len(a:b)]))
+ let a_element = str2nr(get(a:a, idx, 0))
+ let b_element = str2nr(get(a:b, idx, 0))
+ if a_element != b_element
+ return a_element > b_element ? 1 : -1
+ endif
+ endfor
+ " still here, thus everything matched
+ return 0
+endfunction " }}}2
+
+" strwidth() was added in Vim 7.3; if it doesn't exist, we use strlen()
+" and hope for the best :)
+let s:_width = function(exists('*strwidth') ? 'strwidth' : 'strlen')
+lockvar s:_width
+
+function! syntastic#util#screenWidth(str, tabstop) abort " {{{2
+ let chunks = split(a:str, "\t", 1)
+ let width = s:_width(chunks[-1])
+ for c in chunks[:-2]
+ let cwidth = s:_width(c)
+ let width += cwidth + a:tabstop - cwidth % a:tabstop
+ endfor
+ return width
+endfunction " }}}2
+
+"print as much of a:msg as possible without "Press Enter" prompt appearing
+function! syntastic#util#wideMsg(msg) abort " {{{2
+ let old_ruler = &ruler
+ let old_showcmd = &showcmd
+
+ "This is here because it is possible for some error messages to
+ "begin with \n which will cause a "press enter" prompt.
+ let msg = substitute(a:msg, "\n", '', 'g')
+
+ "convert tabs to spaces so that the tabs count towards the window
+ "width as the proper amount of characters
+ let chunks = split(msg, "\t", 1)
+ let msg = join(map(chunks[:-2], 'v:val . repeat(" ", &tabstop - s:_width(v:val) % &tabstop)'), '') . chunks[-1]
+ let msg = strpart(msg, 0, &columns - 1)
+
+ set noruler noshowcmd
+ call syntastic#util#redraw(0)
+
+ echo msg
+
+ let &ruler = old_ruler
+ let &showcmd = old_showcmd
+endfunction " }}}2
+
+" Check whether a buffer is loaded, listed, and not hidden
+function! syntastic#util#bufIsActive(buffer) abort " {{{2
+ " convert to number, or hell breaks loose
+ let buf = str2nr(a:buffer)
+
+ if !bufloaded(buf) || !buflisted(buf)
+ return 0
+ endif
+
+ " get rid of hidden buffers
+ for tab in range(1, tabpagenr('$'))
+ if index(tabpagebuflist(tab), buf) >= 0
+ return 1
+ endif
+ endfor
+
+ return 0
+endfunction " }}}2
+
+" start in directory a:where and walk up the parent folders until it
+" finds a file matching a:what; return path to that file
+function! syntastic#util#findInParent(what, where) abort " {{{2
+ let here = fnamemodify(a:where, ':p')
+
+ let root = syntastic#util#Slash()
+ if syntastic#util#isRunningWindows() && here[1] ==# ':'
+ " The drive letter is an ever-green source of fun. That's because
+ " we don't care about running syntastic on Amiga these days. ;)
+ let root = fnamemodify(root, ':p')
+ let root = here[0] . root[1:]
+ endif
+
+ let old = ''
+ while here !=# ''
+ let p = split(globpath(here, a:what, 1), '\n')
+
+ if !empty(p)
+ return fnamemodify(p[0], ':p')
+ elseif here ==? root || here ==? old
+ break
+ endif
+
+ let old = here
+
+ " we use ':h:h' rather than ':h' since ':p' adds a trailing '/'
+ " if 'here' is a directory
+ let here = fnamemodify(here, ':p:h:h')
+ endwhile
+
+ return ''
+endfunction " }}}2
+
+" Returns unique elements in a list
+function! syntastic#util#unique(list) abort " {{{2
+ let seen = {}
+ let uniques = []
+ for e in a:list
+ if !has_key(seen, e)
+ let seen[e] = 1
+ call add(uniques, e)
+ endif
+ endfor
+ return uniques
+endfunction " }}}2
+
+" A less noisy shellescape()
+function! syntastic#util#shescape(string) abort " {{{2
+ return a:string =~# '\m^[A-Za-z0-9_/.-]\+$' ? a:string : shellescape(a:string)
+endfunction " }}}2
+
+" A less noisy shellescape(expand())
+function! syntastic#util#shexpand(string, ...) abort " {{{2
+ return syntastic#util#shescape(a:0 ? expand(a:string, a:1) : expand(a:string, 1))
+endfunction " }}}2
+
+" Escape arguments
+function! syntastic#util#argsescape(opt) abort " {{{2
+ if type(a:opt) == type('') && a:opt !=# ''
+ return [a:opt]
+ elseif type(a:opt) == type([])
+ return map(copy(a:opt), 'syntastic#util#shescape(v:val)')
+ endif
+
+ return []
+endfunction " }}}2
+
+" decode XML entities
+function! syntastic#util#decodeXMLEntities(string) abort " {{{2
+ let str = a:string
+ let str = substitute(str, '\m<', '<', 'g')
+ let str = substitute(str, '\m>', '>', 'g')
+ let str = substitute(str, '\m"', '"', 'g')
+ let str = substitute(str, '\m'', "'", 'g')
+ let str = substitute(str, '\m&', '\&', 'g')
+ return str
+endfunction " }}}2
+
+function! syntastic#util#redraw(full) abort " {{{2
+ if a:full
+ redraw!
+ else
+ redraw
+ endif
+endfunction " }}}2
+
+function! syntastic#util#dictFilter(errors, filter) abort " {{{2
+ let rules = s:_translateFilter(a:filter)
+ " call syntastic#log#debug(g:_SYNTASTIC_DEBUG_TRACE, "applying filter:", rules)
+ try
+ call filter(a:errors, rules)
+ catch /\m^Vim\%((\a\+)\)\=:E/
+ let msg = matchstr(v:exception, '\m^Vim\%((\a\+)\)\=:\zs.*')
+ call syntastic#log#error('quiet_messages: ' . msg)
+ endtry
+endfunction " }}}2
+
+" Return a [seconds, fractions] list of strings, representing the
+" (hopefully high resolution) time since program start
+function! syntastic#util#stamp() abort " {{{2
+ return split( split(reltimestr(reltime(g:_SYNTASTIC_START)))[0], '\.' )
+endfunction " }}}2
+
+" }}}1
+
+" Private functions {{{1
+
+function! s:_translateFilter(filters) abort " {{{2
+ let conditions = []
+ for k in keys(a:filters)
+ if type(a:filters[k]) == type([])
+ call extend(conditions, map(copy(a:filters[k]), 's:_translateElement(k, v:val)'))
+ else
+ call add(conditions, s:_translateElement(k, a:filters[k]))
+ endif
+ endfor
+
+ if conditions == []
+ let conditions = ['1']
+ endif
+ return len(conditions) == 1 ? conditions[0] : join(map(conditions, '"(" . v:val . ")"'), ' && ')
+endfunction " }}}2
+
+function! s:_translateElement(key, term) abort " {{{2
+ let fkey = a:key
+ if fkey[0] ==# '!'
+ let fkey = fkey[1:]
+ let not = 1
+ else
+ let not = 0
+ endif
+
+ if fkey ==? 'level'
+ let op = not ? ' ==? ' : ' !=? '
+ let ret = 'v:val["type"]' . op . string(a:term[0])
+ elseif fkey ==? 'type'
+ if a:term ==? 'style'
+ let op = not ? ' ==? ' : ' !=? '
+ let ret = 'get(v:val, "subtype", "")' . op . '"style"'
+ else
+ let op = not ? '!' : ''
+ let ret = op . 'has_key(v:val, "subtype")'
+ endif
+ elseif fkey ==? 'regex'
+ let op = not ? ' =~? ' : ' !~? '
+ let ret = 'v:val["text"]' . op . string(a:term)
+ elseif fkey ==? 'file' || fkey[:4] ==? 'file:'
+ let op = not ? ' =~# ' : ' !~# '
+ let ret = 'bufname(str2nr(v:val["bufnr"]))'
+ let mod = fkey[4:]
+ if mod !=# ''
+ let ret = 'fnamemodify(' . ret . ', ' . string(mod) . ')'
+ endif
+ let ret .= op . string(a:term)
+ else
+ call syntastic#log#warn('quiet_messages: ignoring invalid key ' . strtrans(string(fkey)))
+ let ret = '1'
+ endif
+ return ret
+endfunction " }}}2
+
+function! s:_rmrf(what) abort " {{{2
+ if !exists('s:rmdir')
+ let s:rmdir = syntastic#util#shescape(get(g:, 'netrw_localrmdir', 'rmdir'))
+ endif
+
+ if getftype(a:what) ==# 'dir'
+ if filewritable(a:what) != 2
+ return
+ endif
+
+ for f in split(globpath(a:what, '*', 1), "\n")
+ call s:_rmrf(f)
+ endfor
+ silent! call syntastic#util#system(s:rmdir . ' ' . syntastic#util#shescape(a:what))
+ else
+ silent! call delete(a:what)
+ endif
+endfunction " }}}2
+
+" }}}1
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/config/home/vim/bundle/syntastic/doc/syntastic.txt b/config/home/vim/bundle/syntastic/doc/syntastic.txt
new file mode 100644
index 0000000..c64b336
--- /dev/null
+++ b/config/home/vim/bundle/syntastic/doc/syntastic.txt
@@ -0,0 +1,956 @@
+*syntastic.txt* Syntax checking on the fly has never been so pimp.
+*syntastic*
+
+
+ It's a bird! It's a plane! ZOMG It's ... ~
+
+ _____ __ __ _ ~
+ / ___/__ ______ / /_____ ______/ /_(_)____ ~
+ \__ \/ / / / __ \/ __/ __ `/ ___/ __/ / ___/ ~
+ ___/ / /_/ / / / / /_/ /_/ (__ ) /_/ / /__ ~
+ /____/\__, /_/ /_/\__/\__,_/____/\__/_/\___/ ~
+ /____/ ~
+
+
+
+ Reference Manual~
+
+
+==============================================================================
+CONTENTS *syntastic-contents*
+
+ 1.Intro........................................|syntastic-intro|
+ 1.1.Quick start............................|syntastic-quickstart|
+ 1.2.Recommended settings...................|syntastic-recommended|
+ 2.Functionality provided.......................|syntastic-functionality|
+ 2.1.The statusline flag....................|syntastic-statusline-flag|
+ 2.2.Error signs............................|syntastic-error-signs|
+ 2.3.Error window...........................|syntastic-error-window|
+ 2.4.Error highlighting.....................|syntastic-highlighting|
+ 2.5.Aggregating errors.....................|syntastic-aggregating-errors|
+ 2.6.Filtering errors.......................|syntastic-filtering-errors|
+ 3.Commands.....................................|syntastic-commands|
+ 4.Global Options...............................|syntastic-global-options|
+ 5.Checker Options..............................|syntastic-checker-options|
+ 5.1.Choosing which checkers to use.........|syntastic-filetype-checkers|
+ 5.2.Choosing the executable................|syntastic-config-exec|
+ 5.3.Configuring specific checkers..........|syntastic-config-makeprg|
+ 5.4.Sorting errors.........................|syntastic-config-sort|
+ 6.Notes........................................|syntastic-notes|
+ 6.1.Handling of composite filetypes........|syntastic-composite|
+ 6.2.Editing files over network.............|syntastic-netrw|
+ 6.3.The 'shellslash' option................|syntastic-shellslash|
+ 7.Compatibility with other software............|syntastic-compatibility|
+ 7.1.The csh and tcsh shells................|syntastic-csh|
+ 7.2.Eclim..................................|syntastic-eclim|
+ 7.3.The fish shell.........................|syntastic-fish|
+ 7.4.The fizsh shell........................|syntastic-fizsh|
+ 7.5.powerline..............................|syntastic-powerline|
+ 7.6.The PowerShell shell...................|syntastic-powershell|
+ 7.7.python-mode............................|syntastic-pymode|
+ 7.8.vim-auto-save..........................|syntastic-vim-auto-save|
+ 7.9.vim-go.................................|syntastic-vim-go|
+ 7.10.vim-virtualenv........................|syntastic-vim-virtualenv|
+ 7.11.YouCompleteMe.........................|syntastic-ycm|
+ 8.About........................................|syntastic-about|
+ 9.License......................................|syntastic-license|
+
+
+==============================================================================
+1. Intro *syntastic-intro*
+
+Syntastic is a syntax checking plugin that runs files through external syntax
+checkers. This can be done on demand, or automatically as files are saved and
+opened. If syntax errors 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.
+
+Syntastic comes in two parts: the syntax checker plugins, and the core. The
+syntax checker plugins are defined on a per-filetype basis where each one wraps
+up an external syntax checking program. The core script delegates off to these
+plugins and uses their output to provide the syntastic functionality.
+
+Take a look at the wiki for a list of supported filetypes and checkers:
+
+ https://github.com/scrooloose/syntastic/wiki/Syntax-Checkers
+
+Note: This doc only deals with using syntastic. To learn how to write syntax
+checker integrations, see the guide on the GitHub wiki:
+
+ https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide
+
+------------------------------------------------------------------------------
+1.1. Quick start *syntastic-quickstart*
+
+Syntastic comes preconfigured with a default list of enabled checkers per
+filetype. This list is kept reasonably short to prevent slowing down Vim or
+trying to use conflicting checkers.
+
+You can see the list of checkers available for the current filetype with the
+|:SyntasticInfo| command.
+
+You probably want to override the configured list of checkers for the
+filetypes you use, and also change the arguments passed to specific checkers
+to suit your needs. See |syntastic-checker-options| below for details.
+
+Use |:SyntasticCheck| to manually check right now. Use |:Errors| to open the
+|location-list| window, and |:lclose| to close it. You can clear the error
+list with |:SyntasticReset|, and you can use |:SyntasticToggleMode| to switch
+between active (checking on writing the buffer) and passive (manual) checking.
+
+You don't have to switch focus to the |location-list| window to jump to the
+different errors. Vim provides several built-in commands for this, for
+example |:lnext| and |:lprevious|. You may want to add shortcut mappings for
+these commands, or perhaps install a plugin such as Tim Pope's 'unimpaired'
+(see https://github.com/tpope/vim-unimpaired) that provides such mappings.
+
+------------------------------------------------------------------------------
+1.2. Recommended settings *syntastic-recommended*
+
+Syntastic has a large number of options that can be configured, and the
+defaults are not particularly well suitable for new users. It is recommended
+that you start by adding the following lines to your vimrc, and return to them
+later as needed: >
+ set statusline+=%#warningmsg#
+ set statusline+=%{SyntasticStatuslineFlag()}
+ set statusline+=%*
+
+ let g:syntastic_always_populate_loc_list = 1
+ let g:syntastic_auto_loc_list = 1
+ let g:syntastic_check_on_open = 1
+ let g:syntastic_check_on_wq = 0
+<
+==============================================================================
+2. Functionality provided *syntastic-functionality*
+
+Syntax checking can be done automatically or on demand (see
+|'syntastic_mode_map'| and |:SyntasticToggleMode| for configuring this).
+
+When syntax checking is done, the features below can be used to notify the
+user of errors. See |syntastic-global-options| for how to configure and
+activate/deactivate these features.
+
+ * A statusline flag
+ * Signs beside lines with errors
+ * The |location-list| can be populated with the errors for the associated
+ buffer
+ * Erroneous parts of lines can be highlighted (this functionality is only
+ provided by some syntax checkers)
+ * Balloons (if the |+balloon_eval| feature is compiled in) can be used to
+ display error messages for erroneous lines when hovering the mouse over
+ them
+ * Error messages from multiple checkers can be aggregated in a single list
+
+------------------------------------------------------------------------------
+2.1. The statusline flag *syntastic-statusline-flag*
+
+To use the statusline flag, this must appear in your |'statusline'| setting >
+ %{SyntasticStatuslineFlag()}
+<
+Something like this could be more useful: >
+ set statusline+=%#warningmsg#
+ set statusline+=%{SyntasticStatuslineFlag()}
+ set statusline+=%*
+<
+When syntax errors are detected a flag will be shown. The content of the flag
+is derived from the |syntastic_stl_format| option.
+
+------------------------------------------------------------------------------
+2.2. Error signs *syntastic-error-signs*
+
+Syntastic uses the |:sign| commands to mark lines with errors and warnings in
+the sign column. To enable this feature, use the |'syntastic_enable_signs'|
+option.
+
+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
+groups:
+ SyntasticErrorSign - For syntax errors, links to 'error' by default
+ SyntasticWarningSign - For syntax warnings, links to 'todo' by default
+ SyntasticStyleErrorSign - For style errors, links to 'SyntasticErrorSign'
+ by default
+ SyntasticStyleWarningSign - For style warnings, links to
+ 'SyntasticWarningSign' by default
+
+Example: >
+ highlight SyntasticErrorSign guifg=white guibg=red
+<
+To set up highlighting for the line where a sign resides, you can use the
+following highlight groups:
+ SyntasticErrorLine
+ SyntasticWarningLine
+ SyntasticStyleErrorLine - Links to 'SyntasticErrorLine' by default
+ SyntasticStyleWarningLine - Links to 'SyntasticWarningLine' by default
+
+Example: >
+ highlight SyntasticErrorLine guibg=#2f0000
+<
+------------------------------------------------------------------------------
+2.3. The error window *syntastic-error-window*
+
+You can use the |:Errors| command to display the errors for the current buffer
+in the |location-list|.
+
+Note that when you use |:Errors| the current location list is overwritten with
+Syntastic's own location list. 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
+the checkers, in order to reduce clashes with other plugins. Consequently, if
+you run |:lopen| or |:lwindow| rather than |:Errors| to open the error window you
+wouldn't see syntastic's list of errors. If you insist on using |:lopen| or
+|:lwindow| you should either run |:SyntasticSetLoclist| after running the checks,
+or set |syntastic_always_populate_loc_list| which tells syntastic to update the
+|location-list| automatically.
+
+------------------------------------------------------------------------------
+2.4. Error highlighting *syntastic-highlighting*
+
+Some checkers provide enough information for syntastic to be able to highlight
+errors. By default the SpellBad syntax highlight group is used to color errors,
+and the SpellCap group is used for warnings. If you wish to customize the
+colors for highlighting you can use the following groups:
+ SyntasticError - Links to 'SpellBad' by default
+ SyntasticWarning - Links to 'SpellCap' by default
+ SyntasticStyleError - Links to SyntasticError by default
+ SyntasticStyleWarning - Links to SyntasticWarning by default
+
+Example: >
+ highlight SyntasticError guibg=#2f0000
+<
+------------------------------------------------------------------------------
+2.5. Aggregating errors *syntastic-aggregating-errors*
+
+By default, namely if |'syntastic_aggregate_errors'| is unset, syntastic runs
+in turn the checkers corresponding to the filetype of the current file (see
+|syntastic-filetype-checkers|), and stops as soon as a checker reports any
+errors. It then notifies you of the errors using the notification mechanisms
+above. In this mode error lists are always produced by a single checker, and,
+if you open the error window, the name of the checker that generated the errors
+is shown on the statusline of the error window.
+
+If |'syntastic_aggregate_errors'| is set, syntastic runs all checkers that
+apply (still cf. |syntastic-filetype-checkers|), then aggregates errors found
+by all checkers in a single list, and notifies you. In this mode each error
+message is labeled with the name of the checker that generated it, but you can
+disable generation of these labels by turning off '|syntastic_id_checkers|'.
+
+If |'syntastic_sort_aggregated_errors'| is set (which is the default), messages
+in the aggregated list are grouped by file, then sorted by line number, then
+type, then column number. Otherwise messages produced by the same checker are
+grouped together, and sorting within each group is decided by the variables
+|'syntastic___sort'|.
+
+------------------------------------------------------------------------------
+2.6 Filtering errors *syntastic-filtering-errors*
+
+You can selectively disable some of the errors found by checkers either
+using |'syntastic_quiet_messages'|, or by specifying a list of patterns in
+|'syntastic_ignore_files'|.
+
+See also: |'syntastic___quiet_messages'|.
+
+==============================================================================
+3. Commands *syntastic-commands*
+
+:Errors *:Errors*
+
+When errors have been detected, use this command to pop up the |location-list|
+and display the error messages.
+
+Please note that the |:Errors| command overwrites the current location list with
+syntastic's own location list.
+
+:SyntasticToggleMode *:SyntasticToggleMode*
+
+Toggles syntastic between active and passive mode. See |'syntastic_mode_map'|
+for more info.
+
+:SyntasticCheck *:SyntasticCheck*
+
+Manually cause a syntax check to be done. By default the checkers in the
+|'g:syntastic__checkers'| or |'b:syntastic_checkers'| lists are run,
+cf. |syntastic-filetype-checkers|. If |syntastic_aggregate_errors| is unset
+(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
+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
+case |'g:syntastic__checkers'| and |'b:syntastic_checkers'| are
+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.
+
+Example: >
+ :SyntasticCheck flake8 pylint
+<
+:SyntasticInfo *:SyntasticInfo*
+
+The command takes an optional argument, and outputs information about the
+checkers available for the filetype named by said argument, or for the current
+filetype if no argument was provided.
+
+:SyntasticReset *:SyntasticReset*
+
+Resets the list of errors and turns off all error notifiers.
+
+:SyntasticSetLoclist *:SyntasticSetLoclist*
+
+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.
+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
+the location list explicitly.
+
+==============================================================================
+4. Global Options *syntastic-global-options*
+
+
+ *'syntastic_check_on_open'*
+Default: 0
+If enabled, syntastic will do syntax checks when buffers are first loaded as
+well as on saving >
+ let g:syntastic_check_on_open = 1
+<
+ *'syntastic_check_on_wq'*
+Default: 1
+Normally syntastic runs syntax checks whenever buffers are written to disk.
+If you want to skip these checks when you issue |:wq|, |:x|, and |:ZZ|, set this
+variable to 0. >
+ let g:syntastic_check_on_wq = 0
+<
+ *'syntastic_aggregate_errors'*
+Default: 0
+When enabled, syntastic runs all checkers that apply to the current filetype,
+then aggregates errors found by all checkers and displays them. When disabled,
+syntastic runs each checker in turn, and stops to display the results the first
+time a checker finds any errors. >
+ let g:syntastic_aggregate_errors = 1
+<
+ *'syntastic_id_checkers'*
+Default: 1
+When results from multiple checkers are aggregated in a single error list
+(that is either when |syntastic_aggregate_errors| is enabled, or when checking
+a file with a composite filetype), it might not be immediately obvious which
+checker has produced a given error message. This variable instructs syntastic
+to label error messages with the names of the checkers that created them. >
+ let g:syntastic_id_checkers = 0
+<
+ *'syntastic_sort_aggregated_errors'*
+Default: 1
+By default, when results from multiple checkers are aggregated in a single
+error list (that is either when |syntastic_aggregate_errors| is enabled, or
+when checking a file with a composite filetype), errors are grouped by file,
+then sorted by line number, then grouped by type (namely errors take precedence
+over warnings), then they are sorted by column number. If you want to leave
+messages grouped by checker output, set this variable to 0. >
+ let g:syntastic_sort_aggregated_errors = 0
+<
+ *'syntastic_echo_current_error'*
+Default: 1
+If enabled, syntastic will echo current error to the command window. If
+multiple errors are found on the same line, |syntastic_cursor_columns| is used
+to decide which one is shown. >
+ let g:syntastic_echo_current_error = 1
+<
+ *'syntastic_cursor_columns'*
+Default: 1
+This option controls which errors are echoed to the command window if
+|syntastic_echo_current_error| is set and multiple errors are found on the same
+line. When the option is enabled, the first error corresponding to the current
+column is show. Otherwise, the first error on the current line is echoed,
+regardless of the cursor position on the current line.
+
+When dealing with very large lists of errors, disabling this option can speed
+up navigation significantly: >
+ let g:syntastic_cursor_column = 0
+<
+ *'syntastic_enable_signs'*
+Default: 1
+Use this option to tell syntastic whether to use the |:sign| interface to mark
+syntax errors: >
+ let g:syntastic_enable_signs = 1
+<
+ *'syntastic_error_symbol'* *'syntastic_style_error_symbol'*
+ *'syntastic_warning_symbol'* *'syntastic_style_warning_symbol'*
+Use this option to control what the syntastic |:sign| text contains. Several
+error symbols can be customized:
+ syntastic_error_symbol - For syntax errors, defaults to '>>'
+ syntastic_style_error_symbol - For style errors, defaults to 'S>'
+ syntastic_warning_symbol - For syntax warnings, defaults to '>>'
+ syntastic_style_warning_symbol - For style warnings, defaults to 'S>'
+
+Example: >
+ let g:syntastic_error_symbol = "✗"
+ let g:syntastic_warning_symbol = "⚠"
+<
+ *'syntastic_enable_balloons'*
+Default: 1
+Use this option to tell syntastic whether to display error messages in balloons
+when the mouse is hovered over erroneous lines: >
+ let g:syntastic_enable_balloons = 1
+<
+Note that Vim must be compiled with |+balloon_eval|.
+
+ *'syntastic_enable_highlighting'*
+Default: 1
+Use this option to tell syntastic whether to use syntax highlighting to mark
+errors (where possible). Highlighting can be turned off with the following >
+ let g:syntastic_enable_highlighting = 0
+<
+ *'syntastic_always_populate_loc_list'*
+Default: 0
+Enable this option to tell syntastic to always stick any detected errors into
+the |location-list|: >
+ let g:syntastic_always_populate_loc_list = 1
+<
+ *'syntastic_auto_jump'*
+Default: 0
+Enable this option if you want the cursor to jump to the first detected issue
+when saving or opening a file.
+
+When set to 0 the cursor won't jump automatically. >
+ let g:syntastic_auto_jump = 0
+<
+When set to 1 the cursor will always jump to the first issue detected,
+regardless of type. >
+ let g:syntastic_auto_jump = 1
+<
+When set to 2 the cursor will jump to the first issue detected, but only if
+this issue is an error. >
+ let g:syntastic_auto_jump = 2
+<
+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. >
+ let g:syntastic_auto_jump = 3
+<
+ *'syntastic_auto_loc_list'*
+Default: 2
+Use this option to tell syntastic to automatically open and/or close the
+|location-list| (see |syntastic-error-window|).
+
+When set to 0 the error window will not be opened or closed automatically. >
+ let g:syntastic_auto_loc_list = 0
+<
+When set to 1 the error window will be automatically opened when errors are
+detected, and closed when none are detected. >
+ let g:syntastic_auto_loc_list = 1
+<
+When set to 2 the error window will be automatically closed when no errors are
+detected, but not opened automatically. >
+ let g:syntastic_auto_loc_list = 2
+<
+ *'syntastic_loc_list_height'*
+Default: 10
+Use this option to specify the height of the location lists that syntastic
+opens. >
+ let g:syntastic_loc_list_height = 5
+<
+ *'syntastic_ignore_files'*
+Default: []
+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
+matched against these patterns, and the matches are case sensitive. Use |\c|
+to specify case insensitive patterns. Example: >
+ let g:syntastic_ignore_files = ['\m^/usr/include/', '\m\c\.h$']
+<
+ *'syntastic_filetype_map'*
+Default: {}
+Use this option to map non-standard filetypes to standard ones. Corresponding
+checkers are mapped accordingly, which allows syntastic to check files with
+non-standard filetypes: >
+ let g:syntastic_filetype_map = {
+ \ "latex": "tex",
+ \ "gentoo-metadata": "xml" }
+<
+Composite filetypes can also be mapped to simple types, which disables the
+default behaviour of running both checkers against the input file: >
+ let g:syntastic_filetype_map = { "handlebars.html": "handlebars" }
+<
+ *'syntastic_mode_map'*
+Default: { "mode": "active",
+ "active_filetypes": [],
+ "passive_filetypes": [] }
+Use this option to fine tune when automatic syntax checking is done (or not
+done).
+
+The option should be set to something like: >
+
+ let g:syntastic_mode_map = {
+ \ "mode": "active",
+ \ "active_filetypes": ["ruby", "php"],
+ \ "passive_filetypes": ["puppet"] }
+<
+"mode" can be mapped to one of two values - "active" or "passive". When set
+to "active", syntastic does automatic checking whenever a buffer is saved or
+initially opened. When set to "passive" syntastic only checks when the user
+calls |:SyntasticCheck|.
+
+The exceptions to these rules are defined with "active_filetypes" and
+"passive_filetypes". In passive mode, automatic checks are still done for
+filetypes in the "active_filetypes" array (and "passive_filetypes" is
+ignored). In active mode, automatic checks are not done for any filetypes in
+the "passive_filetypes" array ("active_filetypes" is ignored).
+
+If any of "mode", "active_filetypes", or "passive_filetypes" are left
+unspecified, they default to values above.
+
+If local variable |'b:syntastic_mode'| is defined its value takes precedence
+over all calculations involving |'syntastic_mode_map'| for the corresponding
+buffer.
+
+At runtime, the |:SyntasticToggleMode| command can be used to switch between
+active and passive modes.
+
+ *'b:syntastic_mode'*
+Default: unset
+Only the local form |'b:syntastic_mode'| is used. When set to either "active"
+or "passive", it takes precedence over |'syntastic_mode_map'| when deciding
+whether the corresponding buffer should be checked automatically.
+
+ *'syntastic_quiet_messages'*
+Default: {}
+Use this option to filter out some of the messages produced by checkers. The
+option should be set to something like: >
+ let g:syntastic_quiet_messages = {
+ \ "!level": "errors",
+ \ "type": "style",
+ \ "regex": '\m\[C03\d\d\]',
+ \ "file:p": ['\m^/usr/include/', '\m\c\.h$'] }
+<
+Each element turns off messages matching the patterns specified by the
+corresponding value. Values are lists, but if a list consist of a single
+element you may omit the brackets (e.g. you may write "style" instead of
+["style"]). Elements with values [] or '' are ignored (this is useful for
+overriding filters, cf. |filter-overrides|).
+
+ "level" - takes one of two values, "warnings" or "errors"
+ "type" - can be either "syntax" or "style"
+ "regex" - is matched against the messages' text as a case insensitive
+ |regular-expression|
+ "file" - is matched against the filenames the messages refer to, as a
+ case sensitive |regular-expression|.
+
+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).
+
+The "file" key may be followed by one or more filename modifiers (see
+|filename-modifiers|). The modifiers are applied to the filenames the messages
+refer to before matching against the value (i.e. in the above example the full
+path of the issues are matched against '\m^/usr/include/' and '\m\c\.h$').
+
+If |'syntastic_id_checkers'| is set, filters are applied before error messages
+are labeled with the names of the checkers that created them.
+
+There are also checker-specific variants of this option, providing finer
+control. They are named |'syntastic___quiet_messages'|.
+
+For a particular checker, if both a |'syntastic_quiet_messages'| filter and
+a checker-specific filter are present, they are both applied (to the list of
+errors produced by the said checker). In case of conflicting values for the
+same keys, the values of the checker-specific filters take precedence.
+
+ *filter-overrides*
+Since filter elements with values [] or '' are ignored, you can disable global
+filters for particular checkers, by setting the values of the corresponding
+elements in |'syntastic___quiet_messages'| to [] or ''. For
+example, the following setting will silence all warnings, except for the
+ones produced by "pylint": >
+ let g:syntastic_quiet_messages = { "level": "warnings" }
+ let g:syntastic_python_pylint_quiet_messages = { "level" : [] }
+<
+ *'syntastic_stl_format'*
+Default: [Syntax: line:%F (%t)]
+Use this option to control what the syntastic statusline text contains. Several
+magic flags are available to insert information:
+ %e - number of errors
+ %w - number of warnings
+ %t - total number of warnings and errors
+ %fe - line number of first error
+ %fw - line number of first warning
+ %F - line number of first warning or error
+
+Several additional flags are available to hide text under certain conditions:
+ %E{...} - hide the text in the brackets unless there are errors
+ %W{...} - hide the text in the brackets unless there are warnings
+ %B{...} - hide the text in the brackets unless there are both warnings AND
+ errors
+These flags can't be nested.
+
+Example: >
+ let g:syntastic_stl_format = '[%E{Err: %fe #%e}%B{, }%W{Warn: %fw #%w}]'
+<
+If this format is used and the current buffer has 5 errors and 1 warning
+starting on lines 20 and 10 respectively then this would appear on the
+statusline: >
+ [Err: 20 #5, Warn: 10 #1]
+<
+If the buffer had 2 warnings, starting on line 5 then this would appear: >
+ [Warn: 5 #2]
+<
+ *'b:syntastic_skip_checks'*
+Default: unset
+Only the local form |'b:syntastic_skip_checks'| is used. When set to a true
+value, no checks are run against the corresponding buffer. Example: >
+ let b:syntastic_skip_checks = 1
+<
+ *'syntastic_full_redraws'*
+Default: 0 in GUI Vim and MacVim, 1 otherwise
+Controls whether syntastic calls |:redraw| or |:redraw!| for screen redraws.
+Changing it can in principle make screen redraws smoother, but it can also
+cause screen to flicker, or cause ghost characters. Leaving it to the default
+should be safe.
+
+ *'syntastic_exit_checks'*
+Default: 0 when running under "cmd.exe" on Windows, 1 otherwise
+Syntastic attempts to catch abnormal termination conditions from checkers by
+looking at their exit codes. The "cmd.exe" shell on Windows make these checks
+meaningless, by returning 1 to Vim when the checkers exit with non-zero codes.
+The above variable can be used to disable exit code checks in syntastic.
+
+ *'syntastic_shell'*
+Default: Vim's 'shell'
+
+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
+file "stdout" and "stderr" redirections ">file" and "2>file". Examples of
+compatible shells are "zsh", "bash", "ksh", and of course the original Bourne
+"sh".
+
+This shell is independent of Vim's 'shell', and it isn't used for interactive
+operations. It must take care to initialize all environment variables needed
+by the checkers you're using. Example: >
+ let g:syntastic_shell = "/bin/sh"
+<
+ *'syntastic_debug'*
+Default: 0
+Set this to the sum of one or more of the following flags to enable
+debugging:
+
+ 1 - trace general workflow
+ 2 - dump location lists
+ 4 - trace notifiers
+ 8 - trace autocommands
+ 16 - dump options
+ 32 - trace running of specific checkers
+
+Example: >
+ let g:syntastic_debug = 1
+<
+Syntastic will then add debugging messages to Vim's |message-history|. You can
+examine these messages with |:mes|.
+
+ *'syntastic_debug_file'*
+Default: unset
+When set, debugging messages are written to the file named by its value, in
+addition to being added to Vim's |message-history|: >
+ let g:syntastic_debug_file = '~/syntastic.log'
+<
+ *'syntastic_extra_filetypes'*
+Default: []
+List of filetypes handled by checkers external to syntastic. If you have a Vim
+plugin that adds a checker for syntastic, and if the said checker deals with a
+filetype that is unknown to syntastic, you might consider adding that filetype
+to this list: >
+ let g:syntastic_extra_filetypes = [ "make", "gitcommit" ]
+<
+This will allow |:SyntasticInfo| to do proper tab completion for the new
+filetypes.
+
+==============================================================================
+5. Checker Options *syntastic-checker-options*
+
+------------------------------------------------------------------------------
+5.1 Choosing which checkers to use *syntastic-filetype-checkers*
+
+ *'g:syntastic__checkers'*
+You can tell syntastic which checkers to run for a given filetype by setting a
+variable 'g:syntastic__checkers' to a list of checkers, e.g. >
+ let g:syntastic_php_checkers = ["php", "phpcs", "phpmd"]
+<
+ *'b:syntastic_checkers'*
+There is also a per-buffer version of this setting, 'b:syntastic_checkers'.
+When set, it takes precedence over |'g:syntastic__checkers'|. You can
+use this in an autocmd to configure specific checkers for particular paths: >
+ autocmd FileType python if stridx(expand("%:p"), "/some/path/") == 0 |
+ \ let b:syntastic_checkers = ["pylint"] | endif
+<
+If neither |'g:syntastic__checkers'| nor |'b:syntastic_checkers'|
+is set, a default list of checker is used. Beware however that this list
+deliberately kept minimal, for performance reasons.
+
+Take a look at the wiki to find out what checkers and filetypes are supported
+by syntastic:
+
+ https://github.com/scrooloose/syntastic/wiki/Syntax-Checkers
+
+Use |:SyntasticInfo| to see which checkers are available for a given filetype.
+
+------------------------------------------------------------------------------
+5.2 Choosing the executable *syntastic-config-exec*
+
+ *'syntastic___exec'*
+The executable run by a checker is normally defined automatically, when the
+checker is registered. You can however override it, by setting the variable
+'g:syntastic___exec': >
+ let g:syntastic_ruby_mri_exec = '~/bin/ruby2'
+<
+This variable has a local version, 'b:syntastic___exec',
+which takes precedence over the global one in the corresponding buffer.
+
+ *'b:syntastic__exec'*
+And there is also a local variable named 'b:syntastic__exec', which
+takes precedence over both 'b:syntastic___exec' and
+'g:syntastic___exec' in the buffers where it is defined.
+
+------------------------------------------------------------------------------
+5.3 Configuring specific checkers *syntastic-config-makeprg*
+
+Most checkers use the 'makeprgBuild()' function and provide many options by
+default - in fact you can customise every part of the command that gets called.
+
+ *'syntastic___