Guest User

rom/programs/edit

a guest
May 15th, 2012
264
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. local tArgs = { ... }
  3. if #tArgs == 0 then
  4.     print( "Usage: edit <path>" )
  5.     return
  6. end
  7.  
  8. local sPath = shell.resolve( tArgs[1] )
  9. local bReadOnly = fs.isReadOnly( sPath )
  10. if fs.exists( sPath ) and fs.isDir( sPath ) then
  11.     print( "Cannot edit a directory" )
  12.     return
  13. end
  14.  
  15. local w,h = term.getSize()
  16. local x,y = 1,1
  17. local scrollX, scrollY = 0,0
  18.  
  19. local bMenu = false
  20. local nMenuItem = 1
  21.  
  22. local tStatusParts = {left='',right=''}
  23. local sStatus = ""
  24. local tLines = {}
  25.  
  26. local function load()
  27.     tLines = {}
  28.     if fs.exists( sPath ) then
  29.         local file = io.open( sPath, "r" )
  30.         local sLine = file:read()
  31.         while sLine do
  32.             table.insert( tLines, sLine )
  33.             sLine = file:read()
  34.         end
  35.         file:close()
  36.     else
  37.         table.insert( tLines, "" )
  38.     end
  39. end
  40.  
  41. local function save()
  42.     local file = io.open( sPath, "w" )
  43.     if file then
  44.         for n, sLine in ipairs( tLines ) do
  45.             file:write( sLine .. "\n" )
  46.         end
  47.         file:close()
  48.         return true
  49.     end
  50.     return false
  51. end
  52.  
  53. local function redrawText()
  54.     for y=1,h-1 do
  55.         term.setCursorPos( 1 - scrollX, y )
  56.         term.clearLine()
  57.  
  58.         local sLine = tLines[ y + scrollY ]
  59.         if sLine ~= nil then
  60.             term.write( sLine )
  61.         end
  62.     end
  63.     term.setCursorPos( x - scrollX, y - scrollY )
  64. end
  65.  
  66. local function redrawLine()
  67.     local sLine = tLines[y]
  68.     term.setCursorPos( 1 - scrollX, y - scrollY )
  69.     term.clearLine()
  70.     term.write( sLine )
  71.     term.setCursorPos( x - scrollX, y - scrollY )
  72. end
  73.  
  74. local tMenuItems = { "Save", "Exit" }
  75.  
  76. local function redrawMenu()
  77.     term.setCursorPos( 1, h )
  78.     term.clearLine()
  79.    
  80.     if bMenu then
  81.         local sBuild = ''
  82.         for n,sItem in ipairs( tMenuItems ) do
  83.             if n == nMenuItem then
  84.                 sBuild=sBuild.."["..sItem.."]"
  85.             else
  86.                 sBuild=sBuild.." "..sItem.." " --<FIXME> Might want to shave this.
  87.             end
  88.         end
  89.         tStatusParts['left']=sBuild
  90.     else
  91.         tStatusParts['left']='Ctrl'
  92.     end
  93.     if tStatusParts['right'] then
  94.         term.setCursorPos( w-tStatusParts['right']:len(), h )
  95.         term.write(tStatusParts['right'])
  96.     end
  97.     if tStatusParts['left'] then
  98.         term.setCursorPos( 1, h )
  99.         term.write(tStatusParts['left'])
  100.     end
  101.     term.setCursorPos( x - scrollX, y - scrollY )
  102. end
  103.  
  104. local function setStatus(pos, _sText)
  105.     tStatusParts[pos] = _sText
  106.     redrawMenu()
  107. end
  108.  
  109. local function updateRightStatus()
  110.     -- Tracks current position of total line numbers.
  111.     --print(y)
  112.     --print(#tLines)
  113.     setStatus("right", tostring(y)..'/'..tostring(#tLines))
  114. end
  115.  
  116. local function setCursor( x, y )
  117.     local screenX = x - scrollX
  118.     local screenY = y - scrollY
  119.    
  120.     local bRedraw = false
  121.     if screenX < 1 then
  122.         scrollX = x - 1
  123.         screenX = 1
  124.         bRedraw = true
  125.     elseif screenX > w then
  126.         scrollX = x - w
  127.         screenX = w
  128.         bRedraw = true
  129.     end
  130.    
  131.     if screenY < 1 then
  132.         scrollY = y - 1
  133.         screenY = 1
  134.         bRedraw = true
  135.     elseif screenY > h-1 then
  136.         scrollY = y - (h-1)
  137.         screenY = h-1
  138.         bRedraw = true
  139.     end
  140.    
  141.     if bRedraw then
  142.         redrawText()
  143.     end
  144.     term.setCursorPos( screenX, screenY )
  145. end
  146.  
  147. load()
  148.  
  149. term.clear()
  150. term.setCursorPos(x,y)
  151. term.setCursorBlink( true )
  152.  
  153. redrawText()
  154. updateRightStatus()
  155. redrawMenu()
  156.  
  157. local bRunning = true
  158. local tMenuFunctions = {
  159.     ["Exit"] = function()
  160.         bRunning = false
  161.     end,
  162.     ["Save"] = function()
  163.         if save() then
  164.             setStatus("left", "Saved to "..sPath )
  165.         else
  166.             setStatus("left", "Access denied" )
  167.         end
  168.     end,
  169. }
  170.  
  171. local function doMenuItem( _n )
  172.     local fnMenu = tMenuFunctions[ tMenuItems[_n] ]
  173.     if fnMenu then
  174.         fnMenu()
  175.     end
  176.  
  177.     bMenu = false
  178.     term.setCursorBlink( true )
  179.     redrawMenu()
  180. end
  181.  
  182. while bRunning do
  183.   local sEvent, param = os.pullEvent()
  184.   if sEvent == "key" then
  185.     if param == 200 then
  186.         -- Up
  187.         if not bMenu then
  188.             -- Move cursor up
  189.             if y > 1 then
  190.                 y = y - 1
  191.                 x = math.min( x, string.len( tLines[y] ) + 1 )
  192.                 setCursor( x, y )
  193.                 updateRightStatus()
  194.             end
  195.         end
  196.     elseif param == 208 then
  197.         -- Down
  198.         if not bMenu then
  199.             -- Move cursor down
  200.             if y < #tLines then
  201.                 y = y + 1
  202.                 x = math.min( x, string.len( tLines[y] ) + 1 )
  203.                 setCursor( x, y )
  204.                 updateRightStatus()
  205.             end
  206.         end
  207.     elseif param == 15 then
  208.         -- Tab
  209.         if not bMenu then
  210.             local sLine = tLines[y]
  211.             tLines[y] = string.sub(sLine,1,x-1) .. "  " .. string.sub(sLine,x)
  212.             redrawLine()
  213.        
  214.             x = x + 2
  215.             setCursor( x, y )
  216.         end
  217.     elseif param == 201 then
  218.         -- Page Up
  219.         if not bMenu then
  220.             -- Move up a page
  221.             local sx,sy=term.getSize()
  222.             if y>sy-1 then
  223.                 y = y-sy-1
  224.             else
  225.                 y = 1
  226.             end
  227.             x = math.min( x, string.len( tLines[y] ) + 1 )
  228.             setCursor( x, y )
  229.             updateRightStatus()
  230.         end
  231.     elseif param == 209 then
  232.         -- Page Down
  233.         if not bMenu then
  234.             -- Move down a page
  235.             local sx,sy=term.getSize()
  236.             if y<#tLines-sy-1 then
  237.                 y = y+sy-1
  238.             else
  239.                 y = #tLines
  240.             end
  241.             x = math.min( x, string.len( tLines[y] ) + 1 )
  242.             setCursor( x, y )
  243.             updateRightStatus()
  244.         end
  245.     elseif param == 199 then
  246.         -- Home
  247.         if not bMenu then
  248.             -- Move cursor to the beginning
  249.             x=1
  250.             setCursor(x,y)
  251.         end
  252.     elseif param == 207 then
  253.         -- End
  254.         if not bMenu then
  255.             -- Move cursor to the end
  256.             x = string.len( tLines[y] ) + 1
  257.             setCursor(x,y)
  258.         end
  259.     elseif param == 203 then
  260.         -- Left
  261.         if not bMenu then
  262.             -- Move cursor left
  263.             if x > 1 then
  264.                 x = x - 1
  265.             elseif x==1 and y>1 then
  266.                 x = string.len( tLines[y-1] ) + 1
  267.                 y = y - 1
  268.                 updateRightStatus()
  269.             end
  270.             setCursor( x, y )
  271.         else
  272.             -- Move menu left
  273.             nMenuItem = nMenuItem - 1
  274.             if nMenuItem < 1 then
  275.                 nMenuItem = #tMenuItems
  276.             end
  277.             redrawMenu()
  278.         end
  279.     elseif param == 205 then
  280.         -- Right
  281.         if not bMenu then
  282.             -- Move cursor right
  283.             if x < string.len( tLines[y] ) + 1 then
  284.                 x = x + 1
  285.             elseif x==string.len( tLines[y] ) + 1 and y<#tLines then
  286.                 x = 1
  287.                 y = y + 1
  288.                 updateRightStatus()
  289.             end
  290.             setCursor( x, y )
  291.         else
  292.             -- Move menu right
  293.             nMenuItem = nMenuItem + 1
  294.             if nMenuItem > #tMenuItems then
  295.                 nMenuItem = 1
  296.             end
  297.             redrawMenu()
  298.         end
  299.     elseif param == 211 then
  300.         -- Delete
  301.         if not bMenu then
  302.             if  x < string.len( tLines[y] ) + 1 then
  303.                 local sLine = tLines[y]
  304.                 tLines[y] = string.sub(sLine,1,x-1) .. string.sub(sLine,x+1)
  305.                 redrawLine()
  306.             elseif y<#tLines then
  307.                 tLines[y] = tLines[y] .. tLines[y+1]
  308.                 table.remove( tLines, y+1 )
  309.                 redrawText()
  310.                 updateRightStatus()
  311.             end
  312.         end
  313.     elseif param == 14 then
  314.         -- Backspace
  315.         if not bMenu then
  316.             if x > 1 then
  317.                 -- Remove character
  318.                 local sLine = tLines[y]
  319.                 tLines[y] = string.sub(sLine,1,x-2) .. string.sub(sLine,x)
  320.                 redrawLine()
  321.        
  322.                 x = x - 1
  323.                 setCursor( x, y )
  324.            
  325.             elseif y > 1 then
  326.                 -- Remove newline
  327.                 local sPrevLen = string.len( tLines[y-1] )
  328.                 tLines[y-1] = tLines[y-1] .. tLines[y]
  329.                 table.remove( tLines, y )
  330.                 redrawText()
  331.            
  332.                 x = sPrevLen + 1
  333.                 y = y - 1
  334.                 setCursor( x, y )
  335.                 updateRightStatus()
  336.             end
  337.         end
  338.        
  339.     elseif param == 28 then
  340.         -- Enter
  341.         if not bMenu then
  342.             -- Newline
  343.             local sLine = tLines[y]
  344.             local _,spaces=string.find(sLine,"^[ ]+")
  345.             if not spaces then spaces=0 end
  346.             tLines[y] = string.sub(sLine,1,x-1)
  347.             table.insert( tLines, y+1, string.rep(' ',spaces)..string.sub(sLine,x) )
  348.             redrawText()
  349.        
  350.             x = spaces+1
  351.             y = y + 1
  352.             setCursor( x, y )
  353.             updateRightStatus()
  354.         else
  355.             -- Menu selection
  356.             doMenuItem( nMenuItem )
  357.         end
  358.        
  359.     elseif param == 29 then
  360.         -- Menu toggle
  361.         bMenu = not bMenu
  362.         if bMenu then
  363.             term.setCursorBlink( false )
  364.             nMenuItem = 1
  365.         else
  366.             setStatus("left","Ctrl")
  367.             term.setCursorBlink( true )
  368.         end
  369.         redrawMenu()
  370.    
  371.     end
  372.        
  373.   elseif sEvent == "char" then
  374.     if not bMenu then
  375.         -- Input text
  376.         local sLine = tLines[y]
  377.         tLines[y] = string.sub(sLine,1,x-1) .. param .. string.sub(sLine,x)
  378.         redrawLine()
  379.    
  380.         x = x + string.len( param )
  381.         setCursor( x, y )
  382.    
  383.     else
  384.         -- Select menu items
  385.         for n,sMenuItem in ipairs( tMenuItems ) do
  386.             if string.lower(string.sub(sMenuItem,1,1)) == string.lower(param) then
  387.                 doMenuItem( n )
  388.                 break
  389.             end
  390.         end
  391.     end
  392.   end
  393. end
  394.  
  395. term.clear()
  396. term.setCursorBlink( false )
  397. term.setCursorPos( 1, 1 )
Advertisement
Add Comment
Please, Sign In to add comment