Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8.9

This commit is contained in:
Florian Nücke 2017-07-22 14:52:39 +02:00
commit 66b6fbb7fa
15 changed files with 421 additions and 82 deletions

View File

@ -684,4 +684,4 @@ while running do
end end
term.clear() term.clear()
term.setCursorBlink(false) term.setCursorBlink(true)

View File

@ -12,7 +12,8 @@ end
shell.prime() shell.prime()
local update_gpu = io.output().tty 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 if #args == 0 then
while true do while true do
@ -20,15 +21,13 @@ if #args == 0 then
while not tty.isAvailable() do while not tty.isAvailable() do
event.pull("term_available") event.pull("term_available")
end end
if interactive == true then -- first time run AND interactive if needs_profile then -- first time run AND interactive
interactive = 0 needs_profile = nil
tty.setReadHandler({hint = sh.hintHandler})
dofile("/etc/profile.lua") dofile("/etc/profile.lua")
end end
io.write(sh.expand(os.getenv("PS1") or "$ ")) io.write(sh.expand(os.getenv("PS1") or "$ "))
tty.setCursorBlink(true)
end end
local command = io.read() local command = tty:read(input_handler)
if command then if command then
command = text.trim(command) command = text.trim(command)
if command == "exit" then if command == "exit" then

View 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

View File

@ -3,9 +3,12 @@ local tty = require("tty")
local fs = require("filesystem") local fs = require("filesystem")
if tty.isAvailable() then if tty.isAvailable() then
tty:write("\27[40m\27[37m") if io.stdout.tty then
io.write("\27[40m\27[37m")
tty.clear() tty.clear()
end end
tty.setCursorBlink(true)
end
dofile("/etc/motd") dofile("/etc/motd")
shell.setAlias("dir", "ls") shell.setAlias("dir", "ls")
@ -31,7 +34,7 @@ os.setenv("IFS", " ")
os.setenv("MANPATH", "/usr/man:.") os.setenv("MANPATH", "/usr/man:.")
os.setenv("PAGER", "/bin/more") os.setenv("PAGER", "/bin/more")
os.setenv("PS1", "\27[40m\27[31m$HOSTNAME$HOSTNAME_SEPARATOR$PWD # \27[37m") 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")) shell.setWorkingDirectory(os.getenv("HOME"))

View File

@ -40,8 +40,8 @@ end
function adapter_api.create_toggle(read, write, switch) function adapter_api.create_toggle(read, write, switch)
return return
{ {
read = function() return tostring(read()) end, read = read and function() return tostring(read()) end,
write = function(value) write = write and function(value)
value = text.trim(tostring(value)) value = text.trim(tostring(value))
local on = value == "1" or value == "true" local on = value == "1" or value == "true"
local off = value == "0" or value == "false" local off = value == "0" or value == "false"

View File

@ -2,6 +2,8 @@ local fs = require("filesystem")
local shell = require("shell") local shell = require("shell")
local tty = require("tty") local tty = require("tty")
local unicode = require("unicode") local unicode = require("unicode")
local tx = require("transforms")
local text = require("text")
local dirsArg, ops = shell.parse(...) local dirsArg, ops = shell.parse(...)
@ -32,7 +34,6 @@ if #dirsArg == 0 then
end end
local ec = 0 local ec = 0
local gpu = tty.gpu()
local fOut = tty.isAvailable() and io.output().tty local fOut = tty.isAvailable() and io.output().tty
local function perr(msg) io.stderr:write(msg,"\n") ec = 2 end local function perr(msg) io.stderr:write(msg,"\n") ec = 2 end
local function stat(names, index) local function stat(names, index)
@ -56,42 +57,30 @@ local function stat(names, index)
return info return info
end end
local function toArray(i) local r={} for n in i do r[#r+1]=n end return r 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 set_color = function() end
local prev_color local function colorize() return end
local function colorize() return prev_color end
if fOut and not ops["no-color"] then if fOut and not ops["no-color"] then
local LSC = os.getenv("LS_COLORS") local LSC = tx.foreach(text.split(os.getenv("LS_COLORS") or "", {":"}, true), function(e)
if type(LSC) == "string" then local parts = text.split(e, {"="}, true)
LSC = require("serialization").unserialize(LSC) return parts[2], parts[1]
end 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
colorize = function(info) colorize = function(info)
return return
info.isLink and LSC.LINK or info.isLink and LSC.ln or
info.isDir and LSC.DIR or info.isDir and LSC.di or
LSC['*'..info.ext] or LSC['*'..info.ext] or
LSC.FILE or LSC.fi
prev_color
end end
set_color=function(c) set_color=function(c)
if gpu.getForeground() ~= c then io.write(string.char(0x1b), "[", c or "", "m")
io.stdout:flush()
gpu.setForeground(c)
end
end
end end
end end
local msft={reports=0,proxies={}} local msft={reports=0,proxies={}}
function msft.report(files, dirs, used, proxy) function msft.report(files, dirs, used, proxy)
local free = proxy.spaceTotal() - proxy.spaceUsed() local free = proxy.spaceTotal() - proxy.spaceUsed()
restore_color() set_color()
local pattern = "%5i File(s) %11i bytes\n%5i Dir(s) %11s bytes free\n" local pattern = "%5i File(s) %s bytes\n%5i Dir(s) %11s bytes free\n"
io.write(string.format(pattern, files, used, dirs, tostring(free))) io.write(string.format(pattern, files, tostring(used), dirs, tostring(free)))
end end
function msft.tail(names) function msft.tail(names)
local fsproxy = fs.get(names.path) local fsproxy = fs.get(names.path)
@ -123,7 +112,7 @@ function msft.final()
for proxy,report in pairs(msft.proxies) do for proxy,report in pairs(msft.proxies) do
table.insert(groups, {proxy=proxy,report=report}) table.insert(groups, {proxy=proxy,report=report})
end end
restore_color() set_color()
print("Total Files Listed:") print("Total Files Listed:")
for _,pair in ipairs(groups) do for _,pair in ipairs(groups) do
local proxy, report = pair.proxy, pair.report 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 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 meta = string.format(format, file_type, write_mode, size, modDate)
local item = info.name..link_target 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 end
elseif ops["1"] or not fOut then elseif ops["1"] or not fOut then
lines.n = #names lines.n = #names
@ -332,7 +321,7 @@ local header = function() end
if #dirsArg > 1 or ops.R then if #dirsArg > 1 or ops.R then
header = function(path) header = function(path)
if not first_display then print() end if not first_display then print() end
restore_color() set_color()
io.write(path,":\n") io.write(path,":\n")
end end
end end
@ -366,11 +355,20 @@ for _,dir in ipairs(dirsArg) do
table.insert(file_set, dir) table.insert(file_set, dir)
end end
end end
io.output():setvbuf("line") io.output():setvbuf("line")
local ok, msg = pcall(function()
if #file_set > 0 then display(sort(file_set)) end if #file_set > 0 then display(sort(file_set)) end
displayDirList(dir_set) displayDirList(dir_set)
msft.final() msft.final()
end)
io.output():flush() io.output():flush()
io.output():setvbuf("no") io.output():setvbuf("no")
restore_color() set_color()
assert(ok, msg)
return ec return ec

View File

@ -68,7 +68,7 @@ local function findKeys(t, r, prefix, name)
end end
end end
tty.setReadHandler({hint = function(line, index) local read_handler = {hint = function(line, index)
line = (line or "") line = (line or "")
local tail = line:sub(index) local tail = line:sub(index)
line = line:sub(1, index - 1) line = line:sub(1, index - 1)
@ -85,7 +85,7 @@ tty.setReadHandler({hint = function(line, index)
table.insert(hints, key .. tail) table.insert(hints, key .. tail)
end end
return hints return hints
end}) end}
io.write("\27[37m".._VERSION .. " Copyright (C) 1994-2017 Lua.org, PUC-Rio\n") 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") 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 while tty.isAvailable() do
io.write(env._PROMPT) io.write(env._PROMPT)
local command = io.read() local command = tty:read(read_handler)
if not command then -- eof if not command then -- eof
return return
end end

View File

@ -24,7 +24,6 @@ end
local function saveConfig() local function saveConfig()
local root = filesystem.get("/") local root = filesystem.get("/")
if root and not root.isReadOnly() then if root and not root.isReadOnly() then
filesystem.makeDirectory("/etc")
local f = filesystem.open("/etc/filesystem.cfg", "w") local f = filesystem.open("/etc/filesystem.cfg", "w")
if f then if f then
f:write("autorun="..tostring(isAutorunEnabled)) f:write("autorun="..tostring(isAutorunEnabled))

View File

@ -194,9 +194,6 @@ function term.write(value, wrap)
end end
function term.read(history, dobreak, hint, pwchar, filter) function term.read(history, dobreak, hint, pwchar, filter)
if not io.stdin.tty then
return io.read("*L")
end
history = history or {} history = history or {}
local handler = history local handler = history
handler.hint = handler.hint or hint handler.hint = handler.hint or hint

View File

@ -3,7 +3,6 @@ local event = require("event")
local kb = require("keyboard") local kb = require("keyboard")
local component = require("component") local component = require("component")
local computer = require("computer") local computer = require("computer")
local process = require("process")
local keys = kb.keys local keys = kb.keys
local tty = {} local tty = {}
@ -19,11 +18,6 @@ tty.window =
tty.internal = {} 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) function tty.key_down_handler(handler, cursor, char, code)
local data = cursor.data local data = cursor.data
local c = false local c = false
@ -268,15 +262,17 @@ function tty.internal.build_vertical_reader()
end end
-- read n bytes, n is unused -- read n bytes, n is unused
function tty.read(_, handler, cursor) function tty.read(self, handler, cursor)
checkArg(1, handler, "table", "number") checkArg(1, handler, "table", "number")
checkArg(2, cursor, "table", "nil") checkArg(2, cursor, "table", "nil")
if type(handler) == "number" then if not io.stdin.tty or io.stdin.stream ~= self then
-- standard read as a stream, asking for n bytes return io.stdin:readLine(false)
handler = process.info().data.handler or {}
end end
if type(handler) ~= "table" then
handler = {}
end
handler.index = 0 handler.index = 0
cursor = cursor or tty.internal.build_vertical_reader() cursor = cursor or tty.internal.build_vertical_reader()
@ -324,7 +320,10 @@ function tty.setCursor(x, y)
window.x, window.y = x, y window.x, window.y = x, y
end 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() local gpu = tty.gpu()
if not gpu then if not gpu then
return return
@ -352,7 +351,8 @@ function tty.write(_, value)
value = window.ansi_escape:sub(5) value = window.ansi_escape:sub(5)
end end
for _,catt in ipairs(color_attributes) do 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 catt = catt - 29
local method = "setForeground" local method = "setForeground"
if catt > 10 then if catt > 10 then

View File

@ -1,3 +1,4 @@
local text = require("text")
local vt100 = {} local vt100 = {}
-- runs patterns on ansi until failure -- runs patterns on ansi until failure
@ -25,15 +26,26 @@ local rules = {}
-- [%d+;%d+;..%d+m -- [%d+;%d+;..%d+m
rules[{"%[", "[%d;]*", "m"}] = function(_, _, number_text) rules[{"%[", "[%d;]*", "m"}] = function(_, _, number_text)
local numbers = {} local numbers = {}
number_text:gsub("[^;]*", function(num) -- prefix and suffix ; act as reset
local n = tonumber(num) or 0 -- e.g. \27[41;m is actually 41 followed by a reset
if n == 0 then 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] = 40
numbers[#numbers + 1] = 37 numbers[#numbers + 1] = 37
else elseif num then
numbers[#numbers + 1] = n numbers[#numbers + 1] = num
end
end end
end)
return numbers return numbers
end end

View File

@ -88,6 +88,7 @@ Robby # Forbidden Planet
Roomba # Under your couch... wait. Roomba # Under your couch... wait.
Rosie # The Jetsons Rosie # The Jetsons
Shakey # The first general-purpose mobile robot that could reason about its actions. Shakey # The first general-purpose mobile robot that could reason about its actions.
SHODAN # System Shock
Skynet # Terminator Skynet # Terminator
Space Core # Portal Space Core # Portal
SpiritedDusty # Contributor SpiritedDusty # Contributor

View File

@ -1,7 +1,6 @@
package li.cil.oc.client.renderer.markdown.segment package li.cil.oc.client.renderer.markdown.segment
import li.cil.oc.client.renderer.markdown.Document import li.cil.oc.client.renderer.markdown.{Document, MarkupFormat}
import li.cil.oc.client.renderer.markdown.MarkupFormat
import net.minecraft.client.gui.FontRenderer import net.minecraft.client.gui.FontRenderer
trait BasicTextSegment extends Segment { trait BasicTextSegment extends Segment {
@ -58,11 +57,21 @@ trait BasicTextSegment extends Segment {
while (pos < s.length) { while (pos < s.length) {
pos += 1 pos += 1
val width = stringWidth(s.take(pos), renderer) val width = stringWidth(s.take(pos), renderer)
if (width >= maxWidth) { val exceedsLineLength = width >= maxWidth
if (lastBreak > 0 || fullWidth <= maxLineWidth || s.exists(breaks.contains)) if (exceedsLineLength) {
if (maxWidth == maxLineWidth && fullWidth == maxLineWidth && !s.exists(breaks.contains)) return s.length val mayUseFullLine = maxWidth == maxLineWidth
else return lastBreak + 1 val canFitInLine = fullWidth <= maxLineWidth
else return pos - 1 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 if (pos < s.length && breaks.contains(s.charAt(pos))) lastBreak = pos
} }

View File

@ -81,7 +81,7 @@ class UnicodeAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
var width = 0 var width = 0
var end = 0 var end = 0
while (width < count) { while (width < count) {
width += FontUtils.wcwidth(value(end)) width += math.max(1, FontUtils.wcwidth(value(end)))
end += 1 end += 1
} }
if (end > 1) lua.pushString(value.substring(0, end - 1)) if (end > 1) lua.pushString(value.substring(0, end - 1))

View File

@ -53,7 +53,7 @@ class UnicodeAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) {
var width = 0 var width = 0
var end = 0 var end = 0
while (width < count) { while (width < count) {
width += FontUtils.wcwidth(value(end)) width += math.max(1, FontUtils.wcwidth(value(end)))
end += 1 end += 1
} }
if (end > 1) LuaValue.valueOf(value.substring(0, end - 1)) if (end > 1) LuaValue.valueOf(value.substring(0, end - 1))