mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-15 02:12:42 -04:00
Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8.9
This commit is contained in:
commit
66b6fbb7fa
@ -684,4 +684,4 @@ while running do
|
||||
end
|
||||
|
||||
term.clear()
|
||||
term.setCursorBlink(false)
|
||||
term.setCursorBlink(true)
|
||||
|
@ -12,7 +12,8 @@ end
|
||||
|
||||
shell.prime()
|
||||
local update_gpu = io.output().tty
|
||||
local interactive = io.input().tty
|
||||
local needs_profile = io.input().tty
|
||||
local input_handler = {hint = sh.hintHandler}
|
||||
|
||||
if #args == 0 then
|
||||
while true do
|
||||
@ -20,15 +21,13 @@ if #args == 0 then
|
||||
while not tty.isAvailable() do
|
||||
event.pull("term_available")
|
||||
end
|
||||
if interactive == true then -- first time run AND interactive
|
||||
interactive = 0
|
||||
tty.setReadHandler({hint = sh.hintHandler})
|
||||
if needs_profile then -- first time run AND interactive
|
||||
needs_profile = nil
|
||||
dofile("/etc/profile.lua")
|
||||
end
|
||||
io.write(sh.expand(os.getenv("PS1") or "$ "))
|
||||
tty.setCursorBlink(true)
|
||||
end
|
||||
local command = io.read()
|
||||
local command = tty:read(input_handler)
|
||||
if command then
|
||||
command = text.trim(command)
|
||||
if command == "exit" then
|
||||
|
321
src/main/resources/assets/opencomputers/loot/openos/bin/tree.lua
Normal file
321
src/main/resources/assets/opencomputers/loot/openos/bin/tree.lua
Normal file
@ -0,0 +1,321 @@
|
||||
local shell = require("shell")
|
||||
local fs = require("filesystem")
|
||||
local tx = require("transforms")
|
||||
local text = require("text")
|
||||
|
||||
local args, opts = shell.parse(...)
|
||||
|
||||
local function die(...)
|
||||
io.stderr:write(...)
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
do -- handle cli
|
||||
if opts.help then
|
||||
print([[Usage: tree [OPTION]... [FILE]...
|
||||
-a, --all do not ignore entries starting with .
|
||||
--full-time with -l, print time in full iso format
|
||||
-h, --human-readable with -l, print human readable sizes
|
||||
--si likewise, but use powers of 1000 not 1024
|
||||
--level=LEVEL descend only LEVEL directories deep
|
||||
--color=WHEN WHEN can be
|
||||
auto - colorize output only if writing to a tty,
|
||||
always - always colorize output,
|
||||
never - never colorize output; (default: auto)
|
||||
-l use a long listing format
|
||||
-f print the full path prefix for each file
|
||||
-i do not print indentation lines
|
||||
-p append "/" indicator to directories
|
||||
-Q, --quote quote filenames with double quotes
|
||||
-r, --reverse reverse order while sorting
|
||||
-S sort by file size
|
||||
-t sort by modification type, newest first
|
||||
-X sort alphabetically by entry extension
|
||||
-C do not count files and directories
|
||||
-R count root directories like other files
|
||||
--help print this help and exit]])
|
||||
return 0
|
||||
end
|
||||
|
||||
if #args == 0 then
|
||||
table.insert(args, ".")
|
||||
end
|
||||
|
||||
opts.level = tonumber(opts.level) or math.huge
|
||||
if opts.level < 1 then
|
||||
die("Invalid level, must be greater than 0")
|
||||
end
|
||||
|
||||
opts.color = opts.color or "auto"
|
||||
if opts.color == "auto" then
|
||||
opts.color = io.stdout.tty and "always" or "never"
|
||||
end
|
||||
|
||||
if opts.color ~= "always" and opts.color ~= "never" then
|
||||
die("Invalid value for --color=WHEN option; WHEN should be auto, always or never")
|
||||
end
|
||||
end
|
||||
|
||||
local function peekable(iterator, state, var1)
|
||||
local nextItem = {iterator(state, var1)}
|
||||
|
||||
return setmetatable({
|
||||
peek = function()
|
||||
return table.unpack(nextItem)
|
||||
end
|
||||
}, {
|
||||
__call = coroutine.wrap(function()
|
||||
while true do
|
||||
local item = nextItem
|
||||
nextItem = {iterator(state, nextItem[1])}
|
||||
coroutine.yield(table.unpack(item))
|
||||
if nextItem[1] == nil then break end
|
||||
end
|
||||
end)
|
||||
})
|
||||
end
|
||||
|
||||
local function filter(entry)
|
||||
return opts.a or entry:sub(1, 1) ~= "."
|
||||
end
|
||||
|
||||
local function stat(path)
|
||||
local st = {}
|
||||
st.path = path
|
||||
st.name = fs.name(path) or "/"
|
||||
st.sortName = st.name:gsub("^%.","")
|
||||
st.time = fs.lastModified(path)
|
||||
st.isLink = fs.isLink(path)
|
||||
st.isDirectory = fs.isDirectory(path)
|
||||
st.size = st.isLink and 0 or fs.size(path)
|
||||
st.extension = st.name:match("(%.[^.]+)$") or ""
|
||||
st.fs = fs.get(path)
|
||||
return st
|
||||
end
|
||||
|
||||
local colorize
|
||||
if opts.color == "always" then
|
||||
-- from /lib/core/full_ls.lua
|
||||
local colors = tx.foreach(text.split(os.getenv("LS_COLORS") or "", {":"}, true), function(e)
|
||||
local parts = text.split(e, {"="}, true)
|
||||
return parts[2], parts[1]
|
||||
end)
|
||||
|
||||
function colorize(stat)
|
||||
return stat.isLink and colors.ln or
|
||||
stat.isDirectory and colors.di or
|
||||
colors["*" .. stat.extension] or
|
||||
colors.fi
|
||||
end
|
||||
end
|
||||
|
||||
local function list(path)
|
||||
return coroutine.wrap(function()
|
||||
local l = {}
|
||||
for entry in fs.list(path) do
|
||||
if filter(entry) then
|
||||
table.insert(l, stat(fs.concat(path, entry)))
|
||||
end
|
||||
end
|
||||
|
||||
if opts.S then
|
||||
table.sort(l, function(a, b)
|
||||
return a.size < b.size
|
||||
end)
|
||||
elseif opts.t then
|
||||
table.sort(l, function(a, b)
|
||||
return a.time < b.time
|
||||
end)
|
||||
elseif opts.X then
|
||||
table.sort(l, function(a, b)
|
||||
return a.extension < b.extension
|
||||
end)
|
||||
else
|
||||
table.sort(l, function(a, b)
|
||||
return a.sortName < b.sortName
|
||||
end)
|
||||
end
|
||||
|
||||
for i = opts.r and #l or 1, opts.r and 1 or #l, opts.r and -1 or 1 do
|
||||
coroutine.yield(l[i])
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function digRoot(rootPath)
|
||||
coroutine.yield(stat(rootPath), {})
|
||||
|
||||
if not fs.isDirectory(rootPath) then
|
||||
return
|
||||
end
|
||||
local iterStack = {peekable(list(rootPath))}
|
||||
local pathStack = {rootPath}
|
||||
local levelStack = {not not iterStack[#iterStack]:peek()}
|
||||
|
||||
|
||||
repeat
|
||||
local entry = iterStack[#iterStack]()
|
||||
|
||||
if entry then
|
||||
levelStack[#levelStack] = not not iterStack[#iterStack]:peek()
|
||||
|
||||
local path = fs.concat(fs.concat(table.unpack(pathStack)), entry.name)
|
||||
|
||||
coroutine.yield(entry, levelStack)
|
||||
|
||||
if entry.isDirectory and opts.level > #levelStack then
|
||||
table.insert(iterStack, peekable(list(path)))
|
||||
table.insert(pathStack, entry.name)
|
||||
table.insert(levelStack, not not iterStack[#iterStack]:peek())
|
||||
end
|
||||
else
|
||||
table.remove(iterStack)
|
||||
table.remove(pathStack)
|
||||
table.remove(levelStack)
|
||||
end
|
||||
until #iterStack == 0
|
||||
end
|
||||
|
||||
local function dig(roots)
|
||||
return coroutine.wrap(function()
|
||||
for _, root in ipairs(roots) do
|
||||
digRoot(root)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function nod(n) -- from /lib/core/full_ls.lua
|
||||
return n and (tostring(n):gsub("(%.[0-9]+)0+$","%1")) or "0"
|
||||
end
|
||||
|
||||
local function formatFSize(size) -- from /lib/core/full_ls.lua
|
||||
if not opts.h and not opts["human-readable"] and not opts.si then
|
||||
return tostring(size)
|
||||
end
|
||||
|
||||
local sizes = {"", "K", "M", "G"}
|
||||
local unit = 1
|
||||
local power = opts.si and 1000 or 1024
|
||||
|
||||
while size > power and unit < #sizes do
|
||||
unit = unit + 1
|
||||
size = size / power
|
||||
end
|
||||
|
||||
return nod(math.floor(size*10)/10)..sizes[unit]
|
||||
end
|
||||
|
||||
local function pad(txt) -- from /lib/core/full_ls.lua
|
||||
txt = tostring(txt)
|
||||
return #txt >= 2 and txt or "0" .. txt
|
||||
end
|
||||
|
||||
local function formatTime(epochms) -- from /lib/core/full_ls.lua
|
||||
local month_names = {"January","February","March","April","May","June",
|
||||
"July","August","September","October","November","December"}
|
||||
|
||||
if epochms == 0 then return "" end
|
||||
|
||||
local d = os.date("*t", epochms)
|
||||
local day, hour, min, sec = nod(d.day), pad(nod(d.hour)), pad(nod(d.min)), pad(nod(d.sec))
|
||||
|
||||
if opts["full-time"] then
|
||||
return string.format("%s-%s-%s %s:%s:%s ", d.year, pad(nod(d.month)), pad(day), hour, min, sec)
|
||||
else
|
||||
return string.format("%s %+2s %+2s:%+2s ", month_names[d.month]:sub(1,3), day, hour, pad(min))
|
||||
end
|
||||
end
|
||||
|
||||
local function writeEntry(entry, levelStack)
|
||||
for i, hasNext in ipairs(levelStack) do
|
||||
if opts.i then break end
|
||||
|
||||
if i == #levelStack then
|
||||
if hasNext then
|
||||
io.write("├── ")
|
||||
else
|
||||
io.write("└── ")
|
||||
end
|
||||
else
|
||||
if hasNext then
|
||||
io.write("│ ")
|
||||
else
|
||||
io.write(" ")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if opts.l then
|
||||
io.write("[")
|
||||
|
||||
io.write(entry.isDirectory and "d" or entry.isLink and "l" or "f", "-")
|
||||
io.write("r", entry.fs.isReadOnly() and "-" or "w", " ")
|
||||
|
||||
io.write(formatFSize(entry.size), " ")
|
||||
|
||||
io.write(formatTime(entry.time))
|
||||
io.write("] ")
|
||||
end
|
||||
|
||||
if opts.Q then io.write('"') end
|
||||
|
||||
if opts.color == "always" then
|
||||
io.write("\27[" .. colorize(entry) .. "m")
|
||||
end
|
||||
|
||||
if opts.f then
|
||||
io.write(entry.path)
|
||||
else
|
||||
io.write(entry.name)
|
||||
end
|
||||
|
||||
if opts.color == "always" then
|
||||
io.write("\27[0m")
|
||||
end
|
||||
|
||||
if opts.p and entry.isDirectory then
|
||||
io.write("/")
|
||||
end
|
||||
|
||||
if opts.Q then io.write('"') end
|
||||
io.write("\n")
|
||||
end
|
||||
|
||||
local function writeCount(dirs, files)
|
||||
io.write("\n")
|
||||
io.write(dirs, " director", dirs == 1 and "y" or "ies")
|
||||
io.write(", ")
|
||||
io.write(files, " file", files == 1 and "" or "s")
|
||||
io.write("\n")
|
||||
end
|
||||
|
||||
local dirs, files = 0, 0
|
||||
|
||||
local roots = {}
|
||||
for _, arg in ipairs(args) do
|
||||
local path = shell.resolve(arg)
|
||||
local real, reason = fs.realPath(path)
|
||||
if not real then
|
||||
die("cannot access ", path, ": ", reason or "unknown error")
|
||||
elseif not fs.exists(path) then
|
||||
die("cannot access ", path, ":", "No such file or directory")
|
||||
else
|
||||
table.insert(roots, real)
|
||||
end
|
||||
end
|
||||
|
||||
for entry, levelStack in dig(roots) do
|
||||
if opts.R or #levelStack > 0 then
|
||||
if entry.isDirectory then
|
||||
dirs = dirs + 1
|
||||
else
|
||||
files = files + 1
|
||||
end
|
||||
end
|
||||
writeEntry(entry, levelStack)
|
||||
end
|
||||
|
||||
if not opts.C then
|
||||
writeCount(dirs, files)
|
||||
end
|
||||
|
@ -3,9 +3,12 @@ local tty = require("tty")
|
||||
local fs = require("filesystem")
|
||||
|
||||
if tty.isAvailable() then
|
||||
tty:write("\27[40m\27[37m")
|
||||
if io.stdout.tty then
|
||||
io.write("\27[40m\27[37m")
|
||||
tty.clear()
|
||||
end
|
||||
tty.setCursorBlink(true)
|
||||
end
|
||||
dofile("/etc/motd")
|
||||
|
||||
shell.setAlias("dir", "ls")
|
||||
@ -31,7 +34,7 @@ os.setenv("IFS", " ")
|
||||
os.setenv("MANPATH", "/usr/man:.")
|
||||
os.setenv("PAGER", "/bin/more")
|
||||
os.setenv("PS1", "\27[40m\27[31m$HOSTNAME$HOSTNAME_SEPARATOR$PWD # \27[37m")
|
||||
os.setenv("LS_COLORS", "{FILE=0xFFFFFF,DIR=0x66CCFF,LINK=0xFFAA00,['*.lua']=0x00FF00}")
|
||||
os.setenv("LS_COLORS", "di=0;36:fi=0:ln=0;33:*.lua=0;32")
|
||||
|
||||
shell.setWorkingDirectory(os.getenv("HOME"))
|
||||
|
||||
|
@ -40,8 +40,8 @@ end
|
||||
function adapter_api.create_toggle(read, write, switch)
|
||||
return
|
||||
{
|
||||
read = function() return tostring(read()) end,
|
||||
write = function(value)
|
||||
read = read and function() return tostring(read()) end,
|
||||
write = write and function(value)
|
||||
value = text.trim(tostring(value))
|
||||
local on = value == "1" or value == "true"
|
||||
local off = value == "0" or value == "false"
|
||||
|
@ -2,6 +2,8 @@ local fs = require("filesystem")
|
||||
local shell = require("shell")
|
||||
local tty = require("tty")
|
||||
local unicode = require("unicode")
|
||||
local tx = require("transforms")
|
||||
local text = require("text")
|
||||
|
||||
local dirsArg, ops = shell.parse(...)
|
||||
|
||||
@ -32,7 +34,6 @@ if #dirsArg == 0 then
|
||||
end
|
||||
|
||||
local ec = 0
|
||||
local gpu = tty.gpu()
|
||||
local fOut = tty.isAvailable() and io.output().tty
|
||||
local function perr(msg) io.stderr:write(msg,"\n") ec = 2 end
|
||||
local function stat(names, index)
|
||||
@ -56,42 +57,30 @@ local function stat(names, index)
|
||||
return info
|
||||
end
|
||||
local function toArray(i) local r={} for n in i do r[#r+1]=n end return r end
|
||||
local restore_color = function() end
|
||||
local set_color = function() end
|
||||
local prev_color
|
||||
local function colorize() return prev_color end
|
||||
local function colorize() return end
|
||||
if fOut and not ops["no-color"] then
|
||||
local LSC = os.getenv("LS_COLORS")
|
||||
if type(LSC) == "string" then
|
||||
LSC = require("serialization").unserialize(LSC)
|
||||
end
|
||||
if not LSC then
|
||||
perr("ls: unparsable value for LS_COLORS environment variable")
|
||||
else
|
||||
prev_color = gpu.getForeground()
|
||||
restore_color = function() gpu.setForeground(prev_color) end
|
||||
local LSC = tx.foreach(text.split(os.getenv("LS_COLORS") or "", {":"}, true), function(e)
|
||||
local parts = text.split(e, {"="}, true)
|
||||
return parts[2], parts[1]
|
||||
end)
|
||||
colorize = function(info)
|
||||
return
|
||||
info.isLink and LSC.LINK or
|
||||
info.isDir and LSC.DIR or
|
||||
info.isLink and LSC.ln or
|
||||
info.isDir and LSC.di or
|
||||
LSC['*'..info.ext] or
|
||||
LSC.FILE or
|
||||
prev_color
|
||||
LSC.fi
|
||||
end
|
||||
set_color=function(c)
|
||||
if gpu.getForeground() ~= c then
|
||||
io.stdout:flush()
|
||||
gpu.setForeground(c)
|
||||
end
|
||||
end
|
||||
io.write(string.char(0x1b), "[", c or "", "m")
|
||||
end
|
||||
end
|
||||
local msft={reports=0,proxies={}}
|
||||
function msft.report(files, dirs, used, proxy)
|
||||
local free = proxy.spaceTotal() - proxy.spaceUsed()
|
||||
restore_color()
|
||||
local pattern = "%5i File(s) %11i bytes\n%5i Dir(s) %11s bytes free\n"
|
||||
io.write(string.format(pattern, files, used, dirs, tostring(free)))
|
||||
set_color()
|
||||
local pattern = "%5i File(s) %s bytes\n%5i Dir(s) %11s bytes free\n"
|
||||
io.write(string.format(pattern, files, tostring(used), dirs, tostring(free)))
|
||||
end
|
||||
function msft.tail(names)
|
||||
local fsproxy = fs.get(names.path)
|
||||
@ -123,7 +112,7 @@ function msft.final()
|
||||
for proxy,report in pairs(msft.proxies) do
|
||||
table.insert(groups, {proxy=proxy,report=report})
|
||||
end
|
||||
restore_color()
|
||||
set_color()
|
||||
print("Total Files Listed:")
|
||||
for _,pair in ipairs(groups) do
|
||||
local proxy, report = pair.proxy, pair.report
|
||||
@ -263,7 +252,7 @@ local function display(names)
|
||||
local format = "%s-r%s %+"..tostring(max_size_width).."s %"..tostring(max_date_width).."s"
|
||||
local meta = string.format(format, file_type, write_mode, size, modDate)
|
||||
local item = info.name..link_target
|
||||
return {{color = prev_color, name = meta}, {color = colorize(info), name = item}}
|
||||
return {{name = meta}, {color = colorize(info), name = item}}
|
||||
end
|
||||
elseif ops["1"] or not fOut then
|
||||
lines.n = #names
|
||||
@ -332,7 +321,7 @@ local header = function() end
|
||||
if #dirsArg > 1 or ops.R then
|
||||
header = function(path)
|
||||
if not first_display then print() end
|
||||
restore_color()
|
||||
set_color()
|
||||
io.write(path,":\n")
|
||||
end
|
||||
end
|
||||
@ -366,11 +355,20 @@ for _,dir in ipairs(dirsArg) do
|
||||
table.insert(file_set, dir)
|
||||
end
|
||||
end
|
||||
|
||||
io.output():setvbuf("line")
|
||||
|
||||
local ok, msg = pcall(function()
|
||||
if #file_set > 0 then display(sort(file_set)) end
|
||||
displayDirList(dir_set)
|
||||
msft.final()
|
||||
end)
|
||||
|
||||
io.output():flush()
|
||||
io.output():setvbuf("no")
|
||||
restore_color()
|
||||
set_color()
|
||||
|
||||
assert(ok, msg)
|
||||
|
||||
return ec
|
||||
|
||||
|
@ -68,7 +68,7 @@ local function findKeys(t, r, prefix, name)
|
||||
end
|
||||
end
|
||||
|
||||
tty.setReadHandler({hint = function(line, index)
|
||||
local read_handler = {hint = function(line, index)
|
||||
line = (line or "")
|
||||
local tail = line:sub(index)
|
||||
line = line:sub(1, index - 1)
|
||||
@ -85,7 +85,7 @@ tty.setReadHandler({hint = function(line, index)
|
||||
table.insert(hints, key .. tail)
|
||||
end
|
||||
return hints
|
||||
end})
|
||||
end}
|
||||
|
||||
io.write("\27[37m".._VERSION .. " Copyright (C) 1994-2017 Lua.org, PUC-Rio\n")
|
||||
io.write("\27[33mEnter a statement and hit enter to evaluate it.\n")
|
||||
@ -94,7 +94,7 @@ io.write("Press Ctrl+D to exit the interpreter.\n\27[37m")
|
||||
|
||||
while tty.isAvailable() do
|
||||
io.write(env._PROMPT)
|
||||
local command = io.read()
|
||||
local command = tty:read(read_handler)
|
||||
if not command then -- eof
|
||||
return
|
||||
end
|
||||
|
@ -24,7 +24,6 @@ end
|
||||
local function saveConfig()
|
||||
local root = filesystem.get("/")
|
||||
if root and not root.isReadOnly() then
|
||||
filesystem.makeDirectory("/etc")
|
||||
local f = filesystem.open("/etc/filesystem.cfg", "w")
|
||||
if f then
|
||||
f:write("autorun="..tostring(isAutorunEnabled))
|
||||
|
@ -194,9 +194,6 @@ function term.write(value, wrap)
|
||||
end
|
||||
|
||||
function term.read(history, dobreak, hint, pwchar, filter)
|
||||
if not io.stdin.tty then
|
||||
return io.read("*L")
|
||||
end
|
||||
history = history or {}
|
||||
local handler = history
|
||||
handler.hint = handler.hint or hint
|
||||
|
@ -3,7 +3,6 @@ local event = require("event")
|
||||
local kb = require("keyboard")
|
||||
local component = require("component")
|
||||
local computer = require("computer")
|
||||
local process = require("process")
|
||||
local keys = kb.keys
|
||||
|
||||
local tty = {}
|
||||
@ -19,11 +18,6 @@ tty.window =
|
||||
|
||||
tty.internal = {}
|
||||
|
||||
function tty.setReadHandler(handler)
|
||||
checkArg(1, handler, "table")
|
||||
process.info().data.handler = handler
|
||||
end
|
||||
|
||||
function tty.key_down_handler(handler, cursor, char, code)
|
||||
local data = cursor.data
|
||||
local c = false
|
||||
@ -268,15 +262,17 @@ function tty.internal.build_vertical_reader()
|
||||
end
|
||||
|
||||
-- read n bytes, n is unused
|
||||
function tty.read(_, handler, cursor)
|
||||
function tty.read(self, handler, cursor)
|
||||
checkArg(1, handler, "table", "number")
|
||||
checkArg(2, cursor, "table", "nil")
|
||||
|
||||
if type(handler) == "number" then
|
||||
-- standard read as a stream, asking for n bytes
|
||||
handler = process.info().data.handler or {}
|
||||
if not io.stdin.tty or io.stdin.stream ~= self then
|
||||
return io.stdin:readLine(false)
|
||||
end
|
||||
|
||||
if type(handler) ~= "table" then
|
||||
handler = {}
|
||||
end
|
||||
handler.index = 0
|
||||
cursor = cursor or tty.internal.build_vertical_reader()
|
||||
|
||||
@ -324,7 +320,10 @@ function tty.setCursor(x, y)
|
||||
window.x, window.y = x, y
|
||||
end
|
||||
|
||||
function tty.write(_, value)
|
||||
function tty.write(self, value)
|
||||
if not io.stdout.tty or io.stdout.stream ~= self then
|
||||
return io.write(value)
|
||||
end
|
||||
local gpu = tty.gpu()
|
||||
if not gpu then
|
||||
return
|
||||
@ -352,7 +351,8 @@ function tty.write(_, value)
|
||||
value = window.ansi_escape:sub(5)
|
||||
end
|
||||
for _,catt in ipairs(color_attributes) do
|
||||
local colors = {0x0,0xff0000,0x00ff00,0xffff00,0x0000ff,0xff00ff,0x00ffff,0xffffff}
|
||||
-- B6 is closer to cyan in 4 bit color
|
||||
local colors = {0x0,0xff0000,0x00ff00,0xffff00,0x0000ff,0xff00ff,0x00B6ff,0xffffff}
|
||||
catt = catt - 29
|
||||
local method = "setForeground"
|
||||
if catt > 10 then
|
||||
|
@ -1,3 +1,4 @@
|
||||
local text = require("text")
|
||||
local vt100 = {}
|
||||
|
||||
-- runs patterns on ansi until failure
|
||||
@ -25,15 +26,26 @@ local rules = {}
|
||||
-- [%d+;%d+;..%d+m
|
||||
rules[{"%[", "[%d;]*", "m"}] = function(_, _, number_text)
|
||||
local numbers = {}
|
||||
number_text:gsub("[^;]*", function(num)
|
||||
local n = tonumber(num) or 0
|
||||
if n == 0 then
|
||||
-- prefix and suffix ; act as reset
|
||||
-- e.g. \27[41;m is actually 41 followed by a reset
|
||||
number_text = ";" .. number_text:gsub("^;$","") .. ";"
|
||||
local parts = text.split(number_text, {";"})
|
||||
local last_was_break
|
||||
for _,part in ipairs(parts) do
|
||||
local num = tonumber(part)
|
||||
if not num then
|
||||
num = last_was_break and 0
|
||||
last_was_break = true
|
||||
else
|
||||
last_was_break = false
|
||||
end
|
||||
if num == 0 then
|
||||
numbers[#numbers + 1] = 40
|
||||
numbers[#numbers + 1] = 37
|
||||
else
|
||||
numbers[#numbers + 1] = n
|
||||
elseif num then
|
||||
numbers[#numbers + 1] = num
|
||||
end
|
||||
end
|
||||
end)
|
||||
return numbers
|
||||
end
|
||||
|
||||
|
@ -88,6 +88,7 @@ Robby # Forbidden Planet
|
||||
Roomba # Under your couch... wait.
|
||||
Rosie # The Jetsons
|
||||
Shakey # The first general-purpose mobile robot that could reason about its actions.
|
||||
SHODAN # System Shock
|
||||
Skynet # Terminator
|
||||
Space Core # Portal
|
||||
SpiritedDusty # Contributor
|
||||
|
@ -1,7 +1,6 @@
|
||||
package li.cil.oc.client.renderer.markdown.segment
|
||||
|
||||
import li.cil.oc.client.renderer.markdown.Document
|
||||
import li.cil.oc.client.renderer.markdown.MarkupFormat
|
||||
import li.cil.oc.client.renderer.markdown.{Document, MarkupFormat}
|
||||
import net.minecraft.client.gui.FontRenderer
|
||||
|
||||
trait BasicTextSegment extends Segment {
|
||||
@ -58,11 +57,21 @@ trait BasicTextSegment extends Segment {
|
||||
while (pos < s.length) {
|
||||
pos += 1
|
||||
val width = stringWidth(s.take(pos), renderer)
|
||||
if (width >= maxWidth) {
|
||||
if (lastBreak > 0 || fullWidth <= maxLineWidth || s.exists(breaks.contains))
|
||||
if (maxWidth == maxLineWidth && fullWidth == maxLineWidth && !s.exists(breaks.contains)) return s.length
|
||||
else return lastBreak + 1
|
||||
else return pos - 1
|
||||
val exceedsLineLength = width >= maxWidth
|
||||
if (exceedsLineLength) {
|
||||
val mayUseFullLine = maxWidth == maxLineWidth
|
||||
val canFitInLine = fullWidth <= maxLineWidth
|
||||
val matchesFullLine = fullWidth == maxLineWidth
|
||||
if (lastBreak >= 0) {
|
||||
return lastBreak + 1 // Can do a soft split.
|
||||
}
|
||||
if (mayUseFullLine && matchesFullLine) {
|
||||
return s.length // Special case for exact match.
|
||||
}
|
||||
if (canFitInLine && !mayUseFullLine) {
|
||||
return 0 // Wrap line, use next line.
|
||||
}
|
||||
return pos - 1 // Gotta split hard.
|
||||
}
|
||||
if (pos < s.length && breaks.contains(s.charAt(pos))) lastBreak = pos
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ class UnicodeAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
|
||||
var width = 0
|
||||
var end = 0
|
||||
while (width < count) {
|
||||
width += FontUtils.wcwidth(value(end))
|
||||
width += math.max(1, FontUtils.wcwidth(value(end)))
|
||||
end += 1
|
||||
}
|
||||
if (end > 1) lua.pushString(value.substring(0, end - 1))
|
||||
|
@ -53,7 +53,7 @@ class UnicodeAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) {
|
||||
var width = 0
|
||||
var end = 0
|
||||
while (width < count) {
|
||||
width += FontUtils.wcwidth(value(end))
|
||||
width += math.max(1, FontUtils.wcwidth(value(end)))
|
||||
end += 1
|
||||
}
|
||||
if (end > 1) LuaValue.valueOf(value.substring(0, end - 1))
|
||||
|
Loading…
x
Reference in New Issue
Block a user