diff --git a/README.markdown b/README.markdown index e617809..4234b54 100644 --- a/README.markdown +++ b/README.markdown @@ -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 :NERDTreeToggle` +A. Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever key you want): + +`map :NERDTreeToggle` __Q. How can I close vim if the only window left open is a NERDTree?__ diff --git a/autoload/nerdtree.vim b/autoload/nerdtree.vim index 3449676..539e783 100644 --- a/autoload/nerdtree.vim +++ b/autoload/nerdtree.vim @@ -9,29 +9,6 @@ endfunction " SECTION: General Functions {{{1 "============================================================ -"FUNCTION: nerdtree#bufInWindows(bnum){{{2 -"[[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! nerdtree#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: nerdtree#checkForBrowse(dir) {{{2 "inits a secondary nerd tree in the current buffer if appropriate @@ -57,81 +34,6 @@ function! nerdtree#compareNodes(n1, n2) return a:n1.path.compareTo(a:n2.path) endfunction -" FUNCTION: nerdtree#createDefaultBindings() {{{2 -function! nerdtree#createDefaultBindings() - let s = '' . s:SID() . '_' - - call NERDTreeAddKeyMap({ 'key': '', 'scope': "all", 'callback': s."handleMiddleMouse" }) - call NERDTreeAddKeyMap({ 'key': '', '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#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 - " FUNCTION: nerdtree#deprecated(func, [msg]) {{{2 " Issue a deprecation warning for a:func. If a second arg is given, use this " as the deprecation message @@ -147,15 +49,6 @@ function! nerdtree#deprecated(func, ...) endif endfunction -"FUNCTION: nerdtree#escChars(dir) {{{2 -function! nerdtree#escChars() - if nerdtree#runningWindows() - return " `\|\"#%&,?()\*^<>" - endif - - return " \\`\|\"#%&,?()\*^<>[]" -endfunction - " FUNCTION: nerdtree#exec(cmd) {{{2 " same as :exec cmd but eventignore=all is set for the duration function! nerdtree#exec(cmd) @@ -165,68 +58,11 @@ function! nerdtree#exec(cmd) let &ei = old_ei endfunction -" FUNCTION: nerdtree#findAndRevealPath() {{{2 -function! nerdtree#findAndRevealPath() - try - let p = g:NERDTreePath.New(resolve(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: nerdtree#has_opt(options, name) {{{2 function! nerdtree#has_opt(options, name) return has_key(a:options, a:name) && a:options[a:name] == 1 endfunction -" FUNCTION: nerdtree#invokeKeyMap(key) {{{2 -"this is needed since I cant figure out how to invoke dict functions from a -"key map -function! nerdtree#invokeKeyMap(key) - call g:NERDTreeKeyMap.Invoke(a:key) -endfunction - " FUNCTION: nerdtree#loadClassFiles() {{{2 function! nerdtree#loadClassFiles() runtime lib/nerdtree/path.vim @@ -238,12 +74,17 @@ function! nerdtree#loadClassFiles() runtime lib/nerdtree/tree_dir_node.vim runtime lib/nerdtree/opener.vim runtime lib/nerdtree/creator.vim + runtime lib/nerdtree/flag_set.vim + runtime lib/nerdtree/nerdtree.vim + runtime lib/nerdtree/ui.vim + runtime lib/nerdtree/event.vim + runtime lib/nerdtree/notifier.vim endfunction " FUNCTION: nerdtree#postSourceActions() {{{2 function! nerdtree#postSourceActions() call g:NERDTreeBookmark.CacheBookmarks(0) - call nerdtree#createDefaultBindings() + call nerdtree#ui_glue#createDefaultBindings() "load all nerdtree plugins runtime! nerdtree_plugin/**/*.vim @@ -254,44 +95,6 @@ function! nerdtree#runningWindows() return has("win16") || has("win32") || has("win64") endfunction -" Function: s:SID() {{{2 -function s:SID() - if !exists("s:sid") - let s:sid = matchstr(expand(''), '\zs\d\+\ze_SID$') - endif - return s:sid -endfun - -" FUNCTION: nerdtree#tabpagevar(tabnr, var) {{{2 -function! nerdtree#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: nerdtree#treeExistsForBuffer() {{{2 -" Returns 1 if a nerd tree root exists in the current buffer -function! nerdtree#treeExistsForBuf() - return exists("b:NERDTreeRoot") -endfunction - -" Function: nerdtree#treeExistsForTab() {{{2 -" Returns 1 if a nerd tree root exists in the current tab -function! nerdtree#treeExistsForTab() - return exists("t:NERDTreeBufName") -endfunction - "FUNCTION: nerdtree#treeMarkupReg(dir) {{{2 function! nerdtree#treeMarkupReg() if g:NERDTreeDirArrows @@ -311,76 +114,9 @@ function! nerdtree#treeWid() return 2 endfunction -"FUNCTION: nerdtree#upDir(keepState) {{{2 -"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#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 nerdtree#renderView() - call oldRoot.putCursorHere(0, 0) - endif -endfunction - -" Function: nerdtree#unique(list) {{{2 -" returns a:list without duplicates -function! nerdtree#unique(list) - let uniqlist = [] - for elem in a:list - if index(uniqlist, elem) ==# -1 - let uniqlist += [elem] - endif - endfor - return uniqlist -endfunction - " SECTION: View Functions {{{1 "============================================================ -" -"FUNCTION: nerdtree#centerView() {{{2 -"centers the nerd tree window around the cursor (provided the nerd tree -"options permit) -function! nerdtree#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: nerdtree#chRoot(node) {{{2 -" changes the current root to the selected one -function! nerdtree#chRoot(node) - call s:chRoot(a:node) -endfunction "FUNCTION: nerdtree#closeTree() {{{2 "Closes the primary NERD tree window for this tab function! nerdtree#closeTree() @@ -513,7 +249,7 @@ function! nerdtree#dumpHelp() let @h=@h."\" ". g:NERDTreeMapHelp .": toggle help\n" let @h=@h."\"\n\" ----------------------------\n" let @h=@h."\" Bookmark commands~\n" - let @h=@h."\" :Bookmark \n" + let @h=@h."\" :Bookmark []\n" let @h=@h."\" :BookmarkToRoot \n" let @h=@h."\" :RevealBookmark \n" let @h=@h."\" :OpenBookmark \n" @@ -558,92 +294,6 @@ function! nerdtree#echoWarning(msg) echohl normal endfunction -"FUNCTION: nerdtree#firstUsableWindow(){{{2 -"find the window number of the first normal window -function! nerdtree#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: nerdtree#getPath(ln) {{{2 -"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! nerdtree#getPath(ln) - let line = getline(a:ln) - - let rootLine = g:NERDTreeFileNode.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 = nerdtree#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 = nerdtree#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: nerdtree#getTreeWinNum() {{{2 "gets the nerd tree window number for this tab function! nerdtree#getTreeWinNum() @@ -654,111 +304,11 @@ function! nerdtree#getTreeWinNum() endif endfunction -"FUNCTION: nerdtree#indentLevelFor(line) {{{2 -function! nerdtree#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: nerdtree#isTreeOpen() {{{2 function! nerdtree#isTreeOpen() return nerdtree#getTreeWinNum() != -1 endfunction -"FUNCTION: nerdtree#isWindowUsable(winnumber) {{{2 -"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! nerdtree#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 || nerdtree#bufInWindows(winbufnr(a:winnumber)) >= 2 -endfunction - -" FUNCTION: nerdtree#jumpToChild(direction) {{{2 -" Args: -" direction: 0 if going to first child, 1 if going to last -function! nerdtree#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#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! nerdtree#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#promptToDelBuffer(bufnum, msg){{{2 -"prints out the given msg and, if the user responds by pushing 'y' then the -"buffer with the given bufnum is deleted -" -"Args: -"bufnum: the buffer that may be deleted -"msg: a message that will be echoed to the user asking them if they wish to -" del the buffer -function! nerdtree#promptToDelBuffer(bufnum, msg) - echo a:msg - if nr2char(getchar()) ==# 'y' - exec "silent bdelete! " . a:bufnum - endif -endfunction - "FUNCTION: nerdtree#putCursorOnBookmarkTable(){{{2 "Places the cursor at the top of the bookmarks table function! nerdtree#putCursorOnBookmarkTable() @@ -770,7 +320,7 @@ function! nerdtree#putCursorOnBookmarkTable() return cursor(1, 2) endif - let rootNodeLine = g:NERDTreeFileNode.GetRootLineNum() + let rootNodeLine = b:NERDTree.ui.getRootLineNum() let line = 1 while getline(line) !~# '^>-\+Bookmarks-\+$' @@ -810,116 +360,10 @@ function! nerdtree#renderBookmarks() endfunction "FUNCTION: nerdtree#renderView {{{2 -"The entry function for rendering the tree function! nerdtree#renderView() - 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: nerdtree#renderViewSavingPosition {{{2 -"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! nerdtree#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 nerdtree#renderView() - - if currentNode != {} - call currentNode.putCursorHere(0, 0) - endif + call b:NERDTree.render() endfunction " -"FUNCTION: nerdtree#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! nerdtree#restoreScreenState() - if !exists("b:NERDTreeOldTopLine") || !exists("b:NERDTreeOldPos") || !exists("b:NERDTreeOldWindowSize") - return - endif - exec("silent vertical resize ".b:NERDTreeOldWindowSize) - - let old_scrolloff=&scrolloff - let &scrolloff=0 - call cursor(b:NERDTreeOldTopLine, 0) - normal! zt - call setpos(".", b:NERDTreeOldPos) - let &scrolloff=old_scrolloff -endfunction - -"FUNCTION: nerdtree#saveScreenState() {{{2 -"Saves the current cursor position in the current buffer and the window -"scroll position -function! nerdtree#saveScreenState() - let win = winnr() - try - call nerdtree#putCursorInTreeWin() - let b:NERDTreeOldPos = getpos(".") - let b:NERDTreeOldTopLine = line("w0") - let b:NERDTreeOldWindowSize = winwidth("") - call nerdtree#exec(win . "wincmd w") - catch /^NERDTree.InvalidOperationError/ - endtry -endfunction - "FUNCTION: nerdtree#stripMarkupFromLine(line, removeLeadingSpaces){{{2 "returns the given line with all the tree parts stripped off " @@ -941,6 +385,9 @@ function! nerdtree#stripMarkupFromLine(line, removeLeadingSpaces) "strip off any executable flags let line = substitute (line, '*\ze\($\| \)', "","") + "strip off any generic flags + let line = substitute (line, '\[[^]]*\]', "","") + let wasdir = 0 if line =~# '/$' let wasdir = 1 @@ -957,424 +404,4 @@ function! nerdtree#stripMarkupFromLine(line, removeLeadingSpaces) return line endfunction -"SECTION: Interface bindings {{{1 -"============================================================ - -"FUNCTION: s:activateAll() {{{2 -"handle the user activating the updir line -function! s:activateAll() - if getline(".") ==# nerdtree#treeUpDirLine() - return nerdtree#upDir(0) - endif -endfunction -"FUNCTION: s:activateDirNode() {{{2 -"handle the user activating a tree node -function! s:activateDirNode(node) - call a:node.activate({'reuse': 1}) -endfunction - -"FUNCTION: s:activateFileNode() {{{2 -"handle the user activating a tree node -function! s:activateFileNode(node) - call a:node.activate({'reuse': 1, 'where': 'p'}) -endfunction - -"FUNCTION: s:activateBookmark() {{{2 -"handle the user activating a bookmark -function! s:activateBookmark(bm) - call a:bm.activate(!a:bm.path.isDirectory ? {'where': 'p'} : {}) -endfunction - -" FUNCTION: nerdtree#bookmarkNode(name) {{{2 -" Associate the current node with the given name -function! nerdtree#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 nerdtree#renderView() - 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) {{{2 -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) {{{2 -" changes the current root to the selected one -function! s:chRoot(node) - call a:node.makeRoot() - call nerdtree#renderView() - call b:NERDTreeRoot.putCursorHere(0, 0) -endfunction - -" FUNCTION: s:chRootCwd() {{{2 -" changes the current root to CWD -function! nerdtree#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: nerdtree#clearBookmarks(bookmarks) {{{2 -function! nerdtree#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 nerdtree#renderView() -endfunction - -" FUNCTION: s:closeChildren(node) {{{2 -" closes all childnodes of the current node -function! s:closeChildren(node) - call a:node.closeChildren() - call nerdtree#renderView() - call a:node.putCursorHere(0, 0) -endfunction - -" FUNCTION: s:closeCurrentDir(node) {{{2 -" 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 - call a:node.parent.close() - call nerdtree#renderView() - call a:node.parent.putCursorHere(0, 0) - endif -endfunction - -" FUNCTION: s:closeTreeWindow() {{{2 -" 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) {{{2 -" 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 nerdtree#renderView() - redraw - catch /^NERDTree/ - call nerdtree#echoWarning("Could not remove bookmark") - endtry - else - call nerdtree#echo("delete aborted" ) - endif - -endfunction - -" FUNCTION: s:displayHelp() {{{2 -" toggles the help display -function! s:displayHelp() - let b:treeShowHelp = b:treeShowHelp ? 0 : 1 - call nerdtree#renderView() - call nerdtree#centerView() -endfunction - -"FUNCTION: s:handleLeftClick() {{{2 -"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() {{{2 -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:jumpToFirstChild() {{{2 -" wrapper for the jump to child method -function! s:jumpToFirstChild(node) - call nerdtree#jumpToChild(a:node, 0) -endfunction - -" FUNCTION: s:jumpToLastChild() {{{2 -" wrapper for the jump to child method -function! s:jumpToLastChild(node) - call nerdtree#jumpToChild(a:node, 1) -endfunction - -" FUNCTION: s:jumpToParent(node) {{{2 -" 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() {{{2 -" moves the cursor to the root node -function! s:jumpToRoot() - call b:NERDTreeRoot.putCursorHere(1, 0) - call nerdtree#centerView() -endfunction - -" FUNCTION: s:jumpToNextSibling(node) {{{2 -function! s:jumpToNextSibling(node) - call nerdtree#jumpToSibling(a:node, 1) -endfunction - -" FUNCTION: s:jumpToPrevSibling(node) {{{2 -function! s:jumpToPrevSibling(node) - call nerdtree#jumpToSibling(a:node, 0) -endfunction - -" FUNCTION: nerdtree#openBookmark(name) {{{2 -" put the cursor on the given bookmark and, if its a file, open it -function! nerdtree#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) {{{2 -function! s:openHSplit(target) - call a:target.activate({'where': 'h'}) -endfunction - -" FUNCTION: s:openVSplit(target) {{{2 -function! s:openVSplit(target) - call a:target.activate({'where': 'v'}) -endfunction - -" FUNCTION: s:openExplorer(node) {{{2 -function! s:openExplorer(node) - call a:node.openExplorer() -endfunction - -" FUNCTION: s:openInNewTab(target) {{{2 -function! s:openInNewTab(target) - call a:target.activate({'where': 't'}) -endfunction - -" FUNCTION: s:openInNewTabSilent(target) {{{2 -function! s:openInNewTabSilent(target) - call a:target.activate({'where': 't', 'stay': 1}) -endfunction - -" FUNCTION: s:openNodeRecursively(node) {{{2 -function! s:openNodeRecursively(node) - call nerdtree#echo("Recursively opening node. Please wait...") - call a:node.openRecursively() - call nerdtree#renderView() - redraw - call nerdtree#echo("Recursively opening node. Please wait... DONE") -endfunction - -"FUNCTION: s:previewNodeCurrent(node) {{{2 -function! s:previewNodeCurrent(node) - call a:node.open({'stay': 1, 'where': 'p', 'keepopen': 1}) -endfunction - -"FUNCTION: s:previewNodeHSplit(node) {{{2 -function! s:previewNodeHSplit(node) - call a:node.open({'stay': 1, 'where': 'h', 'keepopen': 1}) -endfunction - -"FUNCTION: s:previewNodeVSplit(node) {{{2 -function! s:previewNodeVSplit(node) - call a:node.open({'stay': 1, 'where': 'v', 'keepopen': 1}) -endfunction - -" FUNCTION: nerdtree#revealBookmark(name) {{{2 -" put the cursor on the node associate with the given name -function! nerdtree#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() {{{2 -" 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 nerdtree#renderView() - redraw - call nerdtree#echo("Refreshing the root node. This could take a while... DONE") -endfunction - -" FUNCTION: s:refreshCurrent(node) {{{2 -" 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 nerdtree#renderView() - redraw - call nerdtree#echo("Refreshing node. This could take a while... DONE") -endfunction - -" FUNCTION: s:showMenu(node) {{{2 -function! s:showMenu(node) - let mc = g:NERDTreeMenuController.New(g:NERDTreeMenuItem.AllEnabled()) - call mc.showMenu() -endfunction - -" FUNCTION: s:toggleIgnoreFilter() {{{2 -" toggles the use of the NERDTreeIgnore option -function! s:toggleIgnoreFilter() - let b:NERDTreeIgnoreEnabled = !b:NERDTreeIgnoreEnabled - call nerdtree#renderViewSavingPosition() - call nerdtree#centerView() -endfunction - -" FUNCTION: s:toggleShowBookmarks() {{{2 -" toggles the display of bookmarks -function! s:toggleShowBookmarks() - let b:NERDTreeShowBookmarks = !b:NERDTreeShowBookmarks - if b:NERDTreeShowBookmarks - call nerdtree#renderView() - call nerdtree#putCursorOnBookmarkTable() - else - call nerdtree#renderViewSavingPosition() - endif - call nerdtree#centerView() -endfunction - -" FUNCTION: s:toggleShowFiles() {{{2 -" toggles the display of hidden files -function! s:toggleShowFiles() - let b:NERDTreeShowFiles = !b:NERDTreeShowFiles - call nerdtree#renderViewSavingPosition() - call nerdtree#centerView() -endfunction - -" FUNCTION: s:toggleShowHidden() {{{2 -" toggles the display of hidden files -function! s:toggleShowHidden() - let b:NERDTreeShowHidden = !b:NERDTreeShowHidden - call nerdtree#renderViewSavingPosition() - call nerdtree#centerView() -endfunction - -" FUNCTION: s:toggleZoom() {{{2 -" 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: s:upDirCurrentRootOpen() {{{2 -function! s:upDirCurrentRootOpen() - call nerdtree#upDir(1) -endfunction - -" FUNCTION: s:upDirCurrentRootClosed() {{{2 -function! s:upDirCurrentRootClosed() - call nerdtree#upDir(0) -endfunction - " vim: set sw=4 sts=4 et fdm=marker: diff --git a/autoload/nerdtree/ui_glue.vim b/autoload/nerdtree/ui_glue.vim new file mode 100644 index 0000000..8607389 --- /dev/null +++ b/autoload/nerdtree/ui_glue.vim @@ -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 = '' . s:SID() . '_' + + call NERDTreeAddKeyMap({ 'key': '', 'scope': "all", 'callback': s."handleMiddleMouse" }) + call NERDTreeAddKeyMap({ 'key': '', '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('') + command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.TogglePrimary('') + command! -n=0 -bar NERDTreeClose :call nerdtree#closeTreeIfOpen() + command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreatePrimary('') + 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(''), '\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: diff --git a/doc/NERD_tree.txt b/doc/NERD_tree.txt index bf03896..5d5b3f6 100644 --- a/doc/NERD_tree.txt +++ b/doc/NERD_tree.txt @@ -109,7 +109,7 @@ The following features and functionality are provided by the NERD tree: < :NERDTreeFromBookmark *:NERDTreeFromBookmark* Opens a fresh NERD tree with the root initialized to the dir for - . This only reason to use this command over :NERDTree is for + . The only reason to use this command over :NERDTree is for the completion (which is for bookmarks rather than directories). :NERDTreeToggle [ | ] *: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 +:Bookmark [] Bookmark the current node as . If there is already a bookmark, it is overwritten. must not contain spaces. If 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() diff --git a/lib/nerdtree/bookmark.vim b/lib/nerdtree/bookmark.vim index 5b845d8..6de9be4 100644 --- a/lib/nerdtree/bookmark.vim +++ b/lib/nerdtree/bookmark.vim @@ -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 diff --git a/lib/nerdtree/creator.vim b/lib/nerdtree/creator.vim index 7f0721f..86f951a 100644 --- a/lib/nerdtree/creator.vim +++ b/lib/nerdtree/creator.vim @@ -7,18 +7,18 @@ let g:NERDTreeCreator = s:Creator "FUNCTION: s:Creator._bindMappings() {{{1 function! s:Creator._bindMappings() - "make do the same as the default 'o' mapping - exec "nnoremap :call nerdtree#invokeKeyMap('". g:NERDTreeMapActivateNode ."')" + "make do the same as the activate node mapping + nnoremap :call nerdtree#ui_glue#invokeKeyMap(g:NERDTreeMapActivateNode) call g:NERDTreeKeyMap.BindAll() - command! -buffer -nargs=? Bookmark :call nerdtree#bookmarkNode('') - command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#revealBookmark('') - command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#openBookmark('') - command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#clearBookmarks('') + command! -buffer -nargs=? Bookmark :call nerdtree#ui_glue#bookmarkNode('') + command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#ui_glue#revealBookmark('') + command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#ui_glue#openBookmark('') + command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#ui_glue#clearBookmarks('') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=+ BookmarkToRoot call g:NERDTreeBookmark.ToRoot('') - command! -buffer -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() call nerdtree#renderView() - command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) call nerdtree#renderView() + command! -buffer -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() call b:NERDTree.render() + command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) 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: diff --git a/lib/nerdtree/event.vim b/lib/nerdtree/event.vim new file mode 100644 index 0000000..964e8ff --- /dev/null +++ b/lib/nerdtree/event.vim @@ -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 diff --git a/lib/nerdtree/flag_set.vim b/lib/nerdtree/flag_set.vim new file mode 100644 index 0000000..9d8d335 --- /dev/null +++ b/lib/nerdtree/flag_set.vim @@ -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 diff --git a/lib/nerdtree/key_map.vim b/lib/nerdtree/key_map.vim index 8645765..2411406 100644 --- a/lib/nerdtree/key_map.vim +++ b/lib/nerdtree/key_map.vim @@ -44,7 +44,7 @@ function! s:KeyMap.bind() let premap = self.key == "" ? " " : " " - exec 'nnoremap '. self.key . premap . ':call nerdtree#invokeKeyMap("'. keymapInvokeString .'")' + exec 'nnoremap '. self.key . premap . ':call nerdtree#ui_glue#invokeKeyMap("'. keymapInvokeString .'")' 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 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'] diff --git a/lib/nerdtree/menu_item.vim b/lib/nerdtree/menu_item.vim index 6fb9d9e..92c1bbb 100644 --- a/lib/nerdtree/menu_item.vim +++ b/lib/nerdtree/menu_item.vim @@ -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 diff --git a/lib/nerdtree/nerdtree.vim b/lib/nerdtree/nerdtree.vim new file mode 100644 index 0000000..a41490b --- /dev/null +++ b/lib/nerdtree/nerdtree.vim @@ -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 + diff --git a/lib/nerdtree/notifier.vim b/lib/nerdtree/notifier.vim new file mode 100644 index 0000000..b445f8a --- /dev/null +++ b/lib/nerdtree/notifier.vim @@ -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) + diff --git a/lib/nerdtree/opener.vim b/lib/nerdtree/opener.vim index bcc0d4f..845e55c 100644 --- a/lib/nerdtree/opener.vim +++ b/lib/nerdtree/opener.vim @@ -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 diff --git a/lib/nerdtree/path.vim b/lib/nerdtree/path.vim index 58bb013..dbecb02 100644 --- a/lib/nerdtree/path.vim +++ b/lib/nerdtree/path.vim @@ -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 " + 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 = '= 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) diff --git a/lib/nerdtree/tree_file_node.vim b/lib/nerdtree/tree_file_node.vim index ab8d371..b4924d7 100644 --- a/lib/nerdtree/tree_file_node.vim +++ b/lib/nerdtree/tree_file_node.vim @@ -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) diff --git a/lib/nerdtree/ui.vim b/lib/nerdtree/ui.vim new file mode 100644 index 0000000..ed93d80 --- /dev/null +++ b/lib/nerdtree/ui.vim @@ -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 diff --git a/nerdtree_plugin/fs_menu.vim b/nerdtree_plugin/fs_menu.vim index 9b81ed3..e99a85b 100644 --- a/nerdtree_plugin/fs_menu.vim +++ b/nerdtree_plugin/fs_menu.vim @@ -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 diff --git a/plugin/NERD_tree.vim b/plugin/NERD_tree.vim index 5bee03a..28fd3ad 100644 --- a/plugin/NERD_tree.vim +++ b/plugin/NERD_tree.vim @@ -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('') -command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.TogglePrimary('') -command! -n=0 -bar NERDTreeClose :call nerdtree#closeTreeIfOpen() -command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreatePrimary('') -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() diff --git a/syntax/nerdtree.vim b/syntax/nerdtree.vim index 636d2af..5f7b49c 100644 --- a/syntax/nerdtree.vim +++ b/syntax/nerdtree.vim @@ -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 #^[-\+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