Merge remote-tracking branch 'forkorigin/master'

Conflicts:
	autoload/nerdtree.vim
This commit is contained in:
Luke Petherbridge 2014-11-20 21:35:01 -08:00
commit fa0795acaa
20 changed files with 1523 additions and 1212 deletions

View File

@ -60,7 +60,7 @@ Installation
cd ~/.vim/bundle
git clone https://github.com/scrooloose/nerdtree.git
Then reload vim, run `:helptags`, and check out `:help NERD_tree.txt`.
Then reload vim, run `:Helptags`, and check out `:help NERD_tree.txt`.
Faq
@ -80,11 +80,16 @@ A. Stick this in your vimrc: `autocmd vimenter * NERDTree`
__Q. How can I open a NERDTree automatically when vim starts up if no files were specified?__
A. Stick this in your vimrc `autocmd vimenter * if !argc() | NERDTree | endif`
A. Stick this in your vimrc
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
__Q. How can I map a specific key or shortcut to open NERDTree?__
A. Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever key you want): `map <C-n> :NERDTreeToggle<CR>`
A. Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever key you want):
`map <C-n> :NERDTreeToggle<CR>`
__Q. How can I close vim if the only window left open is a NERDTree?__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,644 @@
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 s: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 b:NERDTree.ui.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 !g:NERDTree.ExistsForTab()
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 s: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 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)
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 b:NERDTree.ui.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 b:NERDTree.ui.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 b:NERDTree.ui.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 s: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
function! s:toggleIgnoreFilter()
call b:NERDTree.ui.toggleIgnoreFilter()
endfunction
" FUNCTION: s:toggleShowBookmarks() {{{1
function! s:toggleShowBookmarks()
call b:NERDTree.ui.toggleShowBookmarks()
endfunction
" FUNCTION: s:toggleShowFiles() {{{1
function! s:toggleShowFiles()
call b:NERDTree.ui.toggleShowFiles()
endfunction
" FUNCTION: s:toggleShowHidden() {{{1
" toggles the display of hidden files
function! s:toggleShowHidden()
call b:NERDTree.ui.toggleShowHidden()
endfunction
" FUNCTION: s:toggleZoom() {{{1
function! s:toggleZoom()
call b:NERDTree.ui.toggleZoom()
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

@ -109,7 +109,7 @@ The following features and functionality are provided by the NERD tree:
<
:NERDTreeFromBookmark <bookmark> *:NERDTreeFromBookmark*
Opens a fresh NERD tree with the root initialized to the dir for
<bookmark>. This only reason to use this command over :NERDTree is for
<bookmark>. The only reason to use this command over :NERDTree is for
the completion (which is for bookmarks rather than directories).
:NERDTreeToggle [<start-directory> | <bookmark>] *:NERDTreeToggle*
@ -160,7 +160,7 @@ click bookmarks or use the |NERDTree-o| mapping to activate them. See also,
Note that the following commands are only available in the NERD tree buffer.
:Bookmark <name>
:Bookmark [<name>]
Bookmark the current node as <name>. If there is already a <name>
bookmark, it is overwritten. <name> must not contain spaces.
If <name> is not provided, it defaults to the file or directory name.
@ -358,7 +358,7 @@ Default key: O
Map option: NERDTreeMapOpenRecursively
Applies to: directories.
Recursively opens the selelected directory.
Recursively opens the selected directory.
All files and directories are cached, but if a directory would not be
displayed due to file filters (see |'NERDTreeIgnore'| |NERDTree-f|) or the
@ -462,8 +462,8 @@ Jump to the previous sibling of the selected node.
------------------------------------------------------------------------------
*NERDTree-C*
Default key: C
Map option: NERDTreeMapChdir
Applies to: directories.
Map option: NERDTreeMapChangeRoot
Applies to: files and directories.
Make the selected directory node the new tree root. If a file is selected, its
parent is used.
@ -609,17 +609,19 @@ NERD tree. These options should be set in your vimrc.
|'loaded_nerd_tree'| Turns off the script.
|'NERDChristmasTree'| Tells the NERD tree to make itself colourful
and pretty.
|'NERDTreeAutoCenter'| Controls whether the NERD tree window centers
when the cursor moves within a specified
distance to the top/bottom of the window.
|'NERDTreeAutoCenterThreshold'| Controls the sensitivity of autocentering.
|'NERDTreeCaseSensitiveSort'| Tells the NERD tree whether to be case
sensitive or not when sorting nodes.
|'NERDTreeSortHiddenFirst'| Tells the NERD tree whether to take the dot
at the beginning of the hidden file names
into account when sorting nodes.
|'NERDTreeChDirMode'| Tells the NERD tree if/when it should change
vim's current working directory.
@ -631,8 +633,13 @@ NERD tree. These options should be set in your vimrc.
|'NERDTreeIgnore'| Tells the NERD tree which files to ignore.
|'NERDTreeRespectWildIgnore'| Tells the NERD tree to respect |'wildignore'|.
|'NERDTreeBookmarksFile'| Where the bookmarks are stored.
|'NERDTreeBookmarksSort'| Whether the bookmarks list is sorted on
display.
|'NERDTreeMouseMode'| Tells the NERD tree how to handle mouse
clicks.
@ -667,8 +674,8 @@ NERD tree. These options should be set in your vimrc.
|'NERDTreeDirArrows'| Tells the NERD tree to use arrows instead of
+ ~ chars when displaying directories.
|'NERDTreeCasadeOpenSingleChildDir'|
Casade open while selected directory has only
|'NERDTreeCascadeOpenSingleChildDir'|
Cascade open while selected directory has only
one child that also is a directory.
|'NERDTreeAutoDeleteBuffer'| Tells the NERD tree to automatically remove
@ -686,15 +693,6 @@ If this plugin is making you feel homicidal, it may be a good idea to turn it
off with this line in your vimrc: >
let loaded_nerd_tree=1
<
------------------------------------------------------------------------------
*'NERDChristmasTree'*
Values: 0 or 1.
Default: 1.
If this option is set to 1 then some extra syntax highlighting elements are
added to the nerd tree to make it more colourful.
Set it to 0 for a more vanilla looking tree.
------------------------------------------------------------------------------
*'NERDTreeAutoCenter'*
@ -817,6 +815,13 @@ line: >
The file filters can be turned on and off dynamically with the |NERDTree-f|
mapping.
------------------------------------------------------------------------------
*'NERDTreeRespectWildIgnore'*
Values: 0 or 1.
Default: 0.
If set to 1, the |'wildignore'| setting is respected.
------------------------------------------------------------------------------
*'NERDTreeBookmarksFile'*
Values: a path
@ -824,6 +829,14 @@ Default: $HOME/.NERDTreeBookmarks
This is where bookmarks are saved. See |NERDTreeBookmarkCommands|.
------------------------------------------------------------------------------
*'NERDTreeBookmarksSort'*
Values: 0 or 1
Default: 1
If set to 0 then the bookmarks list is not sorted.
If set to 1 the bookmarks list is sorted.
------------------------------------------------------------------------------
*'NERDTreeMouseMode'*
Values: 1, 2 or 3.
@ -987,16 +1000,17 @@ option: >
<
------------------------------------------------------------------------------
*'NERDTreeCasadeOpenSingleChildDir'*
*'NERDTreeCascadeOpenSingleChildDir'*
Values: 0 or 1
Default: 1.
When opening dir nodes, this option tells NERDTree to recursively open dirs
that have only one child which is also a dir. NERDTree will stop when it finds
a dir that contains anything but another single dir. This option may be useful
for Java projects. Use one of the follow lines to set this option: >
let NERDTreeCasadeOpenSingleChildDir=0
let NERDTreeCasadeOpenSingleChildDir=1
a dir that contains anything but another single dir. This option also causes
the |NERDTree-x| mapping to close dirs in the same manner. This option may be
useful for Java projects. Use one of the follow lines to set this option: >
let NERDTreeCascadeOpenSingleChildDir=0
let NERDTreeCascadeOpenSingleChildDir=1
<
------------------------------------------------------------------------------
@ -1046,6 +1060,9 @@ NERDTreeAddKeyMap({options}) *NERDTreeAddKeyMap()*
"callback" - the function the new mapping will be bound to
"quickhelpText" - the text that will appear in the quickhelp (see
|NERDTree-?|)
"override" - if 1 then this new mapping will override whatever previous
mapping was defined for the key/scope combo. Useful for overriding the
default mappings.
Additionally, a "scope" argument may be supplied. This constrains the
mapping so that it is only activated if the cursor is on a certain object.
@ -1062,8 +1079,8 @@ NERDTreeAddKeyMap({options}) *NERDTreeAddKeyMap()*
call NERDTreeAddKeyMap({
\ 'key': 'foo',
\ 'callback': 'NERDTreeCDHandler',
\ 'quickhelpText': 'echo full path of current node' })
\ 'scope': 'DirNode'
\ 'quickhelpText': 'echo full path of current node',
\ 'scope': 'DirNode' })
function! NERDTreeCDHandler(dirnode)
call a:dirnode.changeToDir()

