Advertisement
Pinkishu

bedit4

Jul 22nd, 2012
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.08 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-scrollX,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.   local aIndex = scrollY - 1 + lineNum
  110.   if lines[aIndex] and string.len(lines[aIndex]) > scrollX then
  111.     if lineNum-1+scrollY <= #lines then
  112.       local s = scrollX+1
  113.       term.write(string.sub(lines[aIndex],s,s+tw-1))
  114.     end
  115.   end
  116.   restoreCursorPos()
  117. end
  118.  
  119. function redrawLines()
  120.   for i=2,th,1 do
  121.     redrawLine(i)
  122.  
  123.   end
  124.   --restoreCursorPos()
  125. end
  126.  
  127. function trim1(s)
  128.   return (s:gsub("^%s*(.-)%s*$", "%1"))
  129. end
  130.  
  131. function unIndentLines()
  132.   for i,v in ipairs(lines) do
  133.     lines[i] = trim1(lines[i])
  134.   end
  135. end
  136.  
  137. function isInTable(tabl,element,caseSensitive)
  138.   caseSensitive = caseSensitive or false
  139.   for k,v in pairs(tabl) do
  140.     if type(element) == "string" and type(v) == "string" then
  141.       if caseSenstive then
  142.         if element == v then return true end
  143.       else
  144.         if string.lower(element) == string.lower(v) then return true end
  145.       end
  146.     else
  147.       if element == v then return true end
  148.     end
  149.   end
  150.   return false
  151. end
  152.  
  153. function indentProc(chr,buffer,indentLevel,newIndentLevel,inString)
  154.   chr = string.upper(chr)
  155.   if inString then
  156.     if keys[chr] == "STRING" then
  157.       return chr,buffer,indentLevel,newIndentLevel,false
  158.     else
  159.       return chr,buffer,indentLevel,newIndentLevel,inString
  160.     end
  161.   else
  162.     if keys[chr] == "STRING" then
  163.       inString = true
  164.     elseif isInTable(upperKeys,keys[chr]) then
  165.       newIndentLevel = newIndentLevel + 1
  166.     elseif isInTable(lowerKeys, keys[chr]) then
  167.       if newIndentLevel > 0 then
  168.         newIndentLevel = newIndentLevel - 1
  169.       else
  170.         indentLevel = indentLevel -1
  171.         --newIndentLevel = newIndentLevel - 1
  172.       end
  173.     elseif isInTable(splitter,keys[chr]) then
  174.       buffer = ""
  175.     end
  176.     return chr,buffer,indentLevel,newIndentLevel,inString
  177.   end
  178. end
  179.  
  180. function autoIndent()
  181.   unIndentLines()
  182.   local spacing = standardSpaces
  183.   local inString = false
  184.  
  185.   local indentLevel = 0
  186.   for i,_ in ipairs(lines) do
  187.     --lines[i] = string.rep(" ",height*spacing) .. lines[i]
  188.     local buffer = ""
  189.     --local indentLevel = indentLevel
  190.     local newIndentLevel = 0
  191.     --local nextIndentLevel = indentLevel
  192.    
  193.     for k=1,string.len(lines[i]),1 do
  194.       local chr = string.sub(lines[i],k,k)
  195.       if keys[chr] then
  196.        
  197.         _,buffer,indentLevel,newIndentLevel,inString = indentProc(chr,buffer,indentLevel,newIndentLevel,inString)
  198.         buffer = ""
  199.       else
  200.         buffer = buffer .. chr
  201.         --
  202.         if keys[string.upper(buffer)] then
  203.           --print(buffer) read()
  204.           _,buffer,indentLevel,newIndentLevel,inString = indentProc(buffer,buffer,indentLevel,newIndentLevel,inString)
  205.           buffer = ""
  206.         end
  207.       end
  208.      
  209.     end
  210.    
  211.     lines[i] = string.rep(" ",math.max(0,indentLevel)*spacing) .. lines[i]
  212.     indentLevel = indentLevel + newIndentLevel
  213.   end
  214. end
  215.  
  216.  
  217.  
  218. function redrawBar()
  219.   local entries = { "C:"..column, "L:" .. line, ( editMode == 0 and "INS" or "OVR" ), scrollX.."/"..scrollY  }
  220.   local entryWidth = tw / #entries
  221.   term.setCursorPos(1,1)
  222.   term.clearLine()
  223.   for i,v in ipairs(entries) do
  224.     term.setCursorPos(i*entryWidth-(entryWidth/2)-(string.len(v)/2),1)
  225.     term.write(v)
  226.   end
  227.   restoreCursorPos()
  228. end
  229.  
  230. function scroll(nScrollX,nScrollY)
  231.   scrollY = nScrollY
  232.   scrollX = nScrollX
  233.   redrawLines()
  234. end
  235.  
  236. function setCursor(nColumn,nLine)
  237.   column = nColumn
  238.   line = nLine
  239.   local nX,nY = scrollX,scrollY
  240.   if nColumn <= scrollX then
  241.     nX = nColumn - 1
  242.   elseif nColumn > scrollX + tw then
  243.     nX = nColumn-tw
  244.   end
  245.   if nLine > scrollY and nLine <= scrollY + th - 1 then
  246.    
  247.   else
  248.     if nLine <= scrollY then
  249.       nY = nLine -1
  250.       --scroll(column,nLine-1)
  251.      
  252.     elseif nLine > scrollY + th - 1 then
  253.       nY = nLine - (th-1)
  254.       --scroll(column,nLine - (th-1))
  255.     end  
  256.   end
  257.   scroll(nX,nY)
  258.   redrawBar()
  259. end
  260.  
  261. function jumpToLine(lineNum)
  262.   setCursor(column,lineNum)
  263. end
  264.  
  265. function countIndention(str)
  266.  
  267.   for i=1,string.len(str),1 do
  268.     if string.byte(str,i,i) ~= 32 and string.byte(str,i,i) ~= 9 then return i-1 end
  269.   end
  270.   return 0
  271. end
  272.  
  273. jumpToLine(tonumber(tArgs[2]) or line)
  274. redrawLines()
  275. term.setCursorBlink(true)
  276.  
  277. screens.menu.keyHandler = function(p1)
  278.   if p1 == 208 then
  279.     menuIndex = math.min(menuIndex+1,#menuOptions)
  280.     drawMenuCursor()
  281.     --down
  282.   elseif p1 == 200 then
  283.     menuIndex = math.max(1,menuIndex-1)
  284.     drawMenuCursor()
  285.     --up
  286.   elseif p1 == 28 then
  287.     local opt = menuOptions[menuIndex]
  288.     if opt == "New" then
  289.       lines = {""}
  290.       file = "new"
  291.       local count = 0
  292.       while fs.exists(file) do
  293.         count = count + 1
  294.         file = "new-"..count
  295.       end
  296.       column,line=1,1
  297.       setScreen(screens.edit)
  298.     elseif opt == "Exit Menu" then
  299.       setScreen(screens.edit)
  300.     elseif opt == "Quit to Shell" then
  301.       done = true
  302.       os.queueEvent("done")
  303.     elseif opt == "Auto Indent" then
  304.       autoIndent()
  305.       setScreen(screens.edit)
  306.     elseif opt == "Save" then
  307.       saveFile()
  308.       setMenuStatus("Saved.",2.5)
  309.     else
  310.       setMenuStatus("Not implemented yet.", 1.5)
  311.     end
  312.   elseif p1 == menuKey then
  313.     setScreen(screens.edit)
  314.   end
  315. end
  316.  
  317. screens.menu.charHandler = function()
  318.   menuIndex = 1
  319.   term.setCursorBlink(false)
  320.   drawMenu()
  321. end
  322.  
  323. screens.menu["timerHandler"] = function(p1)
  324.   if p1 == menuTimer then
  325.     term.setCursorPos(1,th-1)
  326.     term.clearLine()
  327.     restoreCursorPos()
  328.     menuTimer = nil
  329.   end
  330. end
  331.  
  332. screens.edit.keyHandler = function(p1)
  333.   if p1 == 200 then
  334.     if line > 1 then
  335.       setCursor(math.min(column,string.len(lines[line-1])+1),line-1)
  336.     end
  337.     --up
  338.   elseif p1 == 203 then
  339.     if column > 1 then
  340.       setCursor(column-1,line)
  341.     elseif line > 1 then
  342.       setCursor(string.len(lines[line-1])+1,line-1)
  343.     end
  344.     --left
  345.   elseif p1 == 205 then
  346.     if column < string.len(lines[line]) + 1 then
  347.       setCursor(column+1,line)
  348.     elseif line < #lines then
  349.       setCursor(1,line+1)
  350.     end
  351.     --right
  352.   elseif p1 == 208 then
  353.     if line < #lines then
  354.       setCursor(math.min(column,string.len(lines[line+1])+1),line+1)
  355.     end
  356.     --down
  357.   elseif p1 == 207 then
  358.     setCursor(string.len(lines[line])+1,line)
  359.     --end
  360.   elseif p1 == 199 then
  361.     setCursor(1,line)
  362.     --home
  363.   elseif p1 == 14 then
  364.     --backspace
  365.     local tarX,tarY = column-1,line
  366.     if tarX < 1 then
  367.       if line > 1 then
  368.         lines[line-1] = lines[line-1]..lines[line]
  369.         setCursor(string.len(lines[line-1])+1-string.len(table.remove(lines,line)),line-1)
  370.         redrawLines()
  371.       end
  372.      
  373.     else
  374.       lines[tarY] = string.sub(lines[tarY],0,tarX-1)..string.sub(lines[tarY],tarX+1)
  375.       redrawLine(tarY-scrollY+1)
  376.       setCursor(column-1,line)
  377.     end
  378.   elseif p1 == 28 then
  379.     --enter
  380.     local wSpaces = countIndention(lines[line])
  381.     local nL = string.rep(" ",wSpaces) .. string.sub(lines[line],column)
  382.     lines[line] = string.sub(lines[line],0,column-1)
  383.     table.insert(lines,line+1,nL)
  384.     redrawLines()
  385.     setCursor(1+wSpaces,line+1)
  386.   elseif p1 == 210 then
  387.     --INS
  388.     if editMode == 0 then editMode = 1
  389.     else editMode = 0 end
  390.     redrawBar()
  391.   elseif p1 == 211 then
  392.     --DEL
  393.     if column < string.len(lines[line])+1 then
  394.       lines[line] = string.sub(lines[line],0,column-1)..string.sub(lines[line],column+1)
  395.       redrawLine(line-scrollY+1)
  396.     elseif line < #lines then
  397.       lines[line] = lines[line] .. table.remove(lines,line+1)
  398.       redrawLines()
  399.     end
  400.   elseif p1 == 15 then
  401.     --tab
  402.     for i=1,standardSpaces,1 do
  403.       os.queueEvent("char"," ")
  404.     end
  405.   elseif p1 == menuKey then
  406.     setScreen(screens.menu)
  407.     drawMenu()
  408.   end
  409. end
  410.  
  411. screens.edit.charHandler = function(p1)
  412.   if editMode == 0 then
  413.     lines[line] = string.sub(lines[line],0,column-1)..p1..string.sub(lines[line],column)
  414.   else
  415.     lines[line] = string.sub(lines[line],0,column-1)..p1..string.sub(lines[line],column+1)    
  416.   end
  417.   setCursor(column+1,line)
  418.   redrawLine(line-scrollY+1)
  419. end
  420.  
  421. screens.edit.init = function()
  422.   term.setCursorBlink(true)
  423.   redrawLines()
  424.   redrawBar()
  425.   setCursor(column,line)
  426.  
  427. end
  428.  
  429.  
  430.  
  431. setScreen(screens.edit)
  432.  
  433. while not done do
  434.   local ev,p1 = os.pullEvent()
  435.   if curScreen[ev.."Handler"] then
  436.     curScreen[ev.."Handler"](p1)
  437.   end
  438.  
  439. end
  440.  
  441. term.clear()
  442. term.setCursorPos(1,1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement