Advertisement
minimite

redit

Nov 1st, 2014
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.45 KB | None | 0 0
  1. --Program to not allow the user to modifiy the program
  2. --Just like in the rom folder in ComputerCraft
  3. --By minimite, modified from Dan200
  4. --For ComputerCraft, a minecraft mod
  5.  
  6. -- Get file to edit
  7. local tArgs = { ... }
  8. if #tArgs == 0 then
  9.     print( "Usage: redit <path>" )
  10.     return
  11. end
  12.  
  13. -- Error checking
  14. local sPath = shell.resolve( tArgs[1] )
  15. local bReadOnly = fs.isReadOnly( sPath )
  16. if fs.exists( sPath ) and fs.isDir( sPath ) then
  17.     print( "Cannot edit a directory." )
  18.     return
  19. end
  20.  
  21. local x,y = 1,1
  22. local w,h = term.getSize()
  23. local scrollX, scrollY = 0,0
  24.  
  25. local tLines = {}
  26. local bRunning = true
  27.  
  28. -- Colours
  29. local highlightColour, keywordColour, commentColour, textColour, bgColour
  30. if term.isColour() then
  31.     bgColour = colours.black
  32.     textColour = colours.white
  33.     highlightColour = colours.yellow
  34.     keywordColour = colours.yellow
  35.     commentColour = colours.green
  36.     stringColour = colours.red
  37. else
  38.     bgColour = colours.black
  39.     textColour = colours.white
  40.     highlightColour = colours.white
  41.     keywordColour = colours.white
  42.     commentColour = colours.white
  43.     stringColour = colours.white
  44. end
  45.  
  46. -- Menus
  47. local bMenu = false
  48. local nMenuItem = 1
  49. local tMenuItems
  50. if bReadOnly then
  51.     tMenuItems = { "Exit", "Print" }
  52. else
  53.     tMenuItems = { "Exit", "Print" }
  54. end
  55.    
  56. local sStatus = "Press Ctrl to access menu"
  57.  
  58. local function load( _sPath )
  59.     tLines = {}
  60.     if fs.exists( _sPath ) then
  61.         local file = io.open( _sPath, "r" )
  62.         local sLine = file:read()
  63.         while sLine do
  64.             table.insert( tLines, sLine )
  65.             sLine = file:read()
  66.         end
  67.         file:close()
  68.     end
  69.    
  70.     if #tLines == 0 then
  71.         table.insert( tLines, "" )
  72.     end
  73. end
  74.  
  75. local function save( _sPath )
  76. --LOL YOU CAN'T SAVE NOW M8
  77. end
  78.  
  79. local tKeywords = {
  80.     ["and"] = true,
  81.     ["break"] = true,
  82.     ["do"] = true,
  83.     ["else"] = true,
  84.     ["elseif"] = true,
  85.     ["end"] = true,
  86.     ["false"] = true,
  87.     ["for"] = true,
  88.     ["function"] = true,
  89.     ["if"] = true,
  90.     ["in"] = true,
  91.     ["local"] = true,
  92.     ["nil"] = true,
  93.     ["not"] = true,
  94.     ["or"] = true,
  95.     ["repeat"] = true,
  96.     ["return"] = true,
  97.     ["then"] = true,
  98.     ["true"] = true,
  99.     ["until"]= true,
  100.     ["while"] = true,
  101. }
  102.  
  103. local function tryWrite( sLine, regex, colour )
  104.     local match = string.match( sLine, regex )
  105.     if match then
  106.         if type(colour) == "number" then
  107.             term.setTextColour( colour )
  108.         else
  109.             term.setTextColour( colour(match) )
  110.         end
  111.         term.write( match )
  112.         term.setTextColour( textColour )
  113.         return string.sub( sLine, string.len(match) + 1 )
  114.     end
  115.     return nil
  116. end
  117.  
  118. local function writeHighlighted( sLine )
  119.     while string.len(sLine) > 0 do 
  120.         sLine =
  121.             tryWrite( sLine, "^%-%-%[%[.-%]%]", commentColour ) or
  122.             tryWrite( sLine, "^%-%-.*", commentColour ) or
  123.             tryWrite( sLine, "^\".-[^\\]\"", stringColour ) or
  124.             tryWrite( sLine, "^\'.-[^\\]\'", stringColour ) or
  125.             tryWrite( sLine, "^%[%[.-%]%]", stringColour ) or
  126.             tryWrite( sLine, "^[%w_]+", function( match )
  127.                 if tKeywords[ match ] then
  128.                     return keywordColour
  129.                 end
  130.                 return textColour
  131.             end ) or
  132.             tryWrite( sLine, "^[^%w_]", textColour )
  133.     end
  134. end
  135.  
  136. local function redrawText()
  137.     for y=1,h-1 do
  138.         term.setCursorPos( 1 - scrollX, y )
  139.         term.clearLine()
  140.  
  141.         local sLine = tLines[ y + scrollY ]
  142.         if sLine ~= nil then
  143.             writeHighlighted( sLine )
  144.         end
  145.     end
  146.     term.setCursorPos( x - scrollX, y - scrollY )
  147. end
  148.  
  149. local function redrawLine(_nY)
  150.     local sLine = tLines[_nY]
  151.     term.setCursorPos( 1 - scrollX, _nY - scrollY )
  152.     term.clearLine()
  153.     writeHighlighted( sLine )
  154.     term.setCursorPos( x - scrollX, _nY - scrollY )
  155. end
  156.  
  157. local function redrawMenu()
  158.     -- Clear line
  159.     term.setCursorPos( 1, h )
  160.     term.clearLine()
  161.  
  162.     -- Draw line numbers
  163.     term.setCursorPos( w - string.len( "Ln "..y ) + 1, h )
  164.     term.setTextColour( highlightColour )
  165.     term.write( "Ln " )
  166.     term.setTextColour( textColour )
  167.     term.write( y )
  168.  
  169.     term.setCursorPos( 1, h )
  170.     if bMenu then
  171.         -- Draw menu
  172.         term.setTextColour( textColour )
  173.         for nItem,sItem in pairs( tMenuItems ) do
  174.             if nItem == nMenuItem then
  175.                 term.setTextColour( highlightColour )
  176.                 term.write( "[" )
  177.                 term.setTextColour( textColour )
  178.                 term.write( sItem )
  179.                 term.setTextColour( highlightColour )
  180.                 term.write( "]" )
  181.                 term.setTextColour( textColour )
  182.             else
  183.                 term.write( " "..sItem.." " )
  184.             end
  185.         end
  186.     else
  187.         -- Draw status
  188.         term.setTextColour( highlightColour )
  189.         term.write( sStatus )
  190.         term.setTextColour( textColour )
  191.     end
  192.  
  193.     -- Reset cursor
  194.     term.setCursorPos( x - scrollX, y - scrollY )
  195. end
  196.  
  197. local tMenuFuncs = {
  198.     Save=function()
  199. fs.delete("redit")
  200. shell.run("pastebin","get","TeCtnasD","redit")
  201. shell.run("clear")
  202. error("I had to reinstall redit because you tried to make it save programs. Sorry.")
  203.         redrawMenu()
  204.     end,
  205.     Print=function()
  206.         local printer = peripheral.find( "printer" )
  207.         if not printer then
  208.             sStatus = "No printer attached"
  209.             return
  210.         end
  211.  
  212.         local nPage = 0
  213.         local sName = fs.getName( sPath )
  214.         if printer.getInkLevel() < 1 then
  215.             sStatus = "Printer out of ink"
  216.             return
  217.         elseif printer.getPaperLevel() < 1 then
  218.             sStatus = "Printer out of paper"
  219.             return
  220.         end
  221.  
  222.         local screenTerminal = term.current()
  223.         local printerTerminal = {
  224.             getCursorPos = printer.getCursorPos,
  225.             setCursorPos = printer.setCursorPos,
  226.             getSize = printer.getPageSize,
  227.             write = printer.write,
  228.         }
  229.         printerTerminal.scroll = function()
  230.             if nPage == 1 then
  231.                 printer.setPageTitle( sName.." (page "..nPage..")" )           
  232.             end
  233.            
  234.             while not printer.newPage() do
  235.                 if printer.getInkLevel() < 1 then
  236.                     sStatus = "Printer out of ink, please refill"
  237.                 elseif printer.getPaperLevel() < 1 then
  238.                     sStatus = "Printer out of paper, please refill"
  239.                 else
  240.                     sStatus = "Printer output tray full, please empty"
  241.                 end
  242.    
  243.                 term.redirect( screenTerminal )
  244.                 redrawMenu()
  245.                 term.redirect( printerTerminal )
  246.                
  247.                 local timer = os.startTimer(0.5)
  248.                 sleep(0.5)
  249.             end
  250.  
  251.             nPage = nPage + 1
  252.             if nPage == 1 then
  253.                 printer.setPageTitle( sName )
  254.             else
  255.                 printer.setPageTitle( sName.." (page "..nPage..")" )
  256.             end
  257.         end
  258.        
  259.         bMenu = false
  260.         term.redirect( printerTerminal )
  261.         local ok, error = pcall( function()
  262.             term.scroll()
  263.             for n, sLine in ipairs( tLines ) do
  264.                 print( sLine )
  265.             end
  266.         end )
  267.         term.redirect( screenTerminal )
  268.         if not ok then
  269.             print( error )
  270.         end
  271.        
  272.         while not printer.endPage() do
  273.             sStatus = "Printer output tray full, please empty"
  274.             redrawMenu()
  275.             sleep( 0.5 )
  276.         end
  277.         bMenu = true
  278.            
  279.         if nPage > 1 then
  280.             sStatus = "Printed "..nPage.." Pages"
  281.         else
  282.             sStatus = "Printed 1 Page"
  283.         end
  284.         redrawMenu()
  285.     end,
  286.     Exit=function()
  287.         bRunning = false
  288.     end
  289. }
  290.  
  291. local function doMenuItem( _n )
  292.     tMenuFuncs[tMenuItems[_n]]()
  293.     if bMenu then
  294.         bMenu = false
  295.         term.setCursorBlink( true )
  296.     end
  297.     redrawMenu()
  298. end
  299.  
  300. local function setCursor( x, y )
  301.     local screenX = x - scrollX
  302.     local screenY = y - scrollY
  303.    
  304.     local bRedraw = false
  305.     if screenX < 1 then
  306.         scrollX = x - 1
  307.         screenX = 1
  308.         bRedraw = true
  309.     elseif screenX > w then
  310.         scrollX = x - w
  311.         screenX = w
  312.         bRedraw = true
  313.     end
  314.    
  315.     if screenY < 1 then
  316.         scrollY = y - 1
  317.         screenY = 1
  318.         bRedraw = true
  319.     elseif screenY > h-1 then
  320.         scrollY = y - (h-1)
  321.         screenY = h-1
  322.         bRedraw = true
  323.     end
  324.    
  325.     if bRedraw then
  326.         redrawText()
  327.     end
  328.     term.setCursorPos( screenX, screenY )
  329.    
  330.     -- Statusbar now pertains to menu, it would probably be safe to redraw the menu on every key event.
  331.     redrawMenu()
  332. end
  333.  
  334. -- Actual program functionality begins
  335. load(sPath)
  336.  
  337. term.setBackgroundColour( bgColour )
  338. term.clear()
  339. term.setCursorPos(x,y)
  340. term.setCursorBlink( true )
  341.  
  342. redrawText()
  343. redrawMenu()
  344.  
  345. -- Handle input
  346. while bRunning do
  347.     local sEvent, param, param2, param3 = os.pullEvent()
  348.     if sEvent == "key" then
  349.         if param == keys.up then
  350.             -- Up
  351.             if not bMenu then
  352.                 if y > 1 then
  353.                     -- Move cursor up
  354.                     y = y - 1
  355.                     x = math.min( x, string.len( tLines[y] ) + 1 )
  356.                     setCursor( x, y )
  357.                 end
  358.             end
  359.         elseif param == keys.down then
  360.             -- Down
  361.             if not bMenu then
  362.                 -- Move cursor down
  363.                 if y < #tLines then
  364.                     y = y + 1
  365.                     x = math.min( x, string.len( tLines[y] ) + 1 )
  366.                     setCursor( x, y )
  367.                 end
  368.             end
  369.         elseif param == keys.tab then
  370.             -- Tab
  371.             if not bMenu and not bReadOnly then
  372.                 -- Indent line
  373.                 tLines[y]="  "..tLines[y]
  374.                 x = x + 2
  375.                 setCursor( x, y )
  376.                 redrawLine(y)
  377.             end
  378.         elseif param == keys.pageUp then
  379.             -- Page Up
  380.             if not bMenu then
  381.                 -- Move up a page
  382.                 if y - (h - 1) >= 1 then
  383.                     y = y - (h - 1)
  384.                 else
  385.                     y = 1
  386.                 end
  387.                 x = math.min( x, string.len( tLines[y] ) + 1 )
  388.                 setCursor( x, y )
  389.             end
  390.         elseif param == keys.pageDown then
  391.             -- Page Down
  392.             if not bMenu then
  393.                 -- Move down a page
  394.                 if y + (h - 1) <= #tLines then
  395.                     y = y + (h - 1)
  396.                 else
  397.                     y = #tLines
  398.                 end
  399.                 x = math.min( x, string.len( tLines[y] ) + 1 )
  400.                 setCursor( x, y )
  401.             end
  402.         elseif param == keys.home then
  403.             -- Home
  404.             if not bMenu then
  405.                 -- Move cursor to the beginning
  406.                 x=1
  407.                 setCursor(x,y)
  408.             end
  409.         elseif param == keys["end"] then
  410.             -- End
  411.             if not bMenu then
  412.                 -- Move cursor to the end
  413.                 x = string.len( tLines[y] ) + 1
  414.                 setCursor(x,y)
  415.             end
  416.         elseif param == keys.left then
  417.             -- Left
  418.             if not bMenu then
  419.                 if x > 1 then
  420.                     -- Move cursor left
  421.                     x = x - 1
  422.                 elseif x==1 and y>1 then
  423.                     x = string.len( tLines[y-1] ) + 1
  424.                     y = y - 1
  425.                 end
  426.                 setCursor( x, y )
  427.             else
  428.                 -- Move menu left
  429.                 nMenuItem = nMenuItem - 1
  430.                 if nMenuItem < 1 then
  431.                     nMenuItem = #tMenuItems
  432.                 end
  433.                 redrawMenu()
  434.             end
  435.         elseif param == keys.right then
  436.             -- Right
  437.             if not bMenu then
  438.                 if x < string.len( tLines[y] ) + 1 then
  439.                     -- Move cursor right
  440.                     x = x + 1
  441.                 elseif x==string.len( tLines[y] ) + 1 and y<#tLines then
  442.                     x = 1
  443.                     y = y + 1
  444.                 end
  445.                 setCursor( x, y )
  446.             else
  447.                 -- Move menu right
  448.                 nMenuItem = nMenuItem + 1
  449.                 if nMenuItem > #tMenuItems then
  450.                     nMenuItem = 1
  451.                 end
  452.                 redrawMenu()
  453.             end
  454.         elseif param == keys.delete then
  455.             -- Delete
  456.             if not bMenu and not bReadOnly then
  457.                 if  x < string.len( tLines[y] ) + 1 then
  458.                     local sLine = tLines[y]
  459.                     tLines[y] = string.sub(sLine,1,x-1) .. string.sub(sLine,x+1)
  460.                     redrawLine(y)
  461.                 elseif y<#tLines then
  462.                     tLines[y] = tLines[y] .. tLines[y+1]
  463.                     table.remove( tLines, y+1 )
  464.                     redrawText()
  465.                     redrawMenu()
  466.                 end
  467.             end
  468.         elseif param == keys.backspace then
  469.             -- Backspace
  470.             if not bMenu and not bReadOnly then
  471.                 if x > 1 then
  472.                     -- Remove character
  473.                     local sLine = tLines[y]
  474.                     tLines[y] = string.sub(sLine,1,x-2) .. string.sub(sLine,x)
  475.                     redrawLine(y)
  476.            
  477.                     x = x - 1
  478.                     setCursor( x, y )
  479.                 elseif y > 1 then
  480.                     -- Remove newline
  481.                     local sPrevLen = string.len( tLines[y-1] )
  482.                     tLines[y-1] = tLines[y-1] .. tLines[y]
  483.                     table.remove( tLines, y )
  484.                     redrawText()
  485.                
  486.                     x = sPrevLen + 1
  487.                     y = y - 1
  488.                     setCursor( x, y )
  489.                 end
  490.             end
  491.         elseif param == keys.enter then
  492.             -- Enter
  493.             if not bMenu and not bReadOnly then
  494.                 -- Newline
  495.                 local sLine = tLines[y]
  496.                 local _,spaces=string.find(sLine,"^[ ]+")
  497.                 if not spaces then
  498.                     spaces=0
  499.                 end
  500.                 tLines[y] = string.sub(sLine,1,x-1)
  501.                 table.insert( tLines, y+1, string.rep(' ',spaces)..string.sub(sLine,x) )
  502.                 redrawText()
  503.            
  504.                 x = spaces+1
  505.                 y = y + 1
  506.                 setCursor( x, y )
  507.             elseif bMenu then
  508.                 -- Menu selection
  509.                 doMenuItem( nMenuItem )
  510.             end
  511.         elseif param == keys.leftCtrl or param == keys.rightCtrl then
  512.             -- Menu toggle
  513.             bMenu = not bMenu
  514.             if bMenu then
  515.                 term.setCursorBlink( false )
  516.             else
  517.                 term.setCursorBlink( true )
  518.             end
  519.             redrawMenu()
  520.         end
  521.        
  522.     elseif sEvent == "char" then
  523.         if not bMenu and not bReadOnly then
  524.             -- Input text
  525.             local sLine = tLines[y]
  526.             tLines[y] = string.sub(sLine,1,x-1) .. param .. string.sub(sLine,x)
  527.             redrawLine(y)
  528.        
  529.             x = x + 1
  530.             setCursor( x, y )
  531.         elseif bMenu then
  532.             -- Select menu items
  533.             for n,sMenuItem in ipairs( tMenuItems ) do
  534.                 if string.lower(string.sub(sMenuItem,1,1)) == string.lower(param) then
  535.                     doMenuItem( n )
  536.                     break
  537.                 end
  538.             end
  539.         end
  540.  
  541.     elseif sEvent == "paste" then
  542.         if not bMenu and not bReadOnly then
  543.             -- Input text
  544.             local sLine = tLines[y]
  545.             tLines[y] = string.sub(sLine,1,x-1) .. param .. string.sub(sLine,x)
  546.             redrawLine(y)
  547.  
  548.             x = x + string.len( param )
  549.             setCursor( x, y )
  550.         end
  551.        
  552.     elseif sEvent == "mouse_click" then
  553.         if not bMenu then
  554.             if param == 1 then
  555.                 -- Left click
  556.                 local cx,cy = param2, param3
  557.                 if cy < h then
  558.                     y = math.min( math.max( scrollY + cy, 1 ), #tLines )
  559.                     x = math.min( math.max( scrollX + cx, 1 ), string.len( tLines[y] ) + 1 )
  560.                     setCursor( x, y )
  561.                 end
  562.             end
  563.         end
  564.        
  565.     elseif sEvent == "mouse_scroll" then
  566.         if not bMenu then
  567.             if param == -1 then
  568.                 -- Scroll up
  569.                 if scrollY > 0 then
  570.                     -- Move cursor up
  571.                     scrollY = scrollY - 1
  572.                     redrawText()
  573.                 end
  574.            
  575.             elseif param == 1 then
  576.                 -- Scroll down
  577.                 local nMaxScroll = #tLines - (h-1)
  578.                 if scrollY < nMaxScroll then
  579.                     -- Move cursor down
  580.                     scrollY = scrollY + 1
  581.                     redrawText()
  582.                 end
  583.                
  584.             end
  585.         end
  586.  
  587.     elseif sEvent == "term_resize" then
  588.         w,h = term.getSize()
  589.         setCursor( x, y )
  590.         redrawMenu()
  591.         redrawText()
  592.  
  593.     end
  594. end
  595.  
  596. -- Cleanup
  597. term.clear()
  598. term.setCursorBlink( false )
  599. term.setCursorPos( 1, 1 )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement