diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmdline.c | 3 | ||||
| -rw-r--r-- | src/core-commands.c | 64 | ||||
| -rw-r--r-- | src/glob.c | 17 | ||||
| -rw-r--r-- | src/interface.h | 6 | ||||
| -rw-r--r-- | src/main.c | 5 | ||||
| -rw-r--r-- | src/move-commands.c | 21 | ||||
| -rw-r--r-- | src/qreg-commands.c | 15 | ||||
| -rw-r--r-- | src/qreg.c | 19 | ||||
| -rw-r--r-- | src/ring.c | 11 | ||||
| -rw-r--r-- | src/ring.h | 2 | ||||
| -rw-r--r-- | src/search.c | 27 | ||||
| -rw-r--r-- | src/spawn.c | 12 | ||||
| -rw-r--r-- | src/view.c | 58 | ||||
| -rw-r--r-- | src/view.h | 10 |
14 files changed, 131 insertions, 139 deletions
diff --git a/src/cmdline.c b/src/cmdline.c index d2d9d04..99bc802 100644 --- a/src/cmdline.c +++ b/src/cmdline.c @@ -382,9 +382,6 @@ teco_cmdline_keypress(const gchar *data, gsize len, GError **error) } teco_undo_clear(); - /* also empties all Scintilla undo buffers */ - teco_ring_set_scintilla_undo(TRUE); - teco_view_set_scintilla_undo(teco_qreg_view, TRUE); /* * FIXME: Reset main machine? */ 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; } @@ -482,6 +482,7 @@ teco_state_glob_filename_done(teco_machine_main_t *ctx, teco_string_t str, GErro gboolean matching = FALSE; gboolean colon_modified = teco_machine_main_eval_colon(ctx) > 0; + gsize added_len = 0; teco_int_t teco_test_mode; @@ -517,6 +518,8 @@ teco_state_glob_filename_done(teco_machine_main_t *ctx, teco_string_t str, GErro return NULL; } + sptr_t pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0); + if (str.len > 0) { /* * Match pattern against provided file name @@ -535,12 +538,10 @@ teco_state_glob_filename_done(teco_machine_main_t *ctx, teco_string_t str, GErro gsize len = strlen(filename); filename[len] = '\n'; - sptr_t pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0); teco_undo_int(teco_ranges[0].from) = teco_current_doc_get_dot(); - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); teco_interface_ssm(SCI_ADDTEXT, len+1, (sptr_t)filename); - teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); + added_len += len+1; teco_int_t to = teco_interface_bytes2glyphs_rel(teco_ranges[0].from, pos, len + 1); teco_undo_int(teco_ranges[0].to) = to; @@ -568,12 +569,9 @@ teco_state_glob_filename_done(teco_machine_main_t *ctx, teco_string_t str, GErro g_autoptr(teco_globber_t) globber; globber = teco_globber_new(pattern_str.data, file_flags); - sptr_t pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0); gsize total_len = 0; teco_undo_int(teco_ranges[0].from) = teco_current_doc_get_dot(); - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); - gchar *globbed_filename; while ((globbed_filename = teco_globber_next(globber))) { gsize len = strlen(globbed_filename); @@ -585,13 +583,12 @@ teco_state_glob_filename_done(teco_machine_main_t *ctx, teco_string_t str, GErro */ globbed_filename[len] = '\n'; teco_interface_ssm(SCI_ADDTEXT, len+1, (sptr_t)globbed_filename); + added_len += len+1; g_free(globbed_filename); matching = TRUE; } - teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); - teco_int_t to = teco_interface_bytes2glyphs_rel(teco_ranges[0].from, pos, total_len); teco_undo_int(teco_ranges[0].to) = to; teco_undo_guint(teco_ranges_count) = 1; @@ -600,11 +597,11 @@ teco_state_glob_filename_done(teco_machine_main_t *ctx, teco_string_t str, GErro if (colon_modified) { teco_expressions_push(teco_bool(matching)); - } else if (matching) { + } else if (added_len) { /* text has been inserted */ teco_ring_dirtify(); if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_UNDO, 0, 0); + undo__teco_interface_ssm(SCI_DELETERANGE, pos, added_len); } if (!glob_reg->vtable->set_integer(glob_reg, teco_bool(matching), error)) diff --git a/src/interface.h b/src/interface.h index 9c3d31e..20d9773 100644 --- a/src/interface.h +++ b/src/interface.h @@ -286,6 +286,12 @@ teco_interface_get_character(gsize pos, gsize len) return teco_view_get_character(teco_interface_current_view, pos, len); } +static inline void +teco_undo_interface_insert(gsize pos, gsize len) +{ + return teco_undo_view_insert(teco_interface_current_view, pos, len); +} + /* * The following functions are here for lack of a better place. * They could also be in sciteco.h, but only if declared as non-inline @@ -600,8 +600,6 @@ main(int argc, char **argv) teco_qreg_table_replace(&teco_qreg_table_globals, teco_qreg_plain_new("\e", 1)); teco_undo_enabled = TRUE; - teco_ring_set_scintilla_undo(TRUE); - teco_view_set_scintilla_undo(teco_qreg_view, TRUE); /* * FIXME: Perhaps we should simply call teco_cmdline_init() and @@ -633,9 +631,6 @@ main(int argc, char **argv) */ teco_undo_enabled = FALSE; teco_undo_clear(); - /* also empties all Scintilla undo buffers */ - teco_ring_set_scintilla_undo(FALSE); - teco_view_set_scintilla_undo(teco_qreg_view, FALSE); if (!teco_ed_hook(TECO_ED_HOOK_QUIT, &error)) goto cleanup; diff --git a/src/move-commands.c b/src/move-commands.c index 9ef893e..868bb19 100644 --- a/src/move-commands.c +++ b/src/move-commands.c @@ -472,14 +472,10 @@ teco_state_start_delete_words(teco_machine_main_t *ctx, const gchar *cmd, gint f if (start_pos < pos) teco_current_doc_set_dot(teco_interface_bytes2glyphs_absdot(start_pos)); - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); - teco_interface_ssm(SCI_DELETERANGE, start_pos, end_pos-start_pos); - teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); + if (teco_current_doc_must_undo()) + teco_undo_interface_insert(start_pos, end_pos-start_pos); - if (teco_current_doc_must_undo()) { - undo__teco_interface_ssm(SCI_GOTOPOS, pos, 0); - undo__teco_interface_ssm(SCI_UNDO, 0, 0); - } + teco_interface_ssm(SCI_DELETERANGE, start_pos, end_pos-start_pos); teco_ring_dirtify(); } @@ -562,17 +558,10 @@ teco_state_start_kill(teco_machine_main_t *ctx, const gchar *cmd, gboolean by_li if (len == 0 || teco_is_failure(rc)) return TRUE; - if (teco_current_doc_must_undo()) { - undo__teco_interface_ssm(SCI_GOTOPOS, pos, 0); - undo__teco_interface_ssm(SCI_UNDO, 0, 0); - } + if (teco_current_doc_must_undo()) + teco_undo_interface_insert(from, len); - /* - * Should always generate an undo action. - */ - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); teco_interface_ssm(SCI_DELETERANGE, from, len); - teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); teco_ring_dirtify(); return TRUE; diff --git a/src/qreg-commands.c b/src/qreg-commands.c index a6390a1..0c4c8d4 100644 --- a/src/qreg-commands.c +++ b/src/qreg-commands.c @@ -563,13 +563,11 @@ teco_state_getqregstring_got_register(teco_machine_main_t *ctx, teco_qreg_t *qre sptr_t pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0); if (str.len > 0) { - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); teco_interface_ssm(SCI_ADDTEXT, str.len, (sptr_t)str.data); - 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, pos, str.len); } teco_undo_int(teco_ranges[0].from) = teco_current_doc_get_dot(); @@ -835,17 +833,10 @@ teco_state_copytoqreg_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg, /* * If @-modified, cut into the register */ - if (teco_current_doc_must_undo()) { - undo__teco_interface_ssm(SCI_GOTOPOS, pos, 0); - undo__teco_interface_ssm(SCI_UNDO, 0, 0); - } + if (teco_current_doc_must_undo()) + teco_undo_interface_insert(from, len); - /* - * Should always generate an undo action. - */ - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); teco_interface_ssm(SCI_DELETERANGE, from, len); - teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); teco_ring_dirtify(); if (from+len < pos) @@ -188,7 +188,9 @@ teco_qreg_plain_append_string(teco_qreg_t *qreg, const gchar *str, gsize len, GE teco_doc_undo_edit(&teco_qreg_current->string); teco_doc_undo_reset(&qreg->string); - undo__teco_view_ssm(teco_qreg_view, SCI_UNDO, 0, 0); + + sptr_t pos = teco_view_ssm(teco_qreg_view, SCI_GETCURRENTPOS, 0, 0); + undo__teco_view_ssm(teco_qreg_view, SCI_DELETERANGE, pos, len); } if (teco_qreg_current) @@ -196,9 +198,7 @@ teco_qreg_plain_append_string(teco_qreg_t *qreg, const gchar *str, gsize len, GE teco_doc_edit(&qreg->string, teco_default_codepage()); - teco_view_ssm(teco_qreg_view, SCI_BEGINUNDOACTION, 0, 0); teco_view_ssm(teco_qreg_view, SCI_APPENDTEXT, len, (sptr_t)str); - teco_view_ssm(teco_qreg_view, SCI_ENDUNDOACTION, 0, 0); if (teco_qreg_current) teco_doc_edit(&teco_qreg_current->string, 0); @@ -469,12 +469,12 @@ teco_qreg_external_edit(teco_qreg_t *qreg, GError **error) !qreg->vtable->get_string(qreg, &str.data, &str.len, NULL, error)) return FALSE; - teco_view_ssm(teco_qreg_view, SCI_BEGINUNDOACTION, 0, 0); + teco_undo_view_insert(teco_qreg_view, 0, + teco_view_ssm(teco_qreg_view, SCI_GETLENGTH, 0, 0)); teco_view_ssm(teco_qreg_view, SCI_CLEARALL, 0, 0); + undo__teco_view_ssm(teco_qreg_view, SCI_CLEARALL, 0, 0); teco_view_ssm(teco_qreg_view, SCI_ADDTEXT, str.len, (sptr_t)str.data); - teco_view_ssm(teco_qreg_view, SCI_ENDUNDOACTION, 0, 0); - undo__teco_view_ssm(teco_qreg_view, SCI_UNDO, 0, 0); return TRUE; } @@ -586,12 +586,11 @@ teco_qreg_external_save(teco_qreg_t *qreg, const gchar *filename, GError **error if (!qreg->vtable->get_string(qreg, &str.data, &str.len, NULL, error)) return FALSE; - teco_view_ssm(teco_qreg_view, SCI_BEGINUNDOACTION, 0, 0); + teco_undo_view_insert(teco_qreg_view, 0, + teco_view_ssm(teco_qreg_view, SCI_GETLENGTH, 0, 0)); teco_view_ssm(teco_qreg_view, SCI_CLEARALL, 0, 0); + undo__teco_view_ssm(teco_qreg_view, SCI_CLEARALL, 0, 0); teco_view_ssm(teco_qreg_view, SCI_ADDTEXT, str.len, (sptr_t)str.data); - teco_view_ssm(teco_qreg_view, SCI_ENDUNDOACTION, 0, 0); - - undo__teco_view_ssm(teco_qreg_view, SCI_UNDO, 0, 0); gboolean ret = teco_view_save(teco_qreg_view, filename, error); @@ -503,15 +503,6 @@ teco_ring_undo_close(void) undo__teco_ring_remove_buffer(teco_ring_current); } -void -teco_ring_set_scintilla_undo(gboolean state) -{ - for (teco_tailq_entry_t *cur = teco_ring_head.first; cur != NULL; cur = cur->next) { - teco_buffer_t *buffer = (teco_buffer_t *)cur; - teco_view_set_scintilla_undo(buffer->view, state); - } -} - gboolean teco_ring_sync_lsp(GError **error) { @@ -783,7 +774,7 @@ teco_state_read_file_done(teco_machine_main_t *ctx, teco_string_t str, GError ** teco_ring_dirtify(); if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_UNDO, 0, 0); + undo__teco_interface_ssm(SCI_DELETERANGE, from, to-from); } return &teco_state_start; @@ -121,8 +121,6 @@ teco_ring_undo_edit(void) gboolean teco_ring_close(teco_buffer_t *buffer, GError **error); void teco_ring_undo_close(void); -void teco_ring_set_scintilla_undo(gboolean state); - gboolean teco_ring_sync_lsp(GError **error); void teco_ring_cleanup(void); diff --git a/src/search.c b/src/search.c index 2b2a696..31a551e 100644 --- a/src/search.c +++ b/src/search.c @@ -1353,7 +1353,6 @@ teco_state_search_kill_done(teco_machine_main_t *ctx, teco_string_t str, GError sptr_t pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0); - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); if (teco_search_parameters.pos < pos) { /* kill forwards */ sptr_t anchor = teco_interface_ssm(SCI_GETANCHOR, 0, 0); @@ -1361,17 +1360,13 @@ teco_state_search_kill_done(teco_machine_main_t *ctx, teco_string_t str, GError teco_interface_bytes2glyphs_absdot(teco_search_parameters.pos); if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_GOTOPOS, pos, 0); + teco_undo_interface_insert(teco_search_parameters.pos, + anchor - teco_search_parameters.pos); teco_interface_ssm(SCI_GOTOPOS, anchor, 0); teco_interface_ssm(SCI_DELETERANGE, teco_search_parameters.pos, anchor - teco_search_parameters.pos); - /* NOTE: An undo action is not always created. */ - if (teco_current_doc_must_undo() && - teco_search_parameters.pos != anchor) - undo__teco_interface_ssm(SCI_UNDO, 0, 0); - /* fix up ranges (^Y) */ for (guint i = 0; i < teco_ranges_count; i++) { teco_ranges[i].from -= len_glyphs; @@ -1384,14 +1379,10 @@ teco_state_search_kill_done(teco_machine_main_t *ctx, teco_string_t str, GError /* kill backwards */ teco_current_doc_set_dot(teco_interface_bytes2glyphs_absdot(pos)); + if (teco_current_doc_must_undo()) + teco_undo_interface_insert(pos, teco_search_parameters.pos - pos); teco_interface_ssm(SCI_DELETERANGE, pos, teco_search_parameters.pos - pos); - - /* NOTE: An undo action is not always created. */ - if (teco_current_doc_must_undo() && - teco_search_parameters.pos != pos) - undo__teco_interface_ssm(SCI_UNDO, 0, 0); } - teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); teco_ring_dirtify(); return &teco_state_start; @@ -1438,13 +1429,13 @@ teco_state_search_delete_done(teco_machine_main_t *ctx, teco_string_t str, GErro sptr_t anchor = teco_interface_ssm(SCI_GETANCHOR, 0, 0); teco_current_doc_set_dot(teco_interface_bytes2glyphs_absdot(anchor)); - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); + if (teco_current_doc_must_undo()) { + gsize start = teco_interface_ssm(SCI_GETSELECTIONSTART, 0, 0); + teco_undo_interface_insert(start, teco_interface_ssm(SCI_GETSELECTIONEND, 0, 0) - start); + } + teco_interface_ssm(SCI_REPLACESEL, 0, (sptr_t)""); - 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 &teco_state_start; diff --git a/src/spawn.c b/src/spawn.c index a4bf381..933d8f4 100644 --- a/src/spawn.c +++ b/src/spawn.c @@ -422,10 +422,16 @@ teco_state_execute_done(teco_machine_main_t *ctx, teco_string_t str, GError **er teco_interface_ssm(SCI_GOTOPOS, teco_spawn_ctx.to, 0); } - teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); teco_spawn_ctx.start = teco_spawn_ctx.from; g_main_loop_run(teco_spawn_ctx.mainloop); if (!teco_spawn_ctx.register_argument) { + if (teco_current_doc_must_undo()) { + undo__teco_interface_ssm(SCI_DELETERANGE, teco_spawn_ctx.to, + teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0)-teco_spawn_ctx.to); + teco_undo_interface_insert(teco_spawn_ctx.from, + teco_spawn_ctx.to - teco_spawn_ctx.from); + } + teco_interface_ssm(SCI_DELETERANGE, teco_spawn_ctx.from, teco_spawn_ctx.to - teco_spawn_ctx.from); @@ -437,7 +443,6 @@ teco_state_execute_done(teco_machine_main_t *ctx, teco_string_t str, GError **er teco_current_doc_set_dot(to); } - teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); if (teco_spawn_ctx.register_argument) { if (teco_spawn_ctx.stdout_reader.eol_style >= 0) { @@ -446,9 +451,6 @@ teco_state_execute_done(teco_machine_main_t *ctx, teco_string_t str, GError **er teco_spawn_ctx.stdout_reader.eol_style); } } else if (teco_spawn_ctx.from != teco_spawn_ctx.to || teco_spawn_ctx.text_added) { - /* undo action has only been created if it changed anything */ - if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_UNDO, 0, 0); teco_ring_dirtify(); } @@ -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) { @@ -44,14 +44,6 @@ void undo__teco_view_ssm(teco_view_t *, unsigned int, uptr_t, sptr_t); void teco_view_set_representations(teco_view_t *ctx); -/** @memberof teco_view_t */ -static inline void -teco_view_set_scintilla_undo(teco_view_t *ctx, gboolean state) -{ - teco_view_ssm(ctx, SCI_EMPTYUNDOBUFFER, 0, 0); - teco_view_ssm(ctx, SCI_SETUNDOCOLLECTION, state, 0); -} - gboolean teco_view_load_from_channel(teco_view_t *ctx, GIOChannel *channel, gboolean clear, GError **error); gboolean teco_view_load_from_file(teco_view_t *ctx, const gchar *filename, @@ -92,4 +84,6 @@ teco_int_t teco_view_bytes2glyphs_rel(teco_view_t *ctx, teco_int_t pos_glyphs, teco_int_t teco_view_get_character(teco_view_t *ctx, gsize pos, gsize len); +void teco_undo_view_insert(teco_view_t *view, gsize pos, gsize len); + void teco_view_process_notify(teco_view_t *ctx, const SCNotification *notify); |
