-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathfilesystem.lib.lua
More file actions
224 lines (193 loc) · 5.05 KB
/
filesystem.lib.lua
File metadata and controls
224 lines (193 loc) · 5.05 KB
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
-----------------------------------------------------------------------------
-- Midcraft Commander
-- Author: MewK
--
-- This program is released under the MIT License (MIT).
-----------------------------------------------------------------------------
local w, h = term.getSize()
local hw = math.floor(w / 2)
function buildPath(entry, name)
if entry and entry.fullpath then
return '/' .. fs.combine(entry.fullpath, name or '')
end
return '/' .. fs.combine(entry or '', name or '')
end
function createEntry(_path, _name, _type, _action, _meta, _info)
return {
['path'] = _path,
['name'] = _name,
['fullpath'] = buildPath(_path, _name),
['type'] = _type,
['action'] = _action,
['meta'] = _meta,
['info'] = _info
}
end
function getPath(_path)
for match in string.gmatch(_path, '(.+)/.*') do
return match
end
return '/'
end
function createEntryFromPath(_path, _type)
_path = buildPath(_path)
if _path == '/' then
return createEntry('/', '/', 0)
else
local _parent = buildPath(getPath(_path))
local _name = buildPath(fs.getName(_path))
return createEntry(_parent, _name, 0)
end
end
function compareEntries(entry1, entry2)
return entry1.fullpath < entry2.fullpath
end
function deleteEntry(entry)
if entry and not fs.isReadOnly(entry.fullpath) and not (entry.meta and entry.meta.side) then
fs.delete(entry.fullpath)
return true
end
return false
end
function formatFolder(folder)
if fs.isDir(folder.fullpath) then
for index, entry in ipairs(fs.list(folder.fullpath)) do
deleteEntry(createEntry(folder, entry))
end
end
end
function moveEntry(entry, destination, copyMode, forceOverwrite)
-- Input validation
if not entry or not entry.fullpath or not fs.exists(entry.fullpath) or not destination then
return 0
end
-- File equals
if entry.fullpath == destination then
return -1
end
-- File exists
if fs.exists(destination) then
local overwrite
if forceOverwrite then
overwrite = 'y'
else
term.setCursorPos(1, h)
term.clearLine()
overwrite = read('File exists. Overwrite? (y/n): ', nil)
end
if overwrite == 'y' then
fs.delete(destination)
if copyMode then
fs.copy(entry.fullpath, destination)
else
fs.move(entry.fullpath, destination)
end
return 2
else
return -2
end
else
if copyMode then
fs.copy(entry.fullpath, destination)
else
fs.move(entry.fullpath, destination)
end
return 1
end
end
function listEntries(folder, virtualEntries, folderTypes)
-- Sort into dirs/files
local dirs = {}
local files = {}
-- Get files and folders
if folder.fullpath ~= '/' then
table.insert(dirs, createEntry(folder.fullpath, '..', 0)) -- 0 = folder
end
if fs.exists(folder.fullpath) then
local fileType = 1 -- 1 = program
-- Overwrite type if necessary
if folderTypes then
for _path, _type in pairs(folderTypes) do
if folder.fullpath == _path and (_type == 1 or _type == 2 or _type == 4) then
fileType = _type
break
end
end
end
for index, entry in ipairs(fs.list(folder.fullpath)) do
if fs.isDir(buildPath(folder, entry)) then
local _side = nil
for index, __side in ipairs(redstone.getSides()) do
if disk.isPresent(__side) and disk.hasData(__side) and buildPath(disk.getMountPath(__side)) == buildPath(folder, entry) then
_side = __side
break
end
end
-- External folder
if _side then
table.insert(dirs, createEntry(folder.fullpath, entry, 0, nil, { side = _side })) -- 0 = folder
-- Internal folder
else
table.insert(dirs, createEntry(folder.fullpath, entry, 0)) -- 0 = folder
end
else
table.insert(files, createEntry(folder.fullpath, entry, fileType))
end
end
end
-- Handle virtual entries
if virtualEntries then
for index, entry in ipairs(virtualEntries) do
-- virtual folder
if entry.path == folder.fullpath then
table.insert(dirs, entry) -- 0 = folder
-- virtual entry
elseif entry.fullpath == folder.fullpath and entry.action then
for index, _entry in ipairs(entry.action(entry)) do
if _entry.type == 0 then
table.insert(dirs, _entry) -- 0 = folder
else
table.insert(files, _entry)
end
end
end
end
end
-- Sort tables
table.sort(dirs, compareEntries)
table.sort(files, compareEntries)
for index, file in ipairs(files) do
table.insert(dirs, file)
end
return dirs
end
function runProgram(path, ...)
path = buildPath(shell.resolveProgram(path))
if path ~= nil then
term.clear()
term.setCursorPos(1, 1)
if false then
shell.run('shell', path, ...)
else
shell.run(path, ...)
-- Wait for user action if text is on screen
local cx,cy = term.getCursorPos()
if cx ~= 1 or cy ~= 1 then
local text = 'Press any key to continue'
term.setCursorPos(hw - math.floor(string.len(text) / 2), h)
term.clearLine()
term.write(text)
os.pullEvent('key')
end
end
end
end
function parseCommand(command)
local words = {}
for match in string.gmatch(command, "[^ \t]+") do
table.insert(words, match)
end
if words[1] then
runProgram(words[1], unpack(words, 2))
end
end