Created
June 7, 2010 05:59
-
-
Save malkia/428272 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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