mirror of
				https://github.com/LDDestroier/CC/
				synced 2025-10-30 15:03:01 +00:00 
			
		
		
		
	Added undo/redo
This commit is contained in:
		
							
								
								
									
										131
									
								
								eldit.lua
									
									
									
									
									
								
							
							
						
						
									
										131
									
								
								eldit.lua
									
									
									
									
									
								
							| @@ -10,6 +10,10 @@ local argData = { | |||||||
|  |  | ||||||
| local eldit = {} | local eldit = {} | ||||||
| eldit.buffer = {{}}			-- stores all text, organized like eldit.buffer[yPos][xPos] | eldit.buffer = {{}}			-- stores all text, organized like eldit.buffer[yPos][xPos] | ||||||
|  | eldit.undoBuffer = {{{}}}	-- stores buffers for 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 | ||||||
| eldit.clipboards = {}		-- all clipboard entries | eldit.clipboards = {}		-- all clipboard entries | ||||||
| eldit.selectedClipboard = 1	-- which clipboard to use | eldit.selectedClipboard = 1	-- which clipboard to use | ||||||
| eldit.scrollX = 0			-- horizontal scroll | eldit.scrollX = 0			-- horizontal scroll | ||||||
| @@ -136,6 +140,19 @@ local writeFile = function(path, contents) | |||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
|  | local deepCopy | ||||||
|  | deepCopy = function(tbl) | ||||||
|  | 	local output = {} | ||||||
|  | 	for k,v in pairs(tbl) do | ||||||
|  | 		if type(v) == "table" then | ||||||
|  | 			output[k] = deepCopy(v) | ||||||
|  | 		else | ||||||
|  | 			output[k] = v | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 	return output | ||||||
|  | end | ||||||
|  |  | ||||||
| prompt = function(prebuffer, precy, _eldit) | prompt = function(prebuffer, precy, _eldit) | ||||||
| 	local keysDown = {}					-- list of all keys being pressed | 	local keysDown = {}					-- list of all keys being pressed | ||||||
| 	local miceDown = {}					-- list of all mouse buttons being pressed | 	local miceDown = {}					-- list of all mouse buttons being pressed | ||||||
| @@ -156,6 +173,11 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 	elseif type(prebuffer) == "table" then | 	elseif type(prebuffer) == "table" then | ||||||
| 		eldit.buffer = prebuffer | 		eldit.buffer = prebuffer | ||||||
| 	end | 	end | ||||||
|  | 	eldit.undoBuffer[1] = { | ||||||
|  | 		buffer = deepCopy(eldit.buffer), | ||||||
|  | 		cursors = deepCopy(eldit.cursors), | ||||||
|  | 		selections = deepCopy(eldit.selections) | ||||||
|  | 	} | ||||||
| 	local isCursorBlink = false			-- blinks the background color on each cursor | 	local isCursorBlink = false			-- blinks the background color on each cursor | ||||||
| 	local isInsert = false				-- will overwrite characters instead of appending them | 	local isInsert = false				-- will overwrite characters instead of appending them | ||||||
|  |  | ||||||
| @@ -239,7 +261,7 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 			["\9"] = true | 			["\9"] = true | ||||||
| 		} | 		} | ||||||
| 		local lineNoLen = #tostring(#eldit.buffer) | 		local lineNoLen = #tostring(#eldit.buffer) | ||||||
| 		local textPoses = {math.huge, math.huge}		-- used to identify space characters without text | 		local textPoses = {math.huge, -math.huge}		-- used to identify space characters without text | ||||||
| 		for y = 1, eldit.size.height - 1 do -- minus one because it reserves space for the bar | 		for y = 1, eldit.size.height - 1 do -- minus one because it reserves space for the bar | ||||||
| 			cy = y + eldit.scrollY | 			cy = y + eldit.scrollY | ||||||
| 			-- find text | 			-- find text | ||||||
| @@ -665,6 +687,24 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
|  | 	local compareBuffers | ||||||
|  | 	compareBuffers = function(left, right) | ||||||
|  | 		for k,v in pairs(left) do | ||||||
|  | 			if type(v) == "table" then | ||||||
|  | 				if not compareBuffers(v, right[k]) then | ||||||
|  | 					return false | ||||||
|  | 				end | ||||||
|  | 			elseif right then | ||||||
|  | 				if left[k] ~= right[k] then | ||||||
|  | 					return false | ||||||
|  | 				end | ||||||
|  | 			else | ||||||
|  | 				return false | ||||||
|  | 			end | ||||||
|  | 		end | ||||||
|  | 		return true | ||||||
|  | 	end | ||||||
|  |  | ||||||
| 	-- saves to file, duhh | 	-- saves to file, duhh | ||||||
| 	local saveFile = function() | 	local saveFile = function() | ||||||
| 		local compiled = "" | 		local compiled = "" | ||||||
| @@ -682,6 +722,7 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 	local evt | 	local evt | ||||||
| 	local tID = os.startTimer(0.5)		-- timer for cursor blinking | 	local tID = os.startTimer(0.5)		-- timer for cursor blinking | ||||||
| 	local bartID = os.startTimer(0.1)	-- timer for bar message to go away | 	local bartID = os.startTimer(0.1)	-- timer for bar message to go away | ||||||
|  | 	local undotID						-- timer for when the buffer is put in the undo buffer | ||||||
| 	local doRender = true				-- if true, renders | 	local doRender = true				-- if true, renders | ||||||
|  |  | ||||||
| 	-- converts numerical key events to usable numbers | 	-- converts numerical key events to usable numbers | ||||||
| @@ -726,9 +767,29 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 			elseif evt[2] == bartID then | 			elseif evt[2] == bartID then | ||||||
| 				bartID = os.startTimer(0.1) | 				bartID = os.startTimer(0.1) | ||||||
| 				barlife = math.max(0, barlife - 1) | 				barlife = math.max(0, barlife - 1) | ||||||
|  | 			elseif evt[2] == undotID then | ||||||
|  | 				if not compareBuffers(eldit.buffer, eldit.undoBuffer[#eldit.undoBuffer].buffer or {}) then | ||||||
|  | 					if #eldit.undoBuffer >= eldit.maxUndo then | ||||||
|  | 						repeat | ||||||
|  | 							table.remove(eldit.undoBuffer, 1) | ||||||
|  | 						until #eldit.undoBuffer < eldit.maxUndo | ||||||
|  | 					end | ||||||
|  | 					if eldit.undoPos < #eldit.undoBuffer then | ||||||
|  | 						repeat | ||||||
|  | 							table.remove(eldit.undoBuffer, 0) | ||||||
|  | 						until eldit.undoPos == #eldit.undoBuffer | ||||||
|  | 					end | ||||||
|  | 					eldit.undoPos = math.min(eldit.undoPos + 1, eldit.maxUndo) | ||||||
|  | 					table.insert(eldit.undoBuffer, { | ||||||
|  | 						buffer = deepCopy(eldit.buffer), | ||||||
|  | 						cursors = deepCopy(eldit.cursors), | ||||||
|  | 						selections = deepCopy(eldit.selections), | ||||||
|  | 					}) | ||||||
|  | 				end | ||||||
| 			end | 			end | ||||||
| 		elseif (evt[1] == "char" and not keysDown[keys.leftCtrl]) then | 		elseif (evt[1] == "char" and not keysDown[keys.leftCtrl]) then | ||||||
| 			placeText(evt[2]) | 			placeText(evt[2]) | ||||||
|  | 			undotID = os.startTimer(eldit.undoDelay) | ||||||
| 			doRender = true | 			doRender = true | ||||||
| 		elseif evt[1] == "paste" then | 		elseif evt[1] == "paste" then | ||||||
| 			if keysDown[keys.leftShift] then | 			if keysDown[keys.leftShift] then | ||||||
| @@ -759,12 +820,14 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 						end | 						end | ||||||
| 					end | 					end | ||||||
| 					barmsg = "Pasted from clipboard " .. eldit.selectedClipboard .. "." | 					barmsg = "Pasted from clipboard " .. eldit.selectedClipboard .. "." | ||||||
|  | 					undotID = os.startTimer(eldit.undoDelay) | ||||||
| 				else | 				else | ||||||
| 					barmsg = "Clipboard " .. eldit.selectedClipboard .. " is empty." | 					barmsg = "Clipboard " .. eldit.selectedClipboard .. " is empty." | ||||||
| 				end | 				end | ||||||
| 				barlife = defaultBarLife | 				barlife = defaultBarLife | ||||||
| 			else | 			else | ||||||
| 				placeText(evt[2]) | 				placeText(evt[2]) | ||||||
|  | 				undotID = os.startTimer(eldit.undoDelay) | ||||||
| 			end | 			end | ||||||
| 			doRender = true | 			doRender = true | ||||||
| 		elseif evt[1] == "key" then | 		elseif evt[1] == "key" then | ||||||
| @@ -797,11 +860,27 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 								deleteSelections() | 								deleteSelections() | ||||||
| 								barmsg = "Cut to clipboard " .. eldit.selectedClipboard .. "." | 								barmsg = "Cut to clipboard " .. eldit.selectedClipboard .. "." | ||||||
| 								barlife = defaultBarLife | 								barlife = defaultBarLife | ||||||
|  | 								undotID = os.startTimer(eldit.undoDelay) | ||||||
| 							else | 							else | ||||||
| 								barmsg = "Copied to clipboard " .. eldit.selectedClipboard .. "." | 								barmsg = "Copied to clipboard " .. eldit.selectedClipboard .. "." | ||||||
| 								barlife = defaultBarLife | 								barlife = defaultBarLife | ||||||
| 							end | 							end | ||||||
| 						end | 						end | ||||||
|  |  | ||||||
|  | 					elseif evt[2] == keys.z then | ||||||
|  | 						if eldit.undoPos < #eldit.undoBuffer then | ||||||
|  | 							eldit.undoPos = math.min(#eldit.undoBuffer, eldit.maxUndo, eldit.undoPos + 1) | ||||||
|  | 							eldit.selections = deepCopy(eldit.undoBuffer[eldit.undoPos].selections) | ||||||
|  | 							eldit.cursors = deepCopy(eldit.undoBuffer[eldit.undoPos].cursors) | ||||||
|  | 							eldit.buffer = deepCopy(eldit.undoBuffer[eldit.undoPos].buffer) | ||||||
|  | 							adjustCursor(0, 0, true) | ||||||
|  | 							barmsg = "Redone. (" .. eldit.undoPos .. "/" .. #eldit.undoBuffer .. ")" | ||||||
|  | 							barlife = defaultBarLife | ||||||
|  | 						else | ||||||
|  | 							barmsg = "Reached top of undo buffer. (" .. eldit.undoPos .. "/" .. #eldit.undoBuffer .. ")" | ||||||
|  | 							barlife = defaultBarLife | ||||||
|  | 						end | ||||||
|  | 						doRender = true | ||||||
| 					end | 					end | ||||||
| 					-- In-editor pasting is done with the "paste" event! | 					-- In-editor pasting is done with the "paste" event! | ||||||
| 				else | 				else | ||||||
| @@ -809,12 +888,14 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 						eldit.selectedClipboard = numToKey[evt[2]] | 						eldit.selectedClipboard = numToKey[evt[2]] | ||||||
| 						barmsg = "Selected clipboard " .. eldit.selectedClipboard .. "." | 						barmsg = "Selected clipboard " .. eldit.selectedClipboard .. "." | ||||||
| 						barlife = defaultBarLife | 						barlife = defaultBarLife | ||||||
|  |  | ||||||
| 					elseif evt[2] == keys.backspace then | 					elseif evt[2] == keys.backspace then | ||||||
| 						if #eldit.selections > 0 then | 						if #eldit.selections > 0 then | ||||||
| 							deleteSelections() | 							deleteSelections() | ||||||
| 						else | 						else | ||||||
| 							deleteText("word", "backward") | 							deleteText("word", "backward") | ||||||
| 						end | 						end | ||||||
|  | 						undotID = os.startTimer(eldit.undoDelay) | ||||||
| 						doRender, isCursorBlink = true, false | 						doRender, isCursorBlink = true, false | ||||||
|  |  | ||||||
| 					elseif evt[2] == keys.delete then | 					elseif evt[2] == keys.delete then | ||||||
| @@ -823,6 +904,7 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 						else | 						else | ||||||
| 							deleteText("word", "forward") | 							deleteText("word", "forward") | ||||||
| 						end | 						end | ||||||
|  | 						undotID = os.startTimer(eldit.undoDelay) | ||||||
| 						doRender, isCursorBlink = true, false | 						doRender, isCursorBlink = true, false | ||||||
|  |  | ||||||
| 					elseif evt[2] == keys.q then | 					elseif evt[2] == keys.q then | ||||||
| @@ -843,21 +925,47 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 						}} | 						}} | ||||||
| 						doRender = true | 						doRender = true | ||||||
|  |  | ||||||
|  | 					elseif evt[2] == keys.z then | ||||||
|  |  | ||||||
|  | 						if eldit.undoPos > 1 then | ||||||
|  | 							eldit.undoPos = math.max(1, eldit.undoPos - 1) | ||||||
|  | 							eldit.selections = deepCopy(eldit.undoBuffer[eldit.undoPos].selections) | ||||||
|  | 							eldit.cursors = deepCopy(eldit.undoBuffer[eldit.undoPos].cursors) | ||||||
|  | 							eldit.buffer = deepCopy(eldit.undoBuffer[eldit.undoPos].buffer) | ||||||
|  | 							adjustCursor(0, 0, true) | ||||||
|  | 							barmsg = "Undone. (" .. eldit.undoPos .. "/" .. #eldit.undoBuffer .. ")" | ||||||
|  | 							barlife = defaultBarLife | ||||||
|  | 						else | ||||||
|  | 							barmsg = "Reached back of undo buffer." | ||||||
|  | 							barlife = defaultBarLife | ||||||
|  | 						end | ||||||
|  | 						doRender = true | ||||||
|  |  | ||||||
| 					elseif evt[2] == keys.left then | 					elseif evt[2] == keys.left then | ||||||
| 						adjustCursor(-1, 0, true, "word") | 						adjustCursor(-1, 0, true, "word") | ||||||
| 						doRender, isCursorBlink = true, true | 						doRender, isCursorBlink = true, true | ||||||
|  | 						eldit.undoBuffer[eldit.undoPos].selections = eldit.selections | ||||||
|  | 						eldit.undoBuffer[eldit.undoPos].cursors = eldit.cursors | ||||||
|  |  | ||||||
| 					elseif evt[2] == keys.right then | 					elseif evt[2] == keys.right then | ||||||
| 						adjustCursor(1, 0, true, "word") | 						adjustCursor(1, 0, true, "word") | ||||||
| 						doRender, isCursorBlink = true, true | 						doRender, isCursorBlink = true, true | ||||||
|  | 						eldit.undoBuffer[eldit.undoPos].selections = eldit.selections | ||||||
|  | 						eldit.undoBuffer[eldit.undoPos].cursors = eldit.cursors | ||||||
|  |  | ||||||
| 					elseif evt[2] == keys.up then | 					elseif evt[2] == keys.up then | ||||||
| 						adjustCursor(0, -1, false, "flip") | 						adjustCursor(0, -1, false, "flip") | ||||||
| 						doRender, isCursorBlink = true, true | 						doRender, isCursorBlink = true, true | ||||||
|  | 						undotID = os.startTimer(eldit.undoDelay) | ||||||
|  | 						eldit.undoBuffer[eldit.undoPos].selections = eldit.selections | ||||||
|  | 						eldit.undoBuffer[eldit.undoPos].cursors = eldit.cursors | ||||||
|  |  | ||||||
| 					elseif evt[2] == keys.down then | 					elseif evt[2] == keys.down then | ||||||
| 						adjustCursor(0, 1, false, "flip") | 						adjustCursor(0, 1, false, "flip") | ||||||
| 						doRender, isCursorBlink = true, true | 						doRender, isCursorBlink = true, true | ||||||
|  | 						undotID = os.startTimer(eldit.undoDelay) | ||||||
|  | 						eldit.undoBuffer[eldit.undoPos].selections = eldit.selections | ||||||
|  | 						eldit.undoBuffer[eldit.undoPos].cursors = eldit.cursors | ||||||
|  |  | ||||||
| 					end | 					end | ||||||
| 				end | 				end | ||||||
| @@ -867,6 +975,8 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 				if evt[2] == keys.tab then | 				if evt[2] == keys.tab then | ||||||
| 					placeText("\9") | 					placeText("\9") | ||||||
| 					doRender = true | 					doRender = true | ||||||
|  | 					undotID = os.startTimer(eldit.undoDelay) | ||||||
|  |  | ||||||
| 				elseif evt[2] == keys.insert then | 				elseif evt[2] == keys.insert then | ||||||
| 					isInsert = not isInsert | 					isInsert = not isInsert | ||||||
| 					doRender, isCursorBlink = true, true | 					doRender, isCursorBlink = true, true | ||||||
| @@ -874,6 +984,7 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 				elseif evt[2] == keys.enter then | 				elseif evt[2] == keys.enter then | ||||||
| 					makeNewLine() | 					makeNewLine() | ||||||
| 					doRender, isCursorBlink = true, false | 					doRender, isCursorBlink = true, false | ||||||
|  | 					undotID = os.startTimer(eldit.undoDelay) | ||||||
|  |  | ||||||
| 				elseif evt[2] == keys.home then | 				elseif evt[2] == keys.home then | ||||||
| 					eldit.cursors = {{ | 					eldit.cursors = {{ | ||||||
| @@ -908,6 +1019,7 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 						deleteText("single", "backward") | 						deleteText("single", "backward") | ||||||
| 					end | 					end | ||||||
| 					doRender, isCursorBlink = true, false | 					doRender, isCursorBlink = true, false | ||||||
|  | 					undotID = os.startTimer(eldit.undoDelay) | ||||||
|  |  | ||||||
| 				elseif evt[2] == keys.delete then | 				elseif evt[2] == keys.delete then | ||||||
| 					if #eldit.selections > 0 then | 					if #eldit.selections > 0 then | ||||||
| @@ -916,23 +1028,31 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 						deleteText("single", "forward") | 						deleteText("single", "forward") | ||||||
| 					end | 					end | ||||||
| 					doRender, isCursorBlink = true, false | 					doRender, isCursorBlink = true, false | ||||||
|  | 					undotID = os.startTimer(eldit.undoDelay) | ||||||
|  |  | ||||||
| 				elseif evt[2] == keys.left then | 				elseif evt[2] == keys.left then | ||||||
| 					adjustCursor(-1, 0, true) | 					adjustCursor(-1, 0, true) | ||||||
|  | 					eldit.undoBuffer[eldit.undoPos].selections = eldit.selections | ||||||
|  | 					eldit.undoBuffer[eldit.undoPos].cursors = eldit.cursors | ||||||
| 					doRender, isCursorBlink = true, true | 					doRender, isCursorBlink = true, true | ||||||
|  |  | ||||||
| 				elseif evt[2] == keys.right then | 				elseif evt[2] == keys.right then | ||||||
| 					adjustCursor(1, 0, true) | 					adjustCursor(1, 0, true) | ||||||
|  | 					eldit.undoBuffer[eldit.undoPos].selections = eldit.selections | ||||||
|  | 					eldit.undoBuffer[eldit.undoPos].cursors = eldit.cursors | ||||||
| 					doRender, isCursorBlink = true, true | 					doRender, isCursorBlink = true, true | ||||||
|  |  | ||||||
| 				elseif evt[2] == keys.up then | 				elseif evt[2] == keys.up then | ||||||
| 					adjustCursor(0, -1, false) | 					adjustCursor(0, -1, false) | ||||||
|  | 					eldit.undoBuffer[eldit.undoPos].selections = eldit.selections | ||||||
|  | 					eldit.undoBuffer[eldit.undoPos].cursors = eldit.cursors | ||||||
| 					doRender, isCursorBlink = true, true | 					doRender, isCursorBlink = true, true | ||||||
|  |  | ||||||
| 				elseif evt[2] == keys.down then | 				elseif evt[2] == keys.down then | ||||||
| 					adjustCursor(0, 1, false) | 					adjustCursor(0, 1, false) | ||||||
| 					doRender, isCursorBlink = true, true | 					doRender, isCursorBlink = true, true | ||||||
|  | 					eldit.undoBuffer[eldit.undoPos].selections = eldit.selections | ||||||
|  | 					eldit.undoBuffer[eldit.undoPos].cursors = eldit.cursors | ||||||
| 				end | 				end | ||||||
|  |  | ||||||
| 			end | 			end | ||||||
| @@ -966,6 +1086,8 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 			} | 			} | ||||||
| 			sortSelections() | 			sortSelections() | ||||||
| 			adjustCursor(0, 0, true) | 			adjustCursor(0, 0, true) | ||||||
|  | 			eldit.undoBuffer[eldit.undoPos].selections = eldit.selections | ||||||
|  | 			eldit.undoBuffer[eldit.undoPos].cursors = eldit.cursors | ||||||
| 			doRender = true | 			doRender = true | ||||||
| 		elseif evt[1] == "mouse_drag" then | 		elseif evt[1] == "mouse_drag" then | ||||||
| 			local lineNoLen = #tostring(#eldit.buffer) | 			local lineNoLen = #tostring(#eldit.buffer) | ||||||
| @@ -989,9 +1111,6 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
| 						y = adjEY | 						y = adjEY | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				if isSelecting then |  | ||||||
| 					--lastMouse.ctrl = false |  | ||||||
| 				end |  | ||||||
| 				sortSelections() | 				sortSelections() | ||||||
| 				eldit.cursors[lastMouse.curID] = { | 				eldit.cursors[lastMouse.curID] = { | ||||||
| 					x = eldit.selections[selID][1].x, | 					x = eldit.selections[selID][1].x, | ||||||
| @@ -1001,6 +1120,8 @@ prompt = function(prebuffer, precy, _eldit) | |||||||
|  |  | ||||||
| 				isSelecting = true | 				isSelecting = true | ||||||
| 				adjustCursor(0, 0) | 				adjustCursor(0, 0) | ||||||
|  | 				eldit.undoBuffer[eldit.undoPos].selections = eldit.selections | ||||||
|  | 				eldit.undoBuffer[eldit.undoPos].cursors = eldit.cursors | ||||||
| 				doRender = true | 				doRender = true | ||||||
| 			end | 			end | ||||||
| 		elseif evt[1] == "mouse_up" then | 		elseif evt[1] == "mouse_up" then | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 LDDestroier
					LDDestroier