<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -210,7 +210,6 @@ i.......Open selected file in a split window.....................|NERDTree-i|
 gi......Same as i, but leave the cursor on the NERDTree..........|NERDTree-gi|
 s.......Open selected file in a new vsplit.......................|NERDTree-s|
 gs......Same as s, but leave the cursor on the NERDTree..........|NERDTree-gs|
-!.......Execute the current file.................................|NERDTree-!|
 O.......Recursively open the selected directory..................|NERDTree-O|
 x.......Close the current nodes parent...........................|NERDTree-x|
 X.......Recursively close all children of the current node.......|NERDTree-X|
@@ -338,14 +337,6 @@ The key combo for this mapping is always &quot;g&quot; + NERDTreeMapOpenVSplit (see
 |NERDTree-s|).
 
 ------------------------------------------------------------------------------
-                                                                  *NERDTree-!*
-Default key: !
-Map option: NERDTreeMapExecute
-Applies to: files.
-
-Executes the selected file, prompting for arguments first.
-
-------------------------------------------------------------------------------
                                                                   *NERDTree-O*
 Default key: O
 Map option: NERDTreeMapOpenRecursively
@@ -575,8 +566,12 @@ The NERD tree has a menu that can be programmed via the an API (see
 |NERDTreeMenuAPI|). The idea is to simulate the &quot;right click&quot; menus that most
 file explorers have.
 
-The script comes with one default menu plugin that adds some basic filesystem
-operations to the menu for creating/deleting/moving/copying files and dirs.
+The script comes with two default menu plugins: exec_menuitem.vim and
+fs_menu.vim. fs_menu.vim adds some basic filesystem operations to the menu for
+creating/deleting/moving/copying files and dirs. exec_menuitem.vim provides a
+menu item to execute executable files.
+
+Related tags: |NERDTree-m| |NERDTreeApi|
 
 ==============================================================================
 3. Customisation                                             *NERDTreeOptions*
@@ -924,13 +919,25 @@ This option is used to change the size of the NERD tree when it is loaded.
 ==============================================================================
 4. The NERD tree API                                             *NERDTreeAPI*
 
-The NERD tree script allows you to add custom key mappings and menu items via a
-set of API calls. Any such scripts should be placed in ~/.vim/nerdtree_plugin/
-(*nix) or ~/vimfiles/nerdtree_plugin (windows).
+The NERD tree script allows you to add custom key mappings and menu items via
+a set of API calls. Any scripts that use this API should be placed in
+~/.vim/nerdtree_plugin/ (*nix) or ~/vimfiles/nerdtree_plugin (windows).
 
-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.
+The script exposes some prototype objects that can be used to manipulate the
+tree and/or get information from it: &gt;
+    g:NERDTreePath
+    g:NERDTreeDirNode
+    g:NERDTreeFileNode
+    g:NERDTreeBookmark
+&lt;
+See the code/comments in NERD_tree.vim to find how to use these objects. The
+following code conventions are used:
+    * class members start with a capital letter
+    * instance members start with a lower case letter
+    * private members start with an underscore
+
+See this blog post for more details:
+ http://got-ravings.blogspot.com/2008/09/vim-pr0n-prototype-based-objects.html
 
 ------------------------------------------------------------------------------
 4.1. Key map API                                           *NERDTreeKeymapAPI*
@@ -938,7 +945,7 @@ NERDTreeRender()                                            *NERDTreeRender()*
 NERDTreeAddKeyMap({options})                             *NERDTreeAddKeyMap()*
     Adds a new keymapping for all NERD tree buffers.
     {options} must be a dictionary, and must contain the following keys:
-    &quot;key&quot; - the shortcut key for the new mapping
+    &quot;key&quot; - the trigger key for the new mapping
     &quot;callback&quot; - the function the new mapping will be bound to
     &quot;quickhelpText&quot; - the text that will appear in the quickhelp (see
     |NERDTree-?|)
@@ -952,7 +959,7 @@ NERDTreeAddKeyMap({options})                             *NERDTreeAddKeyMap()*
         function! NERDTreeEchoCurrentNode()
             let n = g:NERDTreeFileNode.GetSelected()
             if n != {}
-                echomsg 'Current node: ' . n.path.str(0)
+                echomsg 'Current node: ' . n.path.str()
             endif
         endfunction
 &lt;
@@ -994,7 +1001,7 @@ NERDTreeAddMenuItem({options})                         *NERDTreeAddMenuItem()*
     &quot;isActiveCallback&quot; - a function that will be called to determine whether
     this menu item will be displayed or not. The callback function must return
     0 or 1.
-    &quot;parent&quot; - if a menu item belongs under a submenu then a parent key must be
+    &quot;parent&quot; - if the menu item belongs under a submenu then this key must be
     specified. This value for this key will be the object that
     was returned when the submenu was created with |NERDTreeAddSubmenu()|.
 
@@ -1042,6 +1049,11 @@ Where selecting &quot;a (s)ub menu&quot; will lead to a second menu: &gt;
 When any of the 3 concrete menu items are selected the function &quot;SomeFunction&quot;
 will be called.
 
+------------------------------------------------------------------------------
+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.
+
 ==============================================================================
 5. About                                                       *NERDTreeAbout*
 
@@ -1063,13 +1075,20 @@ The latest dev versions are on github
 ==============================================================================
 6. Changelog                                               *NERDTreeChangelog*
 
-Next release:
+4.0.0
+    - add a new programmable menu system (see :help NERDTreeMenu).
+    - add new APIs to add menus/menu-items to the menu system as well as
+      custom key mappings to the NERD tree buffer (see :help NERDTreeAPI).
+    - removed the old API functions
+    - added a mapping to maximize/restore the size of nerd tree window, thanks
+      to Guillaume Duranceau for the patch. See :help NERDTree-A for details.
+
     - fix a bug where secondary nerd trees (netrw hijacked trees) and
       NERDTreeQuitOnOpen didnt play nicely, thanks to Curtis Harvey.
     - fix a bug where the script ignored directories whose name ended in a dot,
       thanks to Aggelos Orfanakos for the patch.
-    - added a mapping to maximize/restore the size of nerd tree window, thanks
-      to Guillaume Duranceau for the patch. See :help NERDTree-A for details.
+    - fix a bug when using the x mapping on the tree root, thanks to Bryan
+      Venteicher for the patch.
 
 3.1.1
     - fix a bug where a non-listed no-name buffer was getting created every</diff>
      <filename>doc/NERD_tree.txt</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,7 @@
 &quot; File:        exec_menuitem.vim
 &quot; Description: plugin for NERD Tree that provides an execute file menu item
 &quot; Maintainer:  Martin Grenfell &lt;martin_grenfell at msn dot com&gt;
