Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local tArgs = {...}
- if #tArgs == 0 then
- error("No file specified.")
- end
- local editMode = 0
- local file = tArgs[1]
- local line,column = 1,1
- local scrollX,scrollY = 0,0
- local menuScroll,menuIndex = 0,1
- local tw,th = term.getSize()
- local curScreen = nil
- local keyHandler = nil
- local charHandler = nil
- local menuKey = 197
- local menuTimer = -1
- local standardSpaces = 2
- local menuOptions = { "New", "Open", "Save", "Save As...", "Save Copy As...", "Auto Indent", "Import", "Export", "Options", "Exit Menu", "Quit to Shell" }
- local screens = { edit = { }, menu = { } }
- local done = false
- 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" }
- local upperKeys = { "KEY_BRACE_OPEN", "KEY_THEN", "KEY_DO", "KEY_FUNC_OP", "KEY_PAR_OP" }
- local lowerKeys = { "KEY_END", "KEY_BRACE_CLOSE", "KEY_PAR_CLOSE" }
- local splitter = { "KEY_SPACE" }
- th = th
- term.clear()
- lines = {}
- function printCenteredText(line,text)
- term.setCursorPos(tw/2-string.len(text)/2,line)
- term.write(text)
- end
- function drawMenu()
- term.setCursorBlink(false)
- term.clear()
- printCenteredText(1,"Menu")
- printCenteredText(2,file)
- term.setCursorPos(3,2)
- for i=1,math.min(th-2,#menuOptions),1 do
- term.setCursorPos(3,i+2)
- term.write(menuOptions[i])
- end
- drawMenuCursor()
- end
- function setMenuStatus(text,timer)
- printCenteredText(th,text)
- restoreCursorPos()
- menuTimer = os.startTimer(timer)
- end
- function drawMenuCursor()
- for i=1,math.min(th-2,#menuOptions),1 do
- term.setCursorPos(1,i+2)
- term.write( ( i + menuScroll == menuIndex) and " >" or " " )
- end
- end
- function setScreen(screen)
- curScreen = screen
- if curScreen.init then
- curScreen.init()
- end
- end
- --setScreen(screens.edit)
- function restoreCursorPos()
- term.setCursorPos(column-scrollX,2+(line-scrollY)-1)
- end
- function loadFile(fileName)
- local file = io.open( fileName, "r" )
- lines = {}
- if not fs.exists(fileName) then lines = {""} return end
- for line in file:lines(fileName) do
- table.insert(lines,line)
- end
- end
- loadFile(file)
- if #lines == 0 then lines = {""} end
- function saveFile(saveName)
- saveName = saveName or file
- if fs.exists(saveName..".savbkp") then fs.delete(saveName..".savbkp") end
- if fs.exists( saveName ) then
- fs.copy(saveName,saveName..".savbkp")
- end
- local file = fs.open( saveName, "w")
- for _,v in ipairs(lines) do
- file.writeLine(v)
- end
- file.close()
- if fs.exists(saveName..".savbkp") then
- fs.delete(saveName..".savbkp")
- end
- end
- function redrawLine(lineNum)
- term.setCursorPos(1,lineNum)
- term.clearLine()
- local aIndex = scrollY - 1 + lineNum
- if lines[aIndex] and string.len(lines[aIndex]) > scrollX then
- if lineNum-1+scrollY <= #lines then
- local s = scrollX+1
- term.write(string.sub(lines[aIndex],s,s+tw-1))
- end
- end
- restoreCursorPos()
- end
- function redrawLines()
- for i=2,th,1 do
- redrawLine(i)
- end
- --restoreCursorPos()
- end
- function trim1(s)
- return (s:gsub("^%s*(.-)%s*$", "%1"))
- end
- function unIndentLines()
- for i,v in ipairs(lines) do
- lines[i] = trim1(lines[i])
- end
- end
- function isInTable(tabl,element,caseSensitive)
- caseSensitive = caseSensitive or false
- for k,v in pairs(tabl) do
- if type(element) == "string" and type(v) == "string" then
- if caseSenstive then
- if element == v then return true end
- else
- if string.lower(element) == string.lower(v) then return true end
- end
- else
- if element == v then return true end
- end
- end
- return false
- end
- function indentProc(chr,buffer,indentLevel,newIndentLevel,inString)
- chr = string.upper(chr)
- if inString then
- if keys[chr] == "STRING" then
- return chr,buffer,indentLevel,newIndentLevel,false
- else
- return chr,buffer,indentLevel,newIndentLevel,inString
- end
- else
- if keys[chr] == "STRING" then
- inString = true
- elseif isInTable(upperKeys,keys[chr]) then
- newIndentLevel = newIndentLevel + 1
- elseif isInTable(lowerKeys, keys[chr]) then
- if newIndentLevel > 0 then
- newIndentLevel = newIndentLevel - 1
- else
- indentLevel = indentLevel -1
- --newIndentLevel = newIndentLevel - 1
- end
- elseif isInTable(splitter,keys[chr]) then
- buffer = ""
- end
- return chr,buffer,indentLevel,newIndentLevel,inString
- end
- end
- function autoIndent()
- unIndentLines()
- local spacing = standardSpaces
- local inString = false
- local indentLevel = 0
- for i,_ in ipairs(lines) do
- --lines[i] = string.rep(" ",height*spacing) .. lines[i]
- local buffer = ""
- --local indentLevel = indentLevel
- local newIndentLevel = 0
- --local nextIndentLevel = indentLevel
- for k=1,string.len(lines[i]),1 do
- local chr = string.sub(lines[i],k,k)
- if keys[chr] then
- _,buffer,indentLevel,newIndentLevel,inString = indentProc(chr,buffer,indentLevel,newIndentLevel,inString)
- buffer = ""
- else
- buffer = buffer .. chr
- --
- if keys[string.upper(buffer)] then
- --print(buffer) read()
- _,buffer,indentLevel,newIndentLevel,inString = indentProc(buffer,buffer,indentLevel,newIndentLevel,inString)
- buffer = ""
- end
- end
- end
- lines[i] = string.rep(" ",math.max(0,indentLevel)*spacing) .. lines[i]
- indentLevel = indentLevel + newIndentLevel
- end
- end
- function redrawBar()
- local entries = { "C:"..column, "L:" .. line, ( editMode == 0 and "INS" or "OVR" ), scrollX.."/"..scrollY }
- local entryWidth = tw / #entries
- term.setCursorPos(1,1)
- term.clearLine()
- for i,v in ipairs(entries) do
- term.setCursorPos(i*entryWidth-(entryWidth/2)-(string.len(v)/2),1)
- term.write(v)
- end
- restoreCursorPos()
- end
- function scroll(nScrollX,nScrollY)
- scrollY = nScrollY
- scrollX = nScrollX
- redrawLines()
- end
- function setCursor(nColumn,nLine)
- column = nColumn
- line = nLine
- local nX,nY = scrollX,scrollY
- if nColumn <= scrollX then
- nX = nColumn - 1
- elseif nColumn > scrollX + tw then
- nX = nColumn-tw
- end
- if nLine > scrollY and nLine <= scrollY + th - 1 then
- else
- if nLine <= scrollY then
- nY = nLine -1
- --scroll(column,nLine-1)
- elseif nLine > scrollY + th - 1 then
- nY = nLine - (th-1)
- --scroll(column,nLine - (th-1))
- end
- end
- scroll(nX,nY)
- redrawBar()
- end
- function jumpToLine(lineNum)
- setCursor(column,lineNum)
- end
- function countIndention(str)
- for i=1,string.len(str),1 do
- if string.byte(str,i,i) ~= 32 and string.byte(str,i,i) ~= 9 then return i-1 end
- end
- return 0
- end
- jumpToLine(tonumber(tArgs[2]) or line)
- redrawLines()
- term.setCursorBlink(true)
- screens.menu.keyHandler = function(p1)
- if p1 == 208 then
- menuIndex = math.min(menuIndex+1,#menuOptions)
- drawMenuCursor()
- --down
- elseif p1 == 200 then
- menuIndex = math.max(1,menuIndex-1)
- drawMenuCursor()
- --up
- elseif p1 == 28 then
- local opt = menuOptions[menuIndex]
- if opt == "New" then
- lines = {""}
- file = "new"
- local count = 0
- while fs.exists(file) do
- count = count + 1
- file = "new-"..count
- end
- column,line=1,1
- setScreen(screens.edit)
- elseif opt == "Exit Menu" then
- setScreen(screens.edit)
- elseif opt == "Quit to Shell" then
- done = true
- os.queueEvent("done")
- elseif opt == "Auto Indent" then
- autoIndent()
- setScreen(screens.edit)
- elseif opt == "Save" then
- saveFile()
- setMenuStatus("Saved.",2.5)
- else
- setMenuStatus("Not implemented yet.", 1.5)
- end
- elseif p1 == menuKey then
- setScreen(screens.edit)
- end
- end
- screens.menu.charHandler = function()
- menuIndex = 1
- term.setCursorBlink(false)
- drawMenu()
- end
- screens.menu["timerHandler"] = function(p1)
- if p1 == menuTimer then
- term.setCursorPos(1,th-1)
- term.clearLine()
- restoreCursorPos()
- menuTimer = nil
- end
- end
- screens.edit.keyHandler = function(p1)
- if p1 == 200 then
- if line > 1 then
- setCursor(math.min(column,string.len(lines[line-1])+1),line-1)
- end
- --up
- elseif p1 == 203 then
- if column > 1 then
- setCursor(column-1,line)
- elseif line > 1 then
- setCursor(string.len(lines[line-1])+1,line-1)
- end
- --left
- elseif p1 == 205 then
- if column < string.len(lines[line]) + 1 then
- setCursor(column+1,line)
- elseif line < #lines then
- setCursor(1,line+1)
- end
- --right
- elseif p1 == 208 then
- if line < #lines then
- setCursor(math.min(column,string.len(lines[line+1])+1),line+1)
- end
- --down
- elseif p1 == 207 then
- setCursor(string.len(lines[line])+1,line)
- --end
- elseif p1 == 199 then
- setCursor(1,line)
- --home
- elseif p1 == 14 then
- --backspace
- local tarX,tarY = column-1,line
- if tarX < 1 then
- if line > 1 then
- lines[line-1] = lines[line-1]..lines[line]
- setCursor(string.len(lines[line-1])+1-string.len(table.remove(lines,line)),line-1)
- redrawLines()
- end
- else
- lines[tarY] = string.sub(lines[tarY],0,tarX-1)..string.sub(lines[tarY],tarX+1)
- redrawLine(tarY-scrollY+1)
- setCursor(column-1,line)
- end
- elseif p1 == 28 then
- --enter
- local wSpaces = countIndention(lines[line])
- local nL = string.rep(" ",wSpaces) .. string.sub(lines[line],column)
- lines[line] = string.sub(lines[line],0,column-1)
- table.insert(lines,line+1,nL)
- redrawLines()
- setCursor(1+wSpaces,line+1)
- elseif p1 == 210 then
- --INS
- if editMode == 0 then editMode = 1
- else editMode = 0 end
- redrawBar()
- elseif p1 == 211 then
- --DEL
- if column < string.len(lines[line])+1 then
- lines[line] = string.sub(lines[line],0,column-1)..string.sub(lines[line],column+1)
- redrawLine(line-scrollY+1)
- elseif line < #lines then
- lines[line] = lines[line] .. table.remove(lines,line+1)
- redrawLines()
- end
- elseif p1 == 15 then
- --tab
- for i=1,standardSpaces,1 do
- os.queueEvent("char"," ")
- end
- elseif p1 == menuKey then
- setScreen(screens.menu)
- drawMenu()
- end
- end
- screens.edit.charHandler = function(p1)
- if editMode == 0 then
- lines[line] = string.sub(lines[line],0,column-1)..p1..string.sub(lines[line],column)
- else
- lines[line] = string.sub(lines[line],0,column-1)..p1..string.sub(lines[line],column+1)
- end
- setCursor(column+1,line)
- redrawLine(line-scrollY+1)
- end
- screens.edit.init = function()
- term.setCursorBlink(true)
- redrawLines()
- redrawBar()
- setCursor(column,line)
- end
- setScreen(screens.edit)
- while not done do
- local ev,p1 = os.pullEvent()
- if curScreen[ev.."Handler"] then
- curScreen[ev.."Handler"](p1)
- end
- end
- term.clear()
- term.setCursorPos(1,1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement