forked from el-iot/buffer-tree-explorer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtree.vim
142 lines (100 loc) · 2.84 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
function! GetTree()
let buffer_numbers = map(filter(copy(getbufinfo()), 'v:val.listed'), 'v:val.bufnr')
let tree = {}
for buffer_number in buffer_numbers
let file_path = split(expand("#" . string(buffer_number) . ":p"), g:buffertree_path_sep)
let dir = tree
for step in file_path
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
if g:buffer_tree_explorer_compress == 1
let tree = CompressTree(tree)
endif
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, open_windows)
let items = sort(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, a:open_windows)
else
call GetLinesHelper(value, a:lines, a:offset + 3, a:vlines + [a:offset], last, a:open_windows)
endif
else
if index(a:open_windows, value) != -1
let written_indicator = '◎ '
else
let written_indicator = '• '
endif
if a:fill
call add(a:lines, FillWhitespace(a:offset, a:vlines) . pipe . written_indicator . key . " ⇒ " . value)
else
call add(a:lines, FillWhitespace(a:offset, a:vlines[:-1]) . pipe . written_indicator . key . " ⇒ " . value)
endif
endif
endwhile
endfunction
function! GetLines(tree, open_windows)
let lines = []
call GetLinesHelper(a:tree, lines, 0, [], 1, a:open_windows)
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! GetOpenWindows()
let open_ids = []
for win_id in range(1,winnr('$'))
call add(open_ids, winbufnr(win_id))
endfor
return open_ids
endfunction
function! tree#BufferTree()
let tree = GetTree()
let open_windows = GetOpenWindows()
let lines = GetLines(tree, open_windows)
return lines
endfunction