-&quot; Last Change: 22 July, 2009
+&quot; Last Change: 6 Sep, 2009
 &quot; License:     This program is free software. It comes without any warranty,
 &quot;              to the extent permitted by applicable law. You can redistribute
 &quot;              it and/or modify it under the terms of the Do What The Fuck You
@@ -30,7 +30,7 @@ function! NERDTreeExecFile()
     let treenode = g:NERDTreeFileNode.GetSelected()
     echo &quot;==========================================================\n&quot;
     echo &quot;Complete the command to execute (add arguments etc):\n&quot;
-    let cmd = treenode.path.strForOS(1)
+    let cmd = treenode.path.str({'escape': 1})
     let cmd = input(':!', cmd . ' ')
 
     if cmd != ''</diff>
      <filename>nerdtree_plugin/exec_menuitem.vim</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,7 @@
 &quot; File:        fs_menu.vim
 &quot; Description: plugin for the NERD Tree that provides a file system menu
 &quot; Maintainer:  Martin Grenfell &lt;martin_grenfell at msn dot com&gt;
-&quot; Last Change: 17 July, 2009
+&quot; Last Change: 6 Sep, 2009
 &quot; License:     This program is free software. It comes without any warranty,
 &quot;              to the extent permitted by applicable law. You can redistribute
 &quot;              it and/or modify it under the terms of the Do What The Fuck You
@@ -57,7 +57,7 @@ function! NERDTreeAddNode()
     let newNodeName = input(&quot;Add a childnode\n&quot;.
                           \ &quot;==========================================================\n&quot;.
                           \ &quot;Enter the dir/file name to be created. Dirs end with a '/'\n&quot; .
-                          \ &quot;&quot;, curDirNode.path.strForGlob() . g:NERDTreePath.Slash())
+                          \ &quot;&quot;, curDirNode.path.str({'format': 'Glob'}) . g:NERDTreePath.Slash())
 
     if newNodeName ==# ''
         call s:echo(&quot;Node Creation Aborted.&quot;)
@@ -85,7 +85,7 @@ function! NERDTreeMoveNode()
     let newNodePath = input(&quot;Rename the current node\n&quot; .
                           \ &quot;==========================================================\n&quot; .
                           \ &quot;Enter the new path for the node:                          \n&quot; .
-                          \ &quot;&quot;, curNode.path.strForOS(0))
+                          \ &quot;&quot;, curNode.path.str()
 
     if newNodePath ==# ''
         call s:echo(&quot;Node Renaming Aborted.&quot;)
@@ -93,7 +93,7 @@ function! NERDTreeMoveNode()
     endif
 
     try
-        let bufnum = bufnr(curNode.path.str(0))
+        let bufnum = bufnr(curNode.path.str())
 
         call curNode.rename(newNodePath)
         call NERDTreeRender()
@@ -122,13 +122,13 @@ function! NERDTreeDeleteNode()
         let choice =input(&quot;Delete the current node\n&quot; .
                          \ &quot;==========================================================\n&quot; .
                          \ &quot;STOP! To delete this entire directory, type 'yes'\n&quot; .
-                         \ &quot;&quot; . currentNode.path.strForOS(0) . &quot;: &quot;)
+                         \ &quot;&quot; . currentNode.path.str() . &quot;: &quot;)
         let confirmed = choice ==# 'yes'
     else
         echo &quot;Delete the current node\n&quot; .
            \ &quot;==========================================================\n&quot;.
            \ &quot;Are you sure you wish to delete the node:\n&quot; .
-           \ &quot;&quot; . currentNode.path.strForOS(0) . &quot; (yN):&quot;
+           \ &quot;&quot; . currentNode.path.str() . &quot; (yN):&quot;
         let choice = nr2char(getchar())
         let confirmed = choice ==# 'y'
     endif
@@ -141,7 +141,7 @@ function! NERDTreeDeleteNode()
 
             &quot;if the node is open in a buffer, ask the user if they want to
             &quot;close that buffer
-            let bufnum = bufnr(currentNode.path.str(0))
+            let bufnum = bufnr(currentNode.path.str())
             if buflisted(bufnum)
                 let prompt = &quot;\nNode deleted.\n\nThe file is open in buffer &quot;. bufnum . (bufwinnr(bufnum) ==# -1 ? &quot; (hidden)&quot; : &quot;&quot;) .&quot;. Delete this buffer? (yN)&quot;
                 call s:promptToDelBuffer(bufnum, prompt)
@@ -163,7 +163,7 @@ function! NERDTreeCopyNode()
     let newNodePath = input(&quot;Copy the current node\n&quot; .
                           \ &quot;==========================================================\n&quot; .
                           \ &quot;Enter the new path to copy the node to:                   \n&quot; .
-                          \ &quot;&quot;, currentNode.path.str(0))
+                          \ &quot;&quot;, currentNode.path.str())
 
     if newNodePath != &quot;&quot;
         &quot;strip trailing slash</diff>
      <filename>nerdtree_plugin/fs_menu.vim</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,5 @@
 &quot; ============================================================================
-&quot; File:        nerdtree_git_menu.vim
+&quot; File:        git_menu.vim
 &quot; Description: plugin for the NERD Tree that provides a git menu
 &quot; Maintainer:  Martin Grenfell &lt;martin_grenfell at msn dot com&gt;
 &quot; Last Change: 20 July, 2009
@@ -60,17 +60,17 @@ function! NERDTreeGitMenuEnabled()
 endfunction
 
 function! s:GitRepoPath()
-    return b:NERDTreeRoot.path.str(0) . &quot;.git&quot;
+    return b:NERDTreeRoot.path.str() . &quot;.git&quot;
 endfunction
 
 function! NERDTreeGitMove()
     let node = g:NERDTreeFileNode.GetSelected()
     let path = node.path
-    let p = path.strForOS(1)
+    let p = path.str({'escape': 1})
 
     let newPath = input(&quot;==========================================================\n&quot; .
                           \ &quot;Enter the new path for the file:                          \n&quot; .
-                          \ &quot;&quot;, node.path.strForOS(0))
+                          \ &quot;&quot;, node.path.str())
     if newPath ==# ''
         call s:echo(&quot;git mv aborted.&quot;)
         return
