foxygit / Hush Log in
commits tags

/src/undo.h · 1.83 KB

raw
#ifndef HUSH_UNDO_H
#define HUSH_UNDO_H

#include "document.h"
#include <stdbool.h>

typedef struct {
    Document doc;
    int cursorBlock, cursorOffset;
} Snapshot;

typedef struct {
    Snapshot *items;
    int count, cap;
    int limit; /* max entries kept; oldest evicted beyond this */
} SnapshotStack;

void snapshot_stack_init(SnapshotStack *s, int limit);
void snapshot_stack_free(SnapshotStack *s);
void snapshot_stack_clear(SnapshotStack *s);
void snapshot_stack_push(SnapshotStack *s, const Document *doc, int cursorBlock, int cursorOffset);
/* Pops the most recent snapshot into *out (transfers Document ownership -- caller must
   eventually document_free it). Returns false if the stack is empty. */
bool snapshot_stack_pop(SnapshotStack *s, Snapshot *out);

typedef enum { EDIT_NONE, EDIT_TYPE, EDIT_BACKSPACE, EDIT_DELETE_FWD, EDIT_ENTER, EDIT_PASTE, EDIT_TOGGLE_TASK,
               EDIT_QUICK_INSERT, EDIT_TURN_INTO, EDIT_INSERT_TABLE } EditKind;

typedef struct {
    SnapshotStack undo, redo;
    EditKind lastKind;
    int lastBlock, lastOffset;
} UndoManager;

void undo_manager_init(UndoManager *m, int limit);
void undo_manager_free(UndoManager *m);
/* Clears both stacks and coalescing state -- call when a brand new document is loaded. */
void undo_manager_reset(UndoManager *m);

/* Call BEFORE mutating the document. Pushes a pre-edit snapshot (and clears the redo stack)
   unless this edit coalesces with the immediately preceding one (same kind, cursor unmoved
   since the last edit). */
void undo_manager_before_edit(UndoManager *m, EditKind kind, const Document *doc, int cursorBlock, int cursorOffset);
/* Call AFTER mutating, with the new cursor position, so the next call's coalescing check has
   something to compare against. */
void undo_manager_after_edit(UndoManager *m, EditKind kind, int cursorBlock, int cursorOffset);

#endif