Last active
August 29, 2015 14:06
-
-
Save kamichidu/2025d57b72db02ed52a8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let s:V= vital#of('vital') | |
let s:S= s:V.import('Data.String') | |
let s:L= s:V.import('Data.List') | |
unlet s:V | |
" | |
" Public API | |
" --- | |
" | |
let s:style= {} | |
function! s:style.head_joint(context, parent, node) | |
if !empty(a:parent) | |
return '|' | |
else | |
return '' | |
endif | |
endfunction | |
function! s:style.edge(context, parent, node) | |
return '|' | |
endfunction | |
function! s:style.indicator(context, parent, node) | |
if a:node.is_leaf() | |
return ' ' | |
endif | |
if a:node.state() == 'open' | |
return '-' | |
elseif a:node.state() == 'close' | |
return '+' | |
else | |
return ' ' | |
endif | |
endfunction | |
function! s:style.tail_joint(context, parent, node) | |
return "\n" | |
if empty(a:node.children()) | |
return "\n" | |
else | |
return '' | |
endif | |
endfunction | |
" | |
" Public API | |
" --- | |
" new() | |
" tree.root() : A node object | |
" tree.root({node}) | |
" tree.stringify() : List of string | |
" | |
let s:tree= { | |
\ '__root': {}, | |
\ '__shiftwidth': shiftwidth(), | |
\ '__style': deepcopy(s:style), | |
\} | |
function! s:tree.root(...) | |
if a:0 == 0 | |
return deepcopy(self.__root) | |
else | |
let self.__root= deepcopy(a:1) | |
endif | |
endfunction | |
function! s:tree.shiftwidth(...) | |
if a:0 == 0 | |
return self.__shiftwidth | |
else | |
let self.__shiftwidth= a:1 | |
endif | |
endfunction | |
function! s:tree.style(...) | |
if a:0 == 0 | |
return deepcopy(self.__style) | |
else | |
let self.__style= deepcopy(a:1) | |
endif | |
endfunction | |
function! s:tree.stringify() | |
let context= {} | |
let context.edge_stack= [] | |
let context.style= self.__style | |
let context.shiftwidth= self.__shiftwidth | |
let context.level= 0 | |
return split(join(s:_stringify(context, {}, self.__root), ''), "\n") | |
endfunction | |
function! s:_stringify(context, parent, node) | |
let style= (!empty(a:node.style())) ? a:node.style() : a:context.style | |
let buffer= [] | |
" | |
" {edge}* {head joint} {indicator} {node text} {tail joint} | |
" | |
let buffer= [] | |
for edge in a:context.edge_stack | |
let buffer+= [s:_pad_right(edge, a:context.shiftwidth)] | |
endfor | |
let head_joint= style.head_joint(a:context, a:parent, a:node) | |
let indicator= style.indicator(a:context, a:parent, a:node) | |
let node_text= a:node.text() | |
let tail_joint= style.tail_joint(a:context, a:parent, a:node) | |
let buffer+= [head_joint, indicator, node_text, tail_joint] | |
if a:node.state() == 'open' | |
call s:L.push(a:context.edge_stack, style.edge(a:context, a:parent, a:node)) | |
let a:context.level+= 1 | |
for child in a:node.children() | |
let buffer+= s:_stringify(a:context, a:node, child) | |
endfor | |
let a:context.level-= 1 | |
endif | |
return buffer | |
endfunction | |
function! s:_pad_right(str, width) | |
let str= a:str | |
while strdisplaywidth(str) < a:width | |
let str.= ' ' | |
endwhile | |
return str | |
endfunction | |
" | |
" Public API | |
" --- | |
" new() | |
" node.text() : String | |
" node.text({text}) | |
" node.state() : String | |
" node.state({state}) | |
" node.open() | |
" node.close() | |
" node.indicator() : String | |
" node.children() : List of node objects | |
" | |
let s:node= { | |
\ 'data': {}, | |
\ '__children': [], | |
\ '__text': '', | |
\ '__state': 'close', | |
\ '__style': {}, | |
\} | |
function! s:node.text(...) | |
if a:0 == 0 | |
return self.__text | |
else | |
let self.__text= a:1 | |
endif | |
endfunction | |
function! s:node.state(...) | |
if a:0 == 0 | |
return self.__state | |
else | |
let self.__state= a:1 | |
endif | |
endfunction | |
function! s:node.open(...) | |
call self.state('open') | |
let recursive= get(a:000, 0, 0) | |
if recursive | |
for child in self.children() | |
call child.open(recursive) | |
endfor | |
endif | |
endfunction | |
function! s:node.close(...) | |
call self.state('close') | |
let recursive= get(a:000, 0, 0) | |
if recursive | |
for child in self.children() | |
call child.close(recursive) | |
endfor | |
endif | |
endfunction | |
function! s:node.is_leaf() | |
return empty(self.children()) | |
endfunction | |
function! s:node.children(...) | |
if a:0 == 0 | |
return deepcopy(self.__children) | |
else | |
let self.__children= deepcopy(a:1) | |
endif | |
endfunction | |
function! s:node.style(...) | |
if a:0 == 0 | |
return deepcopy(self.__style) | |
else | |
let self.__style= a:1 | |
endif | |
endfunction | |
" | |
" test | |
" | |
function! s:_children() dict | |
if has_key(self.data, 'children') | |
return self.data.children | |
endif | |
let children= [] | |
for dir in self.data.directories | |
let child= deepcopy(s:node) | |
call child.text(fnamemodify(dir, ':s|/$||:t:s|$|/|')) | |
let child.data= { | |
\ 'files': filter(split(globpath(dir, '*'), "\n"), '!isdirectory(v:val)'), | |
\ 'directories': filter(split(globpath(dir, '*'), "\n"), 'isdirectory(v:val)'), | |
\} | |
let child.children= function('s:_children') | |
let children+= [child] | |
endfor | |
for file in self.data.files | |
let child= deepcopy(s:node) | |
call child.text(fnamemodify(file, ':t')) | |
let child.data= { | |
\ 'files': [], | |
\ 'directories': [], | |
\} | |
let child.children= function('s:_children') | |
let children+= [child] | |
endfor | |
let self.data.children= children | |
return children | |
endfunction | |
function! s:_() | |
let tree= deepcopy(s:tree) | |
let root= deepcopy(s:node) | |
call root.text('') | |
let root.data= {'files': [], 'directories': [expand('~/sources/vim-plugin/vim-benchmark/')]} | |
let root.children= function('s:_children') | |
call root.open() | |
call root.children()[0].open() | |
call root.children()[0].children()[1].open() | |
call tree.root(root) | |
call tree.shiftwidth(4) | |
call tree.style(deepcopy(s:style)) | |
for line in tree.stringify() | |
echo line | |
endfor | |
endfunction | |
call s:_() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi! Does this draw text trees? Can you provide an example? :D