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:
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