nerdtree

A tree explorer plugin for vim.
Index Commits Files Refs
commit 91e0f2253fbecefa7e14f095950341584877ef19
parent c372911c4a49c1747061425cb2685ca3f317c743
Author: Phil Runninger <PhilRunninger@users.noreply.github.com>
Date:   Wed, 24 Oct 2018 22:41:13 -0400

Support unusual characters in file and directory names (#868)

* Use a delimiter in node to separate file/dir name from the rest.

* Switch warning message to use nerdtree#deprecated function.

* Compress the space between the tree symbols and the node.

* Include the delimiter when calculating indent or getting filename.

* Don't need to strip leading delimiter. It will already be gone.

* Simplify the way the delimiter is being used.

I don't know what I was thinking. The delimiter doesn't need to be used
to separate every indicator on the node's text, ie.

Bad:    Tree|GenericFlags|Filename|ExecutableFlag|Link|ReadonlyFlag
Better: Tree GenericFlags|Filename|ExecutableFlag Link ReadonlyFlag

This was unnecessary, given that we're only interested in the filename.
So, just one pair of delimiters is all we need. That greatly simplifies
the _stripMarkup function, and restores a bunch of other statements to
what they already are in the master branch.

* Add syntax highlighting to conceal the delimiter

* Put a if has("conceal") check around the syntax statement using it.

* Make concealment work correctly for LinkFile and readonly files.

* Use highlight Ignore if conceal isn't available.

This is probably the best we can do, especially if some other character
must be used in place of nbsp.

* Make the regex better match the original, but more compact.

It was allowing 2+ spaces, instead of only 1+.

* Fix the syntax highlighing of delimiters around NERDTreeExecFile.

* Bug fix: Parse . and .. from path string with trailing slash.

* Fix unresponsive cascaded directories.

Using ':' as a more visible delimiter, when directories are cascaded,
the line appears in NERDTree like so:

▾ :lib/::nerdtree/:

Before this commit, the s:UI._stripMarkup function was leaving the
internal delimiters in place (lib/::nerdtree/). Now they are removed,
resulting in a valid path (lib/nerdtree/).

* Use .= to shorten statement. Use clearer substitutes to get node name.

* Remove node delimiters that terminate the line.

* If flags are needed after the node name, then put another delimiter
before them.
* When joining directory nodes for cascaded display, strip off the
delimiter from the child node(s).
* Remove the unnecessary substitution of doubled intermediate
delimiters, since they're not in there anymore.

* DRY up the addition of the 2nd delimiter, and use only 1 for all tags.

Diffstat:
Mlib/nerdtree/path.vim | 19++++++++++++++-----
Mlib/nerdtree/tree_dir_node.vim | 3++-
Mlib/nerdtree/tree_file_node.vim | 2+-
Mlib/nerdtree/ui.vim | 25++++---------------------
Mplugin/NERD_tree.vim | 3+++
Msyntax/nerdtree.vim | 9+++++++++
6 files changed, 33 insertions(+), 28 deletions(-)
diff --git a/lib/nerdtree/path.vim b/lib/nerdtree/path.vim
@@ -39,10 +39,10 @@ endfunction
 
 " FUNCTION: Path.cacheDisplayString() {{{1
 function! s:Path.cacheDisplayString() abort
-    let self.cachedDisplayString = self.getLastPathComponent(1)
+    let self.cachedDisplayString = g:NERDTreeNodeDelimiter . self.getLastPathComponent(1)
 
     if self.isExecutable
-        let self.cachedDisplayString = self.cachedDisplayString . '*'
+        let self.cachedDisplayString = self.addDelimiter(self.cachedDisplayString) . '*'
     endif
 
     let self._bookmarkNames = []
@@ -52,15 +52,24 @@ function! s:Path.cacheDisplayString() abort
         endif
     endfor
     if !empty(self._bookmarkNames) && g:NERDTreeMarkBookmarks == 1
-        let self.cachedDisplayString .= ' {' . join(self._bookmarkNames) . '}'
+        let self.cachedDisplayString = self.addDelimiter(self.cachedDisplayString) . ' {' . join(self._bookmarkNames) . '}'
     endif
 
     if self.isSymLink
-        let self.cachedDisplayString .=  ' -> ' . self.symLinkDest
+        let self.cachedDisplayString = self.addDelimiter(self.cachedDisplayString) . ' -> ' . self.symLinkDest
     endif
 
     if self.isReadOnly
-        let self.cachedDisplayString .=  ' ['.g:NERDTreeGlyphReadOnly.']'
+        let self.cachedDisplayString = self.addDelimiter(self.cachedDisplayString) . ' ['.g:NERDTreeGlyphReadOnly.']'
+    endif
+endfunction
+
+" FUNCTION: Path.addDelimiter() {{{1
+function! s:Path.addDelimiter(line)
+    if a:line =~# '\(.*' . g:NERDTreeNodeDelimiter . '\)\{2}'
+        return a:line
+    else
+        return a:line . g:NERDTreeNodeDelimiter
     endif
 endfunction
 
diff --git a/lib/nerdtree/tree_dir_node.vim b/lib/nerdtree/tree_dir_node.vim
@@ -99,7 +99,8 @@ function! s:TreeDirNode.displayString()
     let l:label = ''
     let l:cascade = self.getCascade()
     for l:dirNode in l:cascade
-        let l:label .= l:dirNode.path.displayString()
+        let l:next = l:dirNode.path.displayString()
+        let l:label .= l:label == '' ? l:next : strcharpart(l:next,1)
     endfor
 
     " Select the appropriate open/closed status indicator symbol.
diff --git a/lib/nerdtree/tree_file_node.vim b/lib/nerdtree/tree_file_node.vim
@@ -242,7 +242,7 @@ endfunction
 
 " FUNCTION: TreeFileNode.openInNewTab(options) {{{1
 function! s:TreeFileNode.openInNewTab(options)
-    echomsg 'TreeFileNode.openInNewTab is deprecated'
+    call nerdtree#deprecated('TreeFileNode.openinNewTab', 'is deprecated, use .open() instead.')
     call self.open(extend({'where': 't'}, a:options))
 endfunction
 
diff --git a/lib/nerdtree/ui.vim b/lib/nerdtree/ui.vim
@@ -300,7 +300,7 @@ endfunction
 
 " FUNCTION: s:UI.MarkupReg() {{{1
 function! s:UI.MarkupReg()
-    return '^\(['.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.'] \| \+['.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.'] \| \+\)'
+    return '^ *['.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.']\? '
 endfunction
 
 " FUNCTION: s:UI._renderBookmarks {{{1
@@ -363,30 +363,13 @@ function! s:UI.setShowHidden(val)
 endfunction
 
 " FUNCTION: s:UI._stripMarkup(line){{{1
-" returns the given line with all the tree parts stripped off
+" find the filename in the given line, and return it.
 "
 " Args:
 " line: the subject line
 function! s:UI._stripMarkup(line)
-    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, ' \['.g:NERDTreeGlyphReadOnly.'\]', "","")
-
-    " 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 line = substitute (line,' -> .*',"","") " remove link to
-
-    return line
+    let l:line = substitute(a:line, '^.\{-}' . g:NERDTreeNodeDelimiter, '', '')
+    return substitute(l:line, g:NERDTreeNodeDelimiter.'.*$', '', '')
 endfunction
 
 " FUNCTION: s:UI.render() {{{1
