minecraftwarlock

Edit++

Jul 5th, 2015
918
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 29.35 KB | None | 0 0
  1. -- Get file to edit
  2. local args = {...}
  3. if #args == 0 then
  4.     print("Usage: edit++ <path>")
  5.     return
  6. end
  7.  
  8. local original = shell.resolveProgram(args[1]) or args[1]
  9. if original:sub(1, 1) ~= "/" then
  10.     original = "/" .. original
  11. end
  12.  
  13. local x, y, names, lines, paths, dirs, positions, openPosition, opened, scrollX, scrollY, readOnly = {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}
  14. local w, h = term.getSize()
  15. local current
  16. local menuHeight = 1
  17. local lineNumLen
  18.  
  19. local running = true
  20.  
  21. -- Colors
  22. --Code
  23. local bgColor = colors.white
  24. local textColor = colors.black
  25. local keywordColor = colors.blue
  26. local commentColor = colors.green
  27. local stringColor = colors.lightGray
  28. local numberColor = colors.orange
  29. local functionColor = colors.cyan
  30. local varColor = colors.purple
  31.  
  32. --Menus
  33. local menuTextcolor = colors.white
  34. local selectedColor = colors.lightBlue
  35. local unselectedColor = colors.lightGray
  36. local lineNumColor = colors.gray
  37. local menuBgColor = colors.lightGray
  38. local openColor = colors.green
  39. local closeColor = colors.red
  40. local readOnlyColor = colors.yellow
  41.  
  42.  
  43. -- Menus
  44. local menu = false
  45. local menuItem = 1
  46. local menuItems = {"Save", "Exit", "Run"}
  47.    
  48. local status = "Press Ctrl to access menu"
  49. if string.len(status) > w - 5 then
  50.     status = "Press Ctrl for menu"
  51. end
  52.  
  53. local function load(_path)
  54.     temp = {}
  55.     if fs.exists(_path) then
  56.         local file = io.open(_path, "r")
  57.         local line = file:read()
  58.         while line do
  59.             table.insert(temp, line)
  60.             line = file:read()
  61.         end
  62.         file:close()
  63.     end
  64.    
  65.     if #temp == 0 then
  66.         table.insert(temp, "")
  67.     end
  68.    
  69.     return temp
  70. end
  71.  
  72. local function save(path)
  73.     if not readOnly[path] then
  74.         if not fs.exists(dirs[path]) then
  75.             fs.makeDir(dirs[path])
  76.         end
  77.  
  78.         local file = nil
  79.         local function innerSave()
  80.             file = fs.open(path, "w")
  81.             if file then
  82.                 for n, line in ipairs(lines[path]) do
  83.                     file.write(line .. "\n")
  84.                 end
  85.             else
  86.                 error("Failed to open "..path)
  87.             end
  88.         end
  89.        
  90.         local ok = pcall(innerSave)
  91.         if file then
  92.             file.close()
  93.         end
  94.         return ok
  95.     end
  96. end
  97.  
  98. local function open(path)
  99.     local name
  100.    
  101.     path = shell.resolveProgram(path) or path
  102.     if path:sub(1, 1) ~= "/" then
  103.         path = "/" .. path
  104.     end
  105.     name = string.gsub(path, "^.*/(.-)$", "%1")
  106.    
  107.     if opened[path] then
  108.         current = path
  109.         return
  110.     end
  111.     lines[path] = load(path)
  112.    
  113.     current = path
  114.     names[path] = name
  115.     paths[name] = path
  116.     dirs[path] = path:sub(1, path:len() - name:len())
  117.     opened[path] = true
  118.     x[path] = 1
  119.     y[path] = 1
  120.     scrollX[path] = 0
  121.     scrollY[path] = 0
  122.     readOnly[path] = fs.isReadOnly(path)
  123. end
  124.  
  125. local function close(path)
  126.     if current == original then
  127.         for k, _ in pairs(opened) do
  128.             original = k
  129.             break
  130.         end
  131.     end
  132.    
  133.     save(path)
  134.     paths[names[path]] = nil
  135.     dirs[path] = nil
  136.     names[path] = nil
  137.     lines[path] = nil
  138.     positions[path] = nil
  139.     opened[path] = nil
  140.     x[path] = nil
  141.     y[path] = nil
  142.     scrollX[path] = nil
  143.     scrollY[path] = nil
  144.    
  145.     if current == path then
  146.         current = original
  147.     end
  148. end
  149.  
  150. local keywords = {
  151.     ["and"] = true,
  152.     ["break"] = true,
  153.     ["do"] = true,
  154.     ["else"] = true,
  155.     ["elseif"] = true,
  156.     ["end"] = true,
  157.     ["false"] = true,
  158.     ["for"] = true,
  159.     ["function"] = true,
  160.     ["if"] = true,
  161.     ["in"] = true,
  162.     ["local"] = true,
  163.     ["nil"] = true,
  164.     ["not"] = true,
  165.     ["or"] = true,
  166.     ["repeat"] = true,
  167.     ["return"] = true,
  168.     ["then"] = true,
  169.     ["true"] = true,
  170.     ["until"]= true,
  171.     ["while"] = true,
  172. }
  173.  
  174. local functions = {
  175.     ["bit.band"] = true,
  176.     ["bit.blogic_rshift"] = true,
  177.     ["bit.bnot"] = true,
  178.     ["bit.bor"] = true,
  179.     ["bit.brshift"] = true,
  180.     ["bit.bxor"] = true,
  181.     ["bit.tobits"] = true,
  182.     ["bit.tonumb"] = true,
  183.     ["colors.combine"] = true,
  184.     ["colors.subtract"] = true,
  185.     ["colors.test"] = true,
  186.     ["commands.exec"] = true,
  187.     ["commands.execAsync"] = true,
  188.     ["commands.getBlockInfo"] = true,
  189.     ["commands.getBlockPosition"] = true,
  190.     ["commands.list"] = true,
  191.     ["disk.eject"] = true,
  192.     ["disk.getAudioTitle"] = true,
  193.     ["disk.getID"] = true,
  194.     ["disk.getLabel"] = true,
  195.     ["disk.getMountPath"] = true,
  196.     ["disk.hasAudio"] = true,
  197.     ["disk.hasData"] = true,
  198.     ["disk.isPresent"] = true,
  199.     ["disk.playAudio"] = true,
  200.     ["disk.setLabel"] = true,
  201.     ["disk.stopAudio"] = true,
  202.     ["help.completeTopic"] = true,
  203.     ["help.lookup"] = true,
  204.     ["help.path"] = true,
  205.     ["help.setPath"] = true,
  206.     ["help.topics"] = true,
  207.     ["keys.getName"] = true,
  208.     ["multishell.getCount"] = true,
  209.     ["multishell.getCurrent"] = true,
  210.     ["multishell.launch"] = true,
  211.     ["multishell.setFocus"] = true,
  212.     ["multishell.setTitle"] = true,
  213.     ["multishell.getFocus"] = true,
  214.     ["multishell.getTitle"] = true,
  215.     ["paintutils.drawBox"] = true,
  216.     ["paintutils.drawFilledBox"] = true,
  217.     ["paintutils.drawImage"] = true,
  218.     ["paintutils.drawPixel"] = true,
  219.     ["paintutils.loadImage"] = true,
  220.     ["parallel.waitForAll"] = true,
  221.     ["parallel.waitForAny"] = true,
  222.     ["rendet.broadcast"] = true,
  223.     ["rednet.close"] = true,
  224.     ["rednet.host"] = true,
  225.     ["rednet.isOpen"] = true,
  226.     ["rednet.lookup"] = true,
  227.     ["rednet.open"] = true,
  228.     ["rednet.receive"] = true,
  229.     ["rednet.run"] = true,
  230.     ["rednet.send"] = true,
  231.     ["rednet.unhost"] = true,
  232.     ["shell.aliases"] = true,
  233.     ["shell.complete"] = true,
  234.     ["shell.completeProgram"] = true,
  235.     ["shell.clearAlias"] = true,
  236.     ["shell.dir"] = true,
  237.     ["shell.exit"] = true,
  238.     ["shell.getCompletionInfo"] = true,
  239.     ["shell.getRunningProgram"] = true,
  240.     ["shell.openTab"] = true,
  241.     ["shell.path"] = true,
  242.     ["shell.programs"] = true,
  243.     ["shell.resolve"] = true,
  244.     ["shell.resolveProgram"] = true,
  245.     ["shell.run"] = true,
  246.     ["shell.setAlias"] = true,
  247.     ["shell.setCompletionFunction"] = true,
  248.     ["shell.setDir"] = true,
  249.     ["shell.setPath"] = true,
  250.     ["shell.switchTab"] = true,
  251.     ["term.blit"] = true,
  252.     ["term.clear"] = true,
  253.     ["term.clearLine"] = true,
  254.     ["term.current"] = true,
  255.     ["term.getBackgroundColor"] = true,
  256.     ["term.getBackgroundColour"] = true,
  257.     ["term.getCursorPos"] = true,
  258.     ["term.getSize"] = true,
  259.     ["term.getTextColor"] = true,
  260.     ["term.getTextColour"] = true,
  261.     ["term.isColor"] = true,
  262.     ["term.isColour"] = true,
  263.     ["term.native"] = true,
  264.     ["term.redirect"] = true,
  265.     ["term.scroll"] = true,
  266.     ["term.setBackgroundColor"] = true,
  267.     ["term.setBackgroundColour"] = true,
  268.     ["term.setCursorBlink"] = true,
  269.     ["term.setCursorPos"] = true,
  270.     ["term.setTextColor"] = true,
  271.     ["term.setTextColour"] = true,
  272.     ["textutils.complete"] = true,
  273.     ["textutils.formatTime"] = true,
  274.     ["textuitls.pagedPrint"] = true,
  275.     ["textutils.pagedTabulate"] = true,
  276.     ["textutils.serialize"] = true,
  277.     ["textutils.serializeJSON"] = true,
  278.     ["textutils.slowPrint"] = true,
  279.     ["textutils.slowWrite"] = true,
  280.     ["textutils.tabulate"] = true,
  281.     ["textutils.unserialize"] = true,
  282.     ["textutils.urlEncode"] = true,
  283.     ["turtle.craft"] = true,
  284.     ["turtle.forward"] = true,
  285.     ["turtle.back"] = true,
  286.     ["turtle.up"] = true,
  287.     ["turtle.down"] = true,
  288.     ["turtle.turnleft"] = true,
  289.     ["turtle.turnRight"] = true,
  290.     ["turtle.select"] = true,
  291.     ["turtle.getSelectedSlot"] = true,
  292.     ["turtle.getItemSpace"] = true,
  293.     ["turtle.getItemDetail"] = true,
  294.     ["turtle.equipLeft"] = true,
  295.     ["turtle.equipRight"] = true,
  296.     ["turtle.attack"] = true,
  297.     ["turtle.attackUp"] = true,
  298.     ["turtle.attackDown"] = true,
  299.     ["turtle.dig"] = true,
  300.     ["turtle.digUp"] = true,
  301.     ["turtle.digDown"] = true,
  302.     ["turtle.place"] = true,
  303.     ["turtle.placeUp"] = true,
  304.     ["turtle.placeDown"] = true,
  305.     ["turtle.detect"] = true,
  306.     ["turtle.detectUp"] = true,
  307.     ["turtle.detectDown"] = true,
  308.     ["turtle.inspect"] = true,
  309.     ["turtle.inspectUp"] = true,
  310.     ["turtle.inspectDown"] = true,
  311.     ["turtle.compare"] = true,
  312.     ["turtle.compareUp"] = true,
  313.     ["turtle.compareDown"] = true,
  314.     ["turtle.compareTo"] = true,
  315.     ["turtle.drop"] = true,
  316.     ["turtle.dropUp"] = true,
  317.     ["turtle.dropDown"] = true,
  318.     ["turtle.suck"] = true,
  319.     ["turtle.suckUp"] = true,
  320.     ["turtle.suckDown"] = true,
  321.     ["turtle.refuel"] = true,
  322.     ["turtle.getFuelLevel"] = true,
  323.     ["turtle.getFuelLimit"] = true,
  324.     ["turtle.transferTo"] = true,
  325.     ["vector.new"] = true,
  326.     ["window.create"] = true,
  327.     ["coroutine.create"] = true,
  328.     ["coroutine.resume"] = true,
  329.     ["coroutine.running"] = true,
  330.     ["coroutine.status"] = true,
  331.     ["coroutine.wrap"] = true,
  332.     ["coroutine.yield"] = true,
  333.     ["fs.combine"] = true,
  334.     ["fs.complete"] = true,
  335.     ["fs.copy"] = true,
  336.     ["fs.delete"] = true,
  337.     ["fs.exists"] = true,
  338.     ["fs.find"] = true,
  339.     ["fs.getDrive"] = true,
  340.     ["fs.getFreeSpace"] = true,
  341.     ["fs.getName"] = true,
  342.     ["fs.getSize"] = true,
  343.     ["fs.isDir"] = true,
  344.     ["fs.isReadOnly"] = true,
  345.     ["fs.list"] = true,
  346.     ["fs.makeDir"] = true,
  347.     ["fs.move"] = true,
  348.     ["fs.open"] = true,
  349.     ["http.get"] = true,
  350.     ["http.post"] = true,
  351.     ["http.request"] = true,
  352.     ["os.clock"] = true,
  353.     ["os.day"] = true,
  354.     ["os.getComputerID"] = true,
  355.     ["os.getComputerLabel"] = true,
  356.     ["os.pullEvent"] = true,
  357.     ["os.pullEventRaw"] = true,
  358.     ["os.queueEvent"] = true,
  359.     ["os.reboot"] = true,
  360.     ["os.run"] = true,
  361.     ["os.setAlarm"] = true,
  362.     ["os.setComputerLabel"] = true,
  363.     ["os.shutdown"] = true,
  364.     ["os.sleep"] = true,
  365.     ["os.startTimer"] = true,
  366.     ["os.time"] = true,
  367.     ["os.version"] = true,
  368.     ["peripheral.call"] = true,
  369.     ["peripheral.find"] = true,
  370.     ["peripheral.getMethods"] = true,
  371.     ["peripheral.getNames"] = true,
  372.     ["peripheral.getType"] = true,
  373.     ["peripheral.isPresent"] = true,
  374.     ["peripheral.wrap"] = true,
  375.     ["print"] = true,
  376.     ["redstone.getAnalogInput"] = true,
  377.     ["redstone.getAnalogOutput"] = true,
  378.     ["redstone.getBundledInput"] = true,
  379.     ["redstone.getInput"] = true,
  380.     ["redstone.getOutput"] = true,
  381.     ["redstone.getSides"] = true,
  382.     ["redstone.setAnalogOutput"] = true,
  383.     ["redstone.setBundledOutput"] = true,
  384.     ["redstone.setOutput"] = true,
  385.     ["redstone.testBundledInput"] = true,
  386.     ["tonumber"] = true,
  387.     ["tostring"] = true,
  388.     ["write"] = true,
  389.     ["assert"] = true,
  390.     ["dofile"] = true,
  391.     ["error"] = true,
  392.     ["getfenv"] = true,
  393.     ["getmetatable"] = true,
  394.     ["ipairs"] = true,
  395.     ["loadfile"] = true,
  396.     ["loadstring"] = true,
  397.     ["next"] = true,
  398.     ["pairs"] = true,
  399.     ["pcall"] = true,
  400.     ["rawequal"] = true,
  401.     ["rawget"] = true,
  402.     ["rawset"] = true,
  403.     ["select"] = true,
  404.     ["setfenv"] = true,
  405.     ["setmetatable"] = true,
  406.     ["type"] = true,
  407.     ["unpack"] = true,
  408.     ["xpcall"] = true,
  409.     ["io.close"] = true,
  410.     ["io.flush"] = true,
  411.     ["io.input"] = true,
  412.     ["io.lines"] = true,
  413.     ["io.open"] = true,
  414.     ["io.output"] = true,
  415.     ["io.read"] = true,
  416.     ["io.type"] = true,
  417.     ["io.write"] = true,
  418.     ["math.abs"] = true,
  419.     ["math.acos"] = true,
  420.     ["math.asin"] = true,
  421.     ["math.atan"] = true,
  422.     ["math.atan2"] = true,
  423.     ["math.ceil"] = true,
  424.     ["math.cos"] = true,
  425.     ["math.cosh"] = true,
  426.     ["math.deg"] = true,
  427.     ["math.exp"] = true,
  428.     ["math.floor"] = true,
  429.     ["math.fmod"] = true,
  430.     ["math.frexp"] = true,
  431.     ["math.ldexp"] = true,
  432.     ["math.log"] = true,
  433.     ["math.log10"] = true,
  434.     ["math.max"] = true,
  435.     ["math.min"] = true,
  436.     ["math.modf"] = true,
  437.     ["math.rad"] = true,
  438.     ["math.random"] = true,
  439.     ["math.randomseed"] = true,
  440.     ["math.sin"] = true,
  441.     ["math.sinh"] = true,
  442.     ["math.sqrt"] = true,
  443.     ["math.tan"] = true,
  444.     ["math.tanh"] = true,
  445.     ["string.byte"] = true,
  446.     ["string.char"] = true,
  447.     ["string.dump"] = true,
  448.     ["string.find"] = true,
  449.     ["string.format"] = true,
  450.     ["string.gmatch"] = true,
  451.     ["string.gsub"] = true,
  452.     ["string.len"] = true,
  453.     ["string.lower"] = true,
  454.     ["string.match"] = true,
  455.     ["string.rep"] = true,
  456.     ["string.reverse"] = true,
  457.     ["string.sub"] = true,
  458.     ["string.upper"] = true,
  459.     ["table.concat"] = true,
  460.     ["table.insert"] = true,
  461.     ["table.maxn"] = true,
  462.     ["table.remove"] = true,
  463.     ["table.sort"] = true,
  464.     ["gps.locate"] = true,
  465.    
  466. }
  467.  
  468. local vars = {
  469.     ["colors.white"] = true,
  470.     ["colors.orange"] = true,
  471.     ["colors.magenta"] = true,
  472.     ["colors.lightBlue"] = true,
  473.     ["colors.yellow"] = true,
  474.     ["colors.lime"] = true,
  475.     ["colors.pink"] = true,
  476.     ["colors.gray"] = true,
  477.     ["colors.lightGray"] = true,
  478.     ["colors.cyan"] = true,
  479.     ["colors.purple"] = true,
  480.     ["colors.blue"] = true,
  481.     ["colors.brown"] = true,
  482.     ["colors.green"] = true,
  483.     ["colors.red"] = true,
  484.     ["colors.black"] = true,
  485.     ["_G"] = true,
  486.     ["_VERSION"] = true,
  487.     ["_CC_VERSION"] = true,
  488.     ["_MC_VERSION"] = true,
  489.     ["math.huge"] = true,
  490.     ["math.pi"] = true,
  491.     ["keys.a"] = true,
  492.     ["keys.b"] = true,
  493.     ["keys.c"] = true,
  494.     ["keys.d"] = true,
  495.     ["keys.e"] = true,
  496.     ["keys.f"] = true,
  497.     ["keys.g"] = true,
  498.     ["keys.h"] = true,
  499.     ["keys.i"] = true,
  500.     ["keys.j"] = true,
  501.     ["keys.k"] = true,
  502.     ["keys.l"] = true,
  503.     ["keys.m"] = true,
  504.     ["keys.n"] = true,
  505.     ["keys.o"] = true,
  506.     ["keys.p"] = true,
  507.     ["keys.q"] = true,
  508.     ["keys.r"] = true,
  509.     ["keys.s"] = true,
  510.     ["keys.t"] = true,
  511.     ["keys.u"] = true,
  512.     ["keys.v"] = true,
  513.     ["keys.w"] = true,
  514.     ["keys.x"] = true,
  515.     ["keys.y"] = true,
  516.     ["keys.z"] = true,
  517.     ["keys.one"] = true,
  518.     ["keys.two"] = true,
  519.     ["keys.three"] = true,
  520.     ["keys.four"] = true,
  521.     ["keys.five"] = true,
  522.     ["keys.six"] = true,
  523.     ["keys.seven"] = true,
  524.     ["keys.eight"] = true,
  525.     ["keys.nine"] = true,
  526.     ["keys.zero"] = true,
  527.     ["keys.minus"] = true,
  528.     ["keys.equals"] = true,
  529.     ["keys.backspace"] = true,
  530.     ["keys.tab"] = true,
  531.     ["keys.leftBracket"] = true,
  532.     ["keys.rightBracket"] = true,
  533.     ["keys.enter"] = true,
  534.     ["keys.leftCtrl"] = true,
  535.     ["keys.semiColon"] = true,
  536.     ["keys.apostrophe"] = true,
  537.     ["keys.grave"] = true,
  538.     ["keys.leftShift"] = true,
  539.     ["keys.backslash"] = true,
  540.     ["keys.comma"] = true,
  541.     ["keys.period"] = true,
  542.     ["keys.slash"] = true,
  543.     ["keys.rightShift"] = true,
  544.     ["keys.multiply"] = true,
  545.     ["keys.leftAlt"] = true,
  546.     ["keys.space"] = true,
  547.     ["keys.capsLock"] = true,
  548.     ["keys.f1"] = true,
  549.     ["keys.f2"] = true,
  550.     ["keys.f3"] = true,
  551.     ["keys.f4"] = true,
  552.     ["keys.f5"] = true,
  553.     ["keys.f6"] = true,
  554.     ["keys.f7"] = true,
  555.     ["keys.f8"] = true,
  556.     ["keys.f9"] = true,
  557.     ["keys.f10"] = true,
  558.     ["keys.numLock"] = true,
  559.     ["keys.scollLock"] = true,
  560.     ["keys.numPad7"] = true,
  561.     ["keys.numPad8"] = true,
  562.     ["keys.numPad9"] = true,
  563.     ["keys.numPadSubtract"] = true,
  564.     ["keys.numPad4"] = true,
  565.     ["keys.numPad5"] = true,
  566.     ["keys.numPad6"] = true,
  567.     ["keys.numPadAdd"] = true,
  568.     ["keys.numPad1"] = true,
  569.     ["keys.numPad2"] = true,
  570.     ["keys.numPad3"] = true,
  571.     ["keys.numPad0"] = true,
  572.     ["keys.numPadDecimal"] = true,
  573.     ["keys.f11"] = true,
  574.     ["keys.f12"] = true,
  575.     ["keys.f13"] = true,
  576.     ["keys.f14"] = true,
  577.     ["keys.f15"] = true,
  578.     ["keys.kana"] = true,
  579.     ["keys.convert"] = true,
  580.     ["keys.noconvert"] = true,
  581.     ["keys.yen"] = true,
  582.     ["keys.numPadEquals"] = true,
  583.     ["keys.cimcumflex"] = true,
  584.     ["keys.at"] = true,
  585.     ["keys.colon"] = true,
  586.     ["keys.underscore"] = true,
  587.     ["keys.kanji"] = true,
  588.     ["keys.stop"] = true,
  589.     ["keys.ax"] = true,
  590.     ["keys.numPadEnter"] = true,
  591.     ["keys.rightCtrl"] = true,
  592.     ["keys.numPadComma"] = true,
  593.     ["keys.numPadDivide"] = true,
  594.     ["keys.rightAlt"] = true,
  595.     ["keys.pause"] = true,
  596.     ["keys.home"] = true,
  597.     ["keys.up"] = true,
  598.     ["keys.pageUp"] = true,
  599.     ["keys.left"] = true,
  600.     ["keys.right"] = true,
  601.     ["keys.down"] = true,
  602.     ["keys.pageDown"] = true,
  603.     ["keys.insert"] = true,
  604.     ["keys.delete"] = true,
  605. }
  606.  
  607. local function tryWrite(line, regex, color)
  608.     local match = string.match(line, regex)
  609.     if match then
  610.         if type(color) == "number" then
  611.             term.setTextColor(color)
  612.         else
  613.             term.setTextColor(color(match))
  614.         end
  615.         term.write(match)
  616.         term.setTextColor(textColor)
  617.         return string.sub(line, string.len(match) + 1)
  618.     end
  619.     return nil
  620. end
  621.  
  622. local function writeHighlighted(line)
  623.     while string.len(line) > 0 do  
  624.         line =
  625.             tryWrite(line, "^%-%-%[%[.-%]%]", commentColor) or
  626.             tryWrite(line, "^%-%-.*", commentColor) or
  627.             tryWrite(line, "^\".-[^\\]\"", stringColor) or
  628.             tryWrite(line, "^\'.-[^\\]\'", stringColor) or
  629.             tryWrite(line, "^%[%[.-%]%]", stringColor) or
  630.             tryWrite(line, "^%-?%d+", numberColor) or
  631.             tryWrite(line, "^%-?%d+%.%d+", numberColor) or
  632.             tryWrite(line, "^%-?%d+[eE][%+%-]%d+", numberColor) or
  633.             tryWrite(line, "^%-?%d+[eE]%d+", numberColor) or
  634.             tryWrite(line, "^%-?%d+%.%d+[eE][%+%-]%d+", numberColor) or
  635.             tryWrite(line, "^%-?%d+%.%d+[eE]%d+", numberColor) or
  636.             tryWrite(line, "^[%w_]+%.[%w_]+", function(match)
  637.                 if functions[match] then
  638.                     return functionColor
  639.                 elseif vars[match] then
  640.                     return varColor
  641.                 end
  642.                 return textColor
  643.             end) or
  644.             tryWrite(line, "^[%w_]+", function(match)
  645.                 if keywords[match] then
  646.                     return keywordColor
  647.                 elseif functions[match] then
  648.                     return functionColor
  649.                 elseif vars[match] then
  650.                     return varColor
  651.                 end
  652.                 return textColor
  653.             end) or
  654.             tryWrite(line, "^[^%w_]", textColor)
  655.     end
  656. end
  657.  
  658. local function redrawHead()
  659.     menuHeight = 1
  660.     term.setBackgroundColor(menuBgColor)
  661.     term.setCursorPos(1, menuHeight)
  662.     term.clearLine()
  663.    
  664.     for k, v in pairs(names) do
  665.    
  666.         term.setTextColor(menuTextcolor)
  667.        
  668.         if readOnly[k] then
  669.             term.setTextColor(readOnlyColor)
  670.         end
  671.        
  672.         if term.getCursorPos() > w - v:len() - 1 then
  673.             menuHeight = menuHeight + 1
  674.             term.setCursorPos(1, menuHeight)
  675.             term.setBackgroundColor(menuBgColor)
  676.             term.clearLine()
  677.         end
  678.        
  679.         positions[k] = {term.getCursorPos()}
  680.        
  681.         if k == current then
  682.             term.setBackgroundColor(selectedColor)
  683.         else
  684.             term.setBackgroundColor(unselectedColor)
  685.         end
  686.        
  687.         term.write(v)
  688.         term.setTextColor(closeColor)
  689.         term.write("x ")
  690.     end
  691.    
  692.     term.setBackgroundColor(menuBgColor)
  693.     if term.getCursorPos() > w then
  694.         menuHeight = menuHeight + 1
  695.         term.setCursorPos(1, menuHeight)
  696.         term.setBackgroundColor(menuBgColor)
  697.         term.clearLine()
  698.     end
  699.    
  700.     openPosition = {term.getCursorPos()}
  701.     term.setTextColor(openColor)
  702.     term.write("+")
  703. end
  704.  
  705. local function insureLength(s, len)
  706.     while s:len() < len do
  707.         s = s .. " "
  708.     end
  709.     return s
  710. end
  711.  
  712. local function redrawLine(i)
  713.     if lines[current][i] ~= nil then
  714.         writeHighlighted(lines[current][i])
  715.     end
  716.        
  717.         term.setCursorPos(1, i + menuHeight - scrollY[current])
  718.         term.setBackgroundColor(menuBgColor)
  719.         term.setTextColor(lineNumColor)
  720.         term.write(insureLength(tostring(i), lineNumLen))
  721. end
  722.  
  723. local function redrawText(cursorBlink)
  724.     lineNumLen = math.max(string.len(tostring(#lines[current])), 2)
  725.     for i = 1, h - menuHeight do
  726.         term.setCursorPos(lineNumLen + 1 - scrollX[current], i + menuHeight)
  727.         term.setBackgroundColor(bgColor)
  728.         term.clearLine()
  729.         redrawLine(i + scrollY[current])
  730.     end
  731.    
  732.     if cursorBlink == nil then
  733.         cursorBlink = true
  734.     end
  735.    
  736.     if x[current] - scrollX[current] < 1 or y[current] - scrollY[current] < 1 then
  737.         term.setCursorBlink(false)
  738.     else
  739.         if type(cursorBlink) ~= "boolean" then
  740.             error(type(cursorBlink))
  741.         end
  742.         term.setCursorBlink(cursorBlink)
  743.     end
  744.    
  745.     term.setTextColor(textColor)
  746.     term.setCursorPos(x[current] - scrollX[current] + lineNumLen, y[current] - scrollY[current] + menuHeight)
  747. end
  748.  
  749. local function drawCursor()
  750.     local screenX = x[current] - scrollX[current]
  751.     local screenY = y[current] - scrollY[current]
  752.    
  753.     local redraw = false
  754.     if screenX < 1 then
  755.         scrollX[current] = x[current] - 1
  756.         screenX = 1
  757.         redraw = true
  758.     elseif screenX > w - lineNumLen then
  759.         scrollX[current] = x[current] - w + lineNumLen
  760.         screenX = w - lineNumLen
  761.         redraw = true
  762.     end
  763.    
  764.     if screenY < 1 then
  765.         scrollY[current] = y[current] - 1
  766.         screenY = 1
  767.         redraw = true
  768.     elseif screenY > h - menuHeight then
  769.         scrollY[current] = y[current] - h + menuHeight
  770.         screenY = h - menuHeight
  771.         redraw = true
  772.     end
  773.    
  774.     if redraw then
  775.         redrawText()
  776.     end
  777.    
  778.     if cursorBlink == nil then
  779.         cursorBlink = true
  780.     end
  781.    
  782.     if screenX < 1 or screenY < 1 then
  783.         term.setCursorBlink(false)
  784.     else
  785.         term.setCursorBlink(cursorBlink)
  786.     end
  787.    
  788.     term.setTextColor(textColor)
  789.     term.setCursorPos(screenX + lineNumLen, screenY + menuHeight)
  790. end
  791.  
  792. local function redrawMenu()
  793.     if menu then
  794.         term.setCursorBlink(false)
  795.         term.setCursorPos(1, h)
  796.         term.clearLine()
  797.        
  798.         term.setTextColor(textColor)
  799.         for k, v in ipairs(menuItems) do
  800.             if k == menuItem then
  801.                 term.setTextColor(selectedColor)
  802.             else
  803.                 term.setTextColor(menuTextcolor)
  804.             end
  805.             term.write("[")
  806.             term.write(v)
  807.             term.write("]")
  808.         end
  809.     end
  810. end
  811.  
  812. local menuFuncs = {
  813.     Save = function()
  814.         for k, _ in pairs(opened) do
  815.             save(k)
  816.         end
  817.     end,
  818.    
  819.     Exit = function()
  820.         running = false
  821.     end,
  822.     Run = function()
  823.         for k, _ in pairs(opened) do
  824.             save(k)
  825.         end
  826.         term.setBackgroundColor(colors.black)
  827.         term.setTextColor(colors.white)
  828.         term.setCursorPos(1, 1)
  829.         term.clear()
  830.         term.write("Arguments: ")
  831.         shell.run(current .. " " .. read())
  832.         term.setBackgroundColor(colors.black)
  833.         term.setTextColor(colors.white)
  834.         print("press enter to return to edit++...")
  835.         while true do
  836.             local event, a = os.pullEvent()
  837.             if event == "key" and a == keys.enter then break end
  838.         end
  839.         redrawHead()
  840.         redrawText()
  841.         redrawMenu()
  842.     end
  843. }
  844.  
  845. local function doMenuItem(i)
  846.     menuFuncs[menuItems[i]]()
  847.     menu = false
  848.     redrawText()
  849. end
  850.  
  851. local function fullList(dir)
  852.     local contents = fs.list(dir)
  853.     contents.fullName = dir
  854.     contents.name = fs.getName(dir)
  855.     contents.open = true
  856.     for k, v in ipairs(contents) do
  857.         if fs.isDir(dir .. v) then
  858.             contents[k] = fullList(dir .. v .. "/")
  859.         else
  860.             contents[k] = dir .. contents[k]
  861.         end
  862.     end
  863.     return contents
  864. end
  865.  
  866. local function renderFolder(contents)
  867.     term.setTextColor(colors.green)
  868.     local _, indentation = string.gsub(contents.fullName, "/", "/")
  869.     if contents.open then
  870.         term.write(string.rep("  ", indentation - 1) .. "v " .. contents.name)
  871.         local _, _y = term.getCursorPos()
  872.         for k, v in ipairs(contents) do
  873.             term.setCursorPos(1, _y + 1)
  874.             if type(v) == "string" then
  875.                 term.setTextColor(colors.white)
  876.                 term.write(string.rep("  ", indentation) .. fs.getName(v))
  877.             else
  878.                 renderFolder(v)
  879.             end
  880.             _, _y = term.getCursorPos()
  881.         end
  882.     else
  883.         term.write(string.rep("  ", indentation - 1) .. "> " .. contents.name)
  884.     end
  885. end
  886.  
  887. local function fileChooser()
  888.     term.setBackgroundColor(colors.black)
  889.     term.setTextColor(colors.white)
  890.     term.clear()
  891.     term.setCursorPos(1, 1)
  892.     term.setCursorBlink(false)
  893.     local contents = fullList("/")
  894.     renderFolder(contents)
  895.     sleep(10)
  896.     return current
  897. end
  898.    
  899.  
  900. term.setBackgroundColor(bgColor)
  901. term.clear()
  902. open(original)
  903. redrawHead()
  904. redrawText()
  905. redrawMenu()
  906. drawCursor()
  907.  
  908. while running do
  909.     local event, a, b, c = os.pullEvent()
  910.     if event == "key" then
  911.         if a == keys.up then
  912.             if not menu then
  913.                 if y[current] > 1 then
  914.                     y[current] = y[current] - 1
  915.                     x[current] = math.min(x[current], string.len(lines[current][y[current]]) + 1)
  916.                     drawCursor()
  917.                 end
  918.             end
  919.         elseif a == keys.down then
  920.             if not menu then
  921.                 if y[current] < #lines[current] then
  922.                     y[current] = y[current] + 1
  923.                     x[current] = math.min( x[current], string.len(lines[current][y[current]]) + 1)
  924.                     drawCursor()
  925.                 end
  926.             end
  927.         elseif a == keys.tab then
  928.             if not menu and not readOnly[current] then
  929.                 lines[current][y[current]] = "  " .. lines[current][y[current]]
  930.                 x[current] = x[current] + 2
  931.                 drawCursor()
  932.                 redrawText()
  933.             end
  934.         elseif a == keys.pageUp then
  935.             if not menu then
  936.                 if y[current] - (h - menuHeight) >= 1 then
  937.                     y[current] = y[current] - (h - menuHeight)
  938.                 else
  939.                     y[current] = 1
  940.                 end
  941.                 x[current] = math.min(x[current], string.len(lines[current][y[current]]) + 1)
  942.                 drawCursor()
  943.             end
  944.         elseif a == keys.pageDown then
  945.             if not menu then
  946.                 if y[current] + (h - menuHeight) <= #lines[current] then
  947.                     y[current] = y[current] + (h - menuHeight)
  948.                 else
  949.                     y[current] = #lines[current]
  950.                 end
  951.                 x[current] = math.min(x[current], string.len(lines[current][y[current]]) + 1)
  952.                 drawCursor()
  953.             end
  954.         elseif a == keys.home then
  955.             if not menu then
  956.                 x[current] = 1
  957.                 drawCursor()
  958.             end
  959.         elseif a == keys["end"] then
  960.             if not menu then
  961.                 x[current] = string.len(lines[current][y[current]]) + 1
  962.                 drawCursor()
  963.             end
  964.         elseif a == keys.left then
  965.             if not menu then
  966.                 if x[current] > 1 then
  967.                     x[current] = x[current] - 1
  968.                 elseif x[current] == 1 and y[current] > 1 then
  969.                     x[current] = string.len(lines[current][y[current] - 1]) + 1
  970.                     y[current] = y[current] - 1
  971.                 end
  972.                 drawCursor()
  973.             else
  974.                 menuItem = menuItem - 1
  975.                 if menuItem < 1 then
  976.                     menuItem = #menuItems
  977.                 end
  978.                 redrawMenu()
  979.             end
  980.         elseif a == keys.right then
  981.             if not menu then
  982.                 if x[current] < string.len(lines[current][y[current]]) + 1 then
  983.                     x[current] = x[current] + 1
  984.                 elseif x[current] == string.len(lines[current][y[current]]) + 1 and y[current] < #lines[current] then
  985.                     x[current] = 1
  986.                     y[current] = y[current] + 1
  987.                 end
  988.                 drawCursor()
  989.             else
  990.                 menuItem = menuItem + 1
  991.                 if menuItem > #menuItems then
  992.                     menuItem = 1
  993.                 end
  994.                 redrawMenu()
  995.             end
  996.         elseif a == keys.delete then
  997.             if not menu and not readOnly[current] then
  998.                 if  x[current] < string.len(lines[current][y[current]]) + 1 then
  999.                     local line = lines[current][y[current]]
  1000.                     lines[current][y[current]] = string.sub(line, 1, x[current] - 1) .. string.sub(line, x[current] + 1)
  1001.                     redrawText()
  1002.                 elseif y[current] < #lines[current] then
  1003.                     lines[current][y[current]] = lines[current][y[current]] .. lines[current][y[current] + 1]
  1004.                     table.remove(lines[current], y[current] + 1)
  1005.                     redrawText()
  1006.                 end
  1007.             end
  1008.         elseif a == keys.backspace then
  1009.             if not menu and not readOnly[current] then
  1010.                 if x[current] > 1 then
  1011.                     local line = lines[current][y[current]]
  1012.                     lines[current][y[current]] = string.sub(line, 1, x[current] - 2) .. string.sub(line, x[current])
  1013.                     redrawText()
  1014.            
  1015.                     x[current] = x[current] - 1
  1016.                     drawCursor()
  1017.                 elseif y[current] > 1 then
  1018.                     local prevLen = string.len(lines[current][y[current] - 1])
  1019.                     lines[current][y[current] - 1] = lines[current][y[current] - 1] .. lines[current][y[current]]
  1020.                     table.remove(lines[current], y[current])
  1021.                     redrawText()
  1022.                
  1023.                     x[current] = prevLen + 1
  1024.                     y[current] = y[current] - 1
  1025.                     drawCursor()
  1026.                 end
  1027.             end
  1028.         elseif a == keys.leftCtrl or a == 157 then
  1029.             if menu then
  1030.                 menu = false
  1031.                 redrawText()
  1032.             else
  1033.                 menu = true
  1034.                 redrawMenu()
  1035.             end
  1036.         elseif a == keys.enter then
  1037.             if not menu and not readOnly[current] then
  1038.                 line = lines[current][y[current]]
  1039.                 local _, spaces = string.find(line, "^[ ]+")
  1040.                 if not spaces then
  1041.                     spaces = 0
  1042.                 end
  1043.                
  1044.                 lines[current][y[current]] = string.sub(line, 1, x[current] - 1)
  1045.                
  1046.            
  1047.                 table.insert(lines[current], y[current] + 1, string.rep(" ", spaces) .. string.sub(line, x[current]))
  1048.                
  1049.                 x[current] = spaces + 1
  1050.                 y[current] = y[current] + 1
  1051.                 redrawText()
  1052.                 drawCursor()
  1053.             elseif menu then
  1054.                 doMenuItem(menuItem)
  1055.             end
  1056.         end
  1057.     elseif event == "char" then
  1058.         if not (menu or readOnly[current]) then
  1059.             local line = lines[current][y[current]]
  1060.             lines[current][y[current]] = string.sub(line, 1, x[current] - 1) .. a .. string.sub(line, x[current])
  1061.             redrawText()
  1062.        
  1063.             x[current] = x[current] + 1
  1064.             drawCursor()
  1065.             term.setTextColor(colors.black)
  1066.         elseif menu then
  1067.             for i, _menuItem in ipairs(menuItems) do
  1068.                 if string.lower(string.sub(_menuItem, 1, 1)) == string.lower(a) then
  1069.                     doMenuItem(i)
  1070.                     break
  1071.                 end
  1072.             end
  1073.         end
  1074.     elseif event == "paste" then
  1075.         if not menu and not readOnly[current] then
  1076.             local line = lines[current][y[current]]
  1077.             lines[current][y[current]] = string.sub(line, 1, x[current] - 1) .. a .. string.sub(line, x[current])
  1078.             redrawText()
  1079.  
  1080.             x[current] = x[current] + string.len(a)
  1081.             drawCursor()
  1082.         end
  1083.     elseif event == "mouse_click" then
  1084.         if a == 1 then
  1085.             local cx,cy = b, c
  1086.             if not menu and cy > menuHeight and cx > lineNumLen then
  1087.                 y[current] = math.min(math.max(scrollY[current] + cy - menuHeight, 1), #lines[current])
  1088.                 x[current] = math.min(math.max(scrollX[current] + cx - lineNumLen, 1), string.len(lines[current][y[current]]) + 1)
  1089.                 drawCursor()
  1090.             elseif cy <= menuHeight then
  1091.                 for k, v in pairs(positions) do
  1092.                     if cx == v[1] + string.len(names[k]) and cy == v[2] then
  1093.                         save(k)
  1094.                         close(k)
  1095.                         local i = 0
  1096.                         for k, v in pairs(opened) do
  1097.                             i = i + 1
  1098.                         end
  1099.                         if i == 0 then
  1100.                             running = false
  1101.                             break
  1102.                         end
  1103.                         redrawHead()
  1104.                         redrawText()
  1105.                         redrawMenu()
  1106.                         break
  1107.                     elseif cx >= v[1] and cx < v[1] + string.len(names[k]) + 2 and cy == v[2] then
  1108.                         current = k
  1109.                         redrawHead()
  1110.                         redrawText()
  1111.                         redrawMenu()
  1112.                         break
  1113.                     end
  1114.                 end
  1115.                 if cx == openPosition[1] and cy == openPosition[2] then
  1116.                     -- open(fileChooser())
  1117.                     term.setBackgroundColor(colors.black)
  1118.                     term.setTextColor(colors.white)
  1119.                     term.clear()
  1120.                     term.setCursorPos(1, 1)
  1121.                     term.write("Select a file: ")
  1122.                     open(read())
  1123.                     redrawHead()
  1124.                     redrawText()
  1125.                     redrawMenu()
  1126.                 end
  1127.             end
  1128.         end
  1129.     elseif event == "mouse_scroll" then
  1130.         if not menu then
  1131.             if a == -1 then
  1132.                 if scrollY[current] > 0 then
  1133.                     scrollY[current] = scrollY[current] - 1
  1134.                     redrawText()
  1135.                 end
  1136.             elseif a == 1 then
  1137.                 local maxScroll = #lines[current] - (h - 1)
  1138.                 if scrollY[current] < maxScroll then
  1139.                     scrollY[current] = scrollY[current] + 1
  1140.                     redrawText()
  1141.                 end
  1142.                
  1143.             end
  1144.         end
  1145.     elseif event == "term_resize" then
  1146.         w, h = term.getSize()
  1147.         redrawHead()
  1148.         redrawText()
  1149.         redrawMenu()
  1150.         drawCursor()
  1151.     end
  1152. end
  1153.  
  1154. term.setBackgroundColor(colors.black)
  1155. term.clear()
  1156. term.setCursorPos(1, 1)
Advertisement
Add Comment
Please, Sign In to add comment