@@ -82,24 +82,24 @@ endfunction
 function! NERDTreeGitAdd()
     let node = g:NERDTreeFileNode.GetSelected()
     let path = node.path
-    call s:execGitCmd('add ' . path.strForOS(1))
+    call s:execGitCmd('add ' . path.str({'escape': 1}))
 endfunction
 
 function! NERDTreeGitRemove()
     let node = g:NERDTreeFileNode.GetSelected()
     let path = node.path
-    call s:execGitCmd('rm ' . path.strForOS(1))
+    call s:execGitCmd('rm ' . path.str({'escape': 1}))
 endfunction
 
 function! NERDTreeGitCheckout()
     let node = g:NERDTreeFileNode.GetSelected()
     let path = node.path
-    call s:execGitCmd('checkout ' . path.strForOS(1))
+    call s:execGitCmd('checkout ' . path.str({'escape': 1}))
 endfunction
 
 function! s:execGitCmd(sub_cmd)
     let extra_options  = '--git-dir=' . s:GitRepoPath() . ' '
-    let extra_options .= '--work-tree=' . b:NERDTreeRoot.path.str(0)
+    let extra_options .= '--work-tree=' . b:NERDTreeRoot.path.str()
     let cmd = &quot;git&quot; . ' ' . extra_options . ' ' . a:sub_cmd
 
     let output = system(cmd)</diff>
      <filename>nerdtree_plugin/git_menu.vim</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,7 @@
 &quot; File:        NERD_tree.vim
 &quot; Description: vim global plugin that provides a nice tree explorer
 &quot; Maintainer:  Martin Grenfell &lt;martin_grenfell at msn dot com&gt;
-&quot; Last Change: 7 Jun, 2009
+&quot; Last Change: 6 Sep, 2009
 &quot; License:     This program is free software. It comes without any warranty,
 &quot;              to the extent permitted by applicable law. You can redistribute
 &quot;              it and/or modify it under the terms of the Do What The Fuck You
@@ -79,7 +79,9 @@ endif
 &quot;once here
 let s:NERDTreeSortStarIndex = index(g:NERDTreeSortOrder, '*')
 
-call s:initVariable(&quot;g:NERDTreeStatusline&quot;, &quot;%{b:NERDTreeRoot.path.strForOS(0)}&quot;)
+if !exists('g:NERDTreeStatusline')
+    let g:NERDTreeStatusline = &quot;%{b:NERDTreeRoot.path.str()}&quot;
+endif
 call s:initVariable(&quot;g:NERDTreeWinPos&quot;, &quot;left&quot;)
 call s:initVariable(&quot;g:NERDTreeWinSize&quot;, 31)
 
@@ -103,7 +105,6 @@ call s:initVariable(&quot;g:NERDTreeMapChdir&quot;, &quot;cd&quot;)
 call s:initVariable(&quot;g:NERDTreeMapCloseChildren&quot;, &quot;X&quot;)
 call s:initVariable(&quot;g:NERDTreeMapCloseDir&quot;, &quot;x&quot;)
 call s:initVariable(&quot;g:NERDTreeMapDeleteBookmark&quot;, &quot;D&quot;)
-call s:initVariable(&quot;g:NERDTreeMapExecute&quot;, &quot;!&quot;)
 call s:initVariable(&quot;g:NERDTreeMapMenu&quot;, &quot;m&quot;)
 call s:initVariable(&quot;g:NERDTreeMapHelp&quot;, &quot;?&quot;)
 call s:initVariable(&quot;g:NERDTreeMapJumpFirstChild&quot;, &quot;K&quot;)
@@ -340,7 +341,7 @@ function! s:Bookmark.mustExist()
     if !self.path.exists()
         call s:Bookmark.CacheBookmarks(1)
         throw &quot;NERDTree.BookmarkPointsToInvalidLocationError: the bookmark \&quot;&quot;.