View File

@ -19,7 +19,9 @@ function! s:Bookmark.AddBookmark(name, path)
endif
endfor
call add(s:Bookmark.Bookmarks(), s:Bookmark.New(a:name, a:path))
call s:Bookmark.Sort()
if g:NERDTreeBookmarksSort ==# 1
call s:Bookmark.Sort()
endif
endfunction
" FUNCTION: Bookmark.Bookmarks() {{{1
@ -101,7 +103,9 @@ function! s:Bookmark.CacheBookmarks(silent)
call nerdtree#echo(invalidBookmarksFound . " invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.")
endif
endif
call s:Bookmark.Sort()
if g:NERDTreeBookmarksSort ==# 1
call s:Bookmark.Sort()
endif
endif
endfunction
@ -271,7 +275,7 @@ function! s:Bookmark.toRoot()
let targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path)
endtry
call targetNode.makeRoot()
call nerdtree#renderView()
call b:NERDTree.render()
call targetNode.putCursorHere(0, 0)
endif
endfunction
@ -289,7 +293,7 @@ function! s:Bookmark.validate()
return 1
else
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.")
return 0
endif

View File

@ -7,18 +7,18 @@ let g:NERDTreeCreator = s:Creator
"FUNCTION: s:Creator._bindMappings() {{{1
function! s:Creator._bindMappings()
"make <cr> do the same as the default 'o' mapping
exec "nnoremap <silent> <buffer> <cr> :call nerdtree#invokeKeyMap('". g:NERDTreeMapActivateNode ."')<cr>"
"make <cr> do the same as the activate node mapping
nnoremap <silent> <buffer> <cr> :call nerdtree#ui_glue#invokeKeyMap(g:NERDTreeMapActivateNode)<cr>
call g:NERDTreeKeyMap.BindAll()
command! -buffer -nargs=? Bookmark :call nerdtree#bookmarkNode('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#revealBookmark('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#openBookmark('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#clearBookmarks('<args>')
command! -buffer -nargs=? Bookmark :call nerdtree#ui_glue#bookmarkNode('<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#ui_glue#openBookmark('<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 -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() <bar> call nerdtree#renderView()
command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) <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 b:NERDTree.render()
command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write()
endfunction
@ -49,26 +49,23 @@ function! s:Creator.createPrimary(name)
call path.changeToDir()
endif
if nerdtree#treeExistsForTab()
if g:NERDTree.ExistsForTab()
if nerdtree#isTreeOpen()
call nerdtree#closeTree()
endif
unlet t:NERDTreeBufName
endif
let newRoot = g:NERDTreeDirNode.New(path)
call newRoot.open()
call self._createTreeWin()
call self._createNERDTree(path)
let b:NERDTreeType = "primary"
let b:treeShowHelp = 0
let b:NERDTreeIgnoreEnabled = 1
let b:NERDTreeShowFiles = g:NERDTreeShowFiles
let b:NERDTreeShowHidden = g:NERDTreeShowHidden
let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks
let b:NERDTreeRoot = newRoot
let b:NERDTreeType = "primary"
call nerdtree#renderView()
call b:NERDTree.render()
call b:NERDTreeRoot.putCursorHere(0, 0)
call self._broadcastInitEvent()
@ -99,18 +96,26 @@ function! s:Creator.createSecondary(dir)
exec "silent edit " . self._nextBufferName()
let b:NERDTreePreviousBuf = bufnr(previousBuf)
let b:NERDTreeRoot = g:NERDTreeDirNode.New(path)
call b:NERDTreeRoot.open()
call self._createNERDTree(path)
call self._setCommonBufOptions()
let b:NERDTreeType = "secondary"
call nerdtree#renderView()
call b:NERDTree.render()
call self._broadcastInitEvent()
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()
let creator = s:Creator.New()
@ -122,12 +127,12 @@ function! s:Creator.createMirror()
"get the names off all the nerd tree buffers
let treeBufNames = []
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)
call add(treeBufNames, nextName)
endif
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
"tree buffer names
@ -158,7 +163,7 @@ function! s:Creator.createMirror()
return
endif
if nerdtree#treeExistsForTab() && nerdtree#isTreeOpen()
if g:NERDTree.ExistsForTab() && nerdtree#isTreeOpen()
call nerdtree#closeTree()
endif
@ -166,7 +171,7 @@ function! s:Creator.createMirror()
call self._createTreeWin()
exec 'buffer ' . bufferName
if !&hidden
call nerdtree#renderView()
call b:NERDTree.render()
endif
endfunction
@ -279,8 +284,8 @@ function! s:Creator._setCommonBufOptions()
let b:NERDTreeShowFiles = g:NERDTreeShowFiles
let b:NERDTreeShowHidden = g:NERDTreeShowHidden
let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks
setfiletype nerdtree
call self._bindMappings()
setlocal filetype=nerdtree
endfunction
"FUNCTION: s:Creator._setupStatusline() {{{1
@ -290,6 +295,24 @@ function! s:Creator._setupStatusline()
endif
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)
let creator = s:Creator.New()
@ -304,13 +327,13 @@ endfunction
"dir: the full path for the root node (is only used if the NERD tree is being
"initialized.
function! s:Creator.togglePrimary(dir)
if nerdtree#treeExistsForTab()
if g:NERDTree.ExistsForTab()
if !nerdtree#isTreeOpen()
call self._createTreeWin()
if !&hidden
call nerdtree#renderView()
call b:NERDTree.render()
endif
call nerdtree#restoreScreenState()
call b:NERDTree.ui.restoreScreenState()
else
call nerdtree#closeTree()
endif
@ -319,4 +342,16 @@ function! s:Creator.togglePrimary(dir)
endif
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:

