mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-17 19:25:20 -04:00
rework more and less. simpler code, works with long lines payonel 09/04/2018 10:38 AM
This commit is contained in:
parent
4e5188da08
commit
bb1c97edb4
@ -1,10 +1,11 @@
|
|||||||
local keyboard = require("keyboard")
|
local keys = require("keyboard").keys
|
||||||
local shell = require("shell")
|
local shell = require("shell")
|
||||||
|
local unicode = require("unicode")
|
||||||
local term = require("term") -- using term for negative scroll feature
|
local term = require("term") -- using term for negative scroll feature
|
||||||
|
|
||||||
local args = shell.parse(...)
|
local args, ops = shell.parse(...)
|
||||||
if #args > 1 then
|
if #args > 1 then
|
||||||
io.write("Usage: less <filename>\n")
|
io.write("Usage: ", os.getenv("_"):match("/([^/]+)%.lua$"), " <filename>\n")
|
||||||
io.write("- or no args reads stdin\n")
|
io.write("- or no args reads stdin\n")
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
@ -14,86 +15,127 @@ if not io.output().tty then
|
|||||||
return os.execute(cat_cmd)
|
return os.execute(cat_cmd)
|
||||||
end
|
end
|
||||||
|
|
||||||
term.clear()
|
|
||||||
|
|
||||||
local preader = io.popen(cat_cmd)
|
local preader = io.popen(cat_cmd)
|
||||||
local buffer = setmetatable({}, {__index = function(tbl, index)
|
local scrollback = not ops.noback and {}
|
||||||
if type(index) ~= "number" or index < 1 then return end
|
local bottom = 0
|
||||||
while #tbl < index do
|
|
||||||
local line = preader:read()
|
|
||||||
if not line then return end
|
|
||||||
table.insert(tbl, line)
|
|
||||||
end
|
|
||||||
return tbl[index]
|
|
||||||
end})
|
|
||||||
|
|
||||||
local index = 1
|
local width, height = term.getViewport()
|
||||||
|
|
||||||
local _, height = term.getViewport()
|
local function split(full_line)
|
||||||
local status = ":"
|
local index = 1
|
||||||
|
local parts = {}
|
||||||
local function goback(n)
|
while true do
|
||||||
n = math.min(index - height, n)
|
local sub = full_line:sub(index)
|
||||||
if n <= 0 then return end -- make no back scroll, we're at the top
|
-- checking #sub < width first is faster, save a unicode call
|
||||||
term.scroll(-n)
|
if #sub < width or unicode.wlen(sub) <= width then
|
||||||
index = index - n
|
parts[#parts + 1] = sub
|
||||||
for y = 1, math.min(height - 1, n) do
|
break
|
||||||
term.setCursor(1, y)
|
end
|
||||||
print(buffer[index - height + y])
|
parts[#parts + 1] = unicode.wtrunc(sub, width + 1)
|
||||||
end
|
index = index + #parts[#parts]
|
||||||
term.setCursor(1, height)
|
if index > #full_line then
|
||||||
end
|
|
||||||
|
|
||||||
local function goforward(n)
|
|
||||||
if not buffer[index] then return end -- nothing to do
|
|
||||||
for test_index = index, index + n do
|
|
||||||
if not buffer[test_index] then
|
|
||||||
n = math.min(n, test_index - index)
|
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return parts
|
||||||
term.clearLine()
|
|
||||||
term.scroll(n)
|
|
||||||
if n >= height then
|
|
||||||
index = index + (n - height) + 1
|
|
||||||
n = height - 1
|
|
||||||
end
|
|
||||||
term.setCursor(1, height - n)
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function scan(num)
|
||||||
|
local result = {}
|
||||||
|
local line_count = 0
|
||||||
|
for i=1, num do
|
||||||
|
local lines = {}
|
||||||
|
if scrollback and (bottom + i) <= #scrollback then
|
||||||
|
lines = {scrollback[bottom + i]}
|
||||||
|
else
|
||||||
|
local full_line = preader:read()
|
||||||
|
if not full_line then preader:close() break end
|
||||||
|
-- with buffering, we can buffer ahead too, and read more smoothly
|
||||||
|
local buffering = false
|
||||||
|
for _,line in ipairs(split(full_line)) do
|
||||||
|
if not buffering then
|
||||||
|
lines[#lines + 1] = line
|
||||||
|
end
|
||||||
|
if scrollback then
|
||||||
|
buffering = true
|
||||||
|
scrollback[#scrollback + 1] = line
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _,line in ipairs(lines) do
|
||||||
|
result[#result + 1] = line
|
||||||
|
line_count = line_count + 1
|
||||||
|
if #result > height then
|
||||||
|
table.remove(result, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if line_count >= num then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return result, line_count
|
||||||
|
end
|
||||||
|
|
||||||
|
local function status()
|
||||||
|
io.write(":")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function goback(n)
|
||||||
|
if not scrollback then return end
|
||||||
|
local current_top = bottom - height + 1
|
||||||
|
n = math.min(current_top, n)
|
||||||
|
if n < 1 then return end
|
||||||
|
local top = current_top - n + 1
|
||||||
|
term.scroll(-n)
|
||||||
|
term.setCursor(1, 1)
|
||||||
|
for i=1, n do
|
||||||
|
if i >= height then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
print(scrollback[top + i - 1])
|
||||||
|
end
|
||||||
|
term.setCursor(1, height)
|
||||||
|
bottom = bottom - n
|
||||||
|
end
|
||||||
|
|
||||||
|
local function goforward(n)
|
||||||
|
term.clearLine()
|
||||||
|
local update, line_count = scan(n)
|
||||||
|
for _,line in ipairs(update) do
|
||||||
|
print(line)
|
||||||
|
end
|
||||||
|
if ops.noback and line_count < n then
|
||||||
|
os.exit()
|
||||||
|
end
|
||||||
|
bottom = bottom + line_count
|
||||||
|
end
|
||||||
|
|
||||||
|
goforward(height - 1)
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
local _, y = term.getCursor()
|
term.clearLine()
|
||||||
local print_next_line = true
|
status()
|
||||||
if y == height then
|
local e, _, _, code = term.pull()
|
||||||
print_next_line = false
|
if e == "interrupted" then
|
||||||
term.clearLine()
|
break
|
||||||
io.write(status)
|
elseif e == "key_down" then
|
||||||
local _, _, _, code = term.pull("key_down")
|
if code == keys.q then
|
||||||
if code == keyboard.keys.q then
|
|
||||||
term.clearLine()
|
term.clearLine()
|
||||||
os.exit(1) -- abort
|
os.exit() -- abort
|
||||||
elseif code == keyboard.keys["end"] then
|
elseif code == keys["end"] then
|
||||||
print_next_line = goforward(math.huge)
|
goforward(math.huge)
|
||||||
elseif code == keyboard.keys.space or code == keyboard.keys.pageDown then
|
elseif code == keys.space or code == keys.pageDown then
|
||||||
print_next_line = goforward(height - 1)
|
goforward(height - 1)
|
||||||
elseif code == keyboard.keys.enter or code == keyboard.keys.down then
|
elseif code == keys.enter or code == keys.down then
|
||||||
print_next_line = goforward(1)
|
goforward(1)
|
||||||
elseif code == keyboard.keys.up then
|
elseif code == keys.up then
|
||||||
goback(1)
|
goback(1)
|
||||||
elseif code == keyboard.keys.pageUp then
|
elseif code == keys.pageUp then
|
||||||
goback(height - 1)
|
goback(height - 1)
|
||||||
end
|
elseif code == keys.home then
|
||||||
end
|
goback(math.huge)
|
||||||
if print_next_line then
|
|
||||||
local line = buffer[index]
|
|
||||||
if line then
|
|
||||||
print(line)
|
|
||||||
index = index + 1
|
|
||||||
else
|
|
||||||
term.setCursor(1, height)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,44 +1,2 @@
|
|||||||
local keyboard = require("keyboard")
|
|
||||||
local shell = require("shell")
|
local shell = require("shell")
|
||||||
local term = require("term")
|
return loadfile(shell.resolve("less", "lua"))("--noback", ...)
|
||||||
|
|
||||||
local args = shell.parse(...)
|
|
||||||
if #args > 1 then
|
|
||||||
io.write("Usage: more <filename>\n")
|
|
||||||
io.write("- or no args reads stdin\n")
|
|
||||||
return 1
|
|
||||||
end
|
|
||||||
|
|
||||||
local cat_cmd = table.concat({"cat", ...}, " ")
|
|
||||||
if not io.output().tty then
|
|
||||||
return os.execute(cat_cmd)
|
|
||||||
end
|
|
||||||
|
|
||||||
term.clear()
|
|
||||||
|
|
||||||
local preader = io.popen(cat_cmd)
|
|
||||||
local intercept = true
|
|
||||||
while true do
|
|
||||||
local _, height, _, _, _, y = term.getViewport()
|
|
||||||
if intercept and y == height then
|
|
||||||
term.clearLine()
|
|
||||||
io.write(":") -- status
|
|
||||||
::INPUT::
|
|
||||||
local _, _, _, code = term.pull("key_down")
|
|
||||||
if code == keyboard.keys.q then
|
|
||||||
term.clearLine()
|
|
||||||
os.exit(1) -- abort
|
|
||||||
elseif code == keyboard.keys["end"] then
|
|
||||||
intercept = false
|
|
||||||
elseif code == keyboard.keys.space or code == keyboard.keys.pageDown then
|
|
||||||
term.clear() -- clear whole screen, get new page drawn; move cursor to 1,1
|
|
||||||
elseif code == keyboard.keys.enter or code == keyboard.keys.down then
|
|
||||||
term.clearLine() -- remove status bar
|
|
||||||
term.scroll(1) -- move everything up one
|
|
||||||
term.setCursor(1, height - 1)
|
|
||||||
else
|
|
||||||
goto INPUT
|
|
||||||
end
|
|
||||||
end
|
|
||||||
print(preader:read() or os.exit())
|
|
||||||
end
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user