-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtree.vim
148 lines (100 loc) · 2.74 KB
/
tree.vim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
let s:hidden_sep = "|||"
echohl None
function! GetTree(buffer_numbers)
let tree = {}
for buffer_number in a:buffer_numbers
let file_path = split(expand("#" . string(buffer_number) . ":p"), g:buffertree_path_sep)
let dir = tree
for step in file_path
" check if this is the end
if len(file_path) == 1
let dir[step] = buffer_number
else
if !has_key(dir, step)
let dir[step] = {}
endif
let dir = dir[step]
endif
let file_path = file_path[1:]
endfor
endfor
return tree
endfunction
function! FillWhitespace(n, lines)
let space = ""
for i in range(a:n)
if index(a:lines, i) == -1
let space = space . " "
else
let space = space . "│"
endif
endfor
return space
endfunction
function! GetLinesHelper(tree, lines, offset, vlines, fill)
let items = items(a:tree)
while len(items) > 0
" pop
let [key, value] = items[0]
let items = items[1:]
if len(items) > 0
let last = 0
let pipe = "├─ "
else
let pipe = "└─ "
let last = 1
endif
if type(value) is v:t_dict
call add(a:lines, FillWhitespace(a:offset, a:vlines) . pipe . key)
if last == 1
call GetLinesHelper(value, a:lines, a:offset + 3, a:vlines, last)
else
call GetLinesHelper(value, a:lines, a:offset + 3, a:vlines + [a:offset], last)
endif
else
if a:fill
call add(a:lines, FillWhitespace(a:offset, a:vlines) . pipe . s:hidden_sep . key . g:buffertree_arrow . value)
else
call add(a:lines, FillWhitespace(a:offset, a:vlines[:-1]) . pipe . s:hidden_sep . key . g:buffertree_arrow . value)
endif
endif
endwhile
endfunction
function! GetLines(tree)
let lines = []
call GetLinesHelper(a:tree, lines, 0, [], 1)
return lines
endfunction
function! CompressTree(tree)
let sep = "/"
if type(a:tree) is v:t_dict
for [k1, v1] in items(a:tree)
let a:tree[k1] = CompressTree(v1)
if type(v1) is v:t_dict && len(items(v1)) == 1
let [k2, v2] = items(v1)[0]
let a:tree[k1 . sep . k2] = v2
call remove(a:tree, k1)
endif
endfor
endif
return a:tree
endfunction
function! tree#BufferTree()
let buffer_numbers = map(filter(copy(getbufinfo()), 'v:val.listed'), 'v:val.bufnr')
let tree = GetTree(buffer_numbers)
if g:buffertree_compress == 1
let tree = CompressTree(tree)
endif
let lines = GetLines(tree)
for line in lines
if stridx(line, s:hidden_sep) != -1
let sections = split(line, s:hidden_sep)
echo sections[0]
echohl BufferTreeFile
echon sections[1]
echohl None
else
echo line
endif
endfor
endfunction