Advertisement
JackMacWindows

ComputerCraft less

Sep 6th, 2019
339
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.59 KB | None | 0 0
  1. local args = {...}
  2. if #args < 1 then error("Usage: less [options...] <file>") end
  3. local filename = nil
  4. local parseargs = true
  5. local foldLines = true
  6. for i,s in ipairs(args) do
  7.     if string.sub(s, 1, 2) == "--" and parseargs then
  8.         if s == "--version" then print("less for CraftOS v1.0"); return
  9.         elseif s == "--help" then print("..."); return
  10.         elseif s == "--" then parseargs = false
  11.     elseif s == "--chop-long-lines" then foldLines = false
  12.         end
  13.     elseif string.sub(s, 1, 1) == '-' and parseargs then
  14.         for a in string.gmatch(string.sub(s, 2), "[a-zA-Z0-9~]") do
  15.             if a == 'S' then foldLines = false
  16.             elseif a == '' then
  17.             end
  18.         end
  19.     elseif filename == nil then filename = s end
  20. end
  21. if filename == nil then error("Missing filename (\"less --help\" for help)") end
  22.  
  23. local lines = {}
  24. local pos, hpos = 1, 1
  25. local w, h = term.getSize()
  26. local message = nil
  27. h=h-1
  28.  
  29. local function readFile()
  30.     lines = {}
  31.     local file = fs.open(shell.resolve(filename), "r")
  32.     if file == nil then error("Could not open file " .. shell.resolve(filename)) end
  33.     local line = file.readLine()
  34.     while line do
  35.         table.insert(lines, ({string.gsub(line, "\t", "    ")})[1])
  36.         line = file.readLine()
  37.     end
  38.     file.close()
  39.     if foldLines and hpos == 1 then for i = 1, #lines do if #lines[i] > w then
  40.         table.insert(lines, i+1, string.sub(lines[i], w) or "")
  41.         lines[i] = string.sub(lines[i], 1, w - 1)
  42.     end end end
  43. end
  44.  
  45. local function redrawScreen()
  46.     term.clear()
  47.     term.setCursorPos(1, 1)
  48.     term.setCursorBlink(false)
  49.     for i = pos, pos + h - 1 do
  50.         if lines[i] ~= nil then term.write(string.sub(lines[i], hpos)) end
  51.         term.setCursorPos(1, i - pos + 2)
  52.     end
  53.     term.setCursorPos(1, h+1)
  54.     if message then term.blit(message, string.rep("f", #message), string.rep("0", #message))
  55.     elseif pos >= #lines - h then term.blit("(END)", "fffff", "00000")
  56.     else term.write(":") end
  57.     term.setCursorBlink(true)
  58. end
  59.  
  60. local function readCommand(prompt, fg, bg)
  61.     term.setCursorPos(1, h+1)
  62.     term.clearLine()
  63.     term.blit(prompt, fg or string.rep("0", #prompt), bg or string.rep("f", #prompt))
  64.     local str = ""
  65.     local c = 1
  66.     while true do
  67.         term.setCursorPos(#prompt + 1, h + 1)
  68.         term.write(str .. string.rep(" ", w - #str - #prompt - 2))
  69.         term.setCursorPos(#prompt + c, h + 1)
  70.         term.setCursorBlink(true)
  71.         local ev, p1 = os.pullEvent()
  72.         if ev == "key" then
  73.             if p1 == keys.backspace then if str == "" then return nil elseif c > 1 then
  74.                 str = string.sub(str, 1, c-2) .. string.sub(str, c)
  75.                 c=c-1
  76.             end
  77.             elseif p1 == keys.left and c > 1 then c = c - 1
  78.             elseif p1 == keys.right and c < #str + 1 then c = c + 1
  79.             elseif p1 == keys.enter or p1 == keys["return"] then return str
  80.             end
  81.         elseif ev == "char" then
  82.             str = string.sub(str, 1, c-1) .. p1 .. string.sub(str, c)
  83.             c=c+1
  84.         end
  85.     end
  86. end
  87.  
  88. local function flashScreen()
  89.     local br, bg, bb = term.getPaletteColor(colors.black)
  90.     term.setPaletteColor(colors.black, term.getPaletteColor(colors.lightGray))
  91.     sleep(0.1)
  92.     term.setPaletteColor(colors.black, term.getPaletteColor(colors.gray))
  93.     sleep(0.05)
  94.     term.setPaletteColor(colors.black, br, bg, bb)
  95.     sleep(0.05)
  96. end
  97.  
  98. readFile()
  99.  
  100. local lastQuery = nil
  101.  
  102. while true do
  103.     redrawScreen()
  104.     local ev, p1, p2, p3 = os.pullEvent()
  105.     local oldMessage = message
  106.     message = nil
  107.     if ev == "key" then
  108.         if p1 == keys.left and hpos > w / 2 then hpos = hpos - w / 2
  109.         elseif p1 == keys.right then hpos = hpos + w / 2
  110.         elseif p1 == keys.up then if pos > 1 then pos = pos - 1 else flashScreen() end
  111.         elseif (p1 == keys.down or p1 == keys.enter or p1 == keys["return"]) then if pos < #lines - h then pos = pos + 1 else flashScreen() end
  112.         elseif p1 == keys.space then if pos < #lines - h then pos = pos + (pos < #lines - 2*h + 1 and h or (#lines - h) - pos) else flashScreen() end
  113.         end
  114.     elseif ev == "char" then
  115.         if p1 == "q" then break
  116.         elseif p1 == "f" then if pos < #lines - h then pos = pos + (pos < #lines - 2*h + 1 and h or (#lines - h) - pos) else flashScreen() end
  117.         elseif p1 == "b" then if pos > 1 then pos = pos - (pos > h + 1 and h or pos - 1) else flashScreen() end
  118.         elseif p1 == "d" then if pos < #lines - h then pos = pos + (pos < #lines - (1.5*h) + 1 and h / 2 or (#lines - h) - pos) else flashScreen() end
  119.         elseif p1 == "u" then if pos > 1 then pos = pos - (pos > (h / 2) + 1 and (h / 2) or pos - 1) else flashScreen() end
  120.         elseif p1 == "g" or p1 == "<" then pos = 1
  121.         elseif p1 == "G" or p1 == ">" then pos = #lines - h
  122.         elseif p1 == "e" or p1 == "j" then if pos < #lines - h then pos = pos + 1 else flashScreen() end
  123.         elseif p1 == "y" or p1 == "k" then if pos > 1 then pos = pos - 1 else flashScreen() end
  124.         elseif p1 == "K" or p1 == "Y" then pos = pos - 1
  125.         elseif p1 == "J" then pos = pos + 1
  126.         elseif p1 == "/" then
  127.             local query = readCommand("/")
  128.             if query == "" then query = lastQuery end
  129.             if query ~= nil then
  130.                 lastQuery = query
  131.                 local found = false
  132.                 for i = pos + 1, #lines do if string.match(lines[i], query) then
  133.                     pos = i
  134.                     found = true
  135.                     break
  136.                 end end
  137.                 if pos > #lines - h then pos = #lines - h end
  138.                 if not found then message = "Pattern not found" end
  139.             end
  140.         elseif p1 == "?" then
  141.             local query = readCommand("?")
  142.             if query == "" then query = lastQuery end
  143.             if query ~= nil then
  144.                 lastQuery = query
  145.                 local found = false
  146.                 for i = pos - 1, 1, -1 do if string.match(lines[i], query) then
  147.                     pos = i
  148.                     found = true
  149.                     break
  150.                 end end
  151.                 if pos > #lines - h then pos = #lines - h end
  152.                 if not found then message = "Pattern not found" end
  153.             end
  154.         elseif p1 == "n" then
  155.             local found = false
  156.             for i = pos + 1, #lines do if string.match(lines[i], lastQuery) then
  157.                 pos = i
  158.                 found = true
  159.                 break
  160.             end end
  161.             if pos > #lines - h then pos = #lines - h end
  162.             if not found then message = "Pattern not found" end
  163.         elseif p1 == "N" then
  164.             local found = false
  165.             for i = pos - 1, 1, -1 do if string.match(lines[i], lastQuery) then
  166.                 pos = i
  167.                 found = true
  168.                 break
  169.             end end
  170.             if pos > #lines - h then pos = #lines - h end
  171.             if not found then message = "Pattern not found" end
  172.         elseif p1 == "v" then
  173.             shell.run("edit", filename)
  174.             readFile()
  175.         elseif p1 == "!" then
  176.             local cmd = readCommand("!")
  177.             if cmd then shell.run(string.gsub(cmd, "%%", filename)) end
  178.         end
  179.     elseif ev == "term_resize" then
  180.         w, h = term.getSize()
  181.         h=h-1
  182.         readFile()
  183.     elseif ev == "mouse_scroll" then
  184.         if p1 == 1 and pos < #lines - h then pos = pos + 1
  185.         elseif p1 == -1 and pos > 1 then pos = pos - 1 end
  186.     else
  187.         message = oldMessage
  188.     end
  189. end
  190. term.clear()
  191. term.setCursorPos(1, 1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement