mirror of
https://github.com/CCLeonOS/LeonOS.git
synced 2026-03-03 15:17:01 +00:00
feat: 初始提交 LeonOS 实现
添加 LeonOS 的基本实现,包括: - 核心 API 模块(colors, disk, gps, keys, multishell, parallel, rednet, redstone, settings, vector) - 命令行程序(about, alias, bg, clear, copy, delete, edit, fg, help, list, lua, mkdir, move, paint, peripherals, programs, reboot, set, shutdown, threads) - 系统启动脚本和包管理 - 文档(README.md, LICENSE) - 开发工具(devbin)和更新程序 实现功能: - 完整的线程管理系统 - 兼容 ComputerCraft 的 API 设计 - 改进的 shell 和命令补全系统 - 多标签终端支持 - 设置管理系统
This commit is contained in:
201
data/computercraft/lua/rom/startup/00_fs.lua
Normal file
201
data/computercraft/lua/rom/startup/00_fs.lua
Normal file
@@ -0,0 +1,201 @@
|
||||
-- override the fs library to use this resolution function where necessary
|
||||
-- almost identical to the override used in .OS
|
||||
|
||||
local fs = rawget(_G, "fs")
|
||||
|
||||
-- split a file path into segments
|
||||
function fs.split(path)
|
||||
local s = {}
|
||||
for S in path:gmatch("[^/\\]+") do
|
||||
if S == ".." then
|
||||
s[#s] = nil
|
||||
elseif S ~= "." then
|
||||
s[#s+1] = S
|
||||
end
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
-- package isn't loaded yet, so unfortunately this is necessary
|
||||
local function expect(...)
|
||||
return require and require("cc.expect").expect(...)
|
||||
end
|
||||
|
||||
-- path resolution:
|
||||
-- if the path begins with /rc, then redirect to wherever that actually
|
||||
-- is; otherwise, resolve the path based on the current program's working
|
||||
-- directory
|
||||
-- this is to allow .OS to run from anywhere
|
||||
local function resolve(path)
|
||||
local thread = package and package.loaded.thread
|
||||
|
||||
local root = (thread and thread.getroot()) or "/"
|
||||
local pwd = (thread and thread.dir()) or "/"
|
||||
|
||||
if path:sub(1,1) ~= "/" then
|
||||
path = fs.combine(pwd, path)
|
||||
end
|
||||
path = fs.combine(root, path)
|
||||
|
||||
local segments = fs.split(path)
|
||||
if segments[1] == "rc" then
|
||||
return fs.combine(_RC_ROM_DIR, table.concat(segments, "/", 2, #segments))
|
||||
else
|
||||
return path
|
||||
end
|
||||
end
|
||||
|
||||
-- override: fs.combine
|
||||
local combine = fs.combine
|
||||
function fs.combine(...)
|
||||
return "/" .. combine(...)
|
||||
end
|
||||
|
||||
-- override: fs.getDir
|
||||
local getDir = fs.getDir
|
||||
function fs.getDir(p)
|
||||
return "/" .. getDir(p)
|
||||
end
|
||||
|
||||
-- override: fs.exists
|
||||
local exists = fs.exists
|
||||
function fs.exists(path)
|
||||
expect(1, path, "string")
|
||||
return exists(resolve(path))
|
||||
end
|
||||
|
||||
-- override: fs.list
|
||||
local list = fs.list
|
||||
function fs.list(path)
|
||||
expect(1, path, "string")
|
||||
path = resolve(path)
|
||||
local _, files = pcall(list, path)
|
||||
if not _ then return nil, files end
|
||||
if path == "/" then
|
||||
-- inject /rc into the root listing
|
||||
if not exists("/rc") then
|
||||
files[#files+1] = "rc"
|
||||
end
|
||||
end
|
||||
return files
|
||||
end
|
||||
|
||||
-- override: fs.getSize
|
||||
local getSize = fs.getSize
|
||||
function fs.getSize(path)
|
||||
expect(1, path, "string")
|
||||
return getSize((resolve(path)))
|
||||
end
|
||||
|
||||
-- override: fs.isDir
|
||||
local isDir = fs.isDir
|
||||
function fs.isDir(path)
|
||||
expect(1, path, "string")
|
||||
return isDir(resolve(path))
|
||||
end
|
||||
|
||||
-- override: fs.makeDir
|
||||
local makeDir = fs.makeDir
|
||||
function fs.makeDir(path)
|
||||
expect(1, path, "string")
|
||||
return makeDir(resolve(path))
|
||||
end
|
||||
|
||||
-- override: fs.move
|
||||
local move = fs.move
|
||||
function fs.move(a, b)
|
||||
expect(1, a, "string")
|
||||
expect(2, b, "string")
|
||||
return move(resolve(a), resolve(b))
|
||||
end
|
||||
|
||||
-- override: fs.copy
|
||||
local copy = fs.copy
|
||||
function fs.copy(a, b)
|
||||
expect(1, a, "string")
|
||||
expect(2, b, "string")
|
||||
return copy(resolve(a), resolve(b))
|
||||
end
|
||||
|
||||
-- override: fs.delete
|
||||
local delete = fs.delete
|
||||
function fs.delete(path)
|
||||
expect(1, path, "string")
|
||||
return delete(resolve(path))
|
||||
end
|
||||
|
||||
-- override: fs.open
|
||||
local open = fs.open
|
||||
function fs.open(file, mode)
|
||||
expect(1, file, "string")
|
||||
expect(2, mode, "string")
|
||||
return open(resolve(file), mode or "r")
|
||||
end
|
||||
|
||||
-- override: fs.find
|
||||
local find = fs.find
|
||||
function fs.find(path)
|
||||
expect(1, path, "string")
|
||||
return find(resolve(path))
|
||||
end
|
||||
|
||||
-- override: fs.attributes
|
||||
local attributes = fs.attributes
|
||||
function fs.attributes(path)
|
||||
expect(1, path, "string")
|
||||
return attributes(resolve(path))
|
||||
end
|
||||
|
||||
-- new: fs.complete
|
||||
function fs.complete(path, location, include_files, include_dirs)
|
||||
expect(1, path, "string")
|
||||
expect(2, location, "string")
|
||||
expect(3, include_files, "boolean", "nil")
|
||||
expect(4, include_dirs, "boolean", "nil")
|
||||
|
||||
if include_files == nil then include_files = true end
|
||||
if include_dirs == nil then include_dirs = true end
|
||||
|
||||
if path:sub(1,1) == "/" and path:sub(-1) ~= "/" then
|
||||
location = fs.getDir(path)
|
||||
elseif path:sub(-1) == "/" then
|
||||
location = path
|
||||
else
|
||||
location = fs.combine(location, fs.getDir(path))
|
||||
end
|
||||
|
||||
local completions = {}
|
||||
|
||||
if not fs.exists(location) or not fs.isDir(location) then
|
||||
return completions
|
||||
end
|
||||
|
||||
local name = fs.getName(path)
|
||||
if path:sub(-1) == "/" then name = "" end
|
||||
local files = fs.list(location)
|
||||
|
||||
for i=1, #files, 1 do
|
||||
local file = files[i]
|
||||
local full = fs.combine(location, file)
|
||||
if file:sub(1, #name) == name then
|
||||
local dir = fs.isDir(full)
|
||||
if (dir and include_dirs) or include_files then
|
||||
completions[#completions+1] = file:sub(#name+1)
|
||||
if #completions[#completions] == 0 then
|
||||
completions[#completions] = nil
|
||||
end
|
||||
end
|
||||
if dir then
|
||||
completions[#completions+1] = file:sub(#name+1) .. "/"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return completions
|
||||
end
|
||||
|
||||
function fs.isDriveRoot(path)
|
||||
expect(1, path, "string")
|
||||
if #path == 0 then path = "/" end
|
||||
return path == "/" or fs.getDrive(path) == fs.getDrive(fs.getDir(path))
|
||||
end
|
||||
Reference in New Issue
Block a user