nerdtree

A tree explorer plugin for vim.
Index Commits Files Refs
commit b6e3c0db30aea2875da5d9214f05b6586ac7af7c
parent 97433edd43f3a4a95c84389bcaafbe7a047cf756
Author: Jason Franklin <lifecrisis@users.noreply.github.com>
Date:   Tue, 14 Nov 2017 08:37:09 -0500

Merge pull request #759 from lifecrisis/iss549

This pull request repairs the broken "t" and "T" mappings.
Diffstat:
MCHANGELOG | 1+
Mautoload/nerdtree/ui_glue.vim | 14++++++++------
Mlib/nerdtree/creator.vim | 88+++++++++++++++++++++++++++++++++++++------------------------------------------
Mlib/nerdtree/opener.vim | 66++++++++++++++++++++++++++++++++----------------------------------
Mlib/nerdtree/tree_dir_node.vim | 17++++++++++++-----
Mlib/nerdtree/ui.vim | 2++
6 files changed, 96 insertions(+), 92 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
@@ -1,4 +1,5 @@
 Next
+    - Fix broken "t" and "T" mappings, tabs now open at end (lifecrisis) #759
     - Update doc with already existing mapping variables (asnr) #699
     - Fix the broken g:NERDTreeBookmarksSort setting (lifecrisis) #696
     - Correct NERDTreeIgnore pattern in doc (cntoplolicon) #648
diff --git a/autoload/nerdtree/ui_glue.vim b/autoload/nerdtree/ui_glue.vim
@@ -68,10 +68,10 @@ function! nerdtree#ui_glue#createDefaultBindings()
     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpNextSibling, 'scope': "Node", 'callback': s."jumpToNextSibling" })
     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpPrevSibling, 'scope': "Node", 'callback': s."jumpToPrevSibling" })
 
-    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': "Node", 'callback': s."openInNewTab" })
-    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': "Node", 'callback': s."openInNewTabSilent" })
-    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': "Bookmark", 'callback': s."openInNewTab" })
-    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': "Bookmark", 'callback': s."openInNewTabSilent" })
+    call NERDTreeAddKeyMap({ 'key': g: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" })
 
@@ -494,12 +494,14 @@ endfunction
 
 " FUNCTION: s:openInNewTab(target) {{{1
 function! s:openInNewTab(target)
-    call a:target.activate({'where': 't'})
+    let l:opener = g:NERDTreeOpener.New(a:target.path, {'where': 't'})
+    call l:opener.open(a:target)
 endfunction
 
 " FUNCTION: s:openInNewTabSilent(target) {{{1
 function! s:openInNewTabSilent(target)
-    call a:target.activate({'where': 't', 'stay': 1})
+    let l:opener = g:NERDTreeOpener.New(a:target.path, {'where': 't', 'stay': 1})
+    call l:opener.open(a:target)
 endfunction
 
 " FUNCTION: s:openNodeRecursively(node) {{{1
diff --git a/lib/nerdtree/creator.vim b/lib/nerdtree/creator.vim
@@ -1,11 +1,17 @@
-"CLASS: Creator
-"Creates tab/window/mirror nerdtree windows. Sets up all the window and
-"buffer options and key mappings etc.
-"============================================================
+" ============================================================================
+" CLASS: Creator
+"
+" This class is responsible for creating NERDTree instances.  The new NERDTree
+" may be a tab tree, a window tree, or a mirrored tree.  In the process of
+" creating a NERDTree, it sets up all of the window and buffer options and key
+" mappings etc.
+" ============================================================================
+
+
 let s:Creator = {}
 let g:NERDTreeCreator = s:Creator
 
-"FUNCTION: s:Creator._bindMappings() {{{1
+" FUNCTION: s:Creator._bindMappings() {{{1
 function! s:Creator._bindMappings()
     "make <cr> do the same as the activate node mapping
     nnoremap <silent> <buffer> <cr> :call nerdtree#ui_glue#invokeKeyMap(g:NERDTreeMapActivateNode)<cr>
@@ -22,7 +28,7 @@ function! s:Creator._bindMappings()
     command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write()
 endfunction
 
-"FUNCTION: s:Creator._broadcastInitEvent() {{{1
+" FUNCTION: s:Creator._broadcastInitEvent() {{{1
 function! s:Creator._broadcastInitEvent()
     silent doautocmd User NERDTreeInit
 endfunction
@@ -32,55 +38,48 @@ function! s:Creator.BufNamePrefix()
     return 'NERD_tree_'
 endfunction
 
-"FUNCTION: s:Creator.CreateTabTree(a:name) {{{1
+" FUNCTION: s:Creator.CreateTabTree(a:name) {{{1
 function! s:Creator.CreateTabTree(name)
     let creator = s:Creator.New()
     call creator.createTabTree(a:name)
 endfunction
 
-"FUNCTION: s:Creator.createTabTree(a:name) {{{1
-"name: the name of a bookmark or a directory
+" FUNCTION: s:Creator.createTabTree(a:name) {{{1
+" name: the name of a bookmark or a directory
 function! s:Creator.createTabTree(name)
-    let path = self._pathForString(a:name)
-
-    "abort if exception was thrown (bookmark/dir doesn't exist)
-    if empty(path)
-        return
-    endif
+    let l:path = self._pathForString(a:name)
 
-    if path == {}
+    " Abort if an exception was thrown (i.e., if the bookmark or directory
+    " does not exist).
+    if empty(l:path)
         return
     endif
 
-    "if instructed to, then change the vim CWD to the dir the NERDTree is
-    "inited in
+    " Obey the user's preferences for changing the working directory.
     if g:NERDTreeChDirMode != 0
-        call path.changeToDir()
+        call l:path.changeToDir()
     endif
 
     if g:NERDTree.ExistsForTab()
-        if g:NERDTree.IsOpen()
-            call g:NERDTree.Close()
-        endif
-
+        call g:NERDTree.Close()
         call self._removeTreeBufForTab()
     endif
 
     call self._createTreeWin()
-    call self._createNERDTree(path, "tab")
+    call self._createNERDTree(l:path, 'tab')
     call b:NERDTree.render()
     call b:NERDTree.root.putCursorHere(0, 0)
 
     call self._broadcastInitEvent()
 endfunction
 
-"FUNCTION: s:Creator.CreateWindowTree(dir) {{{1
+" FUNCTION: s:Creator.CreateWindowTree(dir) {{{1
 function! s:Creator.CreateWindowTree(dir)
     let creator = s:Creator.New()
     call creator.createWindowTree(a:dir)
 endfunction
 
-"FUNCTION: s:Creator.createWindowTree(dir) {{{1
+" FUNCTION: s:Creator.createWindowTree(dir) {{{1
 function! s:Creator.createWindowTree(dir)
     try
         let path = g:NERDTreePath.New(a:dir)
@@ -110,11 +109,6 @@ endfunction
 " FUNCTION: s:Creator._createNERDTree(path) {{{1
 function! s:Creator._createNERDTree(path, type)
     let b:NERDTree = g:NERDTree.New(a:path, a:type)
-    "TODO: This is kept for compatability only since many things use
-    "b:NERDTreeRoot instead of the new NERDTree.root
-    "Remove this one day
-    let b:NERDTreeRoot = b:NERDTree.root
-
     call b:NERDTree.root.open()
 endfunction
 
@@ -177,9 +171,9 @@ function! s:Creator.createMirror()
     endif
 endfunction
 
-"FUNCTION: s:Creator._createTreeWin() {{{1
-"Inits the NERD tree window. ie. opens it, sizes it, sets all the local
-"options etc
+" FUNCTION: s:Creator._createTreeWin() {{{1
+" Inits the NERD tree window. ie. opens it, sizes it, sets all the local
+" options etc
 function! s:Creator._createTreeWin()
     "create the nerd tree window
     let splitLocation = g:NERDTreeWinPos ==# "left" ? "topleft " : "botright "
@@ -198,7 +192,7 @@ function! s:Creator._createTreeWin()
     call self._setCommonBufOptions()
 endfunction
 
-"FUNCTION: s:Creator._isBufHidden(nr) {{{1
+" FUNCTION: s:Creator._isBufHidden(nr) {{{1
 function! s:Creator._isBufHidden(nr)
     redir => bufs
     silent ls!
@@ -207,7 +201,7 @@ function! s:Creator._isBufHidden(nr)
     return bufs =~ a:nr . '..h'
 endfunction
 
-"FUNCTION: s:Creator.New() {{{1
+" FUNCTION: s:Creator.New() {{{1
 function! s:Creator.New()
     let newCreator = copy(self)
     return newCreator
@@ -232,8 +226,8 @@ function! s:Creator._nextBufferNumber()
     return s:Creator._NextBufNum
 endfunction
 
-"FUNCTION: s:Creator._pathForString(str) {{{1
-"find a bookmark or adirectory for the given string
+" FUNCTION: s:Creator._pathForString(str) {{{1
+" find a bookmark or adirectory for the given string
 function! s:Creator._pathForString(str)
     let path = {}
     if g:NERDTreeBookmark.BookmarkExistsFor(a:str)
@@ -278,7 +272,7 @@ function! s:Creator._removeTreeBufForTab()
     unlet t:NERDTreeBufName
 endfunction
 
-"FUNCTION: s:Creator._setCommonBufOptions() {{{1
+" FUNCTION: s:Creator._setCommonBufOptions() {{{1
 function! s:Creator._setCommonBufOptions()
     "throwaway buffer options
     setlocal noswapfile
@@ -310,7 +304,7 @@ function! s:Creator._setCommonBufOptions()
     setlocal filetype=nerdtree
 endfunction
 
-"FUNCTION: s:Creator._setupStatusline() {{{1
+" FUNCTION: s:Creator._setupStatusline() {{{1
 function! s:Creator._setupStatusline()
     if g:NERDTreeStatusline != -1
         let &l:statusline = g:NERDTreeStatusline
@@ -335,19 +329,19 @@ function! s:Creator._tabpagevar(tabnr, var)
     return v
 endfunction
 
-"FUNCTION: s:Creator.ToggleTabTree(dir) {{{1
+" FUNCTION: s:Creator.ToggleTabTree(dir) {{{1
 function! s:Creator.ToggleTabTree(dir)
     let creator = s:Creator.New()
     call creator.toggleTabTree(a:dir)
 endfunction
 
-"FUNCTION: s:Creator.toggleTabTree(dir) {{{1
-"Toggles the NERD tree. I.e the NERD tree is open, it is closed, if it is
-"closed it is restored or initialized (if it doesnt exist)
+" 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)
 "
-"Args:
-"dir: the full path for the root node (is only used if the NERD tree is being
-"initialized.
+" Args:
+" dir: the full path for the root node (is only used if the NERD tree is being
+" initialized.
 function! s:Creator.toggleTabTree(dir)
     if g:NERDTree.ExistsForTab()
         if !g:NERDTree.IsOpen()
diff --git a/lib/nerdtree/opener.vim b/lib/nerdtree/opener.vim
@@ -75,7 +75,7 @@ function! s:Opener._gotoTargetWin()
         elseif self._where == 'h'
             split
         elseif self._where == 't'
-            tabnew
+            $tabnew
         endif
     else
         call self._checkToCloseTree(1)
@@ -85,7 +85,7 @@ function! s:Opener._gotoTargetWin()
         elseif self._where == 'h'
             call self._newSplit()
         elseif self._where == 't'
-            tabnew
+            $tabnew
         elseif self._where == 'p'
             call self._previousWindow()
         endif
@@ -126,38 +126,29 @@ function! s:Opener._isWindowUsable(winnumber)
 endfunction
 
 " FUNCTION: Opener.New(path, opts) {{{1
+" Instantiate a new NERDTreeOpener object.
 " Args:
-"
-" a:path: The path object that is to be opened.
-"
-" a:opts:
-"
-" A dictionary containing the following keys (all optional):
-"   'where': Specifies whether the node should be opened in new split/tab or in
-"            the previous window. Can be either 'v' or 'h' or 't' (for open in
-"            new tab)
-"   'reuse': if a window is displaying the file then jump the cursor there. Can
-"            'all', 'currenttab' or empty to not reuse.
-"   'keepopen': dont close the tree window
-"   'stay': open the file, but keep the cursor in the tree win
+" a:path: the path object that is to be opened
+" a:opts: a dictionary containing the following optional keys...
+"   'where': specifies whether the node should be opened in new split, in
+"            a new tab or, in the last window; takes values "v", "h", or "t"
+"   'reuse': if file is already shown in a window, jump there; takes values
+"            "all", "currenttab", or empty
+"   'keepopen': boolean (0 or 1); if true, the tree window will not be closed
+"   'stay': boolean (0 or 1); if true, remain in tree window after opening
 function! s:Opener.New(path, opts)
-    let newObj = copy(self)
+    let l:newOpener = copy(self)
 
-    let newObj._path = a:path
-    let newObj._stay = nerdtree#has_opt(a:opts, 'stay')
+    let l:newOpener._keepopen = nerdtree#has_opt(a:opts, 'keepopen')
+    let l:newOpener._nerdtree = b:NERDTree
+    let l:newOpener._path = a:path
+    let l:newOpener._reuse = has_key(a:opts, 'reuse') ? a:opts['reuse'] : ''
+    let l:newOpener._stay = nerdtree#has_opt(a:opts, 'stay')
+    let l:newOpener._where = has_key(a:opts, 'where') ? a:opts['where'] : ''
 
-    if has_key(a:opts, 'reuse')
-        let newObj._reuse = a:opts['reuse']
-    else
-        let newObj._reuse = ''
-    endif
+    call l:newOpener._saveCursorPos()
 
-    let newObj._keepopen = nerdtree#has_opt(a:opts, 'keepopen')
-    let newObj._where = has_key(a:opts, 'where') ? a:opts['where'] : ''
-    let newObj._nerdtree = b:NERDTree
-    call newObj._saveCursorPos()
-
-    return newObj
+    return l:newOpener
 endfunction
 
 " FUNCTION: Opener._newSplit() {{{1
@@ -242,33 +233,40 @@ endfunction
 
 " FUNCTION: Opener.open(target) {{{1
 function! s:Opener.open(target)
+
     if self._path.isDirectory
         call self._openDirectory(a:target)
-    else
-        call self._openFile()
+        return
     endif
+
+    call self._openFile()
 endfunction
 
 " FUNCTION: Opener._openFile() {{{1
 function! s:Opener._openFile()
+
     if self._reuseWindow()
         return
     endif
 
     call self._gotoTargetWin()
-    call self._path.edit()
+
     if self._stay
+        silent call self._path.edit()
         call self._restoreCursorPos()
+        return
     endif
+
+    call self._path.edit()
 endfunction
 
 " FUNCTION: Opener._openDirectory(node) {{{1
 function! s:Opener._openDirectory(node)
+    call self._gotoTargetWin()
+
     if self._nerdtree.isWinTree()
-        call self._gotoTargetWin()
         call g:NERDTreeCreator.CreateWindowTree(a:node.path.str())
     else
-        call self._gotoTargetWin()
         if empty(self._where)
             call b:NERDTree.changeRoot(a:node)
         elseif self._where == 't'
diff --git a/lib/nerdtree/tree_dir_node.vim b/lib/nerdtree/tree_dir_node.vim
@@ -21,12 +21,19 @@ function! s:TreeDirNode.AbsoluteTreeRoot()
 endfunction
 
 " FUNCTION: TreeDirNode.activate([options]) {{{1
-unlet s:TreeDirNode.activate
 function! s:TreeDirNode.activate(...)
-    let opts = a:0 ? a:1 : {}
-    call self.toggleOpen(opts)
-    call self.getNerdtree().render()
-    call self.putCursorHere(0, 0)
+    let l:options = (a:0 > 0) ? a:1 : {}
+
+    call self.toggleOpen(l:options)
+
+    " Note that we only re-render the NERDTree for this node if we did NOT
+    " create a new node and render it in a new window or tab.  In the latter
+    " case, rendering the NERDTree for this node could overwrite the text of
+    " the new NERDTree!
+    if !has_key(l:options, 'where') || empty(l:options['where'])
+        call self.getNerdtree().render()
+        call self.putCursorHere(0, 0)
+    endif
 endfunction
 
 " FUNCTION: TreeDirNode.addChild(treenode, inOrder) {{{1
diff --git a/lib/nerdtree/ui.vim b/lib/nerdtree/ui.vim
@@ -47,6 +47,8 @@ function! s:UI._dumpHelp()
         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:NERDTreeMapCloseDir .": close parent of node\n"
         let help .= "\" ". g:NERDTreeMapCloseChildren .": close all child nodes of\n"
         let help .= "\"    current node recursively\n"