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:
391
data/computercraft/lua/rom/apis/textutils.lua
Normal file
391
data/computercraft/lua/rom/apis/textutils.lua
Normal file
@@ -0,0 +1,391 @@
|
||||
-- rc.textutils
|
||||
|
||||
local rc = require("rc")
|
||||
local term = require("term")
|
||||
local json = require("rc.json")
|
||||
local colors = require("colors")
|
||||
local expect = require("cc.expect").expect
|
||||
local strings = require("cc.strings")
|
||||
|
||||
local tu = {}
|
||||
|
||||
function tu.slowWrite(text, rate)
|
||||
expect(1, text, "string")
|
||||
expect(2, rate, "number", "nil")
|
||||
|
||||
local delay = 1/(rate or 20)
|
||||
for c in text:gmatch(".") do
|
||||
rc.write(c)
|
||||
rc.sleep(delay)
|
||||
end
|
||||
end
|
||||
|
||||
function tu.slowPrint(text, rate)
|
||||
expect(1, text, "string")
|
||||
expect(2, rate, "number", "nil")
|
||||
tu.slowWrite(text.."\n", rate)
|
||||
end
|
||||
|
||||
function tu.formatTime(time, _24h)
|
||||
expect(1, time, "number")
|
||||
expect(2, _24h, "boolean", "nil")
|
||||
|
||||
local fmt = _24h and "!%H:%M" or "!%I:%M %p"
|
||||
|
||||
return (os.date(fmt, time * 3600):gsub("^ ", ""))
|
||||
end
|
||||
|
||||
local function pagedWrite(text, begin)
|
||||
local w, h = term.getSize()
|
||||
local x, y = term.getCursorPos()
|
||||
|
||||
local realTotal = 0
|
||||
local lines = begin or 0
|
||||
|
||||
local elements = strings.splitElements(text, w)
|
||||
|
||||
strings.wrappedWriteElements(elements, w, false, {
|
||||
newline = function()
|
||||
rc.write("\n")
|
||||
realTotal = realTotal + 1
|
||||
lines = lines + 1
|
||||
x, y = term.getCursorPos()
|
||||
|
||||
if lines >= h - 2 then
|
||||
local old = term.getTextColor()
|
||||
term.setTextColor(colors.white)
|
||||
rc.write("Press any key to continue")
|
||||
term.setTextColor(old)
|
||||
rc.pullEvent("char")
|
||||
local _, _y = term.getCursorPos()
|
||||
term.at(1, _y).clearLine()
|
||||
lines = 0
|
||||
end
|
||||
end,
|
||||
|
||||
append = function(newText)
|
||||
term.at(x, y).write(newText)
|
||||
x = x + #newText
|
||||
end,
|
||||
|
||||
getX = function() return x end
|
||||
})
|
||||
|
||||
return realTotal, lines
|
||||
end
|
||||
|
||||
function tu.pagedPrint(text)
|
||||
expect(1, text, "string")
|
||||
return pagedWrite(text .. "\n")
|
||||
end
|
||||
|
||||
local function coloredWrite(paged, ...)
|
||||
local args = table.pack(...)
|
||||
local lines = 0
|
||||
local pageLines = 0
|
||||
|
||||
local write = paged and pagedWrite or rc.write
|
||||
local old_fg, old_bg = term.getTextColor(), term.getBackgroundColor()
|
||||
local _, h = term.getSize()
|
||||
|
||||
for i=1, args.n, 1 do
|
||||
if type(args[i]) == "number" then
|
||||
term.setTextColor(args[i])
|
||||
elseif type(args[i]) == "table" then
|
||||
if args[i].fg or args[i][1] then
|
||||
term.setTextColor(args[i].fg or args[i][1])
|
||||
end
|
||||
|
||||
if args[i].bg or args[i][2] then
|
||||
term.setBackgroundColor(args[i].bg or args[i][2])
|
||||
end
|
||||
else
|
||||
local _lines, _tot = write(args[i], pageLines)
|
||||
lines = lines + _lines
|
||||
pageLines = _tot or 0
|
||||
while pageLines > h do pageLines = pageLines - h end
|
||||
end
|
||||
end
|
||||
|
||||
term.setTextColor(old_fg)
|
||||
term.setBackgroundColor(old_bg)
|
||||
|
||||
return lines
|
||||
end
|
||||
|
||||
local function tabulate(paged, ...)
|
||||
local args = table.pack(...)
|
||||
|
||||
local w = term.getSize()
|
||||
local max_len = 0
|
||||
|
||||
local linear = {}
|
||||
|
||||
for i=1, args.n, 1 do
|
||||
local argi = args[i]
|
||||
expect(i, argi, "table", "number")
|
||||
|
||||
if type(argi) == "table" then
|
||||
for n=1, #argi, 1 do
|
||||
if type(argi[n]) == "table" then
|
||||
local total_len = 2
|
||||
local argin = argi[n]
|
||||
|
||||
for j=1, #argin, 1 do
|
||||
expect(j, argin[j], "string", "number")
|
||||
if type(argin[j]) == "string" then
|
||||
total_len = total_len + #argin[j]
|
||||
end
|
||||
end
|
||||
|
||||
argin.total_len = total_len
|
||||
max_len = math.max(max_len, total_len + 2)
|
||||
|
||||
linear[#linear+1] = argi[n]
|
||||
|
||||
else
|
||||
linear[#linear+1] = expect(n, argi[n], "string")
|
||||
max_len = math.max(max_len, #argi[n] + 2)
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
linear[#linear+1] = args[i]
|
||||
end
|
||||
end
|
||||
|
||||
local written = 0
|
||||
|
||||
local prt = paged and function(_args)
|
||||
if type(_args) == "string" then _args = {_args} end
|
||||
return coloredWrite(true, table.unpack(_args))
|
||||
end or function(_args)
|
||||
if type(_args) == "string" then _args = {_args} end
|
||||
return coloredWrite(false, table.unpack(_args))
|
||||
end
|
||||
|
||||
for i=1, #linear, 1 do
|
||||
local lini = linear[i]
|
||||
|
||||
if type(lini) == "number" then
|
||||
if written > 0 then
|
||||
prt("\n")
|
||||
written = 0
|
||||
end
|
||||
|
||||
term.setTextColor(lini)
|
||||
|
||||
else
|
||||
local len = type(lini) == "table" and lini.total_len or #lini
|
||||
if written + max_len > w then
|
||||
if written + len > w then
|
||||
prt("\n")
|
||||
prt(lini)
|
||||
rc.write((" "):rep(max_len - len))
|
||||
written = max_len
|
||||
|
||||
else
|
||||
prt(lini)
|
||||
prt("\n")
|
||||
written = 0
|
||||
end
|
||||
|
||||
else
|
||||
prt(lini)
|
||||
rc.write((" "):rep(max_len - len))
|
||||
written = written + max_len
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if written > 0 then
|
||||
prt("\n")
|
||||
end
|
||||
end
|
||||
|
||||
function tu.tabulate(...)
|
||||
tabulate(false, ...)
|
||||
end
|
||||
|
||||
function tu.pagedTabulate(...)
|
||||
tabulate(true, ...)
|
||||
end
|
||||
|
||||
local function mk_immut(str, field)
|
||||
return setmetatable({}, {
|
||||
__newindex = function()
|
||||
error(string.format("attempt to modify textutils.%s", field), 2)
|
||||
end,
|
||||
__tostring = function()
|
||||
return str
|
||||
end})
|
||||
end
|
||||
|
||||
tu.empty_json_array = mk_immut("[]", "empty_json_array")
|
||||
tu.json_null = mk_immut("null", "json_null")
|
||||
|
||||
local function serialize(t, _seen)
|
||||
local ret = ""
|
||||
|
||||
if type(t) == "table" then
|
||||
local seen = setmetatable({}, {__index = _seen})
|
||||
|
||||
ret = "{"
|
||||
for k, v in pairs(t) do
|
||||
if seen[k] then
|
||||
k = "<recursion>"
|
||||
end
|
||||
if seen[v] then
|
||||
v = "<recursion>"
|
||||
end
|
||||
if type(k) == "table" then
|
||||
seen[k] = true
|
||||
end
|
||||
if type(v) == "table" then
|
||||
seen[v] = true
|
||||
end
|
||||
ret = ret .. string.format("[%s] = %s,", serialize(k, seen),
|
||||
serialize(v, seen))
|
||||
end
|
||||
ret = ret .. "}"
|
||||
elseif type(t) == "function" or type(t) == "thread" or
|
||||
type(t) == "userdata" then
|
||||
error("cannot serialize type " .. type(t), 2)
|
||||
else
|
||||
return string.format("%q", t)
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
function tu.serialize(t, opts)
|
||||
expect(1, t, "table")
|
||||
expect(2, opts, "table", "nil")
|
||||
|
||||
return serialize(t, {})
|
||||
end
|
||||
|
||||
function tu.unserialize(s)
|
||||
expect(1, s, "string")
|
||||
local call = load("return " .. s, "=<unserialize>", "t", {})
|
||||
if call then return call() end
|
||||
end
|
||||
|
||||
tu.serialise = tu.serialize
|
||||
tu.unserialise = tu.unserialize
|
||||
|
||||
function tu.serializeJSON(t, nbt)
|
||||
expect(1, t, "table")
|
||||
if nbt then
|
||||
error("NBT mode is not yet supported")
|
||||
end
|
||||
return json.encode(t)
|
||||
end
|
||||
|
||||
function tu.unserializeJSON(s)--s, options)
|
||||
expect(1, s, "string")
|
||||
return json.decode(s)
|
||||
end
|
||||
|
||||
tu.serialiseJSON = tu.serializeJSON
|
||||
tu.unserialiseJSON = tu.unserializeJSON
|
||||
|
||||
function tu.urlEncode(str)
|
||||
expect(1, str, "string")
|
||||
|
||||
-- TODO: possibly UTF-8 support?
|
||||
str = str:gsub("[^%w %-%_%.]", function(c)
|
||||
return string.format("%%%02x", c:byte())
|
||||
end):gsub(" ", "+"):gsub("\n", "\r\n")
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
local function split(text)
|
||||
local dots = {""}
|
||||
|
||||
for c in text:gmatch(".") do
|
||||
if c == "." or c == ":" then
|
||||
--dots[#dots+1] = c
|
||||
dots[#dots+1] = ""
|
||||
else
|
||||
dots[#dots] = dots[#dots] .. c
|
||||
end
|
||||
end
|
||||
|
||||
return dots
|
||||
end
|
||||
|
||||
local function getSuffix(thing, default)
|
||||
if type(thing) == "table" then
|
||||
return "."
|
||||
elseif type(thing) == "function" then
|
||||
return "("
|
||||
end
|
||||
return default
|
||||
end
|
||||
|
||||
function tu.complete(text, env)
|
||||
expect(1, text, "string")
|
||||
env = expect(2, env, "table", "nil") or _G
|
||||
|
||||
local last_exp = text:match("[^%(%)%%%+%-%*/%[%]%{%}; =]*$")
|
||||
|
||||
local results = {}
|
||||
|
||||
if last_exp and #last_exp > 0 then
|
||||
local search = {env}
|
||||
local mt = getmetatable(env)
|
||||
if mt and type(mt.__index) == "table" then
|
||||
search[#search+1] = mt.__index
|
||||
end
|
||||
|
||||
for s=1, #search, 1 do
|
||||
local dots = split(last_exp)
|
||||
local current = search[s]
|
||||
|
||||
local final = 0
|
||||
for i=1, #dots, 1 do
|
||||
if current[dots[i]] then
|
||||
current = current[dots[i]]
|
||||
final = i
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
for _=1, final, 1 do table.remove(dots, 1) end
|
||||
|
||||
if #dots == 0 then
|
||||
results[#results+1] = getSuffix(current)
|
||||
end
|
||||
|
||||
if #dots ~= 1 or type(current) ~= "table" then return results end
|
||||
|
||||
local find = dots[1]
|
||||
for key, val in pairs(current) do
|
||||
key = key .. getSuffix(val, "")
|
||||
|
||||
if key:sub(1, #find) == find then
|
||||
results[#results+1] = key:sub(#find + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return results
|
||||
end
|
||||
|
||||
function tu.coloredWrite(...)
|
||||
return coloredWrite(false, ...)
|
||||
end
|
||||
|
||||
function tu.coloredPrint(...)
|
||||
return coloredWrite(false, ...) + rc.write("\n")
|
||||
end
|
||||
|
||||
function tu.coloredPagedPrint(...)
|
||||
return coloredWrite(true, ...) + rc.write("\n")
|
||||
end
|
||||
|
||||
return tu
|
||||
Reference in New Issue
Block a user