diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index dd351350..e2ce07b9 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -5,41 +5,42 @@ labels: bug --- +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 - -- [ ] 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. +Before creating an issue, take some time to search these resources for an answer. It's possible that someone else has already seen and solved your issue. +- [old NERDTree issues](https://github.com/preservim/nerdtree/issues?q=is%3Aissue) +- NERDTree documentation - `:h NERDTree` +- [NERDTree Wiki](https://github.com/preservim/nerdtree/wiki) +- Other resources: , , etc. + +#### Environment +- Operating System: +- Vim/Neovim version `:version`: +- NERDTree version, found on first line of quickhelp `?`: +- Are you using any of these NERDTree-dependent plugins? + - [ ] [Xuyuanp/nerdtree-git-plugin](https://github.com/Xuyuanp/nerdtree-git-plugin) + - [ ] [ryanoasis/vim-devicons](https://github.com/ryanoasis/vim-devicons) + - [ ] [tiagofumo/vim-nerdtree-syntax-highlight](https://github.com/tiagofumo/vim-nerdtree-syntax-highlight) + - [ ] [scrooloose/nerdtree-project-plugin](https://github.com/scrooloose/nerdtree-project-plugin) + - [ ] [PhilRunninger/nerdtree-buffer-ops](https://github.com/PhilRunninger/nerdtree-buffer-ops) + - [ ] [PhilRunninger/nerdtree-visual-selection](https://github.com/PhilRunninger/nerdtree-visual-selection) + - [ ] [jistr/vim-nerdtree-tabs](https://github.com/jistr/vim-nerdtree-tabs) + - [ ] Others (specify): +- Provide a minimal **.vimrc** file that will reproduce the issue. +```vim +``` #### Steps to Reproduce the Issue 1. -#### Current Result (Include screenshots where appropriate.) +#### Current Behavior (Include screenshots where appropriate.) #### Expected Result diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 25f15b02..7e13b7ac 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -3,22 +3,11 @@ name: "General Question" about: "Having trouble setting up NERDTree? Need clarification on a setting? Ask your question here." labels: "general question" --- - - -#### Self-Diagnosis - -- [ ] 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. +Before creating an issue, take some time to search these resources. It's possible that someone else has already asked your question and gotten an answer. +- [old NERDTree issues](https://github.com/preservim/nerdtree/issues?q=is%3Aissue) +- NERDTree documentation - `:h NERDTree` +- [NERDTree Wiki](https://github.com/preservim/nerdtree/wiki) +- Other resource: , , etc. #### State Your Question diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 24dba3f5..911f4598 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,16 +1,7 @@ ### Description of Changes -Closes # +Closes # --- ### 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/.github/workflows/vint.yml b/.github/workflows/vint.yml new file mode 100644 index 00000000..68351b1c --- /dev/null +++ b/.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@v3 + - name: Run vint with reviewdog + uses: reviewdog/action-vint@v1 + with: + github_token: ${{ secrets.github_token }} + reporter: github-pr-review diff --git a/.vintrc.yaml b/.vintrc.yaml new file mode 100644 index 00000000..c44b6aba --- /dev/null +++ b/.vintrc.yaml @@ -0,0 +1,5 @@ +cmdargs: + severity: style_problem + color: true + env: + neovim: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 73d17b13..ba25bf16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,154 +1,257 @@ # NERDTree Change Log - - - +#### 7.1 +- **.3**: + - docs: update FAQ snippets containing quit command. (rzvxa) [#1417](https://github.com/preservim/nerdtree/pull/1417) + - feat: jump to bookmark table shortcut. (ds2606, rzvxa) [#1394](https://github.com/preservim/nerdtree/pull/1394) + - fix: typo in docs for show file lines setting. (lothardp) [#1426](https://github.com/preservim/nerdtree/pull/1426) +- **.2**: + - fix: GetWinNum regex pattern. (rzvxa) [#1409](https://github.com/preservim/nerdtree/pull/1409) + - fix: session restore for nerdtree buffers. (rzvxa) [#1405](https://github.com/preservim/nerdtree/pull/1405) +- **.1**: + - fix: change default binding of filelines to `FL`. (rzvxa) [#1400](https://github.com/preservim/nerdtree/pull/1400) + - fix: toggle zoom resizing. (ds2606) [#1395](https://github.com/preservim/nerdtree/pull/1395) +- **.0**: + - fix: typo in the docs. (bl4kraven) [#1390](https://github.com/preservim/nerdtree/pull/1390) + - feat: add NERDTreeExplore command. (msibal6) [#1389](https://github.com/preservim/nerdtree/pull/1389) + - fix: mapping description in NERDTree.txt. (roccomao) [#1393](https://github.com/preservim/nerdtree/pull/1393) +#### 7.0 +- **.1**: + - Fix NERDTreeFind to handle directory case sensitivity. (dangibson) [#1387](https://github.com/preservim/nerdtree/pull/1387) + - New Show file lines toggle. (hsnks100) [#1384](https://github.com/preservim/nerdtree/pull/1384) + - Add case sensitivity for refreshing nodes. (rzvxa) [#1382](https://github.com/preservim/nerdtree/pull/1382) + - Clarified the NERDTreeChangePermissions prompt. (rzvxa) [#1381](https://github.com/preservim/nerdtree/pull/1381) + - New reveal functionality for Windows. (rzvxa) [#1366](https://github.com/preservim/nerdtree/pull/1366) + - Fix bracket escaping in path names. (kai-patel) [#1359](https://github.com/preservim/nerdtree/pull/1359) + - Fix Case Sensitive Move Operation. (rzvxa) [#1375](https://github.com/preservim/nerdtree/pull/1375) + - New menu command for changing selected node permissions. (mjkloeckner) [#1348](https://github.com/preservim/nerdtree/pull/1348) + - Fix documentation errors. (BubuDavid) [#1372](https://github.com/preservim/nerdtree/pull/1372) + - Fix typo in nerdtree.vim file. (SandeshPyakurel) [#1380](https://github.com/preservim/nerdtree/pull/1380) +- **.0**: + - Now we warn about invalid files instead of ignoring them silently. (rmonico) [#1365](https://github.com/preservim/nerdtree/pull/1365) + - New g:NERDTreeWinPos options for top and bottom. (rzvxa) [#1363](https://github.com/preservim/nerdtree/pull/1363) + - Fix error in README. (nickspoons) [#1330](https://github.com/preservim/nerdtree/pull/1330) + - Fix typo in the documentation. (chapeupreto) [#1306](https://github.com/preservim/nerdtree/pull/1306) +#### 6.10 +- **.16**: Fix documentation errors. (lifecrisis) [#1269](https://github.com/preservim/nerdtree/pull/1269) +- **.15**: Ensure backward compatible testing of types. (lifecrisis) [#1266](https://github.com/preservim/nerdtree/pull/1266) +- **.14**: Replace trim() with a version-compatible alternative. (PhilRunninger) [#1265](https://github.com/preservim/nerdtree/pull/1265) +- **.13**: Change highlighting of bookmarks in the tree. (PhilRunninger) [#1261](https://github.com/preservim/nerdtree/pull/1261) +- **.12**: Answer the question about accessing files over scp or ftp. (PhilRunninger) [#1259](https://github.com/preservim/nerdtree/pull/1259) +- **.11**: Trim filenames created via the fs_menu (elanorigby) [#1243](https://github.com/preservim/nerdtree/pull/1243) +- **.10**: Improve F.A.Q. Answers and Issue Templates (PhilRunninger) [#1249](https://github.com/preservim/nerdtree/pull/1249) +- **.9**: `go` on a bookmark directory will NERDTreeFind it. (PhilRunninger) [#1236](https://github.com/preservim/nerdtree/pull/1236) +- **.8**: Put `Callback` function variables in local scope. (PhilRunninger) [#1230](https://github.com/preservim/nerdtree/pull/1230) +- **.7**: Fix mouse-clicking a file to open it. (PhilRunninger) [#1225](https://github.com/preservim/nerdtree/pull/1225) +- **.6**: Restore the default behavior of the `` key. (PhilRunninger) [#1221](https://github.com/preservim/nerdtree/pull/1221) +- **.5**: Fix `{'keepopen':0}` in NERDTreeCustomOpenArgs (PhilRunninger) [#1217](https://github.com/preservim/nerdtree/pull/1217) +- **.4**: Removed directory separator from sort key (Daniel E) [#1219](https://github.com/preservim/nerdtree/pull/1219) +- **.3**: Add new FAQ and answer: How to prevent buffers replacing NERDTree. (PhilRunninger) [#1215](https://github.com/preservim/nerdtree/pull/1215) +- **.2**: New menu command: Run a system command in this directory. (PhilRunninger) [#1214](https://github.com/preservim/nerdtree/pull/1214) +- **.1**: Escape quotation marks so they can be used in key mappings. (PhilRunninger) [#1213](https://github.com/preservim/nerdtree/pull/1213) +- **.0**: Enable full path specifications for NERDTreeIgnore (PhilRunninger) [#1207](https://github.com/preservim/nerdtree/pull/1207) +#### 6.9 +- **.12**: Respect NERDTreeCustomOpenArgs when opening bookmark (przepompownia) [#1200](https://github.com/preservim/nerdtree/pull/1200) +- **.11**: Revamp the README. (buncis, PhilRunninger) [#1192](https://github.com/preservim/nerdtree/pull/1192), [#1193](https://github.com/preservim/nerdtree/pull/1193) +- **.10**: Open a mirrored NERDTree with correct width (PhilRunninger) [#1177](https://github.com/preservim/nerdtree/pull/1177) +- **.9**: Updated Readme, removed typo (H3RSKO) [#1167](https://github.com/preservim/nerdtree/pull/1167) +- **.8**: Refactor sort comparison functions, removing redundancy (PhilRunninger) [#1166](https://github.com/preservim/nerdtree/pull/1166) +- **.7**: Fix argument of `exists()` function calls checking for autocommands. (PhilRunninger) [#1165](https://github.com/preservim/nerdtree/pull/1165) +- **.6**: Don't use silent when raising User events (PhilRunninger) [#1164](https://github.com/preservim/nerdtree/pull/1164) +- **.5**: Fix highlight for file node. (pirey) [#1157](https://github.com/preservim/nerdtree/pull/1157) +- **.4**: Make sure symbolic links' flags are highlighted correctly. (PhilRunninger) [#1156](https://github.com/preservim/nerdtree/pull/1156) +- **.3**: Fix new NERDTrees' width when previous one was in the only window. (PhilRunninger) [#1153](https://github.com/preservim/nerdtree/pull/1153) +- **.2**: Fix the scope of several key mappings (lifecrisis, PhilRunninger) [#1151](https://github.com/preservim/nerdtree/pull/1151) +- **.1**: Respect user's `&shellslash` setting in CopyNode and RemoveNode functions (PhilRunninger) [#1150](https://github.com/preservim/nerdtree/pull/1150) +- **.0**: Enable opening bookmarks in split windows. (PhilRunninger) [#1144](https://github.com/preservim/nerdtree/pull/1144) +#### 6.8 +- **.0**: Allow concealed characters to show another character. (PhilRunninger) [#1138](https://github.com/preservim/nerdtree/pull/1138) +#### 6.7 +- **.15**: Add curly braces to the list of characters to be escaped. (PhilRunninger) [#1128](https://github.com/preservim/nerdtree/pull/1128) +- **.14**: Use backward-compatible `nerdtree#and()` in one place that was missed. (PhilRunninger) [#1134](https://github.com/preservim/nerdtree/pull/1134) +- **.13**: `cmd.exe /c start "" ` for windows default viewer support. (J. Altayó) [#1130](https://github.com/preservim/nerdtree/pull/1130) +- **.12**: Fixed a bug that caused the file-tree construction to slow down significantly. (Eugenij-W) [#1126](https://github.com/preservim/nerdtree/pull/1126) +- **.11**: Fix exception in NERDTreeFind (on windows OS and If the file is located in the root directory of the disk) (Eugenij-W) [#1122](https://github.com/preservim/nerdtree/pull/1122) +- **.10**: Do not consider the tree root to be "cascadable". (lifecrisis) [#1120](https://github.com/preservim/nerdtree/pull/1120) +- **.9**: Force `:NERDTreeFocus` to allow events to be fired when switching windows. (PhilRunninger) [#1118](https://github.com/preservim/nerdtree/pull/1118) +- **.8**: Fix example code for the `NERDTreeAddKeyMap()` function. (PhilRunninger) [#1116](https://github.com/preservim/nerdtree/pull/1116) +- **.7**: Put `'%'` argument in `bufname()` for backwards compatibility. (PhilRunninger) [#1105](https://github.com/preservim/nerdtree/pull/1105) +- **.6**: If a file's already open in the window, don't edit it again. (PhilRunninger) [#1103](https://github.com/preservim/nerdtree/pull/1103) +- **.5**: Prevent unneeded tree creation in `:NERDTreeToggle[VCS] ` (PhilRunninger) [#1101](https://github.com/preservim/nerdtree/pull/1101) +- **.4**: Add missing calls to the `shellescape()` function (lifecrisis) [#1099](https://github.com/preservim/nerdtree/pull/1099) +- **.3**: Fix vsplit to not open empty buffers when opening previously closed file (AwkwardKore) [#1098](https://github.com/preservim/nerdtree/pull/1098) +- **.2**: Fix infinity loop (on winvim) in FindParentVCSRoot (Eugenij-W) [#1095](https://github.com/preservim/nerdtree/pull/1095) +- **.1**: File Move: Escape existing directory name when looking for open files. (PhilRunninger) [#1094](https://github.com/preservim/nerdtree/pull/1094) +- **.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 ` 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 -- **.0**: Support tab-specific CWDs (PhilRunninger) [#1032](https://github.com/scrooloose/nerdtree/pull/1032) +- **.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/scrooloose/nerdtree/pull/1049) -- **.3**: Save/Set screen state also on WinLeave and WinEnter. (PhilRunninger) [#1048](https://github.com/scrooloose/nerdtree/pull/1048) -- **.2**: Wrap saveScreenState's statements in a try-catch block. (PhilRunninger) [#1047](https://github.com/scrooloose/nerdtree/pull/1047) -- **.1**: Catch errors when trying to read CHANGELOG.md. (PhilRunninger) [#1045](https://github.com/scrooloose/nerdtree/pull/1045) -- **.0**: If file path doesn't exist, :NERDTreeFind its parent directory instead. (PhilRunninger) [#1043](https://github.com/scrooloose/nerdtree/pull/1043) +- **.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/scrooloose/nerdtree/pull/1040) -- **.0**: Make the behavior of window splits consistent (dragonxlwang, PhilRunninger) [#1035](https://github.com/scrooloose/nerdtree/pull/1035) +- **.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/scrooloose/nerdtree/pull/1038) -- **.2**: Enable events when closing NerdTree window. (PhilRunninger) [#1037](https://github.com/scrooloose/nerdtree/pull/1037) -- **.1**: Fix the `e` key mapping to use netrw if desired (PhilRunninger) [#1031](https://github.com/scrooloose/nerdtree/pull/1031) -- **.0**: Add file extension and size to sorting capabilities (PhilRunninger) [#1029](https://github.com/scrooloose/nerdtree/pull/1029) +- **.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/scrooloose/nerdtree/pull/1026) -- **.8**: Revert [#1019](https://github.com/scrooloose/nerdtree/pull/1019) to fix nvim artifacts and flickering. (PhilRunninger) [#1021](https://github.com/scrooloose/nerdtree/pull/1021) -- **.7**: Use :mode only in neovim. MacVim still needs to use :redraw! (PhilRunninger) [#1019](https://github.com/scrooloose/nerdtree/pull/1019) -- **.6**: In CHANGELOG.md and PR template, make reference to PR a true HTML link. (PhilRunninger) [#1017](https://github.com/scrooloose/nerdtree/pull/1017) -- **.5**: Use `:mode` instead of `:redraw!` when updating menu. (PhilRunninger) [#1016](https://github.com/scrooloose/nerdtree/pull/1016) -- **.4**: When searching for root line num, stop at end of file. (PhilRunninger) [#1015](https://github.com/scrooloose/nerdtree/pull/1015) -- **.3**: Fix `` key map on the bookmark (lkebin) [#1014](https://github.com/scrooloose/nerdtree/pull/1014) -- **.2**: Make Enter work on the `.. ( up a dir )` line (PhilRunninger) [#1013](https://github.com/scrooloose/nerdtree/pull/1013) +- **.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 `` 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 `` mapping. (PhilRunninger) [#1011](https://github.com/scrooloose/nerdtree/pull/1011) +- **.0**: Expand functionality of `` 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/scrooloose/nerdtree/pull/1009) -- **.2**: Fix NERDTree opening with the wrong size. (PhilRunninger) [#1008](https://github.com/scrooloose/nerdtree/pull/1008) -- **.1**: Update Changelog and create PR Template (PhilRunninger) [#1007](https://github.com/scrooloose/nerdtree/pull/1007) +- **.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/scrooloose/nerdtree/pull/1005) - - Add a "copy path to clipboard" menu option (PhilRunninger) [#1002](https://github.com/scrooloose/nerdtree/pull/1002) - - Enable root refresh on "vim ." a different way than [#999](https://github.com/scrooloose/nerdtree/pull/999). (PhilRunninger) [#1001](https://github.com/scrooloose/nerdtree/pull/1001) - - Fix refreshroot (PhilRunninger) [#999](https://github.com/scrooloose/nerdtree/pull/999) - - Change version check to look for 703 not 730 (vhalis) [#994](https://github.com/scrooloose/nerdtree/pull/994) - - Change minimum vim (PhilRunninger) [#991](https://github.com/scrooloose/nerdtree/pull/991) - - Allow multi-character DirArrows (PhilRunninger) [#985](https://github.com/scrooloose/nerdtree/pull/985) - - Remove redraw! while still clearing last message empty string. (PhilRunninger) [#979](https://github.com/scrooloose/nerdtree/pull/979) - - fix `_initChildren` function value set to numChildrenCached error (terryding77) [#969](https://github.com/scrooloose/nerdtree/pull/969) - - On Windows, do a case-insensitive comparison of paths. (PhilRunninger) [#967](https://github.com/scrooloose/nerdtree/pull/967) - - Remove the **Please wait... DONE** messages. (PhilRunninger) [#966](https://github.com/scrooloose/nerdtree/pull/966) - - Smarter delimiter default (PhilRunninger) [#963](https://github.com/scrooloose/nerdtree/pull/963) - - Update directory .vimdc readme example (spencerdcarlson) [#961](https://github.com/scrooloose/nerdtree/pull/961) - - Preview bookmarks (PhilRunninger) [#956](https://github.com/scrooloose/nerdtree/pull/956) - - Add new value to NERDTreeQuitOnOpen to close bookmark table (PhilRunninger) [#955](https://github.com/scrooloose/nerdtree/pull/955) - - Add an :EditBookmarks command to edit the bookmarks file (PhilRunninger) [#954](https://github.com/scrooloose/nerdtree/pull/954) - - Before copying, turn off &shellslash. Restore after copy is finished. (PhilRunninger) [#952](https://github.com/scrooloose/nerdtree/pull/952) - - Set a maximum window size when zooming. (PhilRunninger) [#950](https://github.com/scrooloose/nerdtree/pull/950) - - Confirm the wipeout of a unsaved buffer whose file has been renamed. (PhilRunninger) [#949](https://github.com/scrooloose/nerdtree/pull/949) - - Escape a backslash so it can be used in a key mapping. (PhilRunninger) [#948](https://github.com/scrooloose/nerdtree/pull/948) - - Add a NERDTreeMinimalMenu feature (tuzz) [#938](https://github.com/scrooloose/nerdtree/pull/938) - - fixed root path error for windows (zcodes) [#935](https://github.com/scrooloose/nerdtree/pull/935) - - Restore getDirChildren for use in nerdtree-project-plugin. (PhilRunninger) [#929](https://github.com/scrooloose/nerdtree/pull/929) - - Document NERDTreeNodeDelimiter [#912](https://github.com/scrooloose/nerdtree/pull/912) (PhilRunninger) [#926](https://github.com/scrooloose/nerdtree/pull/926) - - Allow modification of menu keybindings (Leandros) [#923](https://github.com/scrooloose/nerdtree/pull/923) - - Add two more disqualifications for isCascadable(). (PhilRunninger) [#914](https://github.com/scrooloose/nerdtree/pull/914) - - Allow highlighting more than one flag. (kristijanhusak) [#908](https://github.com/scrooloose/nerdtree/pull/908) - - Support sorting files and directories by modification time. (PhilRunninger) [#901](https://github.com/scrooloose/nerdtree/pull/901) - - Parse . and .. from path string with trailing slash. (PhilRunninger) [#899](https://github.com/scrooloose/nerdtree/pull/899) - - Force sort to recalculate the cached sortKey. (PhilRunninger) [#898](https://github.com/scrooloose/nerdtree/pull/898) - - Add NERDTreeRefreshRoot command (wgfm) [#897](https://github.com/scrooloose/nerdtree/pull/897) - - Call Resolve on the file's path when calling :NERDTreeFind. (PhilRunninger) [#896](https://github.com/scrooloose/nerdtree/pull/896) - - Catch all errors, not just NERDTree errors. (PhilRunninger) [#894](https://github.com/scrooloose/nerdtree/pull/894) - - Fix typo in help file (lvoisin) [#892](https://github.com/scrooloose/nerdtree/pull/892) - - Make NERDTreeCreator set the `'nolist'` option (lifecrisis) [#889](https://github.com/scrooloose/nerdtree/pull/889) - - Refresh buffers after `m`, `m` operation on a folder (PhilRunninger) [#888](https://github.com/scrooloose/nerdtree/pull/888) - - Use a better arg for FINDSTR when using the m,l command in Windows. (PhilRunninger) [#887](https://github.com/scrooloose/nerdtree/pull/887) - - Fix the / motions, which currently fail with cascades (lifecrisis) [#886](https://github.com/scrooloose/nerdtree/pull/886) - - Function "s:UI.getLineNum()" doesn't always work on cascades. (lifecrisis) [#882](https://github.com/scrooloose/nerdtree/pull/882) - - NERDTreeCWD: reset CWD if changed by NERDTreeFocus (PhilRunninger) [#878](https://github.com/scrooloose/nerdtree/pull/878) - - Use tabnext instead of gt to allow users to remap gt. (PhilRunninger) [#877](https://github.com/scrooloose/nerdtree/pull/877) - - Do a case sensitive comparison of new/existing buffers. (PhilRunninger) [#875](https://github.com/scrooloose/nerdtree/pull/875) - - Fix opening sub-directories that have commas in their name. (PhilRunninger) [#873](https://github.com/scrooloose/nerdtree/pull/873) - - Add new command to open NERDTree in the root of a VCS repository. (PhilRunninger) [#872](https://github.com/scrooloose/nerdtree/pull/872) - - Make sure the path to the bookmarks file exists before writing it. (PhilRunninger) [#871](https://github.com/scrooloose/nerdtree/pull/871) - - Unzoom NERDTree when opening a file (PhilRunninger) [#870](https://github.com/scrooloose/nerdtree/pull/870) - - Support unusual characters in file and directory names (PhilRunninger) [#868](https://github.com/scrooloose/nerdtree/pull/868) - - Reword renamed-buffer prompt to be more clear (aflock) [#867](https://github.com/scrooloose/nerdtree/pull/867) - - Default to placing cursor on root when closing bookmark table (lifecrisis) [#866](https://github.com/scrooloose/nerdtree/pull/866) - - Fix issues with sorting of nodes (PhilRunninger) [#856](https://github.com/scrooloose/nerdtree/pull/856) - - Better OSX detection (bubba-h57) [#853](https://github.com/scrooloose/nerdtree/pull/853) - - Bugfix - ensure keymaps dictionary exists before using it (mnussbaum) [#852](https://github.com/scrooloose/nerdtree/pull/852) - - Decrease startup-time by avoiding linear-time iteration over key mappings (mnussbaum) [#851](https://github.com/scrooloose/nerdtree/pull/851) - - Add code to sort mappings in quickhelp (lifecrisis) [#849](https://github.com/scrooloose/nerdtree/pull/849) - - Use ":clearjumps" in new NERDTree windows (lifecrisis) [#844](https://github.com/scrooloose/nerdtree/pull/844) - - Like m-c did before, create parent directories if needed on m-m. (PhilRunninger) [#840](https://github.com/scrooloose/nerdtree/pull/840) - - BUGFIX: Repair a problem with the `'u'` mapping. (lifecrisis) [#838](https://github.com/scrooloose/nerdtree/pull/838) - - Make the NERDTree buffer writable when rendering it. (PhilRunninger) [#837](https://github.com/scrooloose/nerdtree/pull/837) - - Code cleanup: Remove unsupported bookmark table mappings (lifecrisis) [#835](https://github.com/scrooloose/nerdtree/pull/835) - - Replace strcharpart() with substitute() for backward compatibility (bravestarr) [#834](https://github.com/scrooloose/nerdtree/pull/834) - - Fixed error `unknown function strcharpart` for older versions of Vim (hav4ik) [#833](https://github.com/scrooloose/nerdtree/pull/833) - - Clear output when NERDTree menu is aborted (lifecrisis) [#832](https://github.com/scrooloose/nerdtree/pull/832) - - Display a path with multi-byte characters correctly when it is truncated (bravestarr) [#830](https://github.com/scrooloose/nerdtree/pull/830) - - Support revealing file and executing file with xdg-open for Linux (ngnmhieu) [#824](https://github.com/scrooloose/nerdtree/pull/824) - - If node isn't open, count children on disk before deleting. (PhilRunninger) [#822](https://github.com/scrooloose/nerdtree/pull/822) - - Add new variable g:NERDTreeRemoveFileCmd (kutsan) [#816](https://github.com/scrooloose/nerdtree/pull/816) - - Use a better check for existence of the NERDTree buffer. (PhilRunninger) [#814](https://github.com/scrooloose/nerdtree/pull/814) - - Fix focussing previous buffer when closing NERDTree (mrubli) [#801](https://github.com/scrooloose/nerdtree/pull/801) - - Update the docs for "NERDTreeStatusline" (lifecrisis) [#796](https://github.com/scrooloose/nerdtree/pull/796) - - BUGFIX: Unstable behavior in the "getPath()" method (lifecrisis) [#795](https://github.com/scrooloose/nerdtree/pull/795) - - Revert the bugfix from pull request [#785](https://github.com/scrooloose/nerdtree/pull/785) (lifecrisis) [#794](https://github.com/scrooloose/nerdtree/pull/794) - - BUGFIX: Allow ":NERDTreeFind" to discover hidden files (lifecrisis) [#786](https://github.com/scrooloose/nerdtree/pull/786) - - BUGFIX: Allow ":NERDTreeFind" to reveal new files (lifecrisis) [#785](https://github.com/scrooloose/nerdtree/pull/785) - - Add modelines (lifecrisis) [#782](https://github.com/scrooloose/nerdtree/pull/782) - - Change the type of completion used by NERDTreeFind (lifecrisis) [#781](https://github.com/scrooloose/nerdtree/pull/781) - - change NERDTreeFind with args (zhenyangze) [#778](https://github.com/scrooloose/nerdtree/pull/778) - - Style Choice: Using confirm() when deleting a bookmark (lifecrisis) [#777](https://github.com/scrooloose/nerdtree/pull/777) - - remove useless substitute when `file =~# "/$"` (skyblueee) [#773](https://github.com/scrooloose/nerdtree/pull/773) - - remove useless removeLeadingSpaces in _stripMarkup (skyblueee) [#772](https://github.com/scrooloose/nerdtree/pull/772) - - Make the "o" mapping consistent with "x" (lifecrisis) [#769](https://github.com/scrooloose/nerdtree/pull/769) - - Fix a problem with the "x" handler (lifecrisis) [#768](https://github.com/scrooloose/nerdtree/pull/768) - - Clean up the handler for the "x" mapping (lifecrisis) [#767](https://github.com/scrooloose/nerdtree/pull/767) - - Revert change to tab opening method (lifecrisis) [#766](https://github.com/scrooloose/nerdtree/pull/766) - - BUGFIX: Add back support for "b:NERDTreeRoot" (lifecrisis) [#765](https://github.com/scrooloose/nerdtree/pull/765) - - Fix broken "t" and "T" mappings, tabs now open at end (lifecrisis) [#759](https://github.com/scrooloose/nerdtree/pull/759) - - Update doc with already existing mapping variables (asnr) [#699](https://github.com/scrooloose/nerdtree/pull/699) - - Fix the broken g:NERDTreeBookmarksSort setting (lifecrisis) [#696](https://github.com/scrooloose/nerdtree/pull/696) - - Correct NERDTreeIgnore pattern in doc (cntoplolicon) [#648](https://github.com/scrooloose/nerdtree/pull/648) - - Remove empty segments when splitting path (sooth-sayer) [#574](https://github.com/scrooloose/nerdtree/pull/574) - - Suppress autocmds less agressively (wincent) [#578](https://github.com/scrooloose/nerdtree/pull/578) [#691](https://github.com/scrooloose/nerdtree/pull/691) + - 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 / 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 tabnext instead of 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/scrooloose/nerdtree/pull/676) + - 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/scrooloose/nerdtree/pull/649) - - Reuse/reopen existing window trees where possible [#244](https://github.com/scrooloose/nerdtree/pull/244) + - 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/scrooloose/nerdtree/pull/630) - - Improved a tip in README.markdown (ggicci) [#628](https://github.com/scrooloose/nerdtree/pull/628) - - Shorten delete confimration of empty directory to `y` (mikeperri) [#530](https://github.com/scrooloose/nerdtree/pull/530) - - Fix API call to open directory tree in window (devm33) [#533](https://github.com/scrooloose/nerdtree/pull/533) - - Change default arrows on non-Windows platforms (gwilk) [#546](https://github.com/scrooloose/nerdtree/pull/546) - - Update to README - combine cd and git clone (zwhitchcox) [#584](https://github.com/scrooloose/nerdtree/pull/584) - - Update to README - Tip: start NERDTree when vim starts (therealplato) [#593](https://github.com/scrooloose/nerdtree/pull/593) - - Escape filename when moving an open buffer (zacharyvoase) [#595](https://github.com/scrooloose/nerdtree/pull/595) - - Fixed incorrect :helptags command in README (curran) [#619](https://github.com/scrooloose/nerdtree/pull/619) - - Fixed incomplete escaping of folder arrows (adityanatraj) [#548](https://github.com/scrooloose/nerdtree/pull/548) - - Added NERDTreeCascadeSingleChildDir option (juanibiapina) [#558](https://github.com/scrooloose/nerdtree/pull/558) + - 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/scrooloose/nerdtree/pull/231) + - 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. diff --git a/README.markdown b/README.markdown index 9e539523..1ab47fe6 100644 --- a/README.markdown +++ b/README.markdown @@ -1,145 +1,261 @@ -The NERDTree -============= +# The NERDTree [![Vint](https://github.com/preservim/nerdtree/workflows/Vint/badge.svg)](https://github.com/preservim/nerdtree/actions?workflow=Vint) -Introduction ------------- +## 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. +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) -![NERDTree Screenshot](https://github.com/scrooloose/nerdtree/raw/master/screenshot.png) +## Installation -Installation ------------- +Use your favorite plugin manager to install this plugin. [tpope/vim-pathogen](https://github.com/tpope/vim-pathogen), [VundleVim/Vundle.vim](https://github.com/VundleVim/Vundle.vim), [junegunn/vim-plug](https://github.com/junegunn/vim-plug), and [Shougo/dein.vim](https://github.com/Shougo/dein.vim) are some of the more popular ones. A lengthy discussion of these and other managers can be found on [vi.stackexchange.com](https://vi.stackexchange.com/questions/388/what-is-the-difference-between-the-vim-plugin-managers). Basic instructions are provided below, but please **be sure to read, understand, and follow all the safety rules that come with your ~~power tools~~ plugin manager.** -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. +If you have no favorite, or want to manage your plugins without 3rd-party dependencies, consider using Vim 8+ packages, as described in Greg Hurrell's excellent Youtube video: [Vim screencast #75: Plugin managers](https://www.youtube.com/watch?v=X2_R3uxDN6g). -#### Vim 8+ packages +
+Pathogen +Pathogen is more of a runtime path manager than a plugin manager. You must clone the plugins' repositories yourself to a specific location, and Pathogen makes sure they are available in Vim. -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/scrooloose/nerdtree.git ~/.vim/pack/vendor/start/nerdtree -vim -u NONE -c "helptags ~/.vim/pack/vendor/start/nerdtree/doc" -c q -``` +1. In the terminal, + ```bash + git clone https://github.com/preservim/nerdtree.git ~/.vim/bundle/nerdtree + ``` +1. In your `vimrc`, + ```vim + call pathogen#infect() + syntax on + filetype plugin indent on + ``` +1. Restart Vim, and run `:helptags ~/.vim/bundle/nerdtree/doc/` or `:Helptags`. +
-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. +
+ Vundle -#### [pathogen.vim](https://github.com/tpope/vim-pathogen) +1. Install Vundle, according to its instructions. +1. Add the following text to your `vimrc`. + ```vim + call vundle#begin() + Plugin 'preservim/nerdtree' + call vundle#end() + ``` +1. Restart Vim, and run the `:PluginInstall` statement to install your plugins. +
-In the terminal, -```bash -git clone https://github.com/scrooloose/nerdtree.git ~/.vim/bundle/nerdtree -``` -In your vimrc, -```vim -call pathogen#infect() -syntax on -filetype plugin indent on -``` +
+ Vim-Plug -Then reload vim, run `:helptags ~/.vim/bundle/nerdtree/doc/` or `:Helptags`. - -#### [Vundle.vim](https://github.com/VundleVim/Vundle.vim) -```vim -call vundle#begin() -Plugin 'scrooloose/nerdtree' -call vundle#end() -``` - -#### [vim-plug](https://github.com/junegunn/vim-plug) +1. Install Vim-Plug, according to its instructions. +1. Add the following text to your `vimrc`. ```vim call plug#begin() -Plug 'scrooloose/nerdtree' + Plug 'preservim/nerdtree' call plug#end() ``` +1. Restart Vim, and run the `:PlugInstall` statement to install your plugins. +
+ +
+ Dein + +1. Install Dein, according to its instructions. +1. Add the following text to your `vimrc`. + ```vim + call dein#begin() + call dein#add('preservim/nerdtree') + call dein#end() + ``` +1. Restart Vim, and run the `:call dein#install()` statement to install your plugins. +
+ +
+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: -#### [apt-vim](https://github.com/egalpin/apt-vim) ```bash -apt-vim install -y https://github.com/scrooloose/nerdtree.git +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 ``` +
-F.A.Q. (here, and in the [Wiki](https://github.com/scrooloose/nerdtree/wiki)) ------- - -#### Is there any support for `git` flags? +## Getting Started +After installing NERDTree, the best way to learn it is to turn on the Quick Help. Open NERDTree with the `:NERDTree` command, and press `?` to turn on the Quick Help, which will show you all the mappings and commands available in the NERDTree. Of course, your most complete source of information is the documentation: `:help NERDTree`. -Yes, install [nerdtree-git-plugin](https://github.com/Xuyuanp/nerdtree-git-plugin). +## NERDTree Plugins +NERDTree can be extended with custom mappings and functions using its built-in API. The details of this API are described in the included documentation. Several plugins have been written, and are available on Github for installation like any other plugin. The plugins in this list are maintained (or not) by their respective owners, and certain combinations may be incompatible. ---- -#### Can I have the nerdtree on every tab automatically? +* [Xuyuanp/nerdtree-git-plugin](https://github.com/Xuyuanp/nerdtree-git-plugin): Shows Git status flags for files and folders in NERDTree. +* [ryanoasis/vim-devicons](https://github.com/ryanoasis/vim-devicons): Adds filetype-specific icons to NERDTree files and folders. +* [tiagofumo/vim-nerdtree-syntax-highlight](https://github.com/tiagofumo/vim-nerdtree-syntax-highlight): Adds syntax highlighting to NERDTree based on filetype. +* [scrooloose/nerdtree-project-plugin](https://github.com/scrooloose/nerdtree-project-plugin): Saves and restores the state of the NERDTree between sessions. +* [PhilRunninger/nerdtree-buffer-ops](https://github.com/PhilRunninger/nerdtree-buffer-ops): 1) Highlights open files in a different color. 2) Closes a buffer directly from NERDTree. +* [PhilRunninger/nerdtree-visual-selection](https://github.com/PhilRunninger/nerdtree-visual-selection): Enables NERDTree to open, delete, move, or copy multiple Visually-selected files at once. -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 any others should be listed, mention them in an issue or pull request. -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? +## Frequently Asked Questions -Stick this in your vimrc: `autocmd vimenter * NERDTree` +In the answers to these questions, you will see code blocks that you can put in your `vimrc` file. ---- -#### How can I open a NERDTree automatically when vim starts up if no files were specified? +### How can I map a specific key or shortcut to open NERDTree? -Stick this in your vimrc: +NERDTree doesn't create any shortcuts outside of the NERDTree window, so as not to overwrite any of your other shortcuts. Use the `nnoremap` command in your `vimrc`. You, of course, have many keys and NERDTree commands to choose from. Here are but a few examples. ```vim -autocmd StdinReadPre * let s:std_in=1 -autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif +nnoremap n :NERDTreeFocus +nnoremap :NERDTree +nnoremap :NERDTreeToggle +nnoremap :NERDTreeFind ``` -Note: Now start vim with plain `vim`, not `vim .` +### How do I open NERDTree automatically when Vim starts? +Each code block below is slightly different, as described in the `" Comment lines`. +```vim +" Start NERDTree and leave the cursor in it. +autocmd VimEnter * NERDTree +``` +--- +```vim +" Start NERDTree and put the cursor back in the other window. +autocmd VimEnter * NERDTree | wincmd p +``` --- -#### 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 +" Start NERDTree when Vim is started without file arguments. autocmd StdinReadPre * let s:std_in=1 -autocmd VimEnter * if argc() == 0 && !exists("s:std_in") && v:this_session == "" | NERDTree | endif +autocmd VimEnter * if argc() == 0 && !exists('s:std_in') | NERDTree | endif +``` +--- +```vim +" Start NERDTree. If a file is specified, move the cursor to its window. +autocmd StdinReadPre * let s:std_in=1 +autocmd VimEnter * NERDTree | if argc() > 0 || exists("s:std_in") | wincmd p | endif ``` - --- -#### How can I open NERDTree automatically when vim starts up on opening a directory? ```vim +" Start NERDTree, unless a file or session is specified, eg. vim -S session_file.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 +autocmd VimEnter * if argc() == 0 && !exists('s:std_in') && v:this_session == '' | NERDTree | endif +``` +--- +```vim +" Start NERDTree when Vim starts with a directory argument. +autocmd StdinReadPre * let s:std_in=1 +autocmd VimEnter * if argc() == 1 && isdirectory(argv()[0]) && !exists('s:std_in') | + \ execute 'NERDTree' argv()[0] | wincmd p | enew | execute '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. +### How can I close Vim or a tab automatically when NERDTree is the last window? -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` +Because of the changes in how Vim handles its `autocmd` and layout locking `quit` command is no longer available in Vim9 auto commands, Depending on which version you're running select one of these solutions. ---- -#### How can I map a specific key or shortcut to open NERDTree? +__NeoVim users should be able to choose either one of them!__ + +#### Vim9 -Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever key you want): ```vim -map :NERDTreeToggle +" Exit Vim if NERDTree is the only window remaining in the only tab. +autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | call feedkeys(":quit\:\") | endif ``` +--- +```vim +" Close the tab if NERDTree is the only window remaining in it. +autocmd BufEnter * if winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | call feedkeys(":quit\:\") | endif +``` + +#### Vim8 or older +```vim +" Exit Vim if NERDTree is the only window remaining in the only tab. +autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif +``` --- -#### How can I close vim if the only window left open is a NERDTree? +```vim +" Close the tab if NERDTree is the only window remaining in it. +autocmd BufEnter * if winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif +``` + +### How can I prevent other buffers replacing NERDTree in its window? -Stick this in your vimrc: ```vim -autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif +" If another buffer tries to replace NERDTree, put it in the other window, and bring back NERDTree. +autocmd BufEnter * if winnr() == winnr('h') && bufname('#') =~ 'NERD_tree_\d\+' && bufname('%') !~ 'NERD_tree_\d\+' && winnr('$') > 1 | + \ let buf=bufnr() | buffer# | execute "normal! \w" | execute 'buffer'.buf | endif ``` ---- -#### Can I have different highlighting for different file extensions? +### Can I have the same NERDTree on every tab automatically? -See here: https://github.com/scrooloose/nerdtree/issues/433#issuecomment-92590696 +```vim +" Open the existing NERDTree on each new tab. +autocmd BufWinEnter * if &buftype != 'quickfix' && getcmdwintype() == '' | silent NERDTreeMirror | endif +``` +or change your NERDTree-launching shortcut key like so: +```vim +" Mirror the NERDTree before showing it. This makes it the same on all tabs. +nnoremap :NERDTreeMirror:NERDTreeFocus +``` ---- -#### How can I change default arrows? +### How can I change the default arrows? + +```vim +let g:NERDTreeDirArrowExpandable = '?' +let g:NERDTreeDirArrowCollapsible = '?' +``` +The preceding values are the non-Windows default arrow symbols. Setting these variables to empty strings will remove the arrows completely and shift the entire tree two character positions to the left. See `:h NERDTreeDirArrowExpandable` for more details. + +### How can I show lines of files? + +```vim +let g:NERDTreeFileLines = 1 +``` + +Lines in the file are displayed as shown below. +``` +OpenFileOrExplorer(argv()[0]) | wincmd p | enew | wincmd p | endif | endif + +" Command to call the OpenFileOrExplorer function. +command! -n=? -complete=file -bar Edit :call OpenFileOrExplorer('') + +" Command-mode abbreviation to replace the :edit Vim command. +cnoreabbrev e Edit ``` diff --git a/_config.yml b/_config.yml new file mode 100644 index 00000000..c4192631 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file diff --git a/autoload/nerdtree.vim b/autoload/nerdtree.vim index 76c076e9..d7246dc5 100644 --- a/autoload/nerdtree.vim +++ b/autoload/nerdtree.vim @@ -1,21 +1,21 @@ -if exists("g:loaded_nerdtree_autoload") +if exists('g:loaded_nerdtree_autoload') finish endif let g:loaded_nerdtree_autoload = 1 -let s:rootNERDTreePath = resolve(expand(":p:h:h")) +let s:rootNERDTreePath = resolve(expand(':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(...) +function! nerdtree#version(...) abort let l:text = 'Unknown' try - let l:changelog = readfile(join([s:rootNERDTreePath, "CHANGELOG.md"], nerdtree#slash())) + 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\+' + 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 @@ -30,9 +30,21 @@ endfunction " SECTION: General Functions {{{1 "============================================================ -"FUNCTION: nerdtree#slash() {{{2 -function! nerdtree#slash() +" FUNCTION: nerdtree#closeTreeOnOpen() {{{2 +function! nerdtree#closeTreeOnOpen() abort + return g:NERDTreeQuitOnOpen == 1 || g:NERDTreeQuitOnOpen == 3 +endfunction + +" FUNCTION: nerdtree#closeBookmarksOnOpen() {{{2 +function! nerdtree#closeBookmarksOnOpen() abort + return g:NERDTreeQuitOnOpen == 2 || g:NERDTreeQuitOnOpen == 3 +endfunction +" FUNCTION: nerdtree#slash() {{{2 +" 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! nerdtree#slash() abort if nerdtree#runningWindows() if exists('+shellslash') && &shellslash return '/' @@ -44,31 +56,9 @@ function! nerdtree#slash() return '/' endfunction -"FUNCTION: nerdtree#and(x,y) {{{2 -" Implements and() function for Vim <= 7.2 -function! nerdtree#and(x,y) - 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) +function! nerdtree#checkForBrowse(dir) abort if !isdirectory(a:dir) return endif @@ -83,18 +73,18 @@ 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")) + let path = g:NERDTreePath.New(fnamemodify(a:dir, ':p')) - for i in range(1, bufnr("$")) + for i in range(1, bufnr('$')) unlet! nt - let nt = getbufvar(i, "NERDTree") + 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 + call nt.setPreviousBuf(bufnr('#')) + exec 'buffer ' . i return 1 endif endfor @@ -104,19 +94,19 @@ endfunction " FUNCTION: nerdtree#completeBookmarks(A,L,P) {{{2 " completion function for the bookmark commands -function! nerdtree#completeBookmarks(A,L,P) +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) - return a:n1.path.compareTo(a:n2.path) +"FUNCTION: nerdtree#compareNodes(n1, n2) {{{2 +function! nerdtree#compareNodes(n1, n2) abort + return nerdtree#compareNodePaths(a:n1.path, a:n2.path) endfunction -"FUNCTION: nerdtree#compareNodesBySortKey(n1, n2) {{{2 -function! nerdtree#compareNodesBySortKey(n1, n2) - let sortKey1 = a:n1.path.getSortKey() - let sortKey2 = a:n2.path.getSortKey() +"FUNCTION: nerdtree#compareNodePaths(p1, p2) {{{2 +function! nerdtree#compareNodePaths(p1, p2) abort + let sortKey1 = a:p1.getSortKey() + let sortKey2 = a:p2.getSortKey() let i = 0 while i < min([len(sortKey1), len(sortKey2)]) " Compare chunks upto common length. @@ -128,12 +118,12 @@ function! nerdtree#compareNodesBySortKey(n1, n2) elseif sortKey1[i] ># sortKey2[i] return 1 endif - elseif type(sortKey1[i]) == v:t_number + elseif type(sortKey1[i]) == type(0) return -1 - elseif type(sortKey2[i]) == v:t_number + elseif type(sortKey2[i]) == type(0) return 1 endif - let i = i + 1 + let i += 1 endwhile " Keys are identical upto common length. @@ -150,7 +140,7 @@ 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, ...) +function! nerdtree#deprecated(func, ...) abort let msg = a:0 ? a:func . ' ' . a:1 : a:func . ' is deprecated' if !exists('s:deprecationWarnings') @@ -164,22 +154,25 @@ 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) - let old_ei = &ei +function! nerdtree#exec(cmd, ignoreAll) abort + let old_ei = &eventignore if a:ignoreAll - set ei=all + set eventignore=all endif - exec a:cmd - let &ei = old_ei + try + exec a:cmd + finally + let &eventignore = old_ei + endtry endfunction " FUNCTION: nerdtree#has_opt(options, name) {{{2 -function! nerdtree#has_opt(options, name) - return has_key(a:options, a:name) && a:options[a:name] == 1 +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() +function! nerdtree#loadClassFiles() abort runtime lib/nerdtree/path.vim runtime lib/nerdtree/menu_controller.vim runtime lib/nerdtree/menu_item.vim @@ -197,7 +190,7 @@ function! nerdtree#loadClassFiles() endfunction " FUNCTION: nerdtree#postSourceActions() {{{2 -function! nerdtree#postSourceActions() +function! nerdtree#postSourceActions() abort call g:NERDTreeBookmark.CacheBookmarks(1) call nerdtree#ui_glue#createDefaultBindings() @@ -205,14 +198,72 @@ function! nerdtree#postSourceActions() runtime! nerdtree_plugin/**/*.vim endfunction -"FUNCTION: nerdtree#runningWindows(dir) {{{2 -function! nerdtree#runningWindows() - return has("win16") || has("win32") || has("win64") +"FUNCTION: nerdtree#runningWindows() {{{2 +function! nerdtree#runningWindows() abort + return has('win16') || has('win32') || has('win64') +endfunction + +"FUNCTION: nerdtree#runningCygwin() {{{2 +function! nerdtree#runningCygwin() abort + return has('win32unix') +endfunction + +"FUNCTION: nerdtree#runningMac() {{{2 +function! nerdtree#runningMac() abort + return has('gui_mac') || has('gui_macvim') || has('mac') || has('osx') endfunction -"FUNCTION: nerdtree#runningCygwin(dir) {{{2 -function! nerdtree#runningCygwin() - return has("win32unix") +" FUNCTION: nerdtree#osDefaultCaseSensitiveFS() {{{2 +function! nerdtree#osDefaultCaseSensitiveFS() abort + return s:osDefaultCaseSensitiveFS +endfunction + +" FUNCTION: nerdtree#caseSensitiveFS() {{{2 +function! nerdtree#caseSensitiveFS() abort + return g:NERDTreeCaseSensitiveFS == 1 || + \((g:NERDTreeCaseSensitiveFS == 2 || g:NERDTreeCaseSensitiveFS == 3) && + \nerdtree#osDefaultCaseSensitiveFS()) +endfunction + +"FUNCTION: nerdtree#pathEquals(lhs, rhs) {{{2 +function! nerdtree#pathEquals(lhs, rhs) abort + if nerdtree#caseSensitiveFS() + return a:lhs ==# a:rhs + else + return a:lhs ==? a:rhs + endif +endfunction + +"FUNCTION: nerdtree#onBufLeave() {{{2 +" used for handling the nerdtree BufLeave/WinLeave events. +function! nerdtree#onBufLeave() abort + " detect whether we are in the middle of sourcing a session. + " if it is a buffer from the sourced session we need to restore it. + if exists('g:SessionLoad') && !exists('b:NERDTree') + let bname = bufname('%') + " is the buffer for a tab tree? + if bname =~# '^' . g:NERDTreeCreator.BufNamePrefix() . 'tab_\d\+$' + " rename loaded buffer and mark it as trash to prevent this event + " getting fired again + exec 'file TRASH_' . bname + " delete the trash buffer + exec 'bwipeout!' + " rescue the tab tree at the current working directory + call g:NERDTreeCreator.CreateTabTree(getcwd()) + " is the buffer for a window tree? + elseif bname =~# '^' . g:NERDTreeCreator.BufNamePrefix(). 'win_\d\+$' + " rescue the window tree at the current working directory + call g:NERDTreeCreator.CreateWindowTree(getcwd()) + else " unknown buffer type + " rename buffer to mark it as broken. + exec 'file BROKEN_' . bname + call nerdtree#echoError('Failed to restore "' . bname . '" from session. Is this session created with an older version of NERDTree?') + endif + else + if g:NERDTree.IsOpen() + call b:NERDTree.ui.saveScreenState() + endif + endif endfunction " SECTION: View Functions {{{1 @@ -223,16 +274,16 @@ endfunction " "Args: "msg: the message to echo -function! nerdtree#echo(msg) +function! nerdtree#echo(msg) abort redraw - echomsg empty(a:msg) ? "" : ("NERDTree: " . a:msg) + 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) +function! nerdtree#echoError(msg) abort echohl errormsg call nerdtree#echo(a:msg) echohl normal @@ -242,15 +293,23 @@ endfunction "Wrapper for nerdtree#echo, sets the message type to warningmsg for this message "Args: "msg: the message to echo -function! nerdtree#echoWarning(msg) +function! nerdtree#echoWarning(msg) abort echohl warningmsg call nerdtree#echo(a:msg) echohl normal endfunction "FUNCTION: nerdtree#renderView {{{2 -function! nerdtree#renderView() +function! nerdtree#renderView() abort call b:NERDTree.render() endfunction +if nerdtree#runningWindows() + let s:osDefaultCaseSensitiveFS = 0 +elseif nerdtree#runningMac() + let s:osDefaultCaseSensitiveFS = 0 +else + let s:osDefaultCaseSensitiveFS = 1 +endif + " vim: set sw=4 sts=4 et fdm=marker: diff --git a/autoload/nerdtree/ui_glue.vim b/autoload/nerdtree/ui_glue.vim index 4ba5b05f..c5c96181 100644 --- a/autoload/nerdtree/ui_glue.vim +++ b/autoload/nerdtree/ui_glue.vim @@ -1,80 +1,86 @@ -if exists("g:loaded_nerdtree_ui_glue_autoload") +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() +function! nerdtree#ui_glue#createDefaultBindings() abort let s = '' . s:SID() . '_' call NERDTreeAddKeyMap({ 'key': '', 'scope': 'all', 'callback': s . 'handleMiddleMouse' }) - call NERDTreeAddKeyMap({ 'key': '', 'scope': "all", 'callback': s."handleLeftClick" }) - call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "DirNode", 'callback': s."activateDirNode" }) - call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "FileNode", 'callback': s."activateFileNode" }) - call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "Bookmark", 'callback': s."activateBookmark" }) - call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "all", 'callback': s."activateAll" }) - - call NERDTreeAddKeyMap({ 'key': g: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': '', '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': 'FileNode', 'callback': s.'openHSplit' }) + call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': 'Bookmark', 'callback': s.'openHSplitBookmark' }) + call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': 'FileNode', 'callback': s.'openVSplit' }) + call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': 'Bookmark', 'callback': s.'openVSplitBookmark' }) + + call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': 'FileNode', 'callback': s.'previewNodeCurrent' }) + call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': 'FileNode', 'callback': s.'previewNodeHSplit' }) + call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': 'Bookmark', 'callback': s.'previewNodeHSplitBookmark' }) + call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': 'FileNode', 'callback': s.'previewNodeVSplit' }) + call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': 'Bookmark', 'callback': s.'previewNodeVSplitBookmark' }) + + 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:NERDTreeMapChdir, 'scope': 'Node', 'callback': s.'chCwd' }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapQuit, 'scope': "all", 'callback': s."closeTreeWindow" }) + 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: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: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: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:NERDTreeMapToggleFileLines, 'scope': 'all', 'callback': s.'toggleShowFileLines' }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseDir, 'scope': "Node", 'callback': s."closeCurrentDir" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseChildren, 'scope': "DirNode", 'callback': s."closeChildren" }) + 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: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: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:NERDTreeMapJumpBookmarks, 'scope': 'all', 'callback': s.'jumpToBookmarks' }) 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: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" }) + call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapDeleteBookmark, 'scope': 'Bookmark', 'callback': s.'deleteBookmark' }) endfunction @@ -82,20 +88,20 @@ endfunction "============================================================ "FUNCTION: s:customOpenFile() {{{1 -" Open file node with the "custom" key, initially . -function! s:customOpenFile(node) +" Open file node with the 'custom' key, initially . +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 . -function! s:customOpenDir(node) +" Open directory node with the 'custom' key, initially . +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 . -function! s:customOpenBookmark(node) +" Open bookmark node with the 'custom' key, initially . +function! s:customOpenBookmark(node) abort if a:node.path.isDirectory call a:node.activate(b:NERDTree, s:initCustomOpenArgs().dir) else @@ -104,23 +110,30 @@ function! s:customOpenBookmark(node) endfunction "FUNCTION: s:initCustomOpenArgs() {{{1 -" Make sure NERDTreeCustomOpenArgs has needed keys -function! s:initCustomOpenArgs() - let g:NERDTreeCustomOpenArgs = get(g:, 'NERDTreeCustomOpenArgs', {}) - return extend(g:NERDTreeCustomOpenArgs, {'file':{'reuse': 'all', 'where': 'p'}, 'dir':{}}, 'keep') +function! s:initCustomOpenArgs() abort + let l:defaultOpenArgs = {'file': {'reuse': 'all', 'where': 'p', 'keepopen':!nerdtree#closeTreeOnOpen()}, 'dir': {}} + try + let g:NERDTreeCustomOpenArgs = get(g:, 'NERDTreeCustomOpenArgs', {}) + call extend(g:NERDTreeCustomOpenArgs, l:defaultOpenArgs, 'keep') + catch /^Vim(\a\+):E712:/ + call nerdtree#echoWarning('g:NERDTreeCustomOpenArgs is not set properly. Using default value.') + let g:NERDTreeCustomOpenArgs = l:defaultOpenArgs + finally + return g:NERDTreeCustomOpenArgs + endtry endfunction "FUNCTION: s:activateAll() {{{1 "handle the user activating the updir line -function! s:activateAll() - if getline(".") ==# g:NERDTreeUI.UpDirLine() +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, ...) +function! s:activateDirNode(directoryNode, ...) abort if a:directoryNode.isRoot() && a:directoryNode.isOpen call nerdtree#echo('cannot close tree root') @@ -132,21 +145,21 @@ endfunction "FUNCTION: s:activateFileNode() {{{1 "handle the user activating a tree node -function! s:activateFileNode(node) - call a:node.activate({'reuse': 'all', 'where': 'p'}) +function! s:activateFileNode(node) abort + call a:node.activate({'reuse': 'all', 'where': 'p', 'keepopen': !nerdtree#closeTreeOnOpen()}) endfunction "FUNCTION: s:activateBookmark(bookmark) {{{1 "handle the user activating a bookmark -function! s:activateBookmark(bm) - call a:bm.activate(b:NERDTree, !a:bm.path.isDirectory ? {'where': 'p'} : {}) +function! s:activateBookmark(bm) abort + call a:bm.activate(b:NERDTree, !a:bm.path.isDirectory ? {'where': 'p', 'keepopen': !nerdtree#closeTreeOnOpen()} : {}) endfunction " FUNCTION: nerdtree#ui_glue#bookmarkNode(name) {{{1 " Associate the current node with the given name -function! nerdtree#ui_glue#bookmarkNode(...) +function! nerdtree#ui_glue#bookmarkNode(...) abort let currentNode = g:NERDTreeFileNode.GetSelected() - if currentNode != {} + if currentNode !=# {} let name = a:1 if empty(name) let name = currentNode.path.getLastPathComponent(0) @@ -155,39 +168,39 @@ function! nerdtree#ui_glue#bookmarkNode(...) call currentNode.bookmark(name) call b:NERDTree.render() catch /^NERDTree.IllegalBookmarkNameError/ - call nerdtree#echo("bookmark names must not contain spaces") + call nerdtree#echo('bookmark names must not contain spaces') endtry else - call nerdtree#echo("select a node first") + call nerdtree#echo('select a node first') endif endfunction " FUNCTION: s:chCwd(node) {{{1 -function! s:chCwd(node) +function! s:chCwd(node) abort try call a:node.path.changeToDir() catch /^NERDTree.PathChangeError/ - call nerdtree#echoWarning("could not change cwd") + 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) +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() +function! nerdtree#ui_glue#chRootCwd() abort NERDTreeCWD endfunction " FUNCTION: nnerdtree#ui_glue#clearBookmarks(bookmarks) {{{1 -function! nerdtree#ui_glue#clearBookmarks(bookmarks) +function! nerdtree#ui_glue#clearBookmarks(bookmarks) abort if a:bookmarks ==# '' let currentNode = g:NERDTreeFileNode.GetSelected() - if currentNode != {} + if currentNode !=# {} call currentNode.clearBookmarks() endif else @@ -202,7 +215,7 @@ endfunction " FUNCTION: s:closeChildren(node) {{{1 " closes all childnodes of the current node -function! s:closeChildren(node) +function! s:closeChildren(node) abort call a:node.closeChildren() call b:NERDTree.render() call a:node.putCursorHere(0, 0) @@ -210,7 +223,7 @@ endfunction " FUNCTION: s:closeCurrentDir(node) {{{1 " Close the parent directory of the current node. -function! s:closeCurrentDir(node) +function! s:closeCurrentDir(node) abort if a:node.isRoot() call nerdtree#echo('cannot close parent of tree root') @@ -235,30 +248,30 @@ endfunction " FUNCTION: s:closeTreeWindow() {{{1 " close the tree window -function! s:closeTreeWindow() - if b:NERDTree.isWinTree() && b:NERDTree.previousBuf() != -1 - exec "buffer " . b:NERDTree.previousBuf() +function! s:closeTreeWindow() abort + if b:NERDTree.isWinTree() && b:NERDTree.previousBuf() !=# -1 + exec 'buffer ' . b:NERDTree.previousBuf() else - if winnr("$") > 1 + if winnr('$') > 1 call g:NERDTree.Close() else - call nerdtree#echo("Cannot close last window") + 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) - let l:message = "Delete the bookmark \"" . a:bookmark.name - \ . "\" from the bookmark list?" +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 + if l:selection !=# 1 call nerdtree#echo('bookmark not deleted') return endif @@ -275,24 +288,27 @@ endfunction " FUNCTION: s:displayHelp() {{{1 " toggles the help display -function! s:displayHelp() +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) +function! s:findAndRevealPath(pathStr) abort let l:pathStr = !empty(a:pathStr) ? a:pathStr : expand('%:p') - if !filereadable(l:pathStr) - let l:pathStr = fnamemodify(l:pathStr, ':h') - endif + 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) @@ -326,22 +342,22 @@ function! s:findAndRevealPath(pathStr) call b:NERDTree.ui.setShowHidden(1) endif - let l:node = b:NERDTree.root.reveal(l:pathObj) + 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() +function! s:handleLeftClick() abort let currentNode = g:NERDTreeFileNode.GetSelected() - if currentNode != {} + 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 = "" + let line = split(getline(line('.')), '\zs') + let startToCur = '' for i in range(0,len(line)-1) let startToCur .= line[i] endfor @@ -359,7 +375,7 @@ function! s:handleLeftClick() if currentNode.path.isDirectory call currentNode.activate() else - call currentNode.activate({'reuse': 'all', 'where': 'p'}) + call currentNode.activate({'reuse': 'all', 'where': 'p', 'keepopen':!nerdtree#closeTreeOnOpen()}) endif return endif @@ -368,7 +384,7 @@ function! s:handleLeftClick() endfunction " FUNCTION: s:handleMiddleMouse() {{{1 -function! s:handleMiddleMouse() +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 @@ -391,17 +407,17 @@ 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) +function! nerdtree#ui_glue#invokeKeyMap(key) abort call g:NERDTreeKeyMap.Invoke(a:key) endfunction " FUNCTION: s:jumpToFirstChild(node) {{{1 -function! s:jumpToFirstChild(node) +function! s:jumpToFirstChild(node) abort call s:jumpToChild(a:node, 0) endfunction " FUNCTION: s:jumpToLastChild(node) {{{1 -function! s:jumpToLastChild(node) +function! s:jumpToLastChild(node) abort call s:jumpToChild(a:node, 1) endfunction @@ -411,7 +427,7 @@ endfunction " 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) +function! s:jumpToChild(node, last) abort let l:node = a:node.path.isDirectory ? a:node.getCascadeRoot() : a:node if l:node.isRoot() @@ -430,7 +446,7 @@ 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) +function! s:jumpToParent(node) abort let l:node = a:node.path.isDirectory ? a:node.getCascadeRoot() : a:node if l:node.isRoot() @@ -448,18 +464,18 @@ endfunction " FUNCTION: s:jumpToRoot() {{{1 " moves the cursor to the root node -function! s:jumpToRoot() +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) +function! s:jumpToNextSibling(node) abort call s:jumpToSibling(a:node, 1) endfunction " FUNCTION: s:jumpToPrevSibling(node) {{{1 -function! s:jumpToPrevSibling(node) +function! s:jumpToPrevSibling(node) abort call s:jumpToSibling(a:node, 0) endfunction @@ -469,7 +485,7 @@ endfunction " 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) +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) @@ -481,10 +497,25 @@ function! s:jumpToSibling(node, forward) call b:NERDTree.ui.centerView() endfunction +" FUNCTION: s:jumpToBookmarks() {{{1 +" moves the cursor to the bookmark table +function! s:jumpToBookmarks() abort + try + if b:NERDTree.ui.getShowBookmarks() + call g:NERDTree.CursorToBookmarkTable() + else + call b:NERDTree.ui.setShowBookmarks(1) + endif + catch /^NERDTree/ + call nerdtree#echoError('Failed to jump to the bookmark table') + return + endtry +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) +" implementation for the :OpenBookmark command. +function! nerdtree#ui_glue#openBookmark(name) abort try let l:bookmark = g:NERDTreeBookmark.BookmarkFor(a:name) catch /^NERDTree.BookmarkNotFoundError/ @@ -493,48 +524,71 @@ function! nerdtree#ui_glue#openBookmark(name) endtry if l:bookmark.path.isDirectory call l:bookmark.open(b:NERDTree) - else - call l:bookmark.open(b:NERDTree, {'where': 'p'}) + return endif + + call l:bookmark.open(b:NERDTree, s:initCustomOpenArgs().file) endfunction " FUNCTION: s:openHSplit(target) {{{1 -function! s:openHSplit(target) - call a:target.activate({'where': 'h'}) +function! s:openHSplit(target) abort + call a:target.activate({'where': 'h', 'keepopen': !nerdtree#closeTreeOnOpen()}) endfunction " FUNCTION: s:openVSplit(target) {{{1 -function! s:openVSplit(target) - call a:target.activate({'where': 'v'}) +function! s:openVSplit(target) abort + call a:target.activate({'where': 'v', 'keepopen': !nerdtree#closeTreeOnOpen()}) +endfunction + +"FUNCTION: s:openHSplitBookmark(bookmark) {{{1 +"handle the user activating a bookmark +function! s:openHSplitBookmark(bm) abort + call a:bm.activate(b:NERDTree, !a:bm.path.isDirectory ? {'where': 'h', 'keepopen': !nerdtree#closeTreeOnOpen()} : {}) +endfunction + +"FUNCTION: s:openVSplitBookmark(bookmark) {{{1 +"handle the user activating a bookmark +function! s:openVSplitBookmark(bm) abort + call a:bm.activate(b:NERDTree, !a:bm.path.isDirectory ? {'where': 'v', 'keepopen': !nerdtree#closeTreeOnOpen()} : {}) +endfunction + +" FUNCTION: s:previewHSplitBookmark(bookmark) {{{1 +function! s:previewNodeHSplitBookmark(bookmark) abort + call a:bookmark.activate(b:NERDTree, !a:bookmark.path.isDirectory ? {'stay': 1, 'where': 'h', 'keepopen': 1} : {}) +endfunction + +" FUNCTION: s:previewVSplitBookmark(bookmark) {{{1 +function! s:previewNodeVSplitBookmark(bookmark) abort + call a:bookmark.activate(b:NERDTree, !a:bookmark.path.isDirectory ? {'stay': 1, 'where': 'v', 'keepopen': 1} : {}) endfunction " FUNCTION: s:openExplorer(node) {{{1 -function! s:openExplorer(node) +function! s:openExplorer(node) abort call a:node.openExplorer() endfunction " FUNCTION: s:openInNewTab(target) {{{1 -function! s:openInNewTab(target) - let l:opener = g:NERDTreeOpener.New(a:target.path, {'where': 't'}) +function! s:openInNewTab(target) abort + let l:opener = g:NERDTreeOpener.New(a:target.path, {'where': 't', 'keepopen': !nerdtree#closeTreeOnOpen()}) call l:opener.open(a:target) endfunction " FUNCTION: s:openInNewTabSilent(target) {{{1 -function! s:openInNewTabSilent(target) - let l:opener = g:NERDTreeOpener.New(a:target.path, {'where': 't', 'stay': 1}) +function! s:openInNewTabSilent(target) abort + let l:opener = g:NERDTreeOpener.New(a:target.path, {'where': 't', 'keepopen': !nerdtree#closeTreeOnOpen(), 'stay': 1}) call l:opener.open(a:target) endfunction " FUNCTION: s:openNodeRecursively(node) {{{1 -function! s:openNodeRecursively(node) - call nerdtree#echo("Recursively opening node. Please wait...") +function! s:openNodeRecursively(node) abort + call nerdtree#echo('Recursively opening node. Please wait...') call a:node.openRecursively() call b:NERDTree.render() - call nerdtree#echo("") + call nerdtree#echo('') endfunction " FUNCTION: s:previewBookmark(bookmark) {{{1 -function! s:previewBookmark(bookmark) +function! s:previewBookmark(bookmark) abort if a:bookmark.path.isDirectory execute 'NERDTreeFind '.a:bookmark.path.str() else @@ -543,67 +597,68 @@ function! s:previewBookmark(bookmark) endfunction "FUNCTION: s:previewNodeCurrent(node) {{{1 -function! s:previewNodeCurrent(node) +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) +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) +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) +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") + call nerdtree#echo('Bookmark isn''t 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() +function! s:refreshRoot() abort if !g:NERDTree.IsOpen() return endif - call nerdtree#echo("Refreshing the root node. This could take a while...") + 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 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("") + 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) +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 nerdtree#echo('Refreshing node. This could take a while...') call node.refresh() call b:NERDTree.render() - call nerdtree#echo("") + call nerdtree#echo('') endfunction " FUNCTION: nerdtree#ui_glue#setupCommands() {{{1 -function! nerdtree#ui_glue#setupCommands() +function! nerdtree#ui_glue#setupCommands() abort command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreateTabTree('') command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.ToggleTabTree('') + command! -n=? -complete=dir -bar NERDTreeExplore :call g:NERDTreeCreator.CreateExploreTree('') command! -n=0 -bar NERDTreeClose :call g:NERDTree.Close() command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreateTabTree('') command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror() @@ -614,42 +669,48 @@ function! nerdtree#ui_glue#setupCommands() endfunction " Function: s:SID() {{{1 -function s:SID() - if !exists("s:sid") +function! s:SID() abort + if !exists('s:sid') let s:sid = matchstr(expand(''), '\zs\d\+\ze_SID$') endif return s:sid endfun " FUNCTION: s:showMenu(node) {{{1 -function! s:showMenu(node) +function! s:showMenu(node) abort let mc = g:NERDTreeMenuController.New(g:NERDTreeMenuItem.AllEnabled()) call mc.showMenu() endfunction " FUNCTION: s:toggleIgnoreFilter() {{{1 -function! s:toggleIgnoreFilter() +function! s:toggleIgnoreFilter() abort call b:NERDTree.ui.toggleIgnoreFilter() endfunction " FUNCTION: s:toggleShowBookmarks() {{{1 -function! s:toggleShowBookmarks() +function! s:toggleShowBookmarks() abort call b:NERDTree.ui.toggleShowBookmarks() endfunction " FUNCTION: s:toggleShowFiles() {{{1 -function! s:toggleShowFiles() +function! s:toggleShowFiles() abort call b:NERDTree.ui.toggleShowFiles() endfunction " FUNCTION: s:toggleShowHidden() {{{1 " toggles the display of hidden files -function! s:toggleShowHidden() +function! s:toggleShowHidden() abort call b:NERDTree.ui.toggleShowHidden() endfunction +" FUNCTION: s:toggleShowFileLines() {{{1 +" toggles the display of hidden files +function! s:toggleShowFileLines() abort + call b:NERDTree.ui.toggleShowFileLines() +endfunction + " FUNCTION: s:toggleZoom() {{{1 -function! s:toggleZoom() +function! s:toggleZoom() abort call b:NERDTree.ui.toggleZoom() endfunction @@ -659,7 +720,7 @@ endfunction " 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) +function! nerdtree#ui_glue#upDir(preserveState) abort try call b:NERDTree.root.cacheParent() @@ -683,12 +744,12 @@ function! nerdtree#ui_glue#upDir(preserveState) endfunction " FUNCTION: s:upDirCurrentRootOpen() {{{1 -function! s:upDirCurrentRootOpen() +function! s:upDirCurrentRootOpen() abort call nerdtree#ui_glue#upDir(1) endfunction " FUNCTION: s:upDirCurrentRootClosed() {{{1 -function! s:upDirCurrentRootClosed() +function! s:upDirCurrentRootClosed() abort call nerdtree#ui_glue#upDir(0) endfunction diff --git a/doc/NERDTree.txt b/doc/NERDTree.txt index 32b0b5d1..f8a1fdc1 100644 --- a/doc/NERDTree.txt +++ b/doc/NERDTree.txt @@ -116,14 +116,23 @@ The following features and functionality are provided by the NERDTree: :NERDTreeVCS (opens root of repository containing CWD) < :NERDTreeFromBookmark *:NERDTreeFromBookmark* - Opens a fresh NERDTree with the root initialized to the dir for + Opens a fresh NERDTree with the root initialized to the directory for . The only reason to use this command over :NERDTree is for the completion (which is for bookmarks rather than directories). :NERDTreeToggle [ | ] *:NERDTreeToggle* If a NERDTree already exists for this tab, it is reopened and rendered - again. If no NERDTree exists for this tab then this command acts the - same as the |:NERDTree| command. + again. If or 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 [ | ] *: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; @@ -240,7 +249,7 @@ 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 + Find selected bookmark directory 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| @@ -251,10 +260,10 @@ gs.......Same as s, but leave the cursor on the NERDTree...........|NERDTree-gs| O........Recursively open the selected directory....................|NERDTree-O| x........Close the current nodes parent.............................|NERDTree-x| X........Recursively close all children of the current node.........|NERDTree-X| -e........Edit the current dir.......................................|NERDTree-e| +e........Edit the current directory.................................|NERDTree-e| double-click....same as |NERDTree-o|. -middle-click....same as |NERDTree-i| for files, and |NERDTree-e| for dirs. +middle-click....same as |NERDTree-i| for files, and |NERDTree-e| for directories. D........Delete the current bookmark ...............................|NERDTree-D| @@ -265,19 +274,20 @@ J........Jump down inside directories at the current tree depth.....|NERDTree-J| ....Jump down to next sibling of the current directory.......|NERDTree-C-J| ....Jump up to previous sibling of the current directory.....|NERDTree-C-K| -C........Change the tree root to the selected dir...................|NERDTree-C| +C........Change the tree root to the selected directory.............|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 the CWD to the directory 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| +L........Toggle whether the number of lines in files is displayed..|NERDTree-FL| q........Close the NERDTree window..................................|NERDTree-q| A........Zoom (maximize/minimize) the NERDTree window...............|NERDTree-A| @@ -309,9 +319,8 @@ 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. +If a bookmark that links to a directory is selected then that directory +becomes the new root. The default key combo for this mapping is "g" + NERDTreeMapActivateNode (see |NERDTree-o|). @@ -341,7 +350,7 @@ 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. +Applies to: files, and bookmarks pointing to files. Opens the selected file in a new split window and puts the cursor in the new window. @@ -350,7 +359,7 @@ window. *NERDTree-gi* Default key: gi Map setting: *NERDTreeMapPreviewSplit* -Applies to: files. +Applies to: files, and bookmarks pointing to files. The same as |NERDTree-i| except that the cursor is not moved. @@ -361,7 +370,7 @@ The default key combo for this mapping is "g" + NERDTreeMapOpenSplit (see *NERDTree-s* Default key: s Map setting: *NERDTreeMapOpenVSplit* -Applies to: files. +Applies to: files, and bookmarks pointing to files. Opens the selected file in a new vertically split window and puts the cursor in the new window. @@ -370,7 +379,7 @@ in the new window. *NERDTree-gs* Default key: gs Map setting: *NERDTreeMapPreviewVSplit* -Applies to: files. +Applies to: files, and bookmarks pointing to files. The same as |NERDTree-s| except that the cursor is not moved. @@ -461,7 +470,7 @@ 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 + open directory with children * go to the first child of that node ------------------------------------------------------------------------------ @@ -474,7 +483,7 @@ 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 + an open directory with children * go to the last child of that node ------------------------------------------------------------------------------ @@ -508,7 +517,7 @@ Default key: u Map setting: *NERDTreeMapUpdir* Applies to: no restrictions. -Move the tree root up a dir (like doing a "cd .."). +Move the tree root up a directory (like doing a "cd .."). ------------------------------------------------------------------------------ *NERDTree-U* @@ -524,8 +533,8 @@ 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 directory is selected, recursively refresh that directory, 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. @@ -593,6 +602,14 @@ Applies to: no restrictions. Toggles whether the bookmarks table is displayed. +------------------------------------------------------------------------------ + *NERDTree-FL* +Default key: FL +Map setting: *NERDTreeMapToggleFileLines* +Applies to: no restrictions. + +Toggles whether the number of lines in files is displayed. + ------------------------------------------------------------------------------ *NERDTree-q* Default key: q @@ -626,8 +643,8 @@ 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. +creating/deleting/moving/copying files and directories. exec_menuitem.vim +provides a menu item to execute executable files. Related tags: |NERDTree-m| |NERDTreeApi| @@ -665,6 +682,9 @@ the NERDTree. These settings should be set in your vimrc, using `:let`. |NERDTreeAutoCenterThreshold| Controls the sensitivity of autocentering. +|NERDTreeCaseSensitiveFS| Tells the NERDTree whether or not it is + running in on a case sensitive file system. + |NERDTreeCaseSensitiveSort| Tells the NERDTree whether to be case sensitive or not when sorting nodes. @@ -800,6 +820,26 @@ Default: 3 This setting controls the "sensitivity" of the NERDTree auto centering. See |NERDTreeAutoCenter| for details. +------------------------------------------------------------------------------ + *NERDTreeCaseSensitiveFS* +Values: 0, 1, 2 or 3. +Default: 2. + +If set to 0, the NERDTree will interact with the file system without case +sensitivity. + +If set to 1, the NERDTree will interact with the file system in a case-sensitive +manner. + +If set to 2, the NERDTree assumes its case sensitivity from the OS it is +running on. It Will default to case-insensitive on Windows and macOS +machines and case-sensitive on everything else. Since it's not a foolproof +way of detection, NERDTree won't proceed with any write actions when +the destination is ambiguous. + +Setting it to 3 will perform just like 2, but without suppressing write +actions. + ------------------------------------------------------------------------------ *NERDTreeCaseSensitiveSort* Values: 0 or 1. @@ -913,7 +953,7 @@ 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 +files/directories that match any of the regex's in NERDTreeIgnore won't be displayed. For example if you put the following line in your vimrc: > @@ -921,13 +961,18 @@ For example if you put the following line in your vimrc: > < 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]]'] +There are 3 magic flags that can be appended to the end of each regular +expression to specify that the regex should match only filenames, only lowest +level directories, or a full path. These flags are "[[dir]]", "[[file]]", and +"[[path]]". Example: > + let NERDTreeIgnore=['\.d$[[dir]]', '\.o$[[file]]', 'tmp/cache$[[path]]'] < -This will cause all dirs ending in ".d" to be ignored and all files ending in -".o" to be ignored. +This will cause all directories ending in ".d" to be ignored, all files ending +in ".o" to be ignored, and the "cache" subdirectory of any "tmp" directory to +be ignored. All other "cache" directories will be displayed. + +When using the "[[path]]" tag on Windows, make sure you use escaped +backslashes for the separators in the regex, eg. 'Temp\\cache$[[path]]' Note: to tell the NERDTree not to ignore any files you must use the following line: > @@ -1027,6 +1072,20 @@ 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. +------------------------------------------------------------------------------ + *NERDTreeFileLines* +Values: 0 or 1. +Default: 0. + +If this setting is set to 1 then the NERDTree shows number of lines for each +file. + +This setting can be toggled dynamically, per tree, with the |NERDTree-FL| +mapping. +Use one of the follow lines for this setting: > + let NERDTreeFileLines=0 + let NERDTreeFileLines=1 +< ------------------------------------------------------------------------------ *NERDTreeShowHidden* Values: 0 or 1. @@ -1091,8 +1150,8 @@ Examples: > < 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. +3. Directories 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 @@ -1115,7 +1174,7 @@ setting is used. ------------------------------------------------------------------------------ *NERDTreeWinPos* -Values: "left" or "right" +Values: "left", "right", "top" or "bottom" Default: "left". This setting is used to determine where NERDTree window is placed on the @@ -1125,6 +1184,13 @@ 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. +When setting this variable to "top" or "bottom" make sure to also change the +|NERDTreeWinSize| to a more reasonable size. + +For example: +> + let g:NERDTreeWinSize = 15 +< ------------------------------------------------------------------------------ *NERDTreeWinSize* Values: a positive integer. @@ -1166,8 +1232,9 @@ Use one of the following lines for this setting: > 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: > +When displaying directory nodes, this setting tells NERDTree to collapse +directories that have only one child. Use one of the following lines for this +setting: > let NERDTreeCascadeSingleChildDir=0 let NERDTreeCascadeSingleChildDir=1 < @@ -1176,11 +1243,12 @@ have only one child. Use one of the following lines for this setting: > 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: > +When opening directory nodes, this setting tells NERDTree to recursively open +directories that have only one child which is also a directory. NERDTree will +stop when it finds a directory that contains anything but another single +directory. This setting also causes the |NERDTree-x| mapping to close +directories 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 < @@ -1214,13 +1282,19 @@ Values: Any single character. Defaults: Windows: ~ and + Others: ▾ and ▸ These characters indicate whether a directory is collapsible or expandable. - -They can be set to "\u00a0" to hide the arrows, but 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. Example: > +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. @@ -1230,15 +1304,15 @@ 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/scrooloose/nerdtree/pull/868. +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 is compiled with the +conceal feature, it is the "\x07" + (BEL) character, and it is hidden by setting 'conceallevel' to 2. If you + use autocommands, make sure none of them change that setting in the + NERD_Tree_* 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. @@ -1307,6 +1381,10 @@ following code conventions are used: 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* @@ -1334,18 +1412,18 @@ NERDTreeAddKeyMap({options}) *NERDTreeAddKeyMap()* Example: > call NERDTreeAddKeyMap({ \ 'key': 'foo', - \ 'callback': 'NERDTreeCDHandler', + \ 'callback': 'NERDTreeEchoPathHandler', \ 'quickhelpText': 'echo full path of current node', \ 'scope': 'DirNode' }) - function! NERDTreeCDHandler(dirnode) - call a:dirnode.changeToDir() + function! NERDTreeEchoPathHandler(dirnode) + echo a:dirnode.path.str() 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. + the current directory node. Note this mapping will only fire when the + cursor is on a directory node. ------------------------------------------------------------------------------ 4.2. Menu API *NERDTreeMenuAPI* @@ -1486,11 +1564,11 @@ 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/scrooloose/nerdtree/issues. +to submit an issue at http://github.com/preservim/nerdtree/issues. The latest stable and development versions are on Github. - Stable: http://github.com/scrooloose/nerdtree (master branch) - Development: http://github.com/scrooloose/nerdtree/branches + Stable: http://github.com/preservim/nerdtree (master branch) + Development: http://github.com/preservim/nerdtree/branches Title Credit: * http://ascii.co.uk/art/tree diff --git a/lib/nerdtree/bookmark.vim b/lib/nerdtree/bookmark.vim index b206e7a4..37be451c 100644 --- a/lib/nerdtree/bookmark.vim +++ b/lib/nerdtree/bookmark.vim @@ -33,7 +33,7 @@ endfunction " Class method to get all bookmarks. Lazily initializes the bookmarks global " variable function! s:Bookmark.Bookmarks() - if !exists("g:NERDTreeBookmarks") + if !exists('g:NERDTreeBookmarks') let g:NERDTreeBookmarks = [] endif return g:NERDTreeBookmarks @@ -53,7 +53,7 @@ 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. +" Throws NERDTree.BookmarkNotFoundError if no Bookmark is found. function! s:Bookmark.BookmarkFor(name) let l:result = {} for l:bookmark in s:Bookmark.Bookmarks() @@ -93,7 +93,7 @@ function! s:Bookmark.CacheBookmarks(silent) for i in bookmarkStrings "ignore blank lines - if i != '' + if i !=# '' let name = substitute(i, '^\(.\{-}\) .*$', '\1', '') let path = substitute(i, '^.\{-} \(.*\)$', '\1', '') @@ -111,7 +111,7 @@ function! s:Bookmark.CacheBookmarks(silent) if invalidBookmarksFound call s:Bookmark.Write() if !a:silent - call nerdtree#echo(invalidBookmarksFound . " invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.") + call nerdtree#echo(invalidBookmarksFound . ' invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.') endif endif endif @@ -120,16 +120,16 @@ 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. +" option. Supports the s:Bookmark.SortBookmarksList() method. function! s:Bookmark.CompareBookmarksByName(firstBookmark, secondBookmark) let l:result = 0 - if g:NERDTreeBookmarksSort == 1 + if g:NERDTreeBookmarksSort ==# 1 if a:firstBookmark.name ? a:secondBookmark.name let l:result = 1 endif - elseif g:NERDTreeBookmarksSort == 2 + elseif g:NERDTreeBookmarksSort ==# 2 if a:firstBookmark.name <# a:secondBookmark.name let l:result = -1 elseif a:firstBookmark.name ># a:secondBookmark.name @@ -159,13 +159,13 @@ 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) + 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. +" Throws NERDTree.BookmarkedNodeNotFoundError if the node is not found. " " Args: " searchFromAbsoluteRoot: boolean flag, search from the highest cached node @@ -185,8 +185,8 @@ 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 +" 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) @@ -196,9 +196,9 @@ endfunction " FUNCTION: Bookmark.GetSelected() {{{1 " returns the Bookmark the cursor is over, or {} function! s:Bookmark.GetSelected() - let line = getline(".") + let line = getline('.') let name = substitute(line, '^>\(.\{-}\) .\+$', '\1', '') - if name != line + if name !=# line try return s:Bookmark.BookmarkFor(name) catch /^NERDTree.BookmarkNotFoundError/ @@ -212,7 +212,7 @@ endfunction " Class method to get all invalid bookmark strings read from the bookmarks " file function! s:Bookmark.InvalidBookmarks() - if !exists("g:NERDTreeInvalidBookmarks") + if !exists('g:NERDTreeInvalidBookmarks') let g:NERDTreeInvalidBookmarks = [] endif return g:NERDTreeInvalidBookmarks @@ -222,8 +222,8 @@ endfunction 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() + throw 'NERDTree.BookmarkPointsToInvalidLocationError: the bookmark "'. + \ self.name .'" points to a non existing location: "'. self.path.str() endif endfunction @@ -231,7 +231,7 @@ endfunction " 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 + throw 'NERDTree.IllegalBookmarkNameError: illegal name:' . a:name endif let newBookmark = copy(self) @@ -256,7 +256,7 @@ endfunction function! s:Bookmark.open(nerdtree, ...) let opts = a:0 ? a:1 : {} - if nerdtree#and(g:NERDTreeQuitOnOpen,2) + if nerdtree#closeBookmarksOnOpen() call a:nerdtree.ui.toggleShowBookmarks() endif @@ -292,7 +292,7 @@ endfunction " 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 &nu + if &number let pathStrMaxLen = pathStrMaxLen - &numberwidth endif @@ -335,7 +335,7 @@ function! s:Bookmark.validate() return 1 else call s:Bookmark.CacheBookmarks(1) - call nerdtree#echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.") + call nerdtree#echo(self.name . 'now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.') return 0 endif endfunction @@ -349,7 +349,7 @@ function! s:Bookmark.Write() endfor "add a blank line before the invalid ones - call add(bookmarkStrings, "") + call add(bookmarkStrings, '') for j in s:Bookmark.InvalidBookmarks() call add(bookmarkStrings, j) @@ -358,7 +358,7 @@ function! s:Bookmark.Write() try call writefile(bookmarkStrings, g:NERDTreeBookmarksFile) catch - call nerdtree#echoError("Failed to write bookmarks file. Make sure g:NERDTreeBookmarksFile points to a valid location.") + call nerdtree#echoError('Failed to write bookmarks file. Make sure g:NERDTreeBookmarksFile points to a valid location.') endtry endfunction diff --git a/lib/nerdtree/creator.vim b/lib/nerdtree/creator.vim index efd3cc81..e794e0d9 100644 --- a/lib/nerdtree/creator.vim +++ b/lib/nerdtree/creator.vim @@ -28,7 +28,9 @@ endfunction " FUNCTION: s:Creator._broadcastInitEvent() {{{1 function! s:Creator._broadcastInitEvent() - silent doautocmd User NERDTreeInit + if exists('#User#NERDTreeInit') + doautocmd User NERDTreeInit + endif endfunction " FUNCTION: s:Creator.BufNamePrefix() {{{1 @@ -36,6 +38,29 @@ function! s:Creator.BufNamePrefix() return 'NERD_tree_' endfunction +" FUNCTION: s:Creator.CreateExploreTree(dir) {{{1 +function! s:Creator.CreateExploreTree(dir) + try + let path = g:NERDTreePath.New(a:dir) + catch /^NERDTree.InvalidArgumentsError/ + call nerdtree#echo('Invalid directory name:' . a:dir) + return + endtry + + let creator = s:Creator.New() + if getbufinfo('%')[0].changed && !&hidden && !&autowriteall + let l:splitLocation = g:NERDTreeWinPos ==# 'left' || g:NERDTreeWinPos ==# 'top' ? 'topleft ' : 'botright ' + let l:splitDirection = g:NERDTreeWinPos ==# 'left' || g:NERDTreeWinPos ==# 'right' ? 'vertical' : '' + silent! execute l:splitLocation . l:splitDirection . ' new' + else + silent! execute 'enew' + endif + + call creator.createWindowTree(a:dir) + "we want windowTree buffer to disappear after moving to any other buffer + setlocal bufhidden=wipe +endfunction + " FUNCTION: s:Creator.CreateTabTree(a:name) {{{1 function! s:Creator.CreateTabTree(name) let creator = s:Creator.New() @@ -82,20 +107,20 @@ function! s:Creator.createWindowTree(dir) try let path = g:NERDTreePath.New(a:dir) catch /^NERDTree.InvalidArgumentsError/ - call nerdtree#echo("Invalid directory name:" . a:name) + 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("#") + 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() + exec g:NERDTreeCreatePrefix . ' edit ' . self._nextBufferName('win') - call self._createNERDTree(path, "window") + call self._createNERDTree(path, 'window') let b:NERDTree._previousBuf = bufnr(previousBuf) call self._setCommonBufOptions() @@ -109,7 +134,7 @@ 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 + " plugins use b:NERDTreeRoot instead of b:NERDTree.root. Remove this " assignment in the future. let b:NERDTreeRoot = b:NERDTree.root @@ -126,9 +151,9 @@ endfunction function! s:Creator.createMirror() "get the names off all the nerd tree buffers let treeBufNames = [] - for i in range(1, tabpagenr("$")) + for i in range(1, tabpagenr('$')) let nextName = self._tabpagevar(i, 'NERDTreeBufName') - if nextName != -1 && (!exists("t:NERDTreeBufName") || nextName != t:NERDTreeBufName) + if nextName != -1 && (!exists('t:NERDTreeBufName') || nextName != t:NERDTreeBufName) call add(treeBufNames, nextName) endif endfor @@ -140,7 +165,7 @@ function! s:Creator.createMirror() let i = 0 while i < len(treeBufNames) let bufName = treeBufNames[i] - let treeRoot = getbufvar(bufName, "NERDTree").root + let treeRoot = getbufvar(bufName, 'NERDTree').root let options[i+1 . '. ' . treeRoot.path.str() . ' (buf name: ' . bufName . ')'] = bufName let i = i + 1 endwhile @@ -148,7 +173,7 @@ function! s:Creator.createMirror() "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 = ['Choose a tree to mirror'] let choices = extend(choices, sort(keys(options))) let choice = inputlist(choices) if choice < 1 || choice > len(options) || choice ==# '' @@ -159,7 +184,7 @@ function! s:Creator.createMirror() elseif len(keys(options)) ==# 1 let bufferName = values(options)[0] else - call nerdtree#echo("No trees to mirror") + call nerdtree#echo('No trees to mirror') return endif @@ -170,6 +195,7 @@ function! s:Creator.createMirror() let t:NERDTreeBufName = bufferName call self._createTreeWin() exec 'buffer ' . bufferName + call b:NERDTree.ui.restoreScreenState() if !&hidden call b:NERDTree.render() endif @@ -179,16 +205,17 @@ endfunction " 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:splitLocation = g:NERDTreeWinPos ==# 'left' || g:NERDTreeWinPos ==# 'top' ? 'topleft ' : 'botright ' + let l:splitDirection = g:NERDTreeWinPos ==# 'left' || g:NERDTreeWinPos ==# 'right' ? 'vertical' : '' let l:splitSize = g:NERDTreeWinSize if !g:NERDTree.ExistsForTab() - let t:NERDTreeBufName = self._nextBufferName() - silent! execute l:splitLocation . 'vertical ' . l:splitSize . ' new' + let t:NERDTreeBufName = self._nextBufferName('tab') + silent! execute l:splitLocation . l:splitDirection . ' ' . l:splitSize . ' new' silent! execute 'edit ' . t:NERDTreeBufName - silent! execute 'vertical resize '. l:splitSize + silent! execute l:splitDirection . ' resize '. l:splitSize else - silent! execute l:splitLocation . 'vertical ' . l:splitSize . ' split' + silent! execute l:splitLocation . l:splitDirection . ' ' . l:splitSize . ' split' silent! execute 'buffer ' . t:NERDTreeBufName endif @@ -217,17 +244,29 @@ function! s:Creator.New() 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() +" FUNCTION: s:Creator._nextBufferName(type='') {{{1 +" gets an optional buffer type of either 'tab' or 'win'. +" returns the buffer name for the next nerd tree of such type. +function! s:Creator._nextBufferName(...) + if a:0 > 0 + let type = a:1 + else + let type = '' + end + let name = s:Creator.BufNamePrefix() + if type ==# 'tab' + let name = name . 'tab_' + elseif type ==# 'win' + let name = name . 'win_' + endif + let name = name . 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") + if !exists('s:Creator._NextBufNum') let s:Creator._NextBufNum = 1 else let s:Creator._NextBufNum += 1 @@ -247,14 +286,18 @@ function! s:Creator._pathForString(str) "hack to get an absolute path if a relative path is given if dir =~# '^\.' - let dir = getcwd() . g:NERDTreePath.Slash() . dir + let dir = getcwd() . nerdtree#slash() . dir + endif + + "hack to prevent removing slash if dir is the root of the file system. + if dir !=# '/' + let dir = g:NERDTreePath.Resolve(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) + call nerdtree#echo('No bookmark or directory found for: ' . a:str) return {} endtry endif @@ -274,7 +317,7 @@ function! s:Creator._removeTreeBufForTab() "nerdtree buf may be mirrored/displayed elsewhere if self._isBufHidden(buf) - exec "bwipeout " . buf + exec 'bwipeout ' . buf endif endif @@ -300,11 +343,11 @@ function! s:Creator._setCommonBufOptions() setlocal nowrap if g:NERDTreeShowLineNumbers - setlocal nu + setlocal number else - setlocal nonu + setlocal nonumber if v:version >= 703 - setlocal nornu + setlocal norelativenumber endif endif @@ -330,17 +373,20 @@ endfunction " FUNCTION: s:Creator._tabpagevar(tabnr, var) {{{1 function! s:Creator._tabpagevar(tabnr, var) let currentTab = tabpagenr() - let old_ei = &ei - set ei=all + let old_ei = &eventignore + set eventignore=all - exec "tabnext " . a:tabnr - let v = -1 - if exists('t:' . a:var) - exec 'let v = t:' . a:var - endif - exec "tabnext " . currentTab + try + exec 'tabnext ' . a:tabnr + let v = -1 + if exists('t:' . a:var) + exec 'let v = t:' . a:var + endif + exec 'tabnext ' . currentTab - let &ei = old_ei + finally + let &eventignore = old_ei + endtry return v endfunction @@ -352,17 +398,20 @@ function! s:Creator.ToggleTabTree(dir) endfunction " FUNCTION: s:Creator.toggleTabTree(dir) {{{1 -" Toggles the NERD tree. I.e the NERD tree is open, it is closed, if it is -" closed it is restored or initialized (if it doesnt exist) +" 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 only used if the NERD tree is being -" initialized. +" 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 !&hidden + if !empty(a:dir) && a:dir !=# b:NERDTree.root.path.str() + call self.createTabTree(a:dir) + elseif !&hidden call b:NERDTree.render() endif call b:NERDTree.ui.restoreScreenState() diff --git a/lib/nerdtree/flag_set.vim b/lib/nerdtree/flag_set.vim index bc6e8879..75528674 100644 --- a/lib/nerdtree/flag_set.vim +++ b/lib/nerdtree/flag_set.vim @@ -43,13 +43,13 @@ endfunction "FUNCTION: FlagSet.renderToString() {{{1 function! s:FlagSet.renderToString() - let flagstring = "" + let flagstring = '' for i in values(self._flags) let flagstring .= join(i) endfor if len(flagstring) == 0 - return "" + return '' endif return '[' . flagstring . ']' diff --git a/lib/nerdtree/key_map.vim b/lib/nerdtree/key_map.vim index 584da1f1..ed791677 100644 --- a/lib/nerdtree/key_map.vim +++ b/lib/nerdtree/key_map.vim @@ -51,9 +51,9 @@ function! s:KeyMap.bind() else let keymapInvokeString = self.key endif - let keymapInvokeString = escape(keymapInvokeString, '\') + let keymapInvokeString = escape(keymapInvokeString, '\"') - let premap = self.key == "" ? " " : " " + let premap = self.key ==# '' ? ' ' : ' ' exec 'nnoremap '. self.key . premap . ':call nerdtree#ui_glue#invokeKeyMap("'. keymapInvokeString .'")' endfunction @@ -66,11 +66,11 @@ endfunction "FUNCTION: KeyMap.invoke() {{{1 "Call the KeyMaps callback function function! s:KeyMap.invoke(...) - let Callback = function(self.callback) + let l:Callback = type(self.callback) ==# type(function('tr')) ? self.callback : function(self.callback) if a:0 - call Callback(a:1) + call l:Callback(a:1) else - call Callback() + call l:Callback() endif endfunction @@ -78,11 +78,11 @@ endfunction "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 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 +"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) @@ -100,7 +100,7 @@ function! s:KeyMap.Invoke(key) "try file node if !node.path.isDirectory - let km = s:KeyMap.FindFor(a:key, "FileNode") + let km = s:KeyMap.FindFor(a:key, 'FileNode') if !empty(km) return km.invoke(node) endif @@ -108,14 +108,14 @@ function! s:KeyMap.Invoke(key) "try dir node if node.path.isDirectory - let km = s:KeyMap.FindFor(a:key, "DirNode") + 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") + let km = s:KeyMap.FindFor(a:key, 'Node') if !empty(km) return km.invoke(node) endif @@ -125,14 +125,14 @@ function! s:KeyMap.Invoke(key) "try bookmark let bm = g:NERDTreeBookmark.GetSelected() if !empty(bm) - let km = s:KeyMap.FindFor(a:key, "Bookmark") + 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") + let km = s:KeyMap.FindFor(a:key, 'all') if !empty(km) return km.invoke() endif @@ -143,7 +143,7 @@ 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'])) + if get(opts, 'override', 0) ==# 0 && !empty(s:KeyMap.FindFor(opts['key'], opts['scope'])) return end diff --git a/lib/nerdtree/menu_controller.vim b/lib/nerdtree/menu_controller.vim index 874c09dc..952c67bd 100644 --- a/lib/nerdtree/menu_controller.vim +++ b/lib/nerdtree/menu_controller.vim @@ -44,13 +44,13 @@ function! s:MenuController.showMenu() finally call self._restoreOptions() - " Redraw when "Ctrl-C" or "Esc" is received. - if !l:done || self.selection == -1 + " Redraw when Ctrl-C or Esc is received. + if !l:done || self.selection ==# -1 redraw! endif endtry - if self.selection != -1 + if self.selection !=# -1 let l:m = self._current() call l:m.execute() endif @@ -58,25 +58,25 @@ endfunction "FUNCTION: MenuController._echoPrompt() {{{1 function! s:MenuController._echoPrompt() - let navHelp = "Use " . g:NERDTreeMenuDown . "/" . g:NERDTreeMenuUp . "/enter" + let navHelp = 'Use ' . g:NERDTreeMenuDown . '/' . g:NERDTreeMenuUp . '/enter' if self.isMinimal() let selection = self.menuItems[self.selection].text - let keyword = matchstr(selection, "\([^ ]*") + let keyword = matchstr(selection, '[^ ]*([^ ]*') let shortcuts = map(copy(self.menuItems), "v:val['shortcut']") - let shortcuts[self.selection] = " " . keyword . " " + let shortcuts[self.selection] = ' ' . keyword . ' ' - echo "Menu: [" . join(shortcuts, ",") . "] (" . navHelp . " or shortcut): " + echo 'Menu: [' . join(shortcuts, ',') . '] (' . navHelp . ' or shortcut): ' else - echo "NERDTree Menu. " . navHelp . ", or the shortcuts indicated" - echo "=========================================================" + 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 + if self.selection ==# i + echo '> ' . self.menuItems[i].text else - echo " " . self.menuItems[i].text + echo ' ' . self.menuItems[i].text endif endfor endif @@ -92,20 +92,20 @@ endfunction "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 + if a:key ==# g:NERDTreeMenuDown call self._cursorDown() - elseif a:key == g:NERDTreeMenuUp + elseif a:key ==# g:NERDTreeMenuUp call self._cursorUp() - elseif a:key == nr2char(27) "escape + elseif a:key ==# nr2char(27) "escape let self.selection = -1 return 1 - elseif a:key == "\r" || a:key == "\n" "enter and ctrl-j + elseif a:key ==# "\r" || a:key ==# "\n" "enter and ctrl-j return 1 else let index = self._nextIndexFor(a:key) - if index != -1 + if index !=# -1 let self.selection = index - if len(self._allIndexesFor(a:key)) == 1 + if len(self._allIndexesFor(a:key)) ==# 1 return 1 endif endif @@ -120,7 +120,7 @@ function! s:MenuController._allIndexesFor(shortcut) let toReturn = [] for i in range(0, len(self.menuItems)-1) - if self.menuItems[i].shortcut == a:shortcut + if self.menuItems[i].shortcut ==# a:shortcut call add(toReturn, i) endif endfor @@ -133,13 +133,13 @@ endfunction "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 + 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 + if self.menuItems[i].shortcut ==# a:shortcut return i endif endfor diff --git a/lib/nerdtree/menu_item.vim b/lib/nerdtree/menu_item.vim index 92c1bbbf..7f259171 100644 --- a/lib/nerdtree/menu_item.vim +++ b/lib/nerdtree/menu_item.vim @@ -6,7 +6,7 @@ let g:NERDTreeMenuItem = s:MenuItem "FUNCTION: MenuItem.All() {{{1 "get all top level menu items function! s:MenuItem.All() - if !exists("s:menuItems") + if !exists('s:menuItems') let s:menuItems = [] endif return s:menuItems @@ -58,7 +58,7 @@ function! s:MenuItem.CreateSeparator(options) let standard_options = { 'text': '--------------------', \ 'shortcut': -1, \ 'callback': -1 } - let options = extend(a:options, standard_options, "force") + let options = extend(a:options, standard_options, 'force') return s:MenuItem.Create(options) endfunction @@ -67,7 +67,7 @@ endfunction "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") + let options = extend(a:options, standard_options, 'force') return s:MenuItem.Create(options) endfunction @@ -79,7 +79,7 @@ endfunction "specified function! s:MenuItem.enabled() if self.isActiveCallback != -1 - return {self.isActiveCallback}() + return type(self.isActiveCallback) == type(function('tr')) ? self.isActiveCallback() : {self.isActiveCallback}() endif return 1 endfunction @@ -94,7 +94,11 @@ function! s:MenuItem.execute() call mc.showMenu() else if self.callback != -1 - call {self.callback}() + if type(self.callback) == type(function('tr')) + call self.callback() + else + call {self.callback}() + endif endif endif endfunction diff --git a/lib/nerdtree/nerdtree.vim b/lib/nerdtree/nerdtree.vim index 3e7ade8a..1af5346a 100644 --- a/lib/nerdtree/nerdtree.vim +++ b/lib/nerdtree/nerdtree.vim @@ -27,7 +27,9 @@ function! s:NERDTree.changeRoot(node) call self.render() call self.root.putCursorHere(0, 0) - silent doautocmd User NERDTreeNewRoot + if exists('#User#NERDTreeNewRoot') + doautocmd User NERDTreeNewRoot + endif endfunction "FUNCTION: s:NERDTree.Close() {{{1 @@ -37,45 +39,37 @@ function! s:NERDTree.Close() return endif - if winnr("$") != 1 + 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) + 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("") + let l:activeBufOrWin = l:useWinId ? win_getid() : bufnr('') endif - call nerdtree#exec(s:NERDTree.GetWinNum() . " wincmd w", 1) - call nerdtree#exec("close", 0) + 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) + call nerdtree#exec('call win_gotoid(' . l:activeBufOrWin . ')', 0) else - call nerdtree#exec(bufwinnr(l:activeBufOrWin) . " wincmd w", 0) + 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" + throw 'NERDTree.IllegalOperationError: cant find bookmark table, bookmarks arent active' endif if g:NERDTreeMinimalUI @@ -88,7 +82,7 @@ function! s:NERDTree.CursorToBookmarkTable() while getline(line) !~# '^>-\+Bookmarks-\+$' let line = line + 1 if line >= rootNodeLine - throw "NERDTree.BookmarkTableNotFoundError: didnt find the bookmarks table" + throw 'NERDTree.BookmarkTableNotFoundError: didnt find the bookmarks table' endif endwhile call cursor(line, 2) @@ -96,21 +90,21 @@ endfunction "FUNCTION: s:NERDTree.CursorToTreeWin(){{{1 "Places the cursor in the nerd tree window -function! s:NERDTree.CursorToTreeWin() +function! s:NERDTree.CursorToTreeWin(...) call g:NERDTree.MustBeOpen() - call nerdtree#exec(g:NERDTree.GetWinNum() . "wincmd w", 1) + call nerdtree#exec(g:NERDTree.GetWinNum() . 'wincmd w', a:0 >0 ? a:1 : 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") + 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") + if !exists('t:NERDTreeBufName') return end @@ -133,7 +127,7 @@ function! s:NERDTree.ForCurrentTab() endif let bufnr = bufnr(t:NERDTreeBufName) - return getbufvar(bufnr, "NERDTree") + return getbufvar(bufnr, 'NERDTree') endfunction "FUNCTION: s:NERDTree.getRoot() {{{1 @@ -144,13 +138,13 @@ endfunction "FUNCTION: s:NERDTree.GetWinNum() {{{1 "gets the nerd tree window number for this tab function! s:NERDTree.GetWinNum() - if exists("t:NERDTreeBufName") + 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\+$' + if bufname(winbufnr(w)) =~# '^' . g:NERDTreeCreator.BufNamePrefix() . 'win_\d\+$' return w endif endfor @@ -160,23 +154,23 @@ endfunction "FUNCTION: s:NERDTree.IsOpen() {{{1 function! s:NERDTree.IsOpen() - return s:NERDTree.GetWinNum() != -1 + return s:NERDTree.GetWinNum() !=# -1 endfunction "FUNCTION: s:NERDTree.isTabTree() {{{1 function! s:NERDTree.isTabTree() - return self._type == "tab" + return self._type ==# 'tab' endfunction "FUNCTION: s:NERDTree.isWinTree() {{{1 function! s:NERDTree.isWinTree() - return self._type == "window" + return self._type ==# 'window' endfunction "FUNCTION: s:NERDTree.MustBeOpen() {{{1 function! s:NERDTree.MustBeOpen() if !s:NERDTree.IsOpen() - throw "NERDTree.TreeNotOpen" + throw 'NERDTree.TreeNotOpen' endif endfunction diff --git a/lib/nerdtree/notifier.vim b/lib/nerdtree/notifier.vim index d24fc8f8..ffa2853a 100644 --- a/lib/nerdtree/notifier.vim +++ b/lib/nerdtree/notifier.vim @@ -14,13 +14,14 @@ 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) - call {listener}(event) + for Listener in s:Notifier.GetListenersForEvent(a:event) + let l:Callback = type(Listener) == type(function('tr')) ? Listener : function(Listener) + call l:Callback(event) endfor endfunction function! s:Notifier.GetListenersMap() - if !exists("s:refreshListenersMap") + if !exists('s:refreshListenersMap') let s:refreshListenersMap = {} endif return s:refreshListenersMap diff --git a/lib/nerdtree/opener.vim b/lib/nerdtree/opener.vim index fa0c9884..27993ac7 100644 --- a/lib/nerdtree/opener.vim +++ b/lib/nerdtree/opener.vim @@ -1,7 +1,7 @@ " ============================================================================ " CLASS: Opener " -" The Opener class defines an API for "opening" operations. +" The Opener class defines an API for 'opening' operations. " ============================================================================ @@ -33,8 +33,7 @@ function! s:Opener._bufInWindows(bnum) 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. +" Check the class options 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 @@ -45,8 +44,8 @@ function! s:Opener._checkToCloseTree(newtab) return endif - if (a:newtab && self._where == 't') || !a:newtab - call g:NERDTree.CloseIfQuitOnOpen() + if (a:newtab && self._where ==# 't') || !a:newtab + call g:NERDTree.Close() endif endfunction @@ -54,9 +53,9 @@ endfunction " find the window number of the first normal window function! s:Opener._firstUsableWindow() let i = 1 - while i <= winnr("$") + while i <= winnr('$') let bnum = winbufnr(i) - if bnum != -1 && getbufvar(bnum, '&buftype') ==# '' + if bnum !=# -1 && getbufvar(bnum, '&buftype') ==# '' \ && !getwinvar(i, '&previewwindow') \ && (!getbufvar(bnum, '&modified') || &hidden) return i @@ -70,23 +69,23 @@ endfunction " FUNCTION: Opener._gotoTargetWin() {{{1 function! s:Opener._gotoTargetWin() if b:NERDTree.isWinTree() - if self._where == 'v' + if self._where ==# 'v' call self._newVSplit() - elseif self._where == 'h' + elseif self._where ==# 'h' call self._newSplit() - elseif self._where == 't' + elseif self._where ==# 't' tabnew endif else call self._checkToCloseTree(1) - if self._where == 'v' + if self._where ==# 'v' call self._newVSplit() - elseif self._where == 'h' + elseif self._where ==# 'h' call self._newSplit() - elseif self._where == 't' + elseif self._where ==# 't' tabnew - elseif self._where == 'p' + elseif self._where ==# 'p' call self._previousWindow() endif @@ -102,15 +101,15 @@ endfunction " 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 + if winnr('$') ==# 1 return 0 endif let oldwinnr = winnr() - call nerdtree#exec(a:winnumber . "wincmd p", 1) - let specialWindow = getbufvar("%", '&buftype') != '' || getwinvar('%', '&previewwindow') + call nerdtree#exec(a:winnumber . 'wincmd p', 1) + let specialWindow = getbufvar('%', '&buftype') !=# '' || getwinvar('%', '&previewwindow') let modified = &modified - call nerdtree#exec(oldwinnr . "wincmd p", 1) + call nerdtree#exec(oldwinnr . 'wincmd p', 1) "if its a special window e.g. quickfix or another explorer plugin then we "have to split @@ -131,9 +130,9 @@ endfunction " 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" +" 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 +" '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) @@ -153,30 +152,29 @@ endfunction " FUNCTION: Opener._newSplit() {{{1 function! s:Opener._newSplit() - let onlyOneWin = (winnr("$") ==# 1) + let onlyOneWin = (winnr('$') ==# 1) let savesplitright = &splitright if onlyOneWin - let &splitright = (g:NERDTreeWinPos ==# "left") + let &splitright = (g:NERDTreeWinPos ==# 'left') endif " If only one window (ie. NERDTree), split vertically instead. - let splitMode = onlyOneWin ? "vertical" : "" + let splitMode = onlyOneWin ? 'vertical' : '' " Open the new window try call nerdtree#exec('wincmd p', 1) - call nerdtree#exec(splitMode . " split",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." + 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('silent '. splitMode .' resize '. g:NERDTreeWinSize, 1) call nerdtree#exec('wincmd p', 0) endif @@ -187,15 +185,15 @@ endfunction function! s:Opener._newVSplit() let l:winwidth = winwidth('.') - let onlyOneWin = (winnr("$") ==# 1) + let onlyOneWin = (winnr('$') ==# 1) let savesplitright = &splitright if onlyOneWin - let &splitright = (g:NERDTreeWinPos ==# "left") + let &splitright = (g:NERDTreeWinPos ==# 'left') let l:winwidth = g:NERDTreeWinSize endif call nerdtree#exec('wincmd p', 1) - call nerdtree#exec('vnew', 1) + call nerdtree#exec('vsplit', 1) let l:currentWindowNumber = winnr() @@ -219,7 +217,7 @@ endfunction " FUNCTION: Opener._openFile() {{{1 function! s:Opener._openFile() - if !self._stay && !and(g:NERDTreeQuitOnOpen,1) && exists("b:NERDTreeZoomed") && b:NERDTreeZoomed + if !self._stay && self._keepopen && get(b:, 'NERDTreeZoomed', 0) call b:NERDTree.ui.toggleZoom() endif @@ -247,7 +245,7 @@ function! s:Opener._openDirectory(node) else if empty(self._where) call b:NERDTree.changeRoot(a:node) - elseif self._where == 't' + elseif self._where ==# 't' call g:NERDTreeCreator.CreateTabTree(a:node.path.str()) else call g:NERDTreeCreator.CreateWindowTree(a:node.path.str()) @@ -261,18 +259,18 @@ endfunction " FUNCTION: Opener._previousWindow() {{{1 function! s:Opener._previousWindow() - if !self._isWindowUsable(winnr("#")) && self._firstUsableWindow() ==# -1 + if !self._isWindowUsable(winnr('#')) && self._firstUsableWindow() ==# -1 call self._newSplit() else try - if !self._isWindowUsable(winnr("#")) - call nerdtree#exec(self._firstUsableWindow() . "wincmd w", 1) + 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." + throw 'NERDTree.FileAlreadyOpenAndModifiedError: '. self._path.str() .' is already open and modified.' catch /^Vim\%((\a\+)\)\=:/ echo v:exception endtry @@ -296,13 +294,13 @@ function! s:Opener._reuseWindow() "check the current tab for the window let winnr = bufwinnr('^' . self._path.str() . '$') - if winnr != -1 - call nerdtree#exec(winnr . "wincmd w", 0) + if winnr !=# -1 + call nerdtree#exec(winnr . 'wincmd w', 0) call self._checkToCloseTree(0) return 1 endif - if self._reuse == 'currenttab' + if self._reuse ==# 'currenttab' return 0 endif @@ -312,7 +310,7 @@ function! s:Opener._reuseWindow() call self._checkToCloseTree(1) call nerdtree#exec(tabnr . 'tabnext', 1) let winnr = bufwinnr('^' . self._path.str() . '$') - call nerdtree#exec(winnr . "wincmd w", 0) + call nerdtree#exec(winnr . 'wincmd w', 0) return 1 endif @@ -321,7 +319,7 @@ endfunction " FUNCTION: Opener._saveCursorPos() {{{1 function! s:Opener._saveCursorPos() - let self._bufnr = bufnr("") + let self._bufnr = bufnr('') let self._tabnr = tabpagenr() endfunction diff --git a/lib/nerdtree/path.vim b/lib/nerdtree/path.vim index ccb94238..fa6f59dd 100644 --- a/lib/nerdtree/path.vim +++ b/lib/nerdtree/path.vim @@ -25,10 +25,10 @@ function! s:Path.AbsolutePathFor(pathStr) if l:prependWorkingDir let l:result = getcwd() - if l:result[-1:] == s:Path.Slash() + if l:result[-1:] == nerdtree#slash() let l:result = l:result . a:pathStr else - let l:result = l:result . s:Path.Slash() . a:pathStr + let l:result = l:result . nerdtree#slash() . a:pathStr endif endif @@ -37,7 +37,7 @@ endfunction " FUNCTION: Path.bookmarkNames() {{{1 function! s:Path.bookmarkNames() - if !exists("self._bookmarkNames") + if !exists('self._bookmarkNames') call self.cacheDisplayString() endif return self._bookmarkNames @@ -57,7 +57,7 @@ function! s:Path.cacheDisplayString() abort call add(self._bookmarkNames, i.name) endif endfor - if !empty(self._bookmarkNames) && g:NERDTreeMarkBookmarks == 1 + if !empty(self._bookmarkNames) && g:NERDTreeMarkBookmarks ==# 1 let self.cachedDisplayString = self.addDelimiter(self.cachedDisplayString) . ' {' . join(self._bookmarkNames) . '}' endif @@ -65,6 +65,25 @@ function! s:Path.cacheDisplayString() abort let self.cachedDisplayString = self.addDelimiter(self.cachedDisplayString) . ' -> ' . self.symLinkDest endif + if !self.isDirectory && b:NERDTree.ui.getShowFileLines() != 0 + let l:bufname = self.str({'format': 'Edit'}) + let l:lines = 0 + if executable('wc') + let l:lines = split(system('wc -l "'.l:bufname.'"'))[0] + elseif nerdtree#runningWindows() + let l:lines = substitute(system('type "'.l:bufname.'" | find /c /v ""'), '\n', '', 'g') + else + let s:lines = readfile(l:bufname) + let l:lines = 0 + for s:line in s:lines + let l:lines += 1 + if l:lines >= 20000 + break + endif + endfor + endif + let self.cachedDisplayString = self.addDelimiter(self.cachedDisplayString) . ' ('.l:lines.')' + endif if self.isReadOnly let self.cachedDisplayString = self.addDelimiter(self.cachedDisplayString) . ' ['.g:NERDTreeGlyphReadOnly.']' endif @@ -87,62 +106,18 @@ function! s:Path.changeToDir() endif try - if g:NERDTreeUseTCD && exists(":tcd") == 2 - execute "tcd " . dir + 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()) + execute 'cd ' . dir + call nerdtree#echo('CWD is now: ' . getcwd()) endif catch - throw "NERDTree.PathChangeError: cannot change CWD to " . dir + 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 $" endif - return " \\`\|\"#%&,?()\*^<>[]$" + return " \\`\|\"#%&,?()\*^<>[]{}$" endfunction " FUNCTION: Path.getDir() {{{1 @@ -384,9 +362,10 @@ endfunction " returns the index of the pattern in g:NERDTreeSortOrder that this path matches function! s:Path.getSortOrderIndex() let i = 0 + let l:lpc = self.getLastPathComponent(1) while i < len(g:NERDTreeSortOrder) if g:NERDTreeSortOrder[i] !~? '\[\[-\?\(timestamp\|size\|extension\)\]\]' && - \ self.getLastPathComponent(1) =~# g:NERDTreeSortOrder[i] + \ l:lpc =~# g:NERDTreeSortOrder[i] return i endif let i = i + 1 @@ -402,7 +381,7 @@ function! s:Path._splitChunks(path) let i = 0 while i < len(chunks) "convert number literals to numbers - if match(chunks[i], '^\d\+$') == 0 + if match(chunks[i], '^\d\+$') ==# 0 let chunks[i] = str2nr(chunks[i]) endif let i = i + 1 @@ -413,21 +392,21 @@ 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 + 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)] + 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)] + 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)] + let metadata += [self.isDirectory ? '' : (extension ==# '' ? nr2char(str2nr('0x10ffff',16)) : extension)] endif endfor - if g:NERDTreeSortOrder[0] =~ '\[\[.*\]\]' + if g:NERDTreeSortOrder[0] =~# '\[\[.*\]\]' " Apply tags' sorting first if specified first. let self._sortKey = metadata + [self.getSortOrderIndex()] else @@ -435,7 +414,7 @@ function! s:Path.getSortKey() let self._sortKey = [self.getSortOrderIndex()] + metadata endif - let path = self.getLastPathComponent(1) + let path = self.getLastPathComponent(0) if !g:NERDTreeSortHiddenFirst let path = substitute(path, '^[._]', '', '') endif @@ -500,9 +479,10 @@ function! s:Path.ignore(nerdtree) endif endfor - for callback in g:NERDTree.PathFilters() - if {callback}({'path': self, 'nerdtree': a:nerdtree}) - return 1 + for l:Callback in g:NERDTree.PathFilters() + let l:Callback = type(l:Callback) ==# type(function('tr')) ? l:Callback : function(l:Callback) + if l:Callback({'path': self, 'nerdtree': a:nerdtree}) + return 1 endif endfor endif @@ -523,12 +503,15 @@ endfunction " 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 strpart(pat,len(pat)-8) ==# '[[path]]' + let pat = strpart(pat,0, len(pat)-8) + return self.str() =~# pat + elseif 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]]' + elseif strpart(pat,len(pat)-8) ==# '[[file]]' if self.isDirectory return 0 endif @@ -542,26 +525,36 @@ endfunction " 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 +function! s:Path.isAncestor(child) + return a:child.isUnder(self) 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 +function! s:Path.isUnder(parent) + if a:parent.isDirectory ==# 0 return 0 endif - - let this = self.str() - let that = a:path.str() - return stridx(this, that . s:Path.Slash()) == 0 + if nerdtree#runningWindows() && a:parent.drive !=# self.drive + return 0 + endif + let l:this_count = len(self.pathSegments) + if l:this_count ==# 0 + return 0 + endif + let l:that_count = len(a:parent.pathSegments) + if l:that_count ==# 0 + return 1 + endif + if l:that_count >= l:this_count + return 0 + endif + for i in range(0, l:that_count-1) + if !nerdtree#pathEquals(self.pathSegments[i], a:parent.pathSegments[i]) + return 0 + endif + endfor + return 1 endfunction " FUNCTION: Path.JoinPathStrings(...) {{{1 @@ -581,11 +574,7 @@ endfunction " 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 + return nerdtree#pathEquals(self.str(), a:path.str()) endfunction " FUNCTION: Path.New(pathStr) {{{1 @@ -600,23 +589,6 @@ function! s:Path.New(pathStr) 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 @@ -636,8 +608,8 @@ function! s:Path.readInfoFromDisk(fullpath) let fullpath = s:Path.WinToUnixPath(a:fullpath) - if getftype(fullpath) ==# "fifo" - throw "NERDTree.InvalidFiletypeError: Cant handle FIFO files: " . 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)') @@ -649,7 +621,7 @@ function! s:Path.readInfoFromDisk(fullpath) let self.isDirectory = 0 let self.isReadOnly = filewritable(a:fullpath) ==# 0 else - throw "NERDTree.InvalidArgumentsError: Invalid path = " . a:fullpath + throw 'NERDTree.InvalidArgumentsError: Invalid path = ' . a:fullpath endif let self.isExecutable = 0 @@ -664,7 +636,7 @@ function! s:Path.readInfoFromDisk(fullpath) 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) + let self.isSymLink = (s:Path.Resolve(hardPath) !=# hardPath) if self.isSymLink let self.symLinkDest = s:Path.Resolve(fullpath) @@ -699,13 +671,13 @@ endfunction " Renames this node on the filesystem function! s:Path.rename(newPath) if a:newPath ==# '' - throw "NERDTree.InvalidArgumentsError: Invalid newPath for renaming = ". 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 + if success !=# 0 throw "NERDTree.PathRenameError: Could not rename: '" . self.str() . "'" . 'to:' . a:newPath endif call self.readInfoFromDisk(a:newPath) @@ -741,7 +713,7 @@ endfunction " value associated with 'truncateTo'. A '<' is prepended. function! s:Path.str(...) let options = a:0 ? a:1 : {} - let toReturn = "" + let toReturn = '' if has_key(options, 'format') let format = options['format'] @@ -778,7 +750,7 @@ endfunction " FUNCTION: Path._strForUI() {{{1 function! s:Path._strForUI() let toReturn = '/' . join(self.pathSegments, '/') - if self.isDirectory && toReturn != '/' + if self.isDirectory && toReturn !=# '/' let toReturn = toReturn . '/' endif return toReturn @@ -801,7 +773,7 @@ function! s:Path._strForEdit() " On Windows, the drive letter may be removed by "fnamemodify()". Add it " back, if necessary. - if nerdtree#runningWindows() && l:result[0] == s:Path.Slash() + if nerdtree#runningWindows() && l:result[0] == nerdtree#slash() let l:result = self.drive . l:result endif @@ -816,14 +788,14 @@ endfunction " FUNCTION: Path._strForGlob() {{{1 function! s:Path._strForGlob() - let lead = s:Path.Slash() + let lead = nerdtree#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()) + let toReturn = lead . join(self.pathSegments, nerdtree#slash()) if !nerdtree#runningWindows() let toReturn = escape(toReturn, self._escChars()) @@ -835,7 +807,7 @@ endfunction " 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:separator = nerdtree#slash() let l:leader = l:separator if nerdtree#runningWindows() @@ -882,13 +854,13 @@ function! s:Path.WinToUnixPath(pathstr) let toReturn = a:pathstr "remove the x:\ of the front - let toReturn = substitute(toReturn, '^.*:\(\\\|/\)\?', '/', "") + let toReturn = substitute(toReturn, '^.*:\(\\\|/\)\?', '/', '') "remove the \\ network share from the front - let toReturn = substitute(toReturn, '^\(\\\\\|\/\/\)[^\\\/]*\(\\\|\/\)[^\\\/]*\(\\\|\/\)\?', '/', "") + let toReturn = substitute(toReturn, '^\(\\\\\|\/\/\)[^\\\/]*\(\\\|\/\)[^\\\/]*\(\\\|\/\)\?', '/', '') "convert all \ chars to / - let toReturn = substitute(toReturn, '\', '/', "g") + let toReturn = substitute(toReturn, '\', '/', 'g') return toReturn endfunction diff --git a/lib/nerdtree/tree_dir_node.vim b/lib/nerdtree/tree_dir_node.vim index 4015f0be..5c25c809 100644 --- a/lib/nerdtree/tree_dir_node.vim +++ b/lib/nerdtree/tree_dir_node.vim @@ -14,7 +14,7 @@ let g:NERDTreeDirNode = s:TreeDirNode " Class method that returns the highest cached ancestor of the current root. function! s:TreeDirNode.AbsoluteTreeRoot() let currentNode = b:NERDTree.root - while currentNode.parent != {} + while currentNode.parent !=# {} let currentNode = currentNode.parent endwhile return currentNode @@ -100,20 +100,15 @@ function! s:TreeDirNode.displayString() 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,'^.','','') + let l:label .= l:label ==# '' ? l:next : substitute(l:next,'^.','','') endfor " Select the appropriate open/closed status indicator symbol. - if l:cascade[-1].isOpen - let l:symbol = g:NERDTreeDirArrowCollapsible - else - let l:symbol = g:NERDTreeDirArrowExpandable - endif - + 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() - let l:result = l:symbol . ' ' . l:flags . l:label - return l:result + return l:symbol . l:flags . l:label endfunction " FUNCTION: TreeDirNode.findNode(path) {{{1 @@ -126,14 +121,20 @@ 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 {} + if nerdtree#caseSensitiveFS() + if stridx(a:path.str(), self.path.str(), 0) ==# -1 + return {} + endif + else + if stridx(tolower(a:path.str()), tolower(self.path.str()), 0) ==# -1 + return {} + endif endif if self.path.isDirectory for i in self.children let retVal = i.findNode(a:path) - if retVal != {} + if retVal !=# {} return retVal endif endfor @@ -169,7 +170,7 @@ function! s:TreeDirNode.getCascadeRoot() while !empty(l:parent) && !l:parent.isRoot() - if index(l:parent.getCascade(), self) == -1 + if index(l:parent.getCascade(), self) ==# -1 break endif @@ -218,7 +219,7 @@ endfunction 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." + throw 'NERDTree.InvalidArgumentsError: Index is out of bounds.' endif return array_to_search[a:indx] endfunction @@ -241,7 +242,7 @@ function! s:TreeDirNode.getChildIndex(path) let z = self.getChildCount() while a < z let mid = (a+z)/2 - let diff = a:path.compareTo(self.children[mid].path) + let diff = nerdtree#compareNodePaths(a:path, self.children[mid].path) if diff ==# -1 let z = mid @@ -255,10 +256,10 @@ function! s:TreeDirNode.getChildIndex(path) endfunction " FUNCTION: TreeDirNode.getDirChildren() {{{1 -" Return a list of all child nodes from "self.children" that are of type +" 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') + return filter(copy(self.children), 'v:val.path.isDirectory ==# 1') endfunction " FUNCTION: TreeDirNode._glob(pattern, all) {{{1 @@ -267,7 +268,7 @@ endfunction " " Args: " pattern: (string) the glob pattern to apply -" all: (0 or 1) if 1, include "." and ".." if they match "pattern"; if 0, +" 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, @@ -276,28 +277,32 @@ endfunction " relative paths. function! s:TreeDirNode._glob(pattern, all) - " Construct a path specification such that "globpath()" will return + " Construct a path specification such that globpath() will return " relative pathnames, if possible. - if self.path.str() == getcwd() + if self.path.str() ==# getcwd() let l:pathSpec = ',' else let l:pathSpec = escape(fnamemodify(self.path.str({'format': 'Glob'}), ':.'), ',') + if nerdtree#runningWindows() + let l:pathSpec = substitute(l:pathSpec, "\\[\\(.*\\]\\)", "[[]\\1", "g") + endif + " On Windows, the drive letter may be removed by "fnamemodify()". - if nerdtree#runningWindows() && l:pathSpec[0] == g:NERDTreePath.Slash() + if nerdtree#runningWindows() && l:pathSpec[0] == nerdtree#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')) + " 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') + 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')) + 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 @@ -305,7 +310,7 @@ function! s:TreeDirNode._glob(pattern, all) let l:globList = split(l:globString, "\n") endif - " If "a:all" is false, filter "." and ".." from the output. + " If a:all is false, filter '.' and '..' from the output. if !a:all let l:toRemove = [] @@ -315,13 +320,13 @@ function! s:TreeDirNode._glob(pattern, all) " 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 == '' + if l:tail ==# '' let l:tail = fnamemodify(l:file, ':h:t') endif - if l:tail == '.' || l:tail == '..' + if l:tail ==# '.' || l:tail ==# '..' call add(l:toRemove, l:file) - if len(l:toRemove) == 2 + if len(l:toRemove) ==# 2 break endif endif @@ -341,7 +346,7 @@ endfunction unlet s:TreeDirNode.GetSelected function! s:TreeDirNode.GetSelected() let currentDir = g:NERDTreeFileNode.GetSelected() - if currentDir != {} && !currentDir.isRoot() + if currentDir !=# {} && !currentDir.isRoot() if currentDir.path.isDirectory ==# 0 let currentDir = currentDir.parent endif @@ -373,7 +378,7 @@ endfunction " FUNCTION: TreeDirNode.hasVisibleChildren() {{{1 " returns 1 if this node has any childre, 0 otherwise.. function! s:TreeDirNode.hasVisibleChildren() - return self.getVisibleChildCount() != 0 + return self.getVisibleChildCount() !=# 0 endfunction " FUNCTION: TreeDirNode.isCascadable() {{{1 @@ -382,8 +387,14 @@ endfunction " 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. +" Also, return false if this directory is the tree root, which should never be +" part of a cascade. function! s:TreeDirNode.isCascadable() - if g:NERDTreeCascadeSingleChildDir == 0 + if g:NERDTreeCascadeSingleChildDir ==# 0 + return 0 + endif + + if self.isRoot() return 0 endif @@ -398,14 +409,14 @@ function! s:TreeDirNode.isCascadable() endfor let c = self.getVisibleChildren() - return len(c) == 1 && c[0].path.isDirectory + 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 +" silent: 1 if the function should not echo any 'please wait' messages for " large directories " " Return: the number of child nodes read @@ -416,10 +427,11 @@ function! s:TreeDirNode._initChildren(silent) let files = self._glob('*', 1) + self._glob('.*', 0) if !a:silent && len(files) > g:NERDTreeNotificationThreshold - call nerdtree#echo("Please wait, caching a large dir ...") + call nerdtree#echo('Please wait, caching a large dir ...') endif let invalidFilesFound = 0 + let invalidFiles = [] for i in files try let path = g:NERDTreePath.New(i) @@ -427,15 +439,17 @@ function! s:TreeDirNode._initChildren(silent) call g:NERDTreePathNotifier.NotifyListeners('init', path, self.getNerdtree(), {}) catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/ let invalidFilesFound += 1 + let invalidFiles += [i] endtry endfor + let g:NERDTreeOldSortOrder = g:NERDTreeSortOrder call self.sortChildren() - call nerdtree#echo("") + call nerdtree#echo('') if invalidFilesFound - call nerdtree#echoWarning(invalidFilesFound . " file(s) could not be loaded into the NERD tree") + call nerdtree#echoWarning(invalidFilesFound . ' Invalid file(s): ' . join(invalidFiles, ', ')) endif return self.getChildCount() endfunction @@ -447,8 +461,8 @@ endfunction " 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." + if a:path.isDirectory !=# 1 + throw 'NERDTree.InvalidArgumentsError: A TreeDirNode object must be instantiated with a directory Path object.' endif let newTreeNode = copy(self) @@ -510,7 +524,7 @@ function! s:TreeDirNode.openAlong(...) while node.path.isDirectory call node.open(opts) let level += 1 - if node.getVisibleChildCount() == 1 + if node.getVisibleChildCount() ==# 1 let node = node.getChildByIndex(0, 1) else break @@ -523,8 +537,8 @@ endfunction " 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'}) + execute 'wincmd p' + execute 'edit '.self.path.str({'format':'Edit'}) endfunction " FUNCTION: TreeDirNode.openInNewTab(options) {{{1 @@ -562,12 +576,13 @@ function! s:TreeDirNode.refresh() let files = self._glob('*', 1) + self._glob('.*', 0) let newChildNodes = [] let invalidFilesFound = 0 + let invalidFiles = [] 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 != {} + if newNode !=# {} && path.str() ==# newNode.path.str() call newNode.refresh() call add(newChildNodes, newNode) @@ -576,9 +591,11 @@ function! s:TreeDirNode.refresh() let newNode = g:NERDTreeFileNode.New(path, self.getNerdtree()) let newNode.parent = self call add(newChildNodes, newNode) + call g:NERDTreePathNotifier.NotifyListeners('init', newNode.path, newNode.getNerdtree(), {}) endif catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/ - let invalidFilesFound = 1 + let invalidFilesFound += 1 + let invalidFiles += [i] endtry endfor @@ -587,7 +604,7 @@ function! s:TreeDirNode.refresh() call self.sortChildren() if invalidFilesFound - call nerdtree#echoWarning("some files could not be loaded into the NERD tree") + call nerdtree#echoWarning(invalidFilesFound . ' Invalid file(s): ' . join(invalidFiles, ', ')) endif endif endfunction @@ -614,7 +631,7 @@ 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() + throw 'NERDTree.InvalidArgumentsError: ' . a:path.str() . ' should be under ' . self.path.str() endif call self.open() @@ -622,11 +639,11 @@ function! s:TreeDirNode.reveal(path, ...) 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 == {} + if n ==# {} call self.refresh() let n = self.findNode(a:path) endif - if has_key(opts, "open") + if has_key(opts, 'open') call n.open() endif return n @@ -642,8 +659,8 @@ function! s:TreeDirNode.reveal(path, ...) endfunction " FUNCTION: TreeDirNode.removeChild(treenode) {{{1 -" Remove the given treenode from "self.children". -" Throws "NERDTree.ChildNotFoundError" if the node is not found. +" Remove the given treenode from self.children. +" Throws NERDTree.ChildNotFoundError if the node is not found. " " Args: " treenode: the node object to remove @@ -655,16 +672,16 @@ function! s:TreeDirNode.removeChild(treenode) endif endfor - throw "NERDTree.ChildNotFoundError: child node was not found" + throw 'NERDTree.ChildNotFoundError: child node was not found' endfunction " FUNCTION: TreeDirNode.sortChildren() {{{1 -" Sort "self.children" by alphabetical order and directory priority. +" 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") + let CompareFunc = function('nerdtree#compareNodes') call sort(self.children, CompareFunc) let g:NERDTreeOldSortOrder = g:NERDTreeSortOrder endfunction @@ -676,7 +693,7 @@ function! s:TreeDirNode.toggleOpen(...) if self.isOpen ==# 1 call self.close() else - if g:NERDTreeCascadeOpenSingleChildDir == 0 + if g:NERDTreeCascadeOpenSingleChildDir ==# 0 call self.open(opts) else call self.openAlong(opts) @@ -699,6 +716,7 @@ function! s:TreeDirNode.transplantChild(newNode) break endif endfor + call self.refresh() endfunction " vim: set sw=4 sts=4 et fdm=marker: diff --git a/lib/nerdtree/tree_file_node.vim b/lib/nerdtree/tree_file_node.vim index c14f62a9..957b98ac 100644 --- a/lib/nerdtree/tree_file_node.vim +++ b/lib/nerdtree/tree_file_node.vim @@ -1,7 +1,7 @@ " ============================================================================ " CLASS: TreeFileNode " -" This class is the parent of the "TreeDirNode" class and is the "Component" +" This class is the parent of the TreeDirNode class and is the 'Component' " part of the composite design pattern between the NERDTree node classes. " ============================================================================ @@ -42,7 +42,7 @@ function! s:TreeFileNode.cacheParent() if empty(self.parent) let parentPath = self.path.getParent() if parentPath.equals(self.path) - throw "NERDTree.CannotCacheParentError: already at root" + throw 'NERDTree.CannotCacheParentError: already at root' endif let self.parent = s:TreeFileNode.New(parentPath, self.getNerdtree()) endif @@ -195,7 +195,7 @@ endfunction " FUNCTION: TreeFileNode.isRoot() {{{1 function! s:TreeFileNode.isRoot() if !g:NERDTree.ExistsForBuf() - throw "NERDTree.NoTreeError: No tree exists for the current buffer" + throw 'NERDTree.NoTreeError: No tree exists for the current buffer' endif return self.equals(self.getNerdtree().root) @@ -248,8 +248,8 @@ endfunction " FUNCTION: TreeFileNode.openExplorer() function! s:TreeFileNode.openExplorer() - execute "wincmd p" - execute "edit ".self.path.getParent().str({'format':'Edit'}) + execute 'wincmd p' + execute 'edit '.self.path.getParent().str({'format':'Edit'}) endfunction " FUNCTION: TreeFileNode.putCursorHere(isJump, recurseUpward){{{1 @@ -265,7 +265,7 @@ function! s:TreeFileNode.putCursorHere(isJump, recurseUpward) if a:isJump mark ' endif - call cursor(ln, col(".")) + call cursor(ln, col('.')) else if a:recurseUpward let node = self @@ -317,17 +317,13 @@ endfunction " child nodes are rendered only) " for each depth in the tree function! s:TreeFileNode._renderToString(depth, drawText) - let output = "" + let output = '' if a:drawText ==# 1 let treeParts = repeat(' ', a:depth - 1) - - if !self.path.isDirectory - let treeParts = treeParts . ' ' - endif + let treeParts .= (self.path.isDirectory || g:NERDTreeDirArrowExpandable ==# '' ? '' : ' ') let line = treeParts . self.displayString() - let output = output . line . "\n" endif diff --git a/lib/nerdtree/ui.vim b/lib/nerdtree/ui.vim index 5e8b3b64..867e04b1 100644 --- a/lib/nerdtree/ui.vim +++ b/lib/nerdtree/ui.vim @@ -27,94 +27,100 @@ function! s:UI._dumpHelp() 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" + let help .= '" '. (g:NERDTreeMouseMode ==# 3 ? 'single' : 'double') ."-click,\n" if self.nerdtree.isTabTree() - let help .= "\" ". g:NERDTreeMapActivateNode .": open in prev window\n" + let help .= '" '. g:NERDTreeMapActivateNode .": open in prev window\n" else - let help .= "\" ". g:NERDTreeMapActivateNode .": open in current window\n" + let help .= '" '. g:NERDTreeMapActivateNode .": open in current window\n" endif if self.nerdtree.isTabTree() - let help .= "\" ". g:NERDTreeMapPreview .": preview\n" + 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 .= '" '. 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 .= '" '. 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 .= '" '. (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 .= '" '. 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 .= '" '. g:NERDTreeMapJumpBookmarks .": jump to bookmark table\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: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 .= '" '. 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 .= '" '. 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 .= '" '. 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 .= '" '. 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 .= '" '. 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 .= '" '. 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" + 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" + let help .= '" '. g:NERDTreeMapToggleFileLines .': files lines (' . (self.getShowFileLines() ? '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" + 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 .= '" '. 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 .= '" '. g:NERDTreeMapHelp .": toggle help\n" let help .= "\"\n\" ----------------------------\n" let help .= "\" Bookmark commands~\n" let help .= "\" :Bookmark []\n" @@ -128,7 +134,7 @@ function! s:UI._dumpHelp() let help .= "\" :EditBookmarks\n" silent! put =help elseif !self.isMinimal() - let help ="\" Press ". g:NERDTreeMapHelp ." for help\n" + let help ='" Press '. g:NERDTreeMapHelp ." for help\n" silent! put =help endif endfunction @@ -143,13 +149,14 @@ function! s:UI.New(nerdtree) let newObj._showFiles = g:NERDTreeShowFiles let newObj._showHidden = g:NERDTreeShowHidden let newObj._showBookmarks = g:NERDTreeShowBookmarks + let newObj._showFileLines = g:NERDTreeFileLines 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 +" 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) @@ -157,7 +164,7 @@ function! s:UI.getPath(ln) let rootLine = self.getRootLineNum() - if a:ln == rootLine + if a:ln ==# rootLine return self.nerdtree.root.path endif @@ -174,7 +181,7 @@ function! s:UI.getPath(ln) " remove the tree parts and the leading space let curFile = self._stripMarkup(line) - let dir = "" + let dir = '' let lnum = a:ln while lnum > 0 let lnum = lnum - 1 @@ -182,7 +189,7 @@ function! s:UI.getPath(ln) let curLineStripped = self._stripMarkup(curLine) " have we reached the top of the tree? - if lnum == rootLine + if lnum ==# rootLine let dir = self.nerdtree.root.path.str({'format': 'UI'}) . dir break endif @@ -191,7 +198,7 @@ function! s:UI.getPath(ln) if lpindent < indent let indent = indent - 1 - let dir = substitute (curLineStripped,'^\\', "", "") . dir + let dir = substitute (curLineStripped,'^\\', '', '') . dir continue endif endif @@ -219,17 +226,17 @@ function! s:UI.getLineNum(node) let l:currentLine = getline(l:lineNumber) let l:indentLevel = self._indentLevelFor(l:currentLine) - if l:indentLevel != l:currentPathComponent + 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 + " 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 + if l:fullPath[-1:] ==# '/' && stridx(l:currentPath, l:fullPath) ==# 0 return l:lineNumber endif @@ -240,7 +247,7 @@ function! s:UI.getLineNum(node) " 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:] == '/' + 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 @@ -280,11 +287,20 @@ function! s:UI.getShowHidden() return self._showHidden endfunction +" FUNCTION: s:UI.getShowFileLines() {{{1 +function! s:UI.getShowFileLines() + return self._showFileLines +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. - let l:line = substitute(substitute(a:line, '\V'.g:NERDTreeDirArrowExpandable, ' ', ''), '\V'.g:NERDTreeDirArrowCollapsible, ' ', '') + 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 @@ -296,7 +312,7 @@ endfunction " FUNCTION: s:UI.isIgnoreFilterEnabled() {{{1 function! s:UI.isIgnoreFilterEnabled() - return self._ignoreEnabled == 1 + return self._ignoreEnabled ==# 1 endfunction " FUNCTION: s:UI.isMinimal() {{{1 @@ -313,21 +329,21 @@ endfunction function! s:UI._renderBookmarks() if !self.isMinimal() - call setline(line(".")+1, ">----------Bookmarks----------") - call cursor(line(".")+1, col(".")) + call setline(line('.')+1, '>----------Bookmarks----------') + call cursor(line('.')+1, col('.')) endif - if g:NERDTreeBookmarksSort == 1 || g:NERDTreeBookmarksSort == 2 + 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(".")) + call setline(line('.')+1, i.str()) + call cursor(line('.')+1, col('.')) endfor - call setline(line(".")+1, '') - call cursor(line(".")+1, col(".")) + call setline(line('.')+1, '') + call cursor(line('.')+1, col('.')) endfunction " FUNCTION: s:UI.restoreScreenState() {{{1 @@ -340,13 +356,13 @@ function! s:UI.restoreScreenState() if !has_key(self, '_screenState') return endif - call nerdtree#exec("silent vertical resize " . self._screenState['oldWindowSize'], 1) + 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']) + call setpos('.', self._screenState['oldPos']) let &scrolloff=old_scrolloff endfunction @@ -358,10 +374,10 @@ function! s:UI.saveScreenState() 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) + let self._screenState['oldPos'] = getpos('.') + let self._screenState['oldTopLine'] = line('w0') + let self._screenState['oldWindowSize'] = winnr('$')==1 ? g:NERDTreeWinSize : winwidth('') + call nerdtree#exec(win . 'wincmd w', 1) catch endtry endfunction @@ -387,9 +403,9 @@ function! s:UI.render() " 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") + 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 _ @@ -398,8 +414,8 @@ function! s:UI.render() " delete the blank line before the help and add one after it if !self.isMinimal() - call setline(line(".")+1, "") - call cursor(line(".")+1, col(".")) + call setline(line('.')+1, '') + call cursor(line('.')+1, col('.')) endif if self.getShowBookmarks() @@ -408,14 +424,14 @@ function! s:UI.render() " add the 'up a dir' line if !self.isMinimal() - call setline(line(".")+1, s:UI.UpDirLine()) - call cursor(line(".")+1, col(".")) + 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(".")) + call setline(line('.')+1, header) + call cursor(line('.')+1, col('.')) " draw the tree silent put =self.nerdtree.root.renderToString() @@ -443,13 +459,13 @@ function! s:UI.renderViewSavingPosition() " 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() + while currentNode !=# {} && !currentNode.isVisible() && !currentNode.isRoot() let currentNode = currentNode.parent endwhile call self.render() - if currentNode != {} + if currentNode !=# {} call currentNode.putCursorHere(0, 0) endif endfunction @@ -467,10 +483,10 @@ function! s:UI.toggleIgnoreFilter() 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 +" FUNCTION: s:UI.setShowBookmarks() {{{1 +" Sets the visibility of the Bookmark table. +function! s:UI.setShowBookmarks(value) + let self._showBookmarks = a:value if self.getShowBookmarks() call self.nerdtree.render() @@ -488,6 +504,12 @@ function! s:UI.toggleShowBookmarks() call self.centerView() endfunction +" FUNCTION: s:UI.toggleShowBookmarks() {{{1 +" Toggle the visibility of the Bookmark table. +function! s:UI.toggleShowBookmarks() + call self.setShowBookmarks(!self._showBookmarks) +endfunction + " FUNCTION: s:UI.toggleShowFiles() {{{1 " toggles the display of hidden files function! s:UI.toggleShowFiles() @@ -504,15 +526,26 @@ function! s:UI.toggleShowHidden() call self.centerView() endfunction +" FUNCTION: s:UI.toggleShowFileLines() {{{1 +" toggles the display of file lines +function! s:UI.toggleShowFileLines() + let self._showFileLines = !self._showFileLines + call self.nerdtree.root.refresh() + 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) + if exists('b:NERDTreeZoomed') && b:NERDTreeZoomed + setlocal nowinfixwidth + wincmd = + setlocal winfixwidth + call nerdtree#exec('silent vertical resize '. g:NERDTreeWinSize, 1) let b:NERDTreeZoomed = 0 else - call nerdtree#exec("vertical resize ". get(g:, 'NERDTreeWinSizeMax', ''), 1) + call nerdtree#exec('vertical resize '. get(g:, 'NERDTreeWinSizeMax', ''), 1) let b:NERDTreeZoomed = 1 endif endfunction diff --git a/nerdtree_plugin/exec_menuitem.vim b/nerdtree_plugin/exec_menuitem.vim index c53650a5..fb6c4862 100644 --- a/nerdtree_plugin/exec_menuitem.vim +++ b/nerdtree_plugin/exec_menuitem.vim @@ -9,7 +9,7 @@ " See http://sam.zoy.org/wtfpl/COPYING for more details. " " ============================================================================ -if exists("g:loaded_nerdtree_exec_menuitem") +if exists('g:loaded_nerdtree_exec_menuitem') finish endif let g:loaded_nerdtree_exec_menuitem = 1 @@ -32,9 +32,9 @@ function! NERDTreeExecFile() let cmd = treenode.path.str({'escape': 1}) let cmd = input(':!', cmd . ' ') - if cmd != '' + if cmd !=# '' exec ':!' . cmd else - echo "Aborted" + echo 'Aborted' endif endfunction diff --git a/nerdtree_plugin/fs_menu.vim b/nerdtree_plugin/fs_menu.vim index 0a5de8a4..dfba62a8 100644 --- a/nerdtree_plugin/fs_menu.vim +++ b/nerdtree_plugin/fs_menu.vim @@ -9,13 +9,13 @@ " See http://sam.zoy.org/wtfpl/COPYING for more details. " " ============================================================================ -if exists("g:loaded_nerdtree_fs_menu") +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") +if !exists('g:NERDTreeAutoDeleteBuffer') let g:NERDTreeAutoDeleteBuffer = 0 endif @@ -23,65 +23,75 @@ call NERDTreeAddMenuItem({'text': '(a)dd a childnode', 'shortcut': 'a', 'callbac call NERDTreeAddMenuItem({'text': '(m)ove the current node', 'shortcut': 'm', 'callback': 'NERDTreeMoveNode'}) call NERDTreeAddMenuItem({'text': '(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'}) +if nerdtree#runningMac() + call NERDTreeAddMenuItem({'text': '(r)eveal the current node in the Finder', '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") +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 nerdtree#runningWindows() + call NERDTreeAddMenuItem({'text': '(r)eveal the current node in the Explorer', 'shortcut': 'r', 'callback': 'NERDTreeRevealInExplorer'}) + call NERDTreeAddMenuItem({'text': '(o)pen the current node with system editor', 'shortcut': 'o', 'callback': 'NERDTreeExecuteFileWindows'}) +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'}) +call NERDTreeAddMenuItem({'text': (has('clipboard')?'copy (p)ath to clipboard':'print (p)ath to screen'), 'shortcut': 'p', 'callback': 'NERDTreeCopyPath'}) -if has("unix") || has("osx") +if has('unix') || has('osx') call NERDTreeAddMenuItem({'text': '(l)ist the current node', 'shortcut': 'l', 'callback': 'NERDTreeListNode'}) + call NERDTreeAddMenuItem({'text': '(C)hange node permissions', 'shortcut':'C', 'callback': 'NERDTreeChangePermissions'}) else call NERDTreeAddMenuItem({'text': '(l)ist the current node', 'shortcut': 'l', 'callback': 'NERDTreeListNodeWin32'}) endif +if exists('*system') + call NERDTreeAddMenuItem({'text': 'Run (s)ystem command in this directory', 'shortcut':'s', 'callback': 'NERDTreeSystemCommand'}) +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" + 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:" + 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 ==# '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 ==# '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" + 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?" + 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:" + 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 . " " + return minimal . ' ' else - let divider = "==========================================================" + let divider = '==========================================================' return title . "\n" . divider . "\n" . info . "\n" end endfunction @@ -114,14 +124,14 @@ function! s:promptToDelBuffer(bufnum, msg) let l:listedBufferCount = 0 endif if l:listedBufferCount > 1 - call nerdtree#exec("tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':bnext! ' | endif", 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) + 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) + 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) + call nerdtree#exec('bwipeout! ' . a:bufnum, 0) endif endfunction @@ -140,18 +150,38 @@ function! s:renameBuffer(bufNum, newNodeName, isDirectory) 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, 1) - " 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", 1) - call nerdtree#exec("tabnext " . s:originalTabNumber, 1) - call nerdtree#exec(s:originalWindowNumber . "wincmd w", 1) - " 3. We don't need a previous buffer anymore + let l:tempBufferName = 'NERDTreeRenameTempBuffer' + + " 1. swap deleted file buffer with a temporary one + " this step is needed to compensate for case insensitive filesystems + + " 1.1. create an intermediate(temporary) buffer + call nerdtree#exec('badd ' . l:tempBufferName, 0) + let l:tempBufNum = bufnr(l:tempBufferName) + " 1.2. ensure that all windows which display the just deleted filename + " display the new temp buffer. + call nerdtree#exec('tabdo windo if winbufnr(0) ==# ' . a:bufNum . " | exec ':e! " . l:tempBufferName . "' | endif", 0) + " 1.3. We don't need the deleted file buffer anymore try - call nerdtree#exec("confirm bwipeout " . a:bufNum, 0) + call nerdtree#exec('confirm bwipeout ' . a:bufNum, 0) + catch + " This happens when answering Cancel if confirmation is needed. Do nothing. + endtry + + " 2. swap temporary buffer with the new filename buffer + " 2.1. create the actual new file buffer + call nerdtree#exec('badd ' . quotedFileName, 0) + + " 2.2. ensure that all windows which display the temporary buffer + " display a buffer for the new filename. + call nerdtree#exec('tabdo windo if winbufnr(0) ==# ' . l:tempBufNum . " | exec ':e! " . editStr . "' | endif", 0) + call nerdtree#exec('tabnext ' . s:originalTabNumber, 1) + call nerdtree#exec(s:originalWindowNumber . 'wincmd w', 1) + " 2.3. We don't need the temporary buffer anymore + try + call nerdtree#exec('confirm bwipeout ' . l:tempBufNum, 0) catch " This happens when answering Cancel if confirmation is needed. Do nothing. endtry @@ -160,11 +190,11 @@ 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") + let prompt = s:inputPrompt('add') + let newNodeName = substitute(input(prompt, curDirNode.path.str() . nerdtree#slash(), 'file'), '\(^\s*\|\s*$\)', '', 'g') if newNodeName ==# '' - call nerdtree#echo("Node Creation Aborted.") + call nerdtree#echo('Node Creation Aborted.') return endif @@ -181,32 +211,56 @@ function! NERDTreeAddNode() call b:NERDTree.render() elseif parentNode.isOpen || !empty(parentNode.children) call parentNode.addChild(newTreeNode, 1) + call g:NERDTreePathNotifier.NotifyListeners('init', newTreeNode.path, newTreeNode.getNerdtree(), {}) call NERDTreeRender() call newTreeNode.putCursorHere(1, 0) endif redraw! catch /^NERDTree/ - call nerdtree#echoWarning("Node Not Created.") + 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") + let prompt = s:inputPrompt('move') + let newNodePath = input(prompt, curNode.path.str(), 'file') + while filereadable(newNodePath) + " allow renames with different casing when g:NERDTreeCaseSensitiveFS + " is set to either 0 or 3 and the 2 paths are equal + if (g:NERDTreeCaseSensitiveFS == 0 || g:NERDTreeCaseSensitiveFS == 3) && + \nerdtree#pathEquals(curNode.path.str(), newNodePath) + break + endif + + call nerdtree#echoWarning('This destination already exists, Try again.') + + " inform the user about the flag if we think it is a false positive + " when g:NERDTreeCaseSensitiveFS is set to 2 + if g:NERDTreeCaseSensitiveFS == 2 && + \!nerdtree#osDefaultCaseSensitiveFS() && + \nerdtree#pathEquals(curNode.path.str(), newNodePath) + echon "\n(If it is a false positive please consider assigning NERDTreeCaseSensitiveFS's value)" + endif + + " prompt the user again + let newNodePath = substitute(input(prompt, curNode.path.str(), 'file'), '\(^\s*\|\s*$\)', '', 'g') + endwhile + if newNodePath ==# '' - call nerdtree#echo("Node Renaming Aborted.") + 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() . "/.*"') + let l:curPath = escape(curNode.path.str(),'\') . (nerdtree#runningWindows()?'\\':'/') . '.*' + let l:openBuffers = filter(range(1,bufnr('$')),'bufexists(v:val) && fnamemodify(bufname(v:val),":p") =~# "'.escape(l:curPath,'\').'"') else - let l:openBuffers = filter(range(1,bufnr("$")),'bufexists(v:val) && fnamemodify(bufname(v:val),":p") ==# curNode.path.str()') + let l:openBuffers = filter(range(1,bufnr('$')),'bufexists(v:val) && fnamemodify(bufname(v:val),":p") ==# curNode.path.str()') endif call curNode.rename(newNodePath) @@ -221,9 +275,9 @@ function! NERDTreeMoveNode() " 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)" + 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)" + 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 @@ -236,24 +290,22 @@ function! NERDTreeMoveNode() redraw! catch /^NERDTree/ - call nerdtree#echoWarning("Node Not Renamed.") + 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 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): " + let prompt = s:inputPrompt('delete') . currentNode.path.str() . ' (yN): ' echo prompt let choice = nr2char(getchar()) let confirmed = choice ==# 'y' @@ -266,30 +318,29 @@ function! NERDTreeDeleteNode() "if the node is open in a buffer, ask the user if they want to "close that buffer - let bufnum = bufnr("^".currentNode.path.str()."$") + 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)" + 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") + call nerdtree#echoWarning('Could not remove node') endtry else - call nerdtree#echo("delete aborted") + 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 s:uname = system('uname') let stat_cmd = 'stat -c "%s" ' - if s:uname =~? "Darwin" + if s:uname =~? 'Darwin' let stat_cmd = 'stat -f "%z" ' endif @@ -300,7 +351,7 @@ function! NERDTreeListNode() let metadata = split(system(cmd),'\n') call nerdtree#echo(metadata[0]) else - call nerdtree#echo("No information available") + call nerdtree#echo('No information available') endif endfunction @@ -310,10 +361,10 @@ function! NERDTreeListNodeWin32() if !empty(l:node) let l:path = l:node.path.str() - call nerdtree#echo(printf("%s:%s MOD:%s BYTES:%d PERMISSIONS:%s", + 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)), + \ strftime('%c', getftime(l:path)), \ getfsize(l:path), \ getfperm(l:path))) return @@ -322,21 +373,42 @@ function! NERDTreeListNodeWin32() call nerdtree#echo('node not recognized') endfunction +" FUNCTION: NERDTreeChangePermissions() {{{1 +function! NERDTreeChangePermissions() + let l:node = g:NERDTreeFileNode.GetSelected() + let l:prompt = "change node permissions (chmod args): " + let l:newNodePerm = input(l:prompt) + + if !empty(l:node) + let l:path = l:node.path.str() + let l:cmd = 'chmod ' .. newNodePerm .. ' ' .. path + let l:error = split(system(l:cmd), '\n') + + if !empty(l:error) + call nerdtree#echo(l:error[0]) + endif + + call b:NERDTree.root.refresh() + call b:NERDTree.render() + 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") + let prompt = s:inputPrompt('copy') + let newNodePath = substitute(input(prompt, currentNode.path.str(), 'file'), '\(^\s*\|\s*$\)', '', 'g') - if newNodePath != "" + 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)") + call nerdtree#echo('Warning: copying may overwrite files! Continue? (yN)') let choice = nr2char(getchar()) let confirmed = choice ==# 'y' endif @@ -355,67 +427,132 @@ function! NERDTreeCopyNode() call newNode.putCursorHere(0, 0) endif catch /^NERDTree/ - call nerdtree#echoWarning("Could not copy node") + call nerdtree#echoWarning('Could not copy node') endtry endif else - call nerdtree#echo("Copy aborted.") + 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") - let @* = l:nodePath - call nerdtree#echo("The path [" . l:nodePath . "] was copied to your clipboard.") + 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) + 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() . "'") + let l:node = g:NERDTreeFileNode.GetSelected() + + if empty(l:node) + return endif + + call system('qlmanage -p 2>/dev/null ' . shellescape(l:node.path.str())) endfunction " FUNCTION: NERDTreeRevealInFinder() {{{1 function! NERDTreeRevealInFinder() - let treenode = g:NERDTreeFileNode.GetSelected() - if treenode != {} - call system("open -R '" . treenode.path.str() . "'") + let l:node = g:NERDTreeFileNode.GetSelected() + + if empty(l:node) + return endif + + call system('open -R ' . shellescape(l:node.path.str())) endfunction " FUNCTION: NERDTreeExecuteFile() {{{1 function! NERDTreeExecuteFile() - let treenode = g:NERDTreeFileNode.GetSelected() - if treenode != {} - call system("open '" . treenode.path.str() . "'") + let l:node = g:NERDTreeFileNode.GetSelected() + + if empty(l:node) + return endif + + call system('open ' . shellescape(l:node.path.str())) endfunction " FUNCTION: NERDTreeRevealFileLinux() {{{1 function! NERDTreeRevealFileLinux() - let treenode = g:NERDTreeFileNode.GetSelected() - let parentnode = treenode.parent - if parentnode != {} - call system("xdg-open '" . parentnode.path.str() . "' &") + let l:node = g:NERDTreeFileNode.GetSelected() + + if empty(l:node) + return + endif + + " Handle the edge case of "/", which has no parent. + if l:node.path.str() ==# '/' + call system('xdg-open /') + return endif + + if empty(l:node.parent) + return + endif + + call system('xdg-open ' . shellescape(l:node.parent.path.str())) endfunction " FUNCTION: NERDTreeExecuteFileLinux() {{{1 function! NERDTreeExecuteFileLinux() - let treenode = g:NERDTreeFileNode.GetSelected() - if treenode != {} - call system("xdg-open '" . treenode.path.str() . "' &") + let l:node = g:NERDTreeFileNode.GetSelected() + + if empty(l:node) + return endif + + call system('xdg-open ' . shellescape(l:node.path.str())) endfunction -" vim: set sw=4 sts=4 et fdm=marker: +" FUNCTION: NERDTreeRevealInExplorer() {{{1 +function! NERDTreeRevealInExplorer() + let l:node = g:NERDTreeFileNode.GetSelected() + if empty(l:node) + return + endif + + call system('cmd.exe /c explorer /select, ' . shellescape(l:node.path.str())) +endfunction + +" FUNCTION: NERDTreeExecuteFileWindows() {{{1 +function! NERDTreeExecuteFileWindows() + let l:node = g:NERDTreeFileNode.GetSelected() + + if empty(l:node) + return + endif + + call system('cmd.exe /c start "" ' . shellescape(l:node.path.str())) +endfunction + +" FUNCTION: NERDTreeSystemCommand() {{{1 +function! NERDTreeSystemCommand() + let l:node = g:NERDTreeFileNode.GetSelected() + + if empty(l:node) + return + endif + + let l:cwd = getcwd() + let l:directory = l:node.path.isDirectory ? l:node.path.str() : l:node.parent.path.str() + execute 'cd '.l:directory + + let l:nl = nr2char(10) + echo l:nl . system(input(l:directory . (nerdtree#runningWindows() ? '> ' : ' $ '))) + execute 'cd '.l:cwd +endfunction + +" vim: set sw=4 sts=4 et fdm=marker: diff --git a/nerdtree_plugin/vcs.vim b/nerdtree_plugin/vcs.vim index c30579ae..d20e35e5 100644 --- a/nerdtree_plugin/vcs.vim +++ b/nerdtree_plugin/vcs.vim @@ -11,12 +11,21 @@ " " ============================================================================ command! -n=? -complete=dir -bar NERDTreeVCS :call CreateTabTreeVCS('') +command! -n=? -complete=dir -bar NERDTreeToggleVCS :call ToggleTabTreeVCS('') " 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()) + 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 @@ -25,7 +34,7 @@ endfunction function! s:FindParentVCSRoot(path) let l:path = a:path while !empty(l:path) && - \ l:path._str() !~ '^\(\a:\\\|\/\)$' && + \ l:path._str() !~# '^\(\a:[\\\/]\|\/\)$' && \ !isdirectory(l:path._str() . '/.git') && \ !isdirectory(l:path._str() . '/.svn') && \ !isdirectory(l:path._str() . '/.hg') && @@ -33,6 +42,6 @@ function! s:FindParentVCSRoot(path) \ !isdirectory(l:path._str() . '/_darcs') let l:path = l:path.getParent() endwhile - return (empty(l:path) || l:path._str() =~ '^\(\a:\\\|\/\)$') ? a:path : l:path + return (empty(l:path) || l:path._str() =~# '^\(\a:[\\\/]\|\/\)$') ? a:path : l:path endfunction diff --git a/plugin/NERD_tree.vim b/plugin/NERD_tree.vim index 5faebaaf..84c04fda 100644 --- a/plugin/NERD_tree.vim +++ b/plugin/NERD_tree.vim @@ -11,7 +11,9 @@ " " SECTION: Script init stuff {{{1 "============================================================ -if exists("loaded_nerd_tree") +scriptencoding utf-8 + +if exists('loaded_nerd_tree') finish endif if v:version < 703 @@ -20,145 +22,123 @@ if v:version < 703 endif let loaded_nerd_tree = 1 -"for line continuation - i.e dont want C in &cpo -let s:old_cpo = &cpo -set cpo&vim +"for line continuation - i.e dont want C in &cpoptions +let s:old_cpo = &cpoptions +set cpoptions&vim + +"SECTION: Initialize variable calls and other random constants {{{2 +let g:NERDTreeAutoCenter = get(g:, 'NERDTreeAutoCenter', 1) +let g:NERDTreeAutoCenterThreshold = get(g:, 'NERDTreeAutoCenterThreshold', 3) +let g:NERDTreeCaseSensitiveFS = get(g:, 'NERDTreeCaseSensitiveFS', 2) +let g:NERDTreeCaseSensitiveSort = get(g:, 'NERDTreeCaseSensitiveSort', 0) +let g:NERDTreeNaturalSort = get(g:, 'NERDTreeNaturalSort', 0) +let g:NERDTreeSortHiddenFirst = get(g:, 'NERDTreeSortHiddenFirst', 1) +let g:NERDTreeUseTCD = get(g:, 'NERDTreeUseTCD', 0) +let g:NERDTreeChDirMode = get(g:, 'NERDTreeChDirMode', 0) +let g:NERDTreeCreatePrefix = get(g:, 'NERDTreeCreatePrefix', 'silent') +let g:NERDTreeMinimalUI = get(g:, 'NERDTreeMinimalUI', 0) +let g:NERDTreeMinimalMenu = get(g:, 'NERDTreeMinimalMenu', 0) +let g:NERDTreeIgnore = get(g:, 'NERDTreeIgnore', ['\~$']) +let g:NERDTreeBookmarksFile = get(g:, 'NERDTreeBookmarksFile', expand('$HOME') . '/.NERDTreeBookmarks') +let g:NERDTreeBookmarksSort = get(g:, 'NERDTreeBookmarksSort', 1) +let g:NERDTreeHighlightCursorline = get(g:, 'NERDTreeHighlightCursorline', 1) +let g:NERDTreeHijackNetrw = get(g:, 'NERDTreeHijackNetrw', 1) +let g:NERDTreeMarkBookmarks = get(g:, 'NERDTreeMarkBookmarks', 1) +let g:NERDTreeMouseMode = get(g:, 'NERDTreeMouseMode', 1) +let g:NERDTreeNotificationThreshold = get(g:, 'NERDTreeNotificationThreshold', 100) +let g:NERDTreeQuitOnOpen = get(g:, 'NERDTreeQuitOnOpen', 0) +let g:NERDTreeRespectWildIgnore = get(g:, 'NERDTreeRespectWildIgnore', 0) +let g:NERDTreeShowBookmarks = get(g:, 'NERDTreeShowBookmarks', 0) +let g:NERDTreeShowFiles = get(g:, 'NERDTreeShowFiles', 1) +let g:NERDTreeShowHidden = get(g:, 'NERDTreeShowHidden', 0) +let g:NERDTreeShowLineNumbers = get(g:, 'NERDTreeShowLineNumbers', 0) +let g:NERDTreeSortDirs = get(g:, 'NERDTreeSortDirs', 1) +let g:NERDTreeFileLines = get(g:, 'NERDTreeFileLines', 0) -"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", "▾") + let g:NERDTreeDirArrowExpandable = get(g:, 'NERDTreeDirArrowExpandable', '▸') + let g:NERDTreeDirArrowCollapsible = get(g:, 'NERDTreeDirArrowCollapsible', '▾') else - call s:initVariable("g:NERDTreeDirArrowExpandable", "+") - call s:initVariable("g:NERDTreeDirArrowCollapsible", "~") + let g:NERDTreeDirArrowExpandable = get(g:, 'NERDTreeDirArrowExpandable', '+') + let g:NERDTreeDirArrowCollapsible = get(g:, 'NERDTreeDirArrowCollapsible', '~') endif -call s:initVariable("g:NERDTreeCascadeOpenSingleChildDir", 1) -call s:initVariable("g:NERDTreeCascadeSingleChildDir", 1) +let g:NERDTreeCascadeOpenSingleChildDir = get(g:, 'NERDTreeCascadeOpenSingleChildDir', 1) +let g:NERDTreeCascadeSingleChildDir = get(g:, 'NERDTreeCascadeSingleChildDir', 1) -if !exists("g:NERDTreeSortOrder") - let g:NERDTreeSortOrder = ['\/$', '*', '\.swp$', '\.bak$', '\~$'] -endif +let g:NERDTreeSortOrder = get(g:, 'NERDTreeSortOrder', ['\/$', '*', '\.swp$', '\.bak$', '\~$']) let g:NERDTreeOldSortOrder = [] -call s:initVariable("g:NERDTreeGlyphReadOnly", "RO") +let g:NERDTreeGlyphReadOnly = get(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") +if has('conceal') + let g:NERDTreeNodeDelimiter = get(g:, 'NERDTreeNodeDelimiter', "\x07") +elseif (g:NERDTreeDirArrowExpandable ==# "\u00a0" || g:NERDTreeDirArrowCollapsible ==# "\u00a0") + let g:NERDTreeNodeDelimiter = get(g:, 'NERDTreeNodeDelimiter', "\u00b7") else - call s:initVariable("g:NERDTreeNodeDelimiter", "\u00a0") + let g:NERDTreeNodeDelimiter = get(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():''}" +"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 = get(g:, 'NERDTreeStatusline', "%{exists('b:NERDTree')?b:NERDTree.root.path.str():''}") -endif -call s:initVariable("g:NERDTreeWinPos", "left") -call s:initVariable("g:NERDTreeWinSize", 31) +let g:NERDTreeWinPos = get(g:, 'NERDTreeWinPos', 'left') +let g:NERDTreeWinSize = get(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 ') + let g:NERDTreeRemoveDirCmd = get(g:, 'NERDTreeRemoveDirCmd', 'rmdir /s /q ') + let g:NERDTreeCopyDirCmd = get(g:, 'NERDTreeCopyDirCmd', 'xcopy /s /e /i /y /q ') + let g:NERDTreeCopyFileCmd = get(g:, 'NERDTreeCopyFileCmd', 'copy /y ') else - call s:initVariable("g:NERDTreeRemoveDirCmd", 'rm -rf ') - call s:initVariable("g:NERDTreeCopyCmd", 'cp -r ') + let g:NERDTreeRemoveDirCmd = get(g:, 'NERDTreeRemoveDirCmd', 'rm -rf ') + let g:NERDTreeCopyCmd = get(g:, 'NERDTreeCopyCmd', 'cp -r ') endif - "SECTION: Init variable calls for key mappings {{{2 -call s:initVariable("g:NERDTreeMapCustomOpen", "") -call s:initVariable("g:NERDTreeMapActivateNode", "o") -call s:initVariable("g:NERDTreeMapChangeRoot", "C") -call s:initVariable("g:NERDTreeMapChdir", "cd") -call s:initVariable("g:NERDTreeMapCloseChildren", "X") -call s:initVariable("g:NERDTreeMapCloseDir", "x") -call s:initVariable("g:NERDTreeMapDeleteBookmark", "D") -call s:initVariable("g:NERDTreeMapMenu", "m") -call s:initVariable("g:NERDTreeMapHelp", "?") -call s:initVariable("g:NERDTreeMapJumpFirstChild", "K") -call s:initVariable("g:NERDTreeMapJumpLastChild", "J") -call s:initVariable("g:NERDTreeMapJumpNextSibling", "") -call s:initVariable("g:NERDTreeMapJumpParent", "p") -call s:initVariable("g:NERDTreeMapJumpPrevSibling", "") -call s:initVariable("g:NERDTreeMapJumpRoot", "P") -call s:initVariable("g:NERDTreeMapOpenExpl", "e") -call s:initVariable("g:NERDTreeMapOpenInTab", "t") -call s:initVariable("g:NERDTreeMapOpenInTabSilent", "T") -call s:initVariable("g:NERDTreeMapOpenRecursively", "O") -call s:initVariable("g:NERDTreeMapOpenSplit", "i") -call s:initVariable("g:NERDTreeMapOpenVSplit", "s") -call s:initVariable("g:NERDTreeMapPreview", "g" . NERDTreeMapActivateNode) -call s:initVariable("g:NERDTreeMapPreviewSplit", "g" . NERDTreeMapOpenSplit) -call s:initVariable("g:NERDTreeMapPreviewVSplit", "g" . NERDTreeMapOpenVSplit) -call s:initVariable("g:NERDTreeMapQuit", "q") -call s:initVariable("g:NERDTreeMapRefresh", "r") -call s:initVariable("g:NERDTreeMapRefreshRoot", "R") -call s:initVariable("g:NERDTreeMapToggleBookmarks", "B") -call s:initVariable("g:NERDTreeMapToggleFiles", "F") -call s:initVariable("g:NERDTreeMapToggleFilters", "f") -call s:initVariable("g:NERDTreeMapToggleHidden", "I") -call s:initVariable("g:NERDTreeMapToggleZoom", "A") -call s:initVariable("g:NERDTreeMapUpdir", "u") -call s:initVariable("g:NERDTreeMapUpdirKeepOpen", "U") -call s:initVariable("g:NERDTreeMapCWD", "CD") -call s:initVariable("g:NERDTreeMenuDown", "j") -call s:initVariable("g:NERDTreeMenuUp", "k") +let g:NERDTreeMapCustomOpen = get(g:, 'NERDTreeMapCustomOpen', '') +let g:NERDTreeMapJumpBookmarks = get(g:, 'NERDTreeMapJumpBookmarks', 'gb') +let g:NERDTreeMapActivateNode = get(g:, 'NERDTreeMapActivateNode', 'o') +let g:NERDTreeMapChangeRoot = get(g:, 'NERDTreeMapChangeRoot', 'C') +let g:NERDTreeMapChdir = get(g:, 'NERDTreeMapChdir', 'cd') +let g:NERDTreeMapCloseChildren = get(g:, 'NERDTreeMapCloseChildren', 'X') +let g:NERDTreeMapCloseDir = get(g:, 'NERDTreeMapCloseDir', 'x') +let g:NERDTreeMapDeleteBookmark = get(g:, 'NERDTreeMapDeleteBookmark', 'D') +let g:NERDTreeMapMenu = get(g:, 'NERDTreeMapMenu', 'm') +let g:NERDTreeMapHelp = get(g:, 'NERDTreeMapHelp', '?') +let g:NERDTreeMapJumpFirstChild = get(g:, 'NERDTreeMapJumpFirstChild', 'K') +let g:NERDTreeMapJumpLastChild = get(g:, 'NERDTreeMapJumpLastChild', 'J') +let g:NERDTreeMapJumpNextSibling = get(g:, 'NERDTreeMapJumpNextSibling', '') +let g:NERDTreeMapJumpParent = get(g:, 'NERDTreeMapJumpParent', 'p') +let g:NERDTreeMapJumpPrevSibling = get(g:, 'NERDTreeMapJumpPrevSibling', '') +let g:NERDTreeMapJumpRoot = get(g:, 'NERDTreeMapJumpRoot', 'P') +let g:NERDTreeMapOpenExpl = get(g:, 'NERDTreeMapOpenExpl', 'e') +let g:NERDTreeMapOpenInTab = get(g:, 'NERDTreeMapOpenInTab', 't') +let g:NERDTreeMapOpenInTabSilent = get(g:, 'NERDTreeMapOpenInTabSilent', 'T') +let g:NERDTreeMapOpenRecursively = get(g:, 'NERDTreeMapOpenRecursively', 'O') +let g:NERDTreeMapOpenSplit = get(g:, 'NERDTreeMapOpenSplit', 'i') +let g:NERDTreeMapOpenVSplit = get(g:, 'NERDTreeMapOpenVSplit', 's') +let g:NERDTreeMapPreview = get(g:, 'NERDTreeMapPreview', 'g'.NERDTreeMapActivateNode) +let g:NERDTreeMapPreviewSplit = get(g:, 'NERDTreeMapPreviewSplit', 'g'.NERDTreeMapOpenSplit) +let g:NERDTreeMapPreviewVSplit = get(g:, 'NERDTreeMapPreviewVSplit', 'g'.NERDTreeMapOpenVSplit) +let g:NERDTreeMapQuit = get(g:, 'NERDTreeMapQuit', 'q') +let g:NERDTreeMapRefresh = get(g:, 'NERDTreeMapRefresh', 'r') +let g:NERDTreeMapRefreshRoot = get(g:, 'NERDTreeMapRefreshRoot', 'R') +let g:NERDTreeMapToggleBookmarks = get(g:, 'NERDTreeMapToggleBookmarks', 'B') +let g:NERDTreeMapToggleFiles = get(g:, 'NERDTreeMapToggleFiles', 'F') +let g:NERDTreeMapToggleFilters = get(g:, 'NERDTreeMapToggleFilters', 'f') +let g:NERDTreeMapToggleHidden = get(g:, 'NERDTreeMapToggleHidden', 'I') +let g:NERDTreeMapToggleFileLines = get(g:, 'NERDTreeMapToggleFileLines', 'FL') +let g:NERDTreeMapToggleZoom = get(g:, 'NERDTreeMapToggleZoom', 'A') +let g:NERDTreeMapUpdir = get(g:, 'NERDTreeMapUpdir', 'u') +let g:NERDTreeMapUpdirKeepOpen = get(g:, 'NERDTreeMapUpdirKeepOpen', 'U') +let g:NERDTreeMapCWD = get(g:, 'NERDTreeMapCWD', 'CD') +let g:NERDTreeMenuDown = get(g:, 'NERDTreeMenuDown', 'j') +let g:NERDTreeMenuUp = get(g:, 'NERDTreeMenuUp', 'k') "SECTION: Load class files{{{2 call nerdtree#loadClassFiles() @@ -167,24 +147,25 @@ call nerdtree#loadClassFiles() "============================================================ 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" + exec 'autocmd BufLeave,WinLeave '. g:NERDTreeCreator.BufNamePrefix() .'* call nerdtree#onBufLeave()' "disallow insert mode in the NERDTree - exec "autocmd BufEnter,WinEnter ". g:NERDTreeCreator.BufNamePrefix() ."* stopinsert" + 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("")) + au BufEnter,VimEnter * call nerdtree#checkForBrowse(expand('')) augroup END endif -if g:NERDTreeChDirMode == 3 +if g:NERDTreeChDirMode ==# 3 augroup NERDTreeChDirOnTabSwitch autocmd TabEnter * if g:NERDTree.ExistsForTab()|call g:NERDTree.ForCurrentTab().getRoot().path.changeToDir()|endif augroup END @@ -215,9 +196,9 @@ endfunction function! NERDTreeFocus() if g:NERDTree.IsOpen() - call g:NERDTree.CursorToTreeWin() + call g:NERDTree.CursorToTreeWin(0) else - call g:NERDTreeCreator.ToggleTabTree("") + call g:NERDTreeCreator.ToggleTabTree('') endif endfunction @@ -253,7 +234,7 @@ endfunction " SECTION: Post Source Actions {{{1 call nerdtree#postSourceActions() -"reset &cpo back to users setting -let &cpo = s:old_cpo +"reset &cpoptions back to users setting +let &cpoptions = s:old_cpo " vim: set sw=4 sts=4 et fdm=marker: diff --git a/syntax/nerdtree.vim b/syntax/nerdtree.vim index 99773bf1..6aae6f28 100644 --- a/syntax/nerdtree.vim +++ b/syntax/nerdtree.vim @@ -3,7 +3,7 @@ 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 ."#" +execute "syn match NERDTreeUp #\\V". s:tree_up_dir_line .'#' "quickhelp syntax elements syn match NERDTreeHelpKey #" \{1,2\}[^ ]*:#ms=s+2,me=e-1 @@ -19,36 +19,40 @@ syn match NERDTreeLinkTarget #->.*# containedin=NERDTreeDir,NERDTreeFile syn match NERDTreeLinkFile #.* ->#me=e-3 containedin=NERDTreeFile syn match NERDTreeLinkDir #.*/ ->#me=e-3 containedin=NERDTreeDir -"highlighing for directory nodes and file nodes -syn match NERDTreeDirSlash #/# containedin=NERDTreeDir - -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.' ].*/#' -syn match NERDTreeExecFile #^ .*\*\($\| \)# contains=NERDTreeRO,NERDTreeBookmark -exec 'syn match NERDTreeFile #^[^"\.'.s:dirArrows.'] *[^'.s:dirArrows.']*# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmark,NERDTreeExecFile' - -"highlighting for readonly files -exec 'syn match NERDTreeRO # *\zs.*\ze \['.g:NERDTreeGlyphReadOnly.'\]# contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreeFile' - -syn match NERDTreeFlags #^ *\zs\[[^\]]*\]# containedin=NERDTreeFile,NERDTreeExecFile -syn match NERDTreeFlags #\[[^\]]*\]# containedin=NERDTreeDir - -"highlighing to conceal the delimiter around the file/dir name -if has("conceal") +"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 + setlocal conceallevel=2 concealcursor=nvic else exec 'syn match NERDTreeNodeDelimiters #\%d' . char2nr(g:NERDTreeNodeDelimiter) . '# containedin=ALL' hi! link NERDTreeNodeDelimiters Ignore endif +"highlighting 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,NERDTreeBookmarkName' + exec 'syn match NERDTreeFile #^[^"\.'.s:dirArrows.'] *[^'.s:dirArrows.']*# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmarkName,NERDTreeExecFile' +else + exec 'syn match NERDTreeDir #[^'.g:NERDTreeNodeDelimiter.']\{-}/\ze\($\|'.g:NERDTreeNodeDelimiter.'\)#' + exec 'syn match NERDTreeExecFile #[^'.g:NERDTreeNodeDelimiter.']\{-}'.g:NERDTreeNodeDelimiter.'\*\($\| \)# contains=NERDTreeRO,NERDTreeBookmarkName' + exec 'syn match NERDTreeFile #^.*'.g:NERDTreeNodeDelimiter.'.*[^\/]\($\|'.g:NERDTreeNodeDelimiter.'.*\)# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmarkName,NERDTreeExecFile' +endif + +"highlighting for readonly files +exec 'syn match NERDTreeRO #.*'.g:NERDTreeNodeDelimiter.'\zs.*\ze'.g:NERDTreeNodeDelimiter.'.*\['.g:NERDTreeGlyphReadOnly.'\]# contains=NERDTreeIgnore,NERDTreeBookmarkName,NERDTreeFile' + +exec 'syn match NERDTreeFlags #\[[^\]]*\]\ze'.g:NERDTreeNodeDelimiter.'# containedin=NERDTreeFile,NERDTreeExecFile,NERDTreeLinkFile,NERDTreeRO,NERDTreeDir' + syn match NERDTreeCWD #^[# @@ -89,3 +93,5 @@ hi def link NERDTreeBookmark Statement hi def link NERDTreeFlags Number hi def link NERDTreeCurrentNode Search + +hi NERDTreeFile ctermbg=NONE guibg=NONE