diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2021-10-11 08:51:02 +0300 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2021-10-11 08:51:02 +0300 |
commit | 8ef010da59743fcc4927c790f585ba414ec7b129 (patch) | |
tree | 88b31b9017abc34d0f94209a997413a22788ef95 | |
parent | 8baa1b3ebe163de3a55696e50d49f160529473b3 (diff) | |
download | sciteco-8ef010da59743fcc4927c790f585ba414ec7b129.tar.gz |
optimized caret scrolling: this is a costly operation and is now done only once per keypress
* Esp. costly since Scintilla 5.
* We now avoid any Scintilla message that automatically scrolls the caret (makes the
caret visible) and instead call SCI_SCROLLCARET only once after every keypress in the
interface implementation.
* From nowon, use
* SCI_SETEMPTYSELECTION instead of SCI_GOTOPOS
* SCI_SETEMPTYSELECTION(SCI_POSITIONFROMLINE(...)) instead of SCI_GOTOLINE
* SCI_SETSELECTIONSTART and SCI_SETSELECTIONEND instead of SCI_SETSEL
* With these optimizations we are significantly faster than before
the Scintilla upgrade (6e67f5a682ff46d69888fec61b94bf45cec46721).
It is now even safe to execute the Gtk test suite during CI.
-rw-r--r-- | src/core-commands.c | 29 | ||||
-rw-r--r-- | src/doc.c | 6 | ||||
-rw-r--r-- | src/glob.c | 2 | ||||
-rw-r--r-- | src/help.c | 4 | ||||
-rw-r--r-- | src/interface-curses/interface.c | 10 | ||||
-rw-r--r-- | src/interface-gtk/interface.c | 10 | ||||
-rw-r--r-- | src/qreg-commands.c | 1 | ||||
-rw-r--r-- | src/search.c | 22 | ||||
-rw-r--r-- | src/spawn.c | 5 |
9 files changed, 54 insertions, 35 deletions
diff --git a/src/core-commands.c b/src/core-commands.c index 0db0328..99b37bf 100644 --- a/src/core-commands.c +++ b/src/core-commands.c @@ -196,7 +196,6 @@ teco_state_start_backslash(teco_machine_main_t *ctx, GError **error) gchar *str = teco_expressions_format(buffer, value); teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); teco_interface_ssm(SCI_ADDTEXT, strlen(str), (sptr_t)str); - teco_interface_ssm(SCI_SCROLLCARET, 0, 0); teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); teco_ring_dirtify(); @@ -459,7 +458,6 @@ teco_state_start_cmdline_push(teco_machine_main_t *ctx, GError **error) teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); teco_interface_ssm(SCI_CLEARALL, 0, 0); teco_interface_ssm(SCI_ADDTEXT, teco_cmdline.pc, (sptr_t)teco_cmdline.str.data); - teco_interface_ssm(SCI_SCROLLCARET, 0, 0); teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); /* must always support undo on global register */ @@ -510,9 +508,9 @@ teco_state_start_jump(teco_machine_main_t *ctx, GError **error) if (teco_validate_pos(v)) { if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_GOTOPOS, + undo__teco_interface_ssm(SCI_SETEMPTYSELECTION, teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0), 0); - teco_interface_ssm(SCI_GOTOPOS, v, 0); + teco_interface_ssm(SCI_SETEMPTYSELECTION, v, 0); if (teco_machine_main_eval_colon(ctx)) teco_expressions_push(TECO_SUCCESS); @@ -532,9 +530,9 @@ teco_move_chars(teco_int_t n) if (!teco_validate_pos(pos + n)) return TECO_FAILURE; - teco_interface_ssm(SCI_GOTOPOS, pos + n, 0); + teco_interface_ssm(SCI_SETEMPTYSELECTION, pos + n, 0); if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_GOTOPOS, pos, 0); + undo__teco_interface_ssm(SCI_SETEMPTYSELECTION, pos, 0); return TECO_SUCCESS; } @@ -600,9 +598,11 @@ teco_move_lines(teco_int_t n) if (!teco_validate_line(line)) return TECO_FAILURE; - teco_interface_ssm(SCI_GOTOLINE, line, 0); + /* avoids scrolling caret (expensive operation) */ + teco_interface_ssm(SCI_SETEMPTYSELECTION, + teco_interface_ssm(SCI_POSITIONFROMLINE, line, 0), 0); if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_GOTOPOS, pos, 0); + undo__teco_interface_ssm(SCI_SETEMPTYSELECTION, pos, 0); return TECO_SUCCESS; } @@ -714,11 +714,11 @@ teco_state_start_word(teco_machine_main_t *ctx, GError **error) } if (v < 0) { if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_GOTOPOS, pos, 0); + undo__teco_interface_ssm(SCI_SETEMPTYSELECTION, pos, 0); if (teco_machine_main_eval_colon(ctx)) teco_expressions_push(TECO_SUCCESS); } else { - teco_interface_ssm(SCI_GOTOPOS, pos, 0); + teco_interface_ssm(SCI_SETEMPTYSELECTION, pos, 0); if (!teco_machine_main_eval_colon(ctx)) { teco_error_move_set(error, "W"); return; @@ -766,12 +766,12 @@ teco_delete_words(teco_int_t n) if (n >= 0) { if (size != teco_interface_ssm(SCI_GETLENGTH, 0, 0)) { teco_interface_ssm(SCI_UNDO, 0, 0); - teco_interface_ssm(SCI_GOTOPOS, pos, 0); + teco_interface_ssm(SCI_SETEMPTYSELECTION, pos, 0); } return TECO_FAILURE; } - undo__teco_interface_ssm(SCI_GOTOPOS, pos, 0); + undo__teco_interface_ssm(SCI_SETEMPTYSELECTION, pos, 0); if (teco_current_doc_must_undo()) undo__teco_interface_ssm(SCI_UNDO, 0, 0); teco_ring_dirtify(); @@ -917,7 +917,7 @@ teco_state_start_kill(teco_machine_main_t *ctx, const gchar *cmd, gboolean by_li if (teco_current_doc_must_undo()) { sptr_t pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0); - undo__teco_interface_ssm(SCI_GOTOPOS, pos, 0); + undo__teco_interface_ssm(SCI_SETEMPTYSELECTION, pos, 0); undo__teco_interface_ssm(SCI_UNDO, 0, 0); } @@ -2368,7 +2368,6 @@ teco_state_insert_initial(teco_machine_main_t *ctx, GError **error) for (int i = args; i > 0; i--) if (!teco_expressions_pop_num_calc(NULL, 0, error)) return FALSE; - teco_interface_ssm(SCI_SCROLLCARET, 0, 0); teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); teco_ring_dirtify(); @@ -2385,7 +2384,6 @@ teco_state_insert_process(teco_machine_main_t *ctx, const teco_string_t *str, teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); teco_interface_ssm(SCI_ADDTEXT, new_chars, (sptr_t)(str->data + str->len - new_chars)); - teco_interface_ssm(SCI_SCROLLCARET, 0, 0); teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); teco_ring_dirtify(); @@ -2455,7 +2453,6 @@ teco_state_insert_indent_initial(teco_machine_main_t *ctx, GError **error) memset(spaces, ' ', sizeof(spaces)); teco_interface_ssm(SCI_ADDTEXT, sizeof(spaces), (sptr_t)spaces); } - teco_interface_ssm(SCI_SCROLLCARET, 0, 0); teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); teco_ring_dirtify(); @@ -45,7 +45,8 @@ teco_doc_edit(teco_doc_t *ctx) (sptr_t)teco_doc_get_scintilla(ctx)); teco_view_ssm(teco_qreg_view, SCI_SETFIRSTVISIBLELINE, ctx->first_line, 0); teco_view_ssm(teco_qreg_view, SCI_SETXOFFSET, ctx->xoffset, 0); - teco_view_ssm(teco_qreg_view, SCI_SETSEL, ctx->anchor, (sptr_t)ctx->dot); + teco_view_ssm(teco_qreg_view, SCI_SETSELECTIONSTART, ctx->anchor, 0); + teco_view_ssm(teco_qreg_view, SCI_SETSELECTIONEND, ctx->dot, 0); /* * NOTE: Thanks to a custom Scintilla patch, se representations @@ -64,7 +65,8 @@ teco_doc_undo_edit(teco_doc_t *ctx) */ //undo__teco_view_set_representations(teco_qreg_view); - undo__teco_view_ssm(teco_qreg_view, SCI_SETSEL, ctx->anchor, (sptr_t)ctx->dot); + undo__teco_view_ssm(teco_qreg_view, SCI_SETSELECTIONEND, ctx->dot, 0); + undo__teco_view_ssm(teco_qreg_view, SCI_SETSELECTIONSTART, ctx->anchor, 0); undo__teco_view_ssm(teco_qreg_view, SCI_SETXOFFSET, ctx->xoffset, 0); undo__teco_view_ssm(teco_qreg_view, SCI_SETFIRSTVISIBLELINE, ctx->first_line, 0); undo__teco_view_ssm(teco_qreg_view, SCI_SETDOCPOINTER, 0, @@ -509,7 +509,6 @@ teco_state_glob_filename_done(teco_machine_main_t *ctx, const teco_string_t *str teco_interface_ssm(SCI_ADDTEXT, strlen(filename), (sptr_t)filename); teco_interface_ssm(SCI_ADDTEXT, 1, (sptr_t)"\n"); - teco_interface_ssm(SCI_SCROLLCARET, 0, 0); teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); } @@ -550,7 +549,6 @@ teco_state_glob_filename_done(teco_machine_main_t *ctx, const teco_string_t *str matching = TRUE; } - teco_interface_ssm(SCI_SCROLLCARET, 0, 0); teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); } @@ -307,9 +307,9 @@ teco_state_help_done(teco_machine_main_t *ctx, const teco_string_t *str, GError * multiple topics in the same buffer without * closing it first. */ - undo__teco_interface_ssm(SCI_GOTOPOS, + undo__teco_interface_ssm(SCI_SETEMPTYSELECTION, teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0), 0); - teco_interface_ssm(SCI_GOTOPOS, topic->pos, 0); + teco_interface_ssm(SCI_SETEMPTYSELECTION, topic->pos, 0); return &teco_state_start; } diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c index 825a312..6e6e890 100644 --- a/src/interface-curses/interface.c +++ b/src/interface-curses/interface.c @@ -1582,6 +1582,16 @@ teco_interface_event_loop_iter(void) } /* + * We avoid Scintilla messages that scroll the caret during macro + * execution since it has been benchmarked to be very a very costly operation. + * Instead we do it only once after every keypress. + * + * FIXME: This could be in teco_cmdline_keypress() since it is common among + * all interface implementations. + */ + teco_interface_ssm(SCI_SCROLLCARET, 0, 0); + + /* * Info window is updated very often which is very * costly, especially when using PDC_set_title(), * so we redraw it here, where the overhead does diff --git a/src/interface-gtk/interface.c b/src/interface-gtk/interface.c index 5b9f530..aa63276 100644 --- a/src/interface-gtk/interface.c +++ b/src/interface-gtk/interface.c @@ -880,6 +880,16 @@ teco_interface_handle_key_press(guint keyval, guint state, GError **error) } /* + * We avoid Scintilla messages that scroll the caret during macro + * execution since it has been benchmarked to be very a very costly operation. + * Instead we do it only once after every keypress. + * + * FIXME: This could be in teco_cmdline_keypress() since it is common among + * all interface implementations. + */ + teco_interface_ssm(SCI_SCROLLCARET, 0, 0); + + /* * The styles configured via Scintilla might change * with every keypress. */ diff --git a/src/qreg-commands.c b/src/qreg-commands.c index 35508d7..b505b33 100644 --- a/src/qreg-commands.c +++ b/src/qreg-commands.c @@ -487,7 +487,6 @@ teco_state_getqregstring_got_register(teco_machine_main_t *ctx, teco_qreg_t *qre 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_SCROLLCARET, 0, 0); teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); teco_ring_dirtify(); diff --git a/src/search.c b/src/search.c index 3ccecde..219ddb2 100644 --- a/src/search.c +++ b/src/search.c @@ -541,9 +541,11 @@ teco_do_search(GRegex *re, gint from, gint to, gint *count, GError **error) } } - if (matched_from >= 0 && matched_to >= 0) + if (matched_from >= 0 && matched_to >= 0) { /* match success */ - teco_interface_ssm(SCI_SETSEL, matched_from, matched_to); + teco_interface_ssm(SCI_SETSELECTIONSTART, matched_from, 0); + teco_interface_ssm(SCI_SETSELECTIONEND, matched_to, 0); + } return TRUE; } @@ -554,10 +556,12 @@ teco_state_search_process(teco_machine_main_t *ctx, const teco_string_t *str, gs static const GRegexCompileFlags flags = G_REGEX_CASELESS | G_REGEX_MULTILINE | G_REGEX_DOTALL | G_REGEX_RAW; - if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_SETSEL, - teco_interface_ssm(SCI_GETANCHOR, 0, 0), - teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0)); + if (teco_current_doc_must_undo()) { + undo__teco_interface_ssm(SCI_SETSELECTIONEND, + teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0), 0); + undo__teco_interface_ssm(SCI_SETSELECTIONSTART, + teco_interface_ssm(SCI_GETANCHOR, 0, 0), 0); + } teco_qreg_t *search_reg = teco_qreg_table_find(&teco_qreg_table_globals, "_", 1); g_assert(search_reg != NULL); @@ -648,7 +652,7 @@ teco_state_search_process(teco_machine_main_t *ctx, const teco_string_t *str, gs return TRUE; failure: - teco_interface_ssm(SCI_GOTOPOS, teco_search_parameters.dot, 0); + teco_interface_ssm(SCI_SETEMPTYSELECTION, teco_search_parameters.dot, 0); return TRUE; } @@ -898,8 +902,8 @@ teco_state_search_kill_done(teco_machine_main_t *ctx, const teco_string_t *str, gint anchor = teco_interface_ssm(SCI_GETANCHOR, 0, 0); if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_GOTOPOS, dot, 0); - teco_interface_ssm(SCI_GOTOPOS, anchor, 0); + undo__teco_interface_ssm(SCI_SETEMPTYSELECTION, dot, 0); + teco_interface_ssm(SCI_SETEMPTYSELECTION, anchor, 0); teco_interface_ssm(SCI_DELETERANGE, teco_search_parameters.dot, anchor - teco_search_parameters.dot); diff --git a/src/spawn.c b/src/spawn.c index 085140b..46454ff 100644 --- a/src/spawn.c +++ b/src/spawn.c @@ -296,9 +296,9 @@ teco_state_execute_done(teco_machine_main_t *ctx, const teco_string_t *str, GErr if (!teco_spawn_ctx.register_argument) { if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_GOTOPOS, + undo__teco_interface_ssm(SCI_SETEMPTYSELECTION, teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0), 0); - teco_interface_ssm(SCI_GOTOPOS, teco_spawn_ctx.to, 0); + teco_interface_ssm(SCI_SETEMPTYSELECTION, teco_spawn_ctx.to, 0); } teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); @@ -319,7 +319,6 @@ teco_state_execute_done(teco_machine_main_t *ctx, const teco_string_t *str, GErr /* undo action is only effective if it changed anything */ if (teco_current_doc_must_undo()) undo__teco_interface_ssm(SCI_UNDO, 0, 0); - teco_interface_ssm(SCI_SCROLLCARET, 0, 0); teco_ring_dirtify(); } |