Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the <C-J>/<C-K> motions, which currently fail with cascades #886

Merged
merged 8 commits into from
Sep 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 47 additions & 59 deletions autoload/nerdtree/ui_glue.vim
Original file line number Diff line number Diff line change
Expand Up @@ -348,77 +348,62 @@ 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
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
Expand All @@ -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)

if !empty(sibling)
call sibling.putCursorHere(1, 0)
call b:NERDTree.ui.centerView()
" 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(l:sibling)
return
endif

call l:sibling.putCursorHere(1, 0)
call b:NERDTree.ui.centerView()
endfunction

" FUNCTION: nerdtree#ui_glue#openBookmark(name) {{{1
Expand Down
26 changes: 26 additions & 0 deletions lib/nerdtree/tree_dir_node.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
70 changes: 21 additions & 49 deletions lib/nerdtree/tree_file_node.vim
Original file line number Diff line number Diff line change
Expand Up @@ -116,67 +116,39 @@ 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)
" 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 siblingIndx != -1
" move a long to the next potential sibling node
let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1
if l:nodeIndex == -1
return {}
endif

" keep moving along to the next sibling till we find one that is valid
let numSiblings = self.parent.getChildCount()
while siblingIndx >= 0 && siblingIndx < numSiblings
" Get the next index to begin the search.
let l:nodeIndex += a:direction ? 1 : -1

" 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
while 0 <= l:nodeIndex && l:nodeIndex < self.parent.getChildCount()

" go to next node
let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1
endwhile
" 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
endif

let l:nodeIndex += a:direction ? 1 : -1
endwhile

return {}
endfunction
Expand Down