Merge branch 'master' into expt_add_path_flags_and_git

Conflicts:
	autoload/nerdtree.vim
	lib/nerdtree/creator.vim
This commit is contained in:
Martin Grenfell 2014-07-08 09:38:43 +01:00
commit 8644622000
14 changed files with 1119 additions and 1071 deletions

View File

@ -83,7 +83,7 @@ __Q. How can I open a NERDTree automatically when vim starts up if no files were
A. Stick this in your vimrc A. Stick this in your vimrc
autocmd StdinReadPre * let s:std_in=1 autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if !argc() == 0 && !exists("s:std_in") | NERDTree | endif autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
__Q. How can I map a specific key or shortcut to open NERDTree?__ __Q. How can I map a specific key or shortcut to open NERDTree?__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,668 @@
if exists("g:loaded_nerdtree_ui_glue_autoload")
finish
endif
let g:loaded_nerdtree_ui_glue_autoload = 1
" FUNCTION: nerdtree#ui_glue#createDefaultBindings() {{{1
function! nerdtree#ui_glue#createDefaultBindings()
let s = '<SNR>' . s:SID() . '_'
call NERDTreeAddKeyMap({ 'key': '<MiddleRelease>', 'scope': "all", 'callback': s."handleMiddleMouse" })
call NERDTreeAddKeyMap({ 'key': '<LeftRelease>', 'scope': "all", 'callback': s."handleLeftClick" })
call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "DirNode", 'callback': s."activateDirNode" })
call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "FileNode", 'callback': s."activateFileNode" })
call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "Bookmark", 'callback': s."activateBookmark" })
call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "all", 'callback': s."activateAll" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "DirNode", 'callback': s."activateDirNode" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "FileNode", 'callback': s."activateFileNode" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "Bookmark", 'callback': s."activateBookmark" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "all", 'callback': s."activateAll" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': "Node", 'callback': s."openHSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': "Node", 'callback': s."openVSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': "Bookmark", 'callback': s."openHSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': "Bookmark", 'callback': s."openVSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': "Node", 'callback': s."previewNodeCurrent" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': "Node", 'callback': s."previewNodeVSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': "Node", 'callback': s."previewNodeHSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': "Bookmark", 'callback': s."previewNodeCurrent" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': "Bookmark", 'callback': s."previewNodeVSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': "Bookmark", 'callback': s."previewNodeHSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenRecursively, 'scope': "DirNode", 'callback': s."openNodeRecursively" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdir, 'scope': "all", 'callback': s."upDirCurrentRootClosed" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdirKeepOpen, 'scope': "all", 'callback': s."upDirCurrentRootOpen" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChangeRoot, 'scope': "Node", 'callback': s."chRoot" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChdir, 'scope': "Node", 'callback': s."chCwd" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapQuit, 'scope': "all", 'callback': s."closeTreeWindow" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCWD, 'scope': "all", 'callback': "nerdtree#ui_glue#chRootCwd" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefreshRoot, 'scope': "all", 'callback': s."refreshRoot" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefresh, 'scope': "Node", 'callback': s."refreshCurrent" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapHelp, 'scope': "all", 'callback': s."displayHelp" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleZoom, 'scope': "all", 'callback': s."toggleZoom" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleHidden, 'scope': "all", 'callback': s."toggleShowHidden" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFilters, 'scope': "all", 'callback': s."toggleIgnoreFilter" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFiles, 'scope': "all", 'callback': s."toggleShowFiles" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleBookmarks, 'scope': "all", 'callback': s."toggleShowBookmarks" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseDir, 'scope': "Node", 'callback': s."closeCurrentDir" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseChildren, 'scope': "DirNode", 'callback': s."closeChildren" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapMenu, 'scope': "Node", 'callback': s."showMenu" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpParent, 'scope': "Node", 'callback': s."jumpToParent" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpFirstChild, 'scope': "Node", 'callback': s."jumpToFirstChild" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpLastChild, 'scope': "Node", 'callback': s."jumpToLastChild" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpRoot, 'scope': "all", 'callback': s."jumpToRoot" })
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:NERDTreeMapOpenExpl, 'scope': "DirNode", 'callback': s."openExplorer" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapDeleteBookmark, 'scope': "Bookmark", 'callback': s."deleteBookmark" })
endfunction
"SECTION: Interface bindings {{{1
"============================================================
"FUNCTION: s:activateAll() {{{1
"handle the user activating the updir line
function! s:activateAll()
if getline(".") ==# nerdtree#treeUpDirLine()
return nerdtree#ui_glue#upDir(0)
endif
endfunction
"FUNCTION: s:activateDirNode() {{{1
"handle the user activating a tree node
function! s:activateDirNode(node)
call a:node.activate({'reuse': 1})
endfunction
"FUNCTION: s:activateFileNode() {{{1
"handle the user activating a tree node
function! s:activateFileNode(node)
call a:node.activate({'reuse': 1, 'where': 'p'})
endfunction
"FUNCTION: s:activateBookmark() {{{1
"handle the user activating a bookmark
function! s:activateBookmark(bm)
call a:bm.activate(!a:bm.path.isDirectory ? {'where': 'p'} : {})
endfunction
" FUNCTION: nerdtree#ui_glue#bookmarkNode(name) {{{1
" Associate the current node with the given name
function! nerdtree#ui_glue#bookmarkNode(...)
let currentNode = g:NERDTreeFileNode.GetSelected()
if currentNode != {}
let name = a:1
if empty(name)
let name = currentNode.path.getLastPathComponent(0)
endif
try
call currentNode.bookmark(name)
call b:NERDTree.render()
catch /^NERDTree.IllegalBookmarkNameError/
call nerdtree#echo("bookmark names must not contain spaces")
endtry
else
call nerdtree#echo("select a node first")
endif
endfunction
" FUNCTION: s:chCwd(node) {{{1
function! s:chCwd(node)
try
call a:node.path.changeToDir()
catch /^NERDTree.PathChangeError/
call nerdtree#echoWarning("could not change cwd")
endtry
endfunction
" FUNCTION: s:chRoot(node) {{{1
" changes the current root to the selected one
function! s:chRoot(node)
call a:node.makeRoot()
call b:NERDTree.render()
call b:NERDTreeRoot.putCursorHere(0, 0)
endfunction
" FUNCTION: s:nerdtree#ui_glue#chRootCwd() {{{1
" changes the current root to CWD
function! nerdtree#ui_glue#chRootCwd()
try
let cwd = g:NERDTreePath.New(getcwd())
catch /^NERDTree.InvalidArgumentsError/
call nerdtree#echo("current directory does not exist.")
return
endtry
if cwd.str() == g:NERDTreeFileNode.GetRootForTab().path.str()
return
endif
call nerdtree#chRoot(g:NERDTreeDirNode.New(cwd))
endfunction
" FUNCTION: nnerdtree#ui_glue#clearBookmarks(bookmarks) {{{1
function! nerdtree#ui_glue#clearBookmarks(bookmarks)
if a:bookmarks ==# ''
let currentNode = g:NERDTreeFileNode.GetSelected()
if currentNode != {}
call currentNode.clearBookmarks()
endif
else
for name in split(a:bookmarks, ' ')
let bookmark = g:NERDTreeBookmark.BookmarkFor(name)
call bookmark.delete()
endfor
endif
call b:NERDTree.render()
endfunction
" FUNCTION: s:closeChildren(node) {{{1
" closes all childnodes of the current node
function! s:closeChildren(node)
call a:node.closeChildren()
call b:NERDTree.render()
call a:node.putCursorHere(0, 0)
endfunction
" FUNCTION: s:closeCurrentDir(node) {{{1
" closes the parent dir of the current node
function! s:closeCurrentDir(node)
let parent = a:node.parent
if parent ==# {} || parent.isRoot()
call nerdtree#echo("cannot close tree root")
else
while g:NERDTreeCascadeOpenSingleChildDir && !parent.parent.isRoot()
if parent.parent.getVisibleChildCount() == 1
call parent.close()
let parent = parent.parent
else
break
endif
endwhile
call parent.close()
call b:NERDTree.render()
call parent.putCursorHere(0, 0)
endif
endfunction
" FUNCTION: s:closeTreeWindow() {{{1
" close the tree window
function! s:closeTreeWindow()
if b:NERDTreeType ==# "secondary" && b:NERDTreePreviousBuf != -1
exec "buffer " . b:NERDTreePreviousBuf
else
if winnr("$") > 1
call nerdtree#closeTree()
else
call nerdtree#echo("Cannot close last window")
endif
endif
endfunction
" FUNCTION: s:deleteBookmark(bm) {{{1
" if the cursor is on a bookmark, prompt to delete
function! s:deleteBookmark(bm)
echo "Are you sure you wish to delete the bookmark:\n\"" . a:bm.name . "\" (yN):"
if nr2char(getchar()) ==# 'y'
try
call a:bm.delete()
call b:NERDTree.render()
redraw
catch /^NERDTree/
call nerdtree#echoWarning("Could not remove bookmark")
endtry
else
call nerdtree#echo("delete aborted" )
endif
endfunction
" FUNCTION: s:displayHelp() {{{1
" toggles the help display
function! s:displayHelp()
let b:treeShowHelp = b:treeShowHelp ? 0 : 1
call b:NERDTree.render()
call nerdtree#centerView()
endfunction
" FUNCTION: s:findAndRevealPath() {{{1
function! s:findAndRevealPath()
try
let p = g:NERDTreePath.New(expand("%:p"))
catch /^NERDTree.InvalidArgumentsError/
call nerdtree#echo("no file for the current buffer")
return
endtry
if p.isUnixHiddenPath()
let showhidden=g:NERDTreeShowHidden
let g:NERDTreeShowHidden = 1
endif
if !nerdtree#treeExistsForTab()
try
let cwd = g:NERDTreePath.New(getcwd())
catch /^NERDTree.InvalidArgumentsError/
call nerdtree#echo("current directory does not exist.")
let cwd = p.getParent()
endtry
if p.isUnder(cwd)
call g:NERDTreeCreator.CreatePrimary(cwd.str())
else
call g:NERDTreeCreator.CreatePrimary(p.getParent().str())
endif
else
if !p.isUnder(g:NERDTreeFileNode.GetRootForTab().path)
if !nerdtree#isTreeOpen()
call g:NERDTreeCreator.TogglePrimary('')
else
call nerdtree#putCursorInTreeWin()
endif
let b:NERDTreeShowHidden = g:NERDTreeShowHidden
call nerdtree#chRoot(g:NERDTreeDirNode.New(p.getParent()))
else
if !nerdtree#isTreeOpen()
call g:NERDTreeCreator.TogglePrimary("")
endif
endif
endif
call nerdtree#putCursorInTreeWin()
call b:NERDTreeRoot.reveal(p)
if p.isUnixHiddenFile()
let g:NERDTreeShowHidden = showhidden
endif
endfunction
"FUNCTION: s:handleLeftClick() {{{1
"Checks if the click should open the current node
function! s:handleLeftClick()
let currentNode = g:NERDTreeFileNode.GetSelected()
if currentNode != {}
"the dir arrows are multibyte chars, and vim's string functions only
"deal with single bytes - so split the line up with the hack below and
"take the line substring manually
let line = split(getline(line(".")), '\zs')
let startToCur = ""
for i in range(0,len(line)-1)
let startToCur .= line[i]
endfor
if currentNode.path.isDirectory
if startToCur =~# nerdtree#treeMarkupReg() && startToCur =~# '[+~▾▸] \?$'
call currentNode.activate()
return
endif
endif
if (g:NERDTreeMouseMode ==# 2 && currentNode.path.isDirectory) || g:NERDTreeMouseMode ==# 3
let char = strpart(startToCur, strlen(startToCur)-1, 1)
if char !~# nerdtree#treeMarkupReg()
if currentNode.path.isDirectory
call currentNode.activate()
else
call currentNode.activate({'reuse': 1, 'where': 'p'})
endif
return
endif
endif
endif
endfunction
" FUNCTION: s:handleMiddleMouse() {{{1
function! s:handleMiddleMouse()
let curNode = g:NERDTreeFileNode.GetSelected()
if curNode ==# {}
call nerdtree#echo("Put the cursor on a node first" )
return
endif
if curNode.path.isDirectory
call nerdtree#openExplorer(curNode)
else
call curNode.open({'where': 'h'})
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 nerdtree#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)
call s:jumpToChild(a:node, 0)
endfunction
" FUNCTION: s:jumpToLastChild() {{{1
" wrapper for the jump to child method
function! s:jumpToLastChild(node)
call s:jumpToChild(a:node, 1)
endfunction
" FUNCTION: s:jumpToParent(node) {{{1
" moves the cursor to the parent of the current node
function! s:jumpToParent(node)
if !empty(a:node.parent)
call a:node.parent.putCursorHere(1, 0)
call nerdtree#centerView()
else
call nerdtree#echo("cannot jump to parent")
endif
endfunction
" FUNCTION: s:jumpToRoot() {{{1
" moves the cursor to the root node
function! s:jumpToRoot()
call b:NERDTreeRoot.putCursorHere(1, 0)
call nerdtree#centerView()
endfunction
" FUNCTION: s:jumpToNextSibling(node) {{{1
function! s:jumpToNextSibling(node)
call s:jumpToSibling(a:node, 1)
endfunction
" FUNCTION: s:jumpToPrevSibling(node) {{{1
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
"
" 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 nerdtree#centerView()
endif
endfunction
" FUNCTION: nerdtree#ui_glue#openBookmark(name) {{{1
" put the cursor on the given bookmark and, if its a file, open it
function! nerdtree#ui_glue#openBookmark(name)
try
let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0)
call targetNode.putCursorHere(0, 1)
redraw!
catch /^NERDTree.BookmarkedNodeNotFoundError/
call nerdtree#echo("note - target node is not cached")
let bookmark = g:NERDTreeBookmark.BookmarkFor(a:name)
let targetNode = g:NERDTreeFileNode.New(bookmark.path)
endtry
if targetNode.path.isDirectory
call targetNode.openExplorer()
else
call targetNode.open({'where': 'p'})
endif
endfunction
" FUNCTION: s:openHSplit(target) {{{1
function! s:openHSplit(target)
call a:target.activate({'where': 'h'})
endfunction
" FUNCTION: s:openVSplit(target) {{{1
function! s:openVSplit(target)
call a:target.activate({'where': 'v'})
endfunction
" FUNCTION: s:openExplorer(node) {{{1
function! s:openExplorer(node)
call a:node.openExplorer()
endfunction
" FUNCTION: s:openInNewTab(target) {{{1
function! s:openInNewTab(target)
call a:target.activate({'where': 't'})
endfunction
" FUNCTION: s:openInNewTabSilent(target) {{{1
function! s:openInNewTabSilent(target)
call a:target.activate({'where': 't', 'stay': 1})
endfunction
" FUNCTION: s:openNodeRecursively(node) {{{1
function! s:openNodeRecursively(node)
call nerdtree#echo("Recursively opening node. Please wait...")
call a:node.openRecursively()
call b:NERDTree.render()
redraw
call nerdtree#echo("Recursively opening node. Please wait... DONE")
endfunction
"FUNCTION: s:previewNodeCurrent(node) {{{1
function! s:previewNodeCurrent(node)
call a:node.open({'stay': 1, 'where': 'p', 'keepopen': 1})
endfunction
"FUNCTION: s:previewNodeHSplit(node) {{{1
function! s:previewNodeHSplit(node)
call a:node.open({'stay': 1, 'where': 'h', 'keepopen': 1})
endfunction
"FUNCTION: s:previewNodeVSplit(node) {{{1
function! s:previewNodeVSplit(node)
call a:node.open({'stay': 1, 'where': 'v', 'keepopen': 1})
endfunction
" FUNCTION: nerdtree#ui_glue#revealBookmark(name) {{{1
" put the cursor on the node associate with the given name
function! nerdtree#ui_glue#revealBookmark(name)
try
let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0)
call targetNode.putCursorHere(0, 1)
catch /^NERDTree.BookmarkNotFoundError/
call nerdtree#echo("Bookmark isnt cached under the current root")
endtry
endfunction
" FUNCTION: s:refreshRoot() {{{1
" Reloads the current root. All nodes below this will be lost and the root dir
" will be reloaded.
function! s:refreshRoot()
call nerdtree#echo("Refreshing the root node. This could take a while...")
call b:NERDTreeRoot.refresh()
call b:NERDTree.render()
redraw
call nerdtree#echo("Refreshing the root node. This could take a while... DONE")
endfunction
" FUNCTION: s:refreshCurrent(node) {{{1
" refreshes the root for the current node
function! s:refreshCurrent(node)
let node = a:node
if !node.path.isDirectory
let node = node.parent
endif
call nerdtree#echo("Refreshing node. This could take a while...")
call node.refresh()
call b:NERDTree.render()
redraw
call nerdtree#echo("Refreshing node. This could take a while... DONE")
endfunction
" FUNCTION: nerdtree#ui_glue#setupCommands() {{{1
function! nerdtree#ui_glue#setupCommands()
command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreatePrimary('<args>')
command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.TogglePrimary('<args>')
command! -n=0 -bar NERDTreeClose :call nerdtree#closeTreeIfOpen()
command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreatePrimary('<args>')
command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror()
command! -n=0 -bar NERDTreeFind call nerdtree#ui_glue#findAndRevealPath()
command! -n=0 -bar NERDTreeFocus call NERDTreeFocus()
command! -n=0 -bar NERDTreeCWD call NERDTreeCWD()
endfunction
" Function: s:SID() {{{1
function s:SID()
if !exists("s:sid")
let s:sid = matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')
endif
return s:sid
endfun
" FUNCTION: s:showMenu(node) {{{1
function! s:showMenu(node)
let mc = g:NERDTreeMenuController.New(g:NERDTreeMenuItem.AllEnabled())
call mc.showMenu()
endfunction
" FUNCTION: s:toggleIgnoreFilter() {{{1
" toggles the use of the NERDTreeIgnore option
function! s:toggleIgnoreFilter()
let b:NERDTreeIgnoreEnabled = !b:NERDTreeIgnoreEnabled
call b:NERDTree.ui.renderViewSavingPosition()
call nerdtree#centerView()
endfunction
" FUNCTION: s:toggleShowBookmarks() {{{1
" toggles the display of bookmarks
function! s:toggleShowBookmarks()
let b:NERDTreeShowBookmarks = !b:NERDTreeShowBookmarks
if b:NERDTreeShowBookmarks
call b:NERDTree.render()
call nerdtree#putCursorOnBookmarkTable()
else
call b:NERDTree.ui.renderViewSavingPosition()
endif
call nerdtree#centerView()
endfunction
" FUNCTION: s:toggleShowFiles() {{{1
" toggles the display of hidden files
function! s:toggleShowFiles()
let b:NERDTreeShowFiles = !b:NERDTreeShowFiles
call b:NERDTree.ui.renderViewSavingPosition()
call nerdtree#centerView()
endfunction
" FUNCTION: s:toggleShowHidden() {{{1
" toggles the display of hidden files
function! s:toggleShowHidden()
let b:NERDTreeShowHidden = !b:NERDTreeShowHidden
call b:NERDTree.ui.renderViewSavingPosition()
call nerdtree#centerView()
endfunction
" FUNCTION: s:toggleZoom() {{{1
" zoom (maximize/minimize) the NERDTree window
function! s:toggleZoom()
if exists("b:NERDTreeZoomed") && b:NERDTreeZoomed
let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize
exec "silent vertical resize ". size
let b:NERDTreeZoomed = 0
else
exec "vertical resize"
let b:NERDTreeZoomed = 1
endif
endfunction
"FUNCTION: nerdtree#ui_glue#upDir(keepState) {{{1
"moves the tree up a level
"
"Args:
"keepState: 1 if the current root should be left open when the tree is
"re-rendered
function! nerdtree#ui_glue#upDir(keepState)
let cwd = b:NERDTreeRoot.path.str({'format': 'UI'})
if cwd ==# "/" || cwd =~# '^[^/]..$'
call nerdtree#echo("already at top dir")
else
if !a:keepState
call b:NERDTreeRoot.close()
endif
let oldRoot = b:NERDTreeRoot
if empty(b:NERDTreeRoot.parent)
let path = b:NERDTreeRoot.path.getParent()
let newRoot = g:NERDTreeDirNode.New(path)
call newRoot.open()
call newRoot.transplantChild(b:NERDTreeRoot)
let b:NERDTreeRoot = newRoot
else
let b:NERDTreeRoot = b:NERDTreeRoot.parent
endif
if g:NERDTreeChDirMode ==# 2
call b:NERDTreeRoot.path.changeToDir()
endif
call b:NERDTree.render()
call oldRoot.putCursorHere(0, 0)
endif
endfunction
" FUNCTION: s:upDirCurrentRootOpen() {{{1
function! s:upDirCurrentRootOpen()
call nerdtree#ui_glue#upDir(1)
endfunction
" FUNCTION: s:upDirCurrentRootClosed() {{{1
function! s:upDirCurrentRootClosed()
call nerdtree#ui_glue#upDir(0)
endfunction
" vim: set sw=4 sts=4 et fdm=marker:

