SuicidalSTDz

/.EnderOS/.edit

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