13
lib/nerdtree/event.vim Normal file
View File

@ -0,0 +1,13 @@
"CLASS: Event
"============================================================
let s:Event = {}
let g:NERDTreeEvent = s:Event
function! s:Event.New(nerdtree, subject, action, params) abort
let newObj = copy(self)
let newObj.nerdtree = a:nerdtree
let newObj.subject = a:subject
let newObj.action = a:action
let newObj.params = a:params
return newObj
endfunction

56
lib/nerdtree/flag_set.vim Normal file
View File

@ -0,0 +1,56 @@
"CLASS: FlagSet
"============================================================
let s:FlagSet = {}
let g:NERDTreeFlagSet = s:FlagSet
"FUNCTION: FlagSet.addFlag(scope, flag) {{{1
function! s:FlagSet.addFlag(scope, flag)
let flags = self._flagsForScope(a:scope)
if index(flags, a:flag) == -1
call add(flags, a:flag)
end
endfunction
"FUNCTION: FlagSet.clearFlags(scope) {{{1
function! s:FlagSet.clearFlags(scope)
let self._flags[a:scope] = []
endfunction
"FUNCTION: FlagSet._flagsForScope(scope) {{{1
function! s:FlagSet._flagsForScope(scope)
if !has_key(self._flags, a:scope)
let self._flags[a:scope] = []
endif
return self._flags[a:scope]
endfunction
"FUNCTION: FlagSet.New() {{{1
function! s:FlagSet.New()
let newObj = copy(self)
let newObj._flags = {}
return newObj
endfunction
"FUNCTION: FlagSet.removeFlag(scope, flag) {{{1
function! s:FlagSet.removeFlag(scope, flag)
let flags = self._flagsForScope(a:scope)
let i = index(flags, a:flag)
if i >= 0
call remove(flags, i)
endif
endfunction
"FUNCTION: FlagSet.renderToString() {{{1
function! s:FlagSet.renderToString()
let flagstring = ""
for i in values(self._flags)
let flagstring .= join(i)
endfor
if len(flagstring) == 0
return ""
endif
return '[' . flagstring . ']'
endfunction

View File

@ -44,7 +44,7 @@ function! s:KeyMap.bind()
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
"FUNCTION: KeyMap.Remove(key, scope) {{{1
@ -79,6 +79,16 @@ endfunction
"If a keymap has the scope of "all" then it will be called if no other keymap
"is found for a:key and the scope.
function! s:KeyMap.Invoke(key)
"required because clicking the command window below another window still
"invokes the <LeftRelease> mapping - but changes the window cursor
"is in first
"
"TODO: remove this check when the vim bug is fixed
if !g:NERDTree.ExistsForBuf()
return {}
endif
let node = g:NERDTreeFileNode.GetSelected()
if !empty(node)
@ -124,8 +134,14 @@ endfunction
"FUNCTION: KeyMap.Create(options) {{{1
function! s:KeyMap.Create(options)
let newKeyMap = copy(self)
let opts = extend({'scope': 'all', 'quickhelpText': ''}, copy(a:options))
"dont override other mappings unless the 'override' option is given
if get(opts, 'override', 0) == 0 && !empty(s:KeyMap.FindFor(opts['key'], opts['scope']))
return
end
let newKeyMap = copy(self)
let newKeyMap.key = opts['key']
let newKeyMap.quickhelpText = opts['quickhelpText']
let newKeyMap.callback = opts['callback']

View File

@ -90,7 +90,7 @@ endfunction
"callback
function! s:MenuItem.execute()
if len(self.children)
let mc = s:MenuController.New(self.children)
let mc = g:NERDTreeMenuController.New(self.children)
call mc.showMenu()
else
if self.callback != -1

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

@ -0,0 +1,39 @@
"CLASS: NERDTree
"============================================================
let s:NERDTree = {}
let g:NERDTree = s:NERDTree
" Function: s:NERDTree.ExistsForBuffer() {{{1
" Returns 1 if a nerd tree root exists in the current buffer
function! s:NERDTree.ExistsForBuf()
return exists("b:NERDTreeRoot")
endfunction
" Function: s:NERDTree.ExistsForTab() {{{1
" Returns 1 if a nerd tree root exists in the current tab
function! s:NERDTree.ExistsForTab()
return exists("t:NERDTreeBufName")
endfunction
function! s:NERDTree.ForCurrentBuf()
if s:NERDTree.ExistsForBuf()
return b:NERDTree
else
return {}
endif
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

35
lib/nerdtree/notifier.vim Normal file
View File

@ -0,0 +1,35 @@
"CLASS: Notifier
"============================================================
let s:Notifier = {}
function! s:Notifier.AddListener(event, funcname)
let listeners = s:Notifier.GetListenersForEvent(a:event)
if listeners == []
let listenersMap = s:Notifier.GetListenersMap()
let listenersMap[a:event] = listeners
endif
call add(listeners, a:funcname)
endfunction
function! s:Notifier.NotifyListeners(event, path, params)
let event = g:NERDTreeEvent.New(b:NERDTree, a:path, a:event, a:params)
for listener in s:Notifier.GetListenersForEvent(a:event)
call {listener}(event)
endfor
endfunction
function! s:Notifier.GetListenersMap()
if !exists("s:refreshListenersMap")
let s:refreshListenersMap = {}
endif
return s:refreshListenersMap
endfunction
function! s:Notifier.GetListenersForEvent(name)
let listenersMap = s:Notifier.GetListenersMap()
return get(listenersMap, a:name, [])
endfunction
let g:NERDTreePathNotifier = deepcopy(s:Notifier)

View File

@ -3,6 +3,29 @@
let 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
"Check the class options and global options (i.e. NERDTreeQuitOnOpen) to see
"if the tree should be closed now.
@ -21,6 +44,24 @@ function! s:Opener._checkToCloseTree(newtab)
endif
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! s:Opener._gotoTargetWin()
if b:NERDTreeType ==# "secondary"
@ -48,6 +89,37 @@ function! s:Opener._gotoTargetWin()
endif
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
"Args:
"
@ -190,7 +262,7 @@ function! s:Opener._openDirectory(node)
call self._gotoTargetWin()
if empty(self._where)
call a:node.makeRoot()
call nerdtree#renderView()
call b:NERDTree.render()
call a:node.putCursorHere(0, 0)
elseif self._where == 't'
call g:NERDTreeCreator.CreatePrimary(a:node.path.str())
@ -206,12 +278,12 @@ endfunction
"FUNCTION: Opener._previousWindow() {{{1
function! s:Opener._previousWindow()
if !nerdtree#isWindowUsable(winnr("#")) && nerdtree#firstUsableWindow() ==# -1
if !self._isWindowUsable(winnr("#")) && self._firstUsableWindow() ==# -1
call self._newSplit()
else
try
if !nerdtree#isWindowUsable(winnr("#"))
call nerdtree#exec(nerdtree#firstUsableWindow() . "wincmd w")
if !self._isWindowUsable(winnr("#"))
call nerdtree#exec(self._firstUsableWindow() . "wincmd w")
else
call nerdtree#exec('wincmd p')
endif

View File

