aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2021-10-11 08:51:02 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2021-10-11 08:51:02 +0300
commit8ef010da59743fcc4927c790f585ba414ec7b129 (patch)
tree88b31b9017abc34d0f94209a997413a22788ef95
parent8baa1b3ebe163de3a55696e50d49f160529473b3 (diff)
downloadsciteco-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.c29
-rw-r--r--src/doc.c6
-rw-r--r--src/glob.c2
-rw-r--r--src/help.c4
-rw-r--r--src/interface-curses/interface.c10
-rw-r--r--src/interface-gtk/interface.c10
-rw-r--r--src/qreg-commands.c1
-rw-r--r--src/search.c22
-rw-r--r--src/spawn.c5
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();
diff --git a/src/doc.c b/src/doc.c
index 9485f13..832eb90 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -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,
diff --git a/src/glob.c b/src/glob.c
index f6810c2..2f99a99 100644
--- a/src/glob.c
+++ b/src/glob.c
@@ -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);
}
diff --git a/src/help.c b/src/help.c
index fe6df1d..6f6f454 100644
--- a/src/help.c
+++ b/src/help.c
@@ -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();
}