Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Get file to edit
- local tArgs = {...}
- if #tArgs == 0 then
- print("Usage: edit <path>")
- return
- end
- -- Error checking
- local sPath = shell.resolve(tArgs[1])
- local bReadOnly = fs.isReadOnly(sPath)
- if fs.exists(sPath) and fs.isDir(sPath) then
- print("Cannot edit a directory.")
- return
- end
- local x, y = 1, 1
- local w, h = term.getSize()
- local scrollX, scrollY = 0, 0
- local tLines = {}
- local bRunning = true
- -- Colors
- local highlightColor, keywordColor, commentColor, textColor, bgColor, stringColor, functionColor, numberColor, operatorColor
- if term.isColor() then
- bgColor = colors.black
- textColor = colors.white
- highlightColor = colors.cyan
- keywordColor = colors.cyan
- commentColor = colors.green
- stringColor = colors.red
- functionColor = colors.purple
- numberColor = colors.orange
- operatorColor = colors.blue
- else
- bgColor = colors.black
- textColor = colors.white
- highlightColor = colors.white
- keywordColor = colors.white
- commentColor = colors.white
- stringColor = colors.white
- functionColor = colors.white
- numberColor = colors.white
- operatorColor = colors.white
- end
- -- Menus
- local bMenu = false
- local nMenuItem = 1
- local tMenuItems
- if bReadOnly then
- tMenuItems = {"Exit"}
- else
- tMenuItems = {"Save", "Exit"}
- end
- local sStatus = "Press Ctrl to access menu"
- local function load(_sPath)
- tLines = {}
- if fs.exists(_sPath) then
- local file = io.open(_sPath, "r")
- local sLine = file:read()
- while sLine do
- table.insert(tLines, sLine)
- sLine = file:read()
- end
- file:close()
- end
- if #tLines == 0 then
- table.insert(tLines, "")
- end
- end
- local function save(_sPath)
- -- Create intervening folder
- local sDir = sPath:sub(1, sPath:len() - fs.getName(sPath):len())
- -- Save
- local file = nil
- local function innerSave()
- file = fs.open(_sPath, "w")
- if file then
- for n, sLine in ipairs(tLines) do
- file.write(sLine .. "\n")
- end
- else
- error("Failed to open " .. _sPath)
- end
- end
- local ok = pcall(innerSave)
- if file then
- file:close()
- end
- return ok
- end
- local tKeywords = {
- --Keywords
- ["and"] = keywordColor,
- ["break"] = keywordColor,
- ["do"] = keywordColor,
- ["else"] = keywordColor,
- ["elseif"] = keywordColor,
- ["end"] = keywordColor,
- ["false"] = keywordColor,
- ["for"] = keywordColor,
- ["function"] = keywordColor,
- ["if"] = keywordColor,
- ["in"] = keywordColor,
- ["local"] = keywordColor,
- ["nil"] = keywordColor,
- ["not"] = keywordColor,
- ["or"] = keywordColor,
- ["repeat"] = keywordColor,
- ["return"] = keywordColor,
- ["then"] = keywordColor,
- ["true"] = keywordColor,
- ["until"]= keywordColor,
- ["while"] = keywordColor,
- --Bit
- ["bit"] = functionColor,
- ["bit.blshift"] = functionColor,
- ["bit.brshift"] = functionColor,
- ["bit.blogic_rshift"] = functionColor,
- ["bit.bxor"] = functionColor,
- ["bit.bor"] = functionColor,
- ["bit.band"] = functionColor,
- ["bit.bnot"] = functionColor,
- --Colors
- ["colors.white"] = colors.white,
- ["colors.orange"] = colors.orange,
- ["colors.magenta"] = colors.magenta,
- ["colors.lightBlue"] = colors.lightBlue,
- ["colors.yellow"] = colors.yellow,
- ["colors.lime"] = colors.lime,
- ["colors.pink"] = colors.pink,
- ["colors.gray"] = colors.gray,
- ["colors.lightGray"] = colors.lightGray,
- ["colors.cyan"] = colors.cyan,
- ["colors.purple"] = colors.purple,
- ["colors.blue"] = colors.blue,
- ["colors.brown"] = colors.brown,
- ["colors.green"] = colors.green,
- ["colors.red"] = colors.red,
- ["colors.black"] = colors.black,
- ["colors"] = functionColor,
- ["colors.combine"] = functionColor,
- ["colors.subtract"] = functionColor,
- ["colors.test"] = functionColor,
- --Commands
- ["commands"] = functionColor,
- ["commands.exec"] = functionColor,
- ["commands.execAsync"] = functionColor,
- ["commands.list"] = functionColor,
- ["commands.getBlockPosition"] = functionColor,
- ["commands.getBlockInfo"] = functionColor,
- ["commands.getBlockInfos"] = functionColor,
- --Coroutine
- ["coroutine"] = functionColor,
- ["coroutine.create"] = functionColor,
- ["coroutine.resume"] = functionColor,
- ["coroutine.running"] = functionColor,
- ["coroutine.status"] = functionColor,
- ["coroutine.wrap"] = functionColor,
- ["coroutine.yield"] = functionColor,
- --disk
- ["disk"] = functionColor,
- ["disk.isPresent"] = functionColor,
- ["disk.hasData"] = functionColor,
- ["disk.getMountPath"] = functionColor,
- ["disk.setLabel"] = functionColor,
- ["disk.getLabel"] = functionColor,
- ["disk.getId"] = functionColor,
- ["disk.hasAudio"] = functionColor,
- ["disk.getAudioTitle"] = functionColor,
- ["disk.playAudio"] = functionColor,
- ["disk.stopAudio"] = functionColor,
- ["disk.eject"] = functionColor,
- --fs
- ["fs"] = functionColor,
- ["fs.list"] = functionColor,
- ["fs.exists"] = functionColor,
- ["fs.isDir"] = functionColor,
- ["fs.isReadOnly"] = functionColor,
- ["fs.getName"] = functionColor,
- ["fs.getDrive"] = functionColor,
- ["fs.getSize"] = functionColor,
- ["fs.getFreeSpace"] = functionColor,
- ["fs.makeDir"] = functionColor,
- ["fs.move"] = functionColor,
- ["fs.copy"] = functionColor,
- ["fs.delete"] = functionColor,
- ["fs.combine"] = functionColor,
- ["fs.open"] = functionColor,
- ["fs.find"] = functionColor,
- ["fs.getDir"] = functionColor,
- ["fs.complete"] = functionColor,
- --gps
- ["gps"] = functionColor,
- ["gps.locate"] = functionColor,
- --help
- ["help"] = functionColor,
- ["help.path"] = functionColor,
- ["help.setPath"] = functionColor,
- ["help.lookup"] = functionColor,
- ["help.topics"] = functionColor,
- ["help.completeTopic"] = functionColor,
- --HTTP
- ["http"] = functionColor,
- ["http.request"] = functionColor,
- ["http.get"] = functionColor,
- ["http.post"] = functionColor,
- ["http.checkURL"] = functionColor,
- --io
- ["io"] = functionColor,
- ["io.open"] = functionColor,
- ["io.write"] = functionColor,
- ["io.read"] = functionColor,
- --Keys
- ["keys"] = functionColor,
- ["keys.getName"] = functionColor,
- --Math
- ["math"] = functionColor,
- ["math.abs"] = functionColor,
- ["math.acos"] = functionColor,
- ["math.asin"] = functionColor,
- ["math.atan"] = functionColor,
- ["math.atan2"] = functionColor,
- ["math.ceil"] = functionColor,
- ["math.cos"] = functionColor,
- ["math.cosh"] = functionColor,
- ["math.deg"] = functionColor,
- ["math.exp"] = functionColor,
- ["math.floor"] = functionColor,
- ["math.fmod"] = functionColor,
- ["math.frexp"] = functionColor,
- ["math.huge"] = functionColor,
- ["math.ldexp"] = functionColor,
- ["math.log"] = functionColor,
- ["math.log10"] = functionColor,
- ["math.max"] = functionColor,
- ["math.min"] = functionColor,
- ["math.modf"] = functionColor,
- ["math.pi"] = functionColor,
- ["math.pow"] = functionColor,
- ["math.rad"] = functionColor,
- ["math.random"] = functionColor,
- ["math.randomseed"] = functionColor,
- ["math.sin"] = functionColor,
- ["math.sinh"] = functionColor,
- ["math.sqrt"] = functionColor,
- ["math.tan"] = functionColor,
- ["math.tanh"] = functionColor,
- --multishell
- ["multishell"] = functionColor,
- ["multishell.getCurrent"] = functionColor,
- ["multishell.getCount"] = functionColor,
- ["multishell.launch"] = functionColor,
- ["multishell.setFocus"] = functionColor,
- ["multishell.setTitle"] = functionColor,
- ["multishell.getTitle"] = functionColor,
- ["multishell.getFocus"] = functionColor,
- --os
- ["os"] = functionColor,
- ["os.version"] = functionColor,
- ["os.getComputerID"] = functionColor,
- ["os.getComputerLabel"] = functionColor,
- ["os.run"] = functionColor,
- ["os.loadAPI"] = functionColor,
- ["os.unloadAPI"] = functionColor,
- ["os.pullEvent"] = functionColor,
- ["os.pullEventRaw"] = functionColor,
- ["os.queueEvent"] = functionColor,
- ["os.clock"] = functionColor,
- ["os.startTimer"] = functionColor,
- ["os.cancelTimer"] = functionColor,
- ["os.time"] = functionColor,
- ["os.sleep"] = functionColor,
- ["sleep"] = functionColor,
- ["os.day"] = functionColor,
- ["os.setAlarm"] = functionColor,
- ["os.cancelAlarm"] = functionColor,
- ["os.shutdown"] = functionColor,
- ["os.reboot"] = functionColor,
- --paintutils
- ["paintutils"] = functionColor,
- ["paintutils.loadImage"] = functionColor,
- ["paintutils.drawImage"] = functionColor,
- ["paintutils.drawPixel"] = functionColor,
- ["paintutils.drawLine"] = functionColor,
- ["paintutils.drawBox"] = functionColor,
- ["paintutils.drawFilledBox"] = functionColor,
- --parallel
- ["parallel"] = functionColor,
- ["parallel.waitForAny"] = functionColor,
- ["parallel.waitForAll"] = functionColor,
- --peripheral
- ["peripheral"] = functionColor,
- ["peripheral.isPresent"] = functionColor,
- ["peripheral.getType"] = functionColor,
- ["peripheral.getMethods"] = functionColor,
- ["peripheral.call"] = functionColor,
- ["peripheral.wrap"] = functionColor,
- ["peripheral.find"] = functionColor,
- ["peripheral.getNames"] = functionColor,
- --rednet
- ["rednet"] = functionColor,
- ["rednet.open"] = functionColor,
- ["rednet.close"] = functionColor,
- ["rednet.send"] = functionColor,
- ["rednet.broadcast"] = functionColor,
- ["rednet.receive"] = functionColor,
- ["rednet.isOpen"] = functionColor,
- ["rednet.host"] = functionColor,
- ["rednet.unhost"] = functionColor,
- ["rednet.lookup"] = functionColor,
- ["rednet.run"] = functionColor,
- --redstone
- ["redstone"] = functionColor,
- ["redstone.getSides"] = functionColor,
- ["redstone.getInput"] = functionColor,
- ["redstone.setOutput"] = functionColor,
- ["redstone.getOutput"] = functionColor,
- ["redstone.getAnalogIutput"] = functionColor,
- ["redstone.setAnalogOutput"] = functionColor,
- ["redstone.getAnalogOutput"] = functionColor,
- ["redstone.getBundledOutput"] = functionColor,
- ["redstone.setBundledOutput"] = functionColor,
- ["redstone.getBundledIutput"] = functionColor,
- ["redstone.testBundledIutput"] = functionColor,
- --settings
- ["settings"] = functionColor,
- ["settings.set"] = functionColor,
- ["settings.get"] = functionColor,
- ["settings.unset"] = functionColor,
- ["settings.clear"] = functionColor,
- ["settings.getNames"] = functionColor,
- ["settings.load"] = functionColor,
- ["settings.save"] = functionColor,
- --shell
- ["shell"] = functionColor,
- ["shell.exit"] = functionColor,
- ["shell.run"] = functionColor,
- ["shell.dir"] = functionColor,
- ["shell.setDir"] = functionColor,
- ["shell.path"] = functionColor,
- ["shell.setPath"] = functionColor,
- ["shell.resolve"] = functionColor,
- ["shell.resolveProgram"] = functionColor,
- ["shell.aliases"] = functionColor,
- ["shell.setAlias"] = functionColor,
- ["shell.clearAlias"] = functionColor,
- ["shell.programs"] = functionColor,
- ["shell.getRunningProgram"] = functionColor,
- ["shell.openTab"] = functionColor,
- ["shell.switchTab"] = functionColor,
- ["shell.complete"] = functionColor,
- ["shell.completeProgram"] = functionColor,
- ["shell.setCompletionFunction"] = functionColor,
- ["shell.getCompletionInfo"] = functionColor,
- --string
- ["string"] = functionColor,
- ["string.byte"] = functionColor,
- ["string.char"] = functionColor,
- ["string.dump"] = functionColor,
- ["string.find"] = functionColor,
- ["string.format"] = functionColor,
- ["string.gmatch"] = functionColor,
- ["string.gsub"] = functionColor,
- ["string.len"] = functionColor,
- ["string.lower"] = functionColor,
- ["string.upper"] = functionColor,
- ["string.match"] = functionColor,
- ["string.rep"] = functionColor,
- ["string.reverse"] = functionColor,
- ["string.sub"] = functionColor,
- --table
- ["table"] = functionColor,
- ["table.concat"] = functionColor,
- ["table.insert"] = functionColor,
- ["table.maxn"] = functionColor,
- ["table.remove"] = functionColor,
- ["table.sort"] = functionColor,
- --term
- ["term"] = functionColor,
- ["term.write"] = functionColor,
- ["term.blit"] = functionColor,
- ["term.clear"] = functionColor,
- ["term.clearLine"] = functionColor,
- ["term.getCursorPos"] = functionColor,
- ["term.setCursorPos"] = functionColor,
- ["term.setCursorBlink"] = functionColor,
- ["term.isColor"] = functionColor,
- ["term.getSize"] = functionColor,
- ["term.scroll"] = functionColor,
- ["term.redirect"] = functionColor,
- ["term.current"] = functionColor,
- ["term.native"] = functionColor,
- ["term.setTextColor"] = functionColor,
- ["term.getTextColor"] = functionColor,
- ["term.setBackgroundColor"] = functionColor,
- ["term.getBackgroundColor"] = functionColor,
- --textutils
- ["textutils"] = functionColor,
- ["textutils.slowWrite"] = functionColor,
- ["textutils.slowPrint"] = functionColor,
- ["textutils.formatTime"] = functionColor,
- ["textutils.tabulate"] = functionColor,
- ["textutils.pagedTabulate"] = functionColor,
- ["textutils.pagedPrint"] = functionColor,
- ["textutils.serialize"] = functionColor,
- ["textutils.unserialize"] = functionColor,
- ["textutils.serializeJSON"] = functionColor,
- ["textutils.urlEncode"] = functionColor,
- ["textutils.complete"] = functionColor,
- --turtle
- ["turtle"] = functionColor,
- ["turtle.craft"] = functionColor,
- ["turtle.forward"] = functionColor,
- ["turtle.back"] = functionColor,
- ["turtle.up"] = functionColor,
- ["turtle.down"] = functionColor,
- ["turtle.turnLeft"] = functionColor,
- ["turtle.turnRight"] = functionColor,
- ["turtle.select"] = functionColor,
- ["turtle.getSelectedSlot"] = functionColor,
- ["turtle.getItemCount"] = functionColor,
- ["turtle.getItemSpace"] = functionColor,
- ["turtle.getItemDetail"] = functionColor,
- ["turtle.equipLeft"] = functionColor,
- ["turtle.equipRight"] = functionColor,
- ["turtle.attack"] = functionColor,
- ["turtle.attackUp"] = functionColor,
- ["turtle.attackDown"] = functionColor,
- ["turtle.dig"] = functionColor,
- ["turtle.digUp"] = functionColor,
- ["turtle.digDown"] = functionColor,
- ["turtle.place"] = functionColor,
- ["turtle.placeUp"] = functionColor,
- ["turtle.placeDown"] = functionColor,
- ["turtle.detect"] = functionColor,
- ["turtle.detectUp"] = functionColor,
- ["turtle.detectDown"] = functionColor,
- ["turtle.inspect"] = functionColor,
- ["turtle.inspectUp"] = functionColor,
- ["turtle.inspectDown"] = functionColor,
- ["turtle.compare"] = functionColor,
- ["turtle.compareUp"] = functionColor,
- ["turtle.compareDown"] = functionColor,
- ["turtle.compareTo"] = functionColor,
- ["turtle.drop"] = functionColor,
- ["turtle.dropUp"] = functionColor,
- ["turtle.dropDown"] = functionColor,
- ["turtle.suck"] = functionColor,
- ["turtle.suckUp"] = functionColor,
- ["turtle.suckDown"] = functionColor,
- ["turtle.refuel"] = functionColor,
- ["turtle.getFuelLevel"] = functionColor,
- ["turtle.getFuelLimit"] = functionColor,
- ["turtle.transferTo"] = functionColor,
- --vector
- ["vector"] = functionColor,
- ["vector.new"] = functionColor,
- --lua
- ["tonumber"] = functionColor,
- ["tostring"] = functionColor,
- ["print"] = functionColor,
- ["pairs"] = functionColor,
- ["ipairs"] = functionColor,
- ["pcall"] = functionColor,
- ["error"] = functionColor,
- }
- local function tryWrite(sLine, regex, color)
- local match = string.match(sLine, regex)
- if match then
- if type(color) == "number" then
- term.setTextColor(color)
- else
- term.setTextColor(color(match))
- end
- term.write(match)
- term.setTextColor(textColor)
- return string.sub(sLine, string.len(match) + 1)
- end
- return nil
- end
- local function writeHighlighted(sLine)
- function match(m)
- if tKeywords[m] then
- return tKeywords[m]
- end
- return textColor
- end
- while string.len(sLine) > 0 do
- sLine =
- tryWrite(sLine, "^%-%-%[%[.-%]%]", commentColor) or
- tryWrite(sLine, "^%-%-.*", commentColor) or
- tryWrite(sLine, "^\".-[^\\]\"", stringColor) or
- tryWrite(sLine, "^\'.-[^\\]\'", stringColor) or
- tryWrite(sLine, "^\"\"", stringColor) or
- tryWrite(sLine, "^''", stringColor) or
- tryWrite(sLine, "^%[%[.-%]%]", stringColor) or
- tryWrite(sLine, "^[.]+", operatorColor) or
- tryWrite(sLine, "^[%d%.]+", numberColor) or
- tryWrite(sLine, "^[%d%a%._]+", match) or
- tryWrite(sLine, "^[^%w_.]", operatorColor)
- end
- end
- local function redrawText()
- for y = 1,h - 1 do
- term.setCursorPos(1 - scrollX, y)
- term.clearLine()
- local sLine = tLines[y + scrollY]
- if sLine ~= nil then
- writeHighlighted(sLine)
- end
- end
- term.setCursorPos(x - scrollX, y - scrollY)
- end
- local function redrawLine(_nY)
- local sLine = tLines[_nY]
- term.setCursorPos(1 - scrollX, _nY - scrollY)
- term.clearLine()
- writeHighlighted(sLine)
- term.setCursorPos(x - scrollX, _nY - scrollY)
- end
- local function redrawMenu()
- -- Clear line
- term.setCursorPos(1, h)
- term.clearLine()
- -- Draw line numbers
- term.setCursorPos(w - string.len("Ln " .. y) + 1, h)
- term.setTextColor(highlightColor)
- term.write("Ln ")
- term.setTextColor(textColor)
- term.write(y)
- term.setCursorPos(1, h)
- if bMenu then
- -- Draw menu
- term.setTextColor(textColor)
- for nItem, sItem in pairs(tMenuItems) do
- if nItem == nMenuItem then
- term.setTextColor(highlightColor)
- term.write("[")
- term.setTextColor(textColor)
- term.write(sItem)
- term.setTextColor(highlightColor)
- term.write("]")
- term.setTextColor(textColor)
- else
- term.write(" " .. sItem .. " ")
- end
- end
- else
- -- Draw status
- term.setTextColor(highlightColor)
- term.write(sStatus)
- term.setTextColor(textColor)
- end
- -- Reset cursor
- term.setCursorPos(x - scrollX, y - scrollY)
- end
- local tMenuFuncs = {
- Save = function ()
- if bReadOnly then
- sStatus = "Access denied"
- else
- local ok, err = save(sPath)
- if ok then
- sStatus="Press Ctrl to access menu"
- else
- sStatus="Press Ctrl to access menu"
- end
- end
- redrawMenu()
- end,
- Print = function ()
- local printer = peripheral.find("printer")
- if not printer then
- sStatus = "No printer attached"
- return
- end
- local nPage = 0
- local sName = fs.getName(sPath)
- if printer.getInkLevel() < 1 then
- sStatus = "Printer out of ink"
- return
- elseif printer.getPaperLevel() < 1 then
- sStatus = "Printer out of paper"
- return
- end
- local screenTerminal = term.current()
- local printerTerminal = {
- getCursorPos = printer.getCursorPos,
- setCursorPos = printer.setCursorPos,
- getSize = printer.getPageSize,
- write = printer.write,
- }
- printerTerminal.scroll = function ()
- if nPage == 1 then
- printer.setPageTitle(sName .. " (page " .. nPage .. ")")
- end
- while not printer.newPage() do
- if printer.getInkLevel() < 1 then
- sStatus = "Printer out of ink, please refill"
- elseif printer.getPaperLevel() < 1 then
- sStatus = "Printer out of paper, please refill"
- else
- sStatus = "Printer output tray full, please empty"
- end
- term.redirect(screenTerminal)
- redrawMenu()
- term.redirect(printerTerminal)
- local timer = os.startTimer(0.5)
- sleep(0.5)
- end
- nPage = nPage + 1
- if nPage == 1 then
- printer.setPageTitle(sName)
- else
- printer.setPageTitle(sName .. " (page " .. nPage .. ")")
- end
- end
- bMenu = false
- term.redirect(printerTerminal)
- local ok, error = pcall(function ()
- term.scroll()
- for n, sLine in ipairs(tLines) do
- print(sLine)
- end
- end)
- term.redirect(screenTerminal)
- if not ok then
- print(error)
- end
- while not printer.endPage() do
- sStatus = "Printer output tray full, please empty"
- redrawMenu()
- sleep(0.5)
- end
- bMenu = true
- if nPage > 1 then
- sStatus = "Printed " .. nPage .. " Pages"
- else
- sStatus = "Printed 1 Page"
- end
- redrawMenu()
- end,
- Exit = function ()
- bRunning = false
- end
- }
- local function doMenuItem(_n)
- tMenuFuncs[tMenuItems[_n]]()
- if bMenu then
- bMenu = false
- term.setCursorBlink(true)
- end
- redrawMenu()
- end
- local function setCursor(x, y)
- local screenX = x - scrollX
- local screenY = y - scrollY
- local bRedraw = false
- if screenX < 1 then
- scrollX = x - 1
- screenX = 1
- bRedraw = true
- elseif screenX > w then
- scrollX = x - w
- screenX = w
- bRedraw = true
- end
- if screenY < 1 then
- scrollY = y - 1
- screenY = 1
- bRedraw = true
- elseif screenY > h - 1 then
- scrollY = y - (h - 1)
- screenY = h - 1
- bRedraw = true
- end
- if bRedraw then
- redrawText()
- end
- term.setCursorPos(screenX, screenY)
- -- Statusbar now pertains to menu, it would probably be safe to redraw the menu on every key event.
- redrawMenu()
- end
- -- Actual program functionality begins
- load(sPath)
- term.setBackgroundColor(bgColor)
- term.clear()
- term.setCursorPos(x, y)
- term.setCursorBlink(true)
- redrawText()
- redrawMenu()
- -- Handle input
- while bRunning do
- local sEvent, param, param2, param3 = os.pullEvent()
- if sEvent == "key" then
- if param == keys.up then
- -- Up
- if not bMenu then
- if y > 1 then
- -- Move cursor up
- y = y - 1
- x = math.min(x, string.len(tLines[y]) + 1)
- setCursor(x, y)
- end
- end
- elseif param == keys.down then
- -- Down
- if not bMenu then
- -- Move cursor down
- if y < #tLines then
- y = y + 1
- x = math.min(x, string.len(tLines[y]) + 1)
- setCursor(x, y)
- end
- end
- elseif param == keys.tab then
- -- Tab
- if not bMenu and not bReadOnly then
- -- Indent line
- tLines[y] = " " .. tLines[y]
- x = x + 2
- setCursor(x, y)
- redrawLine(y)
- end
- elseif param == keys.pageUp then
- -- Page Up
- if not bMenu then
- -- Move up a page
- if y - (h - 1) >= 1 then
- y = y - (h - 1)
- else
- y = 1
- end
- x = math.min(x, string.len(tLines[y]) + 1)
- setCursor(x, y)
- end
- elseif param == keys.pageDown then
- -- Page Down
- if not bMenu then
- -- Move down a page
- if y + (h - 1) <= #tLines then
- y = y + (h - 1)
- else
- y = #tLines
- end
- x = math.min(x, string.len(tLines[y]) + 1)
- setCursor(x, y)
- end
- elseif param == keys.home then
- -- Home
- if not bMenu then
- -- Move cursor to the beginning
- x = 1
- setCursor(x, y)
- end
- elseif param == keys["end"] then
- -- End
- if not bMenu then
- -- Move cursor to the end
- x = string.len(tLines[y]) + 1
- setCursor(x, y)
- end
- elseif param == keys.left then
- -- Left
- if not bMenu then
- if x > 1 then
- -- Move cursor left
- x = x - 1
- elseif x == 1 and y > 1 then
- x = string.len(tLines[y - 1]) + 1
- y = y - 1
- end
- setCursor(x, y)
- else
- -- Move menu left
- nMenuItem = nMenuItem - 1
- if nMenuItem < 1 then
- nMenuItem = #tMenuItems
- end
- redrawMenu()
- end
- elseif param == keys.right then
- -- Right
- if not bMenu then
- if x < string.len(tLines[y]) + 1 then
- -- Move cursor right
- x = x + 1
- elseif x == string.len(tLines[y]) + 1 and y < #tLines then
- x = 1
- y = y + 1
- end
- setCursor(x, y)
- else
- -- Move menu right
- nMenuItem = nMenuItem + 1
- if nMenuItem > #tMenuItems then
- nMenuItem = 1
- end
- redrawMenu()
- end
- elseif param == keys.delete then
- -- Delete
- if not bMenu and not bReadOnly then
- if x < string.len(tLines[y]) + 1 then
- local sLine = tLines[y]
- tLines[y] = string.sub(sLine, 1, x - 1) .. string.sub(sLine, x + 1)
- redrawLine(y)
- elseif y < #tLines then
- tLines[y] = tLines[y] .. tLines[y + 1]
- table.remove(tLines, y + 1)
- redrawText()
- redrawMenu()
- end
- end
- elseif param == keys.backspace then
- -- Backspace
- if not bMenu and not bReadOnly then
- if x > 1 then
- -- Remove character
- local sLine = tLines[y]
- tLines[y] = string.sub(sLine, 1, x - 2) .. string.sub(sLine, x)
- redrawLine(y)
- x = x - 1
- setCursor(x, y)
- elseif y > 1 then
- -- Remove newline
- local sPrevLen = string.len(tLines[y - 1])
- tLines[y - 1] = tLines[y - 1] .. tLines[y]
- table.remove(tLines, y)
- redrawText()
- x = sPrevLen + 1
- y = y - 1
- setCursor(x, y)
- end
- end
- elseif param == keys.enter then
- -- Enter
- if not bMenu and not bReadOnly then
- -- Newline
- local sLine = tLines[y]
- local _, spaces = string.find(sLine, "^[ ]+")
- if not spaces then
- spaces = 0
- end
- tLines[y] = string.sub(sLine, 1, x - 1)
- table.insert(tLines, y + 1, string.rep(' ', spaces) .. string.sub(sLine, x))
- redrawText()
- x = spaces + 1
- y = y + 1
- setCursor(x, y)
- elseif bMenu then
- -- Menu selection
- doMenuItem(nMenuItem)
- end
- elseif param == keys.leftCtrl then
- -- Menu toggle
- bMenu = not bMenu
- if bMenu then
- term.setCursorBlink(false)
- else
- term.setCursorBlink(true)
- end
- redrawMenu()
- end
- elseif sEvent == "char" then
- if not bMenu and not bReadOnly then
- -- Input text
- local sLine = tLines[y]
- tLines[y] = string.sub(sLine, 1, x - 1) .. param .. string.sub(sLine, x)
- redrawLine(y)
- x = x + 1
- setCursor(x, y)
- elseif bMenu then
- -- Select menu items
- for n, sMenuItem in ipairs(tMenuItems) do
- if string.lower(string.sub(sMenuItem, 1, 1)) == string.lower(param) then
- doMenuItem(n)
- break
- end
- end
- end
- elseif sEvent == "paste" then
- if not bMenu and not bReadOnly then
- -- Input text
- local sLine = tLines[y]
- tLines[y] = string.sub(sLine, 1, x - 1) .. param .. string.sub(sLine, x)
- redrawLine(y)
- x = x + string.len(param)
- setCursor(x, y)
- end
- elseif sEvent == "mouse_click" then
- if not bMenu then
- if param == 1 then
- -- Left click
- local cx, cy = param2, param3
- if cy < h then
- y = math.min(math.max(scrollY + cy, 1), #tLines)
- x = math.min(math.max(scrollX + cx, 1), string.len(tLines[y]) + 1)
- setCursor(x, y)
- end
- end
- end
- elseif sEvent == "mouse_scroll" then
- if not bMenu then
- if param == -1 then
- -- Scroll up
- if scrollY > 0 then
- -- Move cursor up
- scrollY = scrollY - 1
- redrawText()
- end
- elseif param == 1 then
- -- Scroll down
- local nMaxScroll = #tLines - (h - 1)
- if scrollY < nMaxScroll then
- -- Move cursor down
- scrollY = scrollY + 1
- redrawText()
- end
- end
- end
- elseif sEvent == "window_resize" then
- w, h = term.getSize()
- setCursor(x, y)
- redrawMenu()
- redrawText()
- end
- end
- -- Cleanup
- term.clear()
- term.setCursorBlink(false)
- term.setCursorPos(1, 1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement