KinoftheFlames

Untitled

Sep 24th, 2012
195
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 21.55 KB | None | 0 0
  1. --[[
  2.  
  3. ed v0.3
  4. by KinoftheFlames
  5.  
  6. ed is an IDE intended to replace the native file editor "edit".
  7. The goal of this program is to make editting lua programs for ComputerCraft as fluid as possible.
  8.  
  9. For more info: http://www.computercraft.info/forums2/index.php?/topic/4270-wip-in-game-ideedit-program/
  10.  
  11. CONTROLS:
  12. F3 - Save
  13. F4 - Exit
  14. F5 - Run
  15. F6 - Run with arguments
  16.  
  17. CHANGELOG for v0.3:
  18. I've added some more customizable options for the UI, which you can change by editting the settings variables at the top of ed's file.
  19.  
  20. - Added insertion/overwrite toggle
  21. - Added status bar (optional) with the following information (which is all optional):
  22.    -- Current line number
  23.    -- Total line count (off by default)
  24.    -- Insert/overwrite toggle display
  25. - Added debugging. The file no longer needs to be force-saved to run it, and if there are any run-time errors ed will move the cursor to the error line and display the error.
  26. - You can now run ed from ed as recursively as you'd like and everything should work properly (yo dawg!)
  27. - Added auto-tabbing
  28. - Trying to edit files in non-existant directories now creates those directories
  29.  
  30.  
  31. Future features:
  32. - Find and replace
  33.  
  34. ]]
  35.  
  36. --argument handling
  37. local arg = { ... }
  38. if #arg == 0 then --verify argument exists
  39.     print("Syntax: editor <path>")
  40.     error()
  41. end
  42. if fs.isDir(arg[1]) then --verift not a directory
  43.     print("Error: cannot edit a directory as a file")
  44.     error()
  45. end
  46.  
  47. --debug
  48. local bDebug = true --display debugging info if true
  49. local sDebugText = "" --debug text shown if debugging is on
  50.  
  51. --constants
  52. local SCREEN_ORIGIN = 1
  53. local SCREEN_WIDTH, SCREEN_HEIGHT = term.getSize()
  54. local TIMER_INTERVAL = 300.0 --in seconds (DO NOT SET TO 0, that would be infinite)
  55.  
  56. --settings
  57. local bInsert = true --insert text if true, override text if false
  58. local bShowLineNum = true --toggle visibility of line numbers
  59. local bShowLineNumSep = true --toggle visibility of line numbers seperator
  60. local bShowStatusBar = true --toggle visibility of the line of information at the bottom of the screen
  61.     --toggle visibility of individual status information
  62.     local bStatus_lineNum = true
  63.     local bStatus_lineCount = false
  64.     local bStatus_insert = true
  65. local bShowMessages = true --toggle displaying of messages at the bottom of the screen
  66. local nMinLineDigitsVisible = 1 --[POS] defines how much area for the line numbers is displayed at minimum (program will expand space as needed)
  67. local nSpacesPerTab = 3 --[POS] defines how many visual spaces are in a tab
  68.  
  69. --flags
  70. local bUnsavedChanges = false --tracks whether the file in the editor has been changed since last saved, helps with exit before saving confirmation
  71. local bConfirmingExit = false --if the user tries to exit without saving, this requires them to try again before succeeding
  72.  
  73. --variables
  74. local bRunning = true --false when the program exits
  75. local sFilepath = arg[1] --path to the file being editted
  76. local tFile = { } --table of lines for the file being editted
  77. local xMin, yMin = SCREEN_ORIGIN, SCREEN_ORIGIN --min values for file display
  78. local xMax, yMax = SCREEN_WIDTH, SCREEN_HEIGHT --max values for file display
  79. local xFile, yFile = 1, 1 --the location of the cursor in the text file
  80. local xScroll, yScroll = 0, 0 --amount file is scrolled on screen
  81. local sStatus = "" --text displayed for the status bar at the bottom of the screen
  82. local sMessage = "" --message displayed at the bottom of the screen until next input
  83. local sArguments = "" --stores the last arguments used, bringing them up again when run w/ arguments is called
  84. local sError = "" --stores error information from failed program execution for debugging
  85. local tTimer --timer for main loop and time-based events
  86.  
  87.  
  88.  
  89. ------------------------
  90. --    FILE HANDLING   --
  91. ------------------------
  92.  
  93. --load a file from hdd into editor
  94. function load()
  95.     --error handling file
  96.     if fs.exists(sFilepath) then
  97.         --load file
  98.         local file = fs.open(sFilepath, "r")
  99.         while true do
  100.             local line = file.readLine()
  101.             if line == nil then --if reached end of file
  102.                 break end
  103.            
  104.             table.insert(tFile, line)
  105.         end
  106.         file.close()
  107.     else
  108.         table.insert(tFile, "")
  109.     end
  110. end
  111.  
  112. --save editor's text to a file
  113. function save()
  114.     sMessage = "SAVING..."
  115.     draw()
  116.    
  117.     if bUnsavedChanges then --only save if needed (saves on CPU time)
  118.         --create directory if it doesn't exist
  119.         local dir = string.sub(sFilepath, 1, #sFilepath - #fs.getName(sFilepath))
  120.         if not fs.exists(dir) then
  121.             fs.makeDir(dir) end
  122.        
  123.         --write to file
  124.         local file = fs.open(sFilepath, "w")
  125.         for i,line in ipairs(tFile) do
  126.             file.writeLine(line) end
  127.         file.close()
  128.     end
  129.    
  130.     sMessage = "SAVED to " .. sFilepath
  131.     bUnsavedChanges = false
  132. end
  133.  
  134.  
  135.  
  136. ------------------------
  137. --       VISUAL       --
  138. ------------------------
  139.  
  140. --scrolls the screen with the cursor
  141. function scroll()
  142.     alignCursor()
  143.     local x,y = term.getCursorPos()
  144.    
  145.     if y > yMax then
  146.         yScroll = yScroll + (y - yMax)
  147.     elseif y < yMin then
  148.         yScroll = yScroll - (yMin - y)
  149.     end
  150.     if x > xMax then
  151.         xScroll = xScroll + (x - xMax)
  152.     elseif x < xMin then
  153.         xScroll = xScroll - (xMin - x)
  154.     end
  155. end
  156.  
  157. --brings the visual cursor to the location of the cursor in file
  158. function alignCursor()
  159.     local charsLeftOfCursor = string.sub(tFile[yFile], 1, xFile-1) --chars left of cursor
  160.     local dummy, numTabs = string.gsub(charsLeftOfCursor, "\t", "\t") --gets the number of tabs
  161.    
  162.     local x = xMin + (xFile - 1) - xScroll + numTabs * (nSpacesPerTab - 1)
  163.     local y = yMin + (yFile - 1) - yScroll
  164.    
  165.     term.setCursorPos(x, y)
  166. end
  167.  
  168. --moves cursor around
  169. function shiftCursor(xShift, yShift)
  170.     --format input for error handling
  171.     if yFile + yShift < 1 then
  172.         yShift = -(yFile - 1)
  173.     elseif yFile + yShift > #tFile then
  174.         yShift = #tFile - yFile
  175.     end
  176.        
  177.    
  178.     --handle left/right movement
  179.     if xFile == 1 and xShift < 0 then --if at start of line and moving left, move to end of above line (if exists)
  180.         if yFile ~= 1 then
  181.             xFile = #tFile[yFile-1] + 1
  182.             yFile = yFile - 1
  183.         end
  184.     elseif xFile > #tFile[yFile] and xShift > 0 then --if at end of line and moving right, move to start of next line (if exists)
  185.         if yFile ~= #tFile then
  186.             xFile = 1
  187.             yFile = yFile + 1
  188.         end
  189.     else --horizontal only movement
  190.         xFile = xFile + xShift--normal move
  191.     end
  192.    
  193.     --handle up/down movement
  194.     if yFile == 1 and yShift < 0 then --if at first line and moving up, move to start of line
  195.         xFile = 1
  196.     elseif yFile == #tFile and yShift > 0 then --if at last line and moving down, move to end of line
  197.         xFile = #tFile[yFile] + 1
  198.     else --vertical only movement
  199.         yFile = yFile + yShift --normal move
  200.        
  201.         --if the cursor is past the end of the last character after having moved, move it to the last character
  202.         if xFile > #tFile[yFile] then
  203.             xFile = 1 + #tFile[yFile]
  204.         end
  205.     end
  206. end
  207.  
  208. --move cursor to the start of the line
  209. function shiftCursorHome()
  210.     xFile = 1
  211. end
  212.  
  213. --move cursor to the end of the line (end of text)
  214. function shiftCursorEnd()
  215.     xFile = 1 + #tFile[yFile]
  216. end
  217.  
  218. --adjusts borders of editable area depending on settings and situational factors
  219. function applyBoundrySettings()
  220.     if bShowLineNum then
  221.         local chars = #tostring(#tFile) --characters in line num area = num of digits of last line
  222.         if nMinLineDigitsVisible > chars then --unless there is a minimum character count to enforce which is greater
  223.             chars = nMinLineDigitsVisible end
  224.         xMin = chars + 2 --adjust boundry for editable area
  225.     else
  226.         xMin = SCREEN_ORIGIN end
  227.    
  228.     if bShowStatusBar then
  229.         yMax = SCREEN_HEIGHT - 1
  230.     else
  231.         yMax = SCREEN_HEIGHT end
  232. end
  233.  
  234.  
  235.  
  236. ------------------------
  237. --      DRAWING       --
  238. ------------------------
  239.  
  240. --redraws entire screen
  241. function draw()
  242.     --clear screen
  243.     term.clear()
  244.    
  245.     --draw line numbers
  246.     if bShowLineNum then
  247.         drawLineNum() end
  248.    
  249.     --draw file text
  250.     for i=yMin,yMax do
  251.         if tFile[i+yScroll] ~= nil then --if haven't reached end of file
  252.             term.setCursorPos(xMin, i)
  253.             local modifiedLine = string.gsub(tFile[i+yScroll], "\t", string.rep(" ", nSpacesPerTab)) --replace visual line with defined number of spaces
  254.             term.write(string.sub(modifiedLine, 1 + xScroll, xMax - xMin + 1 + xScroll)) --only draw visible text
  255.         end
  256.     end
  257.    
  258.     --draw status bar
  259.     if bShowStatusBar then
  260.         drawStatusBar() end
  261.    
  262.     --draw message
  263.     if bShowMessages then
  264.         drawMessage() end
  265.    
  266.     --draw debug
  267.     if bDebug then
  268.         drawDebug(sDebugText) end
  269.    
  270.     --place visual cursor in correct position
  271.     alignCursor()
  272. end
  273.  
  274. --draws line numbers and seperator
  275. function drawLineNum()
  276.     applyBoundrySettings()
  277.     local chars = #tostring(#tFile) --characters in line num area = num of digits of last line
  278.     if nMinLineDigitsVisible > chars then --unless there is a minimum character count to enforce which is greater
  279.         chars = nMinLineDigitsVisible end
  280.    
  281.     for i=yMin,yMax do
  282.         local lineNum = i+yScroll --line number of file line being drawn
  283.         if tFile[lineNum] ~= nil then --don't draw line numbers for lines that dont exists in the file
  284.             local numSpaces = chars - #tostring(lineNum) --spaces required to right-align numbers
  285.            
  286.             --draw finally
  287.             term.setCursorPos(SCREEN_ORIGIN, i)
  288.             term.write(string.rep(" ", numSpaces)) --spaces before line number
  289.             term.write(tostring(lineNum)) --line number
  290.             if bShowLineNumSep then
  291.                 term.write("|") end --seperator --TODO: add customizable line seperator (single char)
  292.         end
  293.     end
  294.    
  295.     --sDebugText = sDebugText .. " xMin:"..xMin
  296. end
  297.  
  298. --draw bar with information at the bottom of the screen
  299. function drawStatusBar()
  300.     sStatus = "--< " --paint me like one of your french girls
  301.    
  302.     local charsLeft = SCREEN_WIDTH - 8 --characters available to print
  303.     local nextAdd = "" --next info to add to status bar
  304.    
  305.     --line cursor is on
  306.     if bStatus_lineNum then
  307.         nextAdd = "Ln " .. yFile --cur line
  308.         if bStatus_lineCount then --line count
  309.             nextAdd = nextAdd .. "/" .. #tFile end
  310.        
  311.         charsLeft = addStatus(nextAdd, charsLeft)
  312.     elseif bStatus_lineCount then
  313.         nextAdd = #tFile .. " lines" --line count
  314.         charsLeft = addStatus(nextAdd, charsLeft)
  315.     end
  316.    
  317.     --INS for insert text, OVR for overwrite text
  318.     if bStatus_insert then
  319.         if bInsert then
  320.             nextAdd = "INS"
  321.         else
  322.             nextAdd = "OVR" end
  323.         charsLeft = addStatus(nextAdd, charsLeft)
  324.     end
  325.    
  326.     sStatus = sStatus .. string.rep(" ", charsLeft) --filler
  327.     sStatus = sStatus .. " >--" --paint me like one of your french girls
  328.    
  329.     --draw the bar
  330.     term.setCursorPos(SCREEN_ORIGIN,SCREEN_HEIGHT)
  331.     term.write(sStatus)
  332. end
  333.  
  334. --push next status on to the status text
  335. function addStatus(sText, nCharsLeft)
  336.     if nCharsLeft >= #sText + 2 then --if status can fit wholly on line
  337.         if #sStatus <= 4 then --if first status added
  338.             sStatus = sStatus .. sText
  339.             nCharsLeft = nCharsLeft - #sText --reduce remaining space for statuses
  340.         else
  341.             sStatus = sStatus .. "  " .. sText
  342.             nCharsLeft = nCharsLeft - (#sText + 2) --reduce remaining space for statuses
  343.         end
  344.     end
  345.     return nCharsLeft
  346. end
  347.  
  348. --draw general message at the bottom of the screen for one loop
  349. function drawMessage()
  350.     if sMessage == "" then
  351.         return end
  352.    
  353.     --truncates message
  354.     sMessage = string.sub(sMessage, 1, SCREEN_WIDTH - 8)
  355.    
  356.     --add dashes on the side to draw attention
  357.     local fillerDrawn = ((SCREEN_WIDTH - #sMessage)/2)-2 --num dashes on one side
  358.    
  359.     if fillerDrawn < 2 then
  360.         fillerDrawn = 2 end
  361.    
  362.     local printedText = string.rep("-", fillerDrawn) .. "< " .. sMessage .. " >" .. string.rep("-", fillerDrawn + 1)
  363.    
  364.     --display message
  365.     term.setCursorPos(SCREEN_ORIGIN,SCREEN_HEIGHT) --bottom left
  366.     term.write(printedText)
  367. end
  368.  
  369. --display debug info in bottom right
  370. function drawDebug(sText)
  371.     term.setCursorPos(SCREEN_WIDTH + 1 - #sText, SCREEN_HEIGHT) --set cursor at bottom rightmost while still showing all text
  372.     term.write(sText)
  373. end
  374.  
  375. --draw menu
  376. function drawMenu()
  377.     drawMenu_bg()
  378.     os.pullEvent()
  379. end
  380.  
  381. --the background for the menu
  382. function drawMenu_bg()
  383.     local line = ""
  384.     --draw top line
  385.     line = "o"..string.rep("-", SCREEN_WIDTH-2).."o"
  386.     term.setCursorPos(SCREEN_ORIGIN, SCREEN_ORIGIN)
  387.     term.write(line)
  388.    
  389.     --draw inbetween lines
  390.     for i=SCREEN_ORIGIN+1,SCREEN_HEIGHT-1 do
  391.         line = "|"..string.rep(" ", SCREEN_WIDTH-2).."|"
  392.         term.setCursorPos(SCREEN_ORIGIN, i)
  393.         term.write(line)
  394.     end
  395.    
  396.     --draw bottom line
  397.     line = "O"..string.rep("-", SCREEN_WIDTH-2).."O"
  398.     term.setCursorPos(SCREEN_ORIGIN, SCREEN_HEIGHT)
  399.     term.write(line)
  400. end
  401.  
  402.  
  403. ------------------------
  404. --      DEBUGGING     --
  405. ------------------------
  406.  
  407. --run the program being edited
  408. function run(bArguments)
  409.     local tArguments = {}
  410.    
  411.     --get arugments for program execution
  412.     if bArguments then
  413.         --draw seperator dashes below argument input
  414.         term.setCursorPos(SCREEN_ORIGIN,SCREEN_ORIGIN+1)
  415.         term.write(string.rep("-", SCREEN_WIDTH))
  416.        
  417.         --clear top line and get arguments
  418.         term.setCursorPos(SCREEN_ORIGIN,SCREEN_ORIGIN)
  419.         term.clearLine()
  420.         term.write("Arguments: ")
  421.         sArguments = read(nil, sArguments)
  422.        
  423.         --format arguments (stolen from shell)
  424.         for match in string.gmatch(sArguments, "[^ \t]+") do --grabs each argument, space/tab delimitted
  425.             table.insert(tArguments, match)
  426.         end
  427.     end
  428.    
  429.     --save() --save so its running the program in the editor
  430.     term.clear()
  431.     term.setCursorPos(SCREEN_ORIGIN,SCREEN_ORIGIN)
  432.     --local progSuccess = shell.run(sFilepath, unpack(tArguments)) --OLD WAY (calling without debugging)
  433.     sError = ""
  434.     local progSuccess = runCatchErrors(table.concat(tFile, "\n"), unpack(tArguments))
  435.    
  436.     --formats error info
  437.     if sError and sError ~= "" then
  438.         local s1, s2 = string.find(sError, "%d+:") --the editor
  439.         local errorStart, v = string.find(string.sub(sError, s2), "%d+:") --the executed code
  440.         if errorStart ~= nil then
  441.             sError = string.sub(string.sub(sError, s2), errorStart) --removed editor pre-error text
  442.         else
  443.             sError = string.sub(sError, s1) --removed executed pre-error text (name and colon)
  444.         end
  445.     end
  446.    
  447.     --display whether program succeeded or failed, then prompt to continue
  448.     if progSuccess then
  449.         sMessage = "SUCCESS - Press any key"
  450.     else
  451.         sMessage = "FAILED - Press any key" end
  452.     drawMessage()
  453.    
  454.     while true do
  455.         e, p1 = os.pullEvent()
  456.         if e == "timer" and p1 == tTimer then
  457.             tTimer = os.startTimer(TIMER_INTERVAL) --reset timer
  458.         elseif e == "key" then
  459.             break end
  460.     end
  461.     os.sleep(0) --if the key pressed produces a "char" event, this prevents it from going to the next input loop
  462.    
  463.     initializeSystem() --reset program systerm-oriented settings (in case they've been changed)
  464.    
  465.     if sError and sError ~= "" then --moves cursor to error line and display error message
  466.         local v1, v2 = string.find(sError, "%d+") --get error line
  467.         local errorLine = tonumber(string.sub(sError, v1, v2))
  468.         xFile = 1
  469.         yFile = errorLine
  470.         sMessage = sError
  471.     else --no error
  472.         sMessage = "" end
  473. end
  474.  
  475. --specialized function to run a file and catch the runtime errors
  476. --Courtesy of faubiguy
  477. function runCatchErrors( sProgram, ... ) --sProgram is a string containing the current text. Any other arguments are arguments to the program.
  478.     local tArgs = { ... }
  479.     local fnFile, err = loadstring( sProgram )
  480.     if fnFile then
  481.         local tEnv = {["shell"] = shell}
  482.         setmetatable( tEnv, { __index = _G } )
  483.         setfenv( fnFile, tEnv )
  484.         local ok, err = pcall( function()
  485.                 fnFile( unpack( tArgs ) )
  486.         end )
  487.         if not ok then
  488.                 if err and err ~= "" then
  489.                         print( err )
  490.                         sError = err -- sError is the variable where you want the error
  491.                 end
  492.                 return false
  493.         end
  494.                 sError = "" -- error value set to "" on successful execution
  495.         return true
  496.     end
  497.     if err and err ~= "" then
  498.                 print( err )
  499.                 sError = err -- Again replace sError with the variable where you want the error
  500.         end
  501.     return false
  502. end
  503.  
  504.  
  505. ------------------------
  506. --       TYPING       --
  507. ------------------------
  508.  
  509. --inserts characters the user types in
  510. function insertText(sText)
  511.     local removeChar = 0
  512.     if not bInsert then --overwrite the next char instead of inserting if settings say so
  513.         removeChar = 1 end
  514.    
  515.     --insert/overwrite text
  516.     tFile[yFile] = string.sub(tFile[yFile], 1, xFile-1) .. sText .. string.sub(tFile[yFile], xFile + removeChar)
  517.    
  518.     shiftCursor(#sText, 0)
  519.     bUnsavedChanges = true
  520. end
  521.  
  522. --key press: enter
  523. function key_enter()
  524.     if xFile <= #tFile[yFile] then --if cursor is between characters
  525.         table.insert(tFile, yFile+1, string.sub(tFile[yFile], xFile)) --move remainder of characters to a new line
  526.         tFile[yFile] = string.sub(tFile[yFile], 1, xFile-1) --and delete the moved characters from the previous line
  527.     else --cursor at the end of the line
  528.         table.insert(tFile, yFile+1, "")
  529.     end
  530.    
  531.     --move cursor to begining of line and down
  532.     shiftCursorHome()
  533.     shiftCursor(0,1)
  534.    
  535.     --auto insert tabs equal to number on last line
  536.     local v, numTabs = string.find(tFile[yFile-1], "[\t]+")
  537.     if v ~= 1 or numTabs == nil then --tabs found, but not at the start of the line
  538.         numTabs = 0 end
  539.     insertText(string.rep("\t", numTabs))
  540.    
  541.     bUnsavedChanges = true
  542. end
  543.  
  544. --key press: backspace
  545. function key_backspace()
  546.     if not (yFile == 1 and xFile == 1) then --if not at the first character in the file
  547.         if xFile == 1 then --if at the start of a line, concatenate line above with this line
  548.             shiftCursor(0,-1)
  549.             shiftCursorEnd()
  550.            
  551.             tFile[yFile] = tFile[yFile] .. tFile[yFile+1] --concat lines
  552.             table.remove(tFile, yFile+1) --remove second line
  553.         else --otherwise just delete one character
  554.             shiftCursor(-1,0)
  555.             tFile[yFile] = string.sub(tFile[yFile], 1, xFile-1) .. string.sub(tFile[yFile], xFile+1)
  556.         end
  557.         bUnsavedChanges = true
  558.     end
  559. end
  560.  
  561. --key press: delete
  562. function key_delete()
  563.     if not (yFile == #tFile and xFile == #tFile[yFile] + 1) then --if not at the last character in the file
  564.         if xFile > #tFile[yFile] then --if cursor is at the end of the line, concatenate with line below
  565.             tFile[yFile] = tFile[yFile] .. tFile[yFile+1] --concat lines
  566.             table.remove(tFile, yFile+1) --remove second line
  567.         else --otherwise just delete one character
  568.             tFile[yFile] = string.sub(tFile[yFile], 1, xFile-1) .. string.sub(tFile[yFile], xFile+1)
  569.         end
  570.         bUnsavedChanges = true
  571.     end
  572. end
  573.  
  574.  
  575.  
  576. ------------------------
  577. --       OTHER        --
  578. ------------------------
  579.  
  580. --top level menu accessed via F1
  581. function menu()
  582.     drawMenu()
  583. end
  584.  
  585.  
  586. ------------------------
  587. --        CORE        --
  588. ------------------------
  589.  
  590. --initializes system settings (this is called at startup and after program execution)
  591. function initializeSystem()
  592.     term.setCursorBlink(true)
  593.     alignCursor()
  594. end
  595.  
  596. --intialization
  597. function intialize()
  598.     load() --load file
  599.    
  600.     --setup screen
  601.     applyBoundrySettings()
  602.     draw()
  603.     initializeSystem()
  604. end
  605.  
  606. --handles user input
  607. function input()
  608.     --wait for key input
  609.     local e, p1 = os.pullEvent()
  610.    
  611.     --timer input
  612.     if e == "timer" and p1 == tTimer then --main loop interval timer
  613.         tick()
  614.     else --user input (IMPORTANT distinction)
  615.         sMessage = "" --clear message
  616.        
  617.         --EXIT if confirmed, otherwise reset confirmation flag
  618.         if bConfirmingExit == true and e == "key" and p1 == keys.f4 then
  619.             exit()
  620.         else
  621.             bConfirmingExit = false end
  622.        
  623.         --character input
  624.         if e == "char" then
  625.             insertText(p1)
  626.        
  627.         --non-character, key input
  628.         elseif e == "key" then
  629.             --DONT USE F2, F10, F11, ALT, ESC
  630.            
  631.             --functions
  632.             if p1 == keys.f1 then --menu
  633.                 menu()
  634.             elseif p1 == keys.f3 then --save
  635.                 save()
  636.             elseif p1 == keys.f4 then --exit
  637.                 exit()
  638.             elseif p1 == keys.f5 then --run program in editor
  639.                 run(false)
  640.             elseif p1 == keys.f6 then --run with arguments
  641.                 run(true)
  642.                
  643.             --movement
  644.             elseif p1 == keys.up then --up
  645.                 shiftCursor(0, -1)
  646.             elseif p1 == keys.down then --down
  647.                 shiftCursor(0, 1)
  648.             elseif p1 == keys.left then --left
  649.                 shiftCursor(-1, 0)
  650.             elseif p1 == keys.right then --right
  651.                 shiftCursor(1, 0)
  652.             elseif p1 == keys.home then --home
  653.                 shiftCursorHome()
  654.             elseif p1 == keys["end"] then --end
  655.                 shiftCursorEnd()
  656.             elseif p1 == keys.pageUp then --pasge up
  657.                 shiftCursor(0, -(yMax-yMin))
  658.             elseif p1 == keys.pageDown then --page down
  659.                 shiftCursor(0, yMax-yMin)
  660.            
  661.             --removing characters
  662.             elseif p1 == keys.backspace then --backspace
  663.                 key_backspace()
  664.             elseif p1 == keys.delete then --delete
  665.                 key_delete()
  666.            
  667.             --adding whitespace
  668.             elseif p1 == keys.enter then --enter
  669.                 key_enter()
  670.             elseif p1 == keys.tab then --tab
  671.                 insertText("\t")
  672.                 bUnsavedChanges = true
  673.                
  674.             --insert
  675.             elseif p1 == keys.insert then
  676.                 bInsert = not bInsert
  677.            
  678.             end
  679.         end
  680.     end
  681. end
  682.  
  683. --main timer interval actions
  684. function tick()
  685.     --do interval stuff
  686.     --insertText("HI")
  687.     --sMessage = "TIMER HIT!"
  688.    
  689.     tTimer = os.startTimer(TIMER_INTERVAL) --reset timer
  690. end
  691.  
  692. --main loop
  693. function mainLoop()
  694.     tTimer = os.startTimer(TIMER_INTERVAL) --start interval timer
  695.    
  696.     while bRunning do
  697.         sDebugText = "" --clear debug info
  698.        
  699.         input() --get input and respond
  700.        
  701.         --debug info
  702.         local x,y = term.getCursorPos()
  703.         --sDebugText = sDebugText .. " Running:" ..tostring(bRunning)
  704.         --sDebugText = sDebugText .. " File:"..xFile..","..yFile .." Scrn:"..x..","..y
  705.        
  706.         scroll() --shift screen to show cursor
  707.         draw() --update screen
  708.     end
  709. end
  710.  
  711. --exit program
  712. function exit()
  713.     if bUnsavedChanges and not bConfirmingExit then --if there are unsaved changes, and this warning hasnt displayed yet
  714.         sMessage = "UNSAVED CHANGES - Press F4 to exit"
  715.         bConfirmingExit = true
  716.     else
  717.         bRunning = false end
  718. end
  719.  
  720. --have the program exit cleanly and tidily
  721. function exitCleanup()
  722.     term.clear()
  723.     term.setCursorPos(SCREEN_ORIGIN,SCREEN_ORIGIN)
  724. end
  725.  
  726. intialize()
  727. mainLoop()
  728. exitCleanup()
Advertisement
Add Comment
Please, Sign In to add comment