diff --git a/README.markdown b/README.markdown index 9dacf68..fd8655c 100644 --- a/README.markdown +++ b/README.markdown @@ -55,7 +55,7 @@ The following features and functionality are provided by the NERD tree: Installation ------------ -[pathogen.vim](https://github.com/tpope/vim-pathogen) is the recommended way to install nerdtree. +####[pathogen.vim](https://github.com/tpope/vim-pathogen) cd ~/.vim/bundle git clone https://github.com/scrooloose/nerdtree.git @@ -63,49 +63,59 @@ Installation Then reload vim, run `:Helptags`, and check out `:help NERD_tree.txt`. +####[apt-vim](https://github.com/egalpin/apt-vim) + + apt-vim install -y https://github.com/scrooloose/nerdtree.git + + + Faq --- -__Q. Can I have the nerdtree on every tab automatically?__ +> Is there any support for `git` flags? -A. Nope. If this is something you want then chances are you aren't using tabs - and buffers as they were intended to be used. Read this - http://stackoverflow.com/questions/102384/using-vims-tabs-like-buffers +Yes, install [nerdtree-git-plugin](https://github.com/Xuyuanp/nerdtree-git-plugin). - If you are interested in this behaviour then consider [vim-nerdtree-tabs](https://github.com/jistr/vim-nerdtree-tabs) -__Q. How can I open a NERDTree automatically when vim starts up?__ +> Can I have the nerdtree on every tab automatically? -A. Stick this in your vimrc: `autocmd vimenter * NERDTree` +Nope. If this is something you want then chances are you aren't using tabs and +buffers as they were intended to be used. Read this +http://stackoverflow.com/questions/102384/using-vims-tabs-like-buffers -__Q. How can I open a NERDTree automatically when vim starts up if no files were specified?__ +If you are interested in this behaviour then consider [vim-nerdtree-tabs](https://github.com/jistr/vim-nerdtree-tabs) -A. Stick this in your vimrc +> How can I open a NERDTree automatically when vim starts up? + +Stick this in your vimrc: `autocmd vimenter * NERDTree` + +> How can I open a NERDTree automatically when vim starts up if no files were specified? + +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?__ +> 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` +Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever key you want): -__Q. How can I close vim if the only window left open is a NERDTree?__ + map :NERDTreeToggle -A. Stick this in your vimrc: +> How can I close vim if the only window left open is a NERDTree? - `autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif` +Stick this in your vimrc: + autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif -Changelog ---------- +> Can I have different highlighting for different file extensions? -4.2.0 (2011-12-28) +See here: https://github.com/scrooloose/nerdtree/issues/433#issuecomment-92590696 - * Add NERDTreeDirArrows option to make the UI use pretty arrow chars instead of the old +~| chars to define the tree structure (sickill) - * shift the syntax highlighting out into its own syntax file (gnap) * add some mac specific options to the filesystem menu - for macvim only (andersonfreitas) - * Add NERDTreeMinimalUI option to remove some non functional parts of the nerdtree ui (camthompson) - * tweak the behaviour of :NERDTreeFind - see :help :NERDTreeFind for the new behaviour (benjamingeiger) - * if no name is given to :Bookmark, make it default to the name of the target file/dir (minyoung) - * use 'file' completion when doing copying, create, and move operations (EvanDotPro) - * lots of misc bug fixes (paddyoloughlin, sdewald, camthompson, Vitaly Bogdanov, AndrewRadev, mathias, scottstvnsn, kml, wycats, me RAWR!) +> How can I change default arrows? +Use these variables in your vimrc. Note that below are default arrow symbols + + let g:NERDTreeDirArrows = 1 + let g:NERDTreeDirArrowExpandable = '▸' + let g:NERDTreeDirArrowCollapsible = '▾' diff --git a/autoload/nerdtree.vim b/autoload/nerdtree.vim index 539e783..37d7d10 100644 --- a/autoload/nerdtree.vim +++ b/autoload/nerdtree.vim @@ -34,6 +34,17 @@ function! nerdtree#compareNodes(n1, n2) return a:n1.path.compareTo(a:n2.path) endfunction +"FUNCTION: nerdtree#compareNodesBySortKey(n1, n2) {{{2 +function! nerdtree#compareNodesBySortKey(n1, n2) + if a:n1.path.getSortKey() <# a:n2.path.getSortKey() + return -1 + elseif a:n1.path.getSortKey() ># a:n2.path.getSortKey() + return 1 + else + return 0 + endif +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 @@ -95,175 +106,9 @@ function! nerdtree#runningWindows() return has("win16") || has("win32") || has("win64") endfunction -"FUNCTION: nerdtree#treeMarkupReg(dir) {{{2 -function! nerdtree#treeMarkupReg() - if g:NERDTreeDirArrows - return '^\([▾▸] \| \+[▾▸] \| \+\)' - endif - - return '^[ `|]*[\-+~]' -endfunction - -"FUNCTION: nerdtree#treeUpDirLine(dir) {{{2 -function! nerdtree#treeUpDirLine() - return '.. (up a dir)' -endfunction - -"FUNCTION: nerdtree#treeWid(dir) {{{2 -function! nerdtree#treeWid() - return 2 -endfunction - " SECTION: View Functions {{{1 "============================================================ -"FUNCTION: nerdtree#closeTree() {{{2 -"Closes the primary NERD tree window for this tab -function! nerdtree#closeTree() - if !nerdtree#isTreeOpen() - throw "NERDTree.NoTreeFoundError: no NERDTree is open" - endif - - if winnr("$") != 1 - if winnr() == nerdtree#getTreeWinNum() - call nerdtree#exec("wincmd p") - let bufnr = bufnr("") - call nerdtree#exec("wincmd p") - else - let bufnr = bufnr("") - endif - - call nerdtree#exec(nerdtree#getTreeWinNum() . " wincmd w") - close - call nerdtree#exec(bufwinnr(bufnr) . " wincmd w") - else - close - endif -endfunction - -"FUNCTION: nerdtree#closeTreeIfOpen() {{{2 -"Closes the NERD tree window if it is open -function! nerdtree#closeTreeIfOpen() - if nerdtree#isTreeOpen() - call nerdtree#closeTree() - endif -endfunction - -"FUNCTION: nerdtree#closeTreeIfQuitOnOpen() {{{2 -"Closes the NERD tree window if the close on open option is set -function! nerdtree#closeTreeIfQuitOnOpen() - if g:NERDTreeQuitOnOpen && nerdtree#isTreeOpen() - call nerdtree#closeTree() - endif -endfunction - -"FUNCTION: nerdtree#dumpHelp {{{2 -"prints out the quick help -function! nerdtree#dumpHelp() - let old_h = @h - if b:treeShowHelp ==# 1 - let @h= "\" NERD tree (" . nerdtree#version() . ") quickhelp~\n" - let @h=@h."\" ============================\n" - let @h=@h."\" File node mappings~\n" - let @h=@h."\" ". (g:NERDTreeMouseMode ==# 3 ? "single" : "double") ."-click,\n" - let @h=@h."\" ,\n" - if b:NERDTreeType ==# "primary" - let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in prev window\n" - else - let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in current window\n" - endif - if b:NERDTreeType ==# "primary" - let @h=@h."\" ". g:NERDTreeMapPreview .": preview\n" - endif - let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n" - let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n" - let @h=@h."\" middle-click,\n" - let @h=@h."\" ". g:NERDTreeMapOpenSplit .": open split\n" - let @h=@h."\" ". g:NERDTreeMapPreviewSplit .": preview split\n" - let @h=@h."\" ". g:NERDTreeMapOpenVSplit .": open vsplit\n" - let @h=@h."\" ". g:NERDTreeMapPreviewVSplit .": preview vsplit\n" - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Directory node mappings~\n" - let @h=@h."\" ". (g:NERDTreeMouseMode ==# 1 ? "double" : "single") ."-click,\n" - let @h=@h."\" ". g:NERDTreeMapActivateNode .": open & close node\n" - let @h=@h."\" ". g:NERDTreeMapOpenRecursively .": recursively open node\n" - let @h=@h."\" ". g:NERDTreeMapCloseDir .": close parent of node\n" - let @h=@h."\" ". g:NERDTreeMapCloseChildren .": close all child nodes of\n" - let @h=@h."\" current node recursively\n" - let @h=@h."\" middle-click,\n" - let @h=@h."\" ". g:NERDTreeMapOpenExpl.": explore selected dir\n" - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Bookmark table mappings~\n" - let @h=@h."\" double-click,\n" - let @h=@h."\" ". g:NERDTreeMapActivateNode .": open bookmark\n" - let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n" - let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n" - let @h=@h."\" ". g:NERDTreeMapDeleteBookmark .": delete bookmark\n" - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Tree navigation mappings~\n" - let @h=@h."\" ". g:NERDTreeMapJumpRoot .": go to root\n" - let @h=@h."\" ". g:NERDTreeMapJumpParent .": go to parent\n" - let @h=@h."\" ". g:NERDTreeMapJumpFirstChild .": go to first child\n" - let @h=@h."\" ". g:NERDTreeMapJumpLastChild .": go to last child\n" - let @h=@h."\" ". g:NERDTreeMapJumpNextSibling .": go to next sibling\n" - let @h=@h."\" ". g:NERDTreeMapJumpPrevSibling .": go to prev sibling\n" - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Filesystem mappings~\n" - let @h=@h."\" ". g:NERDTreeMapChangeRoot .": change tree root to the\n" - let @h=@h."\" selected dir\n" - let @h=@h."\" ". g:NERDTreeMapUpdir .": move tree root up a dir\n" - let @h=@h."\" ". g:NERDTreeMapUpdirKeepOpen .": move tree root up a dir\n" - let @h=@h."\" but leave old root open\n" - let @h=@h."\" ". g:NERDTreeMapRefresh .": refresh cursor dir\n" - let @h=@h."\" ". g:NERDTreeMapRefreshRoot .": refresh current root\n" - let @h=@h."\" ". g:NERDTreeMapMenu .": Show menu\n" - let @h=@h."\" ". g:NERDTreeMapChdir .":change the CWD to the\n" - let @h=@h."\" selected dir\n" - let @h=@h."\" ". g:NERDTreeMapCWD .":change tree root to CWD\n" - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Tree filtering mappings~\n" - let @h=@h."\" ". g:NERDTreeMapToggleHidden .": hidden files (" . (b:NERDTreeShowHidden ? "on" : "off") . ")\n" - let @h=@h."\" ". g:NERDTreeMapToggleFilters .": file filters (" . (b:NERDTreeIgnoreEnabled ? "on" : "off") . ")\n" - let @h=@h."\" ". g:NERDTreeMapToggleFiles .": files (" . (b:NERDTreeShowFiles ? "on" : "off") . ")\n" - let @h=@h."\" ". g:NERDTreeMapToggleBookmarks .": bookmarks (" . (b:NERDTreeShowBookmarks ? "on" : "off") . ")\n" - - "add quickhelp entries for each custom key map - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Custom mappings~\n" - for i in g:NERDTreeKeyMap.All() - if !empty(i.quickhelpText) - let @h=@h."\" ". i.key .": ". i.quickhelpText ."\n" - endif - endfor - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Other mappings~\n" - let @h=@h."\" ". g:NERDTreeMapQuit .": Close the NERDTree window\n" - let @h=@h."\" ". g:NERDTreeMapToggleZoom .": Zoom (maximize-minimize)\n" - let @h=@h."\" the NERDTree window\n" - 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."\" :BookmarkToRoot \n" - let @h=@h."\" :RevealBookmark \n" - let @h=@h."\" :OpenBookmark \n" - let @h=@h."\" :ClearBookmarks []\n" - let @h=@h."\" :ClearAllBookmarks\n" - silent! put h - elseif g:NERDTreeMinimalUI == 0 - let @h="\" Press ". g:NERDTreeMapHelp ." for help\n" - silent! put h - endif - - let @h = old_h -endfunction - "FUNCTION: nerdtree#echo {{{2 "A wrapper for :echo. Appends 'NERDTree:' on the front of all messages " @@ -294,114 +139,9 @@ function! nerdtree#echoWarning(msg) echohl normal endfunction -"FUNCTION: nerdtree#getTreeWinNum() {{{2 -"gets the nerd tree window number for this tab -function! nerdtree#getTreeWinNum() - if exists("t:NERDTreeBufName") - return bufwinnr(t:NERDTreeBufName) - else - return -1 - endif -endfunction - -"FUNCTION: nerdtree#isTreeOpen() {{{2 -function! nerdtree#isTreeOpen() - return nerdtree#getTreeWinNum() != -1 -endfunction - -"FUNCTION: nerdtree#putCursorOnBookmarkTable(){{{2 -"Places the cursor at the top of the bookmarks table -function! nerdtree#putCursorOnBookmarkTable() - if !b:NERDTreeShowBookmarks - throw "NERDTree.IllegalOperationError: cant find bookmark table, bookmarks arent active" - endif - - if g:NERDTreeMinimalUI - return cursor(1, 2) - endif - - let rootNodeLine = b:NERDTree.ui.getRootLineNum() - - let line = 1 - while getline(line) !~# '^>-\+Bookmarks-\+$' - let line = line + 1 - if line >= rootNodeLine - throw "NERDTree.BookmarkTableNotFoundError: didnt find the bookmarks table" - endif - endwhile - call cursor(line, 2) -endfunction - -"FUNCTION: nerdtree#putCursorInTreeWin(){{{2 -"Places the cursor in the nerd tree window -function! nerdtree#putCursorInTreeWin() - if !nerdtree#isTreeOpen() - throw "NERDTree.InvalidOperationError: cant put cursor in NERD tree window, no window exists" - endif - - call nerdtree#exec(nerdtree#getTreeWinNum() . "wincmd w") -endfunction - -"FUNCTION: nerdtree#renderBookmarks {{{2 -function! nerdtree#renderBookmarks() - - if g:NERDTreeMinimalUI == 0 - call setline(line(".")+1, ">----------Bookmarks----------") - call cursor(line(".")+1, col(".")) - endif - - for i in g:NERDTreeBookmark.Bookmarks() - call setline(line(".")+1, i.str()) - call cursor(line(".")+1, col(".")) - endfor - - call setline(line(".")+1, '') - call cursor(line(".")+1, col(".")) -endfunction - "FUNCTION: nerdtree#renderView {{{2 function! nerdtree#renderView() call b:NERDTree.render() endfunction -" -"FUNCTION: nerdtree#stripMarkupFromLine(line, removeLeadingSpaces){{{2 -"returns the given line with all the tree parts stripped off -" -"Args: -"line: the subject line -"removeLeadingSpaces: 1 if leading spaces are to be removed (leading spaces = -"any spaces before the actual text of the node) -function! nerdtree#stripMarkupFromLine(line, removeLeadingSpaces) - let line = a:line - "remove the tree parts and the leading space - let line = substitute (line, nerdtree#treeMarkupReg(),"","") - - "strip off any read only flag - let line = substitute (line, ' \[RO\]', "","") - - "strip off any bookmark flags - let line = substitute (line, ' {[^}]*}', "","") - - "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 - endif - let line = substitute (line,' -> .*',"","") " remove link to - if wasdir ==# 1 - let line = substitute (line, '/\?$', '/', "") - endif - - if a:removeLeadingSpaces - let line = substitute (line, '^ *', '', '') - endif - - return line -endfunction " vim: set sw=4 sts=4 et fdm=marker: diff --git a/autoload/nerdtree/ui_glue.vim b/autoload/nerdtree/ui_glue.vim index 8607389..dadb8f8 100644 --- a/autoload/nerdtree/ui_glue.vim +++ b/autoload/nerdtree/ui_glue.vim @@ -85,7 +85,7 @@ endfunction "FUNCTION: s:activateAll() {{{1 "handle the user activating the updir line function! s:activateAll() - if getline(".") ==# nerdtree#treeUpDirLine() + if getline(".") ==# g:NERDTreeUI.UpDirLine() return nerdtree#ui_glue#upDir(0) endif endfunction @@ -93,13 +93,13 @@ endfunction "FUNCTION: s:activateDirNode() {{{1 "handle the user activating a tree node function! s:activateDirNode(node) - call a:node.activate({'reuse': 1}) + call a:node.activate() endfunction "FUNCTION: s:activateFileNode() {{{1 "handle the user activating a tree node function! s:activateFileNode(node) - call a:node.activate({'reuse': 1, 'where': 'p'}) + call a:node.activate({'reuse': 'all', 'where': 'p'}) endfunction "FUNCTION: s:activateBookmark() {{{1 @@ -212,7 +212,7 @@ function! s:closeTreeWindow() exec "buffer " . b:NERDTreePreviousBuf else if winnr("$") > 1 - call nerdtree#closeTree() + call g:NERDTree.Close() else call nerdtree#echo("Cannot close last window") endif @@ -275,20 +275,20 @@ function! s:findAndRevealPath() endif else if !p.isUnder(g:NERDTreeFileNode.GetRootForTab().path) - if !nerdtree#isTreeOpen() + if !g:NERDTree.IsOpen() call g:NERDTreeCreator.TogglePrimary('') else - call nerdtree#putCursorInTreeWin() + call g:NERDTree.CursorToTreeWin() endif let b:NERDTreeShowHidden = g:NERDTreeShowHidden call s:chRoot(g:NERDTreeDirNode.New(p.getParent())) else - if !nerdtree#isTreeOpen() + if !g:NERDTree.IsOpen() call g:NERDTreeCreator.TogglePrimary("") endif endif endif - call nerdtree#putCursorInTreeWin() + call g:NERDTree.CursorToTreeWin() call b:NERDTreeRoot.reveal(p) if p.isUnixHiddenFile() @@ -312,7 +312,7 @@ function! s:handleLeftClick() endfor if currentNode.path.isDirectory - if startToCur =~# nerdtree#treeMarkupReg() && startToCur =~# '[+~▾▸] \?$' + if startToCur =~# g:NERDTreeUI.MarkupReg() && startToCur =~# '[+~'.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.'] \?$' call currentNode.activate() return endif @@ -320,11 +320,11 @@ function! s:handleLeftClick() if (g:NERDTreeMouseMode ==# 2 && currentNode.path.isDirectory) || g:NERDTreeMouseMode ==# 3 let char = strpart(startToCur, strlen(startToCur)-1, 1) - if char !~# nerdtree#treeMarkupReg() + if char !~# g:NERDTreeUI.MarkupReg() if currentNode.path.isDirectory call currentNode.activate() else - call currentNode.activate({'reuse': 1, 'where': 'p'}) + call currentNode.activate({'reuse': 'all', 'where': 'p'}) endif return endif @@ -547,7 +547,7 @@ endfunction 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=0 -bar NERDTreeClose :call g:NERDTree.Close() 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() diff --git a/doc/NERD_tree.txt b/doc/NERD_tree.txt index 5d5b3f6..fbca0e1 100644 --- a/doc/NERD_tree.txt +++ b/doc/NERD_tree.txt @@ -34,6 +34,8 @@ CONTENTS *NERDTree-contents* 4.The NERD tree API.......................|NERDTreeAPI| 4.1.Key map API.......................|NERDTreeKeymapAPI| 4.2.Menu API..........................|NERDTreeMenuAPI| + 4.3.Menu API..........................|NERDTreeAddPathFilter()| + 4.4.Path Listener API.................|NERDTreePathListenerAPI| 5.About...................................|NERDTreeAbout| 6.Changelog...............................|NERDTreeChangelog| 7.Credits.................................|NERDTreeCredits| @@ -131,7 +133,7 @@ The following features and functionality are provided by the NERD tree: :NERDTreeFind *:NERDTreeFind* Find the current file in the tree. - If not tree exists and the current file is under vim's CWD, then init a + If no tree exists and the current file is under vim's CWD, then init a tree at the CWD and reveal the file. Otherwise init a tree in the current file's directory. @@ -1173,6 +1175,44 @@ Where selecting "a (s)ub menu" will lead to a second menu: > When any of the 3 concrete menu items are selected the function "SomeFunction" will be called. +------------------------------------------------------------------------------ +4.3 NERDTreeAddPathFilter(callback) *NERDTreeAddPathFilter()* + +Path filters are essentially a more powerful version of |NERDTreeIgnore|. +If the simple regex matching in |NERDTreeIgnore| is not enough then use +|NERDTreeAddPathFilter()| to add a callback function that paths will be +checked against when the decision to ignore them is made. Example > + + call NERDTreeAddPathFilter('MyFilter') + + function! MyFilter(params) + "params is a dict containing keys: 'nerdtree' and 'path' which are + "g:NERDTree and g:NERDTreePath objects + + "return 1 to ignore params['path'] or 0 otherwise + endfunction +< +------------------------------------------------------------------------------ +4.4 Path Listener API *NERDTreePathListenerAPI* + +Use this API if you want to run a callback for events on Path objects. E.G > + + call g:NERDTreePathNotifier.AddListener("init", "MyListener") + + ".... + + function! MyListener(event) + "This function will be called whenever a Path object is created. + + "a:event is an object that contains a bunch of relevant info - + "including the path in question. See lib/nerdtree/event.vim for details. + endfunction +< +Current events supported: + init ~ + refresh ~ + refreshFlags ~ + ------------------------------------------------------------------------------ NERDTreeRender() *NERDTreeRender()* Re-renders the NERD tree buffer. Useful if you change the state of the @@ -1203,6 +1243,8 @@ Next - add 'scope' argument to the key map API - add NERDTreeCustomIgnoreFilter hook - needs doc - add magic [[dir]] and [[file]] flags to NERDTreeIgnore + - add support for custom path filters. See :help NERDTreeAddPathFilter() + - add path listener API. See :help NERDTreePathListenerAPI. 4.2.0 - Add NERDTreeDirArrows option to make the UI use pretty arrow chars diff --git a/lib/nerdtree/bookmark.vim b/lib/nerdtree/bookmark.vim index 6de9be4..91648d2 100644 --- a/lib/nerdtree/bookmark.vim +++ b/lib/nerdtree/bookmark.vim @@ -87,6 +87,7 @@ function! s:Bookmark.CacheBookmarks(silent) let name = substitute(i, '^\(.\{-}\) .*$', '\1', '') let path = substitute(i, '^.\{-} \(.*\)$', '\1', '') + let path = fnamemodify(path, ':p') try let bookmark = s:Bookmark.New(name, g:NERDTreePath.New(path)) @@ -253,7 +254,7 @@ endfunction " FUNCTION: Bookmark.str() {{{1 " Get the string that should be rendered in the view for this bookmark function! s:Bookmark.str() - let pathStrMaxLen = winwidth(nerdtree#getTreeWinNum()) - 4 - len(self.name) + let pathStrMaxLen = winwidth(g:NERDTree.GetWinNum()) - 4 - len(self.name) if &nu let pathStrMaxLen = pathStrMaxLen - &numberwidth endif @@ -304,7 +305,7 @@ endfunction function! s:Bookmark.Write() let bookmarkStrings = [] for i in s:Bookmark.Bookmarks() - call add(bookmarkStrings, i.name . ' ' . i.path.str()) + call add(bookmarkStrings, i.name . ' ' . fnamemodify(i.path.str(), ':~')) endfor "add a blank line before the invalid ones diff --git a/lib/nerdtree/creator.vim b/lib/nerdtree/creator.vim index 86f951a..89f03a3 100644 --- a/lib/nerdtree/creator.vim +++ b/lib/nerdtree/creator.vim @@ -42,6 +42,15 @@ endfunction "name: the name of a bookmark or a directory function! s:Creator.createPrimary(name) let path = self._pathForString(a:name) + + "abort if exception was thrown (bookmark/dir doesn't exist) + if empty(path) + return + endif + + if path == {} + return + endif "if instructed to, then change the vim CWD to the dir the NERDTree is "inited in @@ -50,8 +59,8 @@ function! s:Creator.createPrimary(name) endif if g:NERDTree.ExistsForTab() - if nerdtree#isTreeOpen() - call nerdtree#closeTree() + if g:NERDTree.IsOpen() + call g:NERDTree.Close() endif unlet t:NERDTreeBufName endif @@ -163,8 +172,8 @@ function! s:Creator.createMirror() return endif - if g:NERDTree.ExistsForTab() && nerdtree#isTreeOpen() - call nerdtree#closeTree() + if g:NERDTree.ExistsForTab() && g:NERDTree.IsOpen() + call g:NERDTree.Close() endif let t:NERDTreeBufName = bufferName @@ -240,7 +249,7 @@ function! s:Creator._pathForString(str) let path = g:NERDTreePath.New(dir) catch /^NERDTree.InvalidArgumentsError/ call nerdtree#echo("No bookmark or directory found for: " . a:str) - return + return {} endtry endif if !path.isDirectory @@ -328,14 +337,14 @@ endfunction "initialized. function! s:Creator.togglePrimary(dir) if g:NERDTree.ExistsForTab() - if !nerdtree#isTreeOpen() + if !g:NERDTree.IsOpen() call self._createTreeWin() if !&hidden call b:NERDTree.render() endif call b:NERDTree.ui.restoreScreenState() else - call nerdtree#closeTree() + call g:NERDTree.Close() endif else call self.createPrimary(a:dir) diff --git a/lib/nerdtree/nerdtree.vim b/lib/nerdtree/nerdtree.vim index a41490b..55f3dd7 100644 --- a/lib/nerdtree/nerdtree.vim +++ b/lib/nerdtree/nerdtree.vim @@ -3,6 +3,73 @@ let s:NERDTree = {} let g:NERDTree = s:NERDTree +"FUNCTION: s:NERDTree.AddPathFilter() {{{1 +function! s:NERDTree.AddPathFilter(callback) + call add(s:NERDTree.PathFilters(), a:callback) +endfunction + +"FUNCTION: s:NERDTree.Close() {{{1 +"Closes the primary NERD tree window for this tab +function! s:NERDTree.Close() + if !s:NERDTree.IsOpen() + return + endif + + if winnr("$") != 1 + if winnr() == s:NERDTree.GetWinNum() + call nerdtree#exec("wincmd p") + let bufnr = bufnr("") + call nerdtree#exec("wincmd p") + else + let bufnr = bufnr("") + endif + + call nerdtree#exec(s:NERDTree.GetWinNum() . " wincmd w") + close + call nerdtree#exec(bufwinnr(bufnr) . " wincmd w") + else + close + endif +endfunction + +"FUNCTION: s:NERDTree.CloseIfQuitOnOpen() {{{1 +"Closes the NERD tree window if the close on open option is set +function! s:NERDTree.CloseIfQuitOnOpen() + if g:NERDTreeQuitOnOpen && s:NERDTree.IsOpen() + call s:NERDTree.Close() + endif +endfunction + +"FUNCTION: s:NERDTree.CursorToBookmarkTable(){{{1 +"Places the cursor at the top of the bookmarks table +function! s:NERDTree.CursorToBookmarkTable() + if !b:NERDTreeShowBookmarks + throw "NERDTree.IllegalOperationError: cant find bookmark table, bookmarks arent active" + endif + + if g:NERDTreeMinimalUI + return cursor(1, 2) + endif + + let rootNodeLine = b:NERDTree.ui.getRootLineNum() + + let line = 1 + while getline(line) !~# '^>-\+Bookmarks-\+$' + let line = line + 1 + if line >= rootNodeLine + throw "NERDTree.BookmarkTableNotFoundError: didnt find the bookmarks table" + endif + endwhile + call cursor(line, 2) +endfunction + +"FUNCTION: s:NERDTree.CursorToTreeWin(){{{1 +"Places the cursor in the nerd tree window +function! s:NERDTree.CursorToTreeWin() + call g:NERDTree.MustBeOpen() + call nerdtree#exec(g:NERDTree.GetWinNum() . "wincmd w") +endfunction + " Function: s:NERDTree.ExistsForBuffer() {{{1 " Returns 1 if a nerd tree root exists in the current buffer function! s:NERDTree.ExistsForBuf() @@ -23,6 +90,29 @@ function! s:NERDTree.ForCurrentBuf() endif endfunction +"FUNCTION: s:NERDTree.GetWinNum() {{{1 +"gets the nerd tree window number for this tab +function! s:NERDTree.GetWinNum() + if exists("t:NERDTreeBufName") + return bufwinnr(t:NERDTreeBufName) + else + return -1 + endif +endfunction + +"FUNCTION: s:NERDTree.IsOpen() {{{1 +function! s:NERDTree.IsOpen() + return s:NERDTree.GetWinNum() != -1 +endfunction + +"FUNCTION: s:NERDTree.MustBeOpen() {{{1 +function! s:NERDTree.MustBeOpen() + if !s:NERDTree.IsOpen() + throw "NERDTree.TreeNotOpen" + endif +endfunction + +"FUNCTION: s:NERDTree.New() {{{1 function! s:NERDTree.New(path) let newObj = copy(self) let newObj.ui = g:NERDTreeUI.New(newObj) @@ -31,9 +121,17 @@ function! s:NERDTree.New(path) return newObj endfunction +"FUNCTION: s:NERDTree.PathFilters() {{{1 +function! s:NERDTree.PathFilters() + if !exists('s:NERDTree._PathFilters') + let s:NERDTree._PathFilters = [] + endif + return s:NERDTree._PathFilters +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/opener.vim b/lib/nerdtree/opener.vim index 845e55c..3a6b392 100644 --- a/lib/nerdtree/opener.vim +++ b/lib/nerdtree/opener.vim @@ -40,7 +40,7 @@ function! s:Opener._checkToCloseTree(newtab) endif if (a:newtab && self._where == 't') || !a:newtab - call nerdtree#closeTreeIfQuitOnOpen() + call g:NERDTree.CloseIfQuitOnOpen() endif endfunction @@ -131,7 +131,8 @@ endfunction " 'where': Specifies whether the node should be opened in new split/tab or in " the previous window. Can be either 'v' or 'h' or 't' (for open in " new tab) -" 'reuse': if a window is displaying the file then jump the cursor there +" 'reuse': if a window is displaying the file then jump the cursor there. Can +" 'all', 'currenttab' or empty to not reuse. " 'keepopen': dont close the tree window " 'stay': open the file, but keep the cursor in the tree win function! s:Opener.New(path, opts) @@ -139,7 +140,13 @@ function! s:Opener.New(path, opts) let newObj._path = a:path let newObj._stay = nerdtree#has_opt(a:opts, 'stay') - let newObj._reuse = nerdtree#has_opt(a:opts, 'reuse') + + if has_key(a:opts, 'reuse') + let newObj._reuse = a:opts['reuse'] + else + let newObj._reuse = '' + endif + let newObj._keepopen = nerdtree#has_opt(a:opts, 'keepopen') let newObj._where = has_key(a:opts, 'where') ? a:opts['where'] : '' let newObj._treetype = b:NERDTreeType @@ -189,7 +196,7 @@ function! s:Opener._newSplit() try exec(splitMode." sp ") catch /^Vim\%((\a\+)\)\=:E37/ - call nerdtree#putCursorInTreeWin() + call g:NERDTree.CursorToTreeWin() throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified." catch /^Vim\%((\a\+)\)\=:/ "do nothing @@ -219,7 +226,7 @@ function! s:Opener._newVSplit() vnew "resize the nerd tree back to the original size - call nerdtree#putCursorInTreeWin() + call g:NERDTree.CursorToTreeWin() exec("silent vertical resize ". winwidth) call nerdtree#exec('wincmd p') endfunction @@ -235,7 +242,7 @@ endfunction "FUNCTION: Opener._openFile() {{{1 function! s:Opener._openFile() - if self._reuse && self._reuseWindow() + if self._reuseWindow() return endif @@ -288,7 +295,7 @@ function! s:Opener._previousWindow() call nerdtree#exec('wincmd p') endif catch /^Vim\%((\a\+)\)\=:E37/ - call nerdtree#putCursorInTreeWin() + call g:NERDTree.CursorToTreeWin() throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified." catch /^Vim\%((\a\+)\)\=:/ echo v:exception @@ -307,23 +314,32 @@ endfunction " "return 1 if we were successful function! s:Opener._reuseWindow() + if empty(self._reuse) + return 0 + endif + "check the current tab for the window let winnr = bufwinnr('^' . self._path.str() . '$') if winnr != -1 call nerdtree#exec(winnr . "wincmd w") call self._checkToCloseTree(0) return 1 - else - "check other tabs - let tabnr = self._path.tabnr() - if tabnr - call self._checkToCloseTree(1) - call nerdtree#exec('normal! ' . tabnr . 'gt') - let winnr = bufwinnr('^' . self._path.str() . '$') - call nerdtree#exec(winnr . "wincmd w") - return 1 - endif endif + + if self._reuse == 'currenttab' + return 0 + endif + + "check other tabs + let tabnr = self._path.tabnr() + if tabnr + call self._checkToCloseTree(1) + call nerdtree#exec('normal! ' . tabnr . 'gt') + let winnr = bufwinnr('^' . self._path.str() . '$') + call nerdtree#exec(winnr . "wincmd w") + return 1 + endif + return 0 endfunction diff --git a/lib/nerdtree/path.vim b/lib/nerdtree/path.vim index 5de1dfe..2af07dd 100644 --- a/lib/nerdtree/path.vim +++ b/lib/nerdtree/path.vim @@ -1,6 +1,12 @@ "we need to use this number many times for sorting... so we calculate it only "once here let s:NERDTreeSortStarIndex = index(g:NERDTreeSortOrder, '*') +" used in formating sortKey, e.g. '%04d' +if exists("log10") + let s:sortKeyFormat = "%0" . float2nr(ceil(log10(len(g:NERDTreeSortOrder)))) . "d" +else + let s:sortKeyFormat = "%04d" +endif "CLASS: Path "============================================================ @@ -361,6 +367,24 @@ function! s:Path.getSortOrderIndex() return s:NERDTreeSortStarIndex endfunction +"FUNCTION: Path.getSortKey() {{{1 +"returns a string used in compare function for sorting +function! s:Path.getSortKey() + if !exists("self._sortKey") + let path = self.getLastPathComponent(1) + if !g:NERDTreeSortHiddenFirst + let path = substitute(path, '^[._]', '', '') + endif + if !g:NERDTreeCaseSensitiveSort + let path = tolower(path) + endif + let self._sortKey = printf(s:sortKeyFormat, self.getSortOrderIndex()) . path + endif + + return self._sortKey +endfunction + + "FUNCTION: Path.isUnixHiddenFile() {{{1 "check for unix hidden files function! s:Path.isUnixHiddenFile() @@ -392,6 +416,12 @@ function! s:Path.ignore() return 1 endif endfor + + for callback in g:NERDTree.PathFilters() + if {callback}({'path': self, 'nerdtree': b:NERDTree}) + return 1 + endif + endfor endif "dont show hidden files unless instructed to @@ -403,10 +433,6 @@ function! s:Path.ignore() return 1 endif - if exists("*NERDTreeCustomIgnoreFilter") && NERDTreeCustomIgnoreFilter(self) - return 1 - endif - return 0 endfunction @@ -611,7 +637,7 @@ function! s:Path.str(...) if has_key(self, '_strFor' . format) exec 'let toReturn = self._strFor' . format . '()' else - raise 'NERDTree.UnknownFormatError: unknown format "'. format .'"' + throw 'NERDTree.UnknownFormatError: unknown format "'. format .'"' endif else let toReturn = self._str() @@ -623,8 +649,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 = ',\n" + if b:NERDTreeType ==# "primary" + let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in prev window\n" + else + let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in current window\n" + endif + if b:NERDTreeType ==# "primary" + let @h=@h."\" ". g:NERDTreeMapPreview .": preview\n" + endif + let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n" + let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n" + let @h=@h."\" middle-click,\n" + let @h=@h."\" ". g:NERDTreeMapOpenSplit .": open split\n" + let @h=@h."\" ". g:NERDTreeMapPreviewSplit .": preview split\n" + let @h=@h."\" ". g:NERDTreeMapOpenVSplit .": open vsplit\n" + let @h=@h."\" ". g:NERDTreeMapPreviewVSplit .": preview vsplit\n" + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Directory node mappings~\n" + let @h=@h."\" ". (g:NERDTreeMouseMode ==# 1 ? "double" : "single") ."-click,\n" + let @h=@h."\" ". g:NERDTreeMapActivateNode .": open & close node\n" + let @h=@h."\" ". g:NERDTreeMapOpenRecursively .": recursively open node\n" + let @h=@h."\" ". g:NERDTreeMapCloseDir .": close parent of node\n" + let @h=@h."\" ". g:NERDTreeMapCloseChildren .": close all child nodes of\n" + let @h=@h."\" current node recursively\n" + let @h=@h."\" middle-click,\n" + let @h=@h."\" ". g:NERDTreeMapOpenExpl.": explore selected dir\n" + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Bookmark table mappings~\n" + let @h=@h."\" double-click,\n" + let @h=@h."\" ". g:NERDTreeMapActivateNode .": open bookmark\n" + let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n" + let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n" + let @h=@h."\" ". g:NERDTreeMapDeleteBookmark .": delete bookmark\n" + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Tree navigation mappings~\n" + let @h=@h."\" ". g:NERDTreeMapJumpRoot .": go to root\n" + let @h=@h."\" ". g:NERDTreeMapJumpParent .": go to parent\n" + let @h=@h."\" ". g:NERDTreeMapJumpFirstChild .": go to first child\n" + let @h=@h."\" ". g:NERDTreeMapJumpLastChild .": go to last child\n" + let @h=@h."\" ". g:NERDTreeMapJumpNextSibling .": go to next sibling\n" + let @h=@h."\" ". g:NERDTreeMapJumpPrevSibling .": go to prev sibling\n" + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Filesystem mappings~\n" + let @h=@h."\" ". g:NERDTreeMapChangeRoot .": change tree root to the\n" + let @h=@h."\" selected dir\n" + let @h=@h."\" ". g:NERDTreeMapUpdir .": move tree root up a dir\n" + let @h=@h."\" ". g:NERDTreeMapUpdirKeepOpen .": move tree root up a dir\n" + let @h=@h."\" but leave old root open\n" + let @h=@h."\" ". g:NERDTreeMapRefresh .": refresh cursor dir\n" + let @h=@h."\" ". g:NERDTreeMapRefreshRoot .": refresh current root\n" + let @h=@h."\" ". g:NERDTreeMapMenu .": Show menu\n" + let @h=@h."\" ". g:NERDTreeMapChdir .":change the CWD to the\n" + let @h=@h."\" selected dir\n" + let @h=@h."\" ". g:NERDTreeMapCWD .":change tree root to CWD\n" + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Tree filtering mappings~\n" + let @h=@h."\" ". g:NERDTreeMapToggleHidden .": hidden files (" . (b:NERDTreeShowHidden ? "on" : "off") . ")\n" + let @h=@h."\" ". g:NERDTreeMapToggleFilters .": file filters (" . (b:NERDTreeIgnoreEnabled ? "on" : "off") . ")\n" + let @h=@h."\" ". g:NERDTreeMapToggleFiles .": files (" . (b:NERDTreeShowFiles ? "on" : "off") . ")\n" + let @h=@h."\" ". g:NERDTreeMapToggleBookmarks .": bookmarks (" . (b:NERDTreeShowBookmarks ? "on" : "off") . ")\n" + + "add quickhelp entries for each custom key map + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Custom mappings~\n" + for i in g:NERDTreeKeyMap.All() + if !empty(i.quickhelpText) + let @h=@h."\" ". i.key .": ". i.quickhelpText ."\n" + endif + endfor + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Other mappings~\n" + let @h=@h."\" ". g:NERDTreeMapQuit .": Close the NERDTree window\n" + let @h=@h."\" ". g:NERDTreeMapToggleZoom .": Zoom (maximize-minimize)\n" + let @h=@h."\" the NERDTree window\n" + 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."\" :BookmarkToRoot \n" + let @h=@h."\" :RevealBookmark \n" + let @h=@h."\" :OpenBookmark \n" + let @h=@h."\" :ClearBookmarks []\n" + let @h=@h."\" :ClearAllBookmarks\n" + silent! put h + elseif g:NERDTreeMinimalUI == 0 + let @h="\" Press ". g:NERDTreeMapHelp ." for help\n" + silent! put h + endif + + let @h = old_h +endfunction + + "FUNCTION: s:UI.new(nerdtree) {{{1 function! s:UI.New(nerdtree) let newObj = copy(self) @@ -51,19 +154,19 @@ function! s:UI.getPath(ln) if !g:NERDTreeDirArrows " in case called from outside the tree - if line !~# '^ *[|`▸▾ ]' || line =~# '^$' + if line !~# '^ *[|`'.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.' ]' || line =~# '^$' return {} endif endif - if line ==# nerdtree#treeUpDirLine() + if line ==# s:UI.UpDirLine() 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 curFile = self._stripMarkup(line, 0) let wasdir = 0 if curFile =~# '/$' @@ -76,7 +179,7 @@ function! s:UI.getPath(ln) while lnum > 0 let lnum = lnum - 1 let curLine = getline(lnum) - let curLineStripped = nerdtree#stripMarkupFromLine(curLine, 1) + let curLineStripped = self._stripMarkup(curLine, 1) "have we reached the top of the tree? if lnum == rootLine @@ -127,7 +230,7 @@ function! s:UI.getLineNum(file_node) let indent = self._indentLevelFor(curLine) if indent ==# curPathComponent - let curLine = nerdtree#stripMarkupFromLine(curLine, 1) + let curLine = self._stripMarkup(curLine, 1) let curPath = join(pathcomponents, '/') . '/' . curLine if stridx(fullpath, curPath, 0) ==# 0 @@ -146,7 +249,6 @@ function! s:UI.getLineNum(file_node) return -1 endfunction - "FUNCTION: s:UI.getRootLineNum(){{{1 "gets the line number of the root node function! s:UI.getRootLineNum() @@ -157,19 +259,49 @@ function! s:UI.getRootLineNum() return rootLine endfunction -"FUNCTION: s:UI._indentLevelFor(line) {{{2 +"FUNCTION: s:UI._indentLevelFor(line) {{{1 function! s:UI._indentLevelFor(line) - let level = match(a:line, '[^ \-+~▸▾`|]') / nerdtree#treeWid() + let level = match(a:line, '[^ \-+~'.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.'`|]') / s:UI.IndentWid() " check if line includes arrows - if match(a:line, '[▸▾]') > -1 + if match(a:line, '['.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.']') > -1 " decrement level as arrow uses 3 ascii chars let level = level - 1 endif return level endfunction +"FUNCTION: s:UI.IndentWid() {{{1 +function! s:UI.IndentWid() + return 2 +endfunction -"FUNCTION: s:UI.restoreScreenState() {{{2 +"FUNCTION: s:UI.MarkupReg() {{{1 +function! s:UI.MarkupReg() + if g:NERDTreeDirArrows + return '^\(['.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.'] \| \+['.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.'] \| \+\)' + endif + + return '^[ `|]*[\-+~]' +endfunction + +"FUNCTION: s:UI._renderBookmarks {{{1 +function! s:UI._renderBookmarks() + + if g:NERDTreeMinimalUI == 0 + call setline(line(".")+1, ">----------Bookmarks----------") + call cursor(line(".")+1, col(".")) + endif + + for i in g:NERDTreeBookmark.Bookmarks() + call setline(line(".")+1, i.str()) + call cursor(line(".")+1, col(".")) + endfor + + call setline(line(".")+1, '') + call cursor(line(".")+1, col(".")) +endfunction + +"FUNCTION: s:UI.restoreScreenState() {{{1 " "Sets the screen state back to what it was when nerdtree#saveScreenState was last "called. @@ -189,23 +321,60 @@ function! s:UI.restoreScreenState() let &scrolloff=old_scrolloff endfunction -"FUNCTION: s:UI.saveScreenState() {{{2 +"FUNCTION: s:UI.saveScreenState() {{{1 "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 + call g:NERDTree.CursorToTreeWin() + 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") endfunction -"FUNCTION: s:UI.render() {{{2 +"FUNCTION: s:UI._stripMarkup(line, removeLeadingSpaces){{{1 +"returns the given line with all the tree parts stripped off +" +"Args: +"line: the subject line +"removeLeadingSpaces: 1 if leading spaces are to be removed (leading spaces = +"any spaces before the actual text of the node) +function! s:UI._stripMarkup(line, removeLeadingSpaces) + let line = a:line + "remove the tree parts and the leading space + let line = substitute (line, g:NERDTreeUI.MarkupReg(),"","") + + "strip off any read only flag + let line = substitute (line, ' \[RO\]', "","") + + "strip off any bookmark flags + let line = substitute (line, ' {[^}]*}', "","") + + "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 + endif + let line = substitute (line,' -> .*',"","") " remove link to + if wasdir ==# 1 + let line = substitute (line, '/\?$', '/', "") + endif + + if a:removeLeadingSpaces + let line = substitute (line, '^ *', '', '') + endif + + return line +endfunction + +"FUNCTION: s:UI.render() {{{1 function! s:UI.render() setlocal modifiable @@ -218,7 +387,7 @@ function! s:UI.render() "delete all lines in the buffer (being careful not to clobber a register) silent 1,$delete _ - call nerdtree#dumpHelp() + call self._dumpHelp() "delete the blank line before the help and add one after it if g:NERDTreeMinimalUI == 0 @@ -227,12 +396,12 @@ function! s:UI.render() endif if b:NERDTreeShowBookmarks - call nerdtree#renderBookmarks() + call self._renderBookmarks() endif "add the 'up a dir' line if !g:NERDTreeMinimalUI - call setline(line(".")+1, nerdtree#treeUpDirLine()) + call setline(line(".")+1, s:UI.UpDirLine()) call cursor(line(".")+1, col(".")) endif @@ -295,7 +464,7 @@ function! s:UI.toggleShowBookmarks() let b:NERDTreeShowBookmarks = !b:NERDTreeShowBookmarks if b:NERDTreeShowBookmarks call b:NERDTree.render() - call nerdtree#putCursorOnBookmarkTable() + call g:NERDTree.CursorToBookmarkTable() else call b:NERDTree.ui.renderViewSavingPosition() endif @@ -330,3 +499,8 @@ function! s:UI.toggleZoom() let b:NERDTreeZoomed = 1 endif endfunction + +"FUNCTION: s:UI.UpDirLine() {{{1 +function! s:UI.UpDirLine() + return '.. (up a dir)' +endfunction diff --git a/nerdtree_plugin/fs_menu.vim b/nerdtree_plugin/fs_menu.vim index e944709..db729b4 100644 --- a/nerdtree_plugin/fs_menu.vim +++ b/nerdtree_plugin/fs_menu.vim @@ -25,7 +25,7 @@ call NERDTreeAddMenuItem({'text': '(m)ove the current node', 'shortcut': 'm', 'c call NERDTreeAddMenuItem({'text': '(d)elete the current node', 'shortcut': 'd', 'callback': 'NERDTreeDeleteNode'}) call NERDTreeAddMenuItem({'text': 'show (p)roperties of the current node', 'shortcut': 'p', 'callback': 'NERDTreeNodeProperties'}) -if has("gui_mac") || has("gui_macvim") +if has("gui_mac") || has("gui_macvim") || has("mac") 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'}) @@ -35,6 +35,10 @@ if g:NERDTreePath.CopyingSupported() call NERDTreeAddMenuItem({'text': '(c)opy the current node', 'shortcut': 'c', 'callback': 'NERDTreeCopyNode'}) endif +if has("unix") || has("osx") + call NERDTreeAddMenuItem({'text': '(l)ist the current node', 'shortcut': 'l', 'callback': 'NERDTreeListNode'}) +endif + "FUNCTION: s:echo(msg){{{1 function! s:echo(msg) redraw @@ -87,10 +91,11 @@ function! s:promptToRenameBuffer(bufnum, msg, newFileName) " 1. ensure that a new buffer is loaded 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! " . quotedFileName . "\" | 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 @@ -273,4 +278,14 @@ function! NERDTreeExecuteFile() endif endfunction +function! NERDTreeListNode() + let treenode = g:NERDTreeFileNode.GetSelected() + if treenode != {} + let metadata = split(system('ls -ld ' . shellescape(treenode.path.str())), '\n') + call s:echo(metadata[0]) + else + call s:echo("No information avaialable") + endif +endfunction + " vim: set sw=4 sts=4 et fdm=marker: diff --git a/plugin/NERD_tree.vim b/plugin/NERD_tree.vim index 28fd3ad..6fff0c3 100644 --- a/plugin/NERD_tree.vim +++ b/plugin/NERD_tree.vim @@ -68,6 +68,8 @@ 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:NERDTreeDirArrowExpandable", "▸") +call s:initVariable("g:NERDTreeDirArrowCollapsible", "▾") call s:initVariable("g:NERDTreeCascadeOpenSingleChildDir", 1) if !exists("g:NERDTreeSortOrder") @@ -148,7 +150,7 @@ call nerdtree#ui_glue#setupCommands() "============================================================ augroup NERDTree "Save the cursor position whenever we close the nerd tree - exec "autocmd BufLeave ". g:NERDTreeCreator.BufNamePrefix() ."* call b:NERDTree.ui.saveScreenState()" + exec "autocmd BufLeave ". g:NERDTreeCreator.BufNamePrefix() ."* if g:NERDTree.IsOpen() | call b:NERDTree.ui.saveScreenState() | endif" "disallow insert mode in the NERDTree exec "autocmd BufEnter ". g:NERDTreeCreator.BufNamePrefix() ."* stopinsert" @@ -185,8 +187,8 @@ function! NERDTreeRender() endfunction function! NERDTreeFocus() - if nerdtree#isTreeOpen() - call nerdtree#putCursorInTreeWin() + if g:NERDTree.IsOpen() + call g:NERDTree.CursorToTreeWin() else call g:NERDTreeCreator.TogglePrimary("") endif @@ -196,6 +198,11 @@ function! NERDTreeCWD() call NERDTreeFocus() call nerdtree#ui_glue#chRootCwd() endfunction + +function! NERDTreeAddPathFilter(callback) + call g:NERDTree.AddPathFilter(a:callback) +endfunction + " SECTION: Post Source Actions {{{1 call nerdtree#postSourceActions() diff --git a/syntax/nerdtree.vim b/syntax/nerdtree.vim index 5f7b49c..846cf49 100644 --- a/syntax/nerdtree.vim +++ b/syntax/nerdtree.vim @@ -23,17 +23,18 @@ syn match NERDTreeLinkDir #.*/ ->#me=e-3 containedin=NERDTreeDir syn match NERDTreeDirSlash #/# containedin=NERDTreeDir if g:NERDTreeDirArrows - syn match NERDTreeClosable #▾# containedin=NERDTreeDir,NERDTreeFile - syn match NERDTreeOpenable #▸# containedin=NERDTreeDir,NERDTreeFile + exec 'syn match NERDTreeClosable #'.escape(g:NERDTreeDirArrowCollapsible, '~').'# containedin=NERDTreeDir,NERDTreeFile' + exec 'syn match NERDTreeOpenable #'.escape(g:NERDTreeDirArrowExpandable, '~').'# containedin=NERDTreeDir,NERDTreeFile' - syn match NERDTreeDir #[^▾▸ ].*/# + let s:dirArrows = escape(g:NERDTreeDirArrowCollapsible, '~').escape(g:NERDTreeDirArrowExpandable, '~') + exec 'syn match NERDTreeDir #[^'.s:dirArrows.' ].*/#' syn match NERDTreeExecFile #^ .*\*\($\| \)# contains=NERDTreeRO,NERDTreeBookmark - syn match NERDTreeFile #^[^"\.▾▸] *[^▾▸]*# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmark,NERDTreeExecFile + exec 'syn match NERDTreeFile #^[^"\.'.s:dirArrows.'] *[^'.s:dirArrows.']*# 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 #^ *\zs\[.\]# containedin=NERDTreeFile,NERDTreeExecFile syn match NERDTreeFlags #\[.\]# containedin=NERDTreeDir else "highlighting for the ~/+ symbols for the directory nodes