diff options
Diffstat (limited to 'undo.lua')
-rw-r--r-- | undo.lua | 110 |
1 files changed, 0 insertions, 110 deletions
diff --git a/undo.lua b/undo.lua deleted file mode 100644 index 912c949..0000000 --- a/undo.lua +++ /dev/null @@ -1,110 +0,0 @@ --- undo/redo by managing the sequence of events in the current session --- based on https://github.com/akkartik/mu1/blob/master/edit/012-editor-undo.mu - --- Incredibly inefficient; we make a copy of lines on every single keystroke. --- The hope here is that we're either editing small files or just reading large files. --- TODO: highlight stuff inserted by any undo/redo operation --- TODO: coalesce multiple similar operations - -function record_undo_event(State, data) - State.history[State.next_history] = data - State.next_history = State.next_history+1 - for i=State.next_history,#State.history do - State.history[i] = nil - end -end - -function undo_event(State) - if State.next_history > 1 then ---? print('moving to history', State.next_history-1) - State.next_history = State.next_history-1 - local result = State.history[State.next_history] - return result - end -end - -function redo_event(State) - if State.next_history <= #State.history then ---? print('restoring history', State.next_history+1) - local result = State.history[State.next_history] - State.next_history = State.next_history+1 - return result - 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(State, s,e) - -- Snapshot everything by default, but subset if requested. - assert(s) - if e == nil then - e = s - end - assert(#State.lines > 0) - if s < 1 then s = 1 end - if s > #State.lines then s = #State.lines end - if e < 1 then e = 1 end - if e > #State.lines then e = #State.lines end - -- compare with App.initialize_globals - local event = { - screen_top=deepcopy(State.screen_top1), - selection=deepcopy(State.selection1), - cursor=deepcopy(State.cursor1), - 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 i=s,e do - local line = State.lines[i] - table.insert(event.lines, {data=line.data}) - end - 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 - -function patch_placeholders(line_cache, from, to) - assert(from.start_line == to.start_line) - for i=from.end_line,from.start_line,-1 do - table.remove(line_cache, i) - end - assert(#to.lines == to.end_line-to.start_line+1) - for i=1,#to.lines do - table.insert(line_cache, to.start_line+i-1, {}) - 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 - if seen and seen[obj] then return seen[obj] end - local s = seen or {} - local result = setmetatable({}, getmetatable(obj)) - s[obj] = result - for k,v in pairs(obj) do - result[deepcopy(k, s)] = deepcopy(v, s) - end - return result -end - -function minmax(a, b) - return math.min(a,b), math.max(a,b) -end |