Skip to content

Instantly share code, notes, and snippets.

@malkia
Created June 7, 2010 05:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save malkia/428272 to your computer and use it in GitHub Desktop.
Save malkia/428272 to your computer and use it in GitHub Desktop.
Editor = {
"1. First Line",
"2. Second Line",
"3. Third Line",
"4. Fourth Line",
"5. Fifth Line",
}
function timeit(fun,info)
info = info or ""
local t = os.clock()
fun()
print( info .. " took " .. tostring(os.clock() - t) .. " seconds" )
end
function Editor.LoadFile(self, name)
name = name or "/Users/malkia/pp/lua-editor/1"
local f = io.input(name)
assert(f, "Editor:LoadFile - Can't open " .. name)
while #self > 0 do
self[#self] = nil
end
for line in f:lines() do
self[#self + 1] = line
end
end
function Editor.SaveFile(self, name)
name = name or "/Users/malkia/pp/lua-editor/2"
local f = io.output(name)
assert(f, "Editor:SaveFile - Can't create " .. name)
for i=1,#self do
f:write(self[i], "\n")
end
f:close()
end
function Editor.DeleteLines(self, firstLine, lineCount)
assert( firstLine >= 1 )
assert( firstLine <= #self )
assert( lineCount >= 1 )
assert( lineCount <= #self - firstLine + 1 )
-- Save the lines to be deleted for the undo operation
local deletedLines = {}
for i=0, lineCount - 1 do
deletedLines[#deletedLines + 1] = self[firstLine + i]
end
-- Move the lines from the next-to-be line to the end of the file
-- To the firstLine
local nextLine = firstLine + lineCount
for i=0, #self - nextLine do
self[firstLine + i] = self[nextLine + i]
end
-- Delete the lines at the end, after the movement
for i=1, lineCount do
self[#self] = nil
end
-- Return an undo operation
return function()
Editor:InsertLines(firstLine, deletedLines)
end
end
function Editor.InsertLines(self, firstLine, linesToInsert)
if type(linesToInsert)=="string" then
linesToInsert = { linesToInsert }
else
if type(linesToInsert)=="number" then
local cnt = linesToInsert
linesToInsert = {}
for i=1,cnt do
linesToInsert[#linesToInsert + 1] = ""
end
end
end
assert( firstLine >= 1, "firstLine >= 1" )
assert( firstLine <= #self + 1, "firstLine <= #self + 1" )
local linesToInsertCount = #linesToInsert
assert( linesToInsertCount >= 1, "linesToInsertCount >= 1" )
if firstLine == #self + 1 then
-- Append
for i=1, linesToInsertCount do
self[#self + 1] = linesToInsert[i]
end
else
-- Expand the number of lines
for i=1, linesToInsertCount do
self[#self + 1] = ""
end
-- Move the lines at the end to
-- Make space for the new lines
local nextLine = firstLine + linesToInsertCount
for i=#self, nextLine, -1 do
self[i] = self[i - linesToInsertCount]
end
-- Put the new lines
for i=0, linesToInsertCount - 1 do
self[firstLine + i] = linesToInsert[i + 1]
end
end
return function()
Editor:DeleteLines(firstLine, linesToInsertCount)
end
end
function Editor.DeleteCharacters(self, line, column, charactersCount)
if line < 1 or line > #self then
error( "Editor:DeleteCharacters - invalid line"..tostring(line) )
end
end
print("")
timeit(function() Editor:LoadFile() end, "LoadFile")
for i=1,10 do
local undo
timeit(function() undo = Editor:DeleteLines(2, 200000) end, "DeleteLines")
timeit(undo, "Undo (InsertLines)")
end
timeit(function() Editor:SaveFile() end, "aveFile")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment