The last cutting-edge commit out of the lot making the terminal a lot nicer
This commit is contained in:
+279
-261
@@ -66,7 +66,7 @@ function module.init()
|
|||||||
end
|
end
|
||||||
if depth == 4 then
|
if depth == 4 then
|
||||||
return {
|
return {
|
||||||
-- Closest colors to the 4 bit OC pallete
|
-- Closest colors to the 4 bit OC palette
|
||||||
-- Better than outright failure
|
-- Better than outright failure
|
||||||
["dark"] = {
|
["dark"] = {
|
||||||
[0] = 0x000000, -- black
|
[0] = 0x000000, -- black
|
||||||
@@ -146,27 +146,20 @@ function module.init()
|
|||||||
|
|
||||||
local cursor = { x = 1, y = 1, X = nil, Y = nil } -- X and Y are managed by ESC s and ESC u
|
local cursor = { x = 1, y = 1, X = nil, Y = nil } -- X and Y are managed by ESC s and ESC u
|
||||||
local printState = 0 -- 0:none 1:in ESC 2:in CSI
|
local printState = 0 -- 0:none 1:in ESC 2:in CSI
|
||||||
local color = {
|
local DEFAULT_FG = ANSIColorPalette["bright"][7] -- TODO make configurable
|
||||||
FG = ANSIColorPalette["bright"][7], BG = ANSIColorPalette["dark"][0],
|
local DEFAULT_BG = ANSIColorPalette["dark"][0]
|
||||||
fg = nil, bg = nil, reverse = false
|
local fg = DEFAULT_FG
|
||||||
}
|
local bg = DEFAULT_BG
|
||||||
color.fg = color.FG
|
local gpuFg = nil
|
||||||
color.bg = color.BG
|
local gpuBg = nil
|
||||||
|
local reverse = false
|
||||||
local current_codepoint = 0
|
local current_codepoint = 0
|
||||||
local bytes_remaining = 0
|
local bytes_remaining = 0
|
||||||
local seq = {}
|
local seq = {}
|
||||||
|
|
||||||
local writeBuf = {}
|
local writeBuf = ""
|
||||||
|
local bufStartX = 1
|
||||||
local function update_gpu_colors()
|
local bufStartY = 1
|
||||||
if color.reverse then
|
|
||||||
gpu.setForeground(color.bg)
|
|
||||||
gpu.setBackground(color.fg)
|
|
||||||
else
|
|
||||||
gpu.setForeground(color.fg)
|
|
||||||
gpu.setBackground(color.bg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local width, height = gpu.getResolution()
|
local width, height = gpu.getResolution()
|
||||||
|
|
||||||
@@ -174,29 +167,60 @@ function module.init()
|
|||||||
return width, height
|
return width, height
|
||||||
end
|
end
|
||||||
|
|
||||||
gpu.setForeground(color.fg)
|
local function update_gpu_colors()
|
||||||
gpu.setBackground(color.bg)
|
if reverse then
|
||||||
|
if gpuBg ~= fg then gpu.setBackground(fg) gpuBg = fg end
|
||||||
local function scroll()
|
if gpuFg ~= bg then gpu.setForeground(bg) gpuFg = bg end
|
||||||
if gpu.copy(1, 2, width, height - 1, 0, -1) then
|
else
|
||||||
gpu.setForeground(color.FG)
|
if gpuBg ~= bg then gpu.setBackground(bg) gpuBg = bg end
|
||||||
gpu.setBackground(color.BG)
|
if gpuFg ~= fg then gpu.setForeground(fg) gpuFg = fg end
|
||||||
gpu.fill(1, height, width, 1, " ")
|
|
||||||
gpu.setForeground(color.fg)
|
|
||||||
gpu.setBackground(color.bg)
|
|
||||||
cursor.y = height
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function scroll(n)
|
||||||
|
if n <= 0 then return end
|
||||||
|
if writeBuf ~= "" then
|
||||||
|
update_gpu_colors()
|
||||||
|
gpu.set(bufStartX, bufStartY, writeBuf)
|
||||||
|
writeBuf = ""
|
||||||
|
end
|
||||||
|
local keep = height - n
|
||||||
|
if keep > 0 then
|
||||||
|
gpu.copy(1, n + 1, width, keep, 0, -n)
|
||||||
|
end
|
||||||
|
if gpuBg ~= bg then
|
||||||
|
gpu.setBackground(bg)
|
||||||
|
gpuBg = bg
|
||||||
|
end
|
||||||
|
gpu.fill(1, keep + 1, width, n, " ")
|
||||||
|
cursor.y = cursor.y - n
|
||||||
|
if cursor.y > height then cursor.y = height end
|
||||||
|
if cursor.y < 1 then cursor.y = 1 end
|
||||||
|
end
|
||||||
|
|
||||||
local function check_wrap_and_scroll()
|
local function check_wrap_and_scroll()
|
||||||
if cursor.x > width then
|
if cursor.x > width then
|
||||||
cursor.x = 1
|
cursor.x = 1
|
||||||
cursor.y = cursor.y + 1
|
cursor.y = cursor.y + 1
|
||||||
end
|
end
|
||||||
|
scroll(cursor.y - height)
|
||||||
while cursor.y > height do
|
|
||||||
scroll()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- must be called before any operation that moves the cursor or changes colors!!!!!!!
|
||||||
|
local function flush()
|
||||||
|
if writeBuf == "" then return end
|
||||||
|
update_gpu_colors()
|
||||||
|
gpu.set(bufStartX, bufStartY, writeBuf)
|
||||||
|
writeBuf = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local function buf_append(s, len)
|
||||||
|
if writeBuf == "" then
|
||||||
|
bufStartX = cursor.x
|
||||||
|
bufStartY = cursor.y
|
||||||
|
end
|
||||||
|
writeBuf = writeBuf .. s
|
||||||
|
cursor.x = cursor.x + len
|
||||||
end
|
end
|
||||||
|
|
||||||
local function exec_csi()
|
local function exec_csi()
|
||||||
@@ -226,117 +250,84 @@ function module.init()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_param(idx, default)
|
-- TODO maybe use a lookup table like this?
|
||||||
if idx <= #params and params[idx] ~= nil then
|
-- local thing = things[op]
|
||||||
return params[idx]
|
-- if thing ~= nil then thing() end
|
||||||
end
|
|
||||||
return default
|
|
||||||
end
|
|
||||||
|
|
||||||
if op == 0x48 or op == 0x66 then
|
|
||||||
local row = get_param(1, 1)
|
|
||||||
local col = get_param(2, 1)
|
|
||||||
cursor.y = row
|
|
||||||
cursor.x = col
|
|
||||||
if cursor.x < 1 then cursor.x = 1 end
|
|
||||||
if cursor.y < 1 then cursor.y = 1 end
|
|
||||||
if cursor.x > width then cursor.x = width end
|
|
||||||
if cursor.y > height then cursor.y = height end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if op == 0x41 then
|
if op == 0x41 then
|
||||||
local n = get_param(1, 1)
|
flush()
|
||||||
cursor.y = cursor.y - n
|
cursor.y = cursor.y - (params[1] or 1)
|
||||||
if cursor.y < 1 then cursor.y = 1 end
|
if cursor.y < 1 then cursor.y = 1 end
|
||||||
return
|
elseif op == 0x42 then
|
||||||
end
|
flush()
|
||||||
|
cursor.y = cursor.y + (params[1] or 1)
|
||||||
if op == 0x42 then
|
|
||||||
local n = get_param(1, 1)
|
|
||||||
cursor.y = cursor.y + n
|
|
||||||
if cursor.y > height then cursor.y = height end
|
if cursor.y > height then cursor.y = height end
|
||||||
return
|
elseif op == 0x43 then
|
||||||
end
|
flush()
|
||||||
|
cursor.x = cursor.x + (params[1] or 1)
|
||||||
if op == 0x43 then
|
|
||||||
local n = get_param(1, 1)
|
|
||||||
cursor.x = cursor.x + n
|
|
||||||
if cursor.x > width then cursor.x = width end
|
if cursor.x > width then cursor.x = width end
|
||||||
return
|
elseif op == 0x44 then
|
||||||
end
|
flush()
|
||||||
|
cursor.x = cursor.x - (params[1] or 1)
|
||||||
if op == 0x44 then
|
|
||||||
local n = get_param(1, 1)
|
|
||||||
cursor.x = cursor.x - n
|
|
||||||
if cursor.x < 1 then cursor.x = 1 end
|
if cursor.x < 1 then cursor.x = 1 end
|
||||||
return
|
elseif op == 0x47 or op == 0x60 then
|
||||||
end
|
flush()
|
||||||
|
cursor.x = params[1] or 1
|
||||||
if op == 0x47 then
|
|
||||||
local col = get_param(1, 1)
|
|
||||||
cursor.x = col
|
|
||||||
if cursor.x < 1 then cursor.x = 1 end
|
if cursor.x < 1 then cursor.x = 1 end
|
||||||
if cursor.x > width then cursor.x = width end
|
if cursor.x > width then cursor.x = width end
|
||||||
return
|
elseif op == 0x48 or op == 0x66 then
|
||||||
end
|
flush()
|
||||||
|
cursor.y = params[1] or 1
|
||||||
if op == 0x4a then
|
cursor.x = params[2] or 1
|
||||||
local mode = get_param(1, 0)
|
if cursor.x < 1 then cursor.x = 1 end
|
||||||
|
if cursor.y < 1 then cursor.y = 1 end
|
||||||
|
if cursor.x > width then cursor.x = width end
|
||||||
|
if cursor.y > height then cursor.y = height end
|
||||||
|
elseif op == 0x4a then
|
||||||
|
flush()
|
||||||
|
local mode = params[1] or 0
|
||||||
|
update_gpu_colors()
|
||||||
if mode == 0 then
|
if mode == 0 then
|
||||||
update_gpu_colors()
|
gpu.fill(cursor.x, cursor.y, width - cursor.x + 1, 1, " ")
|
||||||
gpu.fill(cursor.x, cursor.y, width - cursor.x + 1, height - cursor.y + 1, " ")
|
if cursor.y < height then
|
||||||
|
gpu.fill(1, cursor.y + 1, width, height - cursor.y, " ")
|
||||||
|
end
|
||||||
elseif mode == 1 then
|
elseif mode == 1 then
|
||||||
update_gpu_colors()
|
if cursor.y > 1 then
|
||||||
gpu.fill(1, 1, cursor.x, cursor.y, " ")
|
gpu.fill(1, 1, width, cursor.y - 1, " ")
|
||||||
|
end
|
||||||
|
gpu.fill(1, cursor.y, cursor.x, 1, " ")
|
||||||
elseif mode == 2 then
|
elseif mode == 2 then
|
||||||
update_gpu_colors()
|
|
||||||
gpu.fill(1, 1, width, height, " ")
|
gpu.fill(1, 1, width, height, " ")
|
||||||
cursor.x = 1
|
cursor.x = 1
|
||||||
cursor.y = 1
|
cursor.y = 1
|
||||||
end
|
end
|
||||||
return
|
elseif op == 0x4b then
|
||||||
end
|
flush()
|
||||||
|
local mode = params[1] or 0
|
||||||
if op == 0x4b then
|
|
||||||
local mode = get_param(1, 0)
|
|
||||||
|
|
||||||
if mode == 0 then
|
|
||||||
update_gpu_colors()
|
update_gpu_colors()
|
||||||
|
if mode == 0 then
|
||||||
gpu.fill(cursor.x, cursor.y, width - cursor.x + 1, 1, " ")
|
gpu.fill(cursor.x, cursor.y, width - cursor.x + 1, 1, " ")
|
||||||
elseif mode == 1 then
|
elseif mode == 1 then
|
||||||
update_gpu_colors()
|
|
||||||
gpu.fill(1, cursor.y, cursor.x, 1, " ")
|
gpu.fill(1, cursor.y, cursor.x, 1, " ")
|
||||||
elseif mode == 2 then
|
elseif mode == 2 then
|
||||||
update_gpu_colors()
|
|
||||||
gpu.fill(1, cursor.y, width, 1, " ")
|
gpu.fill(1, cursor.y, width, 1, " ")
|
||||||
end
|
end
|
||||||
return
|
elseif op == 0x64 then
|
||||||
|
flush()
|
||||||
|
cursor.y = params[1] or 1
|
||||||
|
if cursor.y < 1 then
|
||||||
|
cursor.y = 1
|
||||||
end
|
end
|
||||||
|
if cursor.y > height then
|
||||||
if op == 0x60 then
|
cursor.y = height
|
||||||
local col = get_param(1, 1)
|
|
||||||
cursor.x = col
|
|
||||||
if cursor.x < 1 then cursor.x = 1 end
|
|
||||||
if cursor.x > width then cursor.x = width end
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
elseif op == 0x6d then
|
||||||
if op == 0x64 then
|
flush()
|
||||||
local row = get_param(1, 1)
|
|
||||||
cursor.y = row
|
|
||||||
if cursor.y < 1 then cursor.y = 1 end
|
|
||||||
if cursor.y > height then cursor.y = height end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if op == 0x6d then
|
|
||||||
local j = 1
|
local j = 1
|
||||||
local function parse_extended_color()
|
local function parse_extended_color()
|
||||||
local mode = get_param(j + 1, -1)
|
local mode = params[j + 1] or -1
|
||||||
if mode == 5 then
|
if mode == 5 then
|
||||||
local idx = get_param(j + 2, 0)
|
local idx = params[j + 2] or 0
|
||||||
j = j + 2
|
j = j + 2
|
||||||
if idx < 8 then
|
if idx < 8 then
|
||||||
return ANSIColorPalette["dark"][idx]
|
return ANSIColorPalette["dark"][idx]
|
||||||
@@ -353,9 +344,9 @@ function module.init()
|
|||||||
return (v << 16) | (v << 8) | v
|
return (v << 16) | (v << 8) | v
|
||||||
end
|
end
|
||||||
elseif mode == 2 then
|
elseif mode == 2 then
|
||||||
local r = get_param(j + 2, 0)
|
local r = params[j + 2] or 0
|
||||||
local g = get_param(j + 3, 0)
|
local g = params[j + 3] or 0
|
||||||
local b = get_param(j + 4, 0)
|
local b = params[j + 4] or 0
|
||||||
j = j + 4
|
j = j + 4
|
||||||
return (r << 16) | (g << 8) | b
|
return (r << 16) | (g << 8) | b
|
||||||
end
|
end
|
||||||
@@ -363,10 +354,9 @@ function module.init()
|
|||||||
end
|
end
|
||||||
|
|
||||||
if #params == 0 then
|
if #params == 0 then
|
||||||
color.reverse = false
|
reverse = false
|
||||||
color.fg = color.FG
|
fg = DEFAULT_FG
|
||||||
color.bg = color.BG
|
bg = DEFAULT_BG
|
||||||
update_gpu_colors()
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -374,188 +364,203 @@ function module.init()
|
|||||||
local p = params[j] or 0
|
local p = params[j] or 0
|
||||||
|
|
||||||
if p == 0 then
|
if p == 0 then
|
||||||
color.reverse = false
|
reverse = false
|
||||||
color.fg = color.FG
|
fg = DEFAULT_FG
|
||||||
color.bg = color.BG
|
bg = DEFAULT_BG
|
||||||
elseif p == 1 then
|
--elseif p == 1 then
|
||||||
elseif p == 2 then
|
--elseif p == 2 then
|
||||||
elseif p == 3 then
|
--elseif p == 3 then
|
||||||
elseif p == 4 then
|
--elseif p == 4 then
|
||||||
elseif p == 5 or p == 6 then
|
--elseif p == 5 or p == 6 then
|
||||||
elseif p == 7 then
|
elseif p == 7 then
|
||||||
color.reverse = true
|
reverse = true
|
||||||
elseif p == 8 then
|
elseif p == 8 then
|
||||||
color.fg = color.bg
|
fg = bg
|
||||||
elseif p == 9 then
|
--elseif p == 9 then
|
||||||
elseif p == 21 then
|
--elseif p == 21 then
|
||||||
elseif p == 22 then
|
--elseif p == 22 then
|
||||||
elseif p == 23 then
|
--elseif p == 23 then
|
||||||
elseif p == 24 then
|
--elseif p == 24 then
|
||||||
elseif p == 25 then
|
--elseif p == 25 then
|
||||||
elseif p == 27 then
|
elseif p == 27 then
|
||||||
color.reverse = false
|
reverse = false
|
||||||
elseif p == 28 then
|
elseif p == 28 then
|
||||||
color.fg = color.FG
|
fg = DEFAULT_FG
|
||||||
elseif p == 29 then
|
--elseif p == 29 then
|
||||||
elseif 30 <= p and p <= 37 then
|
elseif 30 <= p and p <= 37 then
|
||||||
color.fg = ANSIColorPalette["dark"][p - 30]
|
fg = ANSIColorPalette["dark"][p - 30]
|
||||||
elseif p == 38 then
|
elseif p == 38 then
|
||||||
local c = parse_extended_color()
|
local c = parse_extended_color()
|
||||||
if c then color.fg = c end
|
if c then
|
||||||
|
fg = c
|
||||||
|
end
|
||||||
elseif p == 39 then
|
elseif p == 39 then
|
||||||
color.fg = color.FG
|
fg = DEFAULT_FG
|
||||||
elseif 40 <= p and p <= 47 then
|
elseif 40 <= p and p <= 47 then
|
||||||
color.bg = ANSIColorPalette["dark"][p - 40]
|
bg = ANSIColorPalette["dark"][p - 40]
|
||||||
elseif p == 48 then
|
elseif p == 48 then
|
||||||
local c = parse_extended_color()
|
local c = parse_extended_color()
|
||||||
if c then color.bg = c end
|
if c then
|
||||||
|
bg = c
|
||||||
|
end
|
||||||
elseif p == 49 then
|
elseif p == 49 then
|
||||||
color.bg = color.BG
|
bg = DEFAULT_BG
|
||||||
elseif p == 58 then
|
|
||||||
parse_extended_color()
|
|
||||||
elseif p == 59 then
|
|
||||||
elseif 90 <= p and p <= 97 then
|
elseif 90 <= p and p <= 97 then
|
||||||
color.fg = ANSIColorPalette["bright"][p - 90]
|
fg = ANSIColorPalette["bright"][p - 90]
|
||||||
elseif 100 <= p and p <= 107 then
|
elseif 100 <= p and p <= 107 then
|
||||||
color.bg = ANSIColorPalette["bright"][p - 100]
|
bg = ANSIColorPalette["bright"][p - 100]
|
||||||
end
|
end
|
||||||
|
|
||||||
j = j + 1
|
j = j + 1
|
||||||
end
|
end
|
||||||
update_gpu_colors()
|
elseif op == 0x73 then
|
||||||
return
|
flush()
|
||||||
end
|
|
||||||
|
|
||||||
if op == 0x73 then
|
|
||||||
cursor.X = cursor.x
|
cursor.X = cursor.x
|
||||||
cursor.Y = cursor.y
|
cursor.Y = cursor.y
|
||||||
return
|
elseif op == 0x75 then
|
||||||
end
|
flush()
|
||||||
|
|
||||||
if op == 0x75 then
|
|
||||||
if cursor.X and cursor.Y then
|
if cursor.X and cursor.Y then
|
||||||
cursor.x = cursor.X
|
cursor.x = cursor.X
|
||||||
cursor.y = cursor.Y
|
cursor.y = cursor.Y
|
||||||
if cursor.x < 1 then cursor.x = 1 end
|
if cursor.x < 1 then
|
||||||
if cursor.y < 1 then cursor.y = 1 end
|
cursor.x = 1
|
||||||
if cursor.x > width then cursor.x = width end
|
end
|
||||||
if cursor.y > height then cursor.y = height end
|
if cursor.y < 1 then
|
||||||
|
cursor.y = 1
|
||||||
|
end
|
||||||
|
if cursor.x > width then
|
||||||
|
cursor.x = width
|
||||||
|
end
|
||||||
|
if cursor.y > height then
|
||||||
|
cursor.y = height
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function _G._PUBLIC.terminal.writec(byte)
|
function _G._PUBLIC.terminal.write(text)
|
||||||
|
text = tostring(text)
|
||||||
|
local len = #text
|
||||||
|
local i = 1
|
||||||
|
|
||||||
|
while i <= len do
|
||||||
|
local byte = string.byte(text, i)
|
||||||
|
|
||||||
if byte == 0x1b then
|
if byte == 0x1b then
|
||||||
_PUBLIC.terminal.flush()
|
|
||||||
printState = 1
|
printState = 1
|
||||||
seq = {}
|
seq = {}
|
||||||
return
|
i = i + 1
|
||||||
end
|
elseif printState == 1 then
|
||||||
|
printState = byte == 0x5b and 2 or 0
|
||||||
if printState == 1 then
|
i = i + 1
|
||||||
if byte == 0x5b then
|
elseif printState == 2 then
|
||||||
printState = 2
|
|
||||||
else
|
|
||||||
printState = 0
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if printState == 2 then
|
|
||||||
table.insert(seq, byte)
|
table.insert(seq, byte)
|
||||||
if 0x40 <= byte and byte <= 0x7e then
|
if 0x40 <= byte and byte <= 0x7e then
|
||||||
exec_csi()
|
exec_csi()
|
||||||
printState = 0
|
printState = 0
|
||||||
seq = {}
|
seq = {}
|
||||||
end
|
end
|
||||||
return
|
i = i + 1
|
||||||
end
|
elseif byte == 0xa then
|
||||||
|
flush()
|
||||||
if byte == 0xa then
|
|
||||||
_PUBLIC.terminal.flush()
|
|
||||||
cursor.y = cursor.y + 1
|
cursor.y = cursor.y + 1
|
||||||
cursor.x = 1
|
cursor.x = 1
|
||||||
check_wrap_and_scroll()
|
check_wrap_and_scroll()
|
||||||
return
|
bufStartX = cursor.x
|
||||||
end
|
bufStartY = cursor.y
|
||||||
|
i = i + 1
|
||||||
if byte == 0xd then
|
elseif byte == 0xd then
|
||||||
_PUBLIC.terminal.flush()
|
flush()
|
||||||
cursor.x = 1
|
cursor.x = 1
|
||||||
return
|
bufStartX = 1
|
||||||
end
|
bufStartY = cursor.y
|
||||||
|
i = i + 1
|
||||||
if byte == 0x8 then
|
elseif byte == 0x8 then
|
||||||
_PUBLIC.terminal.flush()
|
flush()
|
||||||
if cursor.x > 1 then
|
if cursor.x > 1 then cursor.x = cursor.x - 1 end
|
||||||
cursor.x = cursor.x - 1
|
i = i + 1
|
||||||
end
|
elseif byte == 0x9 then
|
||||||
return
|
flush()
|
||||||
end
|
|
||||||
|
|
||||||
if byte == 0x9 then
|
|
||||||
_PUBLIC.terminal.flush()
|
|
||||||
cursor.x = ((cursor.x - 1) // 8) * 8 + 9
|
cursor.x = ((cursor.x - 1) // 8) * 8 + 9
|
||||||
if cursor.x < 1 then cursor.x = 1 end
|
|
||||||
if cursor.x > width then cursor.x = width end
|
if cursor.x > width then cursor.x = width end
|
||||||
return
|
i = i + 1
|
||||||
|
elseif byte >= 0x20 and byte <= 0x7E then
|
||||||
|
local j = i + 1
|
||||||
|
while j <= len do
|
||||||
|
local b = string.byte(text, j)
|
||||||
|
if b < 0x20 or b > 0x7E then break end
|
||||||
|
j = j + 1
|
||||||
end
|
end
|
||||||
|
local runLen = j - i
|
||||||
|
local space = width - cursor.x + 1
|
||||||
|
|
||||||
if byte >= 0x20 and byte <= 0x7F then
|
if runLen <= space then
|
||||||
table.insert(writeBuf, string.char(byte))
|
buf_append(text:sub(i, j - 1), runLen)
|
||||||
cursor.x = cursor.x + 1
|
|
||||||
if cursor.x > width then
|
if cursor.x > width then
|
||||||
_PUBLIC.terminal.flush()
|
flush()
|
||||||
end
|
cursor.x = 1
|
||||||
|
cursor.y = cursor.y + 1
|
||||||
check_wrap_and_scroll()
|
check_wrap_and_scroll()
|
||||||
|
bufStartX = cursor.x
|
||||||
|
bufStartY = cursor.y
|
||||||
|
end
|
||||||
|
i = j
|
||||||
|
else
|
||||||
|
buf_append(text:sub(i, i + space - 1), space)
|
||||||
|
flush()
|
||||||
|
cursor.x = 1
|
||||||
|
cursor.y = cursor.y + 1
|
||||||
|
check_wrap_and_scroll()
|
||||||
|
bufStartX = cursor.x
|
||||||
|
bufStartY = cursor.y
|
||||||
|
i = i + space
|
||||||
|
end
|
||||||
elseif byte >= 0xC2 and byte <= 0xDF then
|
elseif byte >= 0xC2 and byte <= 0xDF then
|
||||||
current_codepoint = (byte & 0x1F)
|
current_codepoint = (byte & 0x1F)
|
||||||
bytes_remaining = 1
|
bytes_remaining = 1
|
||||||
|
i = i + 1
|
||||||
elseif byte >= 0xE0 and byte <= 0xEF then
|
elseif byte >= 0xE0 and byte <= 0xEF then
|
||||||
current_codepoint = (byte & 0x0F)
|
current_codepoint = (byte & 0x0F)
|
||||||
bytes_remaining = 2
|
bytes_remaining = 2
|
||||||
|
i = i + 1
|
||||||
elseif byte >= 0xF0 and byte <= 0xF7 then
|
elseif byte >= 0xF0 and byte <= 0xF7 then
|
||||||
current_codepoint = (byte & 0x07)
|
current_codepoint = (byte & 0x07)
|
||||||
bytes_remaining = 3
|
bytes_remaining = 3
|
||||||
|
i = i + 1
|
||||||
elseif byte >= 0x80 and byte <= 0xBF and bytes_remaining > 0 then
|
elseif byte >= 0x80 and byte <= 0xBF and bytes_remaining > 0 then
|
||||||
current_codepoint = (current_codepoint << 6) | (byte & 0x3F)
|
current_codepoint = (current_codepoint << 6) | (byte & 0x3F)
|
||||||
bytes_remaining = bytes_remaining - 1
|
bytes_remaining = bytes_remaining - 1
|
||||||
if bytes_remaining == 0 then
|
if bytes_remaining == 0 then
|
||||||
table.insert(writeBuf, utf8.char(current_codepoint))
|
buf_append(unicode.char(current_codepoint), 1)
|
||||||
cursor.x = cursor.x + 1
|
|
||||||
if cursor.x > width then
|
if cursor.x > width then
|
||||||
_PUBLIC.terminal.flush()
|
flush()
|
||||||
end
|
cursor.x = 1
|
||||||
|
cursor.y = cursor.y + 1
|
||||||
check_wrap_and_scroll()
|
check_wrap_and_scroll()
|
||||||
|
bufStartX = cursor.x
|
||||||
|
bufStartY = cursor.y
|
||||||
|
end
|
||||||
current_codepoint = 0
|
current_codepoint = 0
|
||||||
end
|
end
|
||||||
|
i = i + 1
|
||||||
else
|
else
|
||||||
current_codepoint = 0
|
current_codepoint = 0
|
||||||
bytes_remaining = 0
|
bytes_remaining = 0
|
||||||
|
i = i + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function _G._PUBLIC.terminal.write(text)
|
|
||||||
text = tostring(text)
|
|
||||||
for i = 1, #text do
|
|
||||||
_PUBLIC.terminal.writec(string.byte(text, i))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function _G._PUBLIC.terminal.clear()
|
|
||||||
update_gpu_colors()
|
|
||||||
gpu.fill(1, 1, width, height, " ")
|
|
||||||
writeBuf = {}
|
|
||||||
cursor.x = 1
|
|
||||||
cursor.y = 1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function _G._PUBLIC.terminal.flush()
|
function _G._PUBLIC.terminal.flush()
|
||||||
if #writeBuf == 0 then return end
|
flush()
|
||||||
|
end
|
||||||
|
|
||||||
|
function _G._PUBLIC.terminal.clear()
|
||||||
|
flush()
|
||||||
update_gpu_colors()
|
update_gpu_colors()
|
||||||
gpu.set(cursor.x - #writeBuf, cursor.y, table.concat(writeBuf))
|
gpu.fill(1, 1, width, height, " ")
|
||||||
writeBuf = {}
|
cursor.x = 1
|
||||||
|
cursor.y = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
function _G.print(...)
|
function _G.print(...)
|
||||||
@@ -607,48 +612,65 @@ function module.init()
|
|||||||
|
|
||||||
local cur = unicode.len(text) + 1
|
local cur = unicode.len(text) + 1
|
||||||
if options.prefix then _PUBLIC.terminal.write(options.prefix) end
|
if options.prefix then _PUBLIC.terminal.write(options.prefix) end
|
||||||
_G._PUBLIC.terminal.flush()
|
flush()
|
||||||
local startX, startY = cursor.x, cursor.y
|
local startX, startY = cursor.x, cursor.y
|
||||||
local fg, bg = gpu.getForeground(), gpu.getBackground()
|
|
||||||
local cursorBlink = true
|
local cursorBlink = true
|
||||||
|
|
||||||
local function checkScroll(y)
|
local function checkScroll(y)
|
||||||
for i=1,y-height do
|
if y > height then
|
||||||
scrollDown()
|
local n = y - height
|
||||||
startY=startY-1
|
scroll(n)
|
||||||
|
startY = startY - n
|
||||||
|
y = height
|
||||||
end
|
end
|
||||||
return math.min(y,height)
|
return y
|
||||||
end
|
end
|
||||||
|
|
||||||
local function set(index, character, invertedColors) -- HACK: Currently, this will uncensor all spaces in the inputted text.
|
local function set(index, character, invertedColors) -- HACK: Currently, this will uncensor all spaces in the inputted text.
|
||||||
if character == nil or character == "" then return end
|
if character == nil or character == "" then return end
|
||||||
if options.censor then
|
if options.censor then
|
||||||
character = character:gsub("[^ ]", options.censor)
|
character = character:gsub("[^ ]", options.censor)
|
||||||
end
|
end
|
||||||
if invertedColors then
|
if invertedColors then
|
||||||
gpu.setForeground(bg)
|
if gpuFg ~= bg then gpu.setForeground(bg); gpuFg = bg end
|
||||||
gpu.setBackground(fg)
|
if gpuBg ~= fg then gpu.setBackground(fg); gpuBg = fg end
|
||||||
else
|
else
|
||||||
gpu.setForeground(fg)
|
if gpuFg ~= fg then gpu.setForeground(fg); gpuFg = fg end
|
||||||
gpu.setBackground(bg)
|
if gpuBg ~= bg then gpu.setBackground(bg); gpuBg = bg end
|
||||||
end
|
end
|
||||||
index = startX + index - 1
|
index = startX + index - 1
|
||||||
local setX, setY = (index-1)%width+1, startY+((index-1)//width+1)-1
|
local setX = (index - 1) % width + 1
|
||||||
|
local setY = startY + ((index - 1) // width)
|
||||||
setY = checkScroll(setY)
|
setY = checkScroll(setY)
|
||||||
gpu.set(setX,setY,unicode.sub(character,1,width-setX+1))
|
local firstLen = width - setX + 1
|
||||||
for i=1,math.ceil((#character+setX-1)/width)+1 do
|
gpu.set(setX, setY, unicode.sub(character, 1, firstLen))
|
||||||
gpu.set(1,setY+i,unicode.sub(character,2-setX+i*width,width+i*width-setX))
|
local charLen = unicode.len(character)
|
||||||
|
if charLen > firstLen then
|
||||||
|
local offset = firstLen + 1
|
||||||
|
while offset <= charLen do
|
||||||
|
setY = setY + 1
|
||||||
setY = checkScroll(setY)
|
setY = checkScroll(setY)
|
||||||
|
local segEnd = offset + width - 1
|
||||||
|
gpu.set(1, setY, unicode.sub(character, offset, segEnd))
|
||||||
|
offset = segEnd + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function strDef(a, b)
|
local function strDef(a, b)
|
||||||
if #a == 0 then return b end
|
if #a == 0 then return b end
|
||||||
return a
|
return a
|
||||||
end
|
end
|
||||||
local function curPos(cur)
|
local function curPos(c)
|
||||||
return unicode.wlen(unicode.sub(text,1,cur-1))+1
|
return unicode.wlen(unicode.sub(text, 1, c - 1)) + 1
|
||||||
end
|
end
|
||||||
local function add(chr)
|
local function add(chr)
|
||||||
if type(chr)~="string" or #chr==0 then return end
|
if type(chr) ~= "string" or #chr == 0 then
|
||||||
if unicode.len(text)>=options.maxChars then return end
|
return
|
||||||
|
end
|
||||||
|
if unicode.len(text) >= options.maxChars then
|
||||||
|
return
|
||||||
|
end
|
||||||
if options.maxChars < math.huge then
|
if options.maxChars < math.huge then
|
||||||
chr = unicode.sub(chr, 1, options.maxChars - unicode.len(text))
|
chr = unicode.sub(chr, 1, options.maxChars - unicode.len(text))
|
||||||
end
|
end
|
||||||
@@ -710,10 +732,7 @@ function module.init()
|
|||||||
local function isLine(chr)
|
local function isLine(chr)
|
||||||
return chr == "\n" or chr == "\r"
|
return chr == "\n" or chr == "\r"
|
||||||
end
|
end
|
||||||
--[[ gpu.set(startX,startY,unicode.sub(text,1,width-startX))
|
|
||||||
for i=1,(#text+startX)//width-1 do
|
|
||||||
gpu.set(startX,startY+i,unicode.sub(text,1+i*width,width-startX+i*width))
|
|
||||||
end ]]
|
|
||||||
set(1, text, false)
|
set(1, text, false)
|
||||||
set(curPos(cur), " ", true)
|
set(curPos(cur), " ", true)
|
||||||
|
|
||||||
@@ -724,7 +743,6 @@ function module.init()
|
|||||||
set(curPos(cur), " ", true)
|
set(curPos(cur), " ", true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
local args = { event.pull("key_down", "clipboard", 0.5) }
|
local args = { event.pull("key_down", "clipboard", 0.5) }
|
||||||
local ctrlDown = _PUBLIC.keyboard.getCtrlDown()
|
local ctrlDown = _PUBLIC.keyboard.getCtrlDown()
|
||||||
@@ -776,7 +794,7 @@ function module.init()
|
|||||||
end
|
end
|
||||||
elseif args and args[1] == "clipboard" then
|
elseif args and args[1] == "clipboard" then
|
||||||
local clip = args[3]
|
local clip = args[3]
|
||||||
if not args[3] then goto continue end
|
if not clip then goto continue end
|
||||||
while isLine(unicode.sub(clip, 1, 1)) do clip = unicode.sub(clip, 2) end
|
while isLine(unicode.sub(clip, 1, 1)) do clip = unicode.sub(clip, 2) end
|
||||||
while isLine(unicode.sub(clip, -1)) do clip = unicode.sub(clip, 1, -2) end
|
while isLine(unicode.sub(clip, -1)) do clip = unicode.sub(clip, 1, -2) end
|
||||||
add(clip)
|
add(clip)
|
||||||
@@ -793,7 +811,6 @@ function module.init()
|
|||||||
table.remove(readHistory[options.readHistoryType], #readHistory[options.readHistoryType])
|
table.remove(readHistory[options.readHistoryType], #readHistory[options.readHistoryType])
|
||||||
end
|
end
|
||||||
if historyIdx < #readHistory[options.readHistoryType] then
|
if historyIdx < #readHistory[options.readHistoryType] then
|
||||||
-- table.remove(readHistory[options.readHistoryType],historyIdx)
|
|
||||||
table.insert(readHistory[options.readHistoryType], text)
|
table.insert(readHistory[options.readHistoryType], text)
|
||||||
end
|
end
|
||||||
while #readHistory[options.readHistoryType] > 50 do
|
while #readHistory[options.readHistoryType] > 50 do
|
||||||
@@ -803,8 +820,9 @@ function module.init()
|
|||||||
|
|
||||||
cursor.x = 1
|
cursor.x = 1
|
||||||
cursor.y = cursor.y + math.ceil((unicode.wlen(text) + startX - 1) / width)
|
cursor.y = cursor.y + math.ceil((unicode.wlen(text) + startX - 1) / width)
|
||||||
if cursor.y>height then scroll() end
|
if cursor.y > height then
|
||||||
|
scroll(cursor.y - height)
|
||||||
|
end
|
||||||
return text
|
return text
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user