@ -33,8 +33,10 @@ function! s:Path.bookmarkNames()
endfunction
"FUNCTION: Path.cacheDisplayString() {{{1
function! s:Path.cacheDisplayString()
let self.cachedDisplayString = self.getLastPathComponent(1)
function! s:Path.cacheDisplayString() abort
let self.cachedDisplayString = self.flagSet.renderToString()
let self.cachedDisplayString .= self.getLastPathComponent(1)
if self.isExecutable
let self.cachedDisplayString = self.cachedDisplayString . '*'
@ -103,6 +105,10 @@ function! s:Path.compareTo(path)
elseif thisSS > thatSS
return 1
else
if !g:NERDTreeSortHiddenFirst
let thisPath = substitute(thisPath, '^[._]', '', '')
let thatPath = substitute(thatPath, '^[._]', '', '')
endif
"if the sort sequences are the same then compare the paths
"alphabetically
let pathCompare = g:NERDTreeCaseSensitiveSort ? thisPath <# thatPath : thisPath <? thatPath
@ -141,6 +147,7 @@ function! s:Path.Create(fullpath)
"assume its a file and create
else
call s:Path.createParentDirectories(a:fullpath)
call writefile([], a:fullpath)
endif
catch
@ -161,9 +168,11 @@ function! s:Path.copy(dest)
throw "NERDTree.CopyingNotSupportedError: Copying is not supported on this OS"
endif
call s:Path.createParentDirectories(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)
if success != 0
throw "NERDTree.CopyError: Could not copy ''". self.str() ."'' to: '" . a:dest . "'"
@ -197,6 +206,20 @@ function! s:Path.copyingWillOverwrite(dest)
endif
endfunction
"FUNCTION: Path.createParentDirectories(path) {{{1
"
"create parent directories for this path if needed
"without throwing any errors is those directories already exist
"
"Args:
"path: full path of the node whose parent directories may need to be created
function! s:Path.createParentDirectories(path)
let dir_path = fnamemodify(a:path, ':h')
if !isdirectory(dir_path)
call mkdir(dir_path, 'p')
endif
endfunction
"FUNCTION: Path.delete() {{{1
"
"Deletes the file represented by this path.
@ -268,6 +291,15 @@ function! s:Path.exists()
return filereadable(p) || isdirectory(p)
endfunction
"FUNCTION: Path._escChars() {{{1
function! s:Path._escChars()
if nerdtree#runningWindows()
return " `\|\"#%&,?()\*^<>"
endif
return " \\`\|\"#%&,?()\*^<>[]"
endfunction
"FUNCTION: Path.getDir() {{{1
"
"Returns this path if it is a directory, else this paths parent.
@ -439,6 +471,7 @@ function! s:Path.New(path)
call newPath.readInfoFromDisk(s:Path.AbsolutePathFor(a:path))
let newPath.cachedDisplayString = ""
let newPath.flagSet = g:NERDTreeFlagSet.New()
return newPath
endfunction
@ -516,6 +549,13 @@ endfunction
"FUNCTION: Path.refresh() {{{1
function! s:Path.refresh()
call self.readInfoFromDisk(self.str())
call g:NERDTreePathNotifier.NotifyListeners('refresh', self, {})
call self.cacheDisplayString()
endfunction
"FUNCTION: Path.refreshFlags() {{{1
function! s:Path.refreshFlags()
call g:NERDTreePathNotifier.NotifyListeners('refreshFlags', self, {})
call self.cacheDisplayString()
endfunction
@ -583,8 +623,13 @@ function! s:Path.str(...)
if has_key(options, 'truncateTo')
let limit = options['truncateTo']
if len(toReturn) > limit
let toReturn = "<" . strpart(toReturn, len(toReturn) - limit + 1)
if len(toReturn) > limit-1
let toReturn = toReturn[(len(toReturn)-limit+1):]
if len(split(toReturn, '/')) > 1
let toReturn = '</' . join(split(toReturn, '/')[1:], '/') . '/'
else
let toReturn = '<' . toReturn
endif
endif
endif
@ -604,7 +649,7 @@ endfunction
"
" returns a string that can be used with :cd
function! s:Path._strForCd()
return escape(self.str(), nerdtree#escChars())
return escape(self.str(), self._escChars())
endfunction
"FUNCTION: Path._strForEdit() {{{1
@ -612,25 +657,15 @@ endfunction
"Return: the string for this path that is suitable to be used with the :edit
"command
function! s:Path._strForEdit()
let p = escape(self.str({'format': 'UI'}), nerdtree#escChars())
let cwd = getcwd() . s:Path.Slash()
let p = escape(self.str(), self._escChars())
"return a relative path if we can
let isRelative = 0
if nerdtree#runningWindows()
let isRelative = stridx(tolower(p), tolower(cwd)) == 0
else
let isRelative = stridx(p, cwd) == 0
endif
"make it relative
let p = fnamemodify(p, ':.')
if isRelative
let p = strpart(p, strlen(cwd))
"handle the edge case where the file begins with a + (vim interprets
"the +foo in `:e +foo` as an option to :edit)
if p[0] == "+"
let p = '\' . p
endif
"handle the edge case where the file begins with a + (vim interprets
"the +foo in `:e +foo` as an option to :edit)
if p[0] == "+"
let p = '\' . p
endif
if p ==# ''
@ -652,7 +687,7 @@ function! s:Path._strForGlob()
let toReturn = lead . join(self.pathSegments, s:Path.Slash())
if !nerdtree#runningWindows()
let toReturn = escape(toReturn, nerdtree#escChars())
let toReturn = escape(toReturn, self._escChars())
endif
return toReturn
endfunction

View File

@ -21,7 +21,7 @@ unlet s:TreeDirNode.activate
function! s:TreeDirNode.activate(...)
let opts = a:0 ? a:1 : {}
call self.toggleOpen(opts)
call nerdtree#renderView()
call b:NERDTree.render()
call self.putCursorHere(0, 0)
endfunction
@ -229,7 +229,7 @@ function! s:TreeDirNode._initChildren(silent)
let globDir = dir.str({'format': 'Glob'})
if version >= 703
let filesStr = globpath(globDir, '*', 1) . "\n" . globpath(globDir, '.*', 1)
let filesStr = globpath(globDir, '*', !g:NERDTreeRespectWildIgnore) . "\n" . globpath(globDir, '.*', !g:NERDTreeRespectWildIgnore)
else
let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*')
endif
@ -252,6 +252,7 @@ function! s:TreeDirNode._initChildren(silent)
try
let path = g:NERDTreePath.New(i)
call self.createChild(path, 0)
call g:NERDTreePathNotifier.NotifyListeners('init', path, {})
catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/
let invalidFilesFound += 1
endtry
@ -438,6 +439,20 @@ function! s:TreeDirNode.refresh()
endif
endfunction
"FUNCTION: TreeDirNode.refreshFlags() {{{1
unlet s:TreeDirNode.refreshFlags
function! s:TreeDirNode.refreshFlags()
call self.path.refreshFlags()
for i in self.children
call i.refreshFlags()
endfor
endfunction
"FUNCTION: TreeDirNode.refreshDirFlags() {{{1
function! s:TreeDirNode.refreshDirFlags()
call self.path.refreshFlags()
endfunction
"FUNCTION: TreeDirNode.reveal(path) {{{1
"reveal the given path, i.e. cache and open all treenodes needed to display it
"in the UI
@ -450,7 +465,7 @@ function! s:TreeDirNode.reveal(path)
if self.path.equals(a:path.getParent())
let n = self.findNode(a:path)
call nerdtree#renderView()
call b:NERDTree.render()
call n.putCursorHere(1,0)
return
endif
@ -500,7 +515,7 @@ function! s:TreeDirNode.toggleOpen(...)
if self.isOpen ==# 1
call self.close()
else
if g:NERDTreeCasadeOpenSingleChildDir == 0
if g:NERDTreeCascadeOpenSingleChildDir == 0
call self.open(opts)
else
call self.openAlong(opts)

View File

@ -178,79 +178,20 @@ function! s:TreeFileNode.findSibling(direction)
return {}
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
"get the root node for this tab
function! s:TreeFileNode.GetRootForTab()
if nerdtree#treeExistsForTab()
if g:NERDTree.ExistsForTab()
return getbufvar(t:NERDTreeBufName, 'NERDTreeRoot')
end
return {}
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
"gets the treenode that the cursor is currently over
function! s:TreeFileNode.GetSelected()
try
let path = nerdtree#getPath(line("."))
let path = b:NERDTree.ui.getPath(line("."))
if path ==# {}
return {}
endif
@ -270,7 +211,7 @@ endfunction
"FUNCTION: TreeFileNode.isRoot() {{{1
"returns 1 if this node is b:NERDTreeRoot
function! s:TreeFileNode.isRoot()
if !nerdtree#treeExistsForBuf()
if !g:NERDTree.ExistsForBuf()
throw "NERDTree.NoTreeError: No tree exists for the current buffer"
endif
@ -348,7 +289,7 @@ endfunction
"recurseUpward: try to put the cursor on the parent if the this node isnt
"visible
function! s:TreeFileNode.putCursorHere(isJump, recurseUpward)
let ln = self.getLineNum()
let ln = b:NERDTree.ui.getLineNum(self)
if ln != -1
if a:isJump
mark '
@ -357,11 +298,11 @@ function! s:TreeFileNode.putCursorHere(isJump, recurseUpward)
else
if a:recurseUpward
let node = self
while node != {} && node.getLineNum() ==# -1
while node != {} && b:NERDTree.ui.getLineNum(node) ==# -1
let node = node.parent
call node.open()
endwhile
call nerdtree#renderView()
call b:NERDTree.render()
call node.putCursorHere(a:isJump, 0)
endif
endif
@ -372,6 +313,11 @@ function! s:TreeFileNode.refresh()
call self.path.refresh()
endfunction
"FUNCTION: TreeFileNode.refreshFlags() {{{1
function! s:TreeFileNode.refreshFlags()
call self.path.refreshFlags()
endfunction
"FUNCTION: TreeFileNode.rename() {{{1
"Calls the rename method for this nodes path obj
function! s:TreeFileNode.rename(newName)

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

@ -0,0 +1,332 @@
"CLASS: UI
"============================================================
let s:UI = {}
let g:NERDTreeUI = s:UI
function! s:UI.lolcats()
echomsg "lolcats"
endfunction
"FUNCTION: s:UI.centerView() {{{2
"centers the nerd tree window around the cursor (provided the nerd tree
"options permit)
function! s:UI.centerView()
if g:NERDTreeAutoCenter
let current_line = winline()
let lines_to_top = current_line
let lines_to_bottom = winheight(nerdtree#getTreeWinNum()) - current_line
if lines_to_top < g:NERDTreeAutoCenterThreshold || lines_to_bottom < g:NERDTreeAutoCenterThreshold
normal! zz
endif
endif
endfunction
"FUNCTION: s:UI.new(nerdtree) {{{1
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
" FUNCTION: s:UI.toggleIgnoreFilter() {{{1
" toggles the use of the NERDTreeIgnore option
function! s:UI.toggleIgnoreFilter()
let b:NERDTreeIgnoreEnabled = !b:NERDTreeIgnoreEnabled
call b:NERDTree.ui.renderViewSavingPosition()
call b:NERDTree.ui.centerView()
endfunction
" FUNCTION: s:UI.toggleShowBookmarks() {{{1
" toggles the display of bookmarks
function! s:UI.toggleShowBookmarks()
let b:NERDTreeShowBookmarks = !b:NERDTreeShowBookmarks
if b:NERDTreeShowBookmarks
call b:NERDTree.render()
call nerdtree#putCursorOnBookmarkTable()
else
call b:NERDTree.ui.renderViewSavingPosition()
endif
call b:NERDTree.ui.centerView()
endfunction
" FUNCTION: s:UI.toggleShowFiles() {{{1
" toggles the display of hidden files
function! s:UI.toggleShowFiles()
let b:NERDTreeShowFiles = !b:NERDTreeShowFiles
call b:NERDTree.ui.renderViewSavingPosition()
call b:NERDTree.ui.centerView()
endfunction
" FUNCTION: s:UI.toggleShowHidden() {{{1
" toggles the display of hidden files
function! s:UI.toggleShowHidden()
let b:NERDTreeShowHidden = !b:NERDTreeShowHidden
call b:NERDTree.ui.renderViewSavingPosition()
call self.centerView()
endfunction
" FUNCTION: s:UI.toggleZoom() {{{1
" zoom (maximize/minimize) the NERDTree window
function! s:UI.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

View File

@ -24,7 +24,7 @@ call NERDTreeAddMenuItem({'text': '(a)dd a childnode', 'shortcut': 'a', 'callbac
call NERDTreeAddMenuItem({'text': '(m)ove the current node', 'shortcut': 'm', 'callback': 'NERDTreeMoveNode'})
call NERDTreeAddMenuItem({'text': '(d)elete the current node', 'shortcut': 'd', 'callback': 'NERDTreeDeleteNode'})
if has("gui_mac") || has("gui_macvim")
if has("gui_mac") || has("gui_macvim")
call NERDTreeAddMenuItem({'text': '(r)eveal in Finder the current node', 'shortcut': 'r', 'callback': 'NERDTreeRevealInFinder'})
call NERDTreeAddMenuItem({'text': '(o)pen the current node with system editor', 'shortcut': 'o', 'callback': 'NERDTreeExecuteFile'})
call NERDTreeAddMenuItem({'text': '(q)uicklook the current node', 'shortcut': 'q', 'callback': 'NERDTreeQuickLook'})
@ -82,13 +82,15 @@ endfunction
function! s:promptToRenameBuffer(bufnum, msg, newFileName)
echo a:msg
if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y'
let quotedFileName = "'" . a:newFileName . "'"
" 1. ensure that a new buffer is loaded
exec "badd " . a:newFileName
exec "badd " . quotedFileName
" 2. ensure that all windows which display the just deleted filename
" display a buffer for a new filename.
" display a buffer for a new filename.
let s:originalTabNumber = tabpagenr()
let s:originalWindowNumber = winnr()
exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':e! " . a:newFileName . "' | endif"
let editStr = g:NERDTreePath.New(a:newFileName).str({'format': 'Edit'})
exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':e! " . editStr . "' | endif"
exec "tabnext " . s:originalTabNumber
exec s:originalWindowNumber . "wincmd w"
" 3. We don't need a previous buffer anymore
@ -114,7 +116,10 @@ function! NERDTreeAddNode()
let parentNode = b:NERDTreeRoot.findNode(newPath.getParent())
let newTreeNode = g:NERDTreeFileNode.New(newPath)
if parentNode.isOpen || !empty(parentNode.children)
if empty(parentNode)
call b:NERDTreeRoot.refresh()
call b:NERDTree.render()
elseif parentNode.isOpen || !empty(parentNode.children)
call parentNode.addChild(newTreeNode, 1)
call NERDTreeRender()
call newTreeNode.putCursorHere(1, 0)
@ -138,7 +143,7 @@ function! NERDTreeMoveNode()
endif
try
let bufnum = bufnr(curNode.path.str())
let bufnum = bufnr("^".curNode.path.str()."$")
call curNode.rename(newNodePath)
call NERDTreeRender()
@ -186,7 +191,7 @@ function! NERDTreeDeleteNode()
"if the node is open in a buffer, ask the user if they want to
"close that buffer
let bufnum = bufnr(currentNode.path.str())
let bufnum = bufnr("^".currentNode.path.str()."$")
if buflisted(bufnum)
let prompt = "\nNode deleted.\n\nThe file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Delete this buffer? (yN)"
call s:promptToDelBuffer(bufnum, prompt)
@ -224,7 +229,10 @@ function! NERDTreeCopyNode()
if confirmed
try
let newNode = currentNode.copy(newNodePath)
if !empty(newNode)
if empty(newNode)
call b:NERDTreeRoot.refresh()
call b:NERDTree.render()
else
call NERDTreeRender()
call newNode.putCursorHere(0, 0)
endif

View File

@ -45,28 +45,30 @@ function! s:initVariable(var, value)
endfunction
"SECTION: Init variable calls and other random constants {{{2
call s:initVariable("g:NERDChristmasTree", 1)
call s:initVariable("g:NERDTreeAutoCenter", 1)
call s:initVariable("g:NERDTreeAutoCenterThreshold", 3)
call s:initVariable("g:NERDTreeCaseSensitiveSort", 0)
call s:initVariable("g:NERDTreeSortHiddenFirst", 1)
call s:initVariable("g:NERDTreeChDirMode", 0)
call s:initVariable("g:NERDTreeMinimalUI", 0)
if !exists("g:NERDTreeIgnore")
let g:NERDTreeIgnore = ['\~$']
endif
call s:initVariable("g:NERDTreeBookmarksFile", expand('$HOME') . '/.NERDTreeBookmarks')
call s:initVariable("g:NERDTreeBookmarksSort", 1)
call s:initVariable("g:NERDTreeHighlightCursorline", 1)
call s:initVariable("g:NERDTreeHijackNetrw", 1)
call s:initVariable("g:NERDTreeMouseMode", 1)
call s:initVariable("g:NERDTreeNotificationThreshold", 100)
call s:initVariable("g:NERDTreeQuitOnOpen", 0)
call s:initVariable("g:NERDTreeRespectWildIgnore", 0)
call s:initVariable("g:NERDTreeShowBookmarks", 0)
call s:initVariable("g:NERDTreeShowFiles", 1)
call s:initVariable("g:NERDTreeShowHidden", 0)
call s:initVariable("g:NERDTreeShowLineNumbers", 0)
call s:initVariable("g:NERDTreeSortDirs", 1)
call s:initVariable("g:NERDTreeDirArrows", !nerdtree#runningWindows())
call s:initVariable("g:NERDTreeCasadeOpenSingleChildDir", 1)
call s:initVariable("g:NERDTreeCascadeOpenSingleChildDir", 1)
if !exists("g:NERDTreeSortOrder")
let g:NERDTreeSortOrder = ['\/$', '*', '\.swp$', '\.bak$', '\~$']
@ -140,20 +142,13 @@ call nerdtree#loadClassFiles()
" SECTION: Commands {{{1
"============================================================
"init the command that users start the nerd tree with
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()
call nerdtree#ui_glue#setupCommands()
" SECTION: Auto commands {{{1
"============================================================
augroup NERDTree
"Save the cursor position whenever we close the nerd tree
exec "autocmd BufWinLeave ". g:NERDTreeCreator.BufNamePrefix() ."* call nerdtree#saveScreenState()"
exec "autocmd BufLeave ". g:NERDTreeCreator.BufNamePrefix() ."* call b:NERDTree.ui.saveScreenState()"
"disallow insert mode in the NERDTree
exec "autocmd BufEnter ". g:NERDTreeCreator.BufNamePrefix() ."* stopinsert"
@ -199,7 +194,7 @@ endfunction
function! NERDTreeCWD()
call NERDTreeFocus()
call nerdtree#chRootCwd()
call nerdtree#ui_glue#chRootCwd()
endfunction
" SECTION: Post Source Actions {{{1
call nerdtree#postSourceActions()

View File

@ -1,44 +1,64 @@
let s:tree_up_dir_line = '.. (up a dir)'
"NERDTreeFlags are syntax items that should be invisible, but give clues as to
"how things should be highlighted
syn match NERDTreeFlag #\~#
syn match NERDTreeFlag #\[RO\]#
syn match NERDTreeIgnore #\~#
syn match NERDTreeIgnore #\[RO\]#
"highlighting for the .. (up dir) line at the top of the tree
execute "syn match NERDTreeUp #\\V". s:tree_up_dir_line ."#"
"highlighting for the ~/+ symbols for the directory nodes
syn match NERDTreeClosable #\~\<#
syn match NERDTreeClosable #\~\.#
syn match NERDTreeOpenable #+\<#
syn match NERDTreeOpenable #+\.#he=e-1
"highlighting for the tree structural parts
syn match NERDTreePart #|#
syn match NERDTreePart #`#
syn match NERDTreePartFile #[|`]-#hs=s+1 contains=NERDTreePart
"quickhelp syntax elements
syn match NERDTreeHelpKey #" \{1,2\}[^ ]*:#hs=s+2,he=e-1
syn match NERDTreeHelpKey #" \{1,2\}[^ ]*,#hs=s+2,he=e-1
syn match NERDTreeHelpTitle #" .*\~#hs=s+2,he=e-1 contains=NERDTreeFlag
syn match NERDTreeToggleOn #".*(on)#hs=e-2,he=e-1 contains=NERDTreeHelpKey
syn match NERDTreeToggleOff #".*(off)#hs=e-3,he=e-1 contains=NERDTreeHelpKey
syn match NERDTreeHelpKey #" \{1,2\}[^ ]*:#ms=s+2,me=e-1
syn match NERDTreeHelpKey #" \{1,2\}[^ ]*,#ms=s+2,me=e-1
syn match NERDTreeHelpTitle #" .*\~#ms=s+2,me=e-1
syn match NERDTreeToggleOn #(on)#ms=s+1,he=e-1
syn match NERDTreeToggleOff #(off)#ms=e-3,me=e-1
syn match NERDTreeHelpCommand #" :.\{-}\>#hs=s+3
syn match NERDTreeHelp #^".*# contains=NERDTreeHelpKey,NERDTreeHelpTitle,NERDTreeFlag,NERDTreeToggleOff,NERDTreeToggleOn,NERDTreeHelpCommand
"highlighting for readonly files
syn match NERDTreeRO #.*\[RO\]#hs=s+2 contains=NERDTreeFlag,NERDTreeBookmark,NERDTreePart,NERDTreePartFile
syn match NERDTreeHelp #^".*# contains=NERDTreeHelpKey,NERDTreeHelpTitle,NERDTreeIgnore,NERDTreeToggleOff,NERDTreeToggleOn,NERDTreeHelpCommand
"highlighting for sym links
syn match NERDTreeLink #[^-| `].* -> # contains=NERDTreeBookmark,NERDTreeOpenable,NERDTreeClosable,NERDTreeDirSlash
syn match NERDTreeLinkTarget #->.*# containedin=NERDTreeDir,NERDTreeFile
syn match NERDTreeLinkFile #.* ->#me=e-3 containedin=NERDTreeFile
syn match NERDTreeLinkDir #.*/ ->#me=e-3 containedin=NERDTreeDir
"highlighing for directory nodes and file nodes
syn match NERDTreeDirSlash #/#
syn match NERDTreeDir #[^-| `].*/# contains=NERDTreeLink,NERDTreeDirSlash,NERDTreeOpenable,NERDTreeClosable
syn match NERDTreeExecFile #[|` ].*\*\($\| \)# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark
syn match NERDTreeFile #|-.*# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile
syn match NERDTreeFile #`-.*# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile
syn match NERDTreeDirSlash #/# containedin=NERDTreeDir
if g:NERDTreeDirArrows
syn match NERDTreeClosable #▾# containedin=NERDTreeDir,NERDTreeFile
syn match NERDTreeOpenable #▸# containedin=NERDTreeDir,NERDTreeFile
syn match NERDTreeDir #[^▾▸ ].*/#
syn match NERDTreeExecFile #^ .*\*\($\| \)# contains=NERDTreeRO,NERDTreeBookmark
syn match NERDTreeFile #^[^"\.▾▸] *[^▾▸]*# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmark,NERDTreeExecFile
"highlighting for readonly files
syn match NERDTreeRO # *\zs.*\ze \[RO\]# contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreeFile
syn match NERDTreeFlags #^ *\zs\[.\]# containedin=NERDTreeFile
syn match NERDTreeFlags #\[.\]# containedin=NERDTreeDir
else
"highlighting for the ~/+ symbols for the directory nodes
syn match NERDTreeClosable #\~\<#
syn match NERDTreeClosable #\~\.#
syn match NERDTreeOpenable #+\<#
syn match NERDTreeOpenable #+\.#he=e-1
"highlighting for the tree structural parts
syn match NERDTreePart #|#
syn match NERDTreePart #`#
syn match NERDTreePartFile #[|`]-#hs=s+1 contains=NERDTreePart
syn match NERDTreeDir #[^-| `].*/# contains=NERDTreeLink,NERDTreeOpenable,NERDTreeClosable
syn match NERDTreeExecFile #[|` ].*\*\($\| \)# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark
syn match NERDTreeFile #|-.*# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile
syn match NERDTreeFile #`-.*# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile
"highlighting for readonly files
syn match NERDTreeRO #|-.*\[RO\]#he=e-5 contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreePart,NERDTreePartFile
syn match NERDTreeFlags #-\[.\]# containedin=NERDTreeFile,NERDTreePartFile
syn match NERDTreeFlags #[+~]\zs\[.\]# containedin=NERDTreeDir
endif
syn match NERDTreeCWD #^[</].*$#
"highlighting for bookmarks
@ -50,19 +70,10 @@ syn match NERDTreeBookmarksHeader #^>-\+Bookmarks-\+$# contains=NERDTreeBookmark
syn match NERDTreeBookmarkName #^>.\{-} #he=e-1 contains=NERDTreeBookmarksLeader
syn match NERDTreeBookmark #^>.*$# contains=NERDTreeBookmarksLeader,NERDTreeBookmarkName,NERDTreeBookmarksHeader
if exists("g:NERDChristmasTree") && g:NERDChristmasTree
hi def link NERDTreePart Special
hi def link NERDTreePartFile Type
hi def link NERDTreeFile Normal
hi def link NERDTreeExecFile Title
hi def link NERDTreeDirSlash Identifier
hi def link NERDTreeClosable Type
else
hi def link NERDTreePart Normal
hi def link NERDTreePartFile Normal
hi def link NERDTreeFile Normal
hi def link NERDTreeClosable Title
endif
hi def link NERDTreePart Special
hi def link NERDTreePartFile Type
hi def link NERDTreeExecFile Title
hi def link NERDTreeDirSlash Identifier
hi def link NERDTreeBookmarksHeader statement
hi def link NERDTreeBookmarksLeader ignore
@ -76,13 +87,19 @@ hi def link NERDTreeHelpTitle Macro
hi def link NERDTreeToggleOn Question
hi def link NERDTreeToggleOff WarningMsg
hi def link NERDTreeLinkTarget Type
hi def link NERDTreeLinkFile Macro
hi def link NERDTreeLinkDir Macro
hi def link NERDTreeDir Directory
hi def link NERDTreeUp Directory
hi def link NERDTreeFile Normal
hi def link NERDTreeCWD Statement
hi def link NERDTreeLink Macro
hi def link NERDTreeOpenable Title
hi def link NERDTreeFlag ignore
hi def link NERDTreeClosable Title
hi def link NERDTreeIgnore ignore
hi def link NERDTreeRO WarningMsg
hi def link NERDTreeBookmark Statement
hi def link NERDTreeFlags Number
hi def link NERDTreeCurrentNode Search