Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- term.setBackgroundColor(colors.black)
- term.clear()
- local codeColorIn, handleMovementKeys, handleMouseMenu, handleScreen, handleTimer, handleDelete, handleEnter, handleChar, handleBackspace, handleMouse, save, import
- local text = {} -- text
- local lastText = {}
- local args = {...}
- local e = {} -- event data
- local textmt = {__index = function() return "" end} -- for new lines
- setmetatable(text,textmt)
- local MaxX,MaxY = term.getSize()
- local fancy = false
- local fileName = args[1]
- function import(file) -- import or open
- for i=1,#text do
- text[i] = nil
- lastText[i] = nil
- end
- local doc = ""
- if fs.exists(file) then
- doc = fs.open(file,"r")
- else
- return false
- end
- for i = 1,16384 do
- text[i] = doc.readLine()
- if text[i] == nil then break end
- end
- doc.close()
- return true
- end
- if fileName then
- import(fileName)
- end
- if not fileName then fileName = "NONAME" end
- function save(file) -- what could it mean?
- file = fs.open(file,"w")
- for i=1,(#text)+1 do
- file.writeLine(text[i])
- end
- file.close()
- end
- local settings = {}
- if fs.exists("LightTextSettings") then
- local settingsFile = fs.open("LightTextSettings","r")
- settings = textutils.unserialize(settingsFile.readAll())
- settingsFile.close()
- else
- settings.cursorString = "\149"
- settings.cursorColor = 2048
- settings.tabSize = 3
- local settingsFile = fs.open("LightTextSettings","w")
- settingsFile.writeLine(textutils.serialize(settings))
- settingsFile.close()
- end
- local cursorString = settings.cursorString
- local tabSize = settings.tabSize
- local KEYWORD = {
- ["if"] = colors.yellow,
- ["then"] = colors.yellow,
- ["else"] = colors.yellow,
- ["elseif"] = colors.yellow,
- ["for"] = colors.yellow,
- ["while"] = colors.yellow,
- ["do"] = colors.yellow,
- ["repeat"] = colors.yellow,
- ["return"] = colors.yellow,
- ["until"] = colors.yellow,
- ["end"] = colors.yellow,
- ["function"] = colors.lime,
- ["local"] = colors.yellow,
- ["break"] = colors.yellow,
- ["and"] = colors.blue,
- ["or"] = colors.blue,
- ["not"] = colors.blue,
- ["true"] = colors.blue,
- ["false"] = colors.blue,
- ["nil"] = colors.blue,
- ["in"] = colors.yellow,
- ["term"] = colors.orange,
- ["os"] = colors.orange,
- ["math"] = colors.orange,
- ["fs"] = colors.orange,
- ["io"] = colors.orange,
- ["string"] = colors.orange,
- ["sleep"] = colors.orange,
- ["print"] = colors.orange,
- ["write"] = colors.orange,
- ["shell"] = colors.orange,
- ["tostring"] = colors.orange,
- ["tonumber"] = colors.orange,
- ["setmetatable"] = colors.orange,
- ["getmetatable"] = colors.orange,
- ["..."] = colors.lightBlue, -- Not working properly
- [".."] = colors.brown, -- Not working properly
- ["___LightTextCommentColor"] = colors.lightGray,
- ["___LightTextStringColor"] = colors.cyan -- NYI
- }
- local SYNTAX = {
- ["."] = colors.green,
- [":"] = colors.green,
- [","] = colors.red,
- ["<"] = colors.lightBlue,
- [">"] = colors.lightBlue,
- ["="] = colors.lightBlue,
- ["+"] = colors.lightBlue,
- ["-"] = colors.lightBlue,
- ["/"] = colors.lightBlue,
- ["*"] = colors.lightBlue,
- ["^"] = colors.lightBlue,
- ["("] = colors.lime,
- [")"] = colors.lime,
- ["["] = colors.green,
- ["]"] = colors.green,
- ["{"] = colors.green,
- ["}"] = colors.green,
- ["'"] = colors.red,
- ["\""] = colors.red,
- ["#"] = colors.red
- }
- -- some variables
- local menu = false
- local codeMode = true
- local DefaultBackgroundColor = colors.black
- local DefaultTextColor = colors.white
- local screen = {minX = 1,minY = 1,maxX = 51,maxY = 19}
- local cursor = {x = 1,y = 1}
- local cursorTimer = os.startTimer(0.3)
- local isOnScreenCursor = false
- -- modular functions for event handling
- function handleMouseMenu()
- if e[4] == 3 and e[3] > 14 and e[3] < 18 then
- if codeMode then
- codeMode = false
- else
- codeMode = true
- end
- elseif e[4] == 8 and e[3] < 7 then
- save("TEMP")
- term.setCursorPos(1,1)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- error("",999)
- elseif e[4] == 5 and e[3] < 7 then
- save(fileName)
- elseif e[4] == 6 and e[3] < (11+#fileName) then
- local tempName = "]"
- while true do
- term.setCursorPos(1,6)
- term.clearLine()
- write("[Save as:"..tempName)
- e = {os.pullEvent()}
- if e[1] == "key" and e[2] == keys.enter then
- if #tempName < 2 then
- break
- else
- fileName = tempName:sub(1,#tempName-1)
- save(fileName)
- break
- end
- elseif e[1] == "key" and e[2] == keys.backspace and #tempName > 1 then
- tempName = tempName:sub(1,#tempName-2).."]"
- elseif e[1] == "char" then
- tempName = tempName:sub(1,#tempName-1)..e[2].."]"
- end
- end
- elseif e[4] == 7 and e[3] < 8 then
- local tempName = "] "
- while true do
- term.setCursorPos(1,7)
- write("[Open:"..tempName)
- e = {os.pullEvent()}
- if e[1] == "key" and e[2] == keys.enter then
- if #tempName < 3 then
- break
- else
- fileName = tempName:sub(1,#tempName-1)
- import(fileName)
- break
- end
- elseif e[1] == "key" and e[2] == keys.backspace and #tempName > 2 then
- tempName = tempName:sub(1,#tempName-3).."] "
- elseif e[1] == "char" then
- tempName = tempName:sub(1,#tempName-2)..e[2].."] "
- end
- end
- end
- end
- function handleEnter()
- local lastLine = cursor.y
- if text[cursor.y+1] then
- for i=#text+1,cursor.y+1,-1 do --if there are lines below cursor.y
- text[i] = text[i-1] -- copy every line to one below (reverse order)
- end
- end
- text[cursor.y+1] = ""
- if cursor.x <= #text[cursor.y] then
- text[cursor.y+1] = text[cursor.y]:sub(cursor.x,#text[cursor.y]) -- copy text from cursor.x to end of line to next line
- end
- cursor.y = cursor.y + 1
- if cursor.y > screen.maxY then
- screen.maxY = screen.maxY + 1
- screen.minY = screen.minY + 1
- term.clear()
- end
- screen.maxX = MaxX
- screen.minX = 1
- cursor.x = 1
- if not menu then
- term.setTextColor(DefaultTextColor)
- term.setBackgroundColor(DefaultBackgroundColor)
- if codeMode then
- term.setCursorPos(1,lastLine+1-screen.minY)
- term.setTextColor(DefaultTextColor)
- term.clearLine()
- write(text[lastLine]:sub(screen.minX,screen.maxX))
- codeColorIn(lastLine+1-screen.minY)
- else
- term.setCursorPos(1,lastLine+1-screen.minY)
- term.setTextColor(DefaultTextColor)
- term.clearLine()
- write(text[lastLine]:sub(screen.minX,screen.maxX))
- end
- end
- end
- function handleChar()
- text[cursor.y] = text[cursor.y]:sub(1,cursor.x-1)..e[2]..text[cursor.y]:sub(cursor.x,#text[cursor.y]) --put char at x,y
- cursor.x = cursor.x + 1
- if cursor.y-1+screen.minY == MaxY and cursor.x-1+screen.minX > MaxX-11 then
- screen.maxX = screen.maxX + 1
- screen.minX = screen.minX + 1
- elseif cursor.x > screen.maxX then
- screen.maxX = screen.maxX + 1
- screen.minX = screen.minX + 1
- end
- end
- function handleMouse()
- if e[1] == "mouse_click" or e[1] == "mouse_drag" then
- if #text > e[4]-2+screen.minY then
- cursor.y = e[4]-1+screen.minY
- if #text[e[4]-1+screen.minY] > e[3] - 2 then
- cursor.x = e[3]-1+screen.minX
- else
- cursor.x = #text[e[4]-1+screen.minY]+1
- end
- else
- cursor.y = #text
- end
- elseif e[1] == "mouse_scroll" then
- if e[2] == 1 then
- if #text > screen.minY then
- screen.minY = screen.minY + 1
- screen.maxY = screen.maxY + 1
- if cursor.y < screen.minY then
- cursor.y = cursor.y + 1
- if cursor.x > #text[cursor.y] then
- cursor.x = #text[cursor.y]+1
- end
- end
- end
- elseif e[2] == -1 then
- if screen.minY > 1 then
- screen.maxY = screen.maxY - 1
- screen.minY = screen.minY - 1
- if cursor.y > screen.maxY then
- cursor.y = cursor.y -1
- if #text[cursor.y] < cursor.x then
- cursor.x = #text[cursor.y]+1
- end
- end
- end
- end
- end
- end
- function handleMovementKeys()
- if e[2] == keys.up then -- 1 of 4 movement keys
- if cursor.y > 1 then -- is cursor further down than line 1
- cursor.y = cursor.y - 1
- if text[cursor.y]:sub(cursor.x-1,cursor.x-1) == "" then -- is line above (current) as long as cursor.x
- cursor.x = #text[cursor.y]+1 -- place cursor at end of line (default is same x as before)
- end
- elseif cursor.x > 1 then -- if on first line
- cursor.x = 1
- end
- elseif e[2] == keys.down then -- similar to keys.up
- if #text > cursor.y then
- cursor.y = cursor.y + 1
- if #text[cursor.y] < cursor.x then
- cursor.x = #text[cursor.y]+1
- end
- else
- cursor.x = #text[cursor.y]+1
- end
- elseif e[2] == keys.left then
- if cursor.x > 1 then -- is cursor farther right than x = 1
- cursor.x = cursor.x - 1
- elseif cursor.y > 1 then --does the line above exist?
- cursor.y = cursor.y - 1
- cursor.x = #text[cursor.y]+1
- end
- elseif e[2] == keys.right then
- if #text[cursor.y] >= cursor.x then
- cursor.x = cursor.x + 1
- elseif #text > cursor.y then
- cursor.y = cursor.y + 1
- cursor.x = 1
- end
- elseif e[2] == keys.home then
- cursor.x = 1
- elseif e[2] == keys["end"] then
- cursor.x = #text[cursor.y]+1
- elseif e[2] == keys.pageUp then
- if text[cursor.y-MaxY+1] then
- cursor.y = cursor.y-MaxY+1
- if text[cursor.y]:sub(cursor.x-1,cursor.x-1) == "" then
- cursor.x = #text[cursor.y]
- end
- elseif cursor.y > 1 then
- cursor.y = 1
- if text[cursor.y]:sub(cursor.x-1,cursor.x-1) == "" then
- cursor.x = #text[cursor.y]
- end
- end
- end
- if cursor.x == 0 then
- cursor.x = 1
- end
- end
- function handleBackspace()
- if cursor.x > 1 then --is cursor in text
- text[cursor.y] = text[cursor.y]:sub(1,cursor.x-2)..text[cursor.y]:sub(cursor.x,#text[cursor.y]) --remove char in text
- cursor.x = cursor.x - 1
- elseif cursor.x == 1 and cursor.y > 1 then -- is cursor at start of line and not at line 1
- cursor.x = #text[cursor.y-1]+1 -- get length of above line
- text[cursor.y-1] = text[cursor.y-1]..text[cursor.y] -- copy line to line above
- text[cursor.y] = text[cursor.y+1]
- if text[cursor.y+2] then -- move all lines below one step up
- for i=cursor.y+1,#text-1 do -- from cursor.y to end of file
- text[i] = text[i+1] -- copy line below i to i
- end
- text[#text] = nil -- delete last line (copied)
- end
- cursor.y = cursor.y-1 -- move cursor up
- end
- end
- function handleDelete()
- if text[cursor.y]:sub(cursor.x,cursor.x) ~= "" then
- text[cursor.y] = text[cursor.y]:sub(1,cursor.x-1)..text[cursor.y]:sub(cursor.x+1,#text[cursor.y])
- elseif cursor.x > #text[cursor.y] and text[cursor.y+1] then
- text[cursor.y] = text[cursor.y]..text[cursor.y+1]
- for i=cursor.y+1,#text do -- from cursor.y to end of file
- text[i]=text[i+1] -- copy line below i to i
- end
- text[#text] = nil -- delete last line (copied)
- end
- end
- function handleTimer()
- if isOnScreenCursor then
- isOnScreenCursor = false
- if text[cursor.y]:sub(cursor.x,cursor.x) ~= "" then
- cursorString = text[cursor.y]:sub(cursor.x,cursor.x)
- else
- cursorString = " "
- end
- cursorColor = DefaultTextColor
- else
- isOnScreenCursor = true
- cursorString = settings.cursorString
- settings.cursorColor = colors.blue
- end
- cursorTimer = os.startTimer(0.05)
- end
- function handleScreen()
- while cursor.x < screen.minX do
- screen.minX = screen.minX - 1
- screen.maxX = screen.maxX - 1
- end
- while cursor.x > screen.maxX do
- screen.maxX = screen.maxX + 1
- screen.minX = screen.minX + 1
- end
- while cursor.y < screen.minY do
- screen.minY = screen.minY - 1
- screen.maxY = screen.maxY - 1
- end
- while cursor.y > screen.maxY do
- screen.maxY = screen.maxY + 1
- screen.minY = screen.minY + 1
- end
- while cursor.x-screen.minX+1 > MaxX-9 and cursor.y == screen.maxY do
- screen.minX = screen.minX + 1
- screen.maxX = screen.maxX + 1
- end
- if screen.minX < 1 or screen.minY < 1 then -- baaaad program! >=c How doe? idk.
- term.clear()
- term.setCursorPos(1,1)
- write("ERROR: screen params incorrect\nPlease report this error.\nWait 10 seconds\n"..textutils.serialize(screen)..textutils.serialize(cursor))
- sleep(10)
- screen.minX = 1
- screen.minY = 1
- screen.maxX = MaxX
- screen.maxY = MaxY
- end
- end
- local allowedAdj = {
- [""] = true,
- [" "] = true,
- ["."] = true,
- [":"] = true,
- ["("] = true,
- ["["] = true,
- ["{"] = true,
- ["="] = true,
- ["<"] = true,
- [">"] = true,
- ["*"] = true,
- ["/"] = true,
- ["+"] = true,
- ["-"] = true
- }
- function codeColorIn(n)
- if #text[n-1+screen.minY] > 0 then
- for i=1,#text[n-1+screen.minY] do
- --[[if text[n]:sub(i,i) == "'" then
- term.setCursorPos(i+1-screen.minX,n+1-screen.minY)
- term.setTextColor(KEYWORD.___LightTextStringColor)
- local endstring = i + 1
- local startstring = i
- while i <= #text[n] do
- if text[n]:sub(i,i) == "'" then
- endstring = endstring + 1
- break
- end
- i = i + 1
- endstring = i
- end
- term.setCursorPos(startstring+1-screen.minX,n+1-screen.minY)
- write(text[n]:sub(startstring,endstring))
- end]] --NYI
- for k,v in pairs(SYNTAX) do
- if text[n-1+screen.minY]:sub(i,i) == k then
- term.setCursorPos(i+1-screen.minX,n)
- term.setTextColor(v)
- write(k)
- end
- end
- for k,v in pairs(KEYWORD) do
- if allowedAdj[text[n-1+screen.minY]:sub(i-1,i-1)] and allowedAdj[text[n-1+screen.minY]:sub(i+#k,i+#k)] and text[n-1+screen.minY]:sub(i,i+#k-1) == k then
- term.setCursorPos(i+1-screen.minX,n)
- term.setTextColor(v)
- write(k:sub(1,math.min(#k+1,MaxX-i)))
- i = i+#k
- end
- end
- if text[n-1+screen.minY]:sub(i,i+1) == "--" then
- term.setTextColor(KEYWORD["___LightTextCommentColor"])
- term.setCursorPos(i+1-screen.minX,n)
- write(text[n-1+screen.minY]:sub(i,math.min(MaxX,#text[n-1+screen.minY]+screen.minX-1)))
- break
- end
- end
- end
- end
- while true do -- main loop
- local lastLine = cursor.y
- if not menu then
- term.setCursorPos(1,cursor.y+1-screen.minY)
- term.setTextColor(DefaultTextColor)
- term.clearLine()
- write(text[cursor.y]:sub(screen.minX,screen.maxX))
- codeColorIn(cursor.y+1-screen.minY)
- term.setTextColor(colors.gray)
- term.setCursorPos(MaxX-9,MaxY)
- write("Press ctrl")
- end
- if not menu and isOnScreenCursor then
- term.setCursorPos(cursor.x+1-screen.minX,cursor.y+1-screen.minY)
- if #cursorString ~= 1 then cursorString = " " end
- term.setBackgroundColor(DefaultBackgroundColor)
- term.setTextColor(settings.cursorColor)
- write(cursorString)
- end
- e = {os.pullEventRaw()}
- if e[1] == "term_resize" then
- MaxX,MaxY = term.getSize()
- elseif e[1] == "terminate" then
- save("TEMP")
- term.setCursorPos(1,1)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- error("",999)
- elseif e[1] == "timer" and not menu then
- handleTimer()
- elseif e[1] == "char" and not menu then
- handleChar()
- elseif e[1] == "mouse_click" or e[1] == "mouse_scroll" or e[1] == "mouse_drag" then
- if not menu then
- handleMouse()
- elseif e[1] == "mouse_click" then
- handleMouseMenu()
- end
- elseif e[1] == "key" then
- if not menu and e[2] == keys.up or e[2] == keys.down or e[2] == keys.left or e[2] == keys.right or e[2] == keys.pgUp or e[2] == keys.pgDn or e[2] == keys.home or e[2] == keys["end"] then
- handleMovementKeys()
- elseif not menu and e[2] == keys.enter then
- handleEnter()
- elseif not menu and e[2] == keys.backspace then
- handleBackspace()
- elseif not menu and e[2] == keys.delete then
- handleDelete()
- elseif not menu and e[2] == keys.f1 then
- save(fileName)
- elseif not menu and e[2] == keys.tab then
- text[cursor.y] = text[cursor.y]:sub(1,cursor.x-1)..string.rep(" ",tabSize)..text[cursor.x]:sub(cursor.x,#text[cursor.y]) --put char at x,y
- cursor.x = cursor.x + tabSize
- elseif e[2] == keys.rightCtrl then
- if menu then
- menu = false
- term.setBackgroundColor(colors.black)
- term.clear()
- cursorTimer = os.startTimer(0.3)
- if lastText and #lastText > 0 then
- for i = 1,16384 do
- lastText[i] = nil
- end
- end
- else
- menu = true
- term.clear()
- end
- end
- elseif e[1] == "something else idk" then
- end
- handleScreen()
- if not menu then
- term.setTextColor(DefaultTextColor)
- term.setBackgroundColor(DefaultBackgroundColor)
- for i=1,MaxY do
- if lastText[i-1+screen.minY] ~= text[i-1+screen.minY] or i == lastLine+1-screen.minY or e[1] == "mouse_scroll" or e[2] == keys.up or e[2] == keys.down or e[2] == keys.enter then
- term.setCursorPos(1,i)
- term.setTextColor(DefaultTextColor)
- term.clearLine()
- write(text[i-1+screen.minY]:sub(screen.minX,screen.maxX))
- if codeMode then
- codeColorIn(i)
- end
- end
- lastText[i-1+screen.minY] = text[i-1+screen.minY]
- end
- term.setBackgroundColor(DefaultBackgroundColor)
- term.setCursorPos(MaxX-9,MaxY)
- term.setTextColor(colors.gray)
- write("Press ctrl")
- term.setTextColor(DefaultTextColor)
- elseif menu then
- term.setBackgroundColor(colors.gray)
- term.setTextColor(colors.blue)
- term.clear()
- term.setCursorPos(math.max(1,math.floor(MaxX/2-(#fileName/2)-5)),1)
- write(string.sub("LightText "..fileName,1,MaxX))
- term.setCursorPos(1,3)
- write("Code Mode:")
- term.setCursorPos(15,3)
- if codeMode then
- term.blit(" X","8f","85")
- else
- term.blit("X ","f8","e8")
- end
- term.setCursorPos(1,8)
- write("[Exit]")
- term.setCursorPos(1,5)
- write("[Save] Press f1")
- term.setCursorPos(1,6)
- write("[Save as:"..fileName.."]")
- term.setCursorPos(1,7)
- write("[Open:]")
- term.setCursorPos(MaxX-9,MaxY)
- write("Press ctrl")
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement