From cd1f2c803ec485074af070a2fe942a029775e5bd Mon Sep 17 00:00:00 2001 From: Jason Franklin Date: Sat, 15 Sep 2018 10:18:09 -0400 Subject: [PATCH] Fix the , , J, and K default mappings (#886) These mappings currently fail on cascades. This pull request fixes this problem. --- autoload/nerdtree/ui_glue.vim | 104 ++++++++++++++------------------ lib/nerdtree/tree_dir_node.vim | 26 ++++++++ lib/nerdtree/tree_file_node.vim | 78 ++++++++---------------- 3 files changed, 97 insertions(+), 111 deletions(-) diff --git a/autoload/nerdtree/ui_glue.vim b/autoload/nerdtree/ui_glue.vim index 36e71ec..24c6358 100644 --- a/autoload/nerdtree/ui_glue.vim +++ b/autoload/nerdtree/ui_glue.vim @@ -348,35 +348,6 @@ function! s:handleMiddleMouse() endif endfunction -" FUNCTION: s:jumpToChild(direction) {{{2 -" Args: -" direction: 0 if going to first child, 1 if going to last -function! s:jumpToChild(currentNode, direction) - if a:currentNode.isRoot() - return nerdtree#echo("cannot jump to " . (a:direction ? "last" : "first") . " child") - end - let dirNode = a:currentNode.parent - let childNodes = dirNode.getVisibleChildren() - - let targetNode = childNodes[0] - if a:direction - let targetNode = childNodes[len(childNodes) - 1] - endif - - if targetNode.equals(a:currentNode) - let siblingDir = a:currentNode.parent.findOpenDirSiblingWithVisibleChildren(a:direction) - if siblingDir != {} - let indx = a:direction ? siblingDir.getVisibleChildCount()-1 : 0 - let targetNode = siblingDir.getChildByIndex(indx, 1) - endif - endif - - call targetNode.putCursorHere(1, 0) - - call b:NERDTree.ui.centerView() -endfunction - - " FUNCTION: nerdtree#ui_glue#invokeKeyMap(key) {{{1 "this is needed since I cant figure out how to invoke dict functions from a "key map @@ -384,41 +355,55 @@ function! nerdtree#ui_glue#invokeKeyMap(key) call g:NERDTreeKeyMap.Invoke(a:key) endfunction -" FUNCTION: s:jumpToFirstChild() {{{1 -" wrapper for the jump to child method +" FUNCTION: s:jumpToFirstChild(node) {{{1 function! s:jumpToFirstChild(node) call s:jumpToChild(a:node, 0) endfunction -" FUNCTION: s:jumpToLastChild() {{{1 -" wrapper for the jump to child method +" FUNCTION: s:jumpToLastChild(node) {{{1 function! s:jumpToLastChild(node) call s:jumpToChild(a:node, 1) endfunction +" FUNCTION: s:jumpToChild(node, last) {{{2 +" Jump to the first or last child node at the same file system level. +" +" Args: +" node: the node on which the cursor currently sits +" last: 1 (true) if jumping to last child, 0 (false) if jumping to first +function! s:jumpToChild(node, last) + let l:node = a:node.path.isDirectory ? a:node.getCascadeRoot() : a:node + + if l:node.isRoot() + return + endif + + let l:parent = l:node.parent + let l:children = l:parent.getVisibleChildren() + + let l:target = a:last ? l:children[len(l:children) - 1] : l:children[0] + + call l:target.putCursorHere(1, 0) + call b:NERDTree.ui.centerView() +endfunction + " FUNCTION: s:jumpToParent(node) {{{1 -" Move the cursor to the parent of the specified node. For a cascade, move to -" the parent of the cascade's highest node. At the root, do nothing. +" 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) - let l:parent = a:node.parent + let l:node = a:node.path.isDirectory ? a:node.getCascadeRoot() : a:node - " If "a:node" represents a directory, back out of its cascade. - if a:node.path.isDirectory - while !empty(l:parent) && !l:parent.isRoot() - if index(l:parent.getCascade(), a:node) >= 0 - let l:parent = l:parent.parent - else - break - endif - endwhile + if l:node.isRoot() + return endif - if !empty(l:parent) - call l:parent.putCursorHere(1, 0) - call b:NERDTree.ui.centerView() - else + if empty(l:node.parent) call nerdtree#echo('could not jump to parent node') + return endif + + call l:node.parent.putCursorHere(1, 0) + call b:NERDTree.ui.centerView() endfunction " FUNCTION: s:jumpToRoot() {{{1 @@ -438,19 +423,22 @@ function! s:jumpToPrevSibling(node) call s:jumpToSibling(a:node, 0) endfunction -" FUNCTION: s:jumpToSibling(currentNode, forward) {{{2 -" moves the cursor to the sibling of the current node in the given direction +" FUNCTION: s:jumpToSibling(node, forward) {{{2 +" Move the cursor to the next or previous node at the same file system level. " " Args: -" forward: 1 if the cursor should move to the next sibling, 0 if it should -" move back to the previous sibling -function! s:jumpToSibling(currentNode, forward) - let sibling = a:currentNode.findSibling(a:forward) +" 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) + let l:node = a:node.path.isDirectory ? a:node.getCascadeRoot() : a:node + let l:sibling = l:node.findSibling(a:forward) - if !empty(sibling) - call sibling.putCursorHere(1, 0) - call b:NERDTree.ui.centerView() + if empty(l:sibling) + return endif + + call l:sibling.putCursorHere(1, 0) + call b:NERDTree.ui.centerView() endfunction " FUNCTION: nerdtree#ui_glue#openBookmark(name) {{{1 diff --git a/lib/nerdtree/tree_dir_node.vim b/lib/nerdtree/tree_dir_node.vim index 9d4edee..04c598b 100644 --- a/lib/nerdtree/tree_dir_node.vim +++ b/lib/nerdtree/tree_dir_node.vim @@ -153,6 +153,32 @@ function! s:TreeDirNode.getCascade() return [self] + visChild.getCascade() endfunction +" FUNCTION: TreeDirNode.getCascadeRoot() {{{1 +" Return the first directory node in the cascade in which this directory node +" is rendered. +function! s:TreeDirNode.getCascadeRoot() + + " Don't search above the current NERDTree root node. + if self.isRoot() + return self + endif + + let l:cascadeRoot = self + let l:parent = self.parent + + while !empty(l:parent) && !l:parent.isRoot() + + if index(l:parent.getCascade(), self) == -1 + break + endif + + let l:cascadeRoot = l:parent + let l:parent = l:parent.parent + endwhile + + return l:cascadeRoot +endfunction + " FUNCTION: TreeDirNode.getChildCount() {{{1 " Returns the number of children this node has function! s:TreeDirNode.getChildCount() diff --git a/lib/nerdtree/tree_file_node.vim b/lib/nerdtree/tree_file_node.vim index 3ad9fcb..86aa7a6 100644 --- a/lib/nerdtree/tree_file_node.vim +++ b/lib/nerdtree/tree_file_node.vim @@ -116,68 +116,40 @@ function! s:TreeFileNode.findNode(path) return {} endfunction -" FUNCTION: TreeFileNode.findOpenDirSiblingWithVisibleChildren(direction) {{{1 -" -" Finds the next sibling for this node in the indicated direction. This sibling -" must be a directory and may/may not have children as specified. -" -" Args: -" direction: 0 if you want to find the previous sibling, 1 for the next sibling -" -" Return: -" a treenode object or {} if no appropriate sibling could be found -function! s:TreeFileNode.findOpenDirSiblingWithVisibleChildren(direction) - " if we have no parent then we can have no siblings - if self.parent != {} - let nextSibling = self.findSibling(a:direction) - - while nextSibling != {} - if nextSibling.path.isDirectory && nextSibling.hasVisibleChildren() && nextSibling.isOpen - return nextSibling - endif - let nextSibling = nextSibling.findSibling(a:direction) - endwhile - endif - - return {} -endfunction - " FUNCTION: TreeFileNode.findSibling(direction) {{{1 -" -" Finds the next sibling for this node in the indicated direction +" Find the next or previous sibling of this node. " " Args: -" direction: 0 if you want to find the previous sibling, 1 for the next sibling +" direction: 0 for previous, 1 for next " " Return: -" a treenode object or {} if no sibling could be found +" The next/previous TreeFileNode object or an empty dictionary if not found. function! s:TreeFileNode.findSibling(direction) - " if we have no parent then we can have no siblings - if self.parent != {} - " get the index of this node in its parents children - let siblingIndx = self.parent.getChildIndex(self.path) - - if siblingIndx != -1 - " move a long to the next potential sibling node - let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1 - - " keep moving along to the next sibling till we find one that is valid - let numSiblings = self.parent.getChildCount() - while siblingIndx >= 0 && siblingIndx < numSiblings - - " if the next node is not an ignored node (i.e. wont show up in the - " view) then return it - if self.parent.children[siblingIndx].path.ignore(self.getNerdtree()) ==# 0 - return self.parent.children[siblingIndx] - endif - - " go to next node - let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1 - endwhile - endif + " There can be no siblings if there is no parent. + if empty(self.parent) + return {} endif + let l:nodeIndex = self.parent.getChildIndex(self.path) + + if l:nodeIndex == -1 + return {} + endif + + " Get the next index to begin the search. + let l:nodeIndex += a:direction ? 1 : -1 + + while 0 <= l:nodeIndex && l:nodeIndex < self.parent.getChildCount() + + " Return the next node if it is not ignored. + if !self.parent.children[l:nodeIndex].path.ignore(self.getNerdtree()) + return self.parent.children[l:nodeIndex] + endif + + let l:nodeIndex += a:direction ? 1 : -1 + endwhile + return {} endfunction