nerdtree

A tree explorer plugin for vim.
Index Commits Files Refs
autoload/nerdtree/ui_glue.vim (27393B)
   1 if exists('g:loaded_nerdtree_ui_glue_autoload')
   2     finish
   3 endif
   4 let g:loaded_nerdtree_ui_glue_autoload = 1
   5 
   6 " FUNCTION: nerdtree#ui_glue#createDefaultBindings() {{{1
   7 function! nerdtree#ui_glue#createDefaultBindings() abort
   8     let s = '<SNR>' . s:SID() . '_'
   9 
  10     call NERDTreeAddKeyMap({ 'key': '<MiddleMouse>', 'scope': 'all', 'callback': s . 'handleMiddleMouse' })
  11     call NERDTreeAddKeyMap({ 'key': '<LeftRelease>', 'scope': 'all', 'callback': s.'handleLeftClick' })
  12     call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': 'DirNode', 'callback': s.'activateDirNode' })
  13     call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': 'FileNode', 'callback': s.'activateFileNode' })
  14     call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': 'Bookmark', 'callback': s.'activateBookmark' })
  15     call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': 'all', 'callback': s.'activateAll' })
  16 
  17     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCustomOpen, 'scope':'FileNode', 'callback': s.'customOpenFile'})
  18     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCustomOpen, 'scope':'DirNode', 'callback': s.'customOpenDir'})
  19     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCustomOpen, 'scope':'Bookmark', 'callback': s.'customOpenBookmark'})
  20     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCustomOpen, 'scope':'all', 'callback': s.'activateAll' })
  21 
  22     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': 'DirNode', 'callback': s.'activateDirNode' })
  23     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': 'FileNode', 'callback': s.'activateFileNode' })
  24     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': 'Bookmark', 'callback': s.'activateBookmark' })
  25     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': 'Bookmark', 'callback': s.'previewBookmark' })
  26     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': 'all', 'callback': s.'activateAll' })
  27 
  28     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': 'FileNode', 'callback': s.'openHSplit' })
  29     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': 'Bookmark', 'callback': s.'openHSplitBookmark' })
  30     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': 'FileNode', 'callback': s.'openVSplit' })
  31     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': 'Bookmark', 'callback': s.'openVSplitBookmark' })
  32 
  33     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': 'FileNode', 'callback': s.'previewNodeCurrent' })
  34     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': 'FileNode', 'callback': s.'previewNodeHSplit' })
  35     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': 'Bookmark', 'callback': s.'previewNodeHSplitBookmark' })
  36     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': 'FileNode', 'callback': s.'previewNodeVSplit' })
  37     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': 'Bookmark', 'callback': s.'previewNodeVSplitBookmark' })
  38 
  39     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenRecursively, 'scope': 'DirNode', 'callback': s.'openNodeRecursively' })
  40 
  41     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdir, 'scope': 'all', 'callback': s . 'upDirCurrentRootClosed' })
  42     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdirKeepOpen, 'scope': 'all', 'callback': s . 'upDirCurrentRootOpen' })
  43     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChangeRoot, 'scope': 'Node', 'callback': s . 'chRoot' })
  44 
  45     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChdir, 'scope': 'Node', 'callback': s.'chCwd' })
  46 
  47     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapQuit, 'scope': 'all', 'callback': s.'closeTreeWindow' })
  48 
  49     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCWD, 'scope': 'all', 'callback': 'nerdtree#ui_glue#chRootCwd' })
  50 
  51     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefreshRoot, 'scope': 'all', 'callback': s.'refreshRoot' })
  52     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefresh, 'scope': 'Node', 'callback': s.'refreshCurrent' })
  53 
  54     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapHelp, 'scope': 'all', 'callback': s.'displayHelp' })
  55     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleZoom, 'scope': 'all', 'callback': s.'toggleZoom' })
  56     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleHidden, 'scope': 'all', 'callback': s.'toggleShowHidden' })
  57     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFilters, 'scope': 'all', 'callback': s.'toggleIgnoreFilter' })
  58     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFiles, 'scope': 'all', 'callback': s.'toggleShowFiles' })
  59     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleBookmarks, 'scope': 'all', 'callback': s.'toggleShowBookmarks' })
  60 
  61     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseDir, 'scope': 'Node', 'callback': s.'closeCurrentDir' })
  62     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseChildren, 'scope': 'DirNode', 'callback': s.'closeChildren' })
  63 
  64     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapMenu, 'scope': 'Node', 'callback': s.'showMenu' })
  65 
  66     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpParent, 'scope': 'Node', 'callback': s.'jumpToParent' })
  67     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpFirstChild, 'scope': 'Node', 'callback': s.'jumpToFirstChild' })
  68     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpLastChild, 'scope': 'Node', 'callback': s.'jumpToLastChild' })
  69     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpRoot, 'scope': 'all', 'callback': s.'jumpToRoot' })
  70     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpNextSibling, 'scope': 'Node', 'callback': s.'jumpToNextSibling' })
  71     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpPrevSibling, 'scope': 'Node', 'callback': s.'jumpToPrevSibling' })
  72 
  73     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': 'Node', 'callback': s . 'openInNewTab' })
  74     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': 'Node', 'callback': s . 'openInNewTabSilent' })
  75     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': 'Bookmark', 'callback': s . 'openInNewTab' })
  76     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': 'Bookmark', 'callback': s . 'openInNewTabSilent' })
  77 
  78     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenExpl, 'scope': 'DirNode', 'callback': s.'openExplorer' })
  79     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenExpl, 'scope': 'FileNode', 'callback': s.'openExplorer' })
  80 
  81     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapDeleteBookmark, 'scope': 'Bookmark', 'callback': s.'deleteBookmark' })
  82 endfunction
  83 
  84 
  85 "SECTION: Interface bindings {{{1
  86 "============================================================
  87 
  88 "FUNCTION: s:customOpenFile() {{{1
  89 " Open file node with the 'custom' key, initially <CR>.
  90 function! s:customOpenFile(node) abort
  91     call a:node.activate(s:initCustomOpenArgs().file)
  92 endfunction
  93 
  94 "FUNCTION: s:customOpenDir() {{{1
  95 " Open directory node with the 'custom' key, initially <CR>.
  96 function! s:customOpenDir(node) abort
  97     call s:activateDirNode(a:node, s:initCustomOpenArgs().dir)
  98 endfunction
  99 
 100 "FUNCTION: s:customOpenBookmark() {{{1
 101 " Open bookmark node with the 'custom' key, initially <CR>.
 102 function! s:customOpenBookmark(node) abort
 103     if a:node.path.isDirectory
 104         call a:node.activate(b:NERDTree, s:initCustomOpenArgs().dir)
 105     else
 106         call a:node.activate(b:NERDTree, s:initCustomOpenArgs().file)
 107     endif
 108 endfunction
 109 
 110 "FUNCTION: s:initCustomOpenArgs() {{{1
 111 function! s:initCustomOpenArgs() abort
 112     let l:defaultOpenArgs = {'file': {'reuse': 'all', 'where': 'p', 'keepopen':!nerdtree#closeTreeOnOpen()}, 'dir': {}}
 113     try
 114         let g:NERDTreeCustomOpenArgs = get(g:, 'NERDTreeCustomOpenArgs', {})
 115         call  extend(g:NERDTreeCustomOpenArgs, l:defaultOpenArgs, 'keep')
 116     catch /^Vim(\a\+):E712:/
 117         call nerdtree#echoWarning('g:NERDTreeCustomOpenArgs is not set properly. Using default value.')
 118         let g:NERDTreeCustomOpenArgs = l:defaultOpenArgs
 119     finally
 120         return g:NERDTreeCustomOpenArgs
 121     endtry
 122 endfunction
 123 
 124 "FUNCTION: s:activateAll() {{{1
 125 "handle the user activating the updir line
 126 function! s:activateAll() abort
 127     if getline('.') ==# g:NERDTreeUI.UpDirLine()
 128         return nerdtree#ui_glue#upDir(0)
 129     endif
 130 endfunction
 131 
 132 " FUNCTION: s:activateDirNode(directoryNode, options) {{{1
 133 " Open a directory with optional options
 134 function! s:activateDirNode(directoryNode, ...) abort
 135 
 136     if a:directoryNode.isRoot() && a:directoryNode.isOpen
 137         call nerdtree#echo('cannot close tree root')
 138         return
 139     endif
 140 
 141     call a:directoryNode.activate((a:0 > 0) ? a:1 : {})
 142 endfunction
 143 
 144 "FUNCTION: s:activateFileNode() {{{1
 145 "handle the user activating a tree node
 146 function! s:activateFileNode(node) abort
 147     call a:node.activate({'reuse': 'all', 'where': 'p', 'keepopen': !nerdtree#closeTreeOnOpen()})
 148 endfunction
 149 
 150 "FUNCTION: s:activateBookmark(bookmark) {{{1
 151 "handle the user activating a bookmark
 152 function! s:activateBookmark(bm) abort
 153     call a:bm.activate(b:NERDTree, !a:bm.path.isDirectory ? {'where': 'p', 'keepopen': !nerdtree#closeTreeOnOpen()} : {})
 154 endfunction
 155 
 156 " FUNCTION: nerdtree#ui_glue#bookmarkNode(name) {{{1
 157 " Associate the current node with the given name
 158 function! nerdtree#ui_glue#bookmarkNode(...) abort
 159     let currentNode = g:NERDTreeFileNode.GetSelected()
 160     if currentNode !=# {}
 161         let name = a:1
 162         if empty(name)
 163             let name = currentNode.path.getLastPathComponent(0)
 164         endif
 165         try
 166             call currentNode.bookmark(name)
 167             call b:NERDTree.render()
 168         catch /^NERDTree.IllegalBookmarkNameError/
 169             call nerdtree#echo('bookmark names must not contain spaces')
 170         endtry
 171     else
 172         call nerdtree#echo('select a node first')
 173     endif
 174 endfunction
 175 
 176 " FUNCTION: s:chCwd(node) {{{1
 177 function! s:chCwd(node) abort
 178     try
 179         call a:node.path.changeToDir()
 180     catch /^NERDTree.PathChangeError/
 181         call nerdtree#echoWarning('could not change cwd')
 182     endtry
 183 endfunction
 184 
 185 " FUNCTION: s:chRoot(node) {{{1
 186 " changes the current root to the selected one
 187 function! s:chRoot(node) abort
 188     call b:NERDTree.changeRoot(a:node)
 189 endfunction
 190 
 191 " FUNCTION: s:nerdtree#ui_glue#chRootCwd() {{{1
 192 " Change the NERDTree root to match the current working directory.
 193 function! nerdtree#ui_glue#chRootCwd() abort
 194     NERDTreeCWD
 195 endfunction
 196 
 197 " FUNCTION: nnerdtree#ui_glue#clearBookmarks(bookmarks) {{{1
 198 function! nerdtree#ui_glue#clearBookmarks(bookmarks) abort
 199     if a:bookmarks ==# ''
 200         let currentNode = g:NERDTreeFileNode.GetSelected()
 201         if currentNode !=# {}
 202             call currentNode.clearBookmarks()
 203         endif
 204     else
 205         for name in split(a:bookmarks, ' ')
 206             let bookmark = g:NERDTreeBookmark.BookmarkFor(name)
 207             call bookmark.delete()
 208         endfor
 209     endif
 210     call b:NERDTree.root.refresh()
 211     call b:NERDTree.render()
 212 endfunction
 213 
 214 " FUNCTION: s:closeChildren(node) {{{1
 215 " closes all childnodes of the current node
 216 function! s:closeChildren(node) abort
 217     call a:node.closeChildren()
 218     call b:NERDTree.render()
 219     call a:node.putCursorHere(0, 0)
 220 endfunction
 221 
 222 " FUNCTION: s:closeCurrentDir(node) {{{1
 223 " Close the parent directory of the current node.
 224 function! s:closeCurrentDir(node) abort
 225 
 226     if a:node.isRoot()
 227         call nerdtree#echo('cannot close parent of tree root')
 228         return
 229     endif
 230 
 231     let l:parent = a:node.parent
 232 
 233     while l:parent.isCascadable()
 234         let l:parent = l:parent.parent
 235     endwhile
 236 
 237     if l:parent.isRoot()
 238         call nerdtree#echo('cannot close tree root')
 239         return
 240     endif
 241 
 242     call l:parent.close()
 243     call b:NERDTree.render()
 244     call l:parent.putCursorHere(0, 0)
 245 endfunction
 246 
 247 " FUNCTION: s:closeTreeWindow() {{{1
 248 " close the tree window
 249 function! s:closeTreeWindow() abort
 250     if b:NERDTree.isWinTree() && b:NERDTree.previousBuf() !=# -1
 251         exec 'buffer ' . b:NERDTree.previousBuf()
 252     else
 253         if winnr('$') > 1
 254             call g:NERDTree.Close()
 255         else
 256             call nerdtree#echo('Cannot close last window')
 257         endif
 258     endif
 259 endfunction
 260 
 261 " FUNCTION: s:deleteBookmark(bookmark) {{{1
 262 " Prompt the user to confirm the deletion of the selected bookmark.
 263 function! s:deleteBookmark(bookmark) abort
 264     let l:message = 'Delete the bookmark "' . a:bookmark.name
 265                 \ . '" from the bookmark list?'
 266 
 267     let l:choices = "&Yes\n&No"
 268 
 269     echo | redraw
 270     let l:selection = confirm(l:message, l:choices, 1, 'Warning')
 271 
 272     if l:selection !=# 1
 273         call nerdtree#echo('bookmark not deleted')
 274         return
 275     endif
 276 
 277     try
 278         call a:bookmark.delete()
 279         silent call b:NERDTree.root.refresh()
 280         call b:NERDTree.render()
 281         echo | redraw
 282     catch /^NERDTree/
 283         call nerdtree#echoWarning('could not remove bookmark')
 284     endtry
 285 endfunction
 286 
 287 " FUNCTION: s:displayHelp() {{{1
 288 " toggles the help display
 289 function! s:displayHelp() abort
 290     call b:NERDTree.ui.toggleHelp()
 291     call b:NERDTree.render()
 292     call b:NERDTree.ui.centerView()
 293 endfunction
 294 
 295 " FUNCTION: s:findAndRevealPath(pathStr) {{{1
 296 function! s:findAndRevealPath(pathStr) abort
 297     let l:pathStr = !empty(a:pathStr) ? a:pathStr : expand('%:p')
 298     let l:revealOpts = {}
 299 
 300     if empty(l:pathStr)
 301         call nerdtree#echoWarning('no file for the current buffer')
 302         return
 303     endif
 304 
 305     if !filereadable(l:pathStr)
 306         let l:pathStr = fnamemodify(l:pathStr, ':h')
 307         let l:revealOpts['open'] = 1
 308     endif
 309 
 310     try
 311         let l:pathStr = g:NERDTreePath.Resolve(l:pathStr)
 312         let l:pathObj = g:NERDTreePath.New(l:pathStr)
 313     catch /^NERDTree.InvalidArgumentsError/
 314         call nerdtree#echoWarning('invalid path')
 315         return
 316     endtry
 317 
 318     if !g:NERDTree.ExistsForTab()
 319         try
 320             let l:cwd = g:NERDTreePath.New(getcwd())
 321         catch /^NERDTree.InvalidArgumentsError/
 322             call nerdtree#echo('current directory does not exist.')
 323             let l:cwd = l:pathObj.getParent()
 324         endtry
 325 
 326         if l:pathObj.isUnder(l:cwd)
 327             call g:NERDTreeCreator.CreateTabTree(l:cwd.str())
 328         else
 329             call g:NERDTreeCreator.CreateTabTree(l:pathObj.getParent().str())
 330         endif
 331     else
 332         NERDTreeFocus
 333 
 334         if !l:pathObj.isUnder(b:NERDTree.root.path)
 335             call s:chRoot(g:NERDTreeDirNode.New(l:pathObj.getParent(), b:NERDTree))
 336         endif
 337     endif
 338 
 339     if l:pathObj.isHiddenUnder(b:NERDTree.root.path)
 340         call b:NERDTree.ui.setShowHidden(1)
 341     endif
 342 
 343     let l:node = b:NERDTree.root.reveal(l:pathObj, l:revealOpts)
 344     call b:NERDTree.render()
 345     call l:node.putCursorHere(1, 0)
 346 endfunction
 347 
 348 "FUNCTION: s:handleLeftClick() {{{1
 349 "Checks if the click should open the current node
 350 function! s:handleLeftClick() abort
 351     let currentNode = g:NERDTreeFileNode.GetSelected()
 352     if currentNode !=# {}
 353 
 354         "the dir arrows are multibyte chars, and vim's string functions only
 355         "deal with single bytes - so split the line up with the hack below and
 356         "take the line substring manually
 357         let line = split(getline(line('.')), '\zs')
 358         let startToCur = ''
 359         for i in range(0,len(line)-1)
 360             let startToCur .= line[i]
 361         endfor
 362 
 363         if currentNode.path.isDirectory
 364             if startToCur =~# g:NERDTreeUI.MarkupReg() && startToCur =~# '[+~'.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.'] \?$'
 365                 call currentNode.activate()
 366                 return
 367             endif
 368         endif
 369 
 370         if (g:NERDTreeMouseMode ==# 2 && currentNode.path.isDirectory) || g:NERDTreeMouseMode ==# 3
 371             let char = strpart(startToCur, strlen(startToCur)-1, 1)
 372             if char !~# g:NERDTreeUI.MarkupReg()
 373                 if currentNode.path.isDirectory
 374                     call currentNode.activate()
 375                 else
 376                     call currentNode.activate({'reuse': 'all', 'where': 'p', 'keepopen':!nerdtree#closeTreeOnOpen()})
 377                 endif
 378                 return
 379             endif
 380         endif
 381     endif
 382 endfunction
 383 
 384 " FUNCTION: s:handleMiddleMouse() {{{1
 385 function! s:handleMiddleMouse() abort
 386 
 387     " A middle mouse click does not automatically position the cursor as one
 388     " would expect. Forcing the execution of a regular left mouse click here
 389     " fixes this problem.
 390     execute "normal! \<LeftMouse>"
 391 
 392     let l:currentNode = g:NERDTreeFileNode.GetSelected()
 393     if empty(l:currentNode)
 394         call nerdtree#echoError('use the pointer to select a node')
 395         return
 396     endif
 397 
 398     if l:currentNode.path.isDirectory
 399         call l:currentNode.openExplorer()
 400     else
 401         call l:currentNode.open({'where': 'h'})
 402     endif
 403 endfunction
 404 
 405 " FUNCTION: nerdtree#ui_glue#invokeKeyMap(key) {{{1
 406 "this is needed since I cant figure out how to invoke dict functions from a
 407 "key map
 408 function! nerdtree#ui_glue#invokeKeyMap(key) abort
 409     call g:NERDTreeKeyMap.Invoke(a:key)
 410 endfunction
 411 
 412 " FUNCTION: s:jumpToFirstChild(node) {{{1
 413 function! s:jumpToFirstChild(node) abort
 414     call s:jumpToChild(a:node, 0)
 415 endfunction
 416 
 417 " FUNCTION: s:jumpToLastChild(node) {{{1
 418 function! s:jumpToLastChild(node) abort
 419     call s:jumpToChild(a:node, 1)
 420 endfunction
 421 
 422 " FUNCTION: s:jumpToChild(node, last) {{{1
 423 " Jump to the first or last child node at the same file system level.
 424 "
 425 " Args:
 426 " node: the node on which the cursor currently sits
 427 " last: 1 (true) if jumping to last child, 0 (false) if jumping to first
 428 function! s:jumpToChild(node, last) abort
 429     let l:node = a:node.path.isDirectory ? a:node.getCascadeRoot() : a:node
 430 
 431     if l:node.isRoot()
 432         return
 433     endif
 434 
 435     let l:parent = l:node.parent
 436     let l:children = l:parent.getVisibleChildren()
 437 
 438     let l:target = a:last ? l:children[len(l:children) - 1] : l:children[0]
 439 
 440     call l:target.putCursorHere(1, 0)
 441     call b:NERDTree.ui.centerView()
 442 endfunction
 443 
 444 " FUNCTION: s:jumpToParent(node) {{{1
 445 " Move the cursor to the parent of the specified node.  For a cascade, move to
 446 " the parent of the cascade's first node.  At the root node, do nothing.
 447 function! s:jumpToParent(node) abort
 448     let l:node = a:node.path.isDirectory ? a:node.getCascadeRoot() : a:node
 449 
 450     if l:node.isRoot()
 451         return
 452     endif
 453 
 454     if empty(l:node.parent)
 455         call nerdtree#echo('could not jump to parent node')
 456         return
 457     endif
 458 
 459     call l:node.parent.putCursorHere(1, 0)
 460     call b:NERDTree.ui.centerView()
 461 endfunction
 462 
 463 " FUNCTION: s:jumpToRoot() {{{1
 464 " moves the cursor to the root node
 465 function! s:jumpToRoot() abort
 466     call b:NERDTree.root.putCursorHere(1, 0)
 467     call b:NERDTree.ui.centerView()
 468 endfunction
 469 
 470 " FUNCTION: s:jumpToNextSibling(node) {{{1
 471 function! s:jumpToNextSibling(node) abort
 472     call s:jumpToSibling(a:node, 1)
 473 endfunction
 474 
 475 " FUNCTION: s:jumpToPrevSibling(node) {{{1
 476 function! s:jumpToPrevSibling(node) abort
 477     call s:jumpToSibling(a:node, 0)
 478 endfunction
 479 
 480 " FUNCTION: s:jumpToSibling(node, forward) {{{1
 481 " Move the cursor to the next or previous node at the same file system level.
 482 "
 483 " Args:
 484 " node: the node on which the cursor currently sits
 485 " forward: 0 to jump to previous sibling, 1 to jump to next sibling
 486 function! s:jumpToSibling(node, forward) abort
 487     let l:node = a:node.path.isDirectory ? a:node.getCascadeRoot() : a:node
 488     let l:sibling = l:node.findSibling(a:forward)
 489 
 490     if empty(l:sibling)
 491         return
 492     endif
 493 
 494     call l:sibling.putCursorHere(1, 0)
 495     call b:NERDTree.ui.centerView()
 496 endfunction
 497 
 498 " FUNCTION: nerdtree#ui_glue#openBookmark(name) {{{1
 499 " Open the Bookmark that has the specified name. This function provides the
 500 " implementation for the :OpenBookmark command.
 501 function! nerdtree#ui_glue#openBookmark(name) abort
 502     try
 503         let l:bookmark = g:NERDTreeBookmark.BookmarkFor(a:name)
 504     catch /^NERDTree.BookmarkNotFoundError/
 505         call nerdtree#echoError('bookmark "' . a:name . '" not found')
 506         return
 507     endtry
 508     if l:bookmark.path.isDirectory
 509         call l:bookmark.open(b:NERDTree)
 510         return
 511     endif
 512 
 513     call l:bookmark.open(b:NERDTree, s:initCustomOpenArgs().file)
 514 endfunction
 515 
 516 " FUNCTION: s:openHSplit(target) {{{1
 517 function! s:openHSplit(target) abort
 518     call a:target.activate({'where': 'h', 'keepopen': !nerdtree#closeTreeOnOpen()})
 519 endfunction
 520 
 521 " FUNCTION: s:openVSplit(target) {{{1
 522 function! s:openVSplit(target) abort
 523     call a:target.activate({'where': 'v', 'keepopen': !nerdtree#closeTreeOnOpen()})
 524 endfunction
 525 
 526 "FUNCTION: s:openHSplitBookmark(bookmark) {{{1
 527 "handle the user activating a bookmark
 528 function! s:openHSplitBookmark(bm) abort
 529     call a:bm.activate(b:NERDTree, !a:bm.path.isDirectory ? {'where': 'h', 'keepopen': !nerdtree#closeTreeOnOpen()} : {})
 530 endfunction
 531 
 532 "FUNCTION: s:openVSplitBookmark(bookmark) {{{1
 533 "handle the user activating a bookmark
 534 function! s:openVSplitBookmark(bm) abort
 535     call a:bm.activate(b:NERDTree, !a:bm.path.isDirectory ? {'where': 'v', 'keepopen': !nerdtree#closeTreeOnOpen()} : {})
 536 endfunction
 537 
 538 " FUNCTION: s:previewHSplitBookmark(bookmark) {{{1
 539 function! s:previewNodeHSplitBookmark(bookmark) abort
 540     call a:bookmark.activate(b:NERDTree, !a:bookmark.path.isDirectory ? {'stay': 1, 'where': 'h', 'keepopen': 1} : {})
 541 endfunction
 542 
 543 " FUNCTION: s:previewVSplitBookmark(bookmark) {{{1
 544 function! s:previewNodeVSplitBookmark(bookmark) abort
 545     call a:bookmark.activate(b:NERDTree, !a:bookmark.path.isDirectory ? {'stay': 1, 'where': 'v', 'keepopen': 1} : {})
 546 endfunction
 547 
 548 " FUNCTION: s:openExplorer(node) {{{1
 549 function! s:openExplorer(node) abort
 550     call a:node.openExplorer()
 551 endfunction
 552 
 553 " FUNCTION: s:openInNewTab(target) {{{1
 554 function! s:openInNewTab(target) abort
 555     let l:opener = g:NERDTreeOpener.New(a:target.path, {'where': 't', 'keepopen': !nerdtree#closeTreeOnOpen()})
 556     call l:opener.open(a:target)
 557 endfunction
 558 
 559 " FUNCTION: s:openInNewTabSilent(target) {{{1
 560 function! s:openInNewTabSilent(target) abort
 561     let l:opener = g:NERDTreeOpener.New(a:target.path, {'where': 't', 'keepopen': !nerdtree#closeTreeOnOpen(), 'stay': 1})
 562     call l:opener.open(a:target)
 563 endfunction
 564 
 565 " FUNCTION: s:openNodeRecursively(node) {{{1
 566 function! s:openNodeRecursively(node) abort
 567     call nerdtree#echo('Recursively opening node. Please wait...')
 568     call a:node.openRecursively()
 569     call b:NERDTree.render()
 570     call nerdtree#echo('')
 571 endfunction
 572 
 573 " FUNCTION: s:previewBookmark(bookmark) {{{1
 574 function! s:previewBookmark(bookmark) abort
 575     if a:bookmark.path.isDirectory
 576         execute 'NERDTreeFind '.a:bookmark.path.str()
 577     else
 578         call a:bookmark.activate(b:NERDTree, {'stay': 1, 'where': 'p', 'keepopen': 1})
 579     endif
 580 endfunction
 581 
 582 "FUNCTION: s:previewNodeCurrent(node) {{{1
 583 function! s:previewNodeCurrent(node) abort
 584     call a:node.open({'stay': 1, 'where': 'p', 'keepopen': 1})
 585 endfunction
 586 
 587 "FUNCTION: s:previewNodeHSplit(node) {{{1
 588 function! s:previewNodeHSplit(node) abort
 589     call a:node.open({'stay': 1, 'where': 'h', 'keepopen': 1})
 590 endfunction
 591 
 592 "FUNCTION: s:previewNodeVSplit(node) {{{1
 593 function! s:previewNodeVSplit(node) abort
 594     call a:node.open({'stay': 1, 'where': 'v', 'keepopen': 1})
 595 endfunction
 596 
 597 " FUNCTION: nerdtree#ui_glue#revealBookmark(name) {{{1
 598 " put the cursor on the node associate with the given name
 599 function! nerdtree#ui_glue#revealBookmark(name) abort
 600     try
 601         let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0, b:NERDTree)
 602         call targetNode.putCursorHere(0, 1)
 603     catch /^NERDTree.BookmarkNotFoundError/
 604         call nerdtree#echo('Bookmark isn''t cached under the current root')
 605     endtry
 606 endfunction
 607 
 608 " FUNCTION: s:refreshRoot() {{{1
 609 " Reloads the current root. All nodes below this will be lost and the root dir
 610 " will be reloaded.
 611 function! s:refreshRoot() abort
 612     if !g:NERDTree.IsOpen()
 613         return
 614     endif
 615     call nerdtree#echo('Refreshing the root node. This could take a while...')
 616 
 617     let l:curWin = winnr()
 618     call nerdtree#exec(g:NERDTree.GetWinNum() . 'wincmd w', 1)
 619     call b:NERDTree.root.refresh()
 620     call b:NERDTree.render()
 621     redraw
 622     call nerdtree#exec(l:curWin . 'wincmd w', 1)
 623     call nerdtree#echo('')
 624 endfunction
 625 
 626 " FUNCTION: s:refreshCurrent(node) {{{1
 627 " refreshes the root for the current node
 628 function! s:refreshCurrent(node) abort
 629     let node = a:node
 630     if !node.path.isDirectory
 631         let node = node.parent
 632     endif
 633 
 634     call nerdtree#echo('Refreshing node. This could take a while...')
 635     call node.refresh()
 636     call b:NERDTree.render()
 637     call nerdtree#echo('')
 638 endfunction
 639 
 640 " FUNCTION: nerdtree#ui_glue#setupCommands() {{{1
 641 function! nerdtree#ui_glue#setupCommands() abort
 642     command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreateTabTree('<args>')
 643     command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.ToggleTabTree('<args>')
 644     command! -n=0 -bar NERDTreeClose :call g:NERDTree.Close()
 645     command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreateTabTree('<args>')
 646     command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror()
 647     command! -n=? -complete=file -bar NERDTreeFind call s:findAndRevealPath('<args>')
 648     command! -n=0 -bar NERDTreeRefreshRoot call s:refreshRoot()
 649     command! -n=0 -bar NERDTreeFocus call NERDTreeFocus()
 650     command! -n=0 -bar NERDTreeCWD call NERDTreeCWD()
 651 endfunction
 652 
 653 " Function: s:SID()   {{{1
 654 function! s:SID() abort
 655     if !exists('s:sid')
 656         let s:sid = matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')
 657     endif
 658     return s:sid
 659 endfun
 660 
 661 " FUNCTION: s:showMenu(node) {{{1
 662 function! s:showMenu(node) abort
 663     let mc = g:NERDTreeMenuController.New(g:NERDTreeMenuItem.AllEnabled())
 664     call mc.showMenu()
 665 endfunction
 666 
 667 " FUNCTION: s:toggleIgnoreFilter() {{{1
 668 function! s:toggleIgnoreFilter() abort
 669     call b:NERDTree.ui.toggleIgnoreFilter()
 670 endfunction
 671 
 672 " FUNCTION: s:toggleShowBookmarks() {{{1
 673 function! s:toggleShowBookmarks() abort
 674     call b:NERDTree.ui.toggleShowBookmarks()
 675 endfunction
 676 
 677 " FUNCTION: s:toggleShowFiles() {{{1
 678 function! s:toggleShowFiles() abort
 679     call b:NERDTree.ui.toggleShowFiles()
 680 endfunction
 681 
 682 " FUNCTION: s:toggleShowHidden() {{{1
 683 " toggles the display of hidden files
 684 function! s:toggleShowHidden() abort
 685     call b:NERDTree.ui.toggleShowHidden()
 686 endfunction
 687 
 688 " FUNCTION: s:toggleZoom() {{{1
 689 function! s:toggleZoom() abort
 690     call b:NERDTree.ui.toggleZoom()
 691 endfunction
 692 
 693 " FUNCTION: nerdtree#ui_glue#upDir(preserveState) {{{1
 694 " Move the NERDTree up one level.
 695 "
 696 " Args:
 697 " preserveState: if 1, the current root is left open when the new tree is
 698 " rendered; if 0, the current root node is closed
 699 function! nerdtree#ui_glue#upDir(preserveState) abort
 700 
 701     try
 702         call b:NERDTree.root.cacheParent()
 703     catch /^NERDTree.CannotCacheParentError/
 704         call nerdtree#echo('already at root directory')
 705         return
 706     endtry
 707 
 708     let l:oldRoot = b:NERDTree.root
 709     let l:newRoot = b:NERDTree.root.parent
 710 
 711     call l:newRoot.open()
 712     call l:newRoot.transplantChild(l:oldRoot)
 713 
 714     if !a:preserveState
 715         call l:oldRoot.close()
 716     endif
 717 
 718     call b:NERDTree.changeRoot(l:newRoot)
 719     call l:oldRoot.putCursorHere(0, 0)
 720 endfunction
 721 
 722 " FUNCTION: s:upDirCurrentRootOpen() {{{1
 723 function! s:upDirCurrentRootOpen() abort
 724     call nerdtree#ui_glue#upDir(1)
 725 endfunction
 726 
 727 " FUNCTION: s:upDirCurrentRootClosed() {{{1
 728 function! s:upDirCurrentRootClosed() abort
 729     call nerdtree#ui_glue#upDir(0)
 730 endfunction
 731 
 732 " vim: set sw=4 sts=4 et fdm=marker: