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/core-commands.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/core-commands.c')
| -rw-r--r-- | src/core-commands.c | 64 |
1 files changed, 30 insertions, 34 deletions
diff --git a/src/core-commands.c b/src/core-commands.c index 612d980..6362d95 100644 --- a/src/core-commands.c +++ b/src/core-commands.c @@ -291,13 +291,11 @@ teco_state_start_backslash(teco_machine_main_t *ctx, GError **error) teco_current_doc_set_dot(teco_ranges[0].to); - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); + if (teco_current_doc_must_undo()) + undo__teco_interface_ssm(SCI_DELETERANGE, + teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0), len); teco_interface_ssm(SCI_ADDTEXT, len, (sptr_t)str); - teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); teco_ring_dirtify(); - - if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_UNDO, 0, 0); } else { teco_qreg_t *qreg = ctx->qreg_table_locals->radix; assert(qreg != NULL); @@ -566,16 +564,11 @@ teco_state_start_cmdline_push(teco_machine_main_t *ctx, GError **error) const gchar *macro = (const gchar *)teco_cmdline_ssm(SCI_GETCHARACTERPOINTER, 0, 0); - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); + /* must always support undo on global register */ + teco_undo_interface_insert(0, teco_interface_ssm(SCI_GETLENGTH, 0, 0)); teco_interface_ssm(SCI_CLEARALL, 0, 0); + undo__teco_interface_ssm(SCI_CLEARALL, 0, 0); teco_interface_ssm(SCI_ADDTEXT, teco_cmdline.pc, (sptr_t)macro); - teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); - - /* - * Must always support undo on global register. - * A undo action should always have been generated. - */ - undo__teco_interface_ssm(SCI_UNDO, 0, 0); /* * FIXME: If we would maintain dot in the command line, @@ -2736,16 +2729,15 @@ teco_state_ecommand_encoding(teco_machine_main_t *ctx, GError **error) if (!converted) return; - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); - teco_interface_ssm(SCI_CLEARALL, 0, 0); - teco_interface_ssm(SCI_APPENDTEXT, converted_len, (sptr_t)converted); - teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); - teco_ring_dirtify(); - if (teco_current_doc_must_undo()) { undo__teco_interface_ssm(SCI_GOTOPOS, dot_bytes, 0); - undo__teco_interface_ssm(SCI_UNDO, 0, 0); + teco_undo_interface_insert(0, teco_interface_ssm(SCI_GETLENGTH, 0, 0)); + undo__teco_interface_ssm(SCI_CLEARALL, 0, 0); } + + teco_interface_ssm(SCI_CLEARALL, 0, 0); + teco_interface_ssm(SCI_APPENDTEXT, converted_len, (sptr_t)converted); + teco_ring_dirtify(); } if (new_cp == SC_CP_UTF8) { @@ -2985,6 +2977,9 @@ teco_state_insert_initial(teco_machine_main_t *ctx, GError **error) return TRUE; } + gsize dot_bytes = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0); + gsize added_len = 0; + if (teco_interface_ssm(SCI_GETCODEPAGE, 0, 0) == SC_CP_UTF8) { /* detect possible errors before introducing side effects */ for (gint i = args; i > 0; i--) { @@ -2994,12 +2989,12 @@ teco_state_insert_initial(teco_machine_main_t *ctx, GError **error) return FALSE; } } - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); for (gint i = args; i > 0; i--) { /* 4 bytes should be enough, but we better follow the documentation */ gchar buf[6]; gsize len = g_unichar_to_utf8(teco_expressions_peek_num(i-1), buf); teco_interface_ssm(SCI_ADDTEXT, len, (sptr_t)buf); + added_len += len; } } else { /* everything else is a single-byte encoding */ @@ -3010,17 +3005,16 @@ teco_state_insert_initial(teco_machine_main_t *ctx, GError **error) return FALSE; } } - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); for (gint i = args; i > 0; i--) { gchar chr = (gchar)teco_expressions_peek_num(i-1); teco_interface_ssm(SCI_ADDTEXT, 1, (sptr_t)&chr); } + added_len = args; } - teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); teco_ring_dirtify(); if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_UNDO, 0, 0); + undo__teco_interface_ssm(SCI_DELETERANGE, dot_bytes, added_len); /* This is done only now because it can _theoretically_ fail. */ for (gint i = 0; i < args; i++) @@ -3038,15 +3032,14 @@ teco_state_insert_process(teco_machine_main_t *ctx, teco_string_t str, { g_assert(new_chars > 0); - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); + if (teco_current_doc_must_undo()) + undo__teco_interface_ssm(SCI_DELETERANGE, + teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0), new_chars); + teco_interface_ssm(SCI_ADDTEXT, new_chars, (sptr_t)(str.data + str.len - new_chars)); - teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); teco_ring_dirtify(); - if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_UNDO, 0, 0); - return TRUE; } @@ -3100,8 +3093,11 @@ teco_state_insert_indent_initial(teco_machine_main_t *ctx, GError **error) if (!teco_state_insert_initial(ctx, error)) return FALSE; - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); if (teco_interface_ssm(SCI_GETUSETABS, 0, 0)) { + if (teco_current_doc_must_undo()) + undo__teco_interface_ssm(SCI_DELETERANGE, + teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0), 1); + teco_interface_ssm(SCI_ADDTEXT, 1, (sptr_t)"\t"); /* teco_state_insert_done() expects this */ @@ -3115,16 +3111,16 @@ teco_state_insert_indent_initial(teco_machine_main_t *ctx, GError **error) /* teco_state_insert_done() expects this */ teco_undo_int(teco_ranges[0].to) += len; + if (teco_current_doc_must_undo()) + undo__teco_interface_ssm(SCI_DELETERANGE, + teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0), len); + gchar space = ' '; while (len-- > 0) teco_interface_ssm(SCI_ADDTEXT, 1, (sptr_t)&space); } - teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); teco_ring_dirtify(); - if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_UNDO, 0, 0); - return TRUE; } |
