aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2025-04-04 03:36:17 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2025-04-04 03:53:07 +0300
commitd2f759a1d4c8a42db73ac62cb8317847a1b40249 (patch)
tree780f2fe82f56d6d35409e9fe79b2402282a6df6e
parentb391858790d19a5e91efc824a3329350bc3928d9 (diff)
downloadsciteco-d2f759a1d4c8a42db73ac62cb8317847a1b40249.tar.gz
scroll caret __almost__ always automatically after key presses
* The old heuristics - scroll if dot changes after key press - turned out to be too simplistic. They broke the clang-format macro (M#cf), which left the view at the top of the document since the entire document is temporarily erased. Other simplified examples of this bug would be: @^Um{[: HECcat$ ]:} Mm Or even: @^Um{[: H@X.aG.a ]:} Mm * Actually, the heuristics could be tricked even without deleting any significant amount of text from the buffer. The following test case replaces the previous character with a linefeed in a single key press: @^Um{-DI^J$} Mm If executed on the last visible line, dot wouldn't be scrolled into the view since it did not change. * At the same time, we'd like to keep the existing mouse scroll behavior from fnkeys.tes, which is allowed to scroll dot outside of the visible area. Therefore, dot is scrolled into view always, except after mouse events. You may have to call SCI_SCROLLCARET manually in the ^KMOUSE macro, which is arguably not always straight forward. * Some macros like M#cf may still leave the vertical scrolling position in unexpected positions. This could either be fixed by eradicating all remaining automatic scrolling from Scintilla or by explicitly restoring the vertical position from the macro (FIXME). * This was broken since the introduction of mouse support, so it wasn't in v2.3.0.
-rw-r--r--doc/sciteco.7.template4
-rw-r--r--lib/fnkeys.tes4
-rw-r--r--src/interface-curses/interface.c11
-rw-r--r--src/interface-gtk/interface.c6
4 files changed, 16 insertions, 9 deletions
diff --git a/doc/sciteco.7.template b/doc/sciteco.7.template
index 2a97c02..d5fc4af 100644
--- a/doc/sciteco.7.template
+++ b/doc/sciteco.7.template
@@ -308,6 +308,10 @@ This will not be delivered on Curses unless bit 7 (64) is set in the
You can use \fBEJ\fP with negative keys to retrieve
the event type, mouse coordinates and other information
about the last mouse event.
+Dot is \fInot\fP automatically scrolled into the view when processing
+mouse events, so you can customize scrolling and even have dot leaving the
+visible area.
+You can manually scroll dot into the view by calling \fBSCI_SCROLLCARET\fP.
.TP
.BI ^K x
Any other key with printable representation and all control codes
diff --git a/lib/fnkeys.tes b/lib/fnkeys.tes
index 922548b..6c3b833 100644
--- a/lib/fnkeys.tes
+++ b/lib/fnkeys.tes
@@ -179,14 +179,14 @@
-4EJ&2"=
-4EJ&1"=-1|-2',0ESLINESCROLL
|
- ESZOOMIN
+ ESZOOMIN ESSCROLLCARET
'
{-9D}
!scrolldown!
-4EJ&2"=
-4EJ&1"=1|2',0ESLINESCROLL
|
- ESZOOMOUT
+ ESZOOMOUT ESSCROLLCARET
'
{-9D}
}
diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c
index 75ba036..031ba61 100644
--- a/src/interface-curses/interface.c
+++ b/src/interface-curses/interface.c
@@ -1968,9 +1968,6 @@ teco_interface_event_loop_iter(void)
? teco_interface_blocking_getch()
: GPOINTER_TO_INT(g_queue_pop_head(teco_interface.input_queue));
- const teco_view_t *last_view = teco_interface_current_view;
- sptr_t last_pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0);
-
switch (key) {
case ERR:
/* shouldn't really happen */
@@ -2093,9 +2090,13 @@ teco_interface_event_loop_iter(void)
* Scintilla has been patched to avoid any automatic scrolling since that
* has been benchmarked to be a very costly operation.
* Instead we do it only once after every keypress.
+ *
+ * The only exception is mouse events, so you can scroll the view manually
+ * in the ^KMOUSE macro, allowing dot to be outside of the view.
*/
- if (teco_interface_current_view != last_view ||
- last_pos != teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0))
+#if NCURSES_MOUSE_VERSION >= 2
+ if (key != KEY_MOUSE)
+#endif
teco_interface_ssm(SCI_SCROLLCARET, 0, 0);
teco_interface_refresh();
}
diff --git a/src/interface-gtk/interface.c b/src/interface-gtk/interface.c
index 7f58c45..25f4ccd 100644
--- a/src/interface-gtk/interface.c
+++ b/src/interface-gtk/interface.c
@@ -1383,7 +1383,6 @@ teco_interface_input_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data)
gdk_window_freeze_updates(top_window);
const teco_view_t *last_view = teco_interface_current_view;
- sptr_t last_pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0);
teco_interrupted = FALSE;
switch (event->type) {
@@ -1409,8 +1408,11 @@ teco_interface_input_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data)
* Scintilla has been patched to avoid any automatic scrolling since that
* has been benchmarked to be a very costly operation.
* Instead we do it only once after every keypress.
+ *
+ * The only exception is mouse events, so you can scroll the view manually
+ * in the ^KMOUSE macro, allowing dot to be outside of the view.
*/
- if (last_pos != teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0))
+ if (event->type == GDK_KEY_PRESS)
teco_interface_ssm(SCI_SCROLLCARET, 0, 0);
gdk_window_thaw_updates(top_window);