-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathlfm
168 lines (149 loc) · 4.25 KB
/
lfm
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
local unpack = unpack or table.unpack
local focus = "folders"
--fileTable is a flat table, numerically indexed, of all files/folders in the system
local fileTable
--fileTree is a filename-indexed table, wherein each directory is a table of tables, and each file is a reference to the fileTable entry for that file.
local fileTree
--fileLookup is a path-indexed table, wherein each entry is a reference to the fileTable entry for that path.
local fileLookup = {}
--displayTree is used for collapsed/expanded states of folders
local displayTree
--the currently selected folder, used for file view on the right pane.
local currentFolder = "/"
local folderListState = {
totalHeight = 1,
cursor = 1,
offset = 1,
}
local function navigateToFolder(path)
if path == "" or path == "/" then
return fileTree
end
end
local function buildFileList(path, treeEntry)
local list = {}
for k, v in pairs(treeEntry) do
table.insert(list, fs.combine(path, k))
end
return list
end
local function parseFolder(path, fileTable, fileTree)
for _, file in ipairs(fs.list(path)) do
local fullPath = fs.combine(path, file)
local fTable = {name = file, path = fullPath}
if fs.isDir(file) then
fTable.type = "directory"
table.insert(fileTable, fTable)
fileLookup[fullPath] = fTable
_, fileTree[file] = parseFolder(fullPath, fileTable, {})
else
fTable.type = "file"
table.insert(fileTable, fTable)
fileTree[file] = fTable
fileLookup[fullPath] = fTable
end
end
return fileTable, fileTree
end
fileTable, fileTree = parseFolder("/", {}, {})
local function walkFileTree(tree, depth, result)
if not result then result = {} end
for k, v in pairs(tree) do
if not v.type then
table.insert(result, {name = k, depth = depth, collapsed = true})
walkFileTree(v, depth + 1, result)
end
end
return result
end
displayTree = walkFileTree(fileTree, 1)
table.insert(displayTree, 1, {name = "/", depth = 0, collapsed = false})
local function drawFolderList()
local function prepareLines(displayTable, width)
--prepares a displayable set of lines given a displayTree table and a width
local displayedLines = {}
local drawDepth = 0
for i = 1, #displayTable do
if displayTable[i].depth <= drawDepth then
if drawDepth > displayTable[i].depth then drawDepth = displayTable[i].depth end
table.insert(displayedLines, string.rep(" ", displayTable[i].depth)..(displayTable[i].collapsed and "+ " or "- ")..displayTable[i].name)
if not displayTable[i].collapsed then
drawDepth = displayTable[i].depth + 1
end
end
end
return displayedLines
end
local lines = prepareLines(displayTree, 19)
term.clear()
term.setCursorPos(1, 1)
for i = 1, #lines do
print(lines[i])
end
end
local fileSorts = {
alpha = function(fileList)
local dirs, files = {}, {}
for _, file in ipairs(fileList) do
if fs.isDir(file) then
table.insert(dirs, file)
else
table.insert(files, file)
end
end
local function alphaSort(a, b)
return a:lower() < b:lower()
end
table.sort(dirs, alphaSort)
table.sort(files, alphaSort)
for i = 1, #files do
dirs[#dirs + 1] = files[i]
end
return dirs
end,
}
--fileViews must be redirected to contain them.
local fileViews = {
detailed = function(fileList)
local list = fileSorts.alpha(fileList)
term.clear()
local x, y = term.getSize()
for i = 1, math.min(#list, y) do
term.setCursorPos(1, i)
term.write(fs.getName(list[i]))
term.setCursorPos(x - 5, i)
term.write(tostring(fs.getSize(list[i])))
end
end,
}
local x, y = term.getSize()
local color = term.isColor()
local fileView = framebuffer.new(x - 16, y, color, 18, 1)
local oldFileView = framebuffer.new(x - 16, y, color, 18, 1)
local folderView = framebuffer.new(15, y, color)
local oldFolderView = framebuffer.new(15, y, color)
local list = buildFileList("/", navigateToFolder("/"))
term.clear()
for i = 1, y do
term.setCursorPos(16, i)
term.write("|")
end
while true do
local _old = term.redirect(folderView)
drawFolderList()
if _old then
term.redirect(_old)
else
term.restore()
end
local _old = term.redirect(fileView)
fileViews.detailed(list)
if _old then
term.redirect(_old)
else
term.restore()
end
framebuffer.draw(folderView.buffer, oldFolderView.buffer)
framebuffer.draw(fileView.buffer, oldFileView.buffer)
os.pullEvent()
end