aboutsummaryrefslogtreecommitdiff
path: root/.config/nvim/plugged/nerdtree
diff options
context:
space:
mode:
Diffstat (limited to '.config/nvim/plugged/nerdtree')
-rw-r--r--.config/nvim/plugged/nerdtree/.github/ISSUE_TEMPLATE/bug.md45
-rw-r--r--.config/nvim/plugged/nerdtree/.github/ISSUE_TEMPLATE/feature_request.md8
-rw-r--r--.config/nvim/plugged/nerdtree/.github/ISSUE_TEMPLATE/question.md24
-rw-r--r--.config/nvim/plugged/nerdtree/.github/PULL_REQUEST_TEMPLATE.md16
-rw-r--r--.config/nvim/plugged/nerdtree/.github/workflows/vint.yml15
-rw-r--r--.config/nvim/plugged/nerdtree/.gitignore3
-rw-r--r--.config/nvim/plugged/nerdtree/.vintrc.yaml5
-rw-r--r--.config/nvim/plugged/nerdtree/CHANGELOG.md258
-rw-r--r--.config/nvim/plugged/nerdtree/LICENCE13
-rw-r--r--.config/nvim/plugged/nerdtree/README.markdown157
-rw-r--r--.config/nvim/plugged/nerdtree/_config.yml1
-rw-r--r--.config/nvim/plugged/nerdtree/autoload/nerdtree.vim259
-rw-r--r--.config/nvim/plugged/nerdtree/autoload/nerdtree/ui_glue.vim698
-rw-r--r--.config/nvim/plugged/nerdtree/doc/NERDTree.txt1528
-rw-r--r--.config/nvim/plugged/nerdtree/lib/nerdtree/bookmark.vim365
-rw-r--r--.config/nvim/plugged/nerdtree/lib/nerdtree/creator.vim395
-rw-r--r--.config/nvim/plugged/nerdtree/lib/nerdtree/event.vim13
-rw-r--r--.config/nvim/plugged/nerdtree/lib/nerdtree/flag_set.vim58
-rw-r--r--.config/nvim/plugged/nerdtree/lib/nerdtree/key_map.vim164
-rw-r--r--.config/nvim/plugged/nerdtree/lib/nerdtree/menu_controller.vim211
-rw-r--r--.config/nvim/plugged/nerdtree/lib/nerdtree/menu_item.vim118
-rw-r--r--.config/nvim/plugged/nerdtree/lib/nerdtree/nerdtree.vim215
-rw-r--r--.config/nvim/plugged/nerdtree/lib/nerdtree/notifier.vim35
-rw-r--r--.config/nvim/plugged/nerdtree/lib/nerdtree/opener.vim328
-rw-r--r--.config/nvim/plugged/nerdtree/lib/nerdtree/path.vim897
-rw-r--r--.config/nvim/plugged/nerdtree/lib/nerdtree/tree_dir_node.vim699
-rw-r--r--.config/nvim/plugged/nerdtree/lib/nerdtree/tree_file_node.vim349
-rw-r--r--.config/nvim/plugged/nerdtree/lib/nerdtree/ui.vim529
-rw-r--r--.config/nvim/plugged/nerdtree/nerdtree_plugin/exec_menuitem.vim40
-rw-r--r--.config/nvim/plugged/nerdtree/nerdtree_plugin/fs_menu.vim430
-rw-r--r--.config/nvim/plugged/nerdtree/nerdtree_plugin/vcs.vim47
-rw-r--r--.config/nvim/plugged/nerdtree/plugin/NERD_tree.vim261
-rw-r--r--.config/nvim/plugged/nerdtree/screenshot.pngbin0 -> 87896 bytes
-rw-r--r--.config/nvim/plugged/nerdtree/syntax/nerdtree.vim95
34 files changed, 8279 insertions, 0 deletions
diff --git a/.config/nvim/plugged/nerdtree/.github/ISSUE_TEMPLATE/bug.md b/.config/nvim/plugged/nerdtree/.github/ISSUE_TEMPLATE/bug.md
new file mode 100644
index 0000000..dd35135
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/.github/ISSUE_TEMPLATE/bug.md
@@ -0,0 +1,45 @@
+---
+name: "Bug Report"
+about: "NERDTree is misbehaving? Tell us about it."
+labels: bug
+---
+<!-- Attention! Please Read!
+
+Please fill out ALL the information below so that the issue can be fully
+understood. Omitting information will delay the resolution of your issue. It
+will be labeled "Needs More Info", and may be closed until there is enough
+information.
+
+Keep in mind that others may have the same question in the future. The better
+your information, the more likely they'll be able to help themselves. -->
+
+#### Self-Diagnosis
+<!-- Check the boxes after creating the issue, or use [x]. -->
+- [ ] I have searched the [issues](https://github.com/scrooloose/nerdtree/issues) for an answer to my question.
+- [ ] I have reviewed the NERDTree documentation. `:h NERDTree`
+- [ ] I have reviewed the [Wiki](https://github.com/scrooloose/nerdtree/wiki).
+- [ ] I have searched the web for an answer to my question.
+
+#### Environment (for bug reports)
+- [ ] Operating System:
+- [ ] Vim/Neovim version `:echo v:version`:
+- [ ] NERDTree version, found on 1st line in NERDTree quickhelp `?`:
+- [ ] vimrc settings
+ - [ ] NERDTree variables
+ ```vim
+ ```
+ - Other NERDTree-dependent Plugins
+ - [ ] jistr/vim-nerdtree-tabs
+ - [ ] ryanoasis/vim-devicons
+ - [ ] tiagofumo/vim-nerdtree-syntax-highlight
+ - [ ] Xuyuanp/nerdtree-git-plugin
+ - [ ] Others (specify):
+ - [ ] I've verified the issue occurs with only NERDTree installed.
+
+#### Steps to Reproduce the Issue
+1.
+
+#### Current Result (Include screenshots where appropriate.)
+
+#### Expected Result
+
diff --git a/.config/nvim/plugged/nerdtree/.github/ISSUE_TEMPLATE/feature_request.md b/.config/nvim/plugged/nerdtree/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..35db0f6
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,8 @@
+---
+name: "Feature Request"
+about: "What new feature are you requesting for NERDTree?"
+labels: "feature request"
+---
+
+#### Description
+
diff --git a/.config/nvim/plugged/nerdtree/.github/ISSUE_TEMPLATE/question.md b/.config/nvim/plugged/nerdtree/.github/ISSUE_TEMPLATE/question.md
new file mode 100644
index 0000000..25f15b0
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/.github/ISSUE_TEMPLATE/question.md
@@ -0,0 +1,24 @@
+---
+name: "General Question"
+about: "Having trouble setting up NERDTree? Need clarification on a setting? Ask your question here."
+labels: "general question"
+---
+<!-- Attention! Please Read!
+
+Please fill out ALL the information below so that the issue can be fully
+understood. Omitting information will delay the resolution of your issue. It
+will be labeled "Needs More Info", and may be closed until there is enough
+information.
+
+Keep in mind that others may have the same question in the future. The better
+your information, the more likely they'll be able to help themselves. -->
+
+#### Self-Diagnosis
+<!-- Check the boxes after creating the issue, or use [x]. -->
+- [ ] I have searched the [issues](https://github.com/scrooloose/nerdtree/issues) for an answer to my question.
+- [ ] I have reviewed the NERDTree documentation. `:h NERDTree`
+- [ ] I have reviewed the [Wiki](https://github.com/scrooloose/nerdtree/wiki).
+- [ ] I have searched the web for an answer to my question.
+
+#### State Your Question
+
diff --git a/.config/nvim/plugged/nerdtree/.github/PULL_REQUEST_TEMPLATE.md b/.config/nvim/plugged/nerdtree/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..24dba3f
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,16 @@
+### Description of Changes
+Closes # <!-- Issue number this PR addresses. If none, remove this line. -->
+
+
+---
+### New Version Info
+
+#### Author's Instructions
+- [ ] Derive a new `MAJOR.MINOR.PATCH` version number. Increment the:
+ - `MAJOR` version when you make incompatible API changes
+ - `MINOR` version when you add functionality in a backwards-compatible manner
+ - `PATCH` version when you make backwards-compatible bug fixes
+- [ ] Update [CHANGELOG.md](https://github.com/scrooloose/nerdtree/blob/master/CHANGELOG.md), following the established pattern.
+#### Collaborator's Instructions
+- [ ] Review [CHANGELOG.md](https://github.com/scrooloose/nerdtree/blob/master/CHANGELOG.md), suggesting a different version number if necessary.
+- [ ] After merge, tag the merge commit, e.g. `git tag -a 3.1.4 -m "v3.1.4" && git push origin --tags`
diff --git a/.config/nvim/plugged/nerdtree/.github/workflows/vint.yml b/.config/nvim/plugged/nerdtree/.github/workflows/vint.yml
new file mode 100644
index 0000000..36d7258
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/.github/workflows/vint.yml
@@ -0,0 +1,15 @@
+name: Vint
+on: [push, pull_request]
+jobs:
+ vint:
+ strategy:
+ fail-fast: false
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@master
+ - name: Run vint with reviewdog
+ uses: reviewdog/action-vint@v1.0.1
+ with:
+ github_token: ${{ secrets.github_token }}
+ reporter: github-pr-review
diff --git a/.config/nvim/plugged/nerdtree/.gitignore b/.config/nvim/plugged/nerdtree/.gitignore
new file mode 100644
index 0000000..3698c0e
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/.gitignore
@@ -0,0 +1,3 @@
+*~
+*.swp
+tags
diff --git a/.config/nvim/plugged/nerdtree/.vintrc.yaml b/.config/nvim/plugged/nerdtree/.vintrc.yaml
new file mode 100644
index 0000000..c44b6ab
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/.vintrc.yaml
@@ -0,0 +1,5 @@
+cmdargs:
+ severity: style_problem
+ color: true
+ env:
+ neovim: false
diff --git a/.config/nvim/plugged/nerdtree/CHANGELOG.md b/.config/nvim/plugged/nerdtree/CHANGELOG.md
new file mode 100644
index 0000000..54eef60
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/CHANGELOG.md
@@ -0,0 +1,258 @@
+# NERDTree Change Log
+<!-- Introduce a new MAJOR or MINOR version with a 4-hash header.
+ PATCH versions are listed from newest to oldest under their respective MAJOR.MINOR
+ version in an unordered list. The format is:
+ - **.PATCH**: Pull Request Title (PR Author) [PR Number](Link to PR)
+-->
+#### 6.7
+- **.0**: Open the parent directory when revealing a non-existent file with :NERDTreeFind (bouk) [#1090](https://github.com/preservim/nerdtree/pull/1090)
+#### 6.6
+- **.1**: [add] How to install using dein.vim (kazukazuinaina) [#1087](https://github.com/preservim/nerdtree/pull/1087)
+- **.0**: Add the ability to turn off directory arrows (PhilRunninger) [#1085](https://github.com/preservim/nerdtree/pull/1085)
+#### 6.5
+- **.0**: `NERDTreeToggle <start-directory>` always sets NERDTree root. (PhilRunninger) [#1083](https://github.com/preservim/nerdtree/pull/1083)
+#### 6.4
+- **.6**: NERDTreeFind shows expected message if file doesn't exist e.g. with vim-startify (andys8). [#1081](https://github.com/preservim/nerdtree/pull/1081)
+- **.5**: Ensure events are (or aren't) being ignored correctly. (PhilRunninger) [#1080](https://github.com/preservim/nerdtree/pull/1080)
+- **.4**: Prevent overwriting existing files/dirs on node move. (PhilRunninger) [#1079](https://github.com/preservim/nerdtree/pull/1079)
+- **.3**: Fix regex that finds keyword for minimal menu. (PhilRunninger) [#1075](https://github.com/preservim/nerdtree/pull/1075)
+- **.2**: Lint vimscript, fix errors and warnings, add CI job to review PRs (Caleb Maclennan) [#1071](https://github.com/preservim/nerdtree/pull/1071)
+- **.1**: Ensure backward compatibility. v:t_func is not available before Vim 8.0 (Phil Runninger)
+- **.0**: Allow use of function references as callbacks (HiPhish) [#1067](https://github.com/preservim/nerdtree/pull/1067)
+#### 6.3
+- **.0**: Add new command that behaves like NERDTreeToggle but defaults to the root of a VCS repository. (willfindlay) [#1060](https://github.com/preservim/nerdtree/pull/1060)
+#### 6.2
+- **.1**: Menu option, 'copy path to clipboard' is aware of VIM clipboard option (jhzn) [#1056](https://github.com/preservim/nerdtree/pull/1056)
+- **.0**: Support tab-specific CWDs (PhilRunninger) [#1032](https://github.com/preservim/nerdtree/pull/1032)
+#### 6.1
+- **.4**: Add VIM built-in package management to read me file. (pesarkhobeee) [#1049](https://github.com/preservim/nerdtree/pull/1049)
+- **.3**: Save/Set screen state also on WinLeave and WinEnter. (PhilRunninger) [#1048](https://github.com/preservim/nerdtree/pull/1048)
+- **.2**: Wrap saveScreenState's statements in a try-catch block. (PhilRunninger) [#1047](https://github.com/preservim/nerdtree/pull/1047)
+- **.1**: Catch errors when trying to read CHANGELOG.md. (PhilRunninger) [#1045](https://github.com/preservim/nerdtree/pull/1045)
+- **.0**: If file path doesn't exist, :NERDTreeFind its parent directory instead. (PhilRunninger) [#1043](https://github.com/preservim/nerdtree/pull/1043)
+#### 6.0
+- **.1**: Reintroduce necessary variable mistakenly removed. (PhilRunninger) [#1040](https://github.com/preservim/nerdtree/pull/1040)
+- **.0**: Make the behavior of window splits consistent (dragonxlwang, PhilRunninger) [#1035](https://github.com/preservim/nerdtree/pull/1035)
+#### 5.3
+- **.3**: Fix (p)ath not displaying in the minimal menu (tuzz) [#1038](https://github.com/preservim/nerdtree/pull/1038)
+- **.2**: Enable events when closing NerdTree window. (PhilRunninger) [#1037](https://github.com/preservim/nerdtree/pull/1037)
+- **.1**: Fix the `e` key mapping to use netrw if desired (PhilRunninger) [#1031](https://github.com/preservim/nerdtree/pull/1031)
+- **.0**: Add file extension and size to sorting capabilities (PhilRunninger) [#1029](https://github.com/preservim/nerdtree/pull/1029)
+#### 5.2
+- **.9**: Suppress events for intermediate window/tab/buffer changes (PhilRunninger) [#1026](https://github.com/preservim/nerdtree/pull/1026)
+- **.8**: Revert [#1019](https://github.com/preservim/nerdtree/pull/1019) to fix nvim artifacts and flickering. (PhilRunninger) [#1021](https://github.com/preservim/nerdtree/pull/1021)
+- **.7**: Use :mode only in neovim. MacVim still needs to use :redraw! (PhilRunninger) [#1019](https://github.com/preservim/nerdtree/pull/1019)
+- **.6**: In CHANGELOG.md and PR template, make reference to PR a true HTML link. (PhilRunninger) [#1017](https://github.com/preservim/nerdtree/pull/1017)
+- **.5**: Use `:mode` instead of `:redraw!` when updating menu. (PhilRunninger) [#1016](https://github.com/preservim/nerdtree/pull/1016)
+- **.4**: When searching for root line num, stop at end of file. (PhilRunninger) [#1015](https://github.com/preservim/nerdtree/pull/1015)
+- **.3**: Fix `<CR>` key map on the bookmark (lkebin) [#1014](https://github.com/preservim/nerdtree/pull/1014)
+- **.2**: Make Enter work on the `.. ( up a dir )` line (PhilRunninger) [#1013](https://github.com/preservim/nerdtree/pull/1013)
+- **.1**: Fix nerdtree#version() on Windows. (PhilRunninger)
+- **.0**: Expand functionality of `<CR>` mapping. (PhilRunninger) [#1011](https://github.com/preservim/nerdtree/pull/1011)
+#### 5.1
+- **.3**: Remove @mentions from PR template and change log. They weren't working. (PhilRunninger) [#1009](https://github.com/preservim/nerdtree/pull/1009)
+- **.2**: Fix NERDTree opening with the wrong size. (PhilRunninger) [#1008](https://github.com/preservim/nerdtree/pull/1008)
+- **.1**: Update Changelog and create PR Template (PhilRunninger) [#1007](https://github.com/preservim/nerdtree/pull/1007)
+- **.0**: Too many changes for one patch...
+ - Refresh a dir_node if the file wasn't found in it, and look once more. (PhilRunninger) [#1005](https://github.com/preservim/nerdtree/pull/1005)
+ - Add a "copy path to clipboard" menu option (PhilRunninger) [#1002](https://github.com/preservim/nerdtree/pull/1002)
+ - Enable root refresh on "vim ." a different way than [#999](https://github.com/preservim/nerdtree/pull/999). (PhilRunninger) [#1001](https://github.com/preservim/nerdtree/pull/1001)
+ - Fix refreshroot (PhilRunninger) [#999](https://github.com/preservim/nerdtree/pull/999)
+ - Change version check to look for 703 not 730 (vhalis) [#994](https://github.com/preservim/nerdtree/pull/994)
+ - Change minimum vim (PhilRunninger) [#991](https://github.com/preservim/nerdtree/pull/991)
+ - Allow multi-character DirArrows (PhilRunninger) [#985](https://github.com/preservim/nerdtree/pull/985)
+ - Remove redraw! while still clearing last message empty string. (PhilRunninger) [#979](https://github.com/preservim/nerdtree/pull/979)
+ - fix `_initChildren` function value set to numChildrenCached error (terryding77) [#969](https://github.com/preservim/nerdtree/pull/969)
+ - On Windows, do a case-insensitive comparison of paths. (PhilRunninger) [#967](https://github.com/preservim/nerdtree/pull/967)
+ - Remove the **Please wait... DONE** messages. (PhilRunninger) [#966](https://github.com/preservim/nerdtree/pull/966)
+ - Smarter delimiter default (PhilRunninger) [#963](https://github.com/preservim/nerdtree/pull/963)
+ - Update directory .vimdc readme example (spencerdcarlson) [#961](https://github.com/preservim/nerdtree/pull/961)
+ - Preview bookmarks (PhilRunninger) [#956](https://github.com/preservim/nerdtree/pull/956)
+ - Add new value to NERDTreeQuitOnOpen to close bookmark table (PhilRunninger) [#955](https://github.com/preservim/nerdtree/pull/955)
+ - Add an :EditBookmarks command to edit the bookmarks file (PhilRunninger) [#954](https://github.com/preservim/nerdtree/pull/954)
+ - Before copying, turn off &shellslash. Restore after copy is finished. (PhilRunninger) [#952](https://github.com/preservim/nerdtree/pull/952)
+ - Set a maximum window size when zooming. (PhilRunninger) [#950](https://github.com/preservim/nerdtree/pull/950)
+ - Confirm the wipeout of a unsaved buffer whose file has been renamed. (PhilRunninger) [#949](https://github.com/preservim/nerdtree/pull/949)
+ - Escape a backslash so it can be used in a key mapping. (PhilRunninger) [#948](https://github.com/preservim/nerdtree/pull/948)
+ - Add a NERDTreeMinimalMenu feature (tuzz) [#938](https://github.com/preservim/nerdtree/pull/938)
+ - fixed root path error for windows (zcodes) [#935](https://github.com/preservim/nerdtree/pull/935)
+ - Restore getDirChildren for use in nerdtree-project-plugin. (PhilRunninger) [#929](https://github.com/preservim/nerdtree/pull/929)
+ - Document NERDTreeNodeDelimiter [#912](https://github.com/preservim/nerdtree/pull/912) (PhilRunninger) [#926](https://github.com/preservim/nerdtree/pull/926)
+ - Allow modification of menu keybindings (Leandros) [#923](https://github.com/preservim/nerdtree/pull/923)
+ - Add two more disqualifications for isCascadable(). (PhilRunninger) [#914](https://github.com/preservim/nerdtree/pull/914)
+ - Allow highlighting more than one flag. (kristijanhusak) [#908](https://github.com/preservim/nerdtree/pull/908)
+ - Support sorting files and directories by modification time. (PhilRunninger) [#901](https://github.com/preservim/nerdtree/pull/901)
+ - Parse . and .. from path string with trailing slash. (PhilRunninger) [#899](https://github.com/preservim/nerdtree/pull/899)
+ - Force sort to recalculate the cached sortKey. (PhilRunninger) [#898](https://github.com/preservim/nerdtree/pull/898)
+ - Add NERDTreeRefreshRoot command (wgfm) [#897](https://github.com/preservim/nerdtree/pull/897)
+ - Call Resolve on the file's path when calling :NERDTreeFind. (PhilRunninger) [#896](https://github.com/preservim/nerdtree/pull/896)
+ - Catch all errors, not just NERDTree errors. (PhilRunninger) [#894](https://github.com/preservim/nerdtree/pull/894)
+ - Fix typo in help file (lvoisin) [#892](https://github.com/preservim/nerdtree/pull/892)
+ - Make NERDTreeCreator set the `'nolist'` option (lifecrisis) [#889](https://github.com/preservim/nerdtree/pull/889)
+ - Refresh buffers after `m`, `m` operation on a folder (PhilRunninger) [#888](https://github.com/preservim/nerdtree/pull/888)
+ - Use a better arg for FINDSTR when using the m,l command in Windows. (PhilRunninger) [#887](https://github.com/preservim/nerdtree/pull/887)
+ - Fix the <C-J>/<C-K> motions, which currently fail with cascades (lifecrisis) [#886](https://github.com/preservim/nerdtree/pull/886)
+ - Function "s:UI.getLineNum()" doesn't always work on cascades. (lifecrisis) [#882](https://github.com/preservim/nerdtree/pull/882)
+ - NERDTreeCWD: reset CWD if changed by NERDTreeFocus (PhilRunninger) [#878](https://github.com/preservim/nerdtree/pull/878)
+ - Use <count>tabnext instead of <count>gt to allow users to remap gt. (PhilRunninger) [#877](https://github.com/preservim/nerdtree/pull/877)
+ - Do a case sensitive comparison of new/existing buffers. (PhilRunninger) [#875](https://github.com/preservim/nerdtree/pull/875)
+ - Fix opening sub-directories that have commas in their name. (PhilRunninger) [#873](https://github.com/preservim/nerdtree/pull/873)
+ - Add new command to open NERDTree in the root of a VCS repository. (PhilRunninger) [#872](https://github.com/preservim/nerdtree/pull/872)
+ - Make sure the path to the bookmarks file exists before writing it. (PhilRunninger) [#871](https://github.com/preservim/nerdtree/pull/871)
+ - Unzoom NERDTree when opening a file (PhilRunninger) [#870](https://github.com/preservim/nerdtree/pull/870)
+ - Support unusual characters in file and directory names (PhilRunninger) [#868](https://github.com/preservim/nerdtree/pull/868)
+ - Reword renamed-buffer prompt to be more clear (aflock) [#867](https://github.com/preservim/nerdtree/pull/867)
+ - Default to placing cursor on root when closing bookmark table (lifecrisis) [#866](https://github.com/preservim/nerdtree/pull/866)
+ - Fix issues with sorting of nodes (PhilRunninger) [#856](https://github.com/preservim/nerdtree/pull/856)
+ - Better OSX detection (bubba-h57) [#853](https://github.com/preservim/nerdtree/pull/853)
+ - Bugfix - ensure keymaps dictionary exists before using it (mnussbaum) [#852](https://github.com/preservim/nerdtree/pull/852)
+ - Decrease startup-time by avoiding linear-time iteration over key mappings (mnussbaum) [#851](https://github.com/preservim/nerdtree/pull/851)
+ - Add code to sort mappings in quickhelp (lifecrisis) [#849](https://github.com/preservim/nerdtree/pull/849)
+ - Use ":clearjumps" in new NERDTree windows (lifecrisis) [#844](https://github.com/preservim/nerdtree/pull/844)
+ - Like m-c did before, create parent directories if needed on m-m. (PhilRunninger) [#840](https://github.com/preservim/nerdtree/pull/840)
+ - BUGFIX: Repair a problem with the `'u'` mapping. (lifecrisis) [#838](https://github.com/preservim/nerdtree/pull/838)
+ - Make the NERDTree buffer writable when rendering it. (PhilRunninger) [#837](https://github.com/preservim/nerdtree/pull/837)
+ - Code cleanup: Remove unsupported bookmark table mappings (lifecrisis) [#835](https://github.com/preservim/nerdtree/pull/835)
+ - Replace strcharpart() with substitute() for backward compatibility (bravestarr) [#834](https://github.com/preservim/nerdtree/pull/834)
+ - Fixed error `unknown function strcharpart` for older versions of Vim (hav4ik) [#833](https://github.com/preservim/nerdtree/pull/833)
+ - Clear output when NERDTree menu is aborted (lifecrisis) [#832](https://github.com/preservim/nerdtree/pull/832)
+ - Display a path with multi-byte characters correctly when it is truncated (bravestarr) [#830](https://github.com/preservim/nerdtree/pull/830)
+ - Support revealing file and executing file with xdg-open for Linux (ngnmhieu) [#824](https://github.com/preservim/nerdtree/pull/824)
+ - If node isn't open, count children on disk before deleting. (PhilRunninger) [#822](https://github.com/preservim/nerdtree/pull/822)
+ - Add new variable g:NERDTreeRemoveFileCmd (kutsan) [#816](https://github.com/preservim/nerdtree/pull/816)
+ - Use a better check for existence of the NERDTree buffer. (PhilRunninger) [#814](https://github.com/preservim/nerdtree/pull/814)
+ - Fix focussing previous buffer when closing NERDTree (mrubli) [#801](https://github.com/preservim/nerdtree/pull/801)
+ - Update the docs for "NERDTreeStatusline" (lifecrisis) [#796](https://github.com/preservim/nerdtree/pull/796)
+ - BUGFIX: Unstable behavior in the "getPath()" method (lifecrisis) [#795](https://github.com/preservim/nerdtree/pull/795)
+ - Revert the bugfix from pull request [#785](https://github.com/preservim/nerdtree/pull/785) (lifecrisis) [#794](https://github.com/preservim/nerdtree/pull/794)
+ - BUGFIX: Allow ":NERDTreeFind" to discover hidden files (lifecrisis) [#786](https://github.com/preservim/nerdtree/pull/786)
+ - BUGFIX: Allow ":NERDTreeFind" to reveal new files (lifecrisis) [#785](https://github.com/preservim/nerdtree/pull/785)
+ - Add modelines (lifecrisis) [#782](https://github.com/preservim/nerdtree/pull/782)
+ - Change the type of completion used by NERDTreeFind (lifecrisis) [#781](https://github.com/preservim/nerdtree/pull/781)
+ - change NERDTreeFind with args (zhenyangze) [#778](https://github.com/preservim/nerdtree/pull/778)
+ - Style Choice: Using confirm() when deleting a bookmark (lifecrisis) [#777](https://github.com/preservim/nerdtree/pull/777)
+ - remove useless substitute when `file =~# "/$"` (skyblueee) [#773](https://github.com/preservim/nerdtree/pull/773)
+ - remove useless removeLeadingSpaces in _stripMarkup (skyblueee) [#772](https://github.com/preservim/nerdtree/pull/772)
+ - Make the "o" mapping consistent with "x" (lifecrisis) [#769](https://github.com/preservim/nerdtree/pull/769)
+ - Fix a problem with the "x" handler (lifecrisis) [#768](https://github.com/preservim/nerdtree/pull/768)
+ - Clean up the handler for the "x" mapping (lifecrisis) [#767](https://github.com/preservim/nerdtree/pull/767)
+ - Revert change to tab opening method (lifecrisis) [#766](https://github.com/preservim/nerdtree/pull/766)
+ - BUGFIX: Add back support for "b:NERDTreeRoot" (lifecrisis) [#765](https://github.com/preservim/nerdtree/pull/765)
+ - Fix broken "t" and "T" mappings, tabs now open at end (lifecrisis) [#759](https://github.com/preservim/nerdtree/pull/759)
+ - Update doc with already existing mapping variables (asnr) [#699](https://github.com/preservim/nerdtree/pull/699)
+ - Fix the broken g:NERDTreeBookmarksSort setting (lifecrisis) [#696](https://github.com/preservim/nerdtree/pull/696)
+ - Correct NERDTreeIgnore pattern in doc (cntoplolicon) [#648](https://github.com/preservim/nerdtree/pull/648)
+ - Remove empty segments when splitting path (sooth-sayer) [#574](https://github.com/preservim/nerdtree/pull/574)
+ - Suppress autocmds less agressively (wincent) [#578](https://github.com/preservim/nerdtree/pull/578) [#691](https://github.com/preservim/nerdtree/pull/691)
+ - Add an Issues template to ask for more info initially.
+ - Fix markdown headers in readme (josephfrazier) [#676](https://github.com/preservim/nerdtree/pull/676)
+ - Don't touch `@o` and `@h` registers when rendering
+ - Fix bug with files and directories with dollar signs (alegen) [#649](https://github.com/preservim/nerdtree/pull/649)
+ - Reuse/reopen existing window trees where possible [#244](https://github.com/preservim/nerdtree/pull/244)
+ - Remove NERDTree.previousBuf()
+ - Change color of arrow (Leeiio) [#630](https://github.com/preservim/nerdtree/pull/630)
+ - Improved a tip in README.markdown (ggicci) [#628](https://github.com/preservim/nerdtree/pull/628)
+ - Shorten delete confimration of empty directory to `y` (mikeperri) [#530](https://github.com/preservim/nerdtree/pull/530)
+ - Fix API call to open directory tree in window (devm33) [#533](https://github.com/preservim/nerdtree/pull/533)
+ - Change default arrows on non-Windows platforms (gwilk) [#546](https://github.com/preservim/nerdtree/pull/546)
+ - Update to README - combine cd and git clone (zwhitchcox) [#584](https://github.com/preservim/nerdtree/pull/584)
+ - Update to README - Tip: start NERDTree when vim starts (therealplato) [#593](https://github.com/preservim/nerdtree/pull/593)
+ - Escape filename when moving an open buffer (zacharyvoase) [#595](https://github.com/preservim/nerdtree/pull/595)
+ - Fixed incorrect :helptags command in README (curran) [#619](https://github.com/preservim/nerdtree/pull/619)
+ - Fixed incomplete escaping of folder arrows (adityanatraj) [#548](https://github.com/preservim/nerdtree/pull/548)
+ - Added NERDTreeCascadeSingleChildDir option (juanibiapina) [#558](https://github.com/preservim/nerdtree/pull/558)
+ - Replace strchars() with backward compatible workaround.
+ - Add support for copy command in Windows (SkylerLipthay) [#231](https://github.com/preservim/nerdtree/pull/231)
+ - Fixed typo in README.markdown - :Helptags -> :helptags
+ - Rename "primary" and "secondary" trees to "tab" and "window" trees.
+ - Move a bunch of buffer level variables into the NERDTree and UI classes.
+ - Display cascading dirs on one line to save vertical/horizontal space (matt-gardner: brainstorming/testing)
+ - Remove the old style UI - Remove `NERDTreeDirArrows` option.
+ - On windows default to + and ~ for expand/collapse directory symbols.
+ - Lots more refactoring. Move a bunch of b: level vars into b:NERDTree and friends.
+
+#### 5.0.0
+- Refactor the code significantly:
+ * Break the classes out into their own files.
+ * Make the majority of the code OO - previously large parts were effectively a tangle of "global" methods.
+- Add an API to assign flags to nodes. This allows VCS plugins like https://github.com/Xuyuanp/nerdtree-git-plugin to exist. Thanks to **Xuyuanp** for helping design/test/build said API.
+- add `scope` argument to the key map API see :help NERDTreeAddKeyMap()
+- add magic [[dir]] and [[file]] flags to NERDTreeIgnore
+- add support for custom path filters. See :help NERDTreeAddPathFilter()
+- add path listener API. See :help NERDTreePathListenerAPI.
+- expand the fs menu functionality to list file properties (PhilRunninger, apbarrero, JESii)
+- make bookmarks work with `~` home shortcuts (hiberabyss)
+- show OSX specific fsmenu options in regular vim on mac (evindor)
+- make dir arrow icons configurable (PickRelated)
+- optimise node sorting performance when opening large dirs (vtsang)
+- make the root note render prettier by truncating it at a path slash (gcmt)
+- remove NERDChristmasTree option - its always christmas now
+- add "cascade" open and closing for dirs containing only another single dir. See :help NERDTreeCascadeOpenSingleChildDir (pendulm)
+- Many other fixes, doc updates and contributions from: **actionshrimp**, **agrussellknives**, **alvan**, **AndrewRadev**, **cperl82** (*many small fixes*), **devmanhinton**, **egalpin**, **franksort**, **gastropoda**, **handcraftedbits**, **kelaban**, **lucascaton**, **mixvin**, **pendulm**, **SchDen**, **shanesmith**, **staeff**, **stephenprater**, **toiffel**, **Twinside**, **WoLpH**, **xiaodili**, **zhangoose**
+
+#### 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 from: **AndrewRadev**, **Bogdanov**, **camthompson**, **kml**, **mathias**, **paddyoloughlin**, **scottstvnsn**, **sdewald**, **Vitaly**, **wycats**, me RAWR!
+
+#### 4.1.0
+- features:
+ - NERDTreeFind to reveal the node for the current buffer in the tree, see `|NERDTreeFind|`. This effectively merges the FindInNERDTree plugin (by **Doug McInnes**) into the script.
+ - make NERDTreeQuitOnOpen apply to the t/T keymaps too. Thanks to **Stefan Ritter** and **Rémi Prévost**.
+ - truncate the root node if wider than the tree window. Thanks to **Victor Gonzalez**.
+
+- bugfixes:
+ - really fix window state restoring
+ - fix some win32 path escaping issues. Thanks to **Stephan Baumeister**, **Ricky**, **jfilip1024**, and **Chris Chambers**.
+
+#### 4.0.0
+- add a new programmable menu system (see `:help NERDTreeMenu`).
+- add new APIs to add menus/menu-items to the menu system as well as custom key mappings to the NERD tree buffer (see `:help NERDTreeAPI`).
+- removed the old API functions
+- added a mapping to maximize/restore the size of nerd tree window, thanks to Guillaume Duranceau for the patch. See :help NERDTree-A for details.
+- fix a bug where secondary nerd trees (netrw hijacked trees) and NERDTreeQuitOnOpen didnt play nicely, thanks to **Curtis Harvey**.
+- fix a bug where the script ignored directories whose name ended in a dot, thanks to **Aggelos Orfanakos** for the patch.
+- fix a bug when using the x mapping on the tree root, thanks to **Bryan Venteicher** for the patch.
+- fix a bug where the cursor position/window size of the nerd tree buffer wasnt being stored on closing the window, thanks to **Richard Hart**.
+- fix a bug where NERDTreeMirror would mirror the wrong tree
+
+#### 3.1.1
+- fix a bug where a non-listed no-name buffer was getting created every time the tree windows was created, thanks to **Derek Wyatt** and **owen1**
+- make `<CR>` behave the same as the `o` mapping
+- some helptag fixes in the doc, thanks **strull**.
+- fix a bug when using `:set nohidden` and opening a file where the previous buf was modified. Thanks **iElectric**.
+- other minor fixes
+
+#### 3.1.0
+- New features:
+ - add mappings to open files in a vsplit, see `:help NERDTree-s` and `:help NERDTree-gs`
+ - make the statusline for the nerd tree window default to something hopefully more useful. See `:help 'NERDTreeStatusline'`
+- Bugfixes:
+ - make the hijack netrw functionality work when vim is started with `vim <some dir>` (thanks to **Alf Mikula** for the patch).
+ - fix a bug where the CWD wasnt being changed for some operations even when NERDTreeChDirMode==2 (thanks to **Lucas S. Buchala**)
+ - add -bar to all the nerd tree :commands so they can chain with other :commands (thanks to **tpope**)
+ - fix bugs when ignorecase was set (thanks to **nach**)
+ - fix a bug with the relative path code (thanks to **nach**)
+ - fix a bug where doing a `:cd` would cause `:NERDTreeToggle` to fail (thanks **nach**)
+
+
+#### 3.0.1
+- Bugfixes:
+ - fix bugs with :NERDTreeToggle and :NERDTreeMirror when `'hidden'` was not set
+ - fix a bug where `:NERDTree <path>` would fail if `<path>` was relative and didnt start with a `./` or `../` Thanks to **James Kanze**.
+ - make the `q` mapping work with secondary (`:e <dir>` style) trees, thanks to **jamessan**
+ - fix a bunch of small bugs with secondary trees
+- More insane refactoring.
+
+#### 3.0.0
+- hijack netrw so that doing an `:edit <directory>` will put a NERD tree in the window rather than a netrw browser. See :help 'NERDTreeHijackNetrw'
+- allow sharing of trees across tabs, see `:help :NERDTreeMirror`
+- remove "top" and "bottom" as valid settings for NERDTreeWinPos
+- change the `'<tab>'` mapping to `'i'`
+- change the `'H'` mapping to `'I'`
+- lots of refactoring
diff --git a/.config/nvim/plugged/nerdtree/LICENCE b/.config/nvim/plugged/nerdtree/LICENCE
new file mode 100644
index 0000000..8b1a9d8
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/LICENCE
@@ -0,0 +1,13 @@
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
+
+Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
+
+Everyone is permitted to copy and distribute verbatim or modified
+copies of this license document, and changing it is allowed as long
+as the name is changed.
+
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
diff --git a/.config/nvim/plugged/nerdtree/README.markdown b/.config/nvim/plugged/nerdtree/README.markdown
new file mode 100644
index 0000000..09173a6
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/README.markdown
@@ -0,0 +1,157 @@
+The NERDTree [![Vint](https://github.com/preservim/nerdtree/workflows/Vint/badge.svg)](https://github.com/preservim/nerdtree/actions?workflow=Vint)
+=============
+
+Introduction
+------------
+
+The NERDTree is a file system explorer for the Vim editor. Using this plugin,
+users can visually browse complex directory hierarchies, quickly open files for
+reading or editing, and perform basic file system operations.
+
+This plugin can also be extended with custom mappings using a special API. The
+details of this API and of other NERDTree features are described in the
+included documentation.
+
+![NERDTree Screenshot](https://github.com/preservim/nerdtree/raw/master/screenshot.png)
+
+Installation
+------------
+
+Below are just some of the methods for installing NERDTree. Do not follow all of these instructions; just pick your favorite one. Other plugin managers exist, and NERDTree should install just fine with any of them.
+
+#### Vim 8+ packages
+
+If you are using VIM version 8 or higher you can use its built-in package management; see `:help packages` for more information. Just run these commands in your terminal:
+
+```bash
+git clone https://github.com/preservim/nerdtree.git ~/.vim/pack/vendor/start/nerdtree
+vim -u NONE -c "helptags ~/.vim/pack/vendor/start/nerdtree/doc" -c q
+```
+
+Otherwise, these are some of the several 3rd-party plugin managers you can choose from. Be sure you read the instructions for your chosen plugin, as there typically are additional steps you nee d to take.
+
+#### [pathogen.vim](https://github.com/tpope/vim-pathogen)
+
+In the terminal,
+```bash
+git clone https://github.com/preservim/nerdtree.git ~/.vim/bundle/nerdtree
+```
+In your vimrc,
+```vim
+call pathogen#infect()
+syntax on
+filetype plugin indent on
+```
+
+Then reload vim, run `:helptags ~/.vim/bundle/nerdtree/doc/` or `:Helptags`.
+
+#### [Vundle.vim](https://github.com/VundleVim/Vundle.vim)
+```vim
+call vundle#begin()
+Plugin 'preservim/nerdtree'
+call vundle#end()
+```
+
+#### [vim-plug](https://github.com/junegunn/vim-plug)
+```vim
+call plug#begin()
+Plug 'preservim/nerdtree'
+call plug#end()
+```
+
+#### [dein.vim](https://github.com/Shougo/dein.vim)
+```vim
+call dein#begin()
+call dein#add('preservim/nerdtree')
+call dein#end()
+```
+
+#### [apt-vim](https://github.com/egalpin/apt-vim)
+```bash
+apt-vim install -y https://github.com/preservim/nerdtree.git
+```
+
+F.A.Q. (here, and in the [Wiki](https://github.com/preservim/nerdtree/wiki))
+------
+
+#### 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:
+```vim
+autocmd StdinReadPre * let s:std_in=1
+autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
+```
+
+Note: Now start vim with plain `vim`, not `vim .`
+
+---
+#### What if I'm also opening a saved session, for example `vim -S session_file.vim`? I don't want NERDTree to open in that scenario.
+```vim
+autocmd StdinReadPre * let s:std_in=1
+autocmd VimEnter * if argc() == 0 && !exists("s:std_in") && v:this_session == "" | NERDTree | endif
+```
+
+---
+#### How can I open NERDTree automatically when vim starts up on opening a directory?
+```vim
+autocmd StdinReadPre * let s:std_in=1
+autocmd VimEnter * if argc() == 1 && isdirectory(argv()[0]) && !exists("s:std_in") | exe 'NERDTree' argv()[0] | wincmd p | ene | exe 'cd '.argv()[0] | endif
+```
+
+This window is tab-specific, meaning it's used by all windows in the tab. This trick also prevents NERDTree from hiding when first selecting a file.
+
+Note: Executing `vim ~/some-directory` will open NERDTree and a new edit window. `exe 'cd '.argv()[0]` sets the `pwd` of the new edit window to `~/some-directory`
+
+---
+#### 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):
+```vim
+map <C-n> :NERDTreeToggle<CR>
+```
+
+---
+#### How can I close vim if the only window left open is a NERDTree?
+
+Stick this in your vimrc:
+```vim
+autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
+```
+
+---
+#### Can I have different highlighting for different file extensions?
+
+See here: https://github.com/preservim/nerdtree/issues/433#issuecomment-92590696
+
+---
+#### How can I change default arrows?
+
+Use these variables in your vimrc. Note that below are default arrow symbols
+```vim
+let g:NERDTreeDirArrowExpandable = '▸'
+let g:NERDTreeDirArrowCollapsible = '▾'
+```
+You can remove the arrows altogether by setting these variables to empty strings, as shown below. This will remove not only the arrows, but a single space following them, shifting the whole tree two character positions to the left.
+```vim
+let g:NERDTreeDirArrowExpandable = ''
+let g:NERDTreeDirArrowCollapsible = ''
+```
diff --git a/.config/nvim/plugged/nerdtree/_config.yml b/.config/nvim/plugged/nerdtree/_config.yml
new file mode 100644
index 0000000..c419263
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-cayman \ No newline at end of file
diff --git a/.config/nvim/plugged/nerdtree/autoload/nerdtree.vim b/.config/nvim/plugged/nerdtree/autoload/nerdtree.vim
new file mode 100644
index 0000000..156b260
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/autoload/nerdtree.vim
@@ -0,0 +1,259 @@
+if exists('g:loaded_nerdtree_autoload')
+ finish
+endif
+let g:loaded_nerdtree_autoload = 1
+
+let s:rootNERDTreePath = resolve(expand('<sfile>:p:h:h'))
+
+"FUNCTION: nerdtree#version(...) {{{1
+" If any value is given as an argument, the entire line of text from the
+" change log is shown for the current version; otherwise, only the version
+" number is shown.
+function! nerdtree#version(...) abort
+ let l:text = 'Unknown'
+ try
+ let l:changelog = readfile(join([s:rootNERDTreePath, 'CHANGELOG.md'], nerdtree#slash()))
+ let l:line = 0
+ while l:line <= len(l:changelog)
+ if l:changelog[l:line] =~# '\d\+\.\d\+'
+ let l:text = substitute(l:changelog[l:line], '.*\(\d\+.\d\+\).*', '\1', '')
+ let l:text .= substitute(l:changelog[l:line+1], '^.\{-}\(\.\d\+\).\{-}:\(.*\)', a:0>0 ? '\1:\2' : '\1', '')
+ break
+ endif
+ let l:line += 1
+ endwhile
+ catch
+ endtry
+ return l:text
+endfunction
+
+" SECTION: General Functions {{{1
+"============================================================
+
+"FUNCTION: nerdtree#slash() {{{2
+function! nerdtree#slash() abort
+
+ if nerdtree#runningWindows()
+ if exists('+shellslash') && &shellslash
+ return '/'
+ endif
+
+ return '\'
+ endif
+
+ return '/'
+endfunction
+
+"FUNCTION: nerdtree#and(x,y) {{{2
+" Implements and() function for Vim <= 7.2
+function! nerdtree#and(x,y) abort
+ if exists('*and')
+ return and(a:x, a:y)
+ else
+ let l:x = a:x
+ let l:y = a:y
+ let l:n = 0
+ let l:result = 0
+ while l:x > 0 && l:y > 0
+ if (l:x % 2) && (l:y % 2)
+ let l:result += float2nr(pow(2, l:n))
+ endif
+ let l:x = float2nr(l:x / 2)
+ let l:y = float2nr(l:y / 2)
+ let l:n += 1
+ endwhile
+ return l:result
+ endif
+endfunction
+
+"FUNCTION: nerdtree#checkForBrowse(dir) {{{2
+"inits a window tree in the current buffer if appropriate
+function! nerdtree#checkForBrowse(dir) abort
+ if !isdirectory(a:dir)
+ return
+ endif
+
+ if s:reuseWin(a:dir)
+ return
+ endif
+
+ call g:NERDTreeCreator.CreateWindowTree(a:dir)
+endfunction
+
+"FUNCTION: s:reuseWin(dir) {{{2
+"finds a NERDTree buffer with root of dir, and opens it.
+function! s:reuseWin(dir) abort
+ let path = g:NERDTreePath.New(fnamemodify(a:dir, ':p'))
+
+ for i in range(1, bufnr('$'))
+ unlet! nt
+ let nt = getbufvar(i, 'NERDTree')
+ if empty(nt)
+ continue
+ endif
+
+ if nt.isWinTree() && nt.root.path.equals(path)
+ call nt.setPreviousBuf(bufnr('#'))
+ exec 'buffer ' . i
+ return 1
+ endif
+ endfor
+
+ return 0
+endfunction
+
+" FUNCTION: nerdtree#completeBookmarks(A,L,P) {{{2
+" completion function for the bookmark commands
+function! nerdtree#completeBookmarks(A,L,P) abort
+ return filter(g:NERDTreeBookmark.BookmarkNames(), 'v:val =~# "^' . a:A . '"')
+endfunction
+
+"FUNCTION: nerdtree#compareNodes(dir) {{{2
+function! nerdtree#compareNodes(n1, n2) abort
+ return a:n1.path.compareTo(a:n2.path)
+endfunction
+
+"FUNCTION: nerdtree#compareNodesBySortKey(n1, n2) {{{2
+function! nerdtree#compareNodesBySortKey(n1, n2) abort
+ let sortKey1 = a:n1.path.getSortKey()
+ let sortKey2 = a:n2.path.getSortKey()
+ let i = 0
+ while i < min([len(sortKey1), len(sortKey2)])
+ " Compare chunks upto common length.
+ " If chunks have different type, the one which has
+ " integer type is the lesser.
+ if type(sortKey1[i]) ==# type(sortKey2[i])
+ if sortKey1[i] <# sortKey2[i]
+ return - 1
+ elseif sortKey1[i] ># sortKey2[i]
+ return 1
+ endif
+ elseif type(sortKey1[i]) ==# v:t_number
+ return -1
+ elseif type(sortKey2[i]) ==# v:t_number
+ return 1
+ endif
+ let i = i + 1
+ endwhile
+
+ " Keys are identical upto common length.
+ " The key which has smaller chunks is the lesser one.
+ if len(sortKey1) < len(sortKey2)
+ return -1
+ elseif len(sortKey1) > len(sortKey2)
+ return 1
+ else
+ return 0
+ endif
+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, ...) abort
+ 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, ignoreAll) {{{2
+" Same as :exec cmd but, if ignoreAll is TRUE, set eventignore=all for the duration
+function! nerdtree#exec(cmd, ignoreAll) abort
+ let old_ei = &eventignore
+ if a:ignoreAll
+ set eventignore=all
+ endif
+ try
+ exec a:cmd
+ finally
+ let &eventignore = old_ei
+ endtry
+endfunction
+
+" FUNCTION: nerdtree#has_opt(options, name) {{{2
+function! nerdtree#has_opt(options, name) abort
+ return has_key(a:options, a:name) && a:options[a:name] ==# 1
+endfunction
+
+" FUNCTION: nerdtree#loadClassFiles() {{{2
+function! nerdtree#loadClassFiles() abort
+ 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() abort
+ call g:NERDTreeBookmark.CacheBookmarks(1)
+ call nerdtree#ui_glue#createDefaultBindings()
+
+ "load all nerdtree plugins
+ runtime! nerdtree_plugin/**/*.vim
+endfunction
+
+"FUNCTION: nerdtree#runningWindows(dir) {{{2
+function! nerdtree#runningWindows() abort
+ return has('win16') || has('win32') || has('win64')
+endfunction
+
+"FUNCTION: nerdtree#runningCygwin(dir) {{{2
+function! nerdtree#runningCygwin() abort
+ return has('win32unix')
+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) abort
+ redraw
+ echomsg empty(a:msg) ? '' : ('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) abort
+ 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) abort
+ echohl warningmsg
+ call nerdtree#echo(a:msg)
+ echohl normal
+endfunction
+
+"FUNCTION: nerdtree#renderView {{{2
+function! nerdtree#renderView() abort
+ call b:NERDTree.render()
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/.config/nvim/plugged/nerdtree/autoload/nerdtree/ui_glue.vim b/.config/nvim/plugged/nerdtree/autoload/nerdtree/ui_glue.vim
new file mode 100644
index 0000000..aef1b04
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/autoload/nerdtree/ui_glue.vim
@@ -0,0 +1,698 @@
+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() abort
+ let s = '<SNR>' . s:SID() . '_'
+
+ call NERDTreeAddKeyMap({ 'key': '<MiddleMouse>', 'scope': 'all', 'callback': s . 'handleMiddleMouse' })
+ call NERDTreeAddKeyMap({ 'key': '<LeftRelease>', '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:NERDTreeMapCustomOpen, 'scope':'FileNode', 'callback': s.'customOpenFile'})
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCustomOpen, 'scope':'DirNode', 'callback': s.'customOpenDir'})
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCustomOpen, 'scope':'Bookmark', 'callback': s.'customOpenBookmark'})
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCustomOpen, '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:NERDTreeMapPreview, 'scope': 'Bookmark', 'callback': s.'previewBookmark' })
+ 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: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: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:NERDTreeMapOpenExpl, 'scope': 'FileNode', 'callback': s.'openExplorer' })
+
+ call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapDeleteBookmark, 'scope': 'Bookmark', 'callback': s.'deleteBookmark' })
+endfunction
+
+
+"SECTION: Interface bindings {{{1
+"============================================================
+
+"FUNCTION: s:customOpenFile() {{{1
+" Open file node with the 'custom' key, initially <CR>.
+function! s:customOpenFile(node) abort
+ call a:node.activate(s:initCustomOpenArgs().file)
+endfunction
+
+"FUNCTION: s:customOpenDir() {{{1
+" Open directory node with the 'custom' key, initially <CR>.
+function! s:customOpenDir(node) abort
+ call s:activateDirNode(a:node, s:initCustomOpenArgs().dir)
+endfunction
+
+"FUNCTION: s:customOpenBookmark() {{{1
+" Open bookmark node with the 'custom' key, initially <CR>.
+function! s:customOpenBookmark(node) abort
+ if a:node.path.isDirectory
+ call a:node.activate(b:NERDTree, s:initCustomOpenArgs().dir)
+ else
+ call a:node.activate(b:NERDTree, s:initCustomOpenArgs().file)
+ endif
+endfunction
+
+"FUNCTION: s:initCustomOpenArgs() {{{1
+" Make sure NERDTreeCustomOpenArgs has needed keys
+function! s:initCustomOpenArgs() abort
+ let g:NERDTreeCustomOpenArgs = get(g:, 'NERDTreeCustomOpenArgs', {})
+ return extend(g:NERDTreeCustomOpenArgs, {'file':{'reuse': 'all', 'where': 'p'}, 'dir':{}}, 'keep')
+endfunction
+
+"FUNCTION: s:activateAll() {{{1
+"handle the user activating the updir line
+function! s:activateAll() abort
+ if getline('.') ==# g:NERDTreeUI.UpDirLine()
+ return nerdtree#ui_glue#upDir(0)
+ endif
+endfunction
+
+" FUNCTION: s:activateDirNode(directoryNode, options) {{{1
+" Open a directory with optional options
+function! s:activateDirNode(directoryNode, ...) abort
+
+ if a:directoryNode.isRoot() && a:directoryNode.isOpen
+ call nerdtree#echo('cannot close tree root')
+ return
+ endif
+
+ call a:directoryNode.activate((a:0 > 0) ? a:1 : {})
+endfunction
+
+"FUNCTION: s:activateFileNode() {{{1
+"handle the user activating a tree node
+function! s:activateFileNode(node) abort
+ call a:node.activate({'reuse': 'all', 'where': 'p'})
+endfunction
+
+"FUNCTION: s:activateBookmark(bookmark) {{{1
+"handle the user activating a bookmark
+function! s:activateBookmark(bm) abort
+ call a:bm.activate(b:NERDTree, !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(...) abort
+ 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) abort
+ 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) abort
+ call b:NERDTree.changeRoot(a:node)
+endfunction
+
+" FUNCTION: s:nerdtree#ui_glue#chRootCwd() {{{1
+" Change the NERDTree root to match the current working directory.
+function! nerdtree#ui_glue#chRootCwd() abort
+ NERDTreeCWD
+endfunction
+
+" FUNCTION: nnerdtree#ui_glue#clearBookmarks(bookmarks) {{{1
+function! nerdtree#ui_glue#clearBookmarks(bookmarks) abort
+ 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.root.refresh()
+ call b:NERDTree.render()
+endfunction
+
+" FUNCTION: s:closeChildren(node) {{{1
+" closes all childnodes of the current node
+function! s:closeChildren(node) abort
+ call a:node.closeChildren()
+ call b:NERDTree.render()
+ call a:node.putCursorHere(0, 0)
+endfunction
+
+" FUNCTION: s:closeCurrentDir(node) {{{1
+" Close the parent directory of the current node.
+function! s:closeCurrentDir(node) abort
+
+ if a:node.isRoot()
+ call nerdtree#echo('cannot close parent of tree root')
+ return
+ endif
+
+ let l:parent = a:node.parent
+
+ while l:parent.isCascadable()
+ let l:parent = l:parent.parent
+ endwhile
+
+ if l:parent.isRoot()
+ call nerdtree#echo('cannot close tree root')
+ return
+ endif
+
+ call l:parent.close()
+ call b:NERDTree.render()
+ call l:parent.putCursorHere(0, 0)
+endfunction
+
+" FUNCTION: s:closeTreeWindow() {{{1
+" close the tree window
+function! s:closeTreeWindow() abort
+ if b:NERDTree.isWinTree() && b:NERDTree.previousBuf() !=# -1
+ exec 'buffer ' . b:NERDTree.previousBuf()
+ else
+ if winnr('$') > 1
+ call g:NERDTree.Close()
+ else
+ call nerdtree#echo('Cannot close last window')
+ endif
+ endif
+endfunction
+
+" FUNCTION: s:deleteBookmark(bookmark) {{{1
+" Prompt the user to confirm the deletion of the selected bookmark.
+function! s:deleteBookmark(bookmark) abort
+ let l:message = 'Delete the bookmark "' . a:bookmark.name
+ \ . '" from the bookmark list?'
+
+ let l:choices = "&Yes\n&No"
+
+ echo | redraw
+ let l:selection = confirm(l:message, l:choices, 1, 'Warning')
+
+ if l:selection !=# 1
+ call nerdtree#echo('bookmark not deleted')
+ return
+ endif
+
+ try
+ call a:bookmark.delete()
+ silent call b:NERDTree.root.refresh()
+ call b:NERDTree.render()
+ echo | redraw
+ catch /^NERDTree/
+ call nerdtree#echoWarning('could not remove bookmark')
+ endtry
+endfunction
+
+" FUNCTION: s:displayHelp() {{{1
+" toggles the help display
+function! s:displayHelp() abort
+ call b:NERDTree.ui.toggleHelp()
+ call b:NERDTree.render()
+ call b:NERDTree.ui.centerView()
+endfunction
+
+" FUNCTION: s:findAndRevealPath(pathStr) {{{1
+function! s:findAndRevealPath(pathStr) abort
+ let l:pathStr = !empty(a:pathStr) ? a:pathStr : expand('%:p')
+ let l:revealOpts = {}
+
+ if empty(l:pathStr)
+ call nerdtree#echoWarning('no file for the current buffer')
+ return
+ endif
+
+ if !filereadable(l:pathStr)
+ let l:pathStr = fnamemodify(l:pathStr, ':h')
+ let l:revealOpts['open'] = 1
+ endif
+
+ try
+ let l:pathStr = g:NERDTreePath.Resolve(l:pathStr)
+ let l:pathObj = g:NERDTreePath.New(l:pathStr)
+ catch /^NERDTree.InvalidArgumentsError/
+ call nerdtree#echoWarning('invalid path')
+ return
+ endtry
+
+ if !g:NERDTree.ExistsForTab()
+ try
+ let l:cwd = g:NERDTreePath.New(getcwd())
+ catch /^NERDTree.InvalidArgumentsError/
+ call nerdtree#echo('current directory does not exist.')
+ let l:cwd = l:pathObj.getParent()
+ endtry
+
+ if l:pathObj.isUnder(l:cwd)
+ call g:NERDTreeCreator.CreateTabTree(l:cwd.str())
+ else
+ call g:NERDTreeCreator.CreateTabTree(l:pathObj.getParent().str())
+ endif
+ else
+ NERDTreeFocus
+
+ if !l:pathObj.isUnder(b:NERDTree.root.path)
+ call s:chRoot(g:NERDTreeDirNode.New(l:pathObj.getParent(), b:NERDTree))
+ endif
+ endif
+
+ if l:pathObj.isHiddenUnder(b:NERDTree.root.path)
+ call b:NERDTree.ui.setShowHidden(1)
+ endif
+
+ let l:node = b:NERDTree.root.reveal(l:pathObj, l:revealOpts)
+ call b:NERDTree.render()
+ call l:node.putCursorHere(1, 0)
+endfunction
+
+"FUNCTION: s:handleLeftClick() {{{1
+"Checks if the click should open the current node
+function! s:handleLeftClick() abort
+ 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 =~# '[+~'.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.'] \?$'
+ 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() abort
+
+ " A middle mouse click does not automatically position the cursor as one
+ " would expect. Forcing the execution of a regular left mouse click here
+ " fixes this problem.
+ execute "normal! \<LeftMouse>"
+
+ let l:currentNode = g:NERDTreeFileNode.GetSelected()
+ if empty(l:currentNode)
+ call nerdtree#echoError('use the pointer to select a node')
+ return
+ endif
+
+ if l:currentNode.path.isDirectory
+ call l:currentNode.openExplorer()
+ else
+ call l:currentNode.open({'where': 'h'})
+ endif
+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) abort
+ call g:NERDTreeKeyMap.Invoke(a:key)
+endfunction
+
+" FUNCTION: s:jumpToFirstChild(node) {{{1
+function! s:jumpToFirstChild(node) abort
+ call s:jumpToChild(a:node, 0)
+endfunction
+
+" FUNCTION: s:jumpToLastChild(node) {{{1
+function! s:jumpToLastChild(node) abort
+ call s:jumpToChild(a:node, 1)
+endfunction
+
+" FUNCTION: s:jumpToChild(node, last) {{{1
+" Jump to the first or last child node at the same file system level.
+"
+" Args:
+" node: the node on which the cursor currently sits
+" last: 1 (true) if jumping to last child, 0 (false) if jumping to first
+function! s:jumpToChild(node, last) abort
+ let l:node = a:node.path.isDirectory ? a:node.getCascadeRoot() : a:node
+
+ if l:node.isRoot()
+ return
+ endif
+
+ let l:parent = l:node.parent
+ let l:children = l:parent.getVisibleChildren()
+
+ let l:target = a:last ? l:children[len(l:children) - 1] : l:children[0]
+
+ call l:target.putCursorHere(1, 0)
+ call b:NERDTree.ui.centerView()
+endfunction
+
+" FUNCTION: s:jumpToParent(node) {{{1
+" Move the cursor to the parent of the specified node. For a cascade, move to
+" the parent of the cascade's first node. At the root node, do nothing.
+function! s:jumpToParent(node) abort
+ let l:node = a:node.path.isDirectory ? a:node.getCascadeRoot() : a:node
+
+ if l:node.isRoot()
+ return
+ endif
+
+ if empty(l:node.parent)
+ call nerdtree#echo('could not jump to parent node')
+ return
+ endif
+
+ call l:node.parent.putCursorHere(1, 0)
+ call b:NERDTree.ui.centerView()
+endfunction
+
+" FUNCTION: s:jumpToRoot() {{{1
+" moves the cursor to the root node
+function! s:jumpToRoot() abort
+ call b:NERDTree.root.putCursorHere(1, 0)
+ call b:NERDTree.ui.centerView()
+endfunction
+
+" FUNCTION: s:jumpToNextSibling(node) {{{1
+function! s:jumpToNextSibling(node) abort
+ call s:jumpToSibling(a:node, 1)
+endfunction
+
+" FUNCTION: s:jumpToPrevSibling(node) {{{1
+function! s:jumpToPrevSibling(node) abort
+ call s:jumpToSibling(a:node, 0)
+endfunction
+
+" FUNCTION: s:jumpToSibling(node, forward) {{{1
+" Move the cursor to the next or previous node at the same file system level.
+"
+" Args:
+" node: the node on which the cursor currently sits
+" forward: 0 to jump to previous sibling, 1 to jump to next sibling
+function! s:jumpToSibling(node, forward) abort
+ let l:node = a:node.path.isDirectory ? a:node.getCascadeRoot() : a:node
+ let l:sibling = l:node.findSibling(a:forward)
+
+ if empty(l:sibling)
+ return
+ endif
+
+ call l:sibling.putCursorHere(1, 0)
+ call b:NERDTree.ui.centerView()
+endfunction
+
+" FUNCTION: nerdtree#ui_glue#openBookmark(name) {{{1
+" Open the Bookmark that has the specified name. This function provides the
+" implementation for the :OpenBookmark command.
+function! nerdtree#ui_glue#openBookmark(name) abort
+ try
+ let l:bookmark = g:NERDTreeBookmark.BookmarkFor(a:name)
+ catch /^NERDTree.BookmarkNotFoundError/
+ call nerdtree#echoError('bookmark "' . a:name . '" not found')
+ return
+ endtry
+ if l:bookmark.path.isDirectory
+ call l:bookmark.open(b:NERDTree)
+ else
+ call l:bookmark.open(b:NERDTree, {'where': 'p'})
+ endif
+endfunction
+
+" FUNCTION: s:openHSplit(target) {{{1
+function! s:openHSplit(target) abort
+ call a:target.activate({'where': 'h'})
+endfunction
+
+" FUNCTION: s:openVSplit(target) {{{1
+function! s:openVSplit(target) abort
+ call a:target.activate({'where': 'v'})
+endfunction
+
+" FUNCTION: s:openExplorer(node) {{{1
+function! s:openExplorer(node) abort
+ call a:node.openExplorer()
+endfunction
+
+" FUNCTION: s:openInNewTab(target) {{{1
+function! s:openInNewTab(target) abort
+ let l:opener = g:NERDTreeOpener.New(a:target.path, {'where': 't'})
+ call l:opener.open(a:target)
+endfunction
+
+" FUNCTION: s:openInNewTabSilent(target) {{{1
+function! s:openInNewTabSilent(target) abort
+ let l:opener = g:NERDTreeOpener.New(a:target.path, {'where': 't', 'stay': 1})
+ call l:opener.open(a:target)
+endfunction
+
+" FUNCTION: s:openNodeRecursively(node) {{{1
+function! s:openNodeRecursively(node) abort
+ call nerdtree#echo('Recursively opening node. Please wait...')
+ call a:node.openRecursively()
+ call b:NERDTree.render()
+ call nerdtree#echo('')
+endfunction
+
+" FUNCTION: s:previewBookmark(bookmark) {{{1
+function! s:previewBookmark(bookmark) abort
+ if a:bookmark.path.isDirectory
+ execute 'NERDTreeFind '.a:bookmark.path.str()
+ else
+ call a:bookmark.activate(b:NERDTree, {'stay': 1, 'where': 'p', 'keepopen': 1})
+ endif
+endfunction
+
+"FUNCTION: s:previewNodeCurrent(node) {{{1
+function! s:previewNodeCurrent(node) abort
+ call a:node.open({'stay': 1, 'where': 'p', 'keepopen': 1})
+endfunction
+
+"FUNCTION: s:previewNodeHSplit(node) {{{1
+function! s:previewNodeHSplit(node) abort
+ call a:node.open({'stay': 1, 'where': 'h', 'keepopen': 1})
+endfunction
+
+"FUNCTION: s:previewNodeVSplit(node) {{{1
+function! s:previewNodeVSplit(node) abort
+ 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) abort
+ try
+ let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0, b:NERDTree)
+ 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() abort
+ if !g:NERDTree.IsOpen()
+ return
+ endif
+ call nerdtree#echo('Refreshing the root node. This could take a while...')
+
+ let l:curWin = winnr()
+ call nerdtree#exec(g:NERDTree.GetWinNum() . 'wincmd w', 1)
+ call b:NERDTree.root.refresh()
+ call b:NERDTree.render()
+ redraw
+ call nerdtree#exec(l:curWin . 'wincmd w', 1)
+ call nerdtree#echo('')
+endfunction
+
+" FUNCTION: s:refreshCurrent(node) {{{1
+" refreshes the root for the current node
+function! s:refreshCurrent(node) abort
+ 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()
+ call nerdtree#echo('')
+endfunction
+
+" FUNCTION: nerdtree#ui_glue#setupCommands() {{{1
+function! nerdtree#ui_glue#setupCommands() abort
+ command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreateTabTree('<args>')
+ command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.ToggleTabTree('<args>')
+ command! -n=0 -bar NERDTreeClose :call g:NERDTree.Close()
+ command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreateTabTree('<args>')
+ command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror()
+ command! -n=? -complete=file -bar NERDTreeFind call s:findAndRevealPath('<args>')
+ command! -n=0 -bar NERDTreeRefreshRoot call s:refreshRoot()
+ command! -n=0 -bar NERDTreeFocus call NERDTreeFocus()
+ command! -n=0 -bar NERDTreeCWD call NERDTreeCWD()
+endfunction
+
+" Function: s:SID() {{{1
+function! s:SID() abort
+ if !exists('s:sid')
+ let s:sid = matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')
+ endif
+ return s:sid
+endfun
+
+" FUNCTION: s:showMenu(node) {{{1
+function! s:showMenu(node) abort
+ let mc = g:NERDTreeMenuController.New(g:NERDTreeMenuItem.AllEnabled())
+ call mc.showMenu()
+endfunction
+
+" FUNCTION: s:toggleIgnoreFilter() {{{1
+function! s:toggleIgnoreFilter() abort
+ call b:NERDTree.ui.toggleIgnoreFilter()
+endfunction
+
+" FUNCTION: s:toggleShowBookmarks() {{{1
+function! s:toggleShowBookmarks() abort
+ call b:NERDTree.ui.toggleShowBookmarks()
+endfunction
+
+" FUNCTION: s:toggleShowFiles() {{{1
+function! s:toggleShowFiles() abort
+ call b:NERDTree.ui.toggleShowFiles()
+endfunction
+
+" FUNCTION: s:toggleShowHidden() {{{1
+" toggles the display of hidden files
+function! s:toggleShowHidden() abort
+ call b:NERDTree.ui.toggleShowHidden()
+endfunction
+
+" FUNCTION: s:toggleZoom() {{{1
+function! s:toggleZoom() abort
+ call b:NERDTree.ui.toggleZoom()
+endfunction
+
+" FUNCTION: nerdtree#ui_glue#upDir(preserveState) {{{1
+" Move the NERDTree up one level.
+"
+" Args:
+" preserveState: if 1, the current root is left open when the new tree is
+" rendered; if 0, the current root node is closed
+function! nerdtree#ui_glue#upDir(preserveState) abort
+
+ try
+ call b:NERDTree.root.cacheParent()
+ catch /^NERDTree.CannotCacheParentError/
+ call nerdtree#echo('already at root directory')
+ return
+ endtry
+
+ let l:oldRoot = b:NERDTree.root
+ let l:newRoot = b:NERDTree.root.parent
+
+ call l:newRoot.open()
+ call l:newRoot.transplantChild(l:oldRoot)
+
+ if !a:preserveState
+ call l:oldRoot.close()
+ endif
+
+ call b:NERDTree.changeRoot(l:newRoot)
+ call l:oldRoot.putCursorHere(0, 0)
+endfunction
+
+" FUNCTION: s:upDirCurrentRootOpen() {{{1
+function! s:upDirCurrentRootOpen() abort
+ call nerdtree#ui_glue#upDir(1)
+endfunction
+
+" FUNCTION: s:upDirCurrentRootClosed() {{{1
+function! s:upDirCurrentRootClosed() abort
+ call nerdtree#ui_glue#upDir(0)
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/.config/nvim/plugged/nerdtree/doc/NERDTree.txt b/.config/nvim/plugged/nerdtree/doc/NERDTree.txt
new file mode 100644
index 0000000..47d65cc
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/doc/NERDTree.txt
@@ -0,0 +1,1528 @@
+*NERDTree.txt* A tree explorer plugin to rule the Vim world. Bwahahaha!!
+
+ # #### #### ~
+ ### \/#|### |/#### ~
+ d8 888 ##\/#/ \||/##/_/##/_# ~
+ d88 888 ee ,e e, ### \/###|/ \/ # ### ~
+ d88888 888 88b d88 88b ##_\_#\_\## | #/###_/_#### ~
+ 888 888 888 888 , ## #### # \ #| / #### ##/## ~
+ 888 888 888 "YeeP" __#_--###`. |{,###---###-~ ~
+ \ % @% ~
+ Y88b Y88 888'Y88 888 88e 888 88e \%@% 88P'888'Y88 ~
+ Y88b Y8 888 ,'Y 888 888D 888 888b %o% P' 888 'Y 888,8, ,e e, ,e e, ~
+ b Y88b Y 888C8 888 88" 888 8888D %@% 888 888 " d88 88b d88 88b ~
+ 8b Y88b 888 ",d 888 b, 888 888P %@% 888 888 888 , 888 , ~
+ 88b Y88b 888,d88 888 88b, 888 88" %@% 888 888 "YeeP" "YeeP" ~
+ , -=-%{@%-^- _ ~
+ ejm `} 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.NERDTree mappings.................|NERDTreeMappings|
+ 2.4.The NERDTree menu.................|NERDTreeMenu|
+ 3.Settings................................|NERDTreeSettings|
+ 3.1.Settings summary..................|NERDTreeSettingsSummary|
+ 3.2.Settings details..................|NERDTreeSettingsDetails|
+ 4.The NERDTree API........................|NERDTreeAPI|
+ 4.1.Key map API.......................|NERDTreeKeymapAPI|
+ 4.2.Menu API..........................|NERDTreeMenuAPI|
+ 4.3.Menu API..........................|NERDTreeAddPathFilter()|
+ 4.4.Path Listener API.................|NERDTreePathListenerAPI|
+ 5.About...................................|NERDTreeAbout|
+ 6.License.................................|NERDTreeLicense|
+
+==============================================================================
+1. Intro *NERDTree*
+
+What is this "NERDTree"??
+
+The NERDTree 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 NERDTree:
+ * 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 NERDTree 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 NERDTree 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 NERDTree window will appear exactly
+ as you left it
+ * You can have a separate NERDTree 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) NERDTree 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 [<start-directory> | <bookmark>] *:NERDTree*
+ Opens a fresh NERDTree. 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)
+<
+:NERDTreeVCS [<start-directory> | <bookmark>] *:NERDTreeVCS*
+ Like |:NERDTree|, but searches up the directory tree to find the top of
+ the version control system repository, and roots the NERDTree there. It
+ works with Git, Subversion, Mercurial, Bazaar, and Darcs repositories. A
+ couple of examples: >
+ :NERDTreeVCS /home/marty/nerdtree/doc (opens /home/marty/nerdtree)
+ :NERDTreeVCS (opens root of repository containing CWD)
+<
+:NERDTreeFromBookmark <bookmark> *:NERDTreeFromBookmark*
+ Opens a fresh NERDTree with the root initialized to the dir for
+ <bookmark>. The only reason to use this command over :NERDTree is for
+ the completion (which is for bookmarks rather than directories).
+
+:NERDTreeToggle [<start-directory> | <bookmark>] *:NERDTreeToggle*
+ If a NERDTree already exists for this tab, it is reopened and rendered
+ again. If <start-directory> or <bookmark> is given, the root of NERDTree
+ is set to that path. If no NERDTree exists for this tab then this command
+ acts the same as the |:NERDTree| command.
+
+:NERDTreeToggleVCS [<start-directory> | <bookmark>] *:NERDTreeToggleVCS*
+ Like |:NERDTreeToggle|, but searches up the directory tree to find the top of
+ the version control system repository, and roots the NERDTree there. It
+ works with Git, Subversion, Mercurial, Bazaar, and Darcs repositories. A
+ couple of examples: >
+ :NERDTreeToggleVCS /home/marty/nerdtree/doc (opens /home/marty/nerdtree)
+ :NERDTreeToggleVCS (opens root of repository containing CWD)
+
+:NERDTreeFocus *:NERDTreeFocus*
+ Opens (or reopens) the NERDTree if it is not currently visible;
+ otherwise, the cursor is moved to the already-open NERDTree.
+
+:NERDTreeMirror *:NERDTreeMirror*
+ Shares an existing NERDTree, 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 NERDTree exists, that tree is automatically mirrored.
+ If more than one exists, the script will ask which tree to mirror.
+
+:NERDTreeClose *:NERDTreeClose*
+ Close the NERDTree in this tab.
+
+:NERDTreeFind [<path>] *:NERDTreeFind*
+ Without the optional argument, find and reveal the file for the active
+ buffer in the NERDTree window. With the <path> argument, find and
+ reveal the specified path.
+
+ Focus will be shifted to the NERDTree window, and the cursor will be
+ placed on the tree node for the determined path. If a NERDTree for the
+ current tab does not exist, a new one will be initialized.
+
+:NERDTreeCWD *:NERDTreeCWD*
+ Change the NERDTree root to the current working directory. If no
+ NERDTree exists for this tab, a new one is opened.
+
+:NERDTreeRefreshRoot *:NERDTreeRefreshRoot*
+ Refreshes the NERDTree root node.
+
+------------------------------------------------------------------------------
+2.2. Bookmarks *NERDTreeBookmarks*
+
+Bookmarks in the NERDTree 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: The following commands are only available within the NERDTree buffer.
+
+:Bookmark [<name>]
+ Bookmark the current node as <name>. If there is already a <name>
+ bookmark, it is overwritten. <name> must not contain spaces.
+ If <name> is not provided, it defaults to the file or directory name.
+ For directories, a trailing slash is present.
+
+:BookmarkToRoot <bookmark>
+ Make the directory corresponding to <bookmark> the new root. If a treenode
+ corresponding to <bookmark> is already cached somewhere in the tree then
+ the current tree will be used, otherwise a fresh tree will be opened.
+ Note that if <bookmark> points to a file then its parent will be used
+ instead.
+
+:RevealBookmark <bookmark>
+ 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 <name>
+ The Bookmark named <name> is opened as if |NERDTree-o| was applied to
+ its entry in the Bookmark table. If the Bookmark points to a directory,
+ it is made the new root of the current NERDTree. If the Bookmark points
+ to a file, that file is opened for editing in another window.
+
+:ClearBookmarks [<bookmarks>]
+ Remove all the given bookmarks. If no bookmarks are given then remove all
+ bookmarks on the current node.
+
+:ClearAllBookmarks
+ Remove all bookmarks.
+
+:EditBookmarks
+ Opens the bookmarks file for manual editing, e.g. for removing invalid
+ 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 at 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:
+<bookmark name><space><full path to the bookmark location>
+
+You can use the :EditBookmarks command to open the bookmarks file for editing.
+After you have corrected any invalid bookmarks, either restart vim, or run
+:ReadBookmarks from the NERDTree window.
+
+------------------------------------------------------------------------------
+2.3. NERDTree Mappings *NERDTreeMappings*
+
+Default~
+Key Description help-tag~
+
+o........Open files, directories and bookmarks......................|NERDTree-o|
+go.......Open selected file, but leave cursor in the NERDTree......|NERDTree-go|
+ Open selected bookmark dir in current NERDTree
+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|
+<CR>.....User-definable custom open action.......................|NERDTree-<CR>|
+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|
+
+double-click....same as |NERDTree-o|.
+middle-click....same as |NERDTree-i| for files, and |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|
+<C-J>....Jump down to next sibling of the current directory.......|NERDTree-C-J|
+<C-K>....Jump up to 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 NERDTree 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 setting: 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 setting: NERDTreeMapPreview
+Applies to: files.
+
+If a file node or a bookmark that links to a file is selected, it is opened in
+the previous window, but the cursor does not move.
+
+If a bookmark that links to a directory is selected, that directory is found
+in the current NERDTree. If the directory couldn't be found, a new NERDTree is
+created.
+
+The default key combo for this mapping is "g" + NERDTreeMapActivateNode (see
+|NERDTree-o|).
+
+------------------------------------------------------------------------------
+ *NERDTree-t*
+Default key: t
+Map setting: *NERDTreeMapOpenInTab*
+Applies to: files and directories.
+
+Opens the selected file in a new tab. If a directory is selected, a fresh
+NERDTree for that directory is opened in a new tab.
+
+If a bookmark which points to a directory is selected, open a NERDTree 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 setting: *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 setting: *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 setting: *NERDTreeMapPreviewSplit*
+Applies to: files.
+
+The same as |NERDTree-i| except that the cursor is not moved.
+
+The default key combo for this mapping is "g" + NERDTreeMapOpenSplit (see
+|NERDTree-i|).
+
+------------------------------------------------------------------------------
+ *NERDTree-s*
+Default key: s
+Map setting: *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 setting: *NERDTreeMapPreviewVSplit*
+Applies to: files.
+
+The same as |NERDTree-s| except that the cursor is not moved.
+
+The default key combo for this mapping is "g" + NERDTreeMapOpenVSplit (see
+|NERDTree-s|).
+
+------------------------------------------------------------------------------
+ *NERDTree-<CR>*
+Default key: <CR>
+Map setting: *NERDTreeMapCustomOpen*
+Applies to: files, directories, and bookmarks
+
+Performs a customized open action on the selected node. This allows the user
+to define an action that behaves differently from any of the standard
+keys. See |NERDTreeCustomOpenArgs| for more details.
+------------------------------------------------------------------------------
+ *NERDTree-O*
+Default key: O
+Map setting: *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 setting: *NERDTreeMapCloseDir*
+Applies to: files and directories.
+
+Closes the parent of the selected node.
+
+------------------------------------------------------------------------------
+ *NERDTree-X*
+Default key: X
+Map setting: *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 setting: *NERDTreeMapOpenExpl*
+Applies to: files and directories.
+
+|:edit|s the selected directory, or the selected file's directory. This could
+result in a NERDTree or a netrw being opened, depending on
+|NERDTreeHijackNetrw|.
+
+------------------------------------------------------------------------------
+ *NERDTree-D*
+Default key: D
+Map setting: *NERDTreeMapDeleteBookmark*
+Applies to: lines in the bookmarks table
+
+Deletes the currently selected bookmark.
+
+------------------------------------------------------------------------------
+ *NERDTree-P*
+Default key: P
+Map setting: *NERDTreeMapJumpRoot*
+Applies to: no restrictions.
+
+Jump to the tree root.
+
+------------------------------------------------------------------------------
+ *NERDTree-p*
+Default key: p
+Map setting: *NERDTreeMapJumpParent*
+Applies to: files and directories.
+
+Jump to the parent node of the selected node.
+
+------------------------------------------------------------------------------
+ *NERDTree-K*
+Default key: K
+Map setting: *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 setting: *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: <C-J>
+Map setting: *NERDTreeMapJumpNextSibling*
+Applies to: files and directories.
+
+Jump to the next sibling of the selected node.
+
+------------------------------------------------------------------------------
+ *NERDTree-C-K*
+Default key: <C-K>
+Map setting: *NERDTreeMapJumpPrevSibling*
+Applies to: files and directories.
+
+Jump to the previous sibling of the selected node.
+
+------------------------------------------------------------------------------
+ *NERDTree-C*
+Default key: C
+Map setting: *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 setting: *NERDTreeMapUpdir*
+Applies to: no restrictions.
+
+Move the tree root up a dir (like doing a "cd ..").
+
+------------------------------------------------------------------------------
+ *NERDTree-U*
+Default key: U
+Map setting: *NERDTreeMapUpdirKeepOpen*
+Applies to: no restrictions.
+
+Like |NERDTree-u| except that the old tree root is kept open.
+
+------------------------------------------------------------------------------
+ *NERDTree-r*
+Default key: r
+Map setting: *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 setting: *NERDTreeMapRefreshRoot*
+Applies to: no restrictions.
+
+Recursively refresh the tree root.
+
+------------------------------------------------------------------------------
+ *NERDTree-m*
+Default key: m
+Map setting: *NERDTreeMapMenu*
+Applies to: files and directories.
+
+Display the NERDTree menu. See |NERDTreeMenu| for details.
+
+------------------------------------------------------------------------------
+ *NERDTree-cd*
+Default key: cd
+Map setting: *NERDTreeMapChdir*
+Applies to: files and directories.
+
+Change Vim's current working directory to that of the selected node.
+
+------------------------------------------------------------------------------
+ *NERDTree-CD*
+Default key: CD
+Map setting: *NERDTreeMapCWD*
+Applies to: no restrictions.
+
+Change the NERDTree root to Vim's current working directory.
+
+------------------------------------------------------------------------------
+ *NERDTree-I*
+Default key: I
+Map setting: *NERDTreeMapToggleHidden*
+Applies to: no restrictions.
+
+Toggles whether hidden files (i.e. "dot files") are displayed.
+
+------------------------------------------------------------------------------
+ *NERDTree-f*
+Default key: f
+Map setting: *NERDTreeMapToggleFilters*
+Applies to: no restrictions.
+
+Toggles whether file filters are used. See |NERDTreeIgnore| for details.
+
+------------------------------------------------------------------------------
+ *NERDTree-F*
+Default key: F
+Map setting: *NERDTreeMapToggleFiles*
+Applies to: no restrictions.
+
+Toggles whether file nodes are displayed.
+
+------------------------------------------------------------------------------
+ *NERDTree-B*
+Default key: B
+Map setting: *NERDTreeMapToggleBookmarks*
+Applies to: no restrictions.
+
+Toggles whether the bookmarks table is displayed.
+
+------------------------------------------------------------------------------
+ *NERDTree-q*
+Default key: q
+Map setting: *NERDTreeMapQuit*
+Applies to: no restrictions.
+
+Closes the NERDTree window.
+
+------------------------------------------------------------------------------
+ *NERDTree-A*
+Default key: A
+Map setting: *NERDTreeMapToggleZoom*
+Applies to: no restrictions.
+
+Maximize (zoom) and minimize the NERDTree window.
+
+------------------------------------------------------------------------------
+ *NERDTree-?*
+Default key: ?
+Map setting: *NERDTreeMapHelp*
+Applies to: no restrictions.
+
+Toggles whether the quickhelp is displayed.
+
+------------------------------------------------------------------------------
+ 2.3. The NERDTree menu *NERDTreeMenu*
+
+The NERDTree 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|
+
+------------------------------------------------------------------------------
+ *NERDTreeMenu-j*
+Default key: j
+Map option: *NERDTreeMenuDown*
+Applies to: The NERDTree menu.
+
+Moves the cursor down.
+
+------------------------------------------------------------------------------
+ *NERDTreeMenu-k*
+Default key: k
+Map option: *NERDTreeMenuUp*
+Applies to: The NERDTree menu.
+
+Moves the cursor up.
+
+==============================================================================
+3. Customisation *NERDTreeSettings*
+
+
+------------------------------------------------------------------------------
+3.1. Customisation summary *NERDTreeSettingsSummary*
+
+The plugin provides the following settings that can customise the behaviour
+the NERDTree. These settings should be set in your vimrc, using `:let`.
+
+|loaded_nerd_tree| Turns off the script.
+
+|NERDTreeAutoCenter| Controls whether the NERDTree 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 NERDTree whether to be case
+ sensitive or not when sorting nodes.
+
+|NERDTreeNaturalSort| Tells the NERDTree whether to use natural sort
+ order or not when sorting nodes.
+
+|NERDTreeSortHiddenFirst| Tells the NERDTree whether to take the dot at
+ the beginning of the hidden file names into
+ account when sorting nodes.
+
+|NERDTreeChDirMode| Tells the NERDTree if/when it should change
+ vim's current working directory.
+
+|NERDTreeHighlightCursorline| Tell the NERDTree whether to highlight the
+ current cursor line.
+
+|NERDTreeHijackNetrw| Tell the NERDTree whether to replace the netrw
+ autocommands for exploring local directories.
+
+|NERDTreeIgnore| Tells the NERDTree which files to ignore.
+
+|NERDTreeRespectWildIgnore| Tells the NERDTree to respect `'wildignore'`.
+
+|NERDTreeBookmarksFile| Where the bookmarks are stored.
+
+|NERDTreeBookmarksSort| Control how the Bookmark table is sorted.
+
+|NERDTreeMarkBookmarks| Render bookmarked nodes with markers.
+
+|NERDTreeMouseMode| Manage the interpretation of mouse clicks.
+
+|NERDTreeQuitOnOpen| Closes the tree window or bookmark table after
+ opening a file.
+
+|NERDTreeShowBookmarks| Tells the NERDTree whether to display the
+ bookmarks table on startup.
+
+|NERDTreeShowFiles| Tells the NERDTree whether to display files in
+ the tree on startup.
+
+|NERDTreeShowHidden| Tells the NERDTree whether to display hidden
+ files on startup.
+
+|NERDTreeShowLineNumbers| Tells the NERDTree whether to display line
+ numbers in the tree window.
+
+|NERDTreeSortOrder| Tell the NERDTree how to sort the nodes in the
+ tree.
+
+|NERDTreeStatusline| Set a statusline for NERDTree windows.
+
+|NERDTreeWinPos| Tells the script where to put the NERDTree
+ window.
+
+|NERDTreeWinSize| Sets the window size when the NERDTree is
+ opened.
+
+|NERDTreeWinSizeMax| Sets the maximum window size when the NERDTree
+ is zoomed.
+
+|NERDTreeMinimalUI| Disables display of the 'Bookmarks' label and
+ 'Press ? for help' text.
+
+|NERDTreeMinimalMenu| Use a compact menu that fits on a single line
+ for adding, copying, deleting, etc
+
+|NERDTreeCascadeSingleChildDir|
+ Collapses on the same line directories that have
+ only one child directory.
+
+|NERDTreeCascadeOpenSingleChildDir|
+ Cascade open while selected directory has only
+ one child that also is a directory.
+
+|NERDTreeAutoDeleteBuffer| Tells the NERDTree to automatically remove a
+ buffer when a file is being deleted or renamed
+ via a context menu command.
+
+|NERDTreeCreatePrefix| Specify a prefix to be used when creating the
+ NERDTree window.
+
+|NERDTreeRemoveFileCmd| Specify a custom shell command to be used when
+ deleting files. Note that it should include one
+ space character at the end of the command and it
+ applies only to files.
+
+|NERDTreeRemoveDirCmd| Specify a custom shell command to be used when
+ deleting directories. Note that it should
+ include one space character at the end of the
+ command and it applies only to directories.
+
+|NERDTreeDirArrowCollapsible| These characters indicate when a directory is
+|NERDTreeDirArrowExpandable| either collapsible or expandable.
+
+|NERDTreeNodeDelimiter| A single character that is used to separate the
+ file or directory name from the rest of the
+ characters on the line of text.
+
+|NERDTreeCustomOpenArgs| A dictionary with values that control how a node
+ is opened with the |NERDTree-<CR>| key.
+
+------------------------------------------------------------------------------
+3.2. Customisation details *NERDTreeSettingsDetails*
+
+To enable any of the below settings you should put an appropriate >
+ let <setting>=<value>
+<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 NERDTree 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 setting controls the "sensitivity" of the NERDTree auto centering. See
+|NERDTreeAutoCenter| for details.
+
+------------------------------------------------------------------------------
+ *NERDTreeCaseSensitiveSort*
+Values: 0 or 1.
+Default: 0.
+
+By default the NERDTree 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 setting 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
+<
+------------------------------------------------------------------------------
+ *NERDTreeNaturalSort*
+Values: 0 or 1.
+Default: 0.
+
+By default the NERDTree does not sort nodes in natural sort order, i.e. nodes
+could appear like this: >
+ z1.txt
+ z10.txt
+ z100.txt
+ z11.txt
+ z110.txt
+ z2.txt
+ z20.txt
+ z3.txt
+<
+But if you set this setting to 1 then the natural sort order will be used. The
+above nodes would then be sorted like this: >
+ z1.txt
+ z2.txt
+ z3.txt
+ z10.txt
+ z11.txt
+ z20.txt
+ z100.txt
+ z110.txt
+<
+------------------------------------------------------------------------------
+ *NERDTreeUseTCD*
+Values: 0 or 1.
+Default: 0.
+
+By default, NERDTree will use the `:cd` command to change the current working
+directory. If this setting is turned on, and the `:tcd` command is available, it
+will be used instead.
+
+------------------------------------------------------------------------------
+ *NERDTreeChDirMode*
+Values: 0, 1, 2, or 3.
+Default: 0.
+
+Use this setting 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 NERDTree.
+
+If set to 1 then the CWD is changed when the NERDTree is first loaded to the
+directory it is initialized in. For example, if you start the NERDTree 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 NERDTree with a similar command.
+
+If the setting 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.
+
+If the set to 3, then it behaves the same as if set to 2, and the CWD is
+changed whenever changing tabs to whatever the tree root is on that tab.
+
+------------------------------------------------------------------------------
+ *NERDTreeHighlightCursorline*
+Values: 0 or 1.
+Default: 1.
+
+If set to 1, the current cursor line in the NERDTree buffer will be
+highlighted. This is done using the `'cursorline'` Vim option.
+
+------------------------------------------------------------------------------
+ *NERDTreeHijackNetrw*
+Values: 0 or 1.
+Default: 1.
+
+If set to 1, doing a >
+ :edit <some directory>
+<
+will open up a window level NERDTree instead of a netrw in the target window.
+
+Window level 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 one tree per window - instead of per tab.
+
+------------------------------------------------------------------------------
+ *NERDTreeIgnore*
+Values: a list of regular expressions.
+Default: ['\~$'].
+
+This setting is used to specify which files the NERDTree should ignore. It
+must be a list of regular expressions. When the NERDTree is rendered, any
+files/dirs that match any of the regex's in NERDTreeIgnore won't 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 NERDTree 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, 1, or 2
+Default: 1
+
+This setting controls the method by which the list of user bookmarks is
+sorted. When sorted, bookmarks will render in alphabetical order by name.
+
+If set to 0, the bookmarks list is not sorted.
+If set to 1, the bookmarks list is sorted in a case-insensitive manner.
+If set to 2, the bookmarks list is sorted in a case-sensitive manner.
+
+------------------------------------------------------------------------------
+ *NERDTreeMarkBookmarks*
+Values: 0 or 1
+Default: 1
+
+If set to 1, Bookmarks will be specially marked whenever the NERDTree is
+rendered. Users of the |NERDTreeMinimalUI| setting may prefer to disable
+this setting for even less visual clutter.
+
+------------------------------------------------------------------------------
+ *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,1,2 or 3.
+Default: 0
+
+This setting governs whether the NERDTree window or the bookmarks table closes
+after opening a file with the |NERDTree-o|, |NERDTree-i|, |NERDTree-t| and
+|NERDTree-T| mappings.
+
+ Value | NERDTree Window Behavior
+ -------+-------------------------------------------------------
+ 0 | No change
+ 1 | Closes after opening a file
+ 2 | Closes the bookmark table after opening a bookmark
+ 3(1+2) | Same as both 1 and 2
+
+------------------------------------------------------------------------------
+ *NERDTreeShowBookmarks*
+Values: 0 or 1.
+Default: 0.
+
+If this setting is set to 1 then the bookmarks table will be displayed.
+
+This setting can be toggled dynamically, per tree, with the |NERDTree-B|
+mapping.
+
+------------------------------------------------------------------------------
+ *NERDTreeShowFiles*
+Values: 0 or 1.
+Default: 1.
+
+If this setting is set to 1 then files are displayed in the NERDTree. If it
+is set to 0 then only directories are displayed.
+
+This setting 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 setting tells vim whether to display hidden files by default. This
+setting can be dynamically toggled, per tree, with the |NERDTree-I| mapping.
+Use one of the follow lines for this setting: >
+ let NERDTreeShowHidden=0
+ let NERDTreeShowHidden=1
+<
+------------------------------------------------------------------------------
+ *NERDTreeShowLineNumbers*
+Values: 0 or 1.
+Default: 0.
+
+This setting tells vim whether to display line numbers for the NERDTree
+window. Use one of the follow lines for this setting: >
+ let NERDTreeShowLineNumbers=0
+ let NERDTreeShowLineNumbers=1
+<
+------------------------------------------------------------------------------
+ *NERDTreeSortOrder*
+Values: a list of regular expressions.
+Default: ['\/$', '*', '\.swp$', '\.bak$', '\~$']
+
+This setting is a list of regular expressions which are used to group or sort
+the nodes under their parent.
+
+For example, if the setting is: >
+ ['\.vim$', '\.c$', '\.h$', '*', 'foobar']
+<
+then all .vim files will be grouped 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
+doesn't match any of the other regexps should be placed here.
+
+If no star is present in NERDTreeSortOrder, then one is automatically
+appended to the end of the list.
+
+The regex '\/$' should be used to match directory nodes.
+
+Files can also be sorted by 1) the modification timestamp, 2) the size, or 3)
+the extension. Directories are always sorted by name. To accomplish this, the
+following special flags are used:
+ [[timestamp]] [[-timestamp]] [[size]] [[-size]] [[extension]]
+The hyphen specifies a descending sort; extensions are sorted in ascending
+order only. If placed at the beginning of the list, files are sorted according
+to these flags first, and then grouped by the remaining items in the list. If
+the flags are in any other position of the list, this special sorting is done
+secondarily. See examples 4, 5, and 6 below.
+
+After this sorting is done, the files in each group are sorted alphabetically.
+
+Examples: >
+ (1) ['*', '\/$']
+ (2) []
+ (3) ['\/$', '\.rb$', '\.php$', '*', '\.swp$', '\.bak$', '\~$']
+ (4) ['[[-size]]']
+ (5) ['\/$', '*', '[[timestamp]]']
+ (6) ['foo','\/$','[[extension]]']
+<
+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.
+4. Everything is sorted by size, largest to smallest, with directories
+ considered to have size 0 bytes.
+5. Directories will appear first alphabetically, followed by files, sorted by
+ timestamp, oldest first.
+6. Files and directories matching 'foo' first, followed by other directories,
+ then all other files. Each section of files is sorted by file extension.
+
+------------------------------------------------------------------------------
+ *NERDTreeStatusline*
+Values: Any valid `'statusline'` setting.
+Default: %{exists('b:NERDTree')?b:NERDTree.root.path.str():''}
+
+Defines the value for the `'statusline'` setting in NERDTree windows.
+
+Note: The setting is actually applied using |:let-&|, not |:set|, so
+escaping spaces is not necessary.
+
+Setting this to -1 will deactivate it so that your global `'statusline'`
+setting is used.
+
+------------------------------------------------------------------------------
+ *NERDTreeWinPos*
+Values: "left" or "right"
+Default: "left".
+
+This setting is used to determine where NERDTree window is placed on the
+screen.
+
+This setting 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 NERDTree on the right.
+
+------------------------------------------------------------------------------
+ *NERDTreeWinSize*
+Values: a positive integer.
+Default: 31.
+
+This setting is used to change the size of the NERDTree when it is loaded.
+
+------------------------------------------------------------------------------
+ *NERDTreeMinimalUI*
+Values: 0 or 1
+Default: 0
+
+This setting disables the 'Bookmarks' label 'Press ? for help' text. Use one
+of the following lines for this setting: >
+ let NERDTreeMinimalUI=0
+ let NERDTreeMinimalUI=1
+<
+------------------------------------------------------------------------------
+ *NERDTreeMinimalMenu*
+Values: 0 or 1
+Default: 0
+
+This setting makes NERDTree use a smaller, more compact menu for adding,
+copying, deleting nodes. This menu fits on a single line so Vim doesn't need to
+scroll down to present it. This setting is recommended for users already
+familiar with the menu items. It will look similar to this:
+
+ Menu: [ (a)dd ,m,d,r,o,q,c,l] (Use j/k/enter or shortcut):
+
+An action can be selected with its shortcut key or with the NERDTreeMenuUp and
+NERDTreeMenuDown keys, then pressing enter.
+
+Use one of the following lines for this setting: >
+ let NERDTreeMinimalMenu=0
+ let NERDTreeMinimalMenu=1
+<
+------------------------------------------------------------------------------
+ *NERDTreeCascadeSingleChildDir*
+Values: 0 or 1
+Default: 1.
+
+When displaying dir nodes, this setting tells NERDTree to collapse dirs that
+have only one child. Use one of the following lines for this setting: >
+ let NERDTreeCascadeSingleChildDir=0
+ let NERDTreeCascadeSingleChildDir=1
+<
+------------------------------------------------------------------------------
+ *NERDTreeCascadeOpenSingleChildDir*
+Values: 0 or 1
+Default: 1.
+
+When opening dir nodes, this setting 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 setting also causes
+the |NERDTree-x| mapping to close dirs in the same manner. This setting may be
+useful for Java projects. Use one of the following lines for this setting: >
+ 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 setting is not set you will
+see a confirmation if you really want to delete an old buffer. If you always
+press 'y' then it's worth it to set this setting to 1. Use one of the
+following lines for this setting: >
+ let NERDTreeAutoDeleteBuffer=0
+ let NERDTreeAutoDeleteBuffer=1
+<
+------------------------------------------------------------------------------
+ *NERDTreeCreatePrefix*
+Values: Any valid command prefix.
+Default: "silent".
+
+Internally, NERDTree uses the |:edit| command to create a buffer in which to
+display its tree view. You can augment this behavior by specifying a prefix
+string such as "keepalt" or similar. For example, to have NERDTree create its
+tree window using `silent keepalt keepjumps edit`: >
+ let NERDTreeCreatePrefix='silent keepalt keepjumps'
+<
+------------------------------------------------------------------------------
+ *NERDTreeDirArrowCollapsible* *NERDTreeDirArrowExpandable*
+Values: Any single character.
+Defaults: Windows: ~ and + Others: ▾ and ▸
+
+These characters indicate whether a directory is collapsible or expandable.
+Example: >
+ let NERDTreeDirArrowExpandable=">"
+ let NERDTreeDirArrowCollapsible="v"
+<
+They can be set to "\u00a0" to replace the arrows with a non-breaking space.
+If you do this you may need to change the node delimiter. See
+|NERDTreeNodeDelimiter|. You cannot use the same character for both the arrows
+and the delimiter.
+
+Alternatively, they can be set to '' (an empty string). This removes the
+arrows and the single space that follows them, shifting the entire tree two
+character positions to the left.
+
+------------------------------------------------------------------------------
+ *NERDTreeNodeDelimiter*
+Values: Any single character.
+Default: varies (see below)
+
+This character is used to separate the file or directory name from the rest of
+the characters in the line of text. It allows filenames to contain special
+characters that are otherwise used in the NERDTree, such as square brackets,
+braces, trailing asterisk, and leading space. For more details, see the
+responsible pull request: https://github.com/preservim/nerdtree/pull/868.
+
+The default value of this variable depends on the features compiled into your
+vim and the values of |NERDTreeDirArrowCollapsible| and
+|NERDTreeDirArrowExpandable|.
+ * If your vim is compiled with the +conceal feature, it is the "\x07" (BELL)
+ character, and it is hidden by setting 'conceallevel' to 3. If you use
+ autocommands, make sure none of them change that setting in the NERDTree_*
+ buffers.
+ * If your vim does NOT have the +conceal feature and you're using "\u00a0"
+ (non-breaking space) to hide the directory arrows, "\u00b7" (middle dot)
+ is used as the default delimiter.
+ * If neither condition above applies, NERDTree uses "\u00a0" (non-breaking
+ space) as the default delimiter.
+
+In the 2nd and 3rd cases, NERDTree will use the Ignore highlight group to
+"hide" the delimiter. It should appear as an empty space.
+
+Other plugins can interfere with these defaults, so if you need to change the
+delimiter, be sure to choose a character that won't appear in your filenames
+or any of the flags set by your installed NERDTree plugins. The suggestions
+below are but a few of the many possibilities. Remember to use double quotes
+when specifying by hex or Unicode. >
+ let NERDTreeNodeDelimiter="\x07" "bell
+ let NERDTreeNodeDelimiter="\u00b7" "middle dot
+ let NERDTreeNodeDelimiter="\u00a0" "non-breaking space
+ let NERDTreeNodeDelimiter="😀" "smiley face
+<
+------------------------------------------------------------------------------
+ *NERDTreeCustomOpenArgs*
+Values: A nested dictionary, as described below
+Default: {'file': {'reuse': 'all', 'where': 'p'}, 'dir': {}}
+
+This dictionary contains two keys, 'file' and 'dir', whose values each are
+another dictionary. The inner dictionary is a set of parameters used by
+|NERDTree-<CR>| to open a file or directory. Setting these parameters allows you
+to customize the way the node is opened. The default value matches what
+|NERDTree-o| does. To change that behavior, use these keys and
+values in the inner dictionaries:
+
+'where': specifies whether the node should be opened in a new split ("h" or
+ "v"), in a new tab ("t") or, in the last window ("p").
+'reuse': if file is already shown in a window, jump there; takes values
+ "all", "currenttab", or empty
+'keepopen': boolean (0 or 1); if true, the tree window will not be closed
+'stay': boolean (0 or 1); if true, remain in tree window after opening
+
+For example:
+To open files and directories (creating a new NERDTree) in a new tab, >
+ {'file':{'where': 't'}, 'dir':{'where':'t'}}
+<
+To open a file always in the current tab, and expand directories in place, >
+ {'file': {'reuse':'currenttab', 'where':'p', 'keepopen':1, 'stay':1}}
+<
+==============================================================================
+4. The NERDTree API *NERDTreeAPI*
+
+The NERDTree 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
+
+A number of API functions take a callback argument to call. The callback can
+be either a string with the name of a function to call, or a |Funcref| object
+which will be called directly.
+
+------------------------------------------------------------------------------
+4.1. Key map API *NERDTreeKeymapAPI*
+
+NERDTreeAddKeyMap({options}) *NERDTreeAddKeyMap()*
+ Adds a new keymapping for all NERDTree 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 node OR a directory node
+ "Bookmark" .... a bookmark
+ "all" ......... global scope; handler receives no arguments (default)
+
+ 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 NERDTree 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
+<
+------------------------------------------------------------------------------
+4.4 Path Listener API *NERDTreePathListenerAPI*
+
+Use this API if you want to run a callback for events on Path objects. E.G >
+
+ call g:NERDTreePathNotifier.AddListener("init", "MyListener")
+
+ "....
+
+ function! MyListener(event)
+ "This function will be called whenever a Path object is created.
+
+ "a:event is an object that contains a bunch of relevant info -
+ "including the affected path. See lib/nerdtree/event.vim for details.
+ endfunction
+<
+Current events supported:
+ init ~
+ refresh ~
+ refreshFlags ~
+
+------------------------------------------------------------------------------
+NERDTreeRender() *NERDTreeRender()*
+ Re-renders the NERDTree 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 NERDTree 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 ;)
+
+Martyzilla recruited two other unwitting accomplices to become his minions in
+his quest to conquer the Vim plugin world. While he may still love to receive
+your emails, the best way to send suggestions, bug reports, and questions is
+to submit an issue at http://github.com/preservim/nerdtree/issues.
+
+The latest stable and development versions are on Github.
+ Stable: http://github.com/preservim/nerdtree (master branch)
+ Development: http://github.com/preservim/nerdtree/branches
+
+Title Credit:
+ * http://ascii.co.uk/art/tree
+
+ * Patrick Gillespie's Text ASCII Art Generator
+ http://patorjk.com/software/taag
+ http://patorjk.com/software/taag/#p=display&f=Rozzo&t=the%20NERD%20Tree
+
+==============================================================================
+6. License *NERDTreeLicense*
+
+The NERDTree is released under the wtfpl.
+See http://sam.zoy.org/wtfpl/COPYING.
+
+------------------------------------------------------------------------------
+ vim:tw=78:ts=8:ft=help:noet:nospell
diff --git a/.config/nvim/plugged/nerdtree/lib/nerdtree/bookmark.vim b/.config/nvim/plugged/nerdtree/lib/nerdtree/bookmark.vim
new file mode 100644
index 0000000..248bb07
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/lib/nerdtree/bookmark.vim
@@ -0,0 +1,365 @@
+" ============================================================================
+" CLASS: Bookmark
+"
+" The Bookmark class serves two purposes:
+" (1) It is the top-level prototype for new, concrete Bookmark objects.
+" (2) It provides an interface for client code to query and manipulate the
+" global list of Bookmark objects within the current Vim session.
+" ============================================================================
+
+
+let s:Bookmark = {}
+let g:NERDTreeBookmark = s:Bookmark
+
+" FUNCTION: Bookmark.activate(nerdtree) {{{1
+function! s:Bookmark.activate(nerdtree, ...)
+ call self.open(a:nerdtree, 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))
+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 that returns the Bookmark object having the specified name.
+" Throws NERDTree.BookmarkNotFoundError if no Bookmark is found.
+function! s:Bookmark.BookmarkFor(name)
+ let l:result = {}
+ for l:bookmark in s:Bookmark.Bookmarks()
+ if l:bookmark.name ==# a:name
+ let l:result = l:bookmark
+ break
+ endif
+ endfor
+ if empty(l:result)
+ throw 'NERDTree.BookmarkNotFoundError: "' . a:name . '" not found'
+ endif
+ return l:result
+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', '')
+ let path = fnamemodify(path, ':p')
+
+ 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
+ endif
+endfunction
+
+" FUNCTION: Bookmark.CompareBookmarksByName(firstBookmark, secondBookmark) {{{1
+" Class method that indicates the relative position of two bookmarks when
+" placed in alphabetical order by name. Case-sensitivity is determined by an
+" option. Supports the s:Bookmark.SortBookmarksList() method.
+function! s:Bookmark.CompareBookmarksByName(firstBookmark, secondBookmark)
+ let l:result = 0
+ if g:NERDTreeBookmarksSort ==# 1
+ if a:firstBookmark.name <? a:secondBookmark.name
+ let l:result = -1
+ elseif a:firstBookmark.name >? a:secondBookmark.name
+ let l:result = 1
+ endif
+ elseif g:NERDTreeBookmarksSort ==# 2
+ if a:firstBookmark.name <# a:secondBookmark.name
+ let l:result = -1
+ elseif a:firstBookmark.name ># a:secondBookmark.name
+ let l:result = 1
+ endif
+ endif
+ return l:result
+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()
+ call remove(s:Bookmark.Bookmarks(), index(s:Bookmark.Bookmarks(), self))
+ call s:Bookmark.Write()
+endfunction
+
+" FUNCTION: s:Edit() {{{1
+" opens the NERDTreeBookmarks file for manual editing
+function! s:Bookmark.Edit()
+ call nerdtree#exec('wincmd w', 1)
+ call nerdtree#exec('edit '.g:NERDTreeBookmarksFile, 1)
+endfunction
+
+" FUNCTION: Bookmark.getNode(nerdtree, searchFromAbsoluteRoot) {{{1
+" Returns the tree node object associated with this Bookmark.
+" Throws NERDTree.BookmarkedNodeNotFoundError if the node is not found.
+"
+" Args:
+" searchFromAbsoluteRoot: boolean flag, search from the highest cached node
+" if true and from the current tree root if false
+function! s:Bookmark.getNode(nerdtree, searchFromAbsoluteRoot)
+ if a:searchFromAbsoluteRoot
+ let l:searchRoot = a:nerdtree.root.AbsoluteTreeRoot()
+ else
+ let l:searchRoot = a:nerdtree.root
+ endif
+ let l:targetNode = l:searchRoot.findNode(self.path)
+ if empty(l:targetNode)
+ throw 'NERDTree.BookmarkedNodeNotFoundError: node for bookmark "' . self.name . '" not found'
+ endif
+ return l:targetNode
+endfunction
+
+" FUNCTION: Bookmark.GetNodeForName(name, searchFromAbsoluteRoot, nerdtree) {{{1
+" Class method that returns the tree node object for the Bookmark with the
+" given name. Throws NERDTree.BookmarkNotFoundError if a Bookmark with the
+" name does not exist. Throws NERDTree.BookmarkedNodeNotFoundError if a
+" tree node for the named Bookmark could not be found.
+function! s:Bookmark.GetNodeForName(name, searchFromAbsoluteRoot, nerdtree)
+ let l:bookmark = s:Bookmark.BookmarkFor(a:name)
+ return l:bookmark.getNode(a:nerdtree, 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(nerdtree, [options]) {{{1
+"Args:
+"
+"nerdtree: the tree to load open the bookmark in
+"
+"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(nerdtree, ...)
+ let opts = a:0 ? a:1 : {}
+
+ if nerdtree#and(g:NERDTreeQuitOnOpen,2)
+ call a:nerdtree.ui.toggleShowBookmarks()
+ endif
+
+ if self.path.isDirectory && !has_key(opts, 'where')
+ call self.toRoot(a:nerdtree)
+ 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.SortBookmarksList() {{{1
+" Class method that sorts the global list of bookmarks alphabetically by name.
+" Note that case-sensitivity is determined by a user option.
+function! s:Bookmark.SortBookmarksList()
+ call sort(s:Bookmark.Bookmarks(), s:Bookmark.CompareBookmarksByName, s:Bookmark)
+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 - strdisplaywidth(self.name)
+ if &number
+ let pathStrMaxLen = pathStrMaxLen - &numberwidth
+ endif
+
+ let pathStr = self.path.str({'format': 'UI'})
+ if strdisplaywidth(pathStr) > pathStrMaxLen
+ while strdisplaywidth(pathStr) > pathStrMaxLen && strchars(pathStr) > 0
+ let pathStr = substitute(pathStr, '^.', '', '')
+ endwhile
+ let pathStr = '<' . pathStr
+ endif
+ return '>' . self.name . ' ' . pathStr
+endfunction
+
+" FUNCTION: Bookmark.toRoot(nerdtree) {{{1
+" Set the root of the given NERDTree to the node for this Bookmark. If a node
+" for this Bookmark does not exist, a new one is initialized.
+function! s:Bookmark.toRoot(nerdtree)
+ if self.validate()
+ try
+ let l:targetNode = self.getNode(a:nerdtree, 1)
+ call l:targetNode.closeChildren()
+ catch /^NERDTree.BookmarkedNodeNotFoundError/
+ let l:targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path, a:nerdtree)
+ endtry
+ call a:nerdtree.changeRoot(l:targetNode)
+ endif
+endfunction
+
+" FUNCTION: Bookmark.ToRoot(name, nerdtree) {{{1
+" Class method that makes the Bookmark with the given name the root of
+" specified NERDTree.
+function! s:Bookmark.ToRoot(name, nerdtree)
+ let l:bookmark = s:Bookmark.BookmarkFor(a:name)
+ call l:bookmark.toRoot(a:nerdtree)
+endfunction
+
+" FUNCTION: Bookmark.validate() {{{1
+function! s:Bookmark.validate()
+ if self.path.exists()
+ return 1
+ else
+ call s:Bookmark.CacheBookmarks(1)
+ 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 . ' ' . fnamemodify(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
+
+ try
+ call writefile(bookmarkStrings, g:NERDTreeBookmarksFile)
+ catch
+ call nerdtree#echoError('Failed to write bookmarks file. Make sure g:NERDTreeBookmarksFile points to a valid location.')
+ endtry
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/.config/nvim/plugged/nerdtree/lib/nerdtree/creator.vim b/.config/nvim/plugged/nerdtree/lib/nerdtree/creator.vim
new file mode 100644
index 0000000..e2b3fa0
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/lib/nerdtree/creator.vim
@@ -0,0 +1,395 @@
+" ============================================================================
+" CLASS: Creator
+"
+" This class is responsible for creating NERDTree instances. The new NERDTree
+" may be a tab tree, a window tree, or a mirrored tree. In the process of
+" creating a NERDTree, it sets up all of 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()
+ call g:NERDTreeKeyMap.BindAll()
+
+ command! -buffer -nargs=? Bookmark :call nerdtree#ui_glue#bookmarkNode('<args>')
+ command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#ui_glue#revealBookmark('<args>')
+ command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark call nerdtree#ui_glue#openBookmark('<args>')
+ command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#ui_glue#clearBookmarks('<args>')
+ command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=+ BookmarkToRoot call g:NERDTreeBookmark.ToRoot('<args>', b:NERDTree)
+ command! -buffer -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() <bar> call b:NERDTree.render()
+ command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) <bar> call b:NERDTree.render()
+ command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write()
+ command! -buffer -nargs=0 EditBookmarks call g:NERDTreeBookmark.Edit()
+endfunction
+
+" FUNCTION: s:Creator._broadcastInitEvent() {{{1
+function! s:Creator._broadcastInitEvent()
+ silent doautocmd User NERDTreeInit
+endfunction
+
+" FUNCTION: s:Creator.BufNamePrefix() {{{1
+function! s:Creator.BufNamePrefix()
+ return 'NERD_tree_'
+endfunction
+
+" FUNCTION: s:Creator.CreateTabTree(a:name) {{{1
+function! s:Creator.CreateTabTree(name)
+ let creator = s:Creator.New()
+ call creator.createTabTree(a:name)
+endfunction
+
+" FUNCTION: s:Creator.createTabTree(a:name) {{{1
+" name: the name of a bookmark or a directory
+function! s:Creator.createTabTree(name)
+ let l:path = self._pathForString(a:name)
+
+ " Abort if an exception was thrown (i.e., if the bookmark or directory
+ " does not exist).
+ if empty(l:path)
+ return
+ endif
+
+ " Obey the user's preferences for changing the working directory.
+ if g:NERDTreeChDirMode != 0
+ call l:path.changeToDir()
+ endif
+
+ if g:NERDTree.ExistsForTab()
+ call g:NERDTree.Close()
+ call self._removeTreeBufForTab()
+ endif
+
+ call self._createTreeWin()
+ call self._createNERDTree(l:path, 'tab')
+ call b:NERDTree.render()
+ call b:NERDTree.root.putCursorHere(0, 0)
+
+ call self._broadcastInitEvent()
+endfunction
+
+" FUNCTION: s:Creator.CreateWindowTree(dir) {{{1
+function! s:Creator.CreateWindowTree(dir)
+ let creator = s:Creator.New()
+ call creator.createWindowTree(a:dir)
+endfunction
+
+" FUNCTION: s:Creator.createWindowTree(dir) {{{1
+function! s:Creator.createWindowTree(dir)
+ try
+ let path = g:NERDTreePath.New(a:dir)
+ catch /^NERDTree.InvalidArgumentsError/
+ call nerdtree#echo('Invalid directory name:' . a:dir)
+ 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 window tree buffer to ensure they are
+ "all independent
+ exec g:NERDTreeCreatePrefix . ' edit ' . self._nextBufferName()
+
+ call self._createNERDTree(path, 'window')
+ let b:NERDTree._previousBuf = bufnr(previousBuf)
+ call self._setCommonBufOptions()
+
+ call b:NERDTree.render()
+
+ call self._broadcastInitEvent()
+endfunction
+
+" FUNCTION: s:Creator._createNERDTree(path) {{{1
+function! s:Creator._createNERDTree(path, type)
+ let b:NERDTree = g:NERDTree.New(a:path, a:type)
+
+ " TODO: This assignment is kept for compatibility reasons. Many other
+ " plugins use b:NERDTreeRoot instead of b:NERDTree.root. Remove this
+ " assignment in the future.
+ 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, 'NERDTree').root
+ 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
+" Initialize the NERDTree window. Open the window, size it properly, set all
+" local options, etc.
+function! s:Creator._createTreeWin()
+ let l:splitLocation = g:NERDTreeWinPos ==# 'left' ? 'topleft ' : 'botright '
+ let l:splitSize = g:NERDTreeWinSize
+
+ if !g:NERDTree.ExistsForTab()
+ let t:NERDTreeBufName = self._nextBufferName()
+ silent! execute l:splitLocation . 'vertical ' . l:splitSize . ' new'
+ silent! execute 'edit ' . t:NERDTreeBufName
+ silent! execute 'vertical resize '. l:splitSize
+ else
+ silent! execute l:splitLocation . 'vertical ' . l:splitSize . ' split'
+ silent! execute 'buffer ' . t:NERDTreeBufName
+ endif
+
+ setlocal winfixwidth
+
+ call self._setCommonBufOptions()
+
+ if has('patch-7.4.1925')
+ clearjumps
+ endif
+
+endfunction
+
+" FUNCTION: s:Creator._isBufHidden(nr) {{{1
+function! s:Creator._isBufHidden(nr)
+ redir => bufs
+ silent ls!
+ redir END
+
+ return bufs =~ a:nr . '..h'
+endfunction
+
+" FUNCTION: s:Creator.New() {{{1
+function! s:Creator.New()
+ let newCreator = copy(self)
+ return newCreator
+endfunction
+
+" FUNCTION: s:Creator._nextBufferName() {{{1
+" 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() {{{1
+" 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._removeTreeBufForTab() {{{1
+function! s:Creator._removeTreeBufForTab()
+ let buf = bufnr(t:NERDTreeBufName)
+
+ "if &hidden is not set then it will already be gone
+ if buf != -1
+
+ "nerdtree buf may be mirrored/displayed elsewhere
+ if self._isBufHidden(buf)
+ exec 'bwipeout ' . buf
+ endif
+
+ endif
+
+ unlet t:NERDTreeBufName
+endfunction
+
+" FUNCTION: s:Creator._setCommonBufOptions() {{{1
+function! s:Creator._setCommonBufOptions()
+
+ " Options for a non-file/control buffer.
+ setlocal bufhidden=hide
+ setlocal buftype=nofile
+ setlocal noswapfile
+
+ " Options for controlling buffer/window appearance.
+ setlocal foldcolumn=0
+ setlocal foldmethod=manual
+ setlocal nobuflisted
+ setlocal nofoldenable
+ setlocal nolist
+ setlocal nospell
+ setlocal nowrap
+
+ if g:NERDTreeShowLineNumbers
+ setlocal number
+ else
+ setlocal nonumber
+ if v:version >= 703
+ setlocal norelativenumber
+ endif
+ endif
+
+ iabc <buffer>
+
+ if g:NERDTreeHighlightCursorline
+ setlocal cursorline
+ endif
+
+ call self._setupStatusline()
+ 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 = &eventignore
+ set eventignore=all
+
+ try
+ exec 'tabnext ' . a:tabnr
+ let v = -1
+ if exists('t:' . a:var)
+ exec 'let v = t:' . a:var
+ endif
+ exec 'tabnext ' . currentTab
+
+ finally
+ let &eventignore = old_ei
+ endtry
+
+ return v
+endfunction
+
+" FUNCTION: s:Creator.ToggleTabTree(dir) {{{1
+function! s:Creator.ToggleTabTree(dir)
+ let creator = s:Creator.New()
+ call creator.toggleTabTree(a:dir)
+endfunction
+
+" FUNCTION: s:Creator.toggleTabTree(dir) {{{1
+" Toggles the NERD tree. I.e if the NERD tree is open, it is closed. If it is
+" closed, it is restored or initialized. If dir is not empty, it will be set
+" as the new root.
+"
+" Args:
+" dir: the full path for the root node (is used if the NERD tree is being
+" initialized, or to change the root to a new dir.)
+function! s:Creator.toggleTabTree(dir)
+ if g:NERDTree.ExistsForTab()
+ if !g:NERDTree.IsOpen()
+ call self._createTreeWin()
+ if !empty(a:dir)
+ call self.createTabTree(a:dir)
+ elseif !&hidden
+ call b:NERDTree.render()
+ endif
+ call b:NERDTree.ui.restoreScreenState()
+ else
+ call g:NERDTree.Close()
+ endif
+ else
+ call self.createTabTree(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/nvim/plugged/nerdtree/lib/nerdtree/event.vim b/.config/nvim/plugged/nerdtree/lib/nerdtree/event.vim
new file mode 100644
index 0000000..964e8ff
--- /dev/null
+++ b/.config/nvim/plugged/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/nvim/plugged/nerdtree/lib/nerdtree/flag_set.vim b/.config/nvim/plugged/nerdtree/lib/nerdtree/flag_set.vim
new file mode 100644
index 0000000..7552867
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/lib/nerdtree/flag_set.vim
@@ -0,0 +1,58 @@
+"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
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/.config/nvim/plugged/nerdtree/lib/nerdtree/key_map.vim b/.config/nvim/plugged/nerdtree/lib/nerdtree/key_map.vim
new file mode 100644
index 0000000..f3268c2
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/lib/nerdtree/key_map.vim
@@ -0,0 +1,164 @@
+"CLASS: KeyMap
+"============================================================
+let s:KeyMap = {}
+let g:NERDTreeKeyMap = s:KeyMap
+let s:keyMaps = {}
+
+"FUNCTION: KeyMap.All() {{{1
+function! s:KeyMap.All()
+ let sortedKeyMaps = values(s:keyMaps)
+ call sort(sortedKeyMaps, s:KeyMap.Compare, s:KeyMap)
+
+ return sortedKeyMaps
+endfunction
+
+"FUNCTION: KeyMap.Compare(keyMap1, keyMap2) {{{1
+function! s:KeyMap.Compare(keyMap1, keyMap2)
+
+ if a:keyMap1.key >? a:keyMap2.key
+ return 1
+ endif
+
+ if a:keyMap1.key <? a:keyMap2.key
+ return -1
+ endif
+
+ return 0
+endfunction
+
+"FUNCTION: KeyMap.FindFor(key, scope) {{{1
+function! s:KeyMap.FindFor(key, scope)
+ return get(s:keyMaps, a:key . a:scope, {})
+endfunction
+
+"FUNCTION: KeyMap.BindAll() {{{1
+function! s:KeyMap.BindAll()
+ for i in values(s:keyMaps)
+ 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 '<lt>' 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, '<lt>\1', 'g')
+ else
+ let keymapInvokeString = self.key
+ endif
+ let keymapInvokeString = escape(keymapInvokeString, '\')
+
+ let premap = self.key ==# '<LeftRelease>' ? ' <LeftRelease>' : ' '
+
+ exec 'nnoremap <buffer> <silent> '. self.key . premap . ':call nerdtree#ui_glue#invokeKeyMap("'. keymapInvokeString .'")<cr>'
+endfunction
+
+"FUNCTION: KeyMap.Remove(key, scope) {{{1
+function! s:KeyMap.Remove(key, scope)
+ return remove(s:keyMaps, a:key . a:scope)
+endfunction
+
+"FUNCTION: KeyMap.invoke() {{{1
+"Call the KeyMaps callback function
+function! s:KeyMap.invoke(...)
+ let Callback = type(self.callback) ==# type(function('tr')) ? self.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 <LeftRelease> mapping - but changes the window cursor
+ "is in first
+ "
+ "TODO: remove this check when the vim bug is fixed
+ if !g:NERDTree.ExistsForBuf()
+ return {}
+ endif
+
+ let node = g:NERDTreeFileNode.GetSelected()
+ 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)
+ let s:keyMaps[a:keymap.key . a:keymap.scope] = a:keymap
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/.config/nvim/plugged/nerdtree/lib/nerdtree/menu_controller.vim b/.config/nvim/plugged/nerdtree/lib/nerdtree/menu_controller.vim
new file mode 100644
index 0000000..952c67b
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/lib/nerdtree/menu_controller.vim
@@ -0,0 +1,211 @@
+"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: s:MenuController.isMinimal() {{{1
+function! s:MenuController.isMinimal()
+ return g:NERDTreeMinimalMenu
+endfunction
+
+" FUNCTION: MenuController.showMenu() {{{1
+" Enter the main loop of the NERDTree menu, prompting the user to select
+" a menu item.
+function! s:MenuController.showMenu()
+ call self._saveOptions()
+
+ try
+ let self.selection = 0
+ let l:done = 0
+
+ while !l:done
+ if has('nvim')
+ mode
+ else
+ redraw!
+ endif
+ call self._echoPrompt()
+
+ let l:key = nr2char(getchar())
+ let l:done = self._handleKeypress(l:key)
+ endwhile
+ finally
+ call self._restoreOptions()
+
+ " Redraw when Ctrl-C or Esc is received.
+ if !l:done || self.selection ==# -1
+ redraw!
+ endif
+ endtry
+
+ if self.selection !=# -1
+ let l:m = self._current()
+ call l:m.execute()
+ endif
+endfunction
+
+"FUNCTION: MenuController._echoPrompt() {{{1
+function! s:MenuController._echoPrompt()
+ let navHelp = 'Use ' . g:NERDTreeMenuDown . '/' . g:NERDTreeMenuUp . '/enter'
+
+ if self.isMinimal()
+ let selection = self.menuItems[self.selection].text
+ let keyword = matchstr(selection, '[^ ]*([^ ]*')
+
+ let shortcuts = map(copy(self.menuItems), "v:val['shortcut']")
+ let shortcuts[self.selection] = ' ' . keyword . ' '
+
+ echo 'Menu: [' . join(shortcuts, ',') . '] (' . navHelp . ' or shortcut): '
+ else
+ echo 'NERDTree Menu. ' . navHelp . ', or 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
+ endif
+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 ==# g:NERDTreeMenuDown
+ call self._cursorDown()
+ elseif a:key ==# g:NERDTreeMenuUp
+ 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()
+ if self.isMinimal()
+ let &cmdheight = 1
+ else
+ let &cmdheight = len(self.menuItems) + 3
+ endif
+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/nvim/plugged/nerdtree/lib/nerdtree/menu_item.vim b/.config/nvim/plugged/nerdtree/lib/nerdtree/menu_item.vim
new file mode 100644
index 0000000..7f25917
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/lib/nerdtree/menu_item.vim
@@ -0,0 +1,118 @@
+"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 type(self.isActiveCallback) == type(function('tr')) ? self.isActiveCallback() : {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
+ if type(self.callback) == type(function('tr'))
+ call self.callback()
+ else
+ call {self.callback}()
+ endif
+ 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/nvim/plugged/nerdtree/lib/nerdtree/nerdtree.vim b/.config/nvim/plugged/nerdtree/lib/nerdtree/nerdtree.vim
new file mode 100644
index 0000000..a48f6a8
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/lib/nerdtree/nerdtree.vim
@@ -0,0 +1,215 @@
+"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.changeRoot(node) {{{1
+function! s:NERDTree.changeRoot(node)
+ if a:node.path.isDirectory
+ let self.root = a:node
+ else
+ call a:node.cacheParent()
+ let self.root = a:node.parent
+ endif
+
+ call self.root.open()
+
+ "change dir to the dir of the new root if instructed to
+ if g:NERDTreeChDirMode >= 2
+ call self.root.path.changeToDir()
+ endif
+
+ call self.render()
+ call self.root.putCursorHere(0, 0)
+
+ silent doautocmd User NERDTreeNewRoot
+endfunction
+
+"FUNCTION: s:NERDTree.Close() {{{1
+"Closes the tab tree window for this tab
+function! s:NERDTree.Close()
+ if !s:NERDTree.IsOpen()
+ return
+ endif
+
+ if winnr('$') !=# 1
+ " Use the window ID to identify the currently active window or fall
+ " back on the buffer ID if win_getid/win_gotoid are not available, in
+ " which case we'll focus an arbitrary window showing the buffer.
+ let l:useWinId = exists('*win_getid') && exists('*win_gotoid')
+
+ if winnr() ==# s:NERDTree.GetWinNum()
+ call nerdtree#exec('wincmd p', 1)
+ let l:activeBufOrWin = l:useWinId ? win_getid() : bufnr('')
+ call nerdtree#exec('wincmd p', 1)
+ else
+ let l:activeBufOrWin = l:useWinId ? win_getid() : bufnr('')
+ endif
+
+ call nerdtree#exec(s:NERDTree.GetWinNum() . ' wincmd w', 1)
+ call nerdtree#exec('close', 0)
+ if l:useWinId
+ call nerdtree#exec('call win_gotoid(' . l:activeBufOrWin . ')', 0)
+ else
+ call nerdtree#exec(bufwinnr(l:activeBufOrWin) . ' wincmd w', 0)
+ endif
+ 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 nerdtree#and(g:NERDTreeQuitOnOpen,1) && 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:NERDTree.ui.getShowBookmarks()
+ 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', 1)
+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:NERDTree')
+endfunction
+
+" Function: s:NERDTree.ExistsForTab() {{{1
+" Returns 1 if a nerd tree root exists in the current tab
+function! s:NERDTree.ExistsForTab()
+ if !exists('t:NERDTreeBufName')
+ return
+ end
+
+ "check b:NERDTree is still there and hasn't been e.g. :bdeleted
+ return !empty(getbufvar(bufnr(t:NERDTreeBufName), 'NERDTree'))
+endfunction
+
+function! s:NERDTree.ForCurrentBuf()
+ if s:NERDTree.ExistsForBuf()
+ return b:NERDTree
+ else
+ return {}
+ endif
+endfunction
+
+"FUNCTION: s:NERDTree.ForCurrentTab() {{{1
+function! s:NERDTree.ForCurrentTab()
+ if !s:NERDTree.ExistsForTab()
+ return
+ endif
+
+ let bufnr = bufnr(t:NERDTreeBufName)
+ return getbufvar(bufnr, 'NERDTree')
+endfunction
+
+"FUNCTION: s:NERDTree.getRoot() {{{1
+function! s:NERDTree.getRoot()
+ return self.root
+endfunction
+
+"FUNCTION: s:NERDTree.GetWinNum() {{{1
+"gets the nerd tree window number for this tab
+function! s:NERDTree.GetWinNum()
+ if exists('t:NERDTreeBufName')
+ return bufwinnr(t:NERDTreeBufName)
+ endif
+
+ " If WindowTree, there is no t:NERDTreeBufName variable. Search all windows.
+ for w in range(1,winnr('$'))
+ if bufname(winbufnr(w)) =~# '^' . g:NERDTreeCreator.BufNamePrefix() . '\d\+$'
+ return w
+ endif
+ endfor
+
+ return -1
+endfunction
+
+"FUNCTION: s:NERDTree.IsOpen() {{{1
+function! s:NERDTree.IsOpen()
+ return s:NERDTree.GetWinNum() !=# -1
+endfunction
+
+"FUNCTION: s:NERDTree.isTabTree() {{{1
+function! s:NERDTree.isTabTree()
+ return self._type ==# 'tab'
+endfunction
+
+"FUNCTION: s:NERDTree.isWinTree() {{{1
+function! s:NERDTree.isWinTree()
+ return self._type ==# 'window'
+endfunction
+
+"FUNCTION: s:NERDTree.MustBeOpen() {{{1
+function! s:NERDTree.MustBeOpen()
+ if !s:NERDTree.IsOpen()
+ throw 'NERDTree.TreeNotOpen'
+ endif
+endfunction
+
+"FUNCTION: s:NERDTree.New() {{{1
+function! s:NERDTree.New(path, type)
+ let newObj = copy(self)
+ let newObj.ui = g:NERDTreeUI.New(newObj)
+ let newObj.root = g:NERDTreeDirNode.New(a:path, newObj)
+ let newObj._type = a:type
+ 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.previousBuf() {{{1
+function! s:NERDTree.previousBuf()
+ return self._previousBuf
+endfunction
+
+function! s:NERDTree.setPreviousBuf(bnum)
+ let self._previousBuf = a:bnum
+endfunction
+
+"FUNCTION: s:NERDTree.render() {{{1
+"A convenience function - since this is called often
+function! s:NERDTree.render()
+ call self.ui.render()
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/.config/nvim/plugged/nerdtree/lib/nerdtree/notifier.vim b/.config/nvim/plugged/nerdtree/lib/nerdtree/notifier.vim
new file mode 100644
index 0000000..fc3155d
--- /dev/null
+++ b/.config/nvim/plugged/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, nerdtree, params)
+ let event = g:NERDTreeEvent.New(a:nerdtree, a:path, a:event, a:params)
+
+ for Listener in s:Notifier.GetListenersForEvent(a:event)
+ let Callback = type(Listener) == type(function('tr')) ? Listener : function(Listener)
+ call Callback(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/nvim/plugged/nerdtree/lib/nerdtree/opener.vim b/.config/nvim/plugged/nerdtree/lib/nerdtree/opener.vim
new file mode 100644
index 0000000..d8dba34
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/lib/nerdtree/opener.vim
@@ -0,0 +1,328 @@
+" ============================================================================
+" CLASS: Opener
+"
+" The Opener class defines an API for 'opening' operations.
+" ============================================================================
+
+
+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:NERDTree.isWinTree()
+ if self._where ==# 'v'
+ call self._newVSplit()
+ elseif self._where ==# 'h'
+ call self._newSplit()
+ 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', 1)
+ let specialWindow = getbufvar('%', '&buftype') !=# '' || getwinvar('%', '&previewwindow')
+ let modified = &modified
+ call nerdtree#exec(oldwinnr . 'wincmd p', 1)
+
+ "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
+" Instantiate a new NERDTreeOpener object.
+" Args:
+" a:path: the path object that is to be opened
+" a:opts: a dictionary containing the following optional keys...
+" 'where': specifies whether the node should be opened in new split, in
+" a new tab or, in the last window; takes values 'v', 'h', or 't'
+" 'reuse': if file is already shown in a window, jump there; takes values
+" 'all', 'currenttab', or empty
+" 'keepopen': boolean (0 or 1); if true, the tree window will not be closed
+" 'stay': boolean (0 or 1); if true, remain in tree window after opening
+function! s:Opener.New(path, opts)
+ let l:newOpener = copy(self)
+
+ let l:newOpener._keepopen = nerdtree#has_opt(a:opts, 'keepopen')
+ let l:newOpener._nerdtree = b:NERDTree
+ let l:newOpener._path = a:path
+ let l:newOpener._reuse = has_key(a:opts, 'reuse') ? a:opts['reuse'] : ''
+ let l:newOpener._stay = nerdtree#has_opt(a:opts, 'stay')
+ let l:newOpener._where = has_key(a:opts, 'where') ? a:opts['where'] : ''
+
+ call l:newOpener._saveCursorPos()
+
+ return l:newOpener
+endfunction
+
+" FUNCTION: Opener._newSplit() {{{1
+function! s:Opener._newSplit()
+ let onlyOneWin = (winnr('$') ==# 1)
+ let savesplitright = &splitright
+ if onlyOneWin
+ let &splitright = (g:NERDTreeWinPos ==# 'left')
+ endif
+ " If only one window (ie. NERDTree), split vertically instead.
+ let splitMode = onlyOneWin ? 'vertical' : ''
+
+ " Open the new window
+ try
+ call nerdtree#exec('wincmd p', 1)
+ call nerdtree#exec(splitMode . ' split',1)
+ 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('wincmd p', 1)
+ call nerdtree#exec('silent '. splitMode .' resize '. size, 1)
+ call nerdtree#exec('wincmd p', 0)
+ endif
+
+ let &splitright=savesplitright
+endfunction
+
+" FUNCTION: Opener._newVSplit() {{{1
+function! s:Opener._newVSplit()
+ let l:winwidth = winwidth('.')
+
+ let onlyOneWin = (winnr('$') ==# 1)
+ let savesplitright = &splitright
+ if onlyOneWin
+ let &splitright = (g:NERDTreeWinPos ==# 'left')
+ let l:winwidth = g:NERDTreeWinSize
+ endif
+
+ call nerdtree#exec('wincmd p', 1)
+ call nerdtree#exec('vnew', 1)
+
+ let l:currentWindowNumber = winnr()
+
+ " Restore the NERDTree to its original width.
+ call g:NERDTree.CursorToTreeWin()
+ execute 'silent vertical resize ' . l:winwidth
+
+ call nerdtree#exec(l:currentWindowNumber . 'wincmd w', 0)
+ let &splitright=savesplitright
+endfunction
+
+" FUNCTION: Opener.open(target) {{{1
+function! s:Opener.open(target)
+ if self._path.isDirectory
+ call self._openDirectory(a:target)
+ return
+ endif
+
+ call self._openFile()
+endfunction
+
+" FUNCTION: Opener._openFile() {{{1
+function! s:Opener._openFile()
+ if !self._stay && !and(g:NERDTreeQuitOnOpen,1) && exists('b:NERDTreeZoomed') && b:NERDTreeZoomed
+ call b:NERDTree.ui.toggleZoom()
+ endif
+
+ if self._reuseWindow()
+ return
+ endif
+
+ call self._gotoTargetWin()
+
+ if self._stay
+ silent call self._path.edit()
+ call self._restoreCursorPos()
+ return
+ endif
+
+ call self._path.edit()
+endfunction
+
+" FUNCTION: Opener._openDirectory(node) {{{1
+function! s:Opener._openDirectory(node)
+ call self._gotoTargetWin()
+
+ if self._nerdtree.isWinTree()
+ call g:NERDTreeCreator.CreateWindowTree(a:node.path.str())
+ else
+ if empty(self._where)
+ call b:NERDTree.changeRoot(a:node)
+ elseif self._where ==# 't'
+ call g:NERDTreeCreator.CreateTabTree(a:node.path.str())
+ else
+ call g:NERDTreeCreator.CreateWindowTree(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', 1)
+ else
+ call nerdtree#exec('wincmd p', 1)
+ 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(self._tabnr . 'tabnext', 1)
+ call nerdtree#exec(bufwinnr(self._bufnr) . 'wincmd w', 1)
+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', 0)
+ 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(tabnr . 'tabnext', 1)
+ let winnr = bufwinnr('^' . self._path.str() . '$')
+ call nerdtree#exec(winnr . 'wincmd w', 0)
+ 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/nvim/plugged/nerdtree/lib/nerdtree/path.vim b/.config/nvim/plugged/nerdtree/lib/nerdtree/path.vim
new file mode 100644
index 0000000..6a23c7b
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/lib/nerdtree/path.vim
@@ -0,0 +1,897 @@
+" ============================================================================
+" CLASS: Path
+"
+" The Path class provides an abstracted representation of a file system
+" pathname. Various operations on pathnames are provided and a number of
+" representations of a given path name can be accessed here.
+" ============================================================================
+
+
+let s:Path = {}
+let g:NERDTreePath = s:Path
+
+" FUNCTION: Path.AbsolutePathFor(pathStr) {{{1
+function! s:Path.AbsolutePathFor(pathStr)
+ let l:prependWorkingDir = 0
+
+ if nerdtree#runningWindows()
+ let l:prependWorkingDir = a:pathStr !~# '^.:\(\\\|\/\)\?' && a:pathStr !~# '^\(\\\\\|\/\/\)'
+ else
+ let l:prependWorkingDir = a:pathStr !~# '^/'
+ endif
+
+ let l:result = a:pathStr
+
+ if l:prependWorkingDir
+ let l:result = getcwd()
+
+ if l:result[-1:] ==# s:Path.Slash()
+ let l:result = l:result . a:pathStr
+ else
+ let l:result = l:result . s:Path.Slash() . a:pathStr
+ endif
+ endif
+
+ return l:result
+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 = g:NERDTreeNodeDelimiter . self.getLastPathComponent(1)
+
+ if self.isExecutable
+ let self.cachedDisplayString = self.addDelimiter(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) && g:NERDTreeMarkBookmarks ==# 1
+ let self.cachedDisplayString = self.addDelimiter(self.cachedDisplayString) . ' {' . join(self._bookmarkNames) . '}'
+ endif
+
+ if self.isSymLink
+ let self.cachedDisplayString = self.addDelimiter(self.cachedDisplayString) . ' -> ' . self.symLinkDest
+ endif
+
+ if self.isReadOnly
+ let self.cachedDisplayString = self.addDelimiter(self.cachedDisplayString) . ' ['.g:NERDTreeGlyphReadOnly.']'
+ endif
+endfunction
+
+" FUNCTION: Path.addDelimiter() {{{1
+function! s:Path.addDelimiter(line)
+ if a:line =~# '\(.*' . g:NERDTreeNodeDelimiter . '\)\{2}'
+ return a:line
+ else
+ return a:line . g:NERDTreeNodeDelimiter
+ 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
+ if g:NERDTreeUseTCD && exists(':tcd') ==# 2
+ execute 'tcd ' . dir
+ call nerdtree#echo("Tab's CWD is now: " . getcwd())
+ else
+ execute 'cd ' . dir
+ call nerdtree#echo('CWD is now: ' . getcwd())
+ endif
+ 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)
+
+ if exists('g:NERDTreeCopyCmd')
+ let cmd_prefix = g:NERDTreeCopyCmd
+ else
+ let cmd_prefix = (self.isDirectory ? g:NERDTreeCopyDirCmd : g:NERDTreeCopyFileCmd)
+ endif
+
+ let cmd = cmd_prefix . ' ' . escape(self.str(), self._escChars()) . ' ' . escape(a:dest, self._escChars())
+ let success = system(cmd)
+ if v:shell_error !=# 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') || (exists('g:NERDTreeCopyDirCmd') && exists('g:NERDTreeCopyFileCmd'))
+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 if 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 or directory represented by this path.
+"
+" 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
+ if exists('g:NERDTreeRemoveFileCmd')
+ let cmd = g:NERDTreeRemoveFileCmd . self.str({'escape': 1})
+ let success = system(cmd)
+ else
+ let success = delete(self.str())
+ endif
+
+ 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 g:NERDTreeSortOrder[i] !~? '\[\[-\?\(timestamp\|size\|extension\)\]\]' &&
+ \ self.getLastPathComponent(1) =~# g:NERDTreeSortOrder[i]
+ return i
+ endif
+ let i = i + 1
+ endwhile
+
+ return index(g:NERDTreeSortOrder, '*')
+endfunction
+
+" FUNCTION: Path._splitChunks(path) {{{1
+" returns a list of path chunks
+function! s:Path._splitChunks(path)
+ let chunks = split(a:path, '\(\D\+\|\d\+\)\zs')
+ let i = 0
+ while i < len(chunks)
+ "convert number literals to numbers
+ if match(chunks[i], '^\d\+$') ==# 0
+ let chunks[i] = str2nr(chunks[i])
+ endif
+ let i = i + 1
+ endwhile
+ return chunks
+endfunction
+
+" FUNCTION: Path.getSortKey() {{{1
+" returns a key used in compare function for sorting
+function! s:Path.getSortKey()
+ if !exists('self._sortKey') || g:NERDTreeSortOrder !=# g:NERDTreeOldSortOrder
+ " Look for file metadata tags: [[timestamp]], [[extension]], [[size]]
+ let metadata = []
+ for tag in g:NERDTreeSortOrder
+ if tag =~? '\[\[-\?timestamp\]\]'
+ let metadata += [self.isDirectory ? 0 : getftime(self.str()) * (tag =~# '-' ? -1 : 1)]
+ elseif tag =~? '\[\[-\?size\]\]'
+ let metadata += [self.isDirectory ? 0 : getfsize(self.str()) * (tag =~# '-' ? -1 : 1)]
+ elseif tag =~? '\[\[extension\]\]'
+ let extension = matchstr(self.getLastPathComponent(0), '[^.]\+\.\zs[^.]\+$')
+ let metadata += [self.isDirectory ? '' : (extension ==# '' ? nr2char(str2nr('0x10ffff',16)) : extension)]
+ endif
+ endfor
+
+ if g:NERDTreeSortOrder[0] =~# '\[\[.*\]\]'
+ " Apply tags' sorting first if specified first.
+ let self._sortKey = metadata + [self.getSortOrderIndex()]
+ else
+ " Otherwise, do regex grouping first.
+ let self._sortKey = [self.getSortOrderIndex()] + metadata
+ endif
+
+ let path = self.getLastPathComponent(1)
+ if !g:NERDTreeSortHiddenFirst
+ let path = substitute(path, '^[._]', '', '')
+ endif
+ if !g:NERDTreeCaseSensitiveSort
+ let path = tolower(path)
+ endif
+
+ call extend(self._sortKey, (g:NERDTreeNaturalSort ? self._splitChunks(path) : [path]))
+ endif
+ return self._sortKey
+endfunction
+
+" FUNCTION: Path.isHiddenUnder(path) {{{1
+function! s:Path.isHiddenUnder(path)
+
+ if !self.isUnder(a:path)
+ return 0
+ endif
+
+ let l:startIndex = len(a:path.pathSegments)
+ let l:segments = self.pathSegments[l:startIndex : ]
+
+ for l:segment in l:segments
+
+ if l:segment =~# '^\.'
+ return 1
+ endif
+ endfor
+
+ return 0
+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(nerdtree) {{{1
+" returns true if this path should be ignored
+function! s:Path.ignore(nerdtree)
+ "filter out the user specified paths to ignore
+ if a:nerdtree.ui.isIgnoreFilterEnabled()
+ for i in g:NERDTreeIgnore
+ if self._ignorePatternMatches(i)
+ return 1
+ endif
+ endfor
+
+ for Callback in g:NERDTree.PathFilters()
+ let Callback = type(Callback) ==# type(function('tr')) ? Callback : function(Callback)
+ if Callback({'path': self, 'nerdtree': a:nerdtree})
+ return 1
+ endif
+ endfor
+ endif
+
+ "dont show hidden files unless instructed to
+ if !a:nerdtree.ui.getShowHidden() && self.isUnixHiddenFile()
+ return 1
+ endif
+
+ if a:nerdtree.ui.getShowFiles() ==# 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.isAncestor(path) {{{1
+" return 1 if this path is somewhere above the given path in the filesystem.
+"
+" a:path should be a dir
+function! s:Path.isAncestor(path)
+ if !self.isDirectory
+ return 0
+ endif
+
+ let this = self.str()
+ let that = a:path.str()
+ return stridx(that, this) ==# 0
+endfunction
+
+" FUNCTION: Path.isUnder(path) {{{1
+" return 1 if this path is somewhere under the given path in the filesystem.
+function! s:Path.isUnder(path)
+ 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)
+ if nerdtree#runningWindows()
+ return self.str() ==? a:path.str()
+ else
+ return self.str() ==# a:path.str()
+ endif
+endfunction
+
+" FUNCTION: Path.New(pathStr) {{{1
+function! s:Path.New(pathStr)
+ let l:newPath = copy(self)
+
+ call l:newPath.readInfoFromDisk(s:Path.AbsolutePathFor(a:pathStr))
+
+ let l:newPath.cachedDisplayString = ''
+ let l:newPath.flagSet = g:NERDTreeFlagSet.New()
+
+ return l:newPath
+endfunction
+
+" FUNCTION: Path.Slash() {{{1
+" Return the path separator used by the underlying file system. Special
+" consideration is taken for the use of the 'shellslash' option on Windows
+" systems.
+function! s:Path.Slash()
+
+ if nerdtree#runningWindows()
+ if exists('+shellslash') && &shellslash
+ return '/'
+ endif
+
+ return '\'
+ endif
+
+ return '/'
+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 = filter(split(fullpath, '/'), '!empty(v:val)')
+
+ 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(nerdtree) {{{1
+function! s:Path.refresh(nerdtree)
+ call self.readInfoFromDisk(self.str())
+ call g:NERDTreePathNotifier.NotifyListeners('refresh', self, a:nerdtree, {})
+ call self.cacheDisplayString()
+endfunction
+
+" FUNCTION: Path.refreshFlags(nerdtree) {{{1
+function! s:Path.refreshFlags(nerdtree)
+ call g:NERDTreePathNotifier.NotifyListeners('refreshFlags', self, a:nerdtree, {})
+ 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
+
+ call s:Path.createParentDirectories(a:newPath)
+
+ 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
+" Return a string representation of this Path object.
+"
+" Args:
+" This function takes a single dictionary (optional) with keys and values that
+" specify how the returned pathname should be formatted.
+"
+" The dictionary may have the following keys:
+" 'format'
+" 'escape'
+" 'truncateTo'
+"
+" The 'format' key may have a value of:
+" 'Cd' - a string to be used with ":cd" and similar commands
+" 'Edit' - a string to be used with ":edit" and similar commands
+" 'UI' - a string to be displayed in the NERDTree user interface
+"
+" The 'escape' key, if specified, will cause the output to be escaped with
+" Vim's internal "shellescape()" function.
+"
+" The 'truncateTo' key shortens the length of the path to that given by the
+" value associated with 'truncateTo'. A '<' is 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
+ throw '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 strdisplaywidth(toReturn) > limit-1
+ while strdisplaywidth(toReturn) > limit-1 && strchars(toReturn) > 0
+ let toReturn = substitute(toReturn, '^.', '', '')
+ endwhile
+ 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
+" Return a string representation of this Path that is suitable for use as an
+" argument to Vim's internal ":cd" command.
+function! s:Path._strForCd()
+ return fnameescape(self.str())
+endfunction
+
+" FUNCTION: Path._strForEdit() {{{1
+" Return a string representation of this Path that is suitable for use as an
+" argument to Vim's internal ":edit" command.
+function! s:Path._strForEdit()
+
+ " Make the path relative to the current working directory, if possible.
+ let l:result = fnamemodify(self.str(), ':.')
+
+ " On Windows, the drive letter may be removed by "fnamemodify()". Add it
+ " back, if necessary.
+ if nerdtree#runningWindows() && l:result[0] ==# s:Path.Slash()
+ let l:result = self.drive . l:result
+ endif
+
+ let l:result = fnameescape(l:result)
+
+ if empty(l:result)
+ let l:result = '.'
+ endif
+
+ return l:result
+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
+" Return the absolute pathname associated with this Path object. The pathname
+" returned is appropriate for the underlying file system.
+function! s:Path._str()
+ let l:separator = s:Path.Slash()
+ let l:leader = l:separator
+
+ if nerdtree#runningWindows()
+ let l:leader = self.drive . l:separator
+ endif
+
+ return l:leader . join(self.pathSegments, l:separator)
+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/nvim/plugged/nerdtree/lib/nerdtree/tree_dir_node.vim b/.config/nvim/plugged/nerdtree/lib/nerdtree/tree_dir_node.vim
new file mode 100644
index 0000000..88ac319
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/lib/nerdtree/tree_dir_node.vim
@@ -0,0 +1,699 @@
+" ============================================================================
+" 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:NERDTree.root
+ while currentNode.parent !=# {}
+ let currentNode = currentNode.parent
+ endwhile
+ return currentNode
+endfunction
+
+" FUNCTION: TreeDirNode.activate([options]) {{{1
+function! s:TreeDirNode.activate(...)
+ let l:options = (a:0 > 0) ? a:1 : {}
+
+ call self.toggleOpen(l:options)
+
+ " Note that we only re-render the NERDTree for this node if we did NOT
+ " create a new node and render it in a new window or tab. In the latter
+ " case, rendering the NERDTree for this node could overwrite the text of
+ " the new NERDTree!
+ if !has_key(l:options, 'where') || empty(l:options['where'])
+ call self.getNerdtree().render()
+ call self.putCursorHere(0, 0)
+ endif
+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
+" Mark this TreeDirNode as closed.
+function! s:TreeDirNode.close()
+
+ " Close all directories in this directory node's cascade. This is
+ " necessary to ensure consistency when cascades are rendered.
+ for l:dirNode in self.getCascade()
+ let l:dirNode.isOpen = 0
+ endfor
+endfunction
+
+" FUNCTION: TreeDirNode.closeChildren() {{{1
+" Recursively close any directory nodes that are descendants of this node.
+function! s:TreeDirNode.closeChildren()
+ for l:child in self.children
+ if l:child.path.isDirectory
+ call l:child.close()
+ call l:child.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, self.getNerdtree())
+ call self.addChild(newTreeNode, a:inOrder)
+ return newTreeNode
+endfunction
+
+" FUNCTION: TreeDirNode.displayString() {{{1
+" Assemble and return a string that can represent this TreeDirNode object in
+" the NERDTree window.
+function! s:TreeDirNode.displayString()
+ let l:result = ''
+
+ " Build a label that identifies this TreeDirNode.
+ let l:label = ''
+ let l:cascade = self.getCascade()
+ for l:dirNode in l:cascade
+ let l:next = l:dirNode.path.displayString()
+ let l:label .= l:label ==# '' ? l:next : substitute(l:next,'^.','','')
+ endfor
+
+ " Select the appropriate open/closed status indicator symbol.
+ let l:symbol = (l:cascade[-1].isOpen ? g:NERDTreeDirArrowCollapsible : g:NERDTreeDirArrowExpandable )
+ let l:symbol .= (g:NERDTreeDirArrowExpandable ==# '' ? '' : ' ')
+ let l:flags = l:cascade[-1].path.flagSet.renderToString()
+
+ return l:symbol . l:flags . l:label
+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.getCascade() {{{1
+" Return an array of dir nodes (starting from self) that can be cascade opened.
+function! s:TreeDirNode.getCascade()
+ if !self.isCascadable()
+ return [self]
+ endif
+
+ let vc = self.getVisibleChildren()
+ let visChild = vc[0]
+
+ return [self] + visChild.getCascade()
+endfunction
+
+" FUNCTION: TreeDirNode.getCascadeRoot() {{{1
+" Return the first directory node in the cascade in which this directory node
+" is rendered.
+function! s:TreeDirNode.getCascadeRoot()
+
+ " Don't search above the current NERDTree root node.
+ if self.isRoot()
+ return self
+ endif
+
+ let l:cascadeRoot = self
+ let l:parent = self.parent
+
+ while !empty(l:parent) && !l:parent.isRoot()
+
+ if index(l:parent.getCascade(), self) ==# -1
+ break
+ endif
+
+ let l:cascadeRoot = l:parent
+ let l:parent = l:parent.parent
+ endwhile
+
+ return l:cascadeRoot
+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.getDirChildren() {{{1
+" Return a list of all child nodes from 'self.children' that are of type
+" TreeDirNode. This function supports http://github.com/scrooloose/nerdtree-project-plugin.git.
+function! s:TreeDirNode.getDirChildren()
+ return filter(copy(self.children), 'v:val.path.isDirectory ==# 1')
+endfunction
+
+" FUNCTION: TreeDirNode._glob(pattern, all) {{{1
+" Return a list of strings naming the descendants of the directory in this
+" TreeDirNode object that match the specified glob pattern.
+"
+" Args:
+" pattern: (string) the glob pattern to apply
+" all: (0 or 1) if 1, include '.' and '..' if they match 'pattern'; if 0,
+" always exclude them
+"
+" Note: If the pathnames in the result list are below the working directory,
+" they are returned as pathnames relative to that directory. This is because
+" this function, internally, attempts to obey 'wildignore' rules that use
+" relative paths.
+function! s:TreeDirNode._glob(pattern, all)
+
+ " Construct a path specification such that globpath() will return
+ " relative pathnames, if possible.
+ if self.path.str() ==# getcwd()
+ let l:pathSpec = ','
+ else
+ let l:pathSpec = escape(fnamemodify(self.path.str({'format': 'Glob'}), ':.'), ',')
+
+ " On Windows, the drive letter may be removed by fnamemodify().
+ if nerdtree#runningWindows() && l:pathSpec[0] ==# g:NERDTreePath.Slash()
+ let l:pathSpec = self.path.drive . l:pathSpec
+ endif
+ endif
+
+ let l:globList = []
+
+ " See ':h version7.txt' and ':h version8.txt' for details on the
+ " development of the glob() and globpath() functions.
+ if v:version > 704 || (v:version ==# 704 && has('patch654'))
+ let l:globList = globpath(l:pathSpec, a:pattern, !g:NERDTreeRespectWildIgnore, 1, 0)
+ elseif v:version ==# 704 && has('patch279')
+ let l:globList = globpath(l:pathSpec, a:pattern, !g:NERDTreeRespectWildIgnore, 1)
+ elseif v:version > 702 || (v:version ==# 702 && has('patch051'))
+ let l:globString = globpath(l:pathSpec, a:pattern, !g:NERDTreeRespectWildIgnore)
+ let l:globList = split(l:globString, "\n")
+ else
+ let l:globString = globpath(l:pathSpec, a:pattern)
+ let l:globList = split(l:globString, "\n")
+ endif
+
+ " If a:all is false, filter '.' and '..' from the output.
+ if !a:all
+ let l:toRemove = []
+
+ for l:file in l:globList
+ let l:tail = fnamemodify(l:file, ':t')
+
+ " If l:file has a trailing slash, then its :tail will be ''. Use
+ " :h to drop the slash and the empty string after it; then use :t
+ " to get the directory name.
+ if l:tail ==# ''
+ let l:tail = fnamemodify(l:file, ':h:t')
+ endif
+
+ if l:tail ==# '.' || l:tail ==# '..'
+ call add(l:toRemove, l:file)
+ if len(l:toRemove) ==# 2
+ break
+ endif
+ endif
+ endfor
+
+ for l:file in l:toRemove
+ call remove(l:globList, index(l:globList, l:file))
+ endfor
+ endif
+
+ return l:globList
+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(self.getNerdtree()) ==# 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.isCascadable() {{{1
+" true if this dir has only one visible child that is also a dir
+" false if this dir is bookmarked or symlinked. Why? Two reasons:
+" 1. If cascaded, we don't know which dir is bookmarked or is a symlink.
+" 2. If the parent is a symlink or is bookmarked, you end up with unparsable
+" text, and NERDTree cannot get the path of any child node.
+function! s:TreeDirNode.isCascadable()
+ if g:NERDTreeCascadeSingleChildDir ==# 0
+ return 0
+ endif
+
+ if self.path.isSymLink
+ return 0
+ endif
+
+ for i in g:NERDTreeBookmark.Bookmarks()
+ if i.path.equals(self.path)
+ return 0
+ endif
+ endfor
+
+ let c = self.getVisibleChildren()
+ return len(c) ==# 1 && c[0].path.isDirectory
+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 = []
+
+ let files = self._glob('*', 1) + self._glob('.*', 0)
+
+ if !a:silent && len(files) > g:NERDTreeNotificationThreshold
+ call nerdtree#echo('Please wait, caching a large dir ...')
+ endif
+
+ let invalidFilesFound = 0
+ for i in files
+ try
+ let path = g:NERDTreePath.New(i)
+ call self.createChild(path, 0)
+ call g:NERDTreePathNotifier.NotifyListeners('init', path, self.getNerdtree(), {})
+ catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/
+ let invalidFilesFound += 1
+ endtry
+ endfor
+
+ call self.sortChildren()
+
+ call nerdtree#echo('')
+
+ 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, nerdtree) {{{1
+" Return a new TreeDirNode object with the given path and parent.
+"
+" Args:
+" path: dir that the node represents
+" nerdtree: the tree the node belongs to
+function! s:TreeDirNode.New(path, nerdtree)
+ 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 = {}
+ let newTreeNode._nerdtree = a:nerdtree
+
+ return newTreeNode
+endfunction
+
+" FUNCTION: TreeDirNode.open([options]) {{{1
+" Open this directory node in the current tree or elsewhere if special options
+" are provided. Return 0 if options were processed. Otherwise, return the
+" number of new cached nodes.
+function! s:TreeDirNode.open(...)
+ let l:options = a:0 ? a:1 : {}
+
+ " If special options were specified, process them and return.
+ if has_key(l:options, 'where') && !empty(l:options['where'])
+ let l:opener = g:NERDTreeOpener.New(self.path, l:options)
+ call l:opener.open(self)
+ return 0
+ endif
+
+ " Open any ancestors of this node that render within the same cascade.
+ let l:parent = self.parent
+ while !empty(l:parent) && !l:parent.isRoot()
+ if index(l:parent.getCascade(), self) >= 0
+ let l:parent.isOpen = 1
+ let l:parent = l:parent.parent
+ else
+ break
+ endif
+ endwhile
+
+ let self.isOpen = 1
+
+ let l:numChildrenCached = 0
+ if empty(self.children)
+ let l:numChildrenCached = self._initChildren(0)
+ endif
+
+ return l:numChildrenCached
+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
+" Open an explorer window for this node in the previous window. The explorer
+" can be a NERDTree window or a netrw window.
+function! s:TreeDirNode.openExplorer()
+ execute 'wincmd p'
+ execute 'edit '.self.path.str({'format':'Edit'})
+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.CreateTabTree(self.path.str())
+endfunction
+
+" FUNCTION: TreeDirNode.openRecursively() {{{1
+" Open this directory node and any descendant directory nodes whose pathnames
+" are not ignored.
+function! s:TreeDirNode.openRecursively()
+ silent call self.open()
+
+ for l:child in self.children
+ if l:child.path.isDirectory && !l:child.path.ignore(l:child.getNerdtree())
+ call l:child.openRecursively()
+ endif
+ endfor
+endfunction
+
+" FUNCTION: TreeDirNode.refresh() {{{1
+function! s:TreeDirNode.refresh()
+ call self.path.refresh(self.getNerdtree())
+
+ "if this node was ever opened, refresh its children
+ if self.isOpen || !empty(self.children)
+ let files = self._glob('*', 1) + self._glob('.*', 0)
+ let newChildNodes = []
+ let invalidFilesFound = 0
+ for i in files
+ 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, self.getNerdtree())
+ let newNode.parent = self
+ call add(newChildNodes, newNode)
+ endif
+ catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/
+ let invalidFilesFound = 1
+ endtry
+ 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(self.getNerdtree())
+ for i in self.children
+ call i.refreshFlags()
+ endfor
+endfunction
+
+" FUNCTION: TreeDirNode.refreshDirFlags() {{{1
+function! s:TreeDirNode.refreshDirFlags()
+ call self.path.refreshFlags(self.getNerdtree())
+endfunction
+
+" FUNCTION: TreeDirNode.reveal(path) {{{1
+" reveal the given path, i.e. cache and open all treenodes needed to display it
+" in the UI
+" Returns the revealed node
+function! s:TreeDirNode.reveal(path, ...)
+ let opts = a:0 ? a:1 : {}
+
+ 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)
+ " We may be looking for a newly-saved file that isn't in the tree yet.
+ if n ==# {}
+ call self.refresh()
+ let n = self.findNode(a:path)
+ endif
+ if has_key(opts, 'open')
+ call n.open()
+ endif
+ return n
+ endif
+
+ let p = a:path
+ while !p.getParent().equals(self.path)
+ let p = p.getParent()
+ endwhile
+
+ let n = self.findNode(p)
+ return n.reveal(a:path, opts)
+endfunction
+
+" FUNCTION: TreeDirNode.removeChild(treenode) {{{1
+" Remove the given treenode from self.children.
+" Throws NERDTree.ChildNotFoundError if the node is not found.
+"
+" Args:
+" treenode: the node object to remove
+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
+" Sort self.children by alphabetical order and directory priority.
+function! s:TreeDirNode.sortChildren()
+ if count(g:NERDTreeSortOrder, '*') < 1
+ call add(g:NERDTreeSortOrder, '*')
+ endif
+ let CompareFunc = function('nerdtree#compareNodesBySortKey')
+ call sort(self.children, CompareFunc)
+ let g:NERDTreeOldSortOrder = g:NERDTreeSortOrder
+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/nvim/plugged/nerdtree/lib/nerdtree/tree_file_node.vim b/.config/nvim/plugged/nerdtree/lib/nerdtree/tree_file_node.vim
new file mode 100644
index 0000000..957b98a
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/lib/nerdtree/tree_file_node.vim
@@ -0,0 +1,349 @@
+" ============================================================================
+" CLASS: TreeFileNode
+"
+" This class is the parent of the TreeDirNode class and is the 'Component'
+" part of the composite design pattern between the NERDTree node 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, self.getNerdtree())
+ 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, self.getNerdtree())
+ 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 = self.getNerdtree().root.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.flagSet.renderToString() . 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.findSibling(direction) {{{1
+" Find the next or previous sibling of this node.
+"
+" Args:
+" direction: 0 for previous, 1 for next
+"
+" Return:
+" The next/previous TreeFileNode object or an empty dictionary if not found.
+function! s:TreeFileNode.findSibling(direction)
+
+ " There can be no siblings if there is no parent.
+ if empty(self.parent)
+ return {}
+ endif
+
+ let l:nodeIndex = self.parent.getChildIndex(self.path)
+
+ if l:nodeIndex == -1
+ return {}
+ endif
+
+ " Get the next index to begin the search.
+ let l:nodeIndex += a:direction ? 1 : -1
+
+ while 0 <= l:nodeIndex && l:nodeIndex < self.parent.getChildCount()
+
+ " Return the next node if it is not ignored.
+ if !self.parent.children[l:nodeIndex].path.ignore(self.getNerdtree())
+ return self.parent.children[l:nodeIndex]
+ endif
+
+ let l:nodeIndex += a:direction ? 1 : -1
+ endwhile
+
+ return {}
+endfunction
+
+" FUNCTION: TreeFileNode.getNerdtree(){{{1
+function! s:TreeFileNode.getNerdtree()
+ return self._nerdtree
+endfunction
+
+" FUNCTION: TreeFileNode.GetRootForTab(){{{1
+" get the root node for this tab
+function! s:TreeFileNode.GetRootForTab()
+ if g:NERDTree.ExistsForTab()
+ return getbufvar(t:NERDTreeBufName, 'NERDTree').root
+ end
+ return {}
+endfunction
+
+" FUNCTION: TreeFileNode.GetSelected() {{{1
+" If the cursor is currently positioned on a tree node, return the node.
+" Otherwise, return the empty dictionary.
+function! s:TreeFileNode.GetSelected()
+
+ try
+ let l:path = b:NERDTree.ui.getPath(line('.'))
+
+ if empty(l:path)
+ return {}
+ endif
+
+ return b:NERDTree.root.findNode(l:path)
+ catch
+ 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(self.getNerdtree())
+endfunction
+
+" FUNCTION: TreeFileNode.isRoot() {{{1
+function! s:TreeFileNode.isRoot()
+ if !g:NERDTree.ExistsForBuf()
+ throw 'NERDTree.NoTreeError: No tree exists for the current buffer'
+ endif
+
+ return self.equals(self.getNerdtree().root)
+endfunction
+
+" FUNCTION: TreeFileNode.New(path, nerdtree) {{{1
+" Returns a new TreeNode object with the given path and parent
+"
+" Args:
+" path: file/dir that the node represents
+" nerdtree: the tree the node belongs to
+function! s:TreeFileNode.New(path, nerdtree)
+ if a:path.isDirectory
+ return g:NERDTreeDirNode.New(a:path, a:nerdtree)
+ else
+ let newTreeNode = copy(self)
+ let newTreeNode.path = a:path
+ let newTreeNode.parent = {}
+ let newTreeNode._nerdtree = a:nerdtree
+ 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)
+ call nerdtree#deprecated('TreeFileNode.openinNewTab', 'is deprecated, use .open() instead.')
+ call self.open(extend({'where': 't'}, a:options))
+endfunction
+
+" FUNCTION: TreeFileNode.openExplorer()
+function! s:TreeFileNode.openExplorer()
+ execute 'wincmd p'
+ execute 'edit '.self.path.getParent().str({'format':'Edit'})
+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 = self.getNerdtree().ui.getLineNum(self)
+ if ln != -1
+ if a:isJump
+ mark '
+ endif
+ call cursor(ln, col('.'))
+ else
+ if a:recurseUpward
+ let node = self
+ while node != {} && self.getNerdtree().ui.getLineNum(node) ==# -1
+ let node = node.parent
+ call node.open()
+ endwhile
+ call self._nerdtree.render()
+ call node.putCursorHere(a:isJump, 0)
+ endif
+ endif
+endfunction
+
+" FUNCTION: TreeFileNode.refresh() {{{1
+function! s:TreeFileNode.refresh()
+ call self.path.refresh(self.getNerdtree())
+endfunction
+
+" FUNCTION: TreeFileNode.refreshFlags() {{{1
+function! s:TreeFileNode.refreshFlags()
+ call self.path.refreshFlags(self.getNerdtree())
+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 = self.getNerdtree().root.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)
+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)
+" for each depth in the tree
+function! s:TreeFileNode._renderToString(depth, drawText)
+ let output = ''
+ if a:drawText ==# 1
+
+ let treeParts = repeat(' ', a:depth - 1)
+ let treeParts .= (self.path.isDirectory || g:NERDTreeDirArrowExpandable ==# '' ? '' : ' ')
+
+ 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 self.isCascadable() && a:depth > 0
+
+ let output = output . childNodesToDraw[0]._renderToString(a:depth, 0)
+
+ elseif len(childNodesToDraw) > 0
+ for i in childNodesToDraw
+ let output = output . i._renderToString(a:depth + 1, 1)
+ endfor
+ endif
+ endif
+
+ return output
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/.config/nvim/plugged/nerdtree/lib/nerdtree/ui.vim b/.config/nvim/plugged/nerdtree/lib/nerdtree/ui.vim
new file mode 100644
index 0000000..9ffadf6
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/lib/nerdtree/ui.vim
@@ -0,0 +1,529 @@
+" ============================================================================
+" CLASS: UI
+" ============================================================================
+
+
+let s:UI = {}
+let g:NERDTreeUI = s:UI
+
+" FUNCTION: s:UI.centerView() {{{1
+" 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()
+ if self.getShowHelp()
+ let help = "\" NERDTree (" . nerdtree#version() . ") quickhelp~\n"
+ let help .= "\" ============================\n"
+ let help .= "\" File node mappings~\n"
+ let help .= '" '. (g:NERDTreeMouseMode ==# 3 ? 'single' : 'double') ."-click,\n"
+ if self.nerdtree.isTabTree()
+ let help .= '" '. g:NERDTreeMapActivateNode .": open in prev window\n"
+ else
+ let help .= '" '. g:NERDTreeMapActivateNode .": open in current window\n"
+ endif
+ if self.nerdtree.isTabTree()
+ let help .= '" '. g:NERDTreeMapPreview .": preview\n"
+ endif
+ let help .= '" '. g:NERDTreeMapOpenInTab.": open in new tab\n"
+ let help .= '" '. g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n"
+ let help .= "\" middle-click,\n"
+ let help .= '" '. g:NERDTreeMapOpenSplit .": open split\n"
+ let help .= '" '. g:NERDTreeMapPreviewSplit .": preview split\n"
+ let help .= '" '. g:NERDTreeMapOpenVSplit .": open vsplit\n"
+ let help .= '" '. g:NERDTreeMapPreviewVSplit .": preview vsplit\n"
+ let help .= '" '. g:NERDTreeMapCustomOpen .": custom open\n"
+
+ let help .= "\"\n\" ----------------------------\n"
+ let help .= "\" Directory node mappings~\n"
+ let help .= '" '. (g:NERDTreeMouseMode ==# 1 ? 'double' : 'single') ."-click,\n"
+ let help .= '" '. g:NERDTreeMapActivateNode .": open & close node\n"
+ let help .= '" '. g:NERDTreeMapOpenRecursively .": recursively open node\n"
+ let help .= '" '. g:NERDTreeMapOpenInTab.": open in new tab\n"
+ let help .= '" '. g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n"
+ let help .= '" '. g:NERDTreeMapCustomOpen .": custom open\n"
+ let help .= '" '. g:NERDTreeMapCloseDir .": close parent of node\n"
+ let help .= '" '. g:NERDTreeMapCloseChildren .": close all child nodes of\n"
+ let help .= "\" current node recursively\n"
+ let help .= "\" middle-click,\n"
+ let help .= '" '. g:NERDTreeMapOpenExpl.": explore selected dir\n"
+
+ let help .= "\"\n\" ----------------------------\n"
+ let help .= "\" Bookmark table mappings~\n"
+ let help .= "\" double-click,\n"
+ let help .= '" '. g:NERDTreeMapActivateNode .": open bookmark\n"
+ let help .= '" '. g:NERDTreeMapPreview .": preview file\n"
+ let help .= '" '. g:NERDTreeMapPreview .": find dir in tree\n"
+ let help .= '" '. g:NERDTreeMapOpenInTab.": open in new tab\n"
+ let help .= '" '. g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n"
+ let help .= '" '. g:NERDTreeMapCustomOpen .": custom open\n"
+ let help .= '" '. g:NERDTreeMapDeleteBookmark .": delete bookmark\n"
+
+ let help .= "\"\n\" ----------------------------\n"
+ let help .= "\" Tree navigation mappings~\n"
+ let help .= '" '. g:NERDTreeMapJumpRoot .": go to root\n"
+ let help .= '" '. g:NERDTreeMapJumpParent .": go to parent\n"
+ let help .= '" '. g:NERDTreeMapJumpFirstChild .": go to first child\n"
+ let help .= '" '. g:NERDTreeMapJumpLastChild .": go to last child\n"
+ let help .= '" '. g:NERDTreeMapJumpNextSibling .": go to next sibling\n"
+ let help .= '" '. g:NERDTreeMapJumpPrevSibling .": go to prev sibling\n"
+
+ let help .= "\"\n\" ----------------------------\n"
+ let help .= "\" Filesystem mappings~\n"
+ let help .= '" '. g:NERDTreeMapChangeRoot .": change tree root to the\n"
+ let help .= "\" selected dir\n"
+ let help .= '" '. g:NERDTreeMapUpdir .": move tree root up a dir\n"
+ let help .= '" '. g:NERDTreeMapUpdirKeepOpen .": move tree root up a dir\n"
+ let help .= "\" but leave old root open\n"
+ let help .= '" '. g:NERDTreeMapRefresh .": refresh cursor dir\n"
+ let help .= '" '. g:NERDTreeMapRefreshRoot .": refresh current root\n"
+ let help .= '" '. g:NERDTreeMapMenu .": Show menu\n"
+ let help .= '" '. g:NERDTreeMapChdir .":change the CWD to the\n"
+ let help .= "\" selected dir\n"
+ let help .= '" '. g:NERDTreeMapCWD .":change tree root to CWD\n"
+
+ let help .= "\"\n\" ----------------------------\n"
+ let help .= "\" Tree filtering mappings~\n"
+ let help .= '" '. g:NERDTreeMapToggleHidden .': hidden files (' . (self.getShowHidden() ? 'on' : 'off') . ")\n"
+ let help .= '" '. g:NERDTreeMapToggleFilters .': file filters (' . (self.isIgnoreFilterEnabled() ? 'on' : 'off') . ")\n"
+ let help .= '" '. g:NERDTreeMapToggleFiles .': files (' . (self.getShowFiles() ? 'on' : 'off') . ")\n"
+ let help .= '" '. g:NERDTreeMapToggleBookmarks .': bookmarks (' . (self.getShowBookmarks() ? 'on' : 'off') . ")\n"
+
+ " add quickhelp entries for each custom key map
+ let help .= "\"\n\" ----------------------------\n"
+ let help .= "\" Custom mappings~\n"
+ for i in g:NERDTreeKeyMap.All()
+ if !empty(i.quickhelpText)
+ let help .= '" '. i.key .': '. i.quickhelpText ."\n"
+ endif
+ endfor
+
+ let help .= "\"\n\" ----------------------------\n"
+ let help .= "\" Other mappings~\n"
+ let help .= '" '. g:NERDTreeMapQuit .": Close the NERDTree window\n"
+ let help .= '" '. g:NERDTreeMapToggleZoom .": Zoom (maximize-minimize)\n"
+ let help .= "\" the NERDTree window\n"
+ let help .= '" '. g:NERDTreeMapHelp .": toggle help\n"
+ let help .= "\"\n\" ----------------------------\n"
+ let help .= "\" Bookmark commands~\n"
+ let help .= "\" :Bookmark [<name>]\n"
+ let help .= "\" :BookmarkToRoot <name>\n"
+ let help .= "\" :RevealBookmark <name>\n"
+ let help .= "\" :OpenBookmark <name>\n"
+ let help .= "\" :ClearBookmarks [<names>]\n"
+ let help .= "\" :ClearAllBookmarks\n"
+ let help .= "\" :ReadBookmarks\n"
+ let help .= "\" :WriteBookmarks\n"
+ let help .= "\" :EditBookmarks\n"
+ silent! put =help
+ elseif !self.isMinimal()
+ let help ='" Press '. g:NERDTreeMapHelp ." for help\n"
+ silent! put =help
+ endif
+endfunction
+
+
+" FUNCTION: s:UI.new(nerdtree) {{{1
+function! s:UI.New(nerdtree)
+ let newObj = copy(self)
+ let newObj.nerdtree = a:nerdtree
+ let newObj._showHelp = 0
+ let newObj._ignoreEnabled = 1
+ let newObj._showFiles = g:NERDTreeShowFiles
+ let newObj._showHidden = g:NERDTreeShowHidden
+ let newObj._showBookmarks = g:NERDTreeShowBookmarks
+
+ return newObj
+endfunction
+
+" FUNCTION: s:UI.getPath(ln) {{{1
+" Return the Path object for the node that is rendered on the given line
+" number. If the 'up a dir' line is selected, return the Path object for
+" the parent of the root. Return the empty dictionary if the given line
+" does not reference a tree node.
+function! s:UI.getPath(ln)
+ let line = getline(a:ln)
+
+ let rootLine = self.getRootLineNum()
+
+ if a:ln ==# rootLine
+ return self.nerdtree.root.path
+ endif
+
+ if line ==# s:UI.UpDirLine()
+ return self.nerdtree.root.path.getParent()
+ endif
+
+ if a:ln < rootLine
+ return {}
+ endif
+
+ let indent = self._indentLevelFor(line)
+
+ " remove the tree parts and the leading space
+ let curFile = self._stripMarkup(line)
+
+ let dir = ''
+ let lnum = a:ln
+ while lnum > 0
+ let lnum = lnum - 1
+ let curLine = getline(lnum)
+ let curLineStripped = self._stripMarkup(curLine)
+
+ " have we reached the top of the tree?
+ if lnum ==# rootLine
+ let dir = self.nerdtree.root.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 = self.nerdtree.root.path.drive . dir . curFile
+ let toReturn = g:NERDTreePath.New(curFile)
+ return toReturn
+endfunction
+
+" FUNCTION: s:UI.getLineNum(node) {{{1
+" Return the line number where the given node is rendered. Return -1 if the
+" given node is not visible.
+function! s:UI.getLineNum(node)
+
+ if a:node.isRoot()
+ return self.getRootLineNum()
+ endif
+
+ let l:pathComponents = [substitute(self.nerdtree.root.path.str({'format': 'UI'}), '/\s*$', '', '')]
+ let l:currentPathComponent = 1
+
+ let l:fullPath = a:node.path.str({'format': 'UI'})
+
+ for l:lineNumber in range(self.getRootLineNum() + 1, line('$'))
+ let l:currentLine = getline(l:lineNumber)
+ let l:indentLevel = self._indentLevelFor(l:currentLine)
+
+ if l:indentLevel !=# l:currentPathComponent
+ continue
+ endif
+
+ let l:currentLine = self._stripMarkup(l:currentLine)
+ let l:currentPath = join(l:pathComponents, '/') . '/' . l:currentLine
+
+ " Directories: If the current path 'starts with' the full path, then
+ " either the paths are equal or the line is a cascade containing the
+ " full path.
+ if l:fullPath[-1:] ==# '/' && stridx(l:currentPath, l:fullPath) ==# 0
+ return l:lineNumber
+ endif
+
+ " Files: The paths must exactly match.
+ if l:fullPath ==# l:currentPath
+ return l:lineNumber
+ endif
+
+ " Otherwise: If the full path starts with the current path and the
+ " current path is a directory, we add a new path component.
+ if stridx(l:fullPath, l:currentPath) ==# 0 && l:currentPath[-1:] ==# '/'
+ let l:currentLine = substitute(l:currentLine, '/\s*$', '', '')
+ call add(l:pathComponents, l:currentLine)
+ let l:currentPathComponent += 1
+ endif
+ endfor
+
+ return -1
+endfunction
+
+" FUNCTION: s:UI.getRootLineNum(){{{1
+" gets the line number of the root node
+function! s:UI.getRootLineNum()
+ let rootLine = 1
+ while rootLine <= line('$') && getline(rootLine) !~# '^\(/\|<\)'
+ let rootLine = rootLine + 1
+ endwhile
+ return rootLine
+endfunction
+
+" FUNCTION: s:UI.getShowBookmarks() {{{1
+function! s:UI.getShowBookmarks()
+ return self._showBookmarks
+endfunction
+
+" FUNCTION: s:UI.getShowFiles() {{{1
+function! s:UI.getShowFiles()
+ return self._showFiles
+endfunction
+
+" FUNCTION: s:UI.getShowHelp() {{{1
+function! s:UI.getShowHelp()
+ return self._showHelp
+endfunction
+
+" FUNCTION: s:UI.getShowHidden() {{{1
+function! s:UI.getShowHidden()
+ return self._showHidden
+endfunction
+
+" FUNCTION: s:UI._indentLevelFor(line) {{{1
+function! s:UI._indentLevelFor(line)
+ " Replace multi-character DirArrows with a single space so the
+ " indentation calculation doesn't get messed up.
+ if g:NERDTreeDirArrowExpandable ==# ''
+ let l:line = ' '.a:line
+ else
+ let l:line = substitute(substitute(a:line, '\V'.g:NERDTreeDirArrowExpandable, ' ', ''), '\V'.g:NERDTreeDirArrowCollapsible, ' ', '')
+ endif
+ let leadChars = match(l:line, '\M\[^ ]')
+ return leadChars / s:UI.IndentWid()
+endfunction
+
+" FUNCTION: s:UI.IndentWid() {{{1
+function! s:UI.IndentWid()
+ return 2
+endfunction
+
+" FUNCTION: s:UI.isIgnoreFilterEnabled() {{{1
+function! s:UI.isIgnoreFilterEnabled()
+ return self._ignoreEnabled ==# 1
+endfunction
+
+" FUNCTION: s:UI.isMinimal() {{{1
+function! s:UI.isMinimal()
+ return g:NERDTreeMinimalUI
+endfunction
+
+" FUNCTION: s:UI.MarkupReg() {{{1
+function! s:UI.MarkupReg()
+ return '^ *['.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.']\? '
+endfunction
+
+" FUNCTION: s:UI._renderBookmarks {{{1
+function! s:UI._renderBookmarks()
+
+ if !self.isMinimal()
+ call setline(line('.')+1, '>----------Bookmarks----------')
+ call cursor(line('.')+1, col('.'))
+ endif
+
+ if g:NERDTreeBookmarksSort ==# 1 || g:NERDTreeBookmarksSort ==# 2
+ call g:NERDTreeBookmark.SortBookmarksList()
+ 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
+ call nerdtree#exec('silent vertical resize ' . self._screenState['oldWindowSize'], 1)
+
+ 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()
+ let self._screenState = {}
+ try
+ call g:NERDTree.CursorToTreeWin()
+ let self._screenState['oldPos'] = getpos('.')
+ let self._screenState['oldTopLine'] = line('w0')
+ let self._screenState['oldWindowSize']= winwidth('')
+ call nerdtree#exec(win . 'wincmd w', 1)
+ catch
+ endtry
+endfunction
+
+" FUNCTION: s:UI.setShowHidden(val) {{{1
+function! s:UI.setShowHidden(val)
+ let self._showHidden = a:val
+endfunction
+
+" FUNCTION: s:UI._stripMarkup(line){{{1
+" find the filename in the given line, and return it.
+"
+" Args:
+" line: the subject line
+function! s:UI._stripMarkup(line)
+ let l:line = substitute(a:line, '^.\{-}' . g:NERDTreeNodeDelimiter, '', '')
+ return substitute(l:line, g:NERDTreeNodeDelimiter.'.*$', '', '')
+endfunction
+
+" FUNCTION: s:UI.render() {{{1
+function! s:UI.render()
+ setlocal noreadonly 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 !self.isMinimal()
+ call setline(line('.')+1, '')
+ call cursor(line('.')+1, col('.'))
+ endif
+
+ if self.getShowBookmarks()
+ call self._renderBookmarks()
+ endif
+
+ " add the 'up a dir' line
+ if !self.isMinimal()
+ call setline(line('.')+1, s:UI.UpDirLine())
+ call cursor(line('.')+1, col('.'))
+ endif
+
+ " draw the header line
+ let header = self.nerdtree.root.path.str({'format': 'UI', 'truncateTo': winwidth(0)})
+ call setline(line('.')+1, header)
+ call cursor(line('.')+1, col('.'))
+
+ " draw the tree
+ silent put =self.nerdtree.root.renderToString()
+
+ " 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 readonly 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 self.render()
+
+ if currentNode !=# {}
+ call currentNode.putCursorHere(0, 0)
+ endif
+endfunction
+
+" FUNCTION: s:UI.toggleHelp() {{{1
+function! s:UI.toggleHelp()
+ let self._showHelp = !self._showHelp
+endfunction
+
+" FUNCTION: s:UI.toggleIgnoreFilter() {{{1
+" toggles the use of the NERDTreeIgnore option
+function! s:UI.toggleIgnoreFilter()
+ let self._ignoreEnabled = !self._ignoreEnabled
+ call self.renderViewSavingPosition()
+ call self.centerView()
+endfunction
+
+" FUNCTION: s:UI.toggleShowBookmarks() {{{1
+" Toggle the visibility of the Bookmark table.
+function! s:UI.toggleShowBookmarks()
+ let self._showBookmarks = !self._showBookmarks
+
+ if self.getShowBookmarks()
+ call self.nerdtree.render()
+ call g:NERDTree.CursorToBookmarkTable()
+ else
+
+ if empty(g:NERDTreeFileNode.GetSelected())
+ call b:NERDTree.root.putCursorHere(0, 0)
+ normal! 0
+ endif
+
+ call self.renderViewSavingPosition()
+ endif
+
+ call self.centerView()
+endfunction
+
+" FUNCTION: s:UI.toggleShowFiles() {{{1
+" toggles the display of hidden files
+function! s:UI.toggleShowFiles()
+ let self._showFiles = !self._showFiles
+ call self.renderViewSavingPosition()
+ call self.centerView()
+endfunction
+
+" FUNCTION: s:UI.toggleShowHidden() {{{1
+" toggles the display of hidden files
+function! s:UI.toggleShowHidden()
+ let self._showHidden = !self._showHidden
+ call self.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
+ call nerdtree#exec('silent vertical resize '. size, 1)
+ let b:NERDTreeZoomed = 0
+ else
+ call nerdtree#exec('vertical resize '. get(g:, 'NERDTreeWinSizeMax', ''), 1)
+ let b:NERDTreeZoomed = 1
+ endif
+endfunction
+
+" FUNCTION: s:UI.UpDirLine() {{{1
+function! s:UI.UpDirLine()
+ return '.. (up a dir)'
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/.config/nvim/plugged/nerdtree/nerdtree_plugin/exec_menuitem.vim b/.config/nvim/plugged/nerdtree/nerdtree_plugin/exec_menuitem.vim
new file mode 100644
index 0000000..fb6c486
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/nerdtree_plugin/exec_menuitem.vim
@@ -0,0 +1,40 @@
+" ============================================================================
+" File: exec_menuitem.vim
+" Description: plugin for NERD Tree that provides an execute file menu item
+" Maintainer: Martin Grenfell <martin.grenfell at gmail dot com>
+" License: This program is free software. It comes without any warranty,
+" to the extent permitted by applicable law. You can redistribute
+" it and/or modify it under the terms of the Do What The Fuck You
+" Want To Public License, Version 2, as published by Sam Hocevar.
+" See http://sam.zoy.org/wtfpl/COPYING for more details.
+"
+" ============================================================================
+if exists('g:loaded_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/nvim/plugged/nerdtree/nerdtree_plugin/fs_menu.vim b/.config/nvim/plugged/nerdtree/nerdtree_plugin/fs_menu.vim
new file mode 100644
index 0000000..281116f
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/nerdtree_plugin/fs_menu.vim
@@ -0,0 +1,430 @@
+" ============================================================================
+" File: fs_menu.vim
+" Description: plugin for the NERD Tree that provides a file system menu
+" Maintainer: Martin Grenfell <martin.grenfell at gmail dot com>
+" License: This program is free software. It comes without any warranty,
+" to the extent permitted by applicable law. You can redistribute
+" it and/or modify it under the terms of the Do What The Fuck You
+" Want To Public License, Version 2, as published by Sam Hocevar.
+" See http://sam.zoy.org/wtfpl/COPYING for more details.
+"
+" ============================================================================
+if exists('g:loaded_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') || has('mac')
+ 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 executable('xdg-open')
+ call NERDTreeAddMenuItem({'text': '(r)eveal the current node in file manager', 'shortcut': 'r', 'callback': 'NERDTreeRevealFileLinux'})
+ call NERDTreeAddMenuItem({'text': '(o)pen the current node with system editor', 'shortcut': 'o', 'callback': 'NERDTreeExecuteFileLinux'})
+endif
+
+if g:NERDTreePath.CopyingSupported()
+ call NERDTreeAddMenuItem({'text': '(c)opy the current node', 'shortcut': 'c', 'callback': 'NERDTreeCopyNode'})
+endif
+call NERDTreeAddMenuItem({'text': (has('clipboard')?'copy (p)ath to clipboard':'print (p)ath to screen'), 'shortcut': 'p', 'callback': 'NERDTreeCopyPath'})
+
+if has('unix') || has('osx')
+ call NERDTreeAddMenuItem({'text': '(l)ist the current node', 'shortcut': 'l', 'callback': 'NERDTreeListNode'})
+else
+ call NERDTreeAddMenuItem({'text': '(l)ist the current node', 'shortcut': 'l', 'callback': 'NERDTreeListNodeWin32'})
+endif
+
+"FUNCTION: s:inputPrompt(action){{{1
+"returns the string that should be prompted to the user for the given action
+"
+"Args:
+"action: the action that is being performed, e.g. 'delete'
+function! s:inputPrompt(action)
+ if a:action ==# 'add'
+ let title = 'Add a childnode'
+ let info = "Enter the dir/file name to be created. Dirs end with a '/'"
+ let minimal = 'Add node:'
+
+ elseif a:action ==# 'copy'
+ let title = 'Copy the current node'
+ let info = 'Enter the new path to copy the node to:'
+ let minimal = 'Copy to:'
+
+ elseif a:action ==# 'delete'
+ let title = 'Delete the current node'
+ let info = 'Are you sure you wish to delete the node:'
+ let minimal = 'Delete?'
+
+ elseif a:action ==# 'deleteNonEmpty'
+ let title = 'Delete the current node'
+ let info = "STOP! Directory is not empty! To delete, type 'yes'"
+ let minimal = 'Delete directory?'
+
+ elseif a:action ==# 'move'
+ let title = 'Rename the current node'
+ let info = 'Enter the new path for the node:'
+ let minimal = 'Move to:'
+ endif
+
+ if g:NERDTreeMenuController.isMinimal()
+ redraw! " Clear the menu
+ return minimal . ' '
+ else
+ let divider = '=========================================================='
+ return title . "\n" . divider . "\n" . info . "\n"
+ end
+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()
+ " Go to the next buffer in buffer list if at least one extra buffer is listed
+ " Otherwise open a new empty buffer
+ if v:version >= 800
+ let l:listedBufferCount = len(getbufinfo({'buflisted':1}))
+ elseif v:version >= 702
+ let l:listedBufferCount = len(filter(range(1, bufnr('$')), 'buflisted(v:val)'))
+ else
+ " Ignore buffer count in this case to make sure we keep the old
+ " behavior
+ let l:listedBufferCount = 0
+ endif
+ if l:listedBufferCount > 1
+ call nerdtree#exec('tabdo windo if winbufnr(0) ==# ' . a:bufnum . " | exec ':bnext! ' | endif", 1)
+ else
+ call nerdtree#exec('tabdo windo if winbufnr(0) ==# ' . a:bufnum . " | exec ':enew! ' | endif", 1)
+ endif
+ call nerdtree#exec('tabnext ' . s:originalTabNumber, 1)
+ call nerdtree#exec(s:originalWindowNumber . 'wincmd w', 1)
+ " 3. We don't need a previous buffer anymore
+ call nerdtree#exec('bwipeout! ' . a:bufnum, 0)
+ endif
+endfunction
+
+"FUNCTION: s:renameBuffer(bufNum, newNodeName, isDirectory){{{1
+"The buffer with the given bufNum is replaced with a new one
+"
+"Args:
+"bufNum: the buffer that may be deleted
+"newNodeName: the name given to the renamed node
+"isDirectory: determines how to do the create the new filenames
+function! s:renameBuffer(bufNum, newNodeName, isDirectory)
+ if a:isDirectory
+ let quotedFileName = fnameescape(a:newNodeName . '/' . fnamemodify(bufname(a:bufNum),':t'))
+ let editStr = g:NERDTreePath.New(a:newNodeName . '/' . fnamemodify(bufname(a:bufNum),':t')).str({'format': 'Edit'})
+ else
+ let quotedFileName = fnameescape(a:newNodeName)
+ let editStr = g:NERDTreePath.New(a:newNodeName).str({'format': 'Edit'})
+ endif
+ " 1. ensure that a new buffer is loaded
+ call nerdtree#exec('badd ' . quotedFileName, 0)
+ " 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()
+ call nerdtree#exec('tabdo windo if winbufnr(0) ==# ' . a:bufNum . " | exec ':e! " . editStr . "' | endif", 0)
+ call nerdtree#exec('tabnext ' . s:originalTabNumber, 1)
+ call nerdtree#exec(s:originalWindowNumber . 'wincmd w', 1)
+ " 3. We don't need a previous buffer anymore
+ try
+ call nerdtree#exec('confirm bwipeout ' . a:bufNum, 0)
+ catch
+ " This happens when answering Cancel if confirmation is needed. Do nothing.
+ endtry
+endfunction
+
+"FUNCTION: NERDTreeAddNode(){{{1
+function! NERDTreeAddNode()
+ let curDirNode = g:NERDTreeDirNode.GetSelected()
+ let prompt = s:inputPrompt('add')
+ let newNodeName = input(prompt, curDirNode.path.str() . g:NERDTreePath.Slash(), 'file')
+
+ if newNodeName ==# ''
+ call nerdtree#echo('Node Creation Aborted.')
+ return
+ endif
+
+ try
+ let newPath = g:NERDTreePath.Create(newNodeName)
+ let parentNode = b:NERDTree.root.findNode(newPath.getParent())
+
+ let newTreeNode = g:NERDTreeFileNode.New(newPath, b:NERDTree)
+ " Emptying g:NERDTreeOldSortOrder forces the sort to
+ " recalculate the cached sortKey so nodes sort correctly.
+ let g:NERDTreeOldSortOrder = []
+ if empty(parentNode)
+ call b:NERDTree.root.refresh()
+ call b:NERDTree.render()
+ elseif parentNode.isOpen || !empty(parentNode.children)
+ call parentNode.addChild(newTreeNode, 1)
+ call NERDTreeRender()
+ call newTreeNode.putCursorHere(1, 0)
+ endif
+
+ redraw!
+ catch /^NERDTree/
+ call nerdtree#echoWarning('Node Not Created.')
+ endtry
+endfunction
+
+"FUNCTION: NERDTreeMoveNode(){{{1
+function! NERDTreeMoveNode()
+ let curNode = g:NERDTreeFileNode.GetSelected()
+ let prompt = s:inputPrompt('move')
+ let newNodePath = input(prompt, curNode.path.str(), 'file')
+ while filereadable(newNodePath)
+ call nerdtree#echoWarning('This destination already exists. Try again.')
+ let newNodePath = input(prompt, curNode.path.str(), 'file')
+ endwhile
+
+
+ if newNodePath ==# ''
+ call nerdtree#echo('Node Renaming Aborted.')
+ return
+ endif
+
+ try
+ if curNode.path.isDirectory
+ let l:openBuffers = filter(range(1,bufnr('$')),'bufexists(v:val) && fnamemodify(bufname(v:val),":p") =~# curNode.path.str() . "/.*"')
+ else
+ let l:openBuffers = filter(range(1,bufnr('$')),'bufexists(v:val) && fnamemodify(bufname(v:val),":p") ==# curNode.path.str()')
+ endif
+
+ call curNode.rename(newNodePath)
+ " Emptying g:NERDTreeOldSortOrder forces the sort to
+ " recalculate the cached sortKey so nodes sort correctly.
+ let g:NERDTreeOldSortOrder = []
+ call b:NERDTree.root.refresh()
+ call NERDTreeRender()
+
+ " If the file node is open, or files under the directory node are
+ " open, ask the user if they want to replace the file(s) with the
+ " renamed files.
+ if !empty(l:openBuffers)
+ if curNode.path.isDirectory
+ echo "\nDirectory renamed.\n\nFiles with the old directory name are open in buffers " . join(l:openBuffers, ', ') . '. Replace these buffers with the new files? (yN)'
+ else
+ echo "\nFile renamed.\n\nThe old file is open in buffer " . l:openBuffers[0] . '. Replace this buffer with the new file? (yN)'
+ endif
+ if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y'
+ for bufNum in l:openBuffers
+ call s:renameBuffer(bufNum, newNodePath, curNode.path.isDirectory)
+ endfor
+ endif
+ endif
+
+ call curNode.putCursorHere(1, 0)
+
+ redraw!
+ catch /^NERDTree/
+ call nerdtree#echoWarning('Node Not Renamed.')
+ endtry
+endfunction
+
+" FUNCTION: NERDTreeDeleteNode() {{{1
+function! NERDTreeDeleteNode()
+ let l:shellslash = &shellslash
+ let &shellslash = 0
+ let currentNode = g:NERDTreeFileNode.GetSelected()
+ let confirmed = 0
+
+ if currentNode.path.isDirectory && ((currentNode.isOpen && currentNode.getChildCount() > 0) ||
+ \ (len(currentNode._glob('*', 1)) > 0))
+ let prompt = s:inputPrompt('deleteNonEmpty') . currentNode.path.str() . ': '
+ let choice = input(prompt)
+ let confirmed = choice ==# 'yes'
+ else
+ let prompt = s:inputPrompt('delete') . currentNode.path.str() . ' (yN): '
+ echo prompt
+ 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 nerdtree#echoWarning('Could not remove node')
+ endtry
+ else
+ call nerdtree#echo('delete aborted')
+ endif
+ let &shellslash = l:shellslash
+endfunction
+
+" FUNCTION: NERDTreeListNode() {{{1
+function! NERDTreeListNode()
+ let treenode = g:NERDTreeFileNode.GetSelected()
+ if !empty(treenode)
+ let s:uname = system('uname')
+ let stat_cmd = 'stat -c "%s" '
+
+ if s:uname =~? 'Darwin'
+ let stat_cmd = 'stat -f "%z" '
+ endif
+
+ let cmd = 'size=$(' . stat_cmd . shellescape(treenode.path.str()) . ') && ' .
+ \ 'size_with_commas=$(echo $size | sed -e :a -e "s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta") && ' .
+ \ 'ls -ld ' . shellescape(treenode.path.str()) . ' | sed -e "s/ $size / $size_with_commas /"'
+
+ let metadata = split(system(cmd),'\n')
+ call nerdtree#echo(metadata[0])
+ else
+ call nerdtree#echo('No information available')
+ endif
+endfunction
+
+" FUNCTION: NERDTreeListNodeWin32() {{{1
+function! NERDTreeListNodeWin32()
+ let l:node = g:NERDTreeFileNode.GetSelected()
+
+ if !empty(l:node)
+ let l:path = l:node.path.str()
+ call nerdtree#echo(printf('%s:%s MOD:%s BYTES:%d PERMISSIONS:%s',
+ \ toupper(getftype(l:path)),
+ \ fnamemodify(l:path, ':t'),
+ \ strftime('%c', getftime(l:path)),
+ \ getfsize(l:path),
+ \ getfperm(l:path)))
+ return
+ endif
+
+ call nerdtree#echo('node not recognized')
+endfunction
+
+" FUNCTION: NERDTreeCopyNode() {{{1
+function! NERDTreeCopyNode()
+ let l:shellslash = &shellslash
+ let &shellslash = 0
+ let currentNode = g:NERDTreeFileNode.GetSelected()
+ let prompt = s:inputPrompt('copy')
+ let newNodePath = input(prompt, currentNode.path.str(), 'file')
+
+ if newNodePath !=# ''
+ "strip trailing slash
+ let newNodePath = substitute(newNodePath, '\/$', '', '')
+
+ let confirmed = 1
+ if currentNode.path.copyingWillOverwrite(newNodePath)
+ call nerdtree#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)
+ " Emptying g:NERDTreeOldSortOrder forces the sort to
+ " recalculate the cached sortKey so nodes sort correctly.
+ let g:NERDTreeOldSortOrder = []
+ if empty(newNode)
+ call b:NERDTree.root.refresh()
+ call b:NERDTree.render()
+ else
+ call NERDTreeRender()
+ call newNode.putCursorHere(0, 0)
+ endif
+ catch /^NERDTree/
+ call nerdtree#echoWarning('Could not copy node')
+ endtry
+ endif
+ else
+ call nerdtree#echo('Copy aborted.')
+ endif
+ let &shellslash = l:shellslash
+ redraw!
+endfunction
+
+" FUNCTION: NERDTreeCopyPath() {{{1
+function! NERDTreeCopyPath()
+ let l:nodePath = g:NERDTreeFileNode.GetSelected().path.str()
+ if has('clipboard')
+ if &clipboard ==# 'unnamedplus'
+ let @+ = l:nodePath
+ else
+ let @* = l:nodePath
+ endif
+ call nerdtree#echo('The path [' . l:nodePath . '] was copied to your clipboard.')
+ else
+ call nerdtree#echo('The full path is: ' . l:nodePath)
+ endif
+endfunction
+
+" FUNCTION: NERDTreeQuickLook() {{{1
+function! NERDTreeQuickLook()
+ let treenode = g:NERDTreeFileNode.GetSelected()
+ if treenode !=# {}
+ call system("qlmanage -p 2>/dev/null '" . treenode.path.str() . "'")
+ endif
+endfunction
+
+" FUNCTION: NERDTreeRevealInFinder() {{{1
+function! NERDTreeRevealInFinder()
+ let treenode = g:NERDTreeFileNode.GetSelected()
+ if treenode !=# {}
+ call system("open -R '" . treenode.path.str() . "'")
+ endif
+endfunction
+
+" FUNCTION: NERDTreeExecuteFile() {{{1
+function! NERDTreeExecuteFile()
+ let treenode = g:NERDTreeFileNode.GetSelected()
+ if treenode !=# {}
+ call system("open '" . treenode.path.str() . "'")
+ endif
+endfunction
+
+" FUNCTION: NERDTreeRevealFileLinux() {{{1
+function! NERDTreeRevealFileLinux()
+ let treenode = g:NERDTreeFileNode.GetSelected()
+ let parentnode = treenode.parent
+ if parentnode !=# {}
+ call system("xdg-open '" . parentnode.path.str() . "' &")
+ endif
+endfunction
+
+" FUNCTION: NERDTreeExecuteFileLinux() {{{1
+function! NERDTreeExecuteFileLinux()
+ let treenode = g:NERDTreeFileNode.GetSelected()
+ if treenode !=# {}
+ call system("xdg-open '" . treenode.path.str() . "' &")
+ endif
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:
+
diff --git a/.config/nvim/plugged/nerdtree/nerdtree_plugin/vcs.vim b/.config/nvim/plugged/nerdtree/nerdtree_plugin/vcs.vim
new file mode 100644
index 0000000..36d5427
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/nerdtree_plugin/vcs.vim
@@ -0,0 +1,47 @@
+" ============================================================================
+" File: vcs.vim
+" Description: NERDTree plugin that provides a command to open on the root of
+" a version control system repository.
+" Maintainer: Phil Runninger
+" 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.
+"
+" ============================================================================
+command! -n=? -complete=dir -bar NERDTreeVCS :call <SID>CreateTabTreeVCS('<args>')
+command! -n=? -complete=dir -bar NERDTreeToggleVCS :call <SID>ToggleTabTreeVCS('<args>')
+
+" FUNCTION: s:CreateTabTreeVCS(a:name) {{{1
+function! s:CreateTabTreeVCS(name)
+ let l:path = g:NERDTreeCreator._pathForString(a:name)
+ let l:path = s:FindParentVCSRoot(l:path)
+ call g:NERDTreeCreator.createTabTree(empty(l:path) ? '' : l:path._str())
+endfunction
+
+" FUNCTION: s:ToggleTabTreeVCS(a:name) {{{1
+" Behaves the same as ToggleTabTree except roots directory at VCS root
+function! s:ToggleTabTreeVCS(name)
+ let l:path = g:NERDTreeCreator._pathForString(a:name)
+ let l:path = s:FindParentVCSRoot(l:path)
+ call g:NERDTreeCreator.toggleTabTree(empty(l:path) ? '' : l:path._str())
+endfunction
+
+" FUNCTION: s:FindParentVCSRoot(a:path) {{{1
+" Finds the root version control system folder of the given path. If a:path is
+" not part of a repository, return the original path.
+function! s:FindParentVCSRoot(path)
+ let l:path = a:path
+ while !empty(l:path) &&
+ \ l:path._str() !~# '^\(\a:\\\|\/\)$' &&
+ \ !isdirectory(l:path._str() . '/.git') &&
+ \ !isdirectory(l:path._str() . '/.svn') &&
+ \ !isdirectory(l:path._str() . '/.hg') &&
+ \ !isdirectory(l:path._str() . '/.bzr') &&
+ \ !isdirectory(l:path._str() . '/_darcs')
+ let l:path = l:path.getParent()
+ endwhile
+ return (empty(l:path) || l:path._str() =~# '^\(\a:\\\|\/\)$') ? a:path : l:path
+endfunction
+
diff --git a/.config/nvim/plugged/nerdtree/plugin/NERD_tree.vim b/.config/nvim/plugged/nerdtree/plugin/NERD_tree.vim
new file mode 100644
index 0000000..639f87b
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/plugin/NERD_tree.vim
@@ -0,0 +1,261 @@
+" ============================================================================
+" File: NERD_tree.vim
+" Maintainer: Martin Grenfell <martin.grenfell at gmail dot com>
+" License: This program is free software. It comes without any warranty,
+" to the extent permitted by applicable law. You can redistribute
+" it and/or modify it under the terms of the Do What The Fuck You
+" Want To Public License, Version 2, as published by Sam Hocevar.
+" See http://sam.zoy.org/wtfpl/COPYING for more details.
+"
+" ============================================================================
+"
+" SECTION: Script init stuff {{{1
+"============================================================
+scriptencoding utf-8
+
+if exists('loaded_nerd_tree')
+ finish
+endif
+if v:version < 703
+ echoerr "NERDTree: this plugin requires vim >= 7.3. DOWNLOAD IT! You'll thank me later!"
+ finish
+endif
+let loaded_nerd_tree = 1
+
+"for line continuation - i.e dont want C in &cpoptions
+let s:old_cpo = &cpoptions
+set cpoptions&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:NERDTreeNaturalSort', 0)
+call s:initVariable('g:NERDTreeSortHiddenFirst', 1)
+call s:initVariable('g:NERDTreeUseTCD', 0)
+call s:initVariable('g:NERDTreeChDirMode', 0)
+call s:initVariable('g:NERDTreeCreatePrefix', 'silent')
+call s:initVariable('g:NERDTreeMinimalUI', 0)
+call s:initVariable('g:NERDTreeMinimalMenu', 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:NERDTreeMarkBookmarks', 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)
+
+if !nerdtree#runningWindows() && !nerdtree#runningCygwin()
+ call s:initVariable('g:NERDTreeDirArrowExpandable', '▸')
+ call s:initVariable('g:NERDTreeDirArrowCollapsible', '▾')
+else
+ call s:initVariable('g:NERDTreeDirArrowExpandable', '+')
+ call s:initVariable('g:NERDTreeDirArrowCollapsible', '~')
+endif
+
+call s:initVariable('g:NERDTreeCascadeOpenSingleChildDir', 1)
+call s:initVariable('g:NERDTreeCascadeSingleChildDir', 1)
+
+if !exists('g:NERDTreeSortOrder')
+ let g:NERDTreeSortOrder = ['\/$', '*', '\.swp$', '\.bak$', '\~$']
+endif
+let g:NERDTreeOldSortOrder = []
+
+call s:initVariable('g:NERDTreeGlyphReadOnly', 'RO')
+
+if has('conceal')
+ call s:initVariable('g:NERDTreeNodeDelimiter', "\x07")
+elseif (g:NERDTreeDirArrowExpandable ==# "\u00a0" || g:NERDTreeDirArrowCollapsible ==# "\u00a0")
+ call s:initVariable('g:NERDTreeNodeDelimiter', "\u00b7")
+else
+ call s:initVariable('g:NERDTreeNodeDelimiter', "\u00a0")
+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:NERDTree(its a b: var, and its a hash)
+ let g:NERDTreeStatusline = "%{exists('b:NERDTree')?b:NERDTree.root.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 ')
+ call s:initVariable('g:NERDTreeCopyDirCmd', 'xcopy /s /e /i /y /q ')
+ call s:initVariable('g:NERDTreeCopyFileCmd', 'copy /y ')
+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:NERDTreeMapCustomOpen', '<CR>')
+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', '<C-j>')
+call s:initVariable('g:NERDTreeMapJumpParent', 'p')
+call s:initVariable('g:NERDTreeMapJumpPrevSibling', '<C-k>')
+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')
+call s:initVariable('g:NERDTreeMenuDown', 'j')
+call s:initVariable('g:NERDTreeMenuUp', 'k')
+
+"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,WinLeave '. g:NERDTreeCreator.BufNamePrefix() .'* if g:NERDTree.IsOpen() | call b:NERDTree.ui.saveScreenState() | endif'
+
+ "disallow insert mode in the NERDTree
+ exec 'autocmd BufEnter,WinEnter '. g:NERDTreeCreator.BufNamePrefix() .'* stopinsert'
+augroup END
+
+if g:NERDTreeHijackNetrw
+ augroup NERDTreeHijackNetrw
+ autocmd VimEnter * silent! autocmd! FileExplorer
+ au BufEnter,VimEnter * call nerdtree#checkForBrowse(expand('<amatch>'))
+ augroup END
+endif
+
+if g:NERDTreeChDirMode ==# 3
+ augroup NERDTreeChDirOnTabSwitch
+ autocmd TabEnter * if g:NERDTree.ExistsForTab()|call g:NERDTree.ForCurrentTab().getRoot().path.changeToDir()|endif
+ 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.ToggleTabTree('')
+ endif
+endfunction
+
+function! NERDTreeCWD()
+
+ if empty(getcwd())
+ call nerdtree#echoWarning('current directory does not exist')
+ return
+ endif
+
+ try
+ let l:cwdPath = g:NERDTreePath.New(getcwd())
+ catch /^NERDTree.InvalidArgumentsError/
+ call nerdtree#echoWarning('current directory does not exist')
+ return
+ endtry
+
+ call NERDTreeFocus()
+
+ if b:NERDTree.root.path.equals(l:cwdPath)
+ return
+ endif
+
+ let l:newRoot = g:NERDTreeFileNode.New(l:cwdPath, b:NERDTree)
+ call b:NERDTree.changeRoot(l:newRoot)
+ normal! ^
+endfunction
+
+function! NERDTreeAddPathFilter(callback)
+ call g:NERDTree.AddPathFilter(a:callback)
+endfunction
+
+" SECTION: Post Source Actions {{{1
+call nerdtree#postSourceActions()
+
+"reset &cpoptions back to users setting
+let &cpoptions = s:old_cpo
+
+" vim: set sw=4 sts=4 et fdm=marker:
diff --git a/.config/nvim/plugged/nerdtree/screenshot.png b/.config/nvim/plugged/nerdtree/screenshot.png
new file mode 100644
index 0000000..c410c5d
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/screenshot.png
Binary files differ
diff --git a/.config/nvim/plugged/nerdtree/syntax/nerdtree.vim b/.config/nvim/plugged/nerdtree/syntax/nerdtree.vim
new file mode 100644
index 0000000..df0c804
--- /dev/null
+++ b/.config/nvim/plugged/nerdtree/syntax/nerdtree.vim
@@ -0,0 +1,95 @@
+let s:tree_up_dir_line = '.. (up a dir)'
+syn match NERDTreeIgnore #\~#
+exec 'syn match NERDTreeIgnore #\['.g:NERDTreeGlyphReadOnly.'\]#'
+
+"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
+
+"highlighting to conceal the delimiter around the file/dir name
+if has('conceal')
+ exec 'syn match NERDTreeNodeDelimiters #\%d' . char2nr(g:NERDTreeNodeDelimiter) . '# conceal containedin=ALL'
+ setlocal conceallevel=3 concealcursor=nvic
+else
+ exec 'syn match NERDTreeNodeDelimiters #\%d' . char2nr(g:NERDTreeNodeDelimiter) . '# containedin=ALL'
+ hi! link NERDTreeNodeDelimiters Ignore
+endif
+
+"highlighing for directory nodes and file nodes
+syn match NERDTreeDirSlash #/# containedin=NERDTreeDir
+
+if g:NERDTreeDirArrowExpandable !=# ''
+ exec 'syn match NERDTreeClosable #' . escape(g:NERDTreeDirArrowCollapsible, '~') . '\ze .*/# containedin=NERDTreeDir,NERDTreeFile'
+ exec 'syn match NERDTreeOpenable #' . escape(g:NERDTreeDirArrowExpandable, '~') . '\ze .*/# containedin=NERDTreeDir,NERDTreeFile'
+ let s:dirArrows = escape(g:NERDTreeDirArrowCollapsible, '~]\-').escape(g:NERDTreeDirArrowExpandable, '~]\-')
+ exec 'syn match NERDTreeDir #[^'.s:dirArrows.' ].*/#'
+ exec 'syn match NERDTreeExecFile #^.*'.g:NERDTreeNodeDelimiter.'\*\($\| \)# contains=NERDTreeRO,NERDTreeBookmark'
+ exec 'syn match NERDTreeFile #^[^"\.'.s:dirArrows.'] *[^'.s:dirArrows.']*# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmark,NERDTreeExecFile'
+else
+ exec 'syn match NERDTreeDir #[^'.g:NERDTreeNodeDelimiter.']\{-}/\ze\($\|'.g:NERDTreeNodeDelimiter.'\)#'
+ exec 'syn match NERDTreeExecFile #[^'.g:NERDTreeNodeDelimiter.']\{-}'.g:NERDTreeNodeDelimiter.'\*\($\| \)# contains=NERDTreeRO,NERDTreeBookmark'
+ exec 'syn match NERDTreeFile #^.*'.g:NERDTreeNodeDelimiter.'.*[^\/]\($\|'.g:NERDTreeNodeDelimiter.'.*\)# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmark,NERDTreeExecFile'
+endif
+
+"highlighting for readonly files
+exec 'syn match NERDTreeRO #.*'.g:NERDTreeNodeDelimiter.'\zs.*\ze'.g:NERDTreeNodeDelimiter.'.*\['.g:NERDTreeGlyphReadOnly.'\]# contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreeFile'
+
+exec 'syn match NERDTreeFlags #\[[^\]]*\]\ze'.g:NERDTreeNodeDelimiter.'# containedin=NERDTreeFile,NERDTreeExecFile,NERDTreeDir'
+
+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 Directory
+hi def link NERDTreeClosable Directory
+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