local keys=require("keyboard").keys local shell=require("shell") local unicode=require("unicode") local term=require("term") local args,ops=shell.parse(...) if#args>1 then io.write("Usage: ",os.getenv("_"):match("/([^/]+)%.lua$")," \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 local preader=io.popen(cat_cmd) local scrollback=not ops.noback and{} local bottom=0 local end_of_buffer=false local width,height=term.getViewport() local function split(full_line) local index=1 local parts={} while true do local sub=full_line:sub(index,index+width*3) if#sub#full_line then break end end return parts 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 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() if end_of_buffer then if ops.noback then os.exit() end io.write("(END)") end 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_of_buffer=false end local function goforward(n) term.clearLine() local update,line_count=scan(n) for _,line in ipairs(update)do print(line) end if line_count