commit 7a64b99342bd37248395655399b5a4ef2334b4fe
parent 1146213bf1660a36ffc9269f938602905847d554
Author: lumidify <nobody@lumidify.org>
Date: Thu, 2 Dec 2021 23:25:06 +0100
Add documentation for undo
Diffstat:
M | undo.c | | | 6 | +++--- |
M | undo.h | | | 77 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
2 files changed, 79 insertions(+), 4 deletions(-)
diff --git a/undo.c b/undo.c
@@ -96,7 +96,7 @@ undo_change_mode_group(undo_stack *undo) {
static void
push_undo(
undo_stack *undo, txtbuf *text,
- ledit_range insert_range,
+ ledit_range insert_range, /* maybe not the best name */
ledit_range cursor_range,
int start_group,
enum operation type, enum ledit_mode mode) {
@@ -131,10 +131,10 @@ undo_push_insert(
void
undo_push_delete(
undo_stack *undo, txtbuf *text,
- ledit_range insert_range, ledit_range cursor_range,
+ ledit_range delete_range, ledit_range cursor_range,
int start_group, enum ledit_mode mode) {
push_undo(
- undo, text, insert_range, cursor_range,
+ undo, text, delete_range, cursor_range,
start_group, UNDO_DELETE, mode
);
}
diff --git a/undo.h b/undo.h
@@ -1,3 +1,28 @@
+/*
+ * This handles undo and redo.
+ *
+ * Some things need to be explained:
+ *
+ * Each stack entry contains text, the text range, and the cursor range.
+ * The text is the text that was inserted or deleted, the text range is
+ * the exact line and byte range of the text before it was deleted or
+ * after it was inserted. The cursor range stores the position of the
+ * cursor before and after the operation so it can be restored.
+ *
+ * Each stack entry has a group, a mode group, and the actual mode stored.
+ * When pushing an operation onto the stack, start_group can be specified.
+ * If this is 0, the operation belongs together with the previous operation,
+ * i.e. they will always be undone or redone together.
+ * The current mode of the view is stored with each stack entry so that
+ * all operations belonging to the last "session" in insert mode can be
+ * undone together.
+ * Additionally, undo_change_mode_group should be called when the mode of
+ * the view is changed. This is needed to separate different insert sessions
+ * so multiple sessions aren't undone together if the user just left insert
+ * mode and then returned immediately to insert mode without doing anything
+ * in normal mode.
+ */
+
typedef enum {
UNDO_NORMAL,
UNDO_OLDEST_CHANGE,
@@ -5,27 +30,77 @@ typedef enum {
} undo_status;
typedef struct undo_stack undo_stack;
+
+/*
+ * Callback used for inserting text.
+ * This is called with (respectively) the given callback data, the line index,
+ * the byte index, the text, and the length of the text.
+ */
typedef void (*undo_insert_callback)(void *, size_t, size_t, char *, size_t);
+
+/*
+ * Callback used for deleting text.
+ * This is called with (respectively) the given callback data, the line and
+ * byte index of the beginning of the range, and the line and byte index of
+ * the end of the range.
+ */
typedef void (*undo_delete_callback)(void *, size_t, size_t, size_t, size_t);
+/*
+ * Create an empty undo stack.
+ */
undo_stack *undo_stack_create(void);
+
+/*
+ * Destroy an undo stack.
+ */
void undo_stack_destroy(undo_stack *undo);
+
+/*
+ * Change the mode group.
+ * This does not actually change the mode group yet, it just sets a bit
+ * so the mode group is changed the next time an item is pushed on the stack.
+ */
void undo_change_mode_group(undo_stack *undo);
+
+/*
+ * Push an insert action onto the undo stack.
+ * See documentation at top for details on the other arguments.
+ */
void undo_push_insert(
undo_stack *undo, txtbuf *text,
ledit_range insert_range, ledit_range cursor_range,
int start_group, enum ledit_mode mode
);
+
+/*
+ * Push an delete action onto the undo stack.
+ * See documentation at top for details on the other arguments.
+ */
void undo_push_delete(
undo_stack *undo, txtbuf *text,
- ledit_range insert_range, ledit_range cursor_range,
+ ledit_range delete_range, ledit_range cursor_range,
int start_group, enum ledit_mode mode
);
+
+/*
+ * Undo one step.
+ * 'cur_line_ret' and 'cur_index_ret' are set to the new cursor position.
+ * 'min_line_ret' is set to the minimum line that was touched so the lines
+ * can be recalculated properly.
+ */
undo_status ledit_undo(
undo_stack *undo, enum ledit_mode mode,
void *callback_data, undo_insert_callback insert_cb, undo_delete_callback delete_cb,
size_t *cur_line_ret, size_t *cur_index_ret, size_t *min_line_ret
);
+
+/*
+ * Redo one step.
+ * 'cur_line_ret' and 'cur_index_ret' are set to the new cursor position.
+ * 'min_line_ret' is set to the minimum line that was touched so the lines
+ * can be recalculated properly.
+ */
undo_status ledit_redo(
undo_stack *undo, enum ledit_mode mode,
void *callback_data, undo_insert_callback insert_cb, undo_delete_callback delete_cb,