aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/view.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/view.c')
-rw-r--r--src/view.c58
1 files changed, 52 insertions, 6 deletions
diff --git a/src/view.c b/src/view.c
index 43cdd3f..d866a5e 100644
--- a/src/view.c
+++ b/src/view.c
@@ -65,10 +65,9 @@ teco_view_setup(teco_view_t *ctx)
SC_MOD_INSERTTEXT | SC_MOD_BEFOREDELETE, 0);
/*
- * Start with or without undo collection,
- * depending on teco_undo_enabled.
+ * We are exclusively using SciTECO's undo tokens.
*/
- teco_view_ssm(ctx, SCI_SETUNDOCOLLECTION, teco_undo_enabled, 0);
+ teco_view_ssm(ctx, SCI_SETUNDOCOLLECTION, FALSE, 0);
teco_view_ssm(ctx, SCI_SETFOCUS, TRUE, 0);
@@ -248,7 +247,6 @@ teco_view_load_from_channel(teco_view_t *ctx, GIOChannel *channel,
teco_view_ssm(ctx, SCI_RELEASELINECHARACTERINDEX,
SC_LINECHARACTERINDEX_UTF32, 0);
- teco_view_ssm(ctx, SCI_BEGINUNDOACTION, 0, 0);
if (clear) {
teco_view_ssm(ctx, SCI_CLEARALL, 0, 0);
@@ -322,8 +320,6 @@ teco_view_load_from_channel(teco_view_t *ctx, GIOChannel *channel,
"Inconsistent EOL styles normalized");
cleanup:
- teco_view_ssm(ctx, SCI_ENDUNDOACTION, 0, 0);
-
if (cp == SC_CP_UTF8)
teco_view_ssm(ctx, SCI_ALLOCATELINECHARACTERINDEX,
SC_LINECHARACTERINDEX_UTF32, 0);
@@ -835,6 +831,56 @@ teco_view_get_character(teco_view_t *ctx, gsize pos, gsize len)
return rc < 0 ? rc-1 : rc;
}
+typedef struct {
+ teco_view_t *view;
+ /** dot in bytes before the deletion */
+ gsize dot_bytes;
+ gsize position, length;
+ gchar text[];
+} teco_undo_view_insert_t;
+
+static void
+teco_undo_view_insert_action(teco_undo_view_insert_t *ctx, gboolean run)
+{
+ if (!run)
+ return;
+ teco_view_ssm(ctx->view, SCI_GOTOPOS, ctx->position, 0);
+ teco_view_ssm(ctx->view, SCI_ADDTEXT, ctx->length, (sptr_t)ctx->text);
+ teco_view_ssm(ctx->view, SCI_GOTOPOS, ctx->dot_bytes, 0);
+}
+
+/**
+ * During undo, insert a string from the given view.
+ * This can be used to undo text deletions.
+ *
+ * @param view The view that contains the string
+ * @param pos Beginning of string in bytes
+ * @param len Length of string in bytes
+ */
+void
+teco_undo_view_insert(teco_view_t *view, gsize pos, gsize len)
+{
+ if (!len)
+ return;
+
+ teco_undo_view_insert_t *ctx;
+ ctx = teco_undo_push_size((teco_undo_action_t)teco_undo_view_insert_action,
+ sizeof(*ctx) + len + 1);
+ if (!ctx)
+ return;
+
+ ctx->view = view;
+ ctx->dot_bytes = teco_view_ssm(view, SCI_GETCURRENTPOS, 0, 0);
+ ctx->position = pos;
+ ctx->length = len;
+
+ struct Sci_TextRangeFull range = {
+ .chrg = {pos, pos + len},
+ .lpstrText = ctx->text
+ };
+ teco_view_ssm(view, SCI_GETTEXTRANGEFULL, 0, (sptr_t)&range);
+}
+
void
teco_view_process_notify(teco_view_t *ctx, const SCNotification *notify)
{