Can input filename after starting, fixed bugs

Trying to tab-indent could crash if the selection went past the final line.
Also, pressing ENTER will actually delete your selections now. Oops.
Some micro-optimizations were also added.
This commit is contained in:
LDDestroier 2019-03-29 14:35:42 -04:00 committed by GitHub
parent f87b818877
commit 7869eee78f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 440 additions and 430 deletions

158
eldit.lua
View File

@ -11,6 +11,7 @@ local argData = {
local eldit, config = {}, {}
eldit.buffer = {{}} -- stores all text, organized like eldit.buffer[yPos][xPos]
eldit.undoBuffer = {{{}}} -- stores buffers for undoing/redoing
eldit.allowUndo = true -- whether or not to allow undoing/redoing
eldit.maxUndo = 16 -- maximum size of the undo buffer
eldit.undoPos = 1 -- current position in undo buffer
eldit.undoDelay = 0.5 -- amount of time to wait after typing, before the buffer is put in the undo buffer
@ -161,18 +162,12 @@ deepCopy = function(tbl)
return output
end
local getLineNoLen = function()
if config.showLineNumberIndicator then
return #tostring(#eldit.buffer)
else
return 0
end
end
prompt = function(prebuffer, precy, _eldit)
prompt = function(prebuffer, precy, maxY, _eldit)
term.setCursorBlink(false)
local keysDown = {} -- list of all keys being pressed
local miceDown = {} -- list of all mouse buttons being pressed
eldit = _eldit or eldit -- you can replace the "eldit" table if you want I guess
maxY = maxY or math.huge -- limits amount of lines
local defaultBarLife = 10 -- default amount of time bar msg will stay onscreen
local barmsg = "Started Eldit." -- message displayed on bottom screen
local barlife = defaultBarLife
@ -197,6 +192,15 @@ prompt = function(prebuffer, precy, _eldit)
local isCursorBlink = false -- blinks the background color on each cursor
local isInsert = false -- will overwrite characters instead of appending them
-- gets length of left line numbers, if enabled at all
local getLineNoLen = function()
if config.showLineNumberIndicator then
return #tostring(#eldit.buffer)
else
return 0
end
end
-- list of all characters that will stop a CTRL+Backspace or CTRL+Delete or CTRL+Left/Right
local interruptable = {
[" "] = true,
@ -269,14 +273,17 @@ prompt = function(prebuffer, precy, _eldit)
end
end
-- the big boi function, draws **EVERYTHING**
local render = function()
local cx, cy
-- all characters that count as whitespace
local tab = {
[" "] = true,
["\9"] = true
}
-- the big boi function, draws **EVERYTHING**
local render = function()
local cx, cy
local lineNoLen = getLineNoLen()
local isHighlighted = false
local textPoses = {math.huge, -math.huge} -- used to identify space characters without text
local screen = {{},{},{}}
for y = 1, eldit.size.height - 1 do -- minus one because it reserves space for the bar
@ -286,20 +293,13 @@ prompt = function(prebuffer, precy, _eldit)
cy = y + eldit.scrollY
-- find text
if eldit.buffer[cy] and (config.showWhitespace or config.showTrailingSpace) then
for x = 1, #eldit.buffer[cy] do
if (not tab[eldit.buffer[cy][x]]) and eldit.buffer[cy][x] then
textPoses[1] = x
break
textPoses = {
#(concatTable(eldit.buffer[cy]):match("^ +") or "") + 1,
#eldit.buffer[cy] - #(concatTable(eldit.buffer[y]):match(" +$") or "")
}
end
end
for x = #eldit.buffer[cy], 1, -1 do
if (not tab[eldit.buffer[cy][x]]) and eldit.buffer[cy][x] then
textPoses[2] = x
break
end
end
end
local isHighlighted = false
if cy <= #eldit.buffer and lineNoLen > 0 then
isHighlighted = false
for id,cur in pairs(eldit.cursors) do
if cy == cur.y then
isHighlighted = true
@ -314,8 +314,6 @@ prompt = function(prebuffer, precy, _eldit)
end
end
end
term.setCursorPos(eldit.size.x, eldit.size.y + y - 1)
if cy <= #eldit.buffer and lineNoLen > 0 then
if isHighlighted then
term.setBackgroundColor(colors.gray)
term.setTextColor(colors.white)
@ -323,24 +321,17 @@ prompt = function(prebuffer, precy, _eldit)
term.setBackgroundColor(colors.black)
term.setTextColor(colors.lightGray)
end
term.setCursorPos(eldit.size.x, eldit.size.y + y - 1)
term.write(cy .. (" "):rep(lineNoLen - #tostring(y)))
else
term.write(" ")
end
-- actually draw text
local cChar, cTxt, cBg = " ", " ", " "
term.setCursorPos(eldit.size.x + lineNoLen + 0, eldit.size.y + y - 1)
term.setCursorPos(eldit.size.x + lineNoLen, eldit.size.y + y - 1)
for x = lineNoLen + 1, eldit.size.width do
cx = x + eldit.scrollX - lineNoLen
if checkIfSelected(cx, cy) then
cBg = "b"
else
cBg = "f"
end
if checkIfCursor(cx, cy) and isCursorBlink then
if isInsert then
cTxt, cBg = "0", "f"
@ -348,6 +339,11 @@ prompt = function(prebuffer, precy, _eldit)
cTxt, cBg = "f", "8"
end
else
if checkIfSelected(cx, cy) then
cBg = "b"
else
cBg = "f"
end
cTxt = "0"
end
if config.showWhitespace or config.showTrailingSpace then
@ -378,13 +374,13 @@ prompt = function(prebuffer, precy, _eldit)
)
end
term.setCursorPos(eldit.size.x, eldit.size.y + eldit.size.height - 1)
term.setBackgroundColor(colors.gray)
term.setBackgroundColor(colors.black)
eClearLine()
if barlife > 0 then
term.setTextColor(colors.yellow)
term.write(barmsg)
else
term.setTextColor(colors.white)
term.setTextColor(colors.yellow)
for id,cur in pairs(eldit.cursors) do
term.write("(" .. cur.x .. "," .. cur.y .. ") ")
end
@ -409,12 +405,12 @@ prompt = function(prebuffer, precy, _eldit)
end
end
if lowCur.y - eldit.scrollY < 1 then
eldit.scrollY = highCur.y - 1
elseif highCur.y - eldit.scrollY > eldit.size.height - 1 then
eldit.scrollY = lowCur.y - eldit.size.height + 1
eldit.scrollY = -1 + highCur.y
elseif highCur.y - eldit.scrollY > -1 + eldit.size.height then
eldit.scrollY = 1 + lowCur.y - eldit.size.height
end
if leftCur.x - eldit.scrollX < 1 then
eldit.scrollX = rightCur.x - 1
eldit.scrollX = -1 + rightCur.x
elseif rightCur.x - eldit.scrollX > eldit.size.width - lineNoLen then
eldit.scrollX = leftCur.x - (eldit.size.width - lineNoLen)
end
@ -441,7 +437,7 @@ prompt = function(prebuffer, precy, _eldit)
),
math.max(
0,
#eldit.buffer - eldit.size.height + 1
1 + #eldit.buffer - eldit.size.height
)
)
end
@ -453,7 +449,7 @@ prompt = function(prebuffer, precy, _eldit)
),
math.max(
0,
getMaximumWidth() - eldit.size.width + 1 - lineNoLen
1 + getMaximumWidth() - eldit.size.width - lineNoLen
)
)
end
@ -585,8 +581,7 @@ prompt = function(prebuffer, precy, _eldit)
end
end
cur.x = cur.x + xmod
cur.y = cur.y + ymod
cur.y = math.max(1, math.min(cur.y, #eldit.buffer))
cur.y = math.max(1, math.min(cur.y + ymod, #eldit.buffer))
if xmod ~= 0 then
repeat
if cur.x < 1 and cur.y > 1 then
@ -598,11 +593,7 @@ prompt = function(prebuffer, precy, _eldit)
end
until (cur.x >= 1 and cur.x <= #eldit.buffer[cur.y] + 1) or ((cur.y == 1 and xmod < 0) or (cur.y == #eldit.buffer and xmod > 0))
end
if setLastX then
cur.lastX = cur.x
else
cur.x = cur.lastX
end
cur.lastX = setLastX and cur.x or cur.lastX
if cur.y < 1 then
cur.y = math.max(1, math.min(cur.y, #eldit.buffer))
cur.x = 1
@ -749,9 +740,27 @@ prompt = function(prebuffer, precy, _eldit)
compiled = compiled .. "\n"
end
end
if not eldit.filename then
local cx, cy
repeat
render()
term.setCursorPos(eldit.size.y, eldit.size.y + eldit.size.height - 1)
eClearLine()
term.setTextColor(colors.yellow)
term.write("Save as: ")
term.setTextColor(colors.white)
cx, cy = term.getCursorPos()
term.setCursorPos(cx, cy)
eldit.filename = read()
until (
(not fs.isDir(eldit.filename)) and
#eldit.filename:gsub(" ", "") > 0
)
end
writeFile(eldit.filename, compiled)
barmsg = "Saved to '" .. eldit.filename .. "'."
barlife = defaultBarLife
keysDown, miceDown = {}, {}
end
local evt
@ -790,6 +799,7 @@ prompt = function(prebuffer, precy, _eldit)
scrollToCursor()
while true do
evt = {os.pullEvent()}
repeat
if evt[1] == "timer" then
if evt[2] == tID then
if isCursorBlink then
@ -824,7 +834,7 @@ prompt = function(prebuffer, precy, _eldit)
end
elseif (evt[1] == "char" and not keysDown[keys.leftCtrl]) then
placeText(evt[2])
undotID = os.startTimer(eldit.undoDelay)
if eldit.allowUndo then undotID = os.startTimer(eldit.undoDelay) end
doRender = true
elseif evt[1] == "paste" then
if keysDown[keys.leftShift] then
@ -855,14 +865,14 @@ prompt = function(prebuffer, precy, _eldit)
end
end
barmsg = "Pasted from clipboard " .. eldit.selectedClipboard .. "."
undotID = os.startTimer(eldit.undoDelay)
if eldit.allowUndo then undotID = os.startTimer(eldit.undoDelay) end
else
barmsg = "Clipboard " .. eldit.selectedClipboard .. " is empty."
end
barlife = defaultBarLife
else
placeText(evt[2])
undotID = os.startTimer(eldit.undoDelay)
if eldit.allowUndo then undotID = os.startTimer(eldit.undoDelay) end
end
doRender = true
elseif evt[1] == "key" then
@ -895,7 +905,7 @@ prompt = function(prebuffer, precy, _eldit)
deleteSelections()
barmsg = "Cut to clipboard " .. eldit.selectedClipboard .. "."
barlife = defaultBarLife
undotID = os.startTimer(eldit.undoDelay)
if eldit.allowUndo then undotID = os.startTimer(eldit.undoDelay) end
else
barmsg = "Copied to clipboard " .. eldit.selectedClipboard .. "."
barlife = defaultBarLife
@ -930,7 +940,7 @@ prompt = function(prebuffer, precy, _eldit)
else
deleteText("word", "backward")
end
undotID = os.startTimer(eldit.undoDelay)
if eldit.allowUndo then undotID = os.startTimer(eldit.undoDelay) end
doRender, isCursorBlink = true, false
elseif evt[2] == keys.delete then
@ -939,7 +949,7 @@ prompt = function(prebuffer, precy, _eldit)
else
deleteText("word", "forward")
end
undotID = os.startTimer(eldit.undoDelay)
if eldit.allowUndo then undotID = os.startTimer(eldit.undoDelay) end
doRender, isCursorBlink = true, false
elseif evt[2] == keys.q then
@ -947,6 +957,9 @@ prompt = function(prebuffer, precy, _eldit)
elseif evt[2] == keys.s then
saveFile()
tID = os.startTimer(0.4)
bartID = os.startTimer(0.1)
doRender = true
elseif evt[2] == keys.a then
eldit.selections = {{
@ -991,14 +1004,14 @@ prompt = function(prebuffer, precy, _eldit)
elseif evt[2] == keys.up then
adjustCursor(0, -1, false, "flip")
doRender, isCursorBlink = true, true
undotID = os.startTimer(eldit.undoDelay)
if eldit.allowUndo then undotID = os.startTimer(eldit.undoDelay) end
eldit.undoBuffer[eldit.undoPos].selections = eldit.selections
eldit.undoBuffer[eldit.undoPos].cursors = eldit.cursors
elseif evt[2] == keys.down then
adjustCursor(0, 1, false, "flip")
doRender, isCursorBlink = true, true
undotID = os.startTimer(eldit.undoDelay)
if eldit.allowUndo then undotID = os.startTimer(eldit.undoDelay) end
eldit.undoBuffer[eldit.undoPos].selections = eldit.selections
eldit.undoBuffer[eldit.undoPos].cursors = eldit.cursors
@ -1024,7 +1037,7 @@ prompt = function(prebuffer, precy, _eldit)
end
end
end
else
elseif eldit.buffer[y] then
table.insert(eldit.buffer[y], 1, "\9")
for idd,cur in pairs(eldit.cursors) do
if cur.y == y and cur.x < #eldit.buffer[y] then
@ -1041,16 +1054,17 @@ prompt = function(prebuffer, precy, _eldit)
placeText("\9")
end
doRender = true
undotID = os.startTimer(eldit.undoDelay)
if eldit.allowUndo then undotID = os.startTimer(eldit.undoDelay) end
elseif evt[2] == keys.insert then
isInsert = not isInsert
doRender, isCursorBlink = true, true
elseif evt[2] == keys.enter then
deleteSelections()
makeNewLine()
doRender, isCursorBlink = true, false
undotID = os.startTimer(eldit.undoDelay)
if eldit.allowUndo then undotID = os.startTimer(eldit.undoDelay) end
elseif evt[2] == keys.home then
eldit.cursors = {{
@ -1063,9 +1077,9 @@ prompt = function(prebuffer, precy, _eldit)
elseif evt[2] == keys["end"] then
eldit.cursors = {{
x = #eldit.buffer[eldit.cursors[1].y] + 1,
x = 1 + #eldit.buffer[eldit.cursors[1].y],
y = eldit.cursors[1].y,
lastX = #eldit.buffer[eldit.cursors[1].y] + 1
lastX = 1 + #eldit.buffer[eldit.cursors[1].y]
}}
scrollToCursor()
doRender, isCursorBlink = true, true
@ -1085,7 +1099,7 @@ prompt = function(prebuffer, precy, _eldit)
deleteText("single", "backward")
end
doRender, isCursorBlink = true, false
undotID = os.startTimer(eldit.undoDelay)
if eldit.allowUndo then undotID = os.startTimer(eldit.undoDelay) end
elseif evt[2] == keys.delete then
if #eldit.selections > 0 then
@ -1094,7 +1108,7 @@ prompt = function(prebuffer, precy, _eldit)
deleteText("single", "forward")
end
doRender, isCursorBlink = true, false
undotID = os.startTimer(eldit.undoDelay)
if eldit.allowUndo then undotID = os.startTimer(eldit.undoDelay) end
elseif evt[2] == keys.left then
adjustCursor(-1, 0, true)
@ -1163,9 +1177,9 @@ prompt = function(prebuffer, precy, _eldit)
local adjEX, adjEY = evt[3] + eldit.scrollX, evt[4] + eldit.scrollY
local selID
if (lastMouse.ctrl and not isSelecting) or #eldit.selections == 0 then
selID = #eldit.selections + 1
selID = 1 + #eldit.selections
else
selID = #eldit.selections + 0
selID = #eldit.selections
end
eldit.selections[selID] = {
{
@ -1211,15 +1225,11 @@ prompt = function(prebuffer, precy, _eldit)
doRender = false
end
end
until true
end
end
if not eldit.filename then
print("eldit [filename]")
return
end
local contents = readFile(eldit.filename)
local contents = eldit.filename and readFile(eldit.filename) or nil
local result = {prompt(contents)}
if result[1] == "exit" then