Pinkishu

bedit3

Jul 15th, 2012
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.69 KB | None | 0 0
  1. local tArgs = {...}
  2. if #tArgs == 0 then
  3.   error("No file specified.")
  4. end
  5.  
  6. local editMode = 0
  7. local file = tArgs[1]
  8. local line,column = 1,1
  9. local scrollX,scrollY = 0,0
  10. local menuScroll,menuIndex = 0,1
  11. local tw,th = term.getSize()
  12. local curScreen = nil
  13. local keyHandler = nil
  14. local charHandler = nil
  15. local menuKey = 197
  16. local menuTimer = -1
  17. local standardSpaces = 2
  18. local menuOptions = { "New", "Open", "Save", "Save As...", "Save Copy As...", "Auto Indent", "Import", "Export", "Options", "Exit Menu", "Quit to Shell" }
  19. local screens = { edit = {  }, menu = { } }
  20. local done = false
  21. local keys = { ["\""] = "STRING", ["("] = "KEY_PAR_OP", [")"] = "KEY_PAR_CLOSE", ["{"] = "KEY_BRACE_OPEN", ["}"] = "KEY_BRACE_CLOSE", ["THEN"] = "KEY_THEN", ["DO"] = "KEY_DO", ["END"] = "KEY_END", [" "] = "KEY_SPACE", ["FUNCTION"] = "KEY_FUNC_OP" }
  22. local upperKeys = { "KEY_BRACE_OPEN", "KEY_THEN", "KEY_DO", "KEY_FUNC_OP", "KEY_PAR_OP" }
  23. local lowerKeys = { "KEY_END", "KEY_BRACE_CLOSE", "KEY_PAR_CLOSE" }
  24. local splitter = { "KEY_SPACE" }
  25.  
  26.  
  27. th = th
  28.  
  29. term.clear()
  30.  
  31. lines = {}
  32.  
  33. function printCenteredText(line,text)
  34.   term.setCursorPos(tw/2-string.len(text)/2,line)
  35.   term.write(text)
  36. end
  37.  
  38. function drawMenu()
  39.   term.setCursorBlink(false)
  40.   term.clear()
  41.   printCenteredText(1,"Menu")
  42.   printCenteredText(2,file)
  43.  
  44.   term.setCursorPos(3,2)
  45.   for i=1,math.min(th-2,#menuOptions),1 do
  46.     term.setCursorPos(3,i+2)
  47.     term.write(menuOptions[i])
  48.   end
  49.   drawMenuCursor()
  50. end
  51.  
  52. function setMenuStatus(text,timer)
  53.  
  54.   printCenteredText(th,text)
  55.   restoreCursorPos()
  56.   menuTimer = os.startTimer(timer)
  57.  
  58. end
  59.  
  60. function drawMenuCursor()
  61.   for i=1,math.min(th-2,#menuOptions),1 do
  62.     term.setCursorPos(1,i+2)
  63.     term.write( ( i + menuScroll == menuIndex) and " >" or "  " )
  64.   end
  65. end
  66.  
  67. function setScreen(screen)
  68.   curScreen = screen
  69.   if curScreen.init then
  70.     curScreen.init()
  71.   end
  72. end
  73. --setScreen(screens.edit)
  74.  
  75. function restoreCursorPos()
  76.   term.setCursorPos(column,2+(line-scrollY)-1)
  77. end
  78.  
  79. function loadFile(fileName)
  80.   local file = io.open( fileName, "r" )
  81.   lines = {}
  82.   if not fs.exists(fileName) then lines = {""} return end
  83.   for line in file:lines(fileName) do
  84.     table.insert(lines,line)
  85.   end
  86. end
  87. loadFile(file)
  88. if #lines == 0 then lines = {""} end
  89.  
  90. function saveFile(saveName)
  91.   saveName = saveName or file
  92.   if fs.exists(saveName..".savbkp") then fs.delete(saveName..".savbkp") end
  93.   if fs.exists( saveName ) then
  94.     fs.copy(saveName,saveName..".savbkp")
  95.   end
  96.   local file = fs.open( saveName, "w")
  97.   for _,v in ipairs(lines) do
  98.     file.writeLine(v)
  99.   end
  100.   file.close()
  101.   if fs.exists(saveName..".savbkp") then
  102.     fs.delete(saveName..".savbkp")
  103.   end
  104. end
  105.  
  106. function redrawLine(lineNum)
  107.   term.setCursorPos(1,lineNum)
  108.   term.clearLine()
  109.   if lineNum-1+scrollY <= #lines then
  110.     term.write(lines[scrollY-1+lineNum])
  111.   end
  112.   restoreCursorPos()
  113. end
  114.  
  115. function redrawLines()
  116.   for i=2,th,1 do
  117.     redrawLine(i)
  118.  
  119.   end
  120.   --restoreCursorPos()
  121. end
  122.  
  123. function trim1(s)
  124.   return (s:gsub("^%s*(.-)%s*$", "%1"))
  125. end
  126.  
  127. function unIndentLines()
  128.   for i,v in ipairs(lines) do
  129.     lines[i] = trim1(lines[i])
  130.   end
  131. end
  132.  
  133. function isInTable(tabl,element,caseSensitive)
  134.   caseSensitive = caseSensitive or false
  135.   for k,v in pairs(tabl) do
  136.     if type(element) == "string" and type(v) == "string" then
  137.       if caseSenstive then
  138.         if element == v then return true end
  139.       else
  140.         if string.lower(element) == string.lower(v) then return true end
  141.       end
  142.     else
  143.       if element == v then return true end
  144.     end
  145.   end
  146.   return false
  147. end
  148.  
  149. function indentProc(chr,buffer,indentLevel,newIndentLevel,inString)
  150.   chr = string.upper(chr)
  151.   if inString then
  152.     if keys[chr] == "STRING" then
  153.       return chr,buffer,indentLevel,newIndentLevel,false
  154.     else
  155.       return chr,buffer,indentLevel,newIndentLevel,inString
  156.     end
  157.   else
  158.     if keys[chr] == "STRING" then
  159.       inString = true
  160.     elseif isInTable(upperKeys,keys[chr]) then
  161.       newIndentLevel = newIndentLevel + 1
  162.     elseif isInTable(lowerKeys, keys[chr]) then
  163.       if newIndentLevel > 0 then
  164.         newIndentLevel = newIndentLevel - 1
  165.       else
  166.         indentLevel = indentLevel -1
  167.         --newIndentLevel = newIndentLevel - 1
  168.       end
  169.     elseif isInTable(splitter,keys[chr]) then
  170.       buffer = ""
  171.     end
  172.     return chr,buffer,indentLevel,newIndentLevel,inString
  173.   end
  174. end
  175.  
  176. function autoIndent()
  177.   unIndentLines()
  178.   local spacing = standardSpaces
  179.   local inString = false
  180.  
  181.   local indentLevel = 0
  182.   for i,_ in ipairs(lines) do
  183.     --lines[i] = string.rep(" ",height*spacing) .. lines[i]
  184.     local buffer = ""
  185.     --local indentLevel = indentLevel
  186.     local newIndentLevel = 0
  187.     --local nextIndentLevel = indentLevel
  188.    
  189.     for k=1,string.len(lines[i]),1 do
  190.       local chr = string.sub(lines[i],k,k)
  191.       if keys[chr] then
  192.        
  193.         _,buffer,indentLevel,newIndentLevel,inString = indentProc(chr,buffer,indentLevel,newIndentLevel,inString)
  194.         buffer = ""
  195.       else
  196.         buffer = buffer .. chr
  197.         --
  198.         if keys[string.upper(buffer)] then
  199.           --print(buffer) read()
  200.           _,buffer,indentLevel,newIndentLevel,inString = indentProc(buffer,buffer,indentLevel,newIndentLevel,inString)
  201.           buffer = ""
  202.         end
  203.       end
  204.      
  205.     end
  206.    
  207.     lines[i] = string.rep(" ",math.max(0,indentLevel)*spacing) .. lines[i]
  208.     indentLevel = indentLevel + newIndentLevel
  209.   end
  210. end
  211.  
  212.  
  213.  
  214. function redrawBar()
  215.   local entries = { "C:"..column, "L:" .. line, ( editMode == 0 and "INS" or "OVR" )  }
  216.   local entryWidth = tw / #entries
  217.   term.setCursorPos(1,1)
  218.   term.clearLine()
  219.   for i,v in ipairs(entries) do
  220.     term.setCursorPos(i*entryWidth-(entryWidth/2)-(string.len(v)/2),1)
  221.     term.write(v)
  222.   end
  223.   restoreCursorPos()
  224. end
  225.  
  226. function scroll(nScrollX,nScrollY)
  227.   scrollY = nScrollY
  228.   scrollX = nScrollX
  229.   redrawLines()
  230. end
  231.  
  232. function setCursor(nColumn,nLine)
  233.   column = nColumn
  234.   line = nLine
  235.   if nLine > scrollY and nLine <= scrollY + th - 1 then
  236.    
  237.   else
  238.     if nLine <= scrollY then
  239.       scroll(column,nLine-1)
  240.      
  241.     elseif nLine > scrollY + th - 1 then
  242.       scroll(column,nLine - (th-1))
  243.     end  
  244.   end
  245.   redrawBar()
  246. end
  247.  
  248. function jumpToLine(lineNum)
  249.   setCursor(column,lineNum)
  250. end
  251.  
  252. function countIndention(str)
  253.  
  254.   for i=1,string.len(str),1 do
  255.     if string.byte(str,i,i) ~= 32 and string.byte(str,i,i) ~= 9 then return i-1 end
  256.   end
  257.   return 0
  258. end
  259.  
  260. jumpToLine(tonumber(tArgs[2]) or line)
  261. redrawLines()
  262. term.setCursorBlink(true)
  263.  
  264. screens.menu.keyHandler = function(p1)
  265.   if p1 == 208 then
  266.     menuIndex = math.min(menuIndex+1,#menuOptions)
  267.     drawMenuCursor()
  268.     --down
  269.   elseif p1 == 200 then
  270.     menuIndex = math.max(1,menuIndex-1)
  271.     drawMenuCursor()
  272.     --up
  273.   elseif p1 == 28 then
  274.     local opt = menuOptions[menuIndex]
  275.     if opt == "New" then
  276.       lines = {""}
  277.       file = "new"
  278.       local count = 0
  279.       while fs.exists(file) do
  280.         count = count + 1
  281.         file = "new-"..count
  282.       end
  283.       column,line=1,1
  284.       setScreen(screens.edit)
  285.     elseif opt == "Exit Menu" then
  286.       setScreen(screens.edit)
  287.     elseif opt == "Quit to Shell" then
  288.       done = true
  289.       os.queueEvent("done")
  290.     elseif opt == "Auto Indent" then
  291.       autoIndent()
  292.       setScreen(screens.edit)
  293.     elseif opt == "Save" then
  294.       saveFile()
  295.       setMenuStatus("Saved.",2.5)
  296.     else
  297.       setMenuStatus("Not implemented yet.", 1.5)
  298.     end
  299.   elseif p1 == menuKey then
  300.     setScreen(screens.edit)
  301.   end
  302. end
  303.  
  304. screens.menu.charHandler = function()
  305.   menuIndex = 1
  306.   term.setCursorBlink(false)
  307.   drawMenu()
  308. end
  309.  
  310. screens.menu["timerHandler"] = function(p1)
  311.   if p1 == menuTimer then
  312.     term.setCursorPos(1,th-1)
  313.     term.clearLine()
  314.     restoreCursorPos()
  315.     menuTimer = nil
  316.   end
  317. end
  318.  
  319. screens.edit.keyHandler = function(p1)
  320.   if p1 == 200 then
  321.     if line > 1 then
  322.       setCursor(math.min(column,string.len(lines[line-1])+1),line-1)
  323.     end
  324.     --up
  325.   elseif p1 == 203 then
  326.     if column > 1 then
  327.       setCursor(column-1,line)
  328.     elseif line > 1 then
  329.       setCursor(string.len(lines[line-1])+1,line-1)
  330.     end
  331.     --left
  332.   elseif p1 == 205 then
  333.     if column < string.len(lines[line]) + 1 then
  334.       setCursor(column+1,line)
  335.     elseif line < #lines then
  336.       setCursor(1,line+1)
  337.     end
  338.     --right
  339.   elseif p1 == 208 then
  340.     if line < #lines then
  341.       setCursor(math.min(column,string.len(lines[line+1])+1),line+1)
  342.     end
  343.     --down
  344.   elseif p1 == 207 then
  345.     setCursor(string.len(lines[line])+1,line)
  346.     --end
  347.   elseif p1 == 199 then
  348.     setCursor(1,line)
  349.     --home
  350.   elseif p1 == 14 then
  351.     --backspace
  352.     local tarX,tarY = column-1,line
  353.     if tarX < 1 then
  354.       if line > 1 then
  355.         lines[line-1] = lines[line-1]..lines[line]
  356.         setCursor(string.len(lines[line-1])+1-string.len(table.remove(lines,line)),line-1)
  357.         redrawLines()
  358.       end
  359.      
  360.     else
  361.       lines[tarY] = string.sub(lines[tarY],0,tarX-1)..string.sub(lines[tarY],tarX+1)
  362.       redrawLine(tarY-scrollY+1)
  363.       setCursor(column-1,line)
  364.     end
  365.   elseif p1 == 28 then
  366.     --enter
  367.     local wSpaces = countIndention(lines[line])
  368.     local nL = string.rep(" ",wSpaces) .. string.sub(lines[line],column)
  369.     lines[line] = string.sub(lines[line],0,column-1)
  370.     table.insert(lines,line+1,nL)
  371.     redrawLines()
  372.     setCursor(1+wSpaces,line+1)
  373.   elseif p1 == 210 then
  374.     --INS
  375.     if editMode == 0 then editMode = 1
  376.     else editMode = 0 end
  377.     redrawBar()
  378.   elseif p1 == 211 then
  379.     --DEL
  380.     if column < string.len(lines[line])+1 then
  381.       lines[line] = string.sub(lines[line],0,column-1)..string.sub(lines[line],column+1)
  382.       redrawLine(line-scrollY+1)
  383.     elseif line < #lines then
  384.       lines[line] = lines[line] .. table.remove(lines,line+1)
  385.       redrawLines()
  386.     end
  387.   elseif p1 == 15 then
  388.     --tab
  389.     for i=1,standardSpaces,1 do
  390.       os.queueEvent("char"," ")
  391.     end
  392.   elseif p1 == menuKey then
  393.     setScreen(screens.menu)
  394.     drawMenu()
  395.   end
  396. end
  397.  
  398. screens.edit.charHandler = function(p1)
  399.   if editMode == 0 then
  400.     lines[line] = string.sub(lines[line],0,column-1)..p1..string.sub(lines[line],column)
  401.   else
  402.     lines[line] = string.sub(lines[line],0,column-1)..p1..string.sub(lines[line],column+1)    
  403.   end
  404.   setCursor(column+1,line)
  405.   redrawLine(line-scrollY+1)
  406. end
  407.  
  408. screens.edit.init = function()
  409.   term.setCursorBlink(true)
  410.   redrawLines()
  411.   redrawBar()
  412.   setCursor(column,line)
  413.  
  414. end
  415.  
  416.  
  417.  
  418. setScreen(screens.edit)
  419.  
  420. while not done do
  421.   local ev,p1 = os.pullEvent()
  422.   if curScreen[ev.."Handler"] then
  423.     curScreen[ev.."Handler"](p1)
  424.   end
  425.  
  426. end
  427.  
  428. term.clear()
  429. term.setCursorPos(1,1)
Advertisement
Add Comment
Please, Sign In to add comment