-            \ self.name .&quot;\&quot; points to a non existing location: \&quot;&quot;. self.path.strForOS(0)
+            \ self.name .&quot;\&quot; points to a non existing location: \&quot;&quot;. self.path.str()
     endif
 endfunction
 &quot; FUNCTION: Bookmark.New(name, path) {{{3
@@ -374,7 +375,7 @@ function! s:Bookmark.str()
         let pathStrMaxLen = pathStrMaxLen - &amp;numberwidth
     endif
 
-    let pathStr = self.path.strForOS(0)
+    let pathStr = self.path.str({'format': 'UI'})
     if len(pathStr) &gt; pathStrMaxLen
         let pathStr = '&lt;' . strpart(pathStr, len(pathStr) - pathStrMaxLen)
     endif
@@ -419,7 +420,7 @@ endfunction
 function! s:Bookmark.Write()
     let bookmarkStrings = []
     for i in s:Bookmark.Bookmarks()
-        call add(bookmarkStrings, i.name . ' ' . i.path.strForOS(0))
+        call add(bookmarkStrings, i.name . ' ' . i.path.str())
     endfor
 
     &quot;add a blank line before the invalid ones
@@ -484,8 +485,8 @@ function! s:MenuController.showMenu()
 
         let done = 0
         while !done
-            call self._redraw()
-            echo self._prompt()
+            redraw!
+            call self._echoPrompt()
             let key = nr2char(getchar())
             let done = self._handleKeypress(key)
         endwhile
@@ -499,24 +500,20 @@ function! s:MenuController.showMenu()
     endif
 endfunction
 
-&quot;FUNCTION: MenuController._prompt() {{{3
-&quot;get the prompt that should be displayed to the user
-function! s:MenuController._prompt()
-    let toReturn = ''
-    let toReturn .= &quot;NERDTree Menu. Use j/k/enter and the shortcuts indicated\n&quot;
-    let toReturn .= &quot;==========================================================\n&quot;
+&quot;FUNCTION: MenuController._echoPrompt() {{{3
+function! s:MenuController._echoPrompt()
+    echo &quot;NERDTree Menu. Use j/k/enter and the shortcuts indicated&quot;
+    echo &quot;==========================================================&quot;
 
     for i in range(0, len(self.menuItems)-1)
         if self.selection == i
-            let toReturn .= &quot;&gt; &quot;
+            echohl todo
+            echo &quot;&gt; &quot; . self.menuItems[i].text
+            echohl normal
         else
-            let toReturn .= &quot;  &quot;
+            echo &quot;  &quot; . self.menuItems[i].text
         endif
-
-        let toReturn .= self.menuItems[i].text . &quot;\n&quot;
     endfor
-
-    return toReturn
 endfunction
 
 &quot;FUNCTION: MenuController._current(key) {{{3
@@ -584,26 +581,10 @@ function! s:MenuController._nextIndexFor(shortcut)
     return -1
 endfunction
 
-&quot;FUNCTION: MenuController._redraw() {{{3
-&quot;wrapper for :redraw[!]. Exists mainly to encapsulate a hack where gtk2 gvim
-&quot;doesnt redraw properly without the !
-function! s:MenuController._redraw()
-    if has(&quot;gui_running&quot;)
-        redraw!
-    else
-        redraw
-    endif
-endfunction
-
 &quot;FUNCTION: MenuController._setCmdheight() {{{3
-&quot;sets &amp;cmdheight to whatever is needed to display the menu. The gtk2 gvim
-&quot;spazzes out if we dont have an extra line
+&quot;sets &amp;cmdheight to whatever is needed to display the menu
 function! s:MenuController._setCmdheight()
-    if has(&quot;gui_running&quot;)
-        let &amp;cmdheight = len(self.menuItems) + 3
-    else
-        let &amp;cmdheight = len(self.menuItems) + 2
-    endif
+    let &amp;cmdheight = len(self.menuItems) + 3
 endfunction
 
 &quot;FUNCTION: MenuController._saveOptions() {{{3
@@ -844,83 +825,17 @@ function! s:TreeFileNode.delete()
     call self.parent.removeChild(self)
 endfunction
 
-&quot;FUNCTION: TreeFileNode.renderToString {{{3
-&quot;returns a string representation for this tree to be rendered in the view
-function! s:TreeFileNode.renderToString()
-    return self._renderToString(0, 0, [], self.getChildCount() ==# 1)
+&quot;FUNCTION: TreeFileNode.displayString() {{{3
+&quot;
+&quot;Returns a string that specifies how the node should be represented as a
+&quot;string
+&quot;
+&quot;Return:
+&quot;a string that can be used in the view to represent this node
+function! s:TreeFileNode.displayString()
+    return self.path.displayString()
 endfunction
 
-
-&quot;Args:
-&quot;depth: the current depth in the tree for this call
-&quot;drawText: 1 if we should actually draw the line for this node (if 0 then the
-&quot;child nodes are rendered only)
-&quot;vertMap: a binary array that indicates whether a vertical bar should be draw
-&quot;for each depth in the tree
-&quot;isLastChild:true if this curNode is the last child of its parent
-function! s:TreeFileNode._renderToString(depth, drawText, vertMap, isLastChild)
-    let output = &quot;&quot;
-    if a:drawText ==# 1
-
-        let treeParts = ''
-
-        &quot;get all the leading spaces and vertical tree parts for this line
-        if a:depth &gt; 1
-            for j in a:vertMap[0:-2]
-                if j ==# 1
-                    let treeParts = treeParts . '| '
-                else
-                    let treeParts = treeParts . '  '
-                endif
-            endfor
-        endif
-
-        &quot;get the last vertical tree part for this line which will be different
-        &quot;if this node is the last child of its parent
-        if a:isLastChild
-            let treeParts = treeParts . '`'
-        else
-            let treeParts = treeParts . '|'
-        endif
-
-
-        &quot;smack the appropriate dir/file symbol on the line before the file/dir
-        &quot;name itself
-        if self.path.isDirectory
-            if self.isOpen
-                let treeParts = treeParts . '~'
-            else
-                let treeParts = treeParts . '+'
-            endif
-        else
-            let treeParts = treeParts . '-'
-        endif
-        let line = treeParts . self.strDisplay()
-
-        let output = output . line . &quot;\n&quot;
-    endif
-
-    &quot;if the node is an open dir, draw its children
-    if self.path.isDirectory ==# 1 &amp;&amp; self.isOpen ==# 1
-
-        let childNodesToDraw = self.getVisibleChildren()
-        if len(childNodesToDraw) &gt; 0
-
-            &quot;draw all the nodes children except the last
-            let lastIndx = len(childNodesToDraw)-1
-            if lastIndx &gt; 0
-                for i in childNodesToDraw[0:lastIndx-1]
-                    let output = output . i._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 1), 0)
-                endfor
-            endif
-
-            &quot;draw the last child, indicating that it IS the last
-            let output = output . childNodesToDraw[lastIndx]._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 0), 1)
-        endif
-    endif
-
-    return output
-endfunction
 &quot;FUNCTION: TreeFileNode.equals(treenode) {{{3
 &quot;
 &quot;Compares this treenode to the input treenode and returns 1 if they are the
@@ -932,7 +847,7 @@ endfunction
 &quot;Args:
 &quot;treenode: the other treenode to compare to
 function! s:TreeFileNode.equals(treenode)
-    return self.path.str(1) ==# a:treenode.path.str(1)
+    return self.path.str() ==# a:treenode.path.str()
 endfunction
 
 &quot;FUNCTION: TreeFileNode.findNode(path) {{{3
@@ -1022,11 +937,11 @@ function! s:TreeFileNode.getLineNum()
     let totalLines = line(&quot;$&quot;)
 
     &quot;the path components we have matched so far
-    let pathcomponents = [substitute(b:NERDTreeRoot.path.str(0), '/ *$', '', '')]
+    let pathcomponents = [substitute(b:NERDTreeRoot.path.str({'format': 'UI'}), '/ *$', '', '')]
     &quot;the index of the component we are searching for
     let curPathComponent = 1
 
-    let fullpath = self.path.str(0)
+    let fullpath = self.path.str({'format': 'UI'})
 
 
     let lnum = s:TreeFileNode.GetRootLineNum()
@@ -1113,7 +1028,7 @@ function! s:TreeFileNode.makeRoot()
 
     &quot;change dir to the dir of the new root if instructed to
     if g:NERDTreeChDirMode ==# 2
-        exec &quot;cd &quot; . b:NERDTreeRoot.path.strForEditCmd()
+        exec &quot;cd &quot; . b:NERDTreeRoot.path.str({'format': 'Edit'})
     endif
 endfunction
 &quot;FUNCTION: TreeFileNode.New(path) {{{3
@@ -1141,12 +1056,12 @@ endfunction
 &quot;treenode: file node to open
 function! s:TreeFileNode.open()
     if b:NERDTreeType ==# &quot;secondary&quot;
-        exec 'edit ' . self.path.strForEditCmd()
+        exec 'edit ' . self.path.str({'format': 'Edit'})
         return
     endif
 
     &quot;if the file is already open in this tab then just stick the cursor in it
-    let winnr = bufwinnr('^' . self.path.strForOS(0) . '$')
+    let winnr = bufwinnr('^' . self.path.str() . '$')
     if winnr != -1
         call s:exec(winnr . &quot;wincmd w&quot;)
 
@@ -1160,10 +1075,10 @@ function! s:TreeFileNode.open()
                 else
                     call s:exec('wincmd p')
                 endif
-                exec (&quot;edit &quot; . self.path.strForEditCmd())
+                exec (&quot;edit &quot; . self.path.str({'format': 'Edit'}))
             catch /^Vim\%((\a\+)\)\=:E37/
                 call s:putCursorInTreeWin()
-                throw &quot;NERDTree.FileAlreadyOpenAndModifiedError: &quot;. self.path.str(0) .&quot; is already open and modified.&quot;
+                throw &quot;NERDTree.FileAlreadyOpenAndModifiedError: &quot;. self.path.str() .&quot; is already open and modified.&quot;
             catch /^Vim\%((\a\+)\)\=:/
                 echo v:exception
             endtry
@@ -1175,7 +1090,7 @@ endfunction
 function! s:TreeFileNode.openSplit()
 
     if b:NERDTreeType ==# &quot;secondary&quot;
-        exec &quot;split &quot; . self.path.strForEditCmd()
+        exec &quot;split &quot; . self.path.str({'format': 'Edit'})
         return
     endif
 
@@ -1216,10 +1131,10 @@ function! s:TreeFileNode.openSplit()
 
     &quot; Open the new window
     try
-        exec(splitMode.&quot; sp &quot; . self.path.strForEditCmd())
+        exec(splitMode.&quot; sp &quot; . self.path.str({'format': 'Edit'}))
     catch /^Vim\%((\a\+)\)\=:E37/
         call s:putCursorInTreeWin()
-        throw &quot;NERDTree.FileAlreadyOpenAndModifiedError: &quot;. self.path.str(0) .&quot; is already open and modified.&quot;
+        throw &quot;NERDTree.FileAlreadyOpenAndModifiedError: &quot;. self.path.str() .&quot; is already open and modified.&quot;
     catch /^Vim\%((\a\+)\)\=:/
         &quot;do nothing
     endtry
@@ -1240,7 +1155,7 @@ endfunction
 &quot;Open this node in a new vertical window
 function! s:TreeFileNode.openVSplit()
     if b:NERDTreeType ==# &quot;secondary&quot;
-        exec &quot;vnew &quot; . self.path.strForEditCmd()
+        exec &quot;vnew &quot; . self.path.str({'format': 'Edit'})
         return
     endif
 
@@ -1250,7 +1165,7 @@ function! s:TreeFileNode.openVSplit()
     endif
 
     call s:exec(&quot;wincmd p&quot;)
-    exec &quot;vnew &quot; . self.path.strForEditCmd()
+    exec &quot;vnew &quot; . self.path.str({'format': 'Edit'})
 
     &quot;resize the nerd tree back to the original size
     call s:putCursorInTreeWin()
@@ -1303,17 +1218,83 @@ function! s:TreeFileNode.rename(newName)
         call newParent.refresh()
     endif
 endfunction
-&quot;FUNCTION: TreeFileNode.strDisplay() {{{3
-&quot;
-&quot;Returns a string that specifies how the node should be represented as a
-&quot;string
-&quot;
-&quot;Return:
-&quot;a string that can be used in the view to represent this node
-function! s:TreeFileNode.strDisplay()
-    return self.path.strDisplay()
+&quot;FUNCTION: TreeFileNode.renderToString {{{3
+&quot;returns a string representation for this tree to be rendered in the view
+function! s:TreeFileNode.renderToString()
+    return self._renderToString(0, 0, [], self.getChildCount() ==# 1)
 endfunction
 
+
+&quot;Args:
+&quot;depth: the current depth in the tree for this call
+&quot;drawText: 1 if we should actually draw the line for this node (if 0 then the
+&quot;child nodes are rendered only)
+&quot;vertMap: a binary array that indicates whether a vertical bar should be draw
+&quot;for each depth in the tree
+&quot;isLastChild:true if this curNode is the last child of its parent
+function! s:TreeFileNode._renderToString(depth, drawText, vertMap, isLastChild)
+    let output = &quot;&quot;
+    if a:drawText ==# 1
+
+        let treeParts = ''
+
+        &quot;get all the leading spaces and vertical tree parts for this line
+        if a:depth &gt; 1
+            for j in a:vertMap[0:-2]
+                if j ==# 1
+                    let treeParts = treeParts . '| '
+                else
+                    let treeParts = treeParts . '  '
+                endif
+            endfor
+        endif
+
+        &quot;get the last vertical tree part for this line which will be different
+        &quot;if this node is the last child of its parent
+        if a:isLastChild
+            let treeParts = treeParts . '`'
+        else
+            let treeParts = treeParts . '|'
+        endif
+
+
+        &quot;smack the appropriate dir/file symbol on the line before the file/dir
+        &quot;name itself
+        if self.path.isDirectory
+            if self.isOpen
+                let treeParts = treeParts . '~'
+            else
+                let treeParts = treeParts . '+'
+            endif
+        else
+            let treeParts = treeParts . '-'
+        endif
+        let line = treeParts . self.displayString()
+
+        let output = output . line . &quot;\n&quot;
+    endif
+
+    &quot;if the node is an open dir, draw its children
+    if self.path.isDirectory ==# 1 &amp;&amp; self.isOpen ==# 1
+
+        let childNodesToDraw = self.getVisibleChildren()
+        if len(childNodesToDraw) &gt; 0
+
+            &quot;draw all the nodes children except the last
+            let lastIndx = len(childNodesToDraw)-1
+            if lastIndx &gt; 0
+                for i in childNodesToDraw[0:lastIndx-1]
+                    let output = output . i._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 1), 0)
+                endfor
+            endif
+
+            &quot;draw the last child, indicating that it IS the last
+            let output = output . childNodesToDraw[lastIndx]._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 0), 1)
+        endif
+    endif
+
+    return output
+endfunction
 &quot;CLASS: TreeDirNode {{{2
 &quot;This class is a child of the TreeFileNode class and constitutes the
 &quot;'Composite' part of the composite design pattern between the treenode
@@ -1394,7 +1375,7 @@ function! s:TreeDirNode.findNode(path)
     if a:path.equals(self.path)
         return self
     endif
-    if stridx(a:path.str(1), self.path.str(1), 0) ==# -1
+    if stridx(a:path.str(), self.path.str(), 0) ==# -1
         return {}
     endif
 
@@ -1423,7 +1404,7 @@ endfunction
 &quot;Args:
 &quot;path: a path object
 function! s:TreeDirNode.getChild(path)
-    if stridx(a:path.str(1), self.path.str(1), 0) ==# -1
+    if stridx(a:path.str(), self.path.str(), 0) ==# -1
         return {}
     endif
 
@@ -1459,7 +1440,7 @@ endfunction
 &quot;Args:
 &quot;path: a path object
 function! s:TreeDirNode.getChildIndex(path)
-    if stridx(a:path.str(1), self.path.str(1), 0) ==# -1
+    if stridx(a:path.str(), self.path.str(), 0) ==# -1
         return -1
     endif
 
@@ -1535,7 +1516,8 @@ function! s:TreeDirNode._initChildren(silent)
 
     &quot;get an array of all the files in the nodes dir
     let dir = self.path
-    let filesStr = globpath(dir.strForGlob(), '*') . &quot;\n&quot; . globpath(dir.strForGlob(), '.*')
+    let globDir = dir.str({'format': 'Glob'})
+    let filesStr = globpath(globDir, '*') . &quot;\n&quot; . globpath(globDir, '.*')
     let files = split(filesStr, &quot;\n&quot;)
 
     if !a:silent &amp;&amp; len(files) &gt; g:NERDTreeNotificationThreshold
@@ -1616,7 +1598,7 @@ function! s:TreeDirNode.openExplorer()
         call s:exec('wincmd p')
         call self.openSplit()
     else
-        exec (&quot;silent edit &quot; . self.path.strForEditCmd())
+        exec (&quot;silent edit &quot; . self.path.str({'format': 'Edit'}))
     endif
 endfunction
 &quot;FUNCTION: TreeDirNode.openRecursively() {{{3
@@ -1662,7 +1644,8 @@ function! s:TreeDirNode.refresh()
         let newChildNodes = []
         let invalidFilesFound = 0
         let dir = self.path
-        let filesStr = globpath(dir.strForGlob(), '*') . &quot;\n&quot; . globpath(dir.strForGlob(), '.*')
+        let globDir = dir.str({'format': 'Glob'})
+        let filesStr = globpath(globDir, '*') . &quot;\n&quot; . globpath(globDir, '.*')
         let files = split(filesStr, &quot;\n&quot;)
         for i in files
             &quot;filter out the .. and . directories
@@ -1914,10 +1897,10 @@ function! s:Path.copy(dest)
 
     let dest = s:Path.WinToUnixPath(a:dest)
 
-    let cmd = g:NERDTreeCopyCmd . &quot; &quot; . self.strForOS(0) . &quot; &quot; . dest
+    let cmd = g:NERDTreeCopyCmd . &quot; &quot; . self.str() . &quot; &quot; . dest
     let success = system(cmd)
     if success != 0
-        throw &quot;NERDTree.CopyError: Could not copy ''&quot;. self.strForOS(0) .&quot;'' to: '&quot; . a:dest . &quot;'&quot;
+        throw &quot;NERDTree.CopyError: Could not copy ''&quot;. self.str() .&quot;'' to: '&quot; . a:dest . &quot;'&quot;
     endif
 endfunction
 
@@ -1958,16 +1941,16 @@ endfunction
 function! s:Path.delete()
     if self.isDirectory
 
-        let cmd = g:NERDTreeRemoveDirCmd . self.strForOS(1)
+        let cmd = g:NERDTreeRemoveDirCmd . self.str('escape': 1})
         let success = system(cmd)
 
         if v:shell_error != 0
-            throw &quot;NERDTree.PathDeletionError: Could not delete directory: '&quot; . self.strForOS(0) . &quot;'&quot;
+            throw &quot;NERDTree.PathDeletionError: Could not delete directory: '&quot; . self.str() . &quot;'&quot;
         endif
     else
-        let success = delete(self.strForOS(0))
+        let success = delete(self.str())
         if success != 0
-            throw &quot;NERDTree.PathDeletionError: Could not delete file: '&quot; . self.str(0) . &quot;'&quot;
+            throw &quot;NERDTree.PathDeletionError: Could not delete file: '&quot; . self.str() . &quot;'&quot;
         endif
     endif
 
@@ -1978,6 +1961,17 @@ function! s:Path.delete()
     endfor
 endfunction
 
+&quot;FUNCTION: Path.displayString() {{{3
+&quot;
+&quot;Returns a string that specifies how the path should be represented as a
+&quot;string
+function! s:Path.displayString()
+    if self.cachedDisplayString ==# &quot;&quot;
+        call self.cacheDisplayString()
+    endif
+
+    return self.cachedDisplayString
+endfunction
 &quot;FUNCTION: Path.extractDriveLetter(fullpath) {{{3
 &quot;
 &quot;If running windows, cache the drive letter for this path
@@ -1992,7 +1986,8 @@ endfunction
 &quot;FUNCTION: Path.exists() {{{3
 &quot;return 1 if this path points to a location that is readable or is a directory
 function! s:Path.exists()
-    return filereadable(self.strForOS(0)) || isdirectory(self.strForOS(0))
+    let p = self.str()
+    return filereadable(p) || isdirectory(p)
 endfunction
 &quot;FUNCTION: Path.getDir() {{{3
 &quot;
@@ -2091,7 +2086,7 @@ endfunction
 &quot;Args:
 &quot;path: the other path obj to compare this with
 function! s:Path.equals(path)
-    return self.str(0) ==# a:path.str(0)
+    return self.str() ==# a:path.str()
 endfunction
 
 &quot;FUNCTION: Path.New() {{{3
@@ -2168,7 +2163,7 @@ endfunction
 
 &quot;FUNCTION: Path.refresh() {{{3
 function! s:Path.refresh()
-    call self.readInfoFromDisk(self.strForOS(0))
+    call self.readInfoFromDisk(self.str())
     call self.cacheDisplayString()
 endfunction
 
@@ -2180,9 +2175,9 @@ function! s:Path.rename(newPath)
         throw &quot;NERDTree.InvalidArgumentsError: Invalid newPath for renaming = &quot;. a:newPath
     endif
 
-    let success =  rename(self.strForOS(0), a:newPath)
+    let success =  rename(self.str(), a:newPath)
     if success != 0
-        throw &quot;NERDTree.PathRenameError: Could not rename: '&quot; . self.strForOS(0) . &quot;'&quot; . 'to:' . a:newPath
+        throw &quot;NERDTree.PathRenameError: Could not rename: '&quot; . self.str() . &quot;'&quot; . 'to:' . a:newPath
     endif
     call self.readInfoFromDisk(a:newPath)
 
@@ -2193,56 +2188,77 @@ function! s:Path.rename(newPath)
     call s:Bookmark.Write()
 endfunction
 
-&quot;FUNCTION: Path.str(esc) {{{3
+&quot;FUNCTION: Path.str() {{{3
 &quot;
-&quot;Gets the actual string path that this obj represents.
+&quot;Returns a string representation of this Path
 &quot;
-&quot;Args:
-&quot;esc: if 1 then all the tricky chars in the returned string will be escaped
-function! s:Path.str(esc)
+&quot;Takes an optional dictionary param to specify how the output should be
+&quot;formatted.
+&quot;
+&quot;The dict may have the following keys:
+&quot;  'format'
+&quot;  'escape'
+&quot;
+&quot;The 'format' key may have a value of:
+&quot;  'Cd' - a string to be used with the :cd command
+&quot;  'Edit' - a string to be used with :e :sp :new :tabedit etc
+&quot;  'UI' - a string used in the NERD tree UI
+&quot;
+&quot;If not specified, a generic unix style path string will be returned
+&quot;
+&quot;The 'escape' key, if specified will cause the output to be escaped with
+&quot;shellescape()
+function! s:Path.str(...)
+    let options = a:0 ? a:1 : {}
+    let toReturn = &quot;&quot;
+
+    if has_key(options, 'format')
+        let format = options['format']
+        if has_key(self, '_strFor' . format)
+            exec 'let toReturn = self._strFor' . format . '()'
+        else
+            raise 'NERDTree.UnknownFormatError: unknown format &quot;'. format .'&quot;'
+        endif
+    else
+        let toReturn = self._str()
+    endif
+
+    if has_key(options, 'escape') &amp;&amp; options['escape']
+        let toReturn = shellescape(toReturn)
+    endif
+
+    return toReturn
+endfunction
+
+&quot;FUNCTION: Path._strForUI() {{{3
+function! s:Path._strForUI()
     let toReturn = '/' . join(self.pathSegments, '/')
     if self.isDirectory &amp;&amp; toReturn != '/'
         let toReturn  = toReturn . '/'
     endif
-
-    if a:esc
-        let toReturn = escape(toReturn, s:escape_chars)
-    endif
     return toReturn
 endfunction
 
-&quot;FUNCTION: Path.strForCd() {{{3
+&quot;FUNCTION: Path._strForCd() {{{3
 &quot;
 &quot; returns a string that can be used with :cd
-function! s:Path.strForCd()
+function! s:Path._strForCd()
     if s:running_windows
-        return self.strForOS(0)
+        return self.str()
     else
-        return self.strForOS(1)
-    endif
-endfunction
-&quot;FUNCTION: Path.strDisplay() {{{3
-&quot;
-&quot;Returns a string that specifies how the path should be represented as a
-&quot;string
-function! s:Path.strDisplay()
-    if self.cachedDisplayString ==# &quot;&quot;
-        call self.cacheDisplayString()
+        return self.str({'escape': 1})
     endif
-
-    return self.cachedDisplayString
 endfunction
-
-&quot;FUNCTION: Path.strForEditCmd() {{{3
+&quot;FUNCTION: Path._strForEdit() {{{3
 &quot;
 &quot;Return: the string for this path that is suitable to be used with the :edit
 &quot;command
-function! s:Path.strForEditCmd()
-    let p = self.str(1)
+function! s:Path._strForEdit()
+    let p = self.str({'format': 'UI'})
     let cwd = getcwd()
 
     if s:running_windows
-        let p = tolower(self.strForOS(0))
+        let p = tolower(self.str())
         let cwd = tolower(getcwd())
     endif
 
@@ -2260,8 +2276,8 @@ function! s:Path.strForEditCmd()
     return p
 
 endfunction
-&quot;FUNCTION: Path.strForGlob() {{{3
-function! s:Path.strForGlob()
+&quot;FUNCTION: Path._strForGlob() {{{3
+function! s:Path._strForGlob()
     let lead = s:Path.Slash()
 
     &quot;if we are running windows then slap a drive letter on the front
@@ -2276,16 +2292,12 @@ function! s:Path.strForGlob()
     endif
     return toReturn
 endfunction
-&quot;FUNCTION: Path.strForOS(esc) {{{3
+&quot;FUNCTION: Path._str() {{{3
 &quot;
 &quot;Gets the string path for this path object that is appropriate for the OS.
 &quot;EG, in windows c:\foo\bar
 &quot;    in *nix  /foo/bar
-&quot;
-&quot;Args:
-&quot;esc: if 1 then all the tricky chars in the returned string will be
-&quot; escaped. If we are running windows then the str is double quoted instead.
-function! s:Path.strForOS(esc)
+function! s:Path._str()
     let lead = s:Path.Slash()
 
     &quot;if we are running windows then slap a drive letter on the front
@@ -2293,16 +2305,7 @@ function! s:Path.strForOS(esc)
         let lead = self.drive . '\'
     endif
 
-    let toReturn = lead . join(self.pathSegments, s:Path.Slash())
-
-    if a:esc
-        if s:running_windows
-            let toReturn = '&quot;' .  toReturn . '&quot;'
-        else
-            let toReturn = escape(toReturn, s:escape_chars)
-        endif
-    endif
-    return toReturn
+    return lead . join(self.pathSegments, s:Path.Slash())
 endfunction
 
 &quot;FUNCTION: Path.strTrunk() {{{3
@@ -2527,7 +2530,7 @@ function! s:initNerdTreeMirror()
     while i &lt; len(treeBufNames)
         let bufName = treeBufNames[i]
         let treeRoot = getbufvar(bufName, &quot;NERDTreeRoot&quot;)
-        let options[i+1 . '. ' . treeRoot.path.strForOS(0) . '  (buf name: ' . bufName . ')'] = bufName
+        let options[i+1 . '. ' . treeRoot.path.str() . '  (buf name: ' . bufName . ')'] = bufName
         let i = i + 1
     endwhile
 
@@ -2751,7 +2754,6 @@ function! s:dumpHelp()
         let @h=@h.&quot;\&quot; &quot;. g:NERDTreeMapPreviewSplit .&quot;: preview split\n&quot;
         let @h=@h.&quot;\&quot; &quot;. g:NERDTreeMapOpenVSplit .&quot;: open vsplit\n&quot;
         let @h=@h.&quot;\&quot; &quot;. g:NERDTreeMapPreviewVSplit .&quot;: preview vsplit\n&quot;
-        let @h=@h.&quot;\&quot; &quot;. g:NERDTreeMapExecute.&quot;: Execute file\n&quot;
 
         let @h=@h.&quot;\&quot;\n\&quot; ----------------------------\n&quot;
         let @h=@h.&quot;\&quot; Directory node mappings~\n&quot;
@@ -3122,7 +3124,7 @@ function! s:renderView()
     call cursor(line(&quot;.&quot;)+1, col(&quot;.&quot;))
 
     &quot;draw the header line
-    call setline(line(&quot;.&quot;)+1, b:NERDTreeRoot.path.str(0))
+    call setline(line(&quot;.&quot;)+1, b:NERDTreeRoot.path.str({'format': 'UI'}))
     call cursor(line(&quot;.&quot;)+1, col(&quot;.&quot;))
 
     &quot;draw the tree
@@ -3395,8 +3397,6 @@ function! s:bindMappings()
     exec &quot;nnoremap &lt;silent&gt; &lt;buffer&gt; &quot;. g:NERDTreeMapOpenVSplit .&quot; :call &lt;SID&gt;openEntrySplit(1,0)&lt;cr&gt;&quot;
     exec &quot;nnoremap &lt;silent&gt; &lt;buffer&gt; &quot;. g:NERDTreeMapPreviewVSplit .&quot; :call &lt;SID&gt;previewNode(2)&lt;cr&gt;&quot;
 
-    exec &quot;nnoremap &lt;silent&gt; &lt;buffer&gt; &quot;. g:NERDTreeMapExecute .&quot; :call &lt;SID&gt;executeNode()&lt;cr&gt;&quot;
-
     exec &quot;nnoremap &lt;silent&gt; &lt;buffer&gt; &quot;. g:NERDTreeMapOpenRecursively .&quot; :call &lt;SID&gt;openNodeRecursively()&lt;cr&gt;&quot;
 
     exec &quot;nnoremap &lt;silent&gt; &lt;buffer&gt; &quot;. g:NERDTreeMapUpdirKeepOpen .&quot; :call &lt;SID&gt;upDir(1)&lt;cr&gt;&quot;
@@ -3559,7 +3559,7 @@ function! s:closeCurrentDir()
     endif
 
     let parent = treenode.parent
-    if parent.isRoot()
+    if parent ==# {} || parent.isRoot()
         call s:echo(&quot;cannot close tree root&quot;)
     else
         call treenode.parent.close()
@@ -3613,26 +3613,6 @@ function! s:displayHelp()
     call s:centerView()
 endfunction
 
-&quot; FUNCTION: s:executeNode() {{{2
-function! s:executeNode()
-    let treenode = s:TreeFileNode.GetSelected()
-    if treenode ==# {} || treenode.path.isDirectory
-        call s:echo(&quot;Select an executable file node first&quot; )
-    else
-        echo &quot;NERDTree executor\n&quot; .
-           \ &quot;==========================================================\n&quot;.
-           \ &quot;Complete the command to execute (add arguments etc): \n\n&quot;
-        let cmd = treenode.path.strForOS(1)
-        let cmd = input(':!', cmd . ' ')
-
-        if cmd != ''
-            exec ':!' . cmd
-        else
-            call s:echo(&quot;command aborted&quot;)
-        endif
-    endif
-endfunction
-
 &quot; FUNCTION: s:handleMiddleMouse() {{{2
 function! s:handleMiddleMouse()
     let curNode = s:TreeFileNode.GetSelected()
@@ -3766,9 +3746,9 @@ function! s:openInNewTab(stayCurrentTab)
     if treenode != {}
         if treenode.path.isDirectory
             tabnew
-            call s:initNerdTree(treenode.path.strForOS(0))
+            call s:initNerdTree(treenode.path.str())
         else
-            exec &quot;tabedit &quot; . treenode.path.strForEditCmd()
+            exec &quot;tabedit &quot; . treenode.path.str({'format': 'Edit'})
         endif
     else
         let bookmark = s:getSelectedBookmark()
@@ -3777,7 +3757,7 @@ function! s:openInNewTab(stayCurrentTab)
                 tabnew
                 call s:initNerdTree(bookmark.name)
             else
-                exec &quot;tabedit &quot; . bookmark.path.strForEditCmd()
+                exec &quot;tabedit &quot; . bookmark.path.str({'format': 'Edit'})
             endif
         endif
     endif
@@ -3919,7 +3899,7 @@ endfunction
 &quot;keepState: 1 if the current root should be left open when the tree is
 &quot;re-rendered
 function! s:upDir(keepState)
-    let cwd = b:NERDTreeRoot.path.str(0)
+    let cwd = b:NERDTreeRoot.path.str({'format': 'UI'})
     if cwd ==# &quot;/&quot; || cwd =~ '^[^/]..$'
         call s:echo(&quot;already at top dir&quot;)
     else</diff>
      <filename>plugin/NERD_tree.vim</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>469d976ed91056821e4e3c66d6b146e0e29437f1</id>
    </parent>
  </parents>
  <author>
    <name>marty</name>
    <email>martin_grenfell@msn.com</email>
  </author>
  <url>http://github.com/akitaonrails/vimfiles/commit/6f525c6ef3e5d5556d45b43145bca082ed409ac7</url>
  <id>6f525c6ef3e5d5556d45b43145bca082ed409ac7</id>
  <committed-date>2009-09-06T02:12:58-07:00</committed-date>
  <authored-date>2009-09-06T02:12:58-07:00</authored-date>
  <message>latest nerd tree hacks</message>
  <tree>08acaa94501fcc2ec1554ab2d9456207234036f4</tree>
  <committer>
    <name>marty</name>
    <email>martin_grenfell@msn.com</email>
  </committer>
</commit>
