@@ -139,7 +139,11 @@ call s:initVariable("g:NERDTreeMapUpdir", "u")
139139call s: initVariable (" g:NERDTreeMapUpdirKeepOpen" , " U" )
140140
141141" SECTION: Script level variable declaration{{{2
142- let s: escape_chars = " \\ `\| \" #%&,?()\* ^<>"
142+ if s: running_windows
143+ let s: escape_chars = " `\| \" #%&,?()\* ^<>"
144+ else
145+ let s: escape_chars = " \\ `\| \" #%&,?()\* ^<>"
146+ endif
143147let s: NERDTreeBufName = ' NERD_tree_'
144148
145149let s: tree_wid = 2
@@ -157,6 +161,7 @@ command! -n=? -complete=dir -bar NERDTreeToggle :call s:toggle('<args>')
157161command ! -n =0 - bar NERDTreeClose :call s: closeTreeIfOpen ()
158162command ! -n =1 -complete =customlist ,s: completeBookmarks - bar NERDTreeFromBookmark call s: initNerdTree (' <args>' )
159163command ! -n =0 - bar NERDTreeMirror call s: initNerdTreeMirror ()
164+ command ! -n =0 - bar NERDTreeFind call s: findAndRevealPath ()
160165" SECTION: Auto commands {{{1
161166" ============================================================
162167augroup NERDTree
@@ -332,6 +337,21 @@ function! s:Bookmark.GetNodeForName(name, searchFromAbsoluteRoot)
332337 let bookmark = s: Bookmark .BookmarkFor (a: name )
333338 return bookmark.getNode (a: searchFromAbsoluteRoot )
334339endfunction
340+ " FUNCTION: Bookmark.GetSelected() {{{3
341+ " returns the Bookmark the cursor is over, or {}
342+ function ! s: Bookmark .GetSelected ()
343+ let line = getline (" ." )
344+ let name = substitute (line , ' ^>\(.\{-}\) .\+$' , ' \1' , ' ' )
345+ if name != line
346+ try
347+ return s: Bookmark .BookmarkFor (name)
348+ catch /^NERDTree.BookmarkNotFoundError/
349+ return {}
350+ endtry
351+ endif
352+ return {}
353+ endfunction
354+
335355" Function: Bookmark.InvalidBookmarks() {{{3
336356" Class method to get all invalid bookmark strings read from the bookmarks
337357" file
@@ -361,6 +381,21 @@ function! s:Bookmark.New(name, path)
361381 let newBookmark.path = a: path
362382 return newBookmark
363383endfunction
384+ " FUNCTION: Bookmark.openInNewTab(options) {{{3
385+ " Create a new bookmark object with the given name and path object
386+ function ! s: Bookmark .openInNewTab (options )
387+ let currentTab = tabpagenr ()
388+ if self .path .isDirectory
389+ tabnew
390+ call s: initNerdTree (self .name)
391+ else
392+ exec " tabedit " . bookmark.path .str ({' format' : ' Edit' })
393+ endif
394+
395+ if has_key (a: options , ' stayInCurrentTab' )
396+ exec " tabnext " . currentTab
397+ endif
398+ endfunction
364399" Function: Bookmark.setPath(path) {{{3
365400" makes this bookmark point to the given path
366401function ! s: Bookmark .setPath (path )
@@ -981,11 +1016,19 @@ function! s:TreeFileNode.getLineNum()
9811016 return -1
9821017endfunction
9831018
1019+ " FUNCTION: TreeFileNode.GetRootForTab(){{{3
1020+ " get the root node for this tab
1021+ function ! s: TreeFileNode .GetRootForTab ()
1022+ if s: treeExistsForTab ()
1023+ return getbufvar (t :NERDTreeBufName, ' NERDTreeRoot' )
1024+ end
1025+ return {}
1026+ endfunction
9841027" FUNCTION: TreeFileNode.GetRootLineNum(){{{3
9851028" gets the line number of the root node
9861029function ! s: TreeFileNode .GetRootLineNum ()
9871030 let rootLine = 1
988- while getline (rootLine) !~ ' ^/ '
1031+ while getline (rootLine) !~ ' ^\(/\|<\) '
9891032 let rootLine = rootLine + 1
9901033 endwhile
9911034 return rootLine
@@ -1177,6 +1220,21 @@ function! s:TreeFileNode.openVSplit()
11771220 exec (" silent vertical resize " . winwidth )
11781221 call s: exec (' wincmd p' )
11791222endfunction
1223+ " FUNCTION: TreeFileNode.openInNewTab(options) {{{3
1224+ function ! s: TreeFileNode .openInNewTab (options )
1225+ let currentTab = tabpagenr ()
1226+
1227+ if ! has_key (a: options , ' keepTreeOpen' )
1228+ call s: closeTreeIfQuitOnOpen ()
1229+ endif
1230+
1231+ exec " tabedit " . self .path .str ({' format' : ' Edit' })
1232+
1233+ if has_key (a: options , ' stayInCurrentTab' ) && a: options [' stayInCurrentTab' ]
1234+ exec " tabnext " . currentTab
1235+ endif
1236+
1237+ endfunction
11801238" FUNCTION: TreeFileNode.putCursorHere(isJump, recurseUpward){{{3
11811239" Places the cursor on the line number this node is rendered on
11821240"
@@ -1606,6 +1664,22 @@ function! s:TreeDirNode.openExplorer()
16061664 exec (" silent edit " . self .path .str ({' format' : ' Edit' }))
16071665 endif
16081666endfunction
1667+ " FUNCTION: TreeDirNode.openInNewTab(options) {{{3
1668+ unlet s: TreeDirNode .openInNewTab
1669+ function ! s: TreeDirNode .openInNewTab (options )
1670+ let currentTab = tabpagenr ()
1671+
1672+ if ! has_key (a: options , ' keepTreeOpen' ) || ! a: options [' keepTreeOpen' ]
1673+ call s: closeTreeIfQuitOnOpen ()
1674+ endif
1675+
1676+ tabnew
1677+ call s: initNerdTree (self .path .str ())
1678+
1679+ if has_key (a: options , ' stayInCurrentTab' ) && a: options [' stayInCurrentTab' ]
1680+ exec " tabnext " . currentTab
1681+ endif
1682+ endfunction
16091683" FUNCTION: TreeDirNode.openRecursively() {{{3
16101684" Opens this treenode and all of its children whose paths arent 'ignored'
16111685" because of the file filters.
@@ -1690,6 +1764,31 @@ function! s:TreeDirNode.refresh()
16901764 endif
16911765endfunction
16921766
1767+ " FUNCTION: TreeDirNode.reveal(path) {{{3
1768+ " reveal the given path, i.e. cache and open all treenodes needed to display it
1769+ " in the UI
1770+ function ! s: TreeDirNode .reveal (path )
1771+ if ! a: path .isUnder (self .path )
1772+ throw " NERDTree.InvalidArgumentsError: " . a: path .str () . " should be under " . self .path .str ()
1773+ endif
1774+
1775+ call self .open ()
1776+
1777+ if self .path .equals (a: path .getParent ())
1778+ let n = self .findNode (a: path )
1779+ call s: renderView ()
1780+ call n .putCursorHere (1 ,0 )
1781+ return
1782+ endif
1783+
1784+ let p = a: path
1785+ while ! p .getParent ().equals (self .path )
1786+ let p = p .getParent ()
1787+ endwhile
1788+
1789+ let n = self .findNode (p )
1790+ call n .reveal (a: path )
1791+ endfunction
16931792" FUNCTION: TreeDirNode.removeChild(treenode) {{{3
16941793"
16951794" Removes the given treenode from this nodes set of children
@@ -2079,6 +2178,20 @@ function! s:Path.ignore()
20792178 return 0
20802179endfunction
20812180
2181+ " FUNCTION: Path.isUnder(path) {{{3
2182+ " return 1 if this path is somewhere under the given path in the filesystem.
2183+ "
2184+ " a:path should be a dir
2185+ function ! s: Path .isUnder (path )
2186+ if a: path .isDirectory == 0
2187+ return 0
2188+ endif
2189+
2190+ let this = self .str ()
2191+ let that = a: path .str ()
2192+ return stridx (this, that . s: Path .Slash ()) == 0
2193+ endfunction
2194+
20822195" FUNCTION: Path.JoinPathStrings(...) {{{3
20832196function ! s: Path .JoinPathStrings (... )
20842197 let components = []
@@ -2208,16 +2321,18 @@ endfunction
22082321" The dict may have the following keys:
22092322" 'format'
22102323" 'escape'
2324+ " 'truncateTo'
22112325"
22122326" The 'format' key may have a value of:
22132327" 'Cd' - a string to be used with the :cd command
22142328" 'Edit' - a string to be used with :e :sp :new :tabedit etc
22152329" 'UI' - a string used in the NERD tree UI
22162330"
2217- " If not specified, a generic unix style path string will be returned
2218- "
22192331" The 'escape' key, if specified will cause the output to be escaped with
22202332" shellescape()
2333+ "
2334+ " The 'truncateTo' key causes the resulting string to be truncated to the value
2335+ " 'truncateTo' maps to. A '<' char will be prepended.
22212336function ! s: Path .str (... )
22222337 let options = a: 0 ? a: 1 : {}
22232338 let toReturn = " "
@@ -2237,6 +2352,13 @@ function! s:Path.str(...)
22372352 let toReturn = shellescape (toReturn)
22382353 endif
22392354
2355+ if has_key (options , ' truncateTo' )
2356+ let limit = options [' truncateTo' ]
2357+ if len (toReturn) > limit
2358+ let toReturn = " <" . strpart (toReturn, len (toReturn) - limit + 1 )
2359+ endif
2360+ endif
2361+
22402362 return toReturn
22412363endfunction
22422364
@@ -2396,6 +2518,29 @@ function! s:exec(cmd)
23962518 exec a: cmd
23972519 let &ei = old_ei
23982520endfunction
2521+ " FUNCTION: s:findAndRevealPath() {{{2
2522+ function ! s: findAndRevealPath ()
2523+ try
2524+ let p = s: Path .New (expand (" %" ))
2525+ catch /^NERDTree.InvalidArgumentsError/
2526+ call s: echo (" no file for the current buffer" )
2527+ return
2528+ endtry
2529+
2530+ if ! s: treeExistsForTab ()
2531+ call s: initNerdTree (p .getParent ().str ())
2532+ else
2533+ if ! p .isUnder (s: TreeFileNode .GetRootForTab ().path )
2534+ call s: initNerdTree (p .getParent ().str ())
2535+ else
2536+ if ! s: isTreeOpen ()
2537+ call s: toggle (" " )
2538+ endif
2539+ endif
2540+ endif
2541+ call s: putCursorInTreeWin ()
2542+ call b: NERDTreeRoot .reveal (p )
2543+ endfunction
23992544" FUNCTION: s:initNerdTree(name) {{{2
24002545" Initialise the nerd tree for this tab. The tree will start in either the
24012546" given directory, or the directory associated with the given bookmark
@@ -2898,8 +3043,10 @@ endfunction
28983043function ! s: getPath (ln )
28993044 let line = getline (a: ln )
29003045
3046+ let rootLine = s: TreeFileNode .GetRootLineNum ()
3047+
29013048 " check to see if we have the root node
2902- if line = ~ ' ^\/ '
3049+ if a: ln == rootLine
29033050 return b: NERDTreeRoot .path
29043051 endif
29053052
@@ -2923,7 +3070,6 @@ function! s:getPath(ln)
29233070 let curFile = substitute (curFile, ' /\?$' , ' /' , " " )
29243071 endif
29253072
2926-
29273073 let dir = " "
29283074 let lnum = a: ln
29293075 while lnum > 0
@@ -2932,8 +3078,8 @@ function! s:getPath(ln)
29323078 let curLineStripped = s: stripMarkupFromLine (curLine, 1 )
29333079
29343080 " have we reached the top of the tree?
2935- if curLine = ~ ' ^/ '
2936- let dir = substitute (curLine, ' *$ ' , " " , " " ) . dir
3081+ if lnum == rootLine
3082+ let dir = b: NERDTreeRoot . path . str ({ ' format ' : ' UI ' } ) . dir
29373083 break
29383084 endif
29393085 if curLineStripped = ~ ' /$'
@@ -2951,21 +3097,6 @@ function! s:getPath(ln)
29513097 return toReturn
29523098endfunction
29533099
2954- " FUNCTION: s:getSelectedBookmark() {{{2
2955- " returns the bookmark the cursor is over in the bookmarks table or {}
2956- function ! s: getSelectedBookmark ()
2957- let line = getline (" ." )
2958- let name = substitute (line , ' ^>\(.\{-}\) .\+$' , ' \1' , ' ' )
2959- if name != line
2960- try
2961- return s: Bookmark .BookmarkFor (name)
2962- catch /^NERDTree.BookmarkNotFoundError/
2963- return {}
2964- endtry
2965- endif
2966- return {}
2967- endfunction
2968-
29693100" FUNCTION: s:getTreeWinNum() {{{2
29703101" gets the nerd tree window number for this tab
29713102function ! s: getTreeWinNum ()
@@ -3132,7 +3263,8 @@ function! s:renderView()
31323263 call cursor (line (" ." )+ 1 , col (" ." ))
31333264
31343265 " draw the header line
3135- call setline (line (" ." )+ 1 , b: NERDTreeRoot .path .str ({' format' : ' UI' }))
3266+ let header = b: NERDTreeRoot .path .str ({' format' : ' UI' , ' truncateTo' : winwidth (0 )})
3267+ call setline (line (" ." )+ 1 , header)
31363268 call cursor (line (" ." )+ 1 , col (" ." ))
31373269
31383270 " draw the tree
@@ -3381,7 +3513,7 @@ function! s:activateNode(forceKeepWindowOpen)
33813513 if treenode != {}
33823514 call treenode.activate (a: forceKeepWindowOpen )
33833515 else
3384- let bookmark = s: getSelectedBookmark ()
3516+ let bookmark = s: Bookmark . GetSelected ()
33853517 if ! empty (bookmark)
33863518 call bookmark.activate ()
33873519 endif
@@ -3591,7 +3723,7 @@ endfunction
35913723" FUNCTION: s:deleteBookmark() {{{2
35923724" if the cursor is on a bookmark, prompt to delete
35933725function ! s: deleteBookmark ()
3594- let bookmark = s: getSelectedBookmark ()
3726+ let bookmark = s: Bookmark . GetSelected ()
35953727 if bookmark == # {}
35963728 call s: echo (" Put the cursor on a bookmark" )
35973729 return
@@ -3748,29 +3880,13 @@ endfunction
37483880" stayCurrentTab: if 1 then vim will stay in the current tab, if 0 then vim
37493881" will go to the tab where the new file is opened
37503882function ! s: openInNewTab (stayCurrentTab)
3751- let currentTab = tabpagenr ()
3752-
3753- let treenode = s: TreeFileNode .GetSelected ()
3754- if treenode != {}
3755- if treenode.path .isDirectory
3756- tabnew
3757- call s: initNerdTree (treenode.path .str ())
3758- else
3759- exec " tabedit " . treenode.path .str ({' format' : ' Edit' })
3760- endif
3761- else
3762- let bookmark = s: getSelectedBookmark ()
3763- if bookmark != {}
3764- if bookmark.path .isDirectory
3765- tabnew
3766- call s: initNerdTree (bookmark.name)
3767- else
3768- exec " tabedit " . bookmark.path .str ({' format' : ' Edit' })
3769- endif
3770- endif
3883+ let target = s: TreeFileNode .GetSelected ()
3884+ if target == {}
3885+ let target = s: Bookmark .GetSelected ()
37713886 endif
3772- if a: stayCurrentTab
3773- exec " tabnext " . currentTab
3887+
3888+ if target != {}
3889+ call target.openInNewTab ({' stayInCurrentTab' : a: stayCurrentTab })
37743890 endif
37753891endfunction
37763892
0 commit comments