diff --git a/src/main/resources/assets/opencomputers/loot/openos/bin/cat.lua b/src/main/resources/assets/opencomputers/loot/openos/bin/cat.lua index fafe5f0e9..fcaeb88e8 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/bin/cat.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/bin/cat.lua @@ -7,7 +7,7 @@ if #args == 0 then args = {"-"} end -local input_method, input_param = "read", 2048 +local input_method, input_param = "read", require("tty").window.width for i = 1, #args do local arg = shell.resolve(args[i]) diff --git a/src/main/resources/assets/opencomputers/loot/openos/bin/more.lua b/src/main/resources/assets/opencomputers/loot/openos/bin/more.lua index dfc3d55f6..687a5ed17 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/bin/more.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/bin/more.lua @@ -1,11 +1,7 @@ +local buffer = require("buffer") local keyboard = require("keyboard") local shell = require("shell") -local term = require("term") -- TODO use tty and cursor position instead of global area and gpu -local text = require("text") - -if not io.output().tty then - return loadfile(shell.resolve("cat", "lua"), "bt", _G)(...) -end +local tty = require("tty") local args = shell.parse(...) if #args > 1 then @@ -13,55 +9,49 @@ if #args > 1 then io.write("- or no args reads stdin\n") return 1 end -local arg = args[1] or "-" -local file, reason -if arg == "-" then - file, reason = io.stdin, "this process has no stdin" -else - file, reason = io.open(shell.resolve(arg)) -end -if not file then - io.stderr:write(reason,'\n') - return 1 + +local function clear_line() + tty.window.x = 1 -- move cursor to start of line + io.write("\27[2K") -- clear line end -local line = nil -local function readlines(num) - local _, _, w, h = term.getGlobalArea() - num = num or (h - 1) - for _ = 1, num do - if not line then - line = file:read("*l") - if not line then -- eof - return nil +if io.output().tty then + io.write("\27[2J\27[H") + + local intercept_active = true + local original_stream = io.stdout.stream + local custom_stream = setmetatable({ + scroll = function(...) + local _, height, _, _, _, y = tty.getViewport() + local lines_below = height - y + if intercept_active and lines_below < 1 then + intercept_active = false + original_stream.scroll(-lines_below) -- if zero no scroll action is made [good] + tty.setCursor(1, height) -- move to end + clear_line() + io.write(":") -- status + local _, _, _, code = original_stream:pull(nil, "key_down") -- nil timeout is math.huge + if code == keyboard.keys.q then + clear_line() + os.exit(1) -- abort + elseif code == keyboard.keys["end"] then + io.stdout.stream.scroll = nil -- remove handler + elseif code == keyboard.keys.space or code == keyboard.keys.pageDown then + io.write("\27[2J\27[H") -- clear whole screen, get new page drawn; move cursor to 1,1 + elseif code == keyboard.keys.enter or code == keyboard.keys.down then + clear_line() -- remove status bar + original_stream.scroll(1) -- move everything up one + tty.setCursor(1, height - 1) + end + intercept_active = true end + return original_stream.scroll(...) end - local wrapped - wrapped, line = text.wrap(text.detab(line), w, w) - io.write(wrapped,"\n") - end - term.setCursor(1, h) - term.write(":") - return true + }, {__index=original_stream}) + + local custom_output_buffer = buffer.new("w", custom_stream) + custom_output_buffer:setvbuf("no") + io.output(custom_output_buffer) end -while true do - term.clear() - if not readlines() then - return - end - while true do - local _, _, _, code = term.pull("key_down") - if code == keyboard.keys.q then - term.clearLine() - return - elseif code == keyboard.keys.space or code == keyboard.keys.pageDown then - break - elseif code == keyboard.keys.enter or code == keyboard.keys.down then - term.clearLine() - if not readlines(1) then - return - end - end - end -end +return loadfile(shell.resolve("cat", "lua"))(...) diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/term.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/term.lua index 3dd0b3642..77e63253b 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/term.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/term.lua @@ -248,5 +248,12 @@ function term.bind(gpu, window) return as_window(window, tty.bind, gpu) end -return term +function term.scroll(...) + if io.stdout.tty then + return io.stdout.stream.scroll(...) + end +end +term.internal.run_in_window = as_window + +return term diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/thread.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/thread.lua index 5c62cee07..2e155a423 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/thread.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/thread.lua @@ -60,17 +60,18 @@ function thread.waitForAll(threads, timeout) end local box_thread = {} -local box_thread_handle = {close = thread.waitForAll} +local box_thread_list = {close = thread.waitForAll} -local function get_box_thread_handle(handles, bCreate) +local function get_process_threads(proc, bCreate) + local handles = proc.data.handles for _,next_handle in ipairs(handles) do - local btm_mt = getmetatable(next_handle) - if btm_mt and btm_mt.__index == box_thread_handle then + local handle_mt = getmetatable(next_handle) + if handle_mt and handle_mt.__index == box_thread_list then return next_handle end end if bCreate then - local btm = setmetatable({}, {__index = box_thread_handle}) + local btm = setmetatable({}, {__index = box_thread_list}) table.insert(handles, btm) return btm end @@ -126,10 +127,10 @@ function box_thread:attach(parent) if mt.attached == proc then return self end -- already attached if mt.attached then - local prev_btHandle = assert(get_box_thread_handle(mt.attached.data.handles), "thread panic: no thread handle") - for i,h in ipairs(prev_btHandle) do - if h == self then - table.remove(prev_btHandle, i) + local prev_threads = assert(get_process_threads(mt.attached), "thread panic: no thread handle") + for index,t_in_list in ipairs(prev_threads) do + if t_in_list == self then + table.remove(prev_threads, index) break end end @@ -141,9 +142,9 @@ function box_thread:attach(parent) -- attach to parent or the current process mt.attached = proc - -- this process may not have a box_thread manager handle - local btHandle = get_box_thread_handle(proc.data.handles, true) - table.insert(btHandle, self) + -- this process may not have a box_thread list + local threads = get_process_threads(proc, true) + table.insert(threads, self) -- register on the new parent if waiting_handler then -- event-waiting @@ -158,7 +159,7 @@ function thread.current() local thread_root while proc do if thread_root then - for _,bt in ipairs(get_box_thread_handle(proc.data.handles) or {}) do + for _,bt in ipairs(get_process_threads(proc) or {}) do if bt.pco.root == thread_root then return bt end @@ -287,10 +288,10 @@ function thread.create(fp, ...) if t:status() == "dead" then return end - local htm = get_box_thread_handle(mt.attached.data.handles) - for _,ht in ipairs(htm) do - if ht == t then - table.remove(htm, _) + local threads = get_process_threads(mt.attached) + for index,t_in_list in ipairs(threads) do + if t_in_list == t then + table.remove(threads, index) break end end diff --git a/src/main/resources/assets/opencomputers/lua/machine.lua b/src/main/resources/assets/opencomputers/lua/machine.lua index cb0069831..06f07a70f 100644 --- a/src/main/resources/assets/opencomputers/lua/machine.lua +++ b/src/main/resources/assets/opencomputers/lua/machine.lua @@ -577,7 +577,7 @@ do checkArg(3, repl, "number", "string", "function", "table") checkArg(4, n, "number", "nil") - if #s < SHORT_STRING or type(repl) == "function" then + if #s < SHORT_STRING then return string_gsub(s, pattern, repl, n) end