diff options
| author | Robin Haberkorn <rhaberkorn@fmsbw.de> | 2026-09-25 01:43:56 +0200 |
|---|---|---|
| committer | Robin Haberkorn <rhaberkorn@fmsbw.de> | 2026-09-25 01:43:56 +0200 |
| commit | e371b5fc710c597e175e6b7d7645b3a224a731a1 (patch) | |
| tree | 3861fa4949adfd1c95a06ae0b7dd41c4167a3b7a /src/view.c | |
| parent | 207af96f4eb3220534ea06c2e107517372246544 (diff) | |
instead of relying on Scintilla undo actions, use SciTECO undo tokens exclusively
Previously we were using both Scintilla undo actions and our own undo tokens
and both had to be coordinated via `undo__teco_interface_ssm(SCI_UNDO, 0, 0)`.
This was error prone since we have to predict when an undo action is actually
generated. Furthermore, you had to update SCI_SETUNDOCOLLECTION on all buffers
and the Q-Reg view whenever switching to and from interactive mode.
Also, this probably wasted memory for the doubled undo bookkeeping.
Now, we always set SCI_SETUNDOCOLLECTION(FALSE), even in interactive mode.
teco_undo_view_insert() was introduced to undo text deletions.
While this saves almost no lines of code, it's just a clearer and simpler
architecture.
Diffstat (limited to 'src/view.c')
| -rw-r--r-- | src/view.c | 58 |
1 files changed, 52 insertions, 6 deletions
@@ -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) { |
