Advertisement
Virgilcore

RobcOS TextEdit v1.0

Jun 9th, 2022
948
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 24.31 KB | None | 0 0
  1. -- Get file to edit
  2. local tArgs = { ... }
  3. if #tArgs == 0 then
  4.     local programName = arg[0] or fs.getName(shell.getRunningProgram())
  5.     print("Usage: " .. programName .. " <path>")
  6.     return
  7. end
  8.  
  9. -- Error checking
  10. local sPath = shell.resolve(tArgs[1])
  11. local bReadOnly = fs.isReadOnly(sPath)
  12. if fs.exists(sPath) and fs.isDir(sPath) then
  13.     print("Cannot edit a directory.")
  14.     return
  15. end
  16.  
  17. -- Create .lua files by default
  18. if not fs.exists(sPath) and not string.find(sPath, "%.") then
  19.     local sExtension = settings.get("edit.default_extension")
  20.     if sExtension ~= "" and type(sExtension) == "string" then
  21.         sPath = sPath .. "." .. sExtension
  22.     end
  23. end
  24.  
  25. local x, y = 1, 1
  26. local w, h = term.getSize()
  27. local scrollX, scrollY = 0, 0
  28.  
  29. local tLines = {}
  30. local bRunning = true
  31.  
  32. -- Colours
  33. local highlightColour, keywordColour, commentColour, textColour, bgColour, stringColour
  34. if term.isColour() then
  35.     bgColour = colours.black
  36.     textColour = colours.white
  37.     highlightColour = colours.yellow
  38.     keywordColour = colours.yellow
  39.     commentColour = colours.green
  40.     stringColour = colours.red
  41. else
  42.     bgColour = colours.black
  43.     textColour = colours.white
  44.     highlightColour = colours.white
  45.     keywordColour = colours.white
  46.     commentColour = colours.white
  47.     stringColour = colours.white
  48. end
  49.  
  50. local runHandler = [[multishell.setTitle(multishell.getCurrent(), %q)
  51. local current = term.current()
  52. local ok, err = load(%q, %q, nil, _ENV)
  53. if ok then ok, err = pcall(ok, ...) end
  54. term.redirect(current)
  55. term.setTextColor(term.isColour() and colours.yellow or colours.white)
  56. term.setBackgroundColor(colours.black)
  57. term.setCursorBlink(false)
  58. local _, y = term.getCursorPos()
  59. local _, h = term.getSize()
  60. if not ok then
  61.     printError(err)
  62. end
  63. if ok and y >= h then
  64.     term.scroll(1)
  65. end
  66. term.setCursorPos(1, h)
  67. if ok then
  68.     write("Program finished. ")
  69. end
  70. write("Press any key to continue")
  71. os.pullEvent('key')
  72. ]]
  73.  
  74. -- Menus
  75. local bMenu = false
  76. local nMenuItem = 1
  77. local tMenuItems = {}
  78. if not bReadOnly then
  79.     table.insert(tMenuItems, "Save")
  80. end
  81. if shell.openTab then
  82.     table.insert(tMenuItems, "Run")
  83. end
  84. if peripheral.find("printer") then
  85.     table.insert(tMenuItems, "Print")
  86. end
  87. table.insert(tMenuItems, "Exit")
  88.  
  89. local sStatus
  90. if term.isColour() then
  91.     sStatus = "Press Ctrl or click here to access menu"
  92. else
  93.     sStatus = "Press Ctrl to access menu"
  94. end
  95. if #sStatus > w - 5 then
  96.     sStatus = "Press Ctrl for menu"
  97. end
  98.  
  99. local function load(_sPath)
  100.     tLines = {}
  101.     if fs.exists(_sPath) then
  102.         local file = io.open(_sPath, "r")
  103.         local sLine = file:read()
  104.         while sLine do
  105.             table.insert(tLines, sLine)
  106.             sLine = file:read()
  107.         end
  108.         file:close()
  109.     end
  110.  
  111.     if #tLines == 0 then
  112.         table.insert(tLines, "")
  113.     end
  114. end
  115.  
  116. local function save(_sPath, fWrite)
  117.     -- Create intervening folder
  118.     local sDir = _sPath:sub(1, _sPath:len() - fs.getName(_sPath):len())
  119.     if not fs.exists(sDir) then
  120.         fs.makeDir(sDir)
  121.     end
  122.  
  123.     -- Save
  124.     local file, fileerr
  125.     local function innerSave()
  126.         file, fileerr = fs.open(_sPath, "w")
  127.         if file then
  128.             if file then
  129.                 fWrite(file)
  130.             end
  131.         else
  132.             error("Failed to open " .. _sPath)
  133.         end
  134.     end
  135.  
  136.     local ok, err = pcall(innerSave)
  137.     if file then
  138.         file.close()
  139.     end
  140.     return ok, err, fileerr
  141. end
  142.  
  143. local tKeywords = {
  144.     ["and"] = true,
  145.     ["break"] = true,
  146.     ["do"] = true,
  147.     ["else"] = true,
  148.     ["elseif"] = true,
  149.     ["end"] = true,
  150.     ["false"] = true,
  151.     ["for"] = true,
  152.     ["function"] = true,
  153.     ["if"] = true,
  154.     ["in"] = true,
  155.     ["local"] = true,
  156.     ["nil"] = true,
  157.     ["not"] = true,
  158.     ["or"] = true,
  159.     ["repeat"] = true,
  160.     ["return"] = true,
  161.     ["then"] = true,
  162.     ["true"] = true,
  163.     ["until"] = true,
  164.     ["while"] = true,
  165. }
  166.  
  167. local function tryWrite(sLine, regex, colour)
  168.     local match = string.match(sLine, regex)
  169.     if match then
  170.         if type(colour) == "number" then
  171.             term.setTextColour(colour)
  172.         else
  173.             term.setTextColour(colour(match))
  174.         end
  175.         term.write(match)
  176.         term.setTextColour(textColour)
  177.         return string.sub(sLine, #match + 1)
  178.     end
  179.     return nil
  180. end
  181.  
  182. local function writeHighlighted(sLine)
  183.     while #sLine > 0 do
  184.         sLine =
  185.             tryWrite(sLine, "^%-%-%[%[.-%]%]", commentColour) or
  186.             tryWrite(sLine, "^%-%-.*", commentColour) or
  187.             tryWrite(sLine, "^\"\"", stringColour) or
  188.             tryWrite(sLine, "^\".-[^\\]\"", stringColour) or
  189.             tryWrite(sLine, "^\'\'", stringColour) or
  190.             tryWrite(sLine, "^\'.-[^\\]\'", stringColour) or
  191.             tryWrite(sLine, "^%[%[.-%]%]", stringColour) or
  192.             tryWrite(sLine, "^[%w_]+", function(match)
  193.                 if tKeywords[match] then
  194.                     return keywordColour
  195.                 end
  196.                 return textColour
  197.             end) or
  198.             tryWrite(sLine, "^[^%w_]", textColour)
  199.     end
  200. end
  201.  
  202. local tCompletions
  203. local nCompletion
  204.  
  205. local tCompleteEnv = _ENV
  206. local function complete(sLine)
  207.     if settings.get("edit.autocomplete") then
  208.         local nStartPos = string.find(sLine, "[a-zA-Z0-9_%.:]+$")
  209.         if nStartPos then
  210.             sLine = string.sub(sLine, nStartPos)
  211.         end
  212.         if #sLine > 0 then
  213.             return textutils.complete(sLine, tCompleteEnv)
  214.         end
  215.     end
  216.     return nil
  217. end
  218.  
  219. local function recomplete()
  220.     local sLine = tLines[y]
  221.     if not bMenu and not bReadOnly and x == #sLine + 1 then
  222.         tCompletions = complete(sLine)
  223.         if tCompletions and #tCompletions > 0 then
  224.             nCompletion = 1
  225.         else
  226.             nCompletion = nil
  227.         end
  228.     else
  229.         tCompletions = nil
  230.         nCompletion = nil
  231.     end
  232. end
  233.  
  234. local function writeCompletion(sLine)
  235.     if nCompletion then
  236.         local sCompletion = tCompletions[nCompletion]
  237.         term.setTextColor(colours.white)
  238.         term.setBackgroundColor(colours.grey)
  239.         term.write(sCompletion)
  240.         term.setTextColor(textColour)
  241.         term.setBackgroundColor(bgColour)
  242.     end
  243. end
  244.  
  245. local function redrawText()
  246.     local cursorX, cursorY = x, y
  247.     for y = 1, h - 1 do
  248.         term.setCursorPos(1 - scrollX, y)
  249.         term.clearLine()
  250.  
  251.         local sLine = tLines[y + scrollY]
  252.         if sLine ~= nil then
  253.             writeHighlighted(sLine)
  254.             if cursorY == y and cursorX == #sLine + 1 then
  255.                 writeCompletion()
  256.             end
  257.         end
  258.     end
  259.     term.setCursorPos(x - scrollX, y - scrollY)
  260. end
  261.  
  262. local function redrawLine(_nY)
  263.     local sLine = tLines[_nY]
  264.     if sLine then
  265.         term.setCursorPos(1 - scrollX, _nY - scrollY)
  266.         term.clearLine()
  267.         writeHighlighted(sLine)
  268.         if _nY == y and x == #sLine + 1 then
  269.             writeCompletion()
  270.         end
  271.         term.setCursorPos(x - scrollX, _nY - scrollY)
  272.     end
  273. end
  274.  
  275. local function redrawMenu()
  276.     -- Clear line
  277.     term.setCursorPos(1, h)
  278.     term.clearLine()
  279.  
  280.     -- Draw line numbers
  281.     term.setCursorPos(w - #("Ln " .. y) + 1, h)
  282.     term.setTextColour(highlightColour)
  283.     term.write("Ln ")
  284.     term.setTextColour(textColour)
  285.     term.write(y)
  286.  
  287.     term.setCursorPos(1, h)
  288.     if bMenu then
  289.         -- Draw menu
  290.         term.setTextColour(textColour)
  291.         for nItem, sItem in pairs(tMenuItems) do
  292.             if nItem == nMenuItem then
  293.                 term.setTextColour(highlightColour)
  294.                 term.write("[")
  295.                 term.setTextColour(textColour)
  296.                 term.write(sItem)
  297.                 term.setTextColour(highlightColour)
  298.                 term.write("]")
  299.                 term.setTextColour(textColour)
  300.             else
  301.                 term.write(" " .. sItem .. " ")
  302.             end
  303.         end
  304.     else
  305.         -- Draw status
  306.         term.setTextColour(highlightColour)
  307.         term.write(sStatus)
  308.         term.setTextColour(textColour)
  309.     end
  310.  
  311.     -- Reset cursor
  312.     term.setCursorPos(x - scrollX, y - scrollY)
  313. end
  314.  
  315. local tMenuFuncs = {
  316.     Save = function()
  317.         if bReadOnly then
  318.             sStatus = "Access denied"
  319.         else
  320.             local ok, _, fileerr  = save(sPath, function(file)
  321.                 for _, sLine in ipairs(tLines) do
  322.                     file.write(sLine .. "\n")
  323.                 end
  324.             end)
  325.             if ok then
  326.                 sStatus = "Saved to " .. sPath
  327.             else
  328.                 if fileerr then
  329.                     sStatus = "Error saving to " .. fileerr
  330.                 else
  331.                     sStatus = "Error saving to " .. sPath
  332.                 end
  333.             end
  334.         end
  335.         redrawMenu()
  336.     end,
  337.     Print = function()
  338.         local printer = peripheral.find("printer")
  339.         if not printer then
  340.             sStatus = "No printer attached"
  341.             return
  342.         end
  343.  
  344.         local nPage = 0
  345.         local sName = fs.getName(sPath)
  346.         if printer.getInkLevel() < 1 then
  347.             sStatus = "Printer out of ink"
  348.             return
  349.         elseif printer.getPaperLevel() < 1 then
  350.             sStatus = "Printer out of paper"
  351.             return
  352.         end
  353.  
  354.         local screenTerminal = term.current()
  355.         local printerTerminal = {
  356.             getCursorPos = printer.getCursorPos,
  357.             setCursorPos = printer.setCursorPos,
  358.             getSize = printer.getPageSize,
  359.             write = printer.write,
  360.         }
  361.         printerTerminal.scroll = function()
  362.             if nPage == 1 then
  363.                 printer.setPageTitle(sName .. " (page " .. nPage .. ")")
  364.             end
  365.  
  366.             while not printer.newPage() do
  367.                 if printer.getInkLevel() < 1 then
  368.                     sStatus = "Printer out of ink, please refill"
  369.                 elseif printer.getPaperLevel() < 1 then
  370.                     sStatus = "Printer out of paper, please refill"
  371.                 else
  372.                     sStatus = "Printer output tray full, please empty"
  373.                 end
  374.  
  375.                 term.redirect(screenTerminal)
  376.                 redrawMenu()
  377.                 term.redirect(printerTerminal)
  378.  
  379.                 sleep(0.5)
  380.             end
  381.  
  382.             nPage = nPage + 1
  383.             if nPage == 1 then
  384.                 printer.setPageTitle(sName)
  385.             else
  386.                 printer.setPageTitle(sName .. " (page " .. nPage .. ")")
  387.             end
  388.         end
  389.  
  390.         bMenu = false
  391.         term.redirect(printerTerminal)
  392.         local ok, error = pcall(function()
  393.             term.scroll()
  394.             for _, sLine in ipairs(tLines) do
  395.                 print(sLine)
  396.             end
  397.         end)
  398.         term.redirect(screenTerminal)
  399.         if not ok then
  400.             print(error)
  401.         end
  402.  
  403.         while not printer.endPage() do
  404.             sStatus = "Printer output tray full, please empty"
  405.             redrawMenu()
  406.             sleep(0.5)
  407.         end
  408.         bMenu = true
  409.  
  410.         if nPage > 1 then
  411.             sStatus = "Printed " .. nPage .. " Pages"
  412.         else
  413.             sStatus = "Printed 1 Page"
  414.         end
  415.         redrawMenu()
  416.     end,
  417.     Exit = function()
  418.         bRunning = false
  419.         shell.run("RobcOS")
  420.     end,
  421.     Run = function()
  422.         local sTitle = fs.getName(sPath)
  423.         if sTitle:sub(-4) == ".lua" then
  424.             sTitle = sTitle:sub(1, -5)
  425.         end
  426.         local sTempPath = bReadOnly and ".temp." .. sTitle or fs.combine(fs.getDir(sPath), ".temp." .. sTitle)
  427.         if fs.exists(sTempPath) then
  428.             sStatus = "Error saving to " .. sTempPath
  429.             return
  430.         end
  431.         local ok = save(sTempPath, function(file)
  432.             file.write(runHandler:format(sTitle, table.concat(tLines, "\n"), "@" .. fs.getName(sPath)))
  433.         end)
  434.         if ok then
  435.             local nTask = shell.openTab(sTempPath)
  436.             if nTask then
  437.                 shell.switchTab(nTask)
  438.             else
  439.                 sStatus = "Error starting Task"
  440.             end
  441.             fs.delete(sTempPath)
  442.         else
  443.             sStatus = "Error saving to " .. sTempPath
  444.         end
  445.         redrawMenu()
  446.     end,
  447. }
  448.  
  449. local function doMenuItem(_n)
  450.     tMenuFuncs[tMenuItems[_n]]()
  451.     if bMenu then
  452.         bMenu = false
  453.         term.setCursorBlink(true)
  454.     end
  455.     redrawMenu()
  456. end
  457.  
  458. local function setCursor(newX, newY)
  459.     local _, oldY = x, y
  460.     x, y = newX, newY
  461.     local screenX = x - scrollX
  462.     local screenY = y - scrollY
  463.  
  464.     local bRedraw = false
  465.     if screenX < 1 then
  466.         scrollX = x - 1
  467.         screenX = 1
  468.         bRedraw = true
  469.     elseif screenX > w then
  470.         scrollX = x - w
  471.         screenX = w
  472.         bRedraw = true
  473.     end
  474.  
  475.     if screenY < 1 then
  476.         scrollY = y - 1
  477.         screenY = 1
  478.         bRedraw = true
  479.     elseif screenY > h - 1 then
  480.         scrollY = y - (h - 1)
  481.         screenY = h - 1
  482.         bRedraw = true
  483.     end
  484.  
  485.     recomplete()
  486.     if bRedraw then
  487.         redrawText()
  488.     elseif y ~= oldY then
  489.         redrawLine(oldY)
  490.         redrawLine(y)
  491.     else
  492.         redrawLine(y)
  493.     end
  494.     term.setCursorPos(screenX, screenY)
  495.  
  496.     redrawMenu()
  497. end
  498.  
  499. -- Actual program functionality begins
  500. load(sPath)
  501.  
  502. term.setBackgroundColour(bgColour)
  503. term.clear()
  504. term.setCursorPos(x, y)
  505. term.setCursorBlink(true)
  506.  
  507. recomplete()
  508. redrawText()
  509. redrawMenu()
  510.  
  511. local function acceptCompletion()
  512.     if nCompletion then
  513.         -- Append the completion
  514.         local sCompletion = tCompletions[nCompletion]
  515.         tLines[y] = tLines[y] .. sCompletion
  516.         setCursor(x + #sCompletion , y)
  517.     end
  518. end
  519.  
  520. -- Handle input
  521. while bRunning do
  522.     local sEvent, param, param2, param3 = os.pullEvent()
  523.     if sEvent == "key" then
  524.         if param == keys.up then
  525.             -- Up
  526.             if not bMenu then
  527.                 if nCompletion then
  528.                     -- Cycle completions
  529.                     nCompletion = nCompletion - 1
  530.                     if nCompletion < 1 then
  531.                         nCompletion = #tCompletions
  532.                     end
  533.                     redrawLine(y)
  534.  
  535.                 elseif y > 1 then
  536.                     -- Move cursor up
  537.                     setCursor(
  538.                         math.min(x, #tLines[y - 1] + 1),
  539.                         y - 1
  540.                     )
  541.                 end
  542.             end
  543.  
  544.         elseif param == keys.down then
  545.             -- Down
  546.             if not bMenu then
  547.                 -- Move cursor down
  548.                 if nCompletion then
  549.                     -- Cycle completions
  550.                     nCompletion = nCompletion + 1
  551.                     if nCompletion > #tCompletions then
  552.                         nCompletion = 1
  553.                     end
  554.                     redrawLine(y)
  555.  
  556.                 elseif y < #tLines then
  557.                     -- Move cursor down
  558.                     setCursor(
  559.                         math.min(x, #tLines[y + 1] + 1),
  560.                         y + 1
  561.                     )
  562.                 end
  563.             end
  564.  
  565.         elseif param == keys.tab then
  566.             -- Tab
  567.             if not bMenu and not bReadOnly then
  568.                 if nCompletion and x == #tLines[y] + 1 then
  569.                     -- Accept autocomplete
  570.                     acceptCompletion()
  571.                 else
  572.                     -- Indent line
  573.                     local sLine = tLines[y]
  574.                     tLines[y] = string.sub(sLine, 1, x - 1) .. "    " .. string.sub(sLine, x)
  575.                     setCursor(x + 4, y)
  576.                 end
  577.             end
  578.  
  579.         elseif param == keys.pageUp then
  580.             -- Page Up
  581.             if not bMenu then
  582.                 -- Move up a page
  583.                 local newY
  584.                 if y - (h - 1) >= 1 then
  585.                     newY = y - (h - 1)
  586.                 else
  587.                     newY = 1
  588.                 end
  589.                 setCursor(
  590.                     math.min(x, #tLines[newY] + 1),
  591.                     newY
  592.                 )
  593.             end
  594.  
  595.         elseif param == keys.pageDown then
  596.             -- Page Down
  597.             if not bMenu then
  598.                 -- Move down a page
  599.                 local newY
  600.                 if y + (h - 1) <= #tLines then
  601.                     newY = y + (h - 1)
  602.                 else
  603.                     newY = #tLines
  604.                 end
  605.                 local newX = math.min(x, #tLines[newY] + 1)
  606.                 setCursor(newX, newY)
  607.             end
  608.  
  609.         elseif param == keys.home then
  610.             -- Home
  611.             if not bMenu then
  612.                 -- Move cursor to the beginning
  613.                 if x > 1 then
  614.                     setCursor(1, y)
  615.                 end
  616.             end
  617.  
  618.         elseif param == keys["end"] then
  619.             -- End
  620.             if not bMenu then
  621.                 -- Move cursor to the end
  622.                 local nLimit = #tLines[y] + 1
  623.                 if x < nLimit then
  624.                     setCursor(nLimit, y)
  625.                 end
  626.             end
  627.  
  628.         elseif param == keys.left then
  629.             -- Left
  630.             if not bMenu then
  631.                 if x > 1 then
  632.                     -- Move cursor left
  633.                     setCursor(x - 1, y)
  634.                 elseif x == 1 and y > 1 then
  635.                     setCursor(#tLines[y - 1] + 1, y - 1)
  636.                 end
  637.             else
  638.                 -- Move menu left
  639.                 nMenuItem = nMenuItem - 1
  640.                 if nMenuItem < 1 then
  641.                     nMenuItem = #tMenuItems
  642.                 end
  643.                 redrawMenu()
  644.             end
  645.  
  646.         elseif param == keys.right then
  647.             -- Right
  648.             if not bMenu then
  649.                 local nLimit = #tLines[y] + 1
  650.                 if x < nLimit then
  651.                     -- Move cursor right
  652.                     setCursor(x + 1, y)
  653.                 elseif nCompletion and x == #tLines[y] + 1 then
  654.                     -- Accept autocomplete
  655.                     acceptCompletion()
  656.                 elseif x == nLimit and y < #tLines then
  657.                     -- Go to next line
  658.                     setCursor(1, y + 1)
  659.                 end
  660.             else
  661.                 -- Move menu right
  662.                 nMenuItem = nMenuItem + 1
  663.                 if nMenuItem > #tMenuItems then
  664.                     nMenuItem = 1
  665.                 end
  666.                 redrawMenu()
  667.             end
  668.  
  669.         elseif param == keys.delete then
  670.             -- Delete
  671.             if not bMenu and not bReadOnly then
  672.                 local nLimit = #tLines[y] + 1
  673.                 if x < nLimit then
  674.                     local sLine = tLines[y]
  675.                     tLines[y] = string.sub(sLine, 1, x - 1) .. string.sub(sLine, x + 1)
  676.                     recomplete()
  677.                     redrawLine(y)
  678.                 elseif y < #tLines then
  679.                     tLines[y] = tLines[y] .. tLines[y + 1]
  680.                     table.remove(tLines, y + 1)
  681.                     recomplete()
  682.                     redrawText()
  683.                 end
  684.             end
  685.  
  686.         elseif param == keys.backspace then
  687.             -- Backspace
  688.             if not bMenu and not bReadOnly then
  689.                 if x > 1 then
  690.                     -- Remove character
  691.                     local sLine = tLines[y]
  692.                     if x > 4 and string.sub(sLine, x - 4, x - 1) == "    " and not string.sub(sLine, 1, x - 1):find("%S") then
  693.                         tLines[y] = string.sub(sLine, 1, x - 5) .. string.sub(sLine, x)
  694.                         setCursor(x - 4, y)
  695.                     else
  696.                         tLines[y] = string.sub(sLine, 1, x - 2) .. string.sub(sLine, x)
  697.                         setCursor(x - 1, y)
  698.                     end
  699.                 elseif y > 1 then
  700.                     -- Remove newline
  701.                     local sPrevLen = #tLines[y - 1]
  702.                     tLines[y - 1] = tLines[y - 1] .. tLines[y]
  703.                     table.remove(tLines, y)
  704.                     setCursor(sPrevLen + 1, y - 1)
  705.                     redrawText()
  706.                 end
  707.             end
  708.  
  709.         elseif param == keys.enter or param == keys.numPadEnter then
  710.             -- Enter/Numpad Enter
  711.             if not bMenu and not bReadOnly then
  712.                 -- Newline
  713.                 local sLine = tLines[y]
  714.                 local _, spaces = string.find(sLine, "^[ ]+")
  715.                 if not spaces then
  716.                     spaces = 0
  717.                 end
  718.                 tLines[y] = string.sub(sLine, 1, x - 1)
  719.                 table.insert(tLines, y + 1, string.rep(' ', spaces) .. string.sub(sLine, x))
  720.                 setCursor(spaces + 1, y + 1)
  721.                 redrawText()
  722.  
  723.             elseif bMenu then
  724.                 -- Menu selection
  725.                 doMenuItem(nMenuItem)
  726.  
  727.             end
  728.  
  729.         elseif param == keys.leftCtrl or param == keys.rightCtrl then
  730.             -- Menu toggle
  731.             bMenu = not bMenu
  732.             if bMenu then
  733.                 term.setCursorBlink(false)
  734.             else
  735.                 term.setCursorBlink(true)
  736.             end
  737.             redrawMenu()
  738.         elseif param == keys.rightAlt then
  739.             if bMenu then
  740.                 bMenu = false
  741.                 term.setCursorBlink(true)
  742.                 redrawMenu()
  743.             end
  744.         end
  745.  
  746.     elseif sEvent == "char" then
  747.         if not bMenu and not bReadOnly then
  748.             -- Input text
  749.             local sLine = tLines[y]
  750.             tLines[y] = string.sub(sLine, 1, x - 1) .. param .. string.sub(sLine, x)
  751.             setCursor(x + 1, y)
  752.  
  753.         elseif bMenu then
  754.             -- Select menu items
  755.             for n, sMenuItem in ipairs(tMenuItems) do
  756.                 if string.lower(string.sub(sMenuItem, 1, 1)) == string.lower(param) then
  757.                     doMenuItem(n)
  758.                     break
  759.                 end
  760.             end
  761.         end
  762.  
  763.     elseif sEvent == "paste" then
  764.         if not bReadOnly then
  765.             -- Close menu if open
  766.             if bMenu then
  767.                 bMenu = false
  768.                 term.setCursorBlink(true)
  769.                 redrawMenu()
  770.             end
  771.             -- Input text
  772.             local sLine = tLines[y]
  773.             tLines[y] = string.sub(sLine, 1, x - 1) .. param .. string.sub(sLine, x)
  774.             setCursor(x + #param , y)
  775.         end
  776.  
  777.     elseif sEvent == "mouse_click" then
  778.         local cx, cy = param2, param3
  779.         if not bMenu then
  780.             if param == 1 then
  781.                 -- Left click
  782.                 if cy < h then
  783.                     local newY = math.min(math.max(scrollY + cy, 1), #tLines)
  784.                     local newX = math.min(math.max(scrollX + cx, 1), #tLines[newY] + 1)
  785.                     setCursor(newX, newY)
  786.                 else
  787.                     bMenu = true
  788.                     redrawMenu()
  789.                 end
  790.             end
  791.         else
  792.             if cy == h then
  793.                 local nMenuPosEnd = 1
  794.                 local nMenuPosStart = 1
  795.                 for n, sMenuItem in ipairs(tMenuItems) do
  796.                     nMenuPosEnd = nMenuPosEnd + #sMenuItem + 1
  797.                     if cx > nMenuPosStart and cx < nMenuPosEnd then
  798.                         doMenuItem(n)
  799.                     end
  800.                     nMenuPosEnd = nMenuPosEnd + 1
  801.                     nMenuPosStart = nMenuPosEnd
  802.                 end
  803.             else
  804.                 bMenu = false
  805.                 term.setCursorBlink(true)
  806.                 redrawMenu()
  807.             end
  808.         end
  809.  
  810.     elseif sEvent == "mouse_scroll" then
  811.         if not bMenu then
  812.             if param == -1 then
  813.                 -- Scroll up
  814.                 if scrollY > 0 then
  815.                     -- Move cursor up
  816.                     scrollY = scrollY - 1
  817.                     redrawText()
  818.                 end
  819.  
  820.             elseif param == 1 then
  821.                 -- Scroll down
  822.                 local nMaxScroll = #tLines - (h - 1)
  823.                 if scrollY < nMaxScroll then
  824.                     -- Move cursor down
  825.                     scrollY = scrollY + 1
  826.                     redrawText()
  827.                 end
  828.  
  829.             end
  830.         end
  831.  
  832.     elseif sEvent == "term_resize" then
  833.         w, h = term.getSize()
  834.         setCursor(x, y)
  835.         redrawMenu()
  836.         redrawText()
  837.  
  838.     end
  839. end
  840.  
  841. -- Cleanup
  842. term.clear()
  843. term.setCursorBlink(false)
  844. term.setCursorPos(1, 1)
  845.  
  846.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement