commit fb030bcb1c4da84308516d1094336530d28748ce
parent 6ccf83df24ac3044117e10b99be43d00923dbeea
Author: Phil Runninger <PhilRunninger@users.noreply.github.com>
Date: Thu, 12 Nov 2015 16:11:56 -0500
Merge pull request #1 from scrooloose/master
Merge official code into my fork
Diffstat:
15 files changed, 550 insertions(+), 408 deletions(-)
diff --git 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?
+
+Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever key you want):
-A. Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever key you want): `map <C-n> :NERDTreeToggle<CR>`
+ map <C-n> :NERDTreeToggle<CR>
-__Q. How can I close vim if the only window left open is a NERDTree?__
+> How can I close vim if the only window left open is a NERDTree?
-A. Stick this in your vimrc:
+Stick this in your vimrc:
- `autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif`
+ autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif
+> Can I have different highlighting for different file extensions?
-Changelog
----------
+See here: https://github.com/scrooloose/nerdtree/issues/433#issuecomment-92590696
-4.2.0 (2011-12-28)
+> How can I change default arrows?
- * 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!)
+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
@@ -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."\" <CR>,\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 [<name>]\n"
- let @h=@h."\" :BookmarkToRoot <name>\n"
- let @h=@h."\" :RevealBookmark <name>\n"
- let @h=@h."\" :OpenBookmark <name>\n"
- let @h=@h."\" :ClearBookmarks [<names>]\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
@@ -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('<args>')
command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.TogglePrimary('<args>')
- 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('<args>')
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
@@ -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.
@@ -1174,6 +1176,44 @@ 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
tree and you want to it to be reflected in the UI.
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 = '</' . join(split(toReturn, '/')[1:], '/') . '/'
+ else
+ let toReturn = '<' . toReturn
+ endif
endif
endif
@@ -652,25 +683,15 @@ endfunction
"Return: the string for this path that is suitable to be used with the :edit
"command
function! s:Path._strForEdit()
- let p = escape(self.str({'format': 'UI'}), self._escChars())
- let cwd = getcwd() . s:Path.Slash()
+ let p = escape(self.str(), self._escChars())
- "return a relative path if we can
- let isRelative = 0
- if nerdtree#runningWindows()
- let isRelative = stridx(tolower(p), tolower(cwd)) == 0
- else
- let isRelative = stridx(p, cwd) == 0
- endif
+ "make it relative
+ let p = fnamemodify(p, ':.')
- if isRelative
- let p = strpart(p, strlen(cwd))
-
- "handle the edge case where the file begins with a + (vim interprets
- "the +foo in `:e +foo` as an option to :edit)
- if p[0] == "+"
- let p = '\' . p
- endif
+ "handle the edge case where the file begins with a + (vim interprets
+ "the +foo in `:e +foo` as an option to :edit)
+ if p[0] == "+"
+ let p = '\' . p
endif
if p ==# ''
diff --git a/lib/nerdtree/tree_dir_node.vim b/lib/nerdtree/tree_dir_node.vim
@@ -246,8 +246,12 @@ function! s:TreeDirNode._initChildren(silent)
"filter out the .. and . directories
"Note: we must match .. AND ../ cos sometimes the globpath returns
"../ for path with strange chars (eg $)
- if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$'
-
+" if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$'
+"
+ " Regular expression is too expensive. Use simply string comparison
+ " instead
+ if i[len(i)-3:2] != ".." && i[len(i)-2:2] != ".." &&
+ \ i[len(i)-2:1] != "." && i[len(i)-1] != "."
"put the next file in a new node and attach it
try
let path = g:NERDTreePath.New(i)
@@ -405,8 +409,12 @@ function! s:TreeDirNode.refresh()
"filter out the .. and . directories
"Note: we must match .. AND ../ cos sometimes the globpath returns
"../ for path with strange chars (eg $)
- if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$'
+ "if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$'
+ " Regular expression is too expensive. Use simply string comparison
+ " instead
+ if i[len(i)-3:2] != ".." && i[len(i)-2:2] != ".." &&
+ \ i[len(i)-2:1] != "." && i[len(i)-1] != "."
try
"create a new path and see if it exists in this nodes children
let path = g:NERDTreePath.New(i)
@@ -504,7 +512,7 @@ endfunction
"directory priority.
"
function! s:TreeDirNode.sortChildren()
- let CompareFunc = function("nerdtree#compareNodes")
+ let CompareFunc = function("nerdtree#compareNodesBySortKey")
call sort(self.children, CompareFunc)
endfunction
diff --git a/lib/nerdtree/tree_file_node.vim b/lib/nerdtree/tree_file_node.vim
@@ -383,13 +383,13 @@ function! s:TreeFileNode._renderToString(depth, drawText, vertMap, isLastChild)
if self.path.isDirectory
if self.isOpen
if g:NERDTreeDirArrows
- let treeParts = treeParts . '▾ '
+ let treeParts = treeParts . g:NERDTreeDirArrowCollapsible . ' '
else
let treeParts = treeParts . '~'
endif
else
if g:NERDTreeDirArrows
- let treeParts = treeParts . '▸ '
+ let treeParts = treeParts . g:NERDTreeDirArrowExpandable . ' '
else
let treeParts = treeParts . '+'
endif
diff --git a/lib/nerdtree/ui.vim b/lib/nerdtree/ui.vim
@@ -3,11 +3,6 @@
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)
@@ -15,13 +10,121 @@ 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
+ let lines_to_bottom = winheight(g:NERDTree.GetWinNum()) - current_line
if lines_to_top < g:NERDTreeAutoCenterThreshold || lines_to_bottom < g:NERDTreeAutoCenterThreshold
normal! zz
endif
endif
endfunction
+"FUNCTION: s:UI._dumpHelp {{{1
+"prints out the quick help
+function! s:UI._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."\" <CR>,\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 [<name>]\n"
+ let @h=@h."\" :BookmarkToRoot <name>\n"
+ let @h=@h."\" :RevealBookmark <name>\n"
+ let @h=@h."\" :OpenBookmark <name>\n"
+ let @h=@h."\" :ClearBookmarks [<names>]\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.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() {{{2
+"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
@@ -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
@@ -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
@@ -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