about summary refs log tree commit diff stats
path: root/undo.lua
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2022-06-02 17:46:30 -0700
committerKartik K. Agaram <vc@akkartik.com>2022-06-02 17:46:30 -0700
commit4f76ea37d7a24e6562fb8640935750c50de62e69 (patch)
treea067abd0be2cf6dffcecf231873ace189d62a061 /undo.lua
parent22817492a3c5dd33c7d34c0c505b2bac2661d0ac (diff)
downloadlines.love-4f76ea37d7a24e6562fb8640935750c50de62e69.tar.gz
more efficient undo/redo
Now the bottleneck shifts to applying undo/redo in large files. But
things should be snappy if you don't use the sluggish feature.
Diffstat (limited to 'undo.lua')
-rw-r--r--undo.lua37
1 files changed, 35 insertions, 2 deletions
diff --git a/undo.lua b/undo.lua
index bc47f05..e196d24 100644
--- a/undo.lua
+++ b/undo.lua
@@ -32,8 +32,16 @@ function redo_event()
   end
 end
 
+-- Copy all relevant global state.
 -- Make copies of objects; the rest of the app may mutate them in place, but undo requires immutable histories.
-function snapshot()
+function snapshot(s,e)
+  -- Snapshot everything by default, but subset if requested.
+  if s == nil and e == nil then
+    s = 1
+    e = #Lines
+  elseif e == nil then
+    e = s
+  end
   -- compare with App.initialize_globals
   local event = {
     screen_top=deepcopy(Screen_top1),
@@ -43,10 +51,13 @@ function snapshot()
     previous_drawing_mode=Previous_drawing_mode,
     zoom=Zoom,
     lines={},
+    start_line=s,
+    end_line=e,
     -- no filename; undo history is cleared when filename changes
   }
   -- deep copy lines without cached stuff like text fragments
-  for _,line in ipairs(Lines) do
+  for i=s,e do
+    local line = Lines[i]
     if line.mode == 'text' then
       table.insert(event.lines, {mode='text', data=line.data})
     elseif line.mode == 'drawing' then
@@ -64,6 +75,24 @@ function snapshot()
   return event
 end
 
+function patch(lines, from, to)
+--?   if #from.lines == 1 and #to.lines == 1 then
+--?     assert(from.start_line == from.end_line)
+--?     assert(to.start_line == to.end_line)
+--?     assert(from.start_line == to.start_line)
+--?     lines[from.start_line] = to.lines[1]
+--?     return
+--?   end
+  assert(from.start_line == to.start_line)
+  for i=from.end_line,from.start_line,-1 do
+    table.remove(lines, i)
+  end
+  assert(#to.lines == to.end_line-to.start_line+1)
+  for i=1,#to.lines do
+    table.insert(lines, to.start_line+i-1, to.lines[i])
+  end
+end
+
 -- https://stackoverflow.com/questions/640642/how-do-you-copy-a-lua-table-by-value/26367080#26367080
 function deepcopy(obj, seen)
   if type(obj) ~= 'table' then return obj end
@@ -76,3 +105,7 @@ function deepcopy(obj, seen)
   end
   return result
 end
+
+function minmax(a, b)
+  return math.min(a,b), math.max(a,b)
+end