aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/interface-curses
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2025-04-15 03:43:53 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2025-04-15 03:43:53 +0300
commit29fe0a121d967b7bfbe487e11fd877df13512bf7 (patch)
tree000f925440fa1ddd181587b565d29d8f9b3839f8 /src/interface-curses
parent9b3a91e493d6b708709f49f2324f83de1ae6aec6 (diff)
downloadsciteco-29fe0a121d967b7bfbe487e11fd877df13512bf7.tar.gz
try hard to preserve the vertical scrolling position when auto-scrolling dot
* There are cases, especially where the entire buffer is piped through some external process or when removing and reinserting large parts of the buffer, that dot changes very little, but the vertical scrolling position gets resets. This is especially noticable with the macro @^U{[: HECcat$ ]:}, but also with M#cf (clang-format wrapper from "Useful macros"). * We now try to preserve the vertical position ("first visible line") before scrolling caret.
Diffstat (limited to 'src/interface-curses')
-rw-r--r--src/interface-curses/interface.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c
index 05d2b42..e9099ce 100644
--- a/src/interface-curses/interface.c
+++ b/src/interface-curses/interface.c
@@ -1999,6 +1999,9 @@ 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_vpos = teco_interface_ssm(SCI_GETFIRSTVISIBLELINE, 0, 0);
+
switch (key) {
case ERR:
/* shouldn't really happen */
@@ -2120,15 +2123,24 @@ 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.
+ * Instead we do it only once after almost every keypress.
+ * If possible, the vertical scrolling position is preserved, which helps
+ * for instance if the buffer contents are deleted and restored later on.
*
* 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 NCURSES_MOUSE_VERSION >= 2
- if (key != KEY_MOUSE)
+ if (key == KEY_MOUSE) {
+ teco_interface_refresh();
+ return;
+ }
#endif
- teco_interface_ssm(SCI_SCROLLCARET, 0, 0);
+
+ if (teco_interface_current_view == last_view)
+ teco_interface_ssm(SCI_SETFIRSTVISIBLELINE, last_vpos, 0);
+ teco_interface_ssm(SCI_SCROLLCARET, 0, 0);
+
teco_interface_refresh();
}