View File

@ -275,7 +275,7 @@ function! s:Bookmark.toRoot()
let targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path) let targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path)
endtry endtry
call targetNode.makeRoot() call targetNode.makeRoot()
call nerdtree#renderView() call b:NERDTree.render()
call targetNode.putCursorHere(0, 0) call targetNode.putCursorHere(0, 0)
endif endif
endfunction endfunction
@ -293,7 +293,7 @@ function! s:Bookmark.validate()
return 1 return 1
else else
call s:Bookmark.CacheBookmarks(1) call s:Bookmark.CacheBookmarks(1)
call nerdtree#renderView() call b:NERDTree.render()
call nerdtree#echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.") call nerdtree#echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.")
return 0 return 0
endif endif

View File

@ -12,13 +12,13 @@ function! s:Creator._bindMappings()
call g:NERDTreeKeyMap.BindAll() call g:NERDTreeKeyMap.BindAll()
command! -buffer -nargs=? Bookmark :call nerdtree#bookmarkNode('<args>') command! -buffer -nargs=? Bookmark :call nerdtree#ui_glue#bookmarkNode('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#revealBookmark('<args>') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#ui_glue#revealBookmark('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#openBookmark('<args>') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#ui_glue#openBookmark('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#clearBookmarks('<args>') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#ui_glue#clearBookmarks('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=+ BookmarkToRoot call g:NERDTreeBookmark.ToRoot('<args>') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=+ BookmarkToRoot call g:NERDTreeBookmark.ToRoot('<args>')
command! -buffer -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() <bar> call nerdtree#renderView() command! -buffer -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() <bar> call b:NERDTree.render()
command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) <bar> call nerdtree#renderView() command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) <bar> call b:NERDTree.render()
command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write() command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write()
endfunction endfunction
@ -57,18 +57,15 @@ function! s:Creator.createPrimary(name)
endif endif
call self._createTreeWin() call self._createTreeWin()
let newRoot = g:NERDTreeDirNode.New(path) call self._createNERDTree(path)
let b:NERDTreeRoot = newRoot
let b:NERDTreeType = "primary" let b:NERDTreeType = "primary"
call newRoot.open()
let b:treeShowHelp = 0 let b:treeShowHelp = 0
let b:NERDTreeIgnoreEnabled = 1 let b:NERDTreeIgnoreEnabled = 1
let b:NERDTreeShowFiles = g:NERDTreeShowFiles let b:NERDTreeShowFiles = g:NERDTreeShowFiles
let b:NERDTreeShowHidden = g:NERDTreeShowHidden let b:NERDTreeShowHidden = g:NERDTreeShowHidden
let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks
call nerdtree#renderView() call b:NERDTree.render()
call b:NERDTreeRoot.putCursorHere(0, 0) call b:NERDTreeRoot.putCursorHere(0, 0)
call self._broadcastInitEvent() call self._broadcastInitEvent()
@ -99,18 +96,26 @@ function! s:Creator.createSecondary(dir)
exec "silent edit " . self._nextBufferName() exec "silent edit " . self._nextBufferName()
let b:NERDTreePreviousBuf = bufnr(previousBuf) let b:NERDTreePreviousBuf = bufnr(previousBuf)
call self._createNERDTree(path)
let b:NERDTreeRoot = g:NERDTreeDirNode.New(path)
call b:NERDTreeRoot.open()
call self._setCommonBufOptions() call self._setCommonBufOptions()
let b:NERDTreeType = "secondary" let b:NERDTreeType = "secondary"
call nerdtree#renderView() call b:NERDTree.render()
call self._broadcastInitEvent() call self._broadcastInitEvent()
endfunction endfunction
" FUNCTION: s:Creator._createNERDTree(path) {{{1
function! s:Creator._createNERDTree(path)
let b:NERDTree = g:NERDTree.New(a:path)
"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
" FUNCTION: s:Creator.CreateMirror() {{{1 " FUNCTION: s:Creator.CreateMirror() {{{1
function! s:Creator.CreateMirror() function! s:Creator.CreateMirror()
let creator = s:Creator.New() let creator = s:Creator.New()
@ -122,12 +127,12 @@ function! s:Creator.createMirror()
"get the names off all the nerd tree buffers "get the names off all the nerd tree buffers
let treeBufNames = [] let treeBufNames = []
for i in range(1, tabpagenr("$")) for i in range(1, tabpagenr("$"))
let nextName = nerdtree#tabpagevar(i, 'NERDTreeBufName') let nextName = self._tabpagevar(i, 'NERDTreeBufName')
if nextName != -1 && (!exists("t:NERDTreeBufName") || nextName != t:NERDTreeBufName) if nextName != -1 && (!exists("t:NERDTreeBufName") || nextName != t:NERDTreeBufName)
call add(treeBufNames, nextName) call add(treeBufNames, nextName)
endif endif
endfor endfor
let treeBufNames = nerdtree#unique(treeBufNames) let treeBufNames = self._uniq(treeBufNames)
"map the option names (that the user will be prompted with) to the nerd "map the option names (that the user will be prompted with) to the nerd
"tree buffer names "tree buffer names
@ -166,7 +171,7 @@ function! s:Creator.createMirror()
call self._createTreeWin() call self._createTreeWin()
exec 'buffer ' . bufferName exec 'buffer ' . bufferName
if !&hidden if !&hidden
call nerdtree#renderView() call b:NERDTree.render()
endif endif
endfunction endfunction
@ -290,6 +295,24 @@ function! s:Creator._setupStatusline()
endif endif
endfunction endfunction
" FUNCTION: s:Creator._tabpagevar(tabnr, var) {{{1
function! s:Creator._tabpagevar(tabnr, var)
let currentTab = tabpagenr()
let old_ei = &ei
set ei=all
exec "tabnext " . a:tabnr
let v = -1
if exists('t:' . a:var)
exec 'let v = t:' . a:var
endif
exec "tabnext " . currentTab
let &ei = old_ei
return v
endfunction
"FUNCTION: s:Creator.TogglePrimary(dir) {{{1 "FUNCTION: s:Creator.TogglePrimary(dir) {{{1
function! s:Creator.TogglePrimary(dir) function! s:Creator.TogglePrimary(dir)
let creator = s:Creator.New() let creator = s:Creator.New()
@ -308,9 +331,9 @@ function! s:Creator.togglePrimary(dir)
if !nerdtree#isTreeOpen() if !nerdtree#isTreeOpen()
call self._createTreeWin() call self._createTreeWin()
if !&hidden if !&hidden
call nerdtree#renderView() call b:NERDTree.render()
endif endif
call nerdtree#restoreScreenState() call b:NERDTree.ui.restoreScreenState()
else else
call nerdtree#closeTree() call nerdtree#closeTree()
endif endif
@ -319,4 +342,16 @@ function! s:Creator.togglePrimary(dir)
endif endif
endfunction endfunction
" Function: s:Creator._uniq(list) {{{1
" returns a:list without duplicates
function! s:Creator._uniq(list)
let uniqlist = []
for elem in a:list
if index(uniqlist, elem) ==# -1
let uniqlist += [elem]
endif
endfor
return uniqlist
endfunction
" vim: set sw=4 sts=4 et fdm=marker: " vim: set sw=4 sts=4 et fdm=marker:

View File

@ -44,7 +44,7 @@ function! s:KeyMap.bind()
let premap = self.key == "<LeftRelease>" ? " <LeftRelease>" : " " let premap = self.key == "<LeftRelease>" ? " <LeftRelease>" : " "
exec 'nnoremap <buffer> <silent> '. self.key . premap . ':call nerdtree#invokeKeyMap("'. keymapInvokeString .'")<cr>' exec 'nnoremap <buffer> <silent> '. self.key . premap . ':call nerdtree#ui_glue#invokeKeyMap("'. keymapInvokeString .'")<cr>'
endfunction endfunction
"FUNCTION: KeyMap.Remove(key, scope) {{{1 "FUNCTION: KeyMap.Remove(key, scope) {{{1

23
lib/nerdtree/nerdtree.vim Normal file
View File

@ -0,0 +1,23 @@
"CLASS: NERDTree
"============================================================
let s:NERDTree = {}
let g:NERDTree = s:NERDTree
function! s:NERDTree.ForCurrentBuf()
return b:NERDTree
endfunction
function! s:NERDTree.New(path)
let newObj = copy(self)
let newObj.ui = g:NERDTreeUI.New(newObj)
let newObj.root = g:NERDTreeDirNode.New(a:path)
return newObj
endfunction
"FUNCTION: s:NERDTree.render() {{{1
"A convenience function - since this is called often
function! s:NERDTree.render()
call self.ui.render()
endfunction

View File

@ -3,6 +3,29 @@
let s:Opener = {} let s:Opener = {}
let g:NERDTreeOpener = s:Opener let g:NERDTreeOpener = s:Opener
"FUNCTION: s:Opener._bufInWindows(bnum){{{1
"[[STOLEN FROM VTREEEXPLORER.VIM]]
"Determine the number of windows open to this buffer number.
"Care of Yegappan Lakshman. Thanks!
"
"Args:
"bnum: the subject buffers buffer number
function! s:Opener._bufInWindows(bnum)
let cnt = 0
let winnum = 1
while 1
let bufnum = winbufnr(winnum)
if bufnum < 0
break
endif
if bufnum ==# a:bnum
let cnt = cnt + 1
endif
let winnum = winnum + 1
endwhile
return cnt
endfunction
"FUNCTION: Opener._checkToCloseTree(newtab) {{{1 "FUNCTION: Opener._checkToCloseTree(newtab) {{{1
"Check the class options and global options (i.e. NERDTreeQuitOnOpen) to see "Check the class options and global options (i.e. NERDTreeQuitOnOpen) to see
"if the tree should be closed now. "if the tree should be closed now.
@ -21,6 +44,24 @@ function! s:Opener._checkToCloseTree(newtab)
endif endif
endfunction endfunction
"FUNCTION: s:Opener._firstUsableWindow(){{{1
"find the window number of the first normal window
function! s:Opener._firstUsableWindow()
let i = 1
while i <= winnr("$")
let bnum = winbufnr(i)
if bnum != -1 && getbufvar(bnum, '&buftype') ==# ''
\ && !getwinvar(i, '&previewwindow')
\ && (!getbufvar(bnum, '&modified') || &hidden)
return i
endif
let i += 1
endwhile
return -1
endfunction
"FUNCTION: Opener._gotoTargetWin() {{{1 "FUNCTION: Opener._gotoTargetWin() {{{1
function! s:Opener._gotoTargetWin() function! s:Opener._gotoTargetWin()
if b:NERDTreeType ==# "secondary" if b:NERDTreeType ==# "secondary"
@ -48,6 +89,37 @@ function! s:Opener._gotoTargetWin()
endif endif
endfunction endfunction
"FUNCTION: s:Opener._isWindowUsable(winnumber) {{{1
"Returns 0 if opening a file from the tree in the given window requires it to
"be split, 1 otherwise
"
"Args:
"winnumber: the number of the window in question
function! s:Opener._isWindowUsable(winnumber)
"gotta split if theres only one window (i.e. the NERD tree)
if winnr("$") ==# 1
return 0
endif
let oldwinnr = winnr()
call nerdtree#exec(a:winnumber . "wincmd p")
let specialWindow = getbufvar("%", '&buftype') != '' || getwinvar('%', '&previewwindow')
let modified = &modified
call nerdtree#exec(oldwinnr . "wincmd p")
"if its a special window e.g. quickfix or another explorer plugin then we
"have to split
if specialWindow
return 0
endif
if &hidden
return 1
endif
return !modified || self._bufInWindows(winbufnr(a:winnumber)) >= 2
endfunction
"FUNCTION: Opener.New(path, opts) {{{1 "FUNCTION: Opener.New(path, opts) {{{1
"Args: "Args:
" "
@ -190,7 +262,7 @@ function! s:Opener._openDirectory(node)
call self._gotoTargetWin() call self._gotoTargetWin()
if empty(self._where) if empty(self._where)
call a:node.makeRoot() call a:node.makeRoot()
call nerdtree#renderView() call b:NERDTree.render()
call a:node.putCursorHere(0, 0) call a:node.putCursorHere(0, 0)
elseif self._where == 't' elseif self._where == 't'
call g:NERDTreeCreator.CreatePrimary(a:node.path.str()) call g:NERDTreeCreator.CreatePrimary(a:node.path.str())
@ -206,12 +278,12 @@ endfunction
"FUNCTION: Opener._previousWindow() {{{1 "FUNCTION: Opener._previousWindow() {{{1
function! s:Opener._previousWindow() function! s:Opener._previousWindow()
if !nerdtree#isWindowUsable(winnr("#")) && nerdtree#firstUsableWindow() ==# -1 if !self._isWindowUsable(winnr("#")) && self._firstUsableWindow() ==# -1
call self._newSplit() call self._newSplit()
else else
try try
if !nerdtree#isWindowUsable(winnr("#")) if !self._isWindowUsable(winnr("#"))
call nerdtree#exec(nerdtree#firstUsableWindow() . "wincmd w") call nerdtree#exec(self._firstUsableWindow() . "wincmd w")
else else
call nerdtree#exec('wincmd p') call nerdtree#exec('wincmd p')
endif endif

View File

@ -172,7 +172,7 @@ function! s:Path.copy(dest)
let dest = s:Path.WinToUnixPath(a:dest) let dest = s:Path.WinToUnixPath(a:dest)
let cmd = g:NERDTreeCopyCmd . " " . escape(self.str(), nerdtree#escChars()) . " " . escape(dest, nerdtree#escChars()) let cmd = g:NERDTreeCopyCmd . " " . escape(self.str(), self._escChars()) . " " . escape(dest, self._escChars())
let success = system(cmd) let success = system(cmd)
if success != 0 if success != 0
throw "NERDTree.CopyError: Could not copy ''". self.str() ."'' to: '" . a:dest . "'" throw "NERDTree.CopyError: Could not copy ''". self.str() ."'' to: '" . a:dest . "'"
@ -291,6 +291,15 @@ function! s:Path.exists()
return filereadable(p) || isdirectory(p) return filereadable(p) || isdirectory(p)
endfunction endfunction
"FUNCTION: Path._escChars() {{{1
function! s:Path._escChars()
if nerdtree#runningWindows()
return " `\|\"#%&,?()\*^<>"
endif
return " \\`\|\"#%&,?()\*^<>[]"
endfunction
"FUNCTION: Path.getDir() {{{1 "FUNCTION: Path.getDir() {{{1
" "
"Returns this path if it is a directory, else this paths parent. "Returns this path if it is a directory, else this paths parent.
@ -635,7 +644,7 @@ endfunction
" "
" returns a string that can be used with :cd " returns a string that can be used with :cd
function! s:Path._strForCd() function! s:Path._strForCd()
return escape(self.str(), nerdtree#escChars()) return escape(self.str(), self._escChars())
endfunction endfunction
"FUNCTION: Path._strForEdit() {{{1 "FUNCTION: Path._strForEdit() {{{1
@ -643,7 +652,7 @@ endfunction
"Return: the string for this path that is suitable to be used with the :edit "Return: the string for this path that is suitable to be used with the :edit
"command "command
function! s:Path._strForEdit() function! s:Path._strForEdit()
let p = escape(self.str({'format': 'UI'}), nerdtree#escChars()) let p = escape(self.str({'format': 'UI'}), self._escChars())
let cwd = getcwd() . s:Path.Slash() let cwd = getcwd() . s:Path.Slash()
"return a relative path if we can "return a relative path if we can
@ -683,7 +692,7 @@ function! s:Path._strForGlob()
let toReturn = lead . join(self.pathSegments, s:Path.Slash()) let toReturn = lead . join(self.pathSegments, s:Path.Slash())
if !nerdtree#runningWindows() if !nerdtree#runningWindows()
let toReturn = escape(toReturn, nerdtree#escChars()) let toReturn = escape(toReturn, self._escChars())
endif endif
return toReturn return toReturn
endfunction endfunction

View File

@ -21,7 +21,7 @@ unlet s:TreeDirNode.activate
function! s:TreeDirNode.activate(...) function! s:TreeDirNode.activate(...)
let opts = a:0 ? a:1 : {} let opts = a:0 ? a:1 : {}
call self.toggleOpen(opts) call self.toggleOpen(opts)
call nerdtree#renderView() call b:NERDTree.render()
call self.putCursorHere(0, 0) call self.putCursorHere(0, 0)
endfunction endfunction
@ -460,7 +460,7 @@ function! s:TreeDirNode.reveal(path)
if self.path.equals(a:path.getParent()) if self.path.equals(a:path.getParent())
let n = self.findNode(a:path) let n = self.findNode(a:path)
call nerdtree#renderView() call b:NERDTree.render()
call n.putCursorHere(1,0) call n.putCursorHere(1,0)
return return
endif endif

View File

@ -178,55 +178,6 @@ function! s:TreeFileNode.findSibling(direction)
return {} return {}
endfunction endfunction
"FUNCTION: TreeFileNode.getLineNum(){{{1
"returns the line number this node is rendered on, or -1 if it isnt rendered
function! s:TreeFileNode.getLineNum()
"if the node is the root then return the root line no.
if self.isRoot()
return s:TreeFileNode.GetRootLineNum()
endif
let totalLines = line("$")
"the path components we have matched so far
let pathcomponents = [substitute(b:NERDTreeRoot.path.str({'format': 'UI'}), '/ *$', '', '')]
"the index of the component we are searching for
let curPathComponent = 1
let fullpath = self.path.str({'format': 'UI'})
let lnum = s:TreeFileNode.GetRootLineNum()
while lnum > 0
let lnum = lnum + 1
"have we reached the bottom of the tree?
if lnum ==# totalLines+1
return -1
endif
let curLine = getline(lnum)
let indent = nerdtree#indentLevelFor(curLine)
if indent ==# curPathComponent
let curLine = nerdtree#stripMarkupFromLine(curLine, 1)
let curPath = join(pathcomponents, '/') . '/' . curLine
if stridx(fullpath, curPath, 0) ==# 0
if fullpath ==# curPath || strpart(fullpath, len(curPath)-1,1) ==# '/'
let curLine = substitute(curLine, '/ *$', '', '')
call add(pathcomponents, curLine)
let curPathComponent = curPathComponent + 1
if fullpath ==# curPath
return lnum
endif
endif
endif
endif
endwhile
return -1
endfunction
"FUNCTION: TreeFileNode.GetRootForTab(){{{1 "FUNCTION: TreeFileNode.GetRootForTab(){{{1
"get the root node for this tab "get the root node for this tab
function! s:TreeFileNode.GetRootForTab() function! s:TreeFileNode.GetRootForTab()
@ -236,21 +187,11 @@ function! s:TreeFileNode.GetRootForTab()
return {} return {}
endfunction endfunction
"FUNCTION: TreeFileNode.GetRootLineNum(){{{1
"gets the line number of the root node
function! s:TreeFileNode.GetRootLineNum()
let rootLine = 1
while getline(rootLine) !~# '^\(/\|<\)'
let rootLine = rootLine + 1
endwhile
return rootLine
endfunction
"FUNCTION: TreeFileNode.GetSelected() {{{1 "FUNCTION: TreeFileNode.GetSelected() {{{1
"gets the treenode that the cursor is currently over "gets the treenode that the cursor is currently over
function! s:TreeFileNode.GetSelected() function! s:TreeFileNode.GetSelected()
try try
let path = nerdtree#getPath(line(".")) let path = b:NERDTree.ui.getPath(line("."))
if path ==# {} if path ==# {}
return {} return {}
endif endif
@ -348,7 +289,7 @@ endfunction
"recurseUpward: try to put the cursor on the parent if the this node isnt "recurseUpward: try to put the cursor on the parent if the this node isnt
"visible "visible
function! s:TreeFileNode.putCursorHere(isJump, recurseUpward) function! s:TreeFileNode.putCursorHere(isJump, recurseUpward)
let ln = self.getLineNum() let ln = b:NERDTree.ui.getLineNum(self)
if ln != -1 if ln != -1
if a:isJump if a:isJump
mark ' mark '
@ -357,11 +298,11 @@ function! s:TreeFileNode.putCursorHere(isJump, recurseUpward)
else else
if a:recurseUpward if a:recurseUpward
let node = self let node = self
while node != {} && node.getLineNum() ==# -1 while node != {} && b:NERDTree.ui.getLineNum(node) ==# -1
let node = node.parent let node = node.parent
call node.open() call node.open()
endwhile endwhile
call nerdtree#renderView() call b:NERDTree.render()
call node.putCursorHere(a:isJump, 0) call node.putCursorHere(a:isJump, 0)
endif endif
endif endif

262
lib/nerdtree/ui.vim Normal file
View File

@ -0,0 +1,262 @@
"CLASS: UI
"============================================================
let s:UI = {}
let g:NERDTreeUI = s:UI
function! s:UI.New(nerdtree)
let newObj = copy(self)
let newObj.nerdtree = a:nerdtree
return newObj
endfunction
"FUNCTION: s:UI.getPath(ln) {{{1
"Gets the full path to the node that is rendered on the given line number
"
"Args:
"ln: the line number to get the path for
"
"Return:
"A path if a node was selected, {} if nothing is selected.
"If the 'up a dir' line was selected then the path to the parent of the
"current root is returned
function! s:UI.getPath(ln)
let line = getline(a:ln)
let rootLine = self.getRootLineNum()
"check to see if we have the root node
if a:ln == rootLine
return b:NERDTreeRoot.path
endif
if !g:NERDTreeDirArrows
" in case called from outside the tree
if line !~# '^ *[|`▸▾ ]' || line =~# '^$'
return {}
endif
endif
if line ==# nerdtree#treeUpDirLine()
return b:NERDTreeRoot.path.getParent()
endif
let indent = self._indentLevelFor(line)
"remove the tree parts and the leading space
let curFile = nerdtree#stripMarkupFromLine(line, 0)
let wasdir = 0
if curFile =~# '/$'
let wasdir = 1
let curFile = substitute(curFile, '/\?$', '/', "")
endif
let dir = ""
let lnum = a:ln
while lnum > 0
let lnum = lnum - 1
let curLine = getline(lnum)
let curLineStripped = nerdtree#stripMarkupFromLine(curLine, 1)
"have we reached the top of the tree?
if lnum == rootLine
let dir = b:NERDTreeRoot.path.str({'format': 'UI'}) . dir
break
endif
if curLineStripped =~# '/$'
let lpindent = self._indentLevelFor(curLine)
if lpindent < indent
let indent = indent - 1
let dir = substitute (curLineStripped,'^\\', "", "") . dir
continue
endif
endif
endwhile
let curFile = b:NERDTreeRoot.path.drive . dir . curFile
let toReturn = g:NERDTreePath.New(curFile)
return toReturn
endfunction
"FUNCTION: s:UI.getLineNum(file_node){{{1
"returns the line number this node is rendered on, or -1 if it isnt rendered
function! s:UI.getLineNum(file_node)
"if the node is the root then return the root line no.
if a:file_node.isRoot()
return b:NERDTree.ui.getRootLineNum()
endif
let totalLines = line("$")
"the path components we have matched so far
let pathcomponents = [substitute(b:NERDTreeRoot.path.str({'format': 'UI'}), '/ *$', '', '')]
"the index of the component we are searching for
let curPathComponent = 1
let fullpath = a:file_node.path.str({'format': 'UI'})
let lnum = b:NERDTree.ui.getRootLineNum()
while lnum > 0
let lnum = lnum + 1
"have we reached the bottom of the tree?
if lnum ==# totalLines+1
return -1
endif
let curLine = getline(lnum)
let indent = self._indentLevelFor(curLine)
if indent ==# curPathComponent
let curLine = nerdtree#stripMarkupFromLine(curLine, 1)
let curPath = join(pathcomponents, '/') . '/' . curLine
if stridx(fullpath, curPath, 0) ==# 0
if fullpath ==# curPath || strpart(fullpath, len(curPath)-1,1) ==# '/'
let curLine = substitute(curLine, '/ *$', '', '')
call add(pathcomponents, curLine)
let curPathComponent = curPathComponent + 1
if fullpath ==# curPath
return lnum
endif
endif
endif
endif
endwhile
return -1
endfunction
"FUNCTION: s:UI.getRootLineNum(){{{1
"gets the line number of the root node
function! s:UI.getRootLineNum()
let rootLine = 1
while getline(rootLine) !~# '^\(/\|<\)'
let rootLine = rootLine + 1
endwhile
return rootLine
endfunction
"FUNCTION: s:UI._indentLevelFor(line) {{{2
function! s:UI._indentLevelFor(line)
let level = match(a:line, '[^ \-+~▸▾`|]') / nerdtree#treeWid()
" check if line includes arrows
if match(a:line, '[▸▾]') > -1
" decrement level as arrow uses 3 ascii chars
let level = level - 1
endif
return level
endfunction
"FUNCTION: s:UI.restoreScreenState() {{{2
"
"Sets the screen state back to what it was when nerdtree#saveScreenState was last
"called.
"
"Assumes the cursor is in the NERDTree window
function! s:UI.restoreScreenState()
if !has_key(self, '_screenState')
return
endif
exec("silent vertical resize " . self._screenState['oldWindowSize'])
let old_scrolloff=&scrolloff
let &scrolloff=0
call cursor(self._screenState['oldTopLine'], 0)
normal! zt
call setpos(".", self._screenState['oldPos'])
let &scrolloff=old_scrolloff
endfunction
"FUNCTION: s:UI.saveScreenState() {{{2
"Saves the current cursor position in the current buffer and the window
"scroll position
function! s:UI.saveScreenState()
let win = winnr()
try
call nerdtree#putCursorInTreeWin()
let self._screenState = {}
let self._screenState['oldPos'] = getpos(".")
let self._screenState['oldTopLine'] = line("w0")
let self._screenState['oldWindowSize']= winwidth("")
call nerdtree#exec(win . "wincmd w")
catch /^NERDTree.InvalidOperationError/
endtry
endfunction
"FUNCTION: s:UI.render() {{{2
function! s:UI.render()
setlocal modifiable
"remember the top line of the buffer and the current line so we can
"restore the view exactly how it was
let curLine = line(".")
let curCol = col(".")
let topLine = line("w0")
"delete all lines in the buffer (being careful not to clobber a register)
silent 1,$delete _
call nerdtree#dumpHelp()
"delete the blank line before the help and add one after it
if g:NERDTreeMinimalUI == 0
call setline(line(".")+1, "")
call cursor(line(".")+1, col("."))
endif
if b:NERDTreeShowBookmarks
call nerdtree#renderBookmarks()
endif
"add the 'up a dir' line
if !g:NERDTreeMinimalUI
call setline(line(".")+1, nerdtree#treeUpDirLine())
call cursor(line(".")+1, col("."))
endif
"draw the header line
let header = b:NERDTreeRoot.path.str({'format': 'UI', 'truncateTo': winwidth(0)})
call setline(line(".")+1, header)
call cursor(line(".")+1, col("."))
"draw the tree
let old_o = @o
let @o = b:NERDTreeRoot.renderToString()
silent put o
let @o = old_o
"delete the blank line at the top of the buffer
silent 1,1delete _
"restore the view
let old_scrolloff=&scrolloff
let &scrolloff=0
call cursor(topLine, 1)
normal! zt
call cursor(curLine, curCol)
let &scrolloff = old_scrolloff
setlocal nomodifiable
endfunction
"FUNCTION: UI.renderViewSavingPosition {{{1
"Renders the tree and ensures the cursor stays on the current node or the
"current nodes parent if it is no longer available upon re-rendering
function! s:UI.renderViewSavingPosition()
let currentNode = g:NERDTreeFileNode.GetSelected()
"go up the tree till we find a node that will be visible or till we run
"out of nodes
while currentNode != {} && !currentNode.isVisible() && !currentNode.isRoot()
let currentNode = currentNode.parent
endwhile
call b:NERDTree.render()
if currentNode != {}
call currentNode.putCursorHere(0, 0)
endif
endfunction

View File

@ -117,7 +117,7 @@ function! NERDTreeAddNode()
let newTreeNode = g:NERDTreeFileNode.New(newPath) let newTreeNode = g:NERDTreeFileNode.New(newPath)
if empty(parentNode) if empty(parentNode)
call b:NERDTreeRoot.refresh() call b:NERDTreeRoot.refresh()
call nerdtree#renderView() call b:NERDTree.render()
elseif parentNode.isOpen || !empty(parentNode.children) elseif parentNode.isOpen || !empty(parentNode.children)
call parentNode.addChild(newTreeNode, 1) call parentNode.addChild(newTreeNode, 1)
call NERDTreeRender() call NERDTreeRender()
@ -230,7 +230,7 @@ function! NERDTreeCopyNode()
let newNode = currentNode.copy(newNodePath) let newNode = currentNode.copy(newNodePath)
if empty(newNode) if empty(newNode)
call b:NERDTreeRoot.refresh() call b:NERDTreeRoot.refresh()
call nerdtree#renderView() call b:NERDTree.render()
else else
call NERDTreeRender() call NERDTreeRender()
call newNode.putCursorHere(0, 0) call newNode.putCursorHere(0, 0)

View File

@ -142,20 +142,13 @@ call nerdtree#loadClassFiles()
" SECTION: Commands {{{1 " SECTION: Commands {{{1
"============================================================ "============================================================
"init the command that users start the nerd tree with call nerdtree#ui_glue#setupCommands()
command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreatePrimary('<args>')
command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.TogglePrimary('<args>')
command! -n=0 -bar NERDTreeClose :call nerdtree#closeTreeIfOpen()
command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreatePrimary('<args>')
command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror()
command! -n=0 -bar NERDTreeFind call nerdtree#findAndRevealPath()
command! -n=0 -bar NERDTreeFocus call NERDTreeFocus()
command! -n=0 -bar NERDTreeCWD call NERDTreeCWD()
" SECTION: Auto commands {{{1 " SECTION: Auto commands {{{1
"============================================================ "============================================================
augroup NERDTree augroup NERDTree
"Save the cursor position whenever we close the nerd tree "Save the cursor position whenever we close the nerd tree
exec "autocmd BufWinLeave ". g:NERDTreeCreator.BufNamePrefix() ."* call nerdtree#saveScreenState()" exec "autocmd BufWinLeave ". g:NERDTreeCreator.BufNamePrefix() ."* call b:NERDTree.ui.saveScreenState()"
"disallow insert mode in the NERDTree "disallow insert mode in the NERDTree
exec "autocmd BufEnter ". g:NERDTreeCreator.BufNamePrefix() ."* stopinsert" exec "autocmd BufEnter ". g:NERDTreeCreator.BufNamePrefix() ."* stopinsert"