Advertisement
Guest User

send

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