cbf25999f0
COMING IN THE FULL RELEASE: - A user system - A functional IPC (Inter-Process Communication) system THINGS CAN AND WILL CHANGE FROM NOW UNTIL THE FINAL RELEASE.
352 lines
11 KiB
Lua
352 lines
11 KiB
Lua
local file = ...
|
|
local fs = require("filesystem")
|
|
local event = require("event")
|
|
local component = require("component")
|
|
local unicode = require("unicode")
|
|
local gpu = component.gpu
|
|
local width, height = gpu.getResolution()
|
|
local scrollPosX, scrollPosY = 1, 1
|
|
local cursorPosX, cursorPosY = 1, 1
|
|
local cursorWhite = true
|
|
local changesMade = false
|
|
local renderBuffer = gpu.allocateBuffer()
|
|
local scrollSpeed = 5
|
|
local tab = " "
|
|
--local ocelot = component.ocelot
|
|
|
|
local function rawset(x, y, text)
|
|
termlib.cursorPosX = x
|
|
termlib.cursorPosY = y
|
|
termlib.write(text, false)
|
|
end
|
|
|
|
local filestring, filepath, handle, data, tmpdata
|
|
if file then
|
|
if file:sub(1, 1) == "/" then
|
|
filepath = file
|
|
else
|
|
filepath = shell.workingDirectory .. file
|
|
end
|
|
handle, data, tmpdata = fs.open(filepath, "r"), "", nil
|
|
if fs.exists(filepath) then
|
|
filestring = filepath
|
|
repeat
|
|
tmpdata = handle:read(math.huge)
|
|
data = data .. (tmpdata or "")
|
|
until not tmpdata
|
|
tmpdata = {}
|
|
if data:gmatch("(.-)\n")() then
|
|
for line in data:gmatch("(.-)\n") do
|
|
local newLine = line:gsub("\r", "") -- this took me SO LONG TO FIGURE OUT AAAAAAAA I HATE CRLF I HATE CRLF I HATE CRLF
|
|
table.insert(tmpdata, newLine)
|
|
end
|
|
else
|
|
tmpdata = {data}
|
|
end
|
|
else
|
|
filepath = shell.workingDirectory .. file
|
|
filestring = "[NEW FILE]"
|
|
tmpdata = {""}
|
|
end
|
|
else
|
|
filepath = ""
|
|
filestring = "[NEW FILE]"
|
|
tmpdata = {""}
|
|
end
|
|
local function render()
|
|
gpu.setActiveBuffer(renderBuffer)
|
|
clear()
|
|
--ocelot.log(tostring(scrollPosY))
|
|
local realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
|
|
if realCursorX < 1 then
|
|
scrollPosX = scrollPosX + realCursorX - 1
|
|
cursorPosX = 1
|
|
realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
|
|
end
|
|
for i = scrollPosY, height + scrollPosY - 3 do
|
|
gpu.set(1, i - scrollPosY + 1, (tmpdata[i] or ""):sub(scrollPosX))
|
|
end
|
|
rawset(1, height - 1, "\27[107m\27[30m" .. filestring .. string.rep(" ", width))
|
|
rawset(1, height, "\27[107m\27[30m^X\27[0m Exit \27[107m\27[30m^S\27[0m Save" .. string.rep(" ", width))
|
|
local char = gpu.get(realCursorX, cursorPosY)
|
|
if cursorWhite then
|
|
gpu.setForeground(0)
|
|
gpu.setBackground(0xFFFFFF)
|
|
end
|
|
gpu.set(realCursorX, cursorPosY, char)
|
|
gpu.bitblt()
|
|
gpu.setActiveBuffer(0)
|
|
end
|
|
|
|
local renderFlag, cursorRenderFlag = false, false
|
|
|
|
local function scrollUp()
|
|
cursorPosY = cursorPosY - 1
|
|
cursorRenderFlag = true
|
|
cursorWhite = true
|
|
if cursorPosY < 1 then
|
|
renderFlag = true
|
|
scrollPosY = scrollPosY - 1
|
|
cursorPosY = 1
|
|
end
|
|
if scrollPosY < 1 then
|
|
renderFlag = false
|
|
scrollPosY = 1
|
|
end
|
|
if math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2) < 1 then
|
|
renderFlag = true
|
|
end
|
|
end
|
|
|
|
local function scrollDown()
|
|
cursorPosY = cursorPosY + 1
|
|
cursorRenderFlag = true
|
|
cursorWhite = true
|
|
if cursorPosY + scrollPosY - 1 > #tmpdata then
|
|
renderFlag = false
|
|
cursorPosY = #tmpdata - scrollPosY + 1
|
|
end
|
|
if cursorPosY > height - 2 then
|
|
renderFlag = true
|
|
scrollPosY = scrollPosY + 1
|
|
cursorPosY = height - 2
|
|
end
|
|
if math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2) < 1 then
|
|
renderFlag = true
|
|
end
|
|
end
|
|
|
|
local function scrollLeft()
|
|
cursorRenderFlag = true
|
|
cursorWhite = true
|
|
if cursorPosX > 1 then
|
|
if cursorPosX <= unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2 then
|
|
cursorPosX = cursorPosX - 1
|
|
elseif unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 1 > 1 then
|
|
cursorPosX = unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 1
|
|
end
|
|
elseif scrollPosX > 1 then
|
|
scrollPosX = scrollPosX - 1
|
|
renderFlag = true
|
|
end
|
|
if math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2) < 1 then
|
|
renderFlag = true
|
|
end
|
|
end
|
|
|
|
local function scrollRight()
|
|
cursorRenderFlag = true
|
|
cursorWhite = true
|
|
if cursorPosX <= unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 1 then
|
|
cursorPosX = cursorPosX + 1
|
|
end
|
|
if cursorPosX > width then
|
|
cursorPosX = width
|
|
scrollPosX = scrollPosX + 1
|
|
renderFlag = true
|
|
end
|
|
end
|
|
|
|
local function processEvent(args)
|
|
renderFlag, cursorRenderFlag = false, false
|
|
if args[1] == "key_down" then
|
|
local keycode = args[4]
|
|
local key = keyboard.keys[keycode]
|
|
if keyboard.ctrlDown then
|
|
return false, false, key
|
|
end
|
|
if key == "down" and cursorPosY < #tmpdata then
|
|
scrollDown()
|
|
end
|
|
if key == "up" then
|
|
scrollUp()
|
|
end
|
|
if key == "left" then
|
|
scrollLeft()
|
|
end
|
|
if key == "right" then
|
|
scrollRight()
|
|
end
|
|
if key == "enter" then
|
|
changesMade = true
|
|
renderFlag = true
|
|
cursorWhite = true
|
|
table.insert(tmpdata, cursorPosY + 1, tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX))
|
|
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX - 1)
|
|
cursorPosX = 1
|
|
cursorPosY = cursorPosY + 1
|
|
scrollPosX = 1
|
|
if cursorPosY > height - 2 then
|
|
scrollPosY = scrollPosY + 1
|
|
cursorPosY = height - 2
|
|
end
|
|
end
|
|
if key == "back" then
|
|
changesMade = true
|
|
cursorRenderFlag = true
|
|
cursorWhite = true
|
|
if cursorPosX == 1 and cursorPosY + scrollPosY - 1 > 1 then
|
|
cursorPosY = cursorPosY - 1
|
|
if cursorPosY < 1 then
|
|
scrollPosY = scrollPosY - 1
|
|
cursorPosY = 1
|
|
end
|
|
if scrollPosY < 1 then
|
|
scrollPosY = 1
|
|
end
|
|
cursorPosX = unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2
|
|
if cursorPosX > width then
|
|
scrollPosX = cursorPosX - width + 1
|
|
cursorPosX = width
|
|
end
|
|
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1] .. tmpdata[cursorPosY + 1]
|
|
table.remove(tmpdata, cursorPosY + 1)
|
|
renderFlag = true
|
|
else
|
|
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX + scrollPosX - 3) .. tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX + scrollPosX - 1)
|
|
cursorPosX = math.min(cursorPosX - 1, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) + 1)
|
|
if cursorPosX < 1 then
|
|
cursorPosX = 1
|
|
scrollPosX = scrollPosX - 1
|
|
renderFlag = true
|
|
else
|
|
gpu.set(1, cursorPosY, tmpdata[cursorPosY + scrollPosY - 1]:sub(scrollPosX) .. " ")
|
|
end
|
|
end
|
|
end
|
|
if key == "tab" then
|
|
changesMade = true
|
|
cursorRenderFlag = true
|
|
cursorWhite = true
|
|
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX + scrollPosX - 2) .. tab .. tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX + scrollPosX - 1)
|
|
cursorPosX = cursorPosX + unicode.wlen(tab)
|
|
if cursorPosX > width then
|
|
scrollPosX = scrollPosX + cursorPosX - width
|
|
cursorPosX = width
|
|
renderFlag = true
|
|
else
|
|
gpu.set(1, cursorPosY, tmpdata[cursorPosY + scrollPosY - 1]:sub(scrollPosX))
|
|
end
|
|
end
|
|
if args[3] >= 32 and args[3] <= 126 then
|
|
changesMade = true
|
|
cursorRenderFlag = true
|
|
cursorWhite = true
|
|
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX + scrollPosX - 2) .. unicode.char(args[3]) .. tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX + scrollPosX - 1)
|
|
cursorPosX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1])) + 1
|
|
--ocelot.log(tostring(cursorPosX))
|
|
if cursorPosX > width then
|
|
cursorPosX = width
|
|
scrollPosX = scrollPosX + 1
|
|
renderFlag = true
|
|
else
|
|
gpu.set(1, cursorPosY, tmpdata[cursorPosY + scrollPosY - 1]:sub(scrollPosX))
|
|
end
|
|
end
|
|
elseif args[1] == "scroll" then
|
|
if args[5] == 1 then
|
|
for i = 1, scrollSpeed do
|
|
scrollUp()
|
|
end
|
|
elseif args[5] == -1 and cursorPosY < #tmpdata then
|
|
for i = 1, scrollSpeed do
|
|
scrollDown()
|
|
end
|
|
end
|
|
end
|
|
return renderFlag, cursorRenderFlag
|
|
end
|
|
|
|
local function save()
|
|
gpu.setBackground(0xFFFFFF)
|
|
gpu.setForeground(0)
|
|
gpu.set(1, height - 1, string.rep(" ", width))
|
|
termlib.cursorPosX = 1
|
|
termlib.cursorPosY = height - 1
|
|
local savepath = read(nil, "\27[107m\27[30mSave location: ", filepath)
|
|
gpu.setBackground(0xFFFFFF)
|
|
gpu.setForeground(0)
|
|
if fs.exists(savepath) then
|
|
gpu.set(1, height - 1, string.rep(" ", width))
|
|
local answer = read(nil, "\27[107m\27[30mFile already exists. Overwrite it? [Y/n] ")
|
|
if answer:lower() == "n" then
|
|
gpu.setBackground(0xFFFFFF)
|
|
gpu.setForeground(0)
|
|
gpu.set(1, height - 1, filestring .. string.rep(" ", width))
|
|
return
|
|
end
|
|
end
|
|
local handle, errorMessage = fs.open(savepath, "w")
|
|
if handle then
|
|
if table.concat(tmpdata, "\n"):sub(-1, -1) == "\n" then
|
|
handle:write(table.concat(tmpdata, "\n"))
|
|
else
|
|
handle:write(table.concat(tmpdata, "\n") .. "\n") -- add a newline at the end to follow POSIX standards
|
|
end
|
|
handle:close()
|
|
gpu.set(1, height - 1, filestring .. string.rep(" ", width))
|
|
else
|
|
gpu.set(1, height - 1, "ERROR: " .. errorMessage:gsub("\n", "") .. string.rep(" ", width))
|
|
end
|
|
changesMade = false
|
|
end
|
|
|
|
render()
|
|
while true do
|
|
local args = {event.pull(0.5)}
|
|
local renderFlag, cursorRenderFlag, specialKey = false, false, nil
|
|
local previousCursorX, previousCursorY = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2), cursorPosY
|
|
if args and args[1] then
|
|
cursorWhite = true
|
|
renderFlag, cursorRenderFlag, specialKey = processEvent(args)
|
|
if specialKey == "x" then
|
|
if changesMade then
|
|
termlib.cursorPosX = 1
|
|
termlib.cursorPosY = height - 1
|
|
local response = read(nil, "\27[107m\27[30mWould you like to save changes? [Y/n] ")
|
|
if response:lower() ~= "n" then
|
|
save()
|
|
end
|
|
end
|
|
gpu.freeAllBuffers()
|
|
clear()
|
|
return
|
|
end
|
|
if specialKey == "s" then
|
|
save()
|
|
end
|
|
repeat
|
|
args = {event.pull("key_down", 0)}
|
|
if args and args[1] then
|
|
processEvent(args)
|
|
end
|
|
until not args or not args[1]
|
|
else
|
|
cursorWhite = not cursorWhite
|
|
cursorRenderFlag = true
|
|
end
|
|
if cursorRenderFlag then
|
|
local char = gpu.get(previousCursorX, previousCursorY)
|
|
gpu.set(previousCursorX, previousCursorY, char)
|
|
local realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
|
|
if realCursorX < 1 then
|
|
scrollPosX = scrollPosX + realCursorX - 1
|
|
cursorPosX = 1
|
|
realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
|
|
end
|
|
local char = gpu.get(realCursorX, cursorPosY)
|
|
if cursorWhite then
|
|
gpu.setBackground(0xFFFFFF)
|
|
gpu.setForeground(0)
|
|
end
|
|
gpu.set(realCursorX, cursorPosY, char)
|
|
if cursorWhite then
|
|
gpu.setForeground(0xFFFFFF)
|
|
gpu.setBackground(0)
|
|
end
|
|
end
|
|
if renderFlag then
|
|
render()
|
|
end
|
|
end
|