diff --git a/CHANGELOG b/CHANGELOG index 3d377ab..6dac46d 100644 --- 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 index 2d94fd9..f5b4726 100644 --- 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 index 92e1abe..ec04140 100644 --- 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 do the same as the activate node mapping nnoremap :call nerdtree#ui_glue#invokeKeyMap(g:NERDTreeMapActivateNode) @@ -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) + let l:path = self._pathForString(a:name) - "abort if exception was thrown (bookmark/dir doesn't exist) - if empty(path) + " Abort if an exception was thrown (i.e., if the bookmark or directory + " does not exist). + if empty(l:path) return endif - if 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 index fd32e64..82a0349 100644 --- 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 index 62bcf88..03c3545 100644 --- 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 index 03f11b8..6ee8dab 100644 --- 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"