diff --git a/plugin/NERD_tree.vim b/plugin/NERD_tree.vim
@@ -86,6 +86,9 @@ let g:NERDTreeOldSortOrder = []
 
 call s:initVariable("g:NERDTreeGlyphReadOnly", "RO")
 
+" ASCII 160: non-breaking space used to delimit items in the tree's nodes.
+call s:initVariable("g:NERDTreeNodeDelimiter", "\u00a0")
+
 if !exists('g:NERDTreeStatusline')
 
     "the exists() crap here is a hack to stop vim spazzing out when
diff --git a/syntax/nerdtree.vim b/syntax/nerdtree.vim
@@ -36,6 +36,15 @@ exec 'syn match NERDTreeRO # *\zs.*\ze \['.g:NERDTreeGlyphReadOnly.'\]# contains
 syn match NERDTreeFlags #^ *\zs\[.\]# containedin=NERDTreeFile,NERDTreeExecFile
 syn match NERDTreeFlags #\[.\]# containedin=NERDTreeDir
 
+"highlighing to conceal the delimiter around the file/dir name
+if has("conceal")
+    exec 'syn match NERDTreeNodeDelimiters #' . g:NERDTreeNodeDelimiter . '# conceal containedin=NERDTreeFile,NERDTreeLinkFile,NERDTreeExecFile,NERDTreeRO,NERDTreeDir'
+    setlocal conceallevel=2 concealcursor=nvic
+else
+    exec 'syn match NERDTreeNodeDelimiters #' . g:NERDTreeNodeDelimiter . '# containedin=NERDTreeFile,NERDTreeLinkFile,NERDTreeExecFile,NERDTreeRO,NERDTreeDir'
+    hi! link NERDTreeNodeDelimiters Ignore
+endif
+
 syn match NERDTreeCWD #^[</].*$#
 
 "highlighting for bookmarks