Undo/Redo implementation

后端 未结 10 1374
醉酒成梦
醉酒成梦 2020-11-28 18:59

Give me some thoughts how to implement undo/redo functionality - like we have in text editors. What algorithms should I use and what I may read. thanks.

10条回答
  •  隐瞒了意图╮
    2020-11-28 19:17

    A bit late, but here goes: You specifically refer to text editors, what follow explains an algorithm that can be adapted to whatever it is you are editing. The principle involved is to keep a list of actions/instructions that can be automated to recreate each change you made. Do not make changes to the original file (if not empty), keep it as a back-up.

    Keep a forward-backward linked-list of changes you make to the original file. This list is saved intermittently to a temporary file, until the user actually Saves the changes: when this happens you apply the changes to a new file, copying the old one and simultaneously applying the changes; then rename the original file to a backup, and change the new file's name to the correct name. (You can either keep the saved change-list, or delete it and replace with a subsequent list of changes.)

    Each node in the linked-list contain the following info:.

    • type of change: you either insert data, or you delete data: to "change" data means a delete followed by an insert
    • position in file: can be an offset or line/column-pair
    • data buffer: this is the data involved with the action; if insert it is the data that was inserted; if delete, the data that was deleted.

    To implement Undo, you work backward from the tail of the linked-list, using a 'current-node' pointer or index: where the change was insert, you do a delete but without updating the linked-list; and where it was a delete you insert the data from the data in the linked-list buffer. Do this for each 'Undo'-command from the user. Redo moves the 'current-node' pointer forward and executes the change as per the node. Should the user make a change to the code after undoing, delete all nodes after the'current-node' indicator to the tail, and set tail equal to the 'current-node' indicator. The user's new changes are then inserted after the tail. And that's about it.

提交回复
热议问题