Skip to content

Commit

Permalink
Fixes NERDTree open/close folder icon bugs (fixes #194)
Browse files Browse the repository at this point in the history
* fixes : Recursively open the selected directory
* fixes : Close the current nodes parent
* fixes : Recursively close all children of the current node
* fixes possible rendering issues of glyph open/close changing
  • Loading branch information
ryanoasis committed May 7, 2017
1 parent ad957ba commit 343e50e
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 13 deletions.
143 changes: 133 additions & 10 deletions nerdtree_plugin/webdevicons.vim
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,7 @@ function! WebDevIconsNERDTreeUpDirCurrentRootClosedHandler()
redraw!
endfunction

" NERDTreeMapActivateNode and <2-LeftMouse>
" handle the user activating a tree node
" scope: global
function! WebDevIconsNERDTreeMapActivateNode(node)
function! WebDevIconsNERDTreeDirUpdateFlags(node, glyph)
let path = a:node.path
let isOpen = a:node.isOpen
let padding = g:WebDevIconsNerdTreeAfterGlyphPadding
Expand All @@ -112,35 +109,161 @@ function! WebDevIconsNERDTreeMapActivateNode(node)
let prePadding .= ' '
endif

" toggle flag
if isOpen
let flag = prePadding . g:WebDevIconsUnicodeDecorateFolderNodesDefaultSymbol . padding
else
let flag = prePadding . g:DevIconsDefaultFolderOpenSymbol . padding
endif
let flag = prePadding . a:glyph . padding

call a:node.path.flagSet.clearFlags('webdevicons')

if flag !=? ''
call a:node.path.flagSet.addFlag('webdevicons', flag)
call a:node.path.refreshFlags(b:NERDTree)
endif
endfunction

function! WebDevIconsNERDTreeDirClose(node)
let a:node.path.isOpen = 0
let glyph = g:WebDevIconsUnicodeDecorateFolderNodesDefaultSymbol
call WebDevIconsNERDTreeDirUpdateFlags(a:node, glyph)
endfunction

function! WebDevIconsNERDTreeDirOpen(node)
let a:node.path.isOpen = 1
let glyph = g:DevIconsDefaultFolderOpenSymbol
call WebDevIconsNERDTreeDirUpdateFlags(a:node, glyph)
endfunction

function! WebDevIconsNERDTreeDirOpenRecursively(node)
call WebDevIconsNERDTreeDirOpen(a:node)
for i in a:node.children
if i.path.isDirectory ==# 1
call WebDevIconsNERDTreeDirOpenRecursively(i)
endif
endfor
endfunction

function! WebDevIconsNERDTreeDirCloseRecursively(node)
call WebDevIconsNERDTreeDirClose(a:node)
for i in a:node.children
if i.path.isDirectory ==# 1
call WebDevIconsNERDTreeDirCloseRecursively(i)
endif
endfor
endfunction

function! WebDevIconsNERDTreeDirCloseChildren(node)
for i in a:node.children
if i.path.isDirectory ==# 1
call WebDevIconsNERDTreeDirClose(i)
endif
endfor
endfunction

" NERDTreeMapActivateNode and <2-LeftMouse>
" handle the user activating a tree node
" scope: global
function! WebDevIconsNERDTreeMapActivateNode(node)
let isOpen = a:node.isOpen
if isOpen
let glyph = g:WebDevIconsUnicodeDecorateFolderNodesDefaultSymbol
else
let glyph = g:DevIconsDefaultFolderOpenSymbol
endif
let a:node.path.isOpen = !isOpen
call WebDevIconsNERDTreeDirUpdateFlags(a:node, glyph)
" continue with normal activate logic
call a:node.activate()
" glyph change possible artifact clean-up
redraw!
endfunction

function! WebDevIconsNERDTreeMapOpenRecursively(node)
" normal original logic:
call nerdtree#echo("Recursively opening node. Please wait...")
call a:node.openRecursively()
call WebDevIconsNERDTreeDirOpenRecursively(a:node)
" continue with normal original logic:
call b:NERDTree.render()
" glyph change possible artifact clean-up
redraw!
call nerdtree#echo("Recursively opening node. Please wait... DONE")
endfunction

function! WebDevIconsNERDTreeMapCloseChildren(node)
" close children but not current node:
call WebDevIconsNERDTreeDirCloseChildren(a:node)
" continue with normal original logic:
call a:node.closeChildren()
call b:NERDTree.render()
call a:node.putCursorHere(0, 0)
" glyph change possible artifact clean-up
redraw!
endfunction

function! WebDevIconsNERDTreeMapCloseDir(node)
" continue with normal original logic:
let parent = a:node.parent
while g:NERDTreeCascadeOpenSingleChildDir && !parent.isRoot()
let childNodes = parent.getVisibleChildren()
if len(childNodes) == 1 && childNodes[0].path.isDirectory
let parent = parent.parent
else
break
endif
endwhile
if parent ==# {} || parent.isRoot()
call nerdtree#echo("cannot close tree root")
else
call parent.close()
" update the glyph
call WebDevIconsNERDTreeDirClose(parent)
call b:NERDTree.render()
call parent.putCursorHere(0, 0)
" glyph change possible artifact clean-up
redraw!
endif
endfunction

if g:webdevicons_enable == 1 && g:webdevicons_enable_nerdtree == 1
call s:SetupListeners()

if g:DevIconsEnableFoldersOpenClose

" These overrides are needed because we cannot
" simply use AddListener for reliably updating
" the folder open/close glyphs because the event
" path has no access to the 'isOpen' property
" some of these are a little more brittle/fragile
" than others
" TODO FIXME better way to reliably update
" open/close glyphs in NERDTreeWebDevIconsRefreshListener

" NERDTreeMapActivateNode
call NERDTreeAddKeyMap({
\ 'key': g:NERDTreeMapActivateNode,
\ 'callback': 'WebDevIconsNERDTreeMapActivateNode',
\ 'override': 1,
\ 'scope': 'DirNode' })

" NERDTreeMapOpenRecursively
call NERDTreeAddKeyMap({
\ 'key': g:NERDTreeMapOpenRecursively,
\ 'callback': 'WebDevIconsNERDTreeMapOpenRecursively',
\ 'override': 1,
\ 'scope': 'DirNode' })

" NERDTreeMapCloseChildren
call NERDTreeAddKeyMap({
\ 'key': g:NERDTreeMapCloseChildren,
\ 'callback': 'WebDevIconsNERDTreeMapCloseChildren',
\ 'override': 1,
\ 'scope': 'DirNode' })

" NERDTreeMapCloseChildren
call NERDTreeAddKeyMap({
\ 'key': g:NERDTreeMapCloseDir,
\ 'callback': 'WebDevIconsNERDTreeMapCloseDir',
\ 'override': 1,
\ 'scope': 'Node' })

" <2-LeftMouse>
call NERDTreeAddKeyMap({
\ 'key': '<2-LeftMouse>',
Expand Down
6 changes: 3 additions & 3 deletions plugin/webdevicons.vim
Original file line number Diff line number Diff line change
Expand Up @@ -728,12 +728,12 @@ function! NERDTreeWebDevIconsRefreshListener(event)
if !path.isDirectory
let flag = prePadding . WebDevIconsGetFileTypeSymbol(path.str()) . padding
elseif path.isDirectory && g:WebDevIconsUnicodeDecorateFolderNodes == 1

let directoryOpened = 0

if g:DevIconsEnableFoldersOpenClose && len(path.flagSet._flagsForScope('webdevicons')) > 0
" isOpen is not available on the path listener, compare using symbols
if path.flagSet._flagsForScope('webdevicons')[0] == prePadding . g:DevIconsDefaultFolderOpenSymbol . padding
" isOpen is not available on the path listener directly
" but we added one via overriding particular keymappings for NERDTree
if has_key(path, 'isOpen') && path.isOpen == 1
let directoryOpened = 1
endif
endif
Expand Down

0 comments on commit 343e50e

Please sign in to comment.