home · contact · privacy
Fix off-by-one, too-early-enabling scroll calculations.
authorChristian Heller <c.heller@plomlompom.de>
Tue, 21 Oct 2025 00:57:28 +0000 (02:57 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Tue, 21 Oct 2025 00:57:28 +0000 (02:57 +0200)
src/ircplom/tui_base.py
src/tests/tui_draw.test

index fca16f01632c63bb72839a99401e05ae0bcbefc0..e57f6989ef4e2ead81fc2bae64508f05fdb0666d 100644 (file)
@@ -115,21 +115,21 @@ class _ScrollableWidget(_Widget):
 
 
 class _HistoryWidget(_ScrollableWidget):
-    _history_idx_neg = -1
-    _wrapped_idx_neg: int = -1
-    _history_offset: int = 0
-    _UNSET_HISTORY_IDX_POS: int = -1
+    _y_pgscroll: int
+    _UNSET_IDX_NEG: int = 0
+    _UNSET_IDX_POS: int = -1
     _COMPARAND_HISTORY_IDX_POS: int = -2
     _BOOKMARK_HISTORY_IDX_POS: int = -3
     _PADDING_HISTORY_IDX_POS: int = -4
-    _newest_read_history_idx_pos: int
-    _y_pgscroll: int
 
     def __init__(self, wrap: Callable[[str], list[str]], **kwargs) -> None:
         super().__init__(**kwargs)
         self._wrap = wrap
         self._wrapped: list[tuple[int, str]] = []
-        self._newest_read_history_idx_pos = self._UNSET_HISTORY_IDX_POS
+        self._newest_read_history_idx_pos = self._UNSET_IDX_POS
+        self._history_offset = 0
+        self._history_idx_neg = self._UNSET_IDX_NEG
+        self._wrapped_idx_neg = self._UNSET_IDX_NEG
 
     def _add_wrapped(self, history_idx_pos: int, line: str) -> int:
         wrapped_lines = self._wrap(line)
@@ -151,7 +151,7 @@ class _HistoryWidget(_ScrollableWidget):
             # ensure that of the full line identified by ._history_idx_neg,
             # ._wrapped_idx_neg point to the lowest of its wrap parts
             self._wrapped_idx_neg = (
-                -1 if (not self._wrapped)
+                self._UNSET_IDX_NEG if (not self._wrapped)
                 else (-len(self._wrapped)
                       + self._last_wrapped_idx_pos_for_hist_idx_pos(
                           self._len_full_history + max(self._history_idx_neg,
@@ -161,11 +161,11 @@ class _HistoryWidget(_ScrollableWidget):
     def append(self, to_append: str) -> None:
         super().append(to_append)
         self.taint()
-        if self._history_idx_neg < -1:
+        if not self._UNSET_IDX_NEG != self._history_idx_neg >= -1:
             self._history_idx_neg -= 1
         if self._drawable:
             n_wrapped = self._add_wrapped(len(self._history) - 1, to_append)
-            if self._wrapped_idx_neg < -1:
+            if not self._UNSET_IDX_NEG != self._wrapped_idx_neg >= -1:
                 self._wrapped_idx_neg -= n_wrapped
         if len(self._history) > _LOG_MAX_LEN:
             self._history = self._history[1:]
@@ -201,7 +201,7 @@ class _HistoryWidget(_ScrollableWidget):
             to_write_w_attrs += [(attrs, line)]
 
         if add_scroll_info:
-            scroll_info = f'vvv [{(-1) * self._history_idx_neg}] '
+            scroll_info = f'vvv [{(-1) * self._history_idx_neg - 1}] '
             scroll_info += 'v' * (self._sizes.x - len(scroll_info))
             to_write_w_attrs += [(['reverse'], scroll_info)]
 
@@ -256,7 +256,7 @@ class _HistoryWidget(_ScrollableWidget):
     def _scroll(self, up: bool = True) -> None:
         super()._scroll(up)
         if self._drawable and self._wrapped:
-            if up:
+            if up and len(self._wrapped) > 2:
                 self._wrapped_idx_neg = max(
                         -len(self._wrapped),
                         self._wrapped_idx_neg - self._y_pgscroll)
index 38a5df76c10a7dfb99ce6f4b75fde382d97f236e..5abf93f7297ae7e2b837b1f5bffe8dd0b8bc80b2 100644 (file)
@@ -32,9 +32,16 @@ line 23 on_black,bright_white,reverse §§ §
 > 
 repeat empty-init
 
+# check scrolling on empty history does nothing
+> /window.history.scroll up
+repeat empty-init
+> /window.history.scroll down
+repeat empty-init
+
 # non-empty command input starts log at bottom, with date above it
 > foo
 log 0 #!. invalid prompt command: not prefixed by /
+| with-only-2-lines-history-in
 repeat lines-empty-16 +0
 repeat lines-empty-4 +16
 | history-lines-0:0:2-in
@@ -44,44 +51,57 @@ line 20 on_black,bright_white 20§§-§§-§§ §§
 line 21 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: not prefixed by / §§
 | history-lines-0:0:2-out
 repeat status-prompt-empty
+| with-only-2-lines-history-out
+
+# check scrolling on history merely 2 lines long won't do anything either
+> /window.history.scroll up
+repeat with-only-2-lines-history
+> /window.history.scroll down
+repeat with-only-2-lines-history
 
 # further inputs grow log upwards
 > /foo
 log 0 #!. invalid prompt command: /foo unknown
-> /bar
-log 0 #!. invalid prompt command: /bar unknown
-| before-1st-scroll-in
+| before-first-scroll-in
 repeat lines-empty-16 +0
 repeat lines-empty-2 +16
-| history-lines-0:0:4-in
-repeat history-lines-0:0:2 +18
-| history-lines-0:2:4-in
-line 20 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /foo unknown §§
-line 21 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /bar unknown §§
-| history-lines-0:2:4-out
-| history-lines-0:0:4-out
+repeat lines-empty-1 +18
+repeat history-lines-0:0:2 +19
+| history-lines-0:2:3-in
+line 21 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /foo unknown §§
+| history-lines-0:2:3-out
 repeat status-prompt-empty
-| before-1st-scroll-out
+| before-first-scroll-out
 
-# check scrolling up on short history
+# check scrolling up does something on history 3 lines long
 > /window.history.scroll up
-| after-1st-scroll-in
 | topmost-scroll-in
 repeat lines-empty-16 +0
 repeat lines-empty-4 +16
 repeat history-lines-0:0:1 +20
 | topmost-scroll-out
-line 21 on_black,bright_white,reverse vvv [4] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [2] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-empty
-| after-1st-scroll-out
 
-# check scrolling down on short history
+# check scrolling down on 3-lines history
 > /window.history.scroll down
-repeat before-1st-scroll
+repeat before-first-scroll
+
+> /bar
+log 0 #!. invalid prompt command: /bar unknown
+| history-lines-0:0:4-in
+repeat history-lines-0:0:2 +18
+| history-lines-0:2:4-in
+repeat history-lines-0:2:3 +20
+line 21 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /bar unknown §§
+| history-lines-0:2:4-out
+| history-lines-0:0:4-out
 
 # check history growing below up-scroll
 > /window.history.scroll up
-repeat after-1st-scroll
+repeat topmost-scroll +0
+line 21 on_black,bright_white,reverse vvv [3] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+repeat status-prompt-empty
 > /help
 log 0 #.. commands available in this window:
 log 0 #..   /connect HOST_PORT [NICKNAME_PW] [REALNAME_USERNAME]
@@ -97,7 +117,7 @@ log 0 #..   /window.prompt.move_cursor DIRECTION
 log 0 #..   /window.prompt.scroll DIRECTION
 | before-scrolldown-not-to-bottom-in
 repeat topmost-scroll
-line 21 on_black,bright_white,reverse vvv [16] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [15] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-empty
 | before-scrolldown-not-to-bottom-out
 
@@ -129,7 +149,7 @@ line 19 on_black,bright_cyan #.. §§:§§:§§   /window TOWARDS§§
 line 20 on_black,bright_cyan #.. §§:§§:§§   /window.history.scroll DIRECTION§§
 | history-lines-0:11:12-out
 | history-lines-0:8:12-out
-line 21 on_black,bright_white,reverse vvv [5] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [4] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-empty
 | after-scrolldown-not-to-bottom-out
 
@@ -200,13 +220,17 @@ line 21 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /7 u
 repeat status-prompt-empty
 | at-bottom-before-wrapped-out
 
+# check scroll-down even with long history does nothing
+> /window.history.scroll down
+repeat at-bottom-before-wrapped
+
 # quick look one scroll up to check single-scroll increase of below-scroll count (when up-scroll not limited, and all lines un-wrapped)
 > /window.history.scroll up
 repeat lines-empty-8
 repeat history-lines-0:0:8 +8
 repeat history-lines-0:8:12 +16
 repeat history-lines-0:12:13 +20
-line 21 on_black,bright_white,reverse vvv [12] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [11] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-empty
 > /window.history.scroll down
 repeat at-bottom-before-wrapped
@@ -241,7 +265,7 @@ repeat lines-empty-4 +0
 repeat lines-empty-1 +4
 repeat history-lines-0:0:16 +5
 | scrollup-after-wrapped-out
-line 21 on_black,bright_white,reverse vvv [11] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [10] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-empty
 
 # check scroll-down fully reversible even if over wrapped
@@ -249,14 +273,14 @@ repeat status-prompt-empty
 repeat at-bottom-after-wrapped
 > /window.history.scroll up
 repeat scrollup-after-wrapped
-line 21 on_black,bright_white,reverse vvv [11] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [10] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-empty
 
 # check wrapped input only increases below-scroll count by one 
 > /bar_0123456789_0123456789_012345678
 log 0 #!. invalid prompt command: /bar_0123456789_0123456789_012345678 unknown
 repeat scrollup-after-wrapped
-line 21 on_black,bright_white,reverse vvv [12] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [11] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-empty
 
 # check scroll-down over wrapped will snap down to bottom of wrapped
@@ -266,23 +290,23 @@ repeat history-lines-0:8:16 +2
 repeat history-lines-0:16:24 +10
 repeat history-lines-0:24:26 +18
 repeat history-lines-0:26:27 +20
-line 21 on_black,bright_white,reverse vvv [2] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [1] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-empty
 
 # # check scrolls-up over longer history until top
 > /window.history.scroll up
 repeat scrollup-after-wrapped
-line 21 on_black,bright_white,reverse vvv [12] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [11] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-empty
 > /window.history.scroll up
 repeat lines-empty-16 +0
 repeat history-lines-0:0:4 +16
 repeat history-lines-0:4:5 +20
-line 21 on_black,bright_white,reverse vvv [23] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [22] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-empty
 > /window.history.scroll up
 repeat topmost-scroll
-line 21 on_black,bright_white,reverse vvv [27] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [26] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-empty
 
 # check that triggering creation of new window with new lines adds it to status, with unread-lines count
@@ -308,7 +332,7 @@ log 1 >.. CAP LS :302
 log 1 >.. USER baz 0 * :bar
 log 1 >.. NICK :foo
 repeat topmost-scroll
-line 21 on_black,bright_white,reverse vvv [27] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [26] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 line 22 on_black,bright_white :start)==========================================================([(0:1)] (1:19)§§
 repeat prompt-empty
 
@@ -367,7 +391,7 @@ repeat prompt-empty
 # check switch-back to window 0, retaining clearing of window 1's unread-lines count
 > /window 0
 repeat topmost-scroll
-line 21 on_black,bright_white,reverse vvv [27] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [26] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-after-first-return
 | status-prompt-after-first-return-in
 line 22 on_black,bright_white :start)===============================================================([(0:1)] 1§§
@@ -380,7 +404,7 @@ repeat lines-empty-8 +0
 repeat lines-empty-1 +8
 repeat history-lines-0:0:8 +9
 repeat history-lines-0:8:12 +17
-line 21 on_black,bright_white,reverse vvv [16] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [15] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-after-first-return
 > /window.history.scroll down
 | before-first-sight-of-bookmark-in
@@ -390,7 +414,7 @@ repeat history-lines-0:8:16 +6
 repeat history-lines-0:16:20 +14
 repeat history-lines-0:20:22 +18
 repeat history-lines-0:22:23 +20
-line 21 on_black,bright_white,reverse vvv [5] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [4] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-after-first-return
 | before-first-sight-of-bookmark-out
 > /window.history.scroll down
@@ -417,7 +441,7 @@ repeat lines-empty-2 +0
 repeat history-lines-0:0:16 +2
 repeat history-lines-0:16:18 +18
 repeat history-lines-0:18:19 +20
-line 21 on_black,bright_white,reverse vvv [9] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [8] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-after-first-return
 > /window.history.scroll down
 repeat first-sight-of-bookmark
@@ -513,7 +537,7 @@ repeat history-lines-1:8:12 +14
 repeat history-lines-1:12:14 +18
 repeat history-lines-1:14:15 +20
 | early-win1-upscroll-out
-line 21 on_black,bright_white,reverse vvv [11] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [10] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-both-empty
 > /window.history.scroll down
 repeat history-lines-1:5:6 +0
@@ -525,7 +549,7 @@ repeat bookmark +14
 repeat history-lines-1:19:20 +15
 repeat history-lines-1:20:24 +16
 repeat history-lines-1:24:25 +20
-line 21 on_black,bright_white,reverse vvv [3] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [2] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-both-empty
 
 # check that with new lines left unread, switch away and back into window moves bookmark below newest read line, counts unread lines in status
@@ -556,7 +580,7 @@ repeat history-lines-1:20:24 +15
 repeat history-lines-1:24:25 +19
 repeat bookmark +20
 | keep-bookmark-on-outside-growth-test-out
-line 21 on_black,bright_white,reverse vvv [3] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [2] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 line 22 on_black,bright_white foo.bar.baz:debug)====================================================(0 [(1:2)]§§
 repeat prompt-empty
 
@@ -569,7 +593,7 @@ line 22 on_black,bright_white :start)===========================================
 repeat prompt-empty
 > /window 1
 repeat keep-bookmark-on-outside-growth-test
-line 21 on_black,bright_white,reverse vvv [5] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [4] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 | status-prompt-on-win1-4-unread-in
 line 22 on_black,bright_white foo.bar.baz:debug)====================================================(0 [(1:4)]§§
 repeat prompt-empty
@@ -578,7 +602,7 @@ repeat prompt-empty
 # check same applies when leaving affected window with bookmark out-of-sight
 > /window.history.scroll up
 repeat early-win1-upscroll
-line 21 on_black,bright_white,reverse vvv [13] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [12] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-on-win1-4-unread
 > /window 0
 loggedservermsg 0 1 <.. PING :baz
@@ -588,7 +612,7 @@ line 22 on_black,bright_white :start)===========================================
 repeat prompt-empty
 > /window 1
 repeat early-win1-upscroll
-line 21 on_black,bright_white,reverse vvv [15] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [14] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 line 22 on_black,bright_white foo.bar.baz:debug)====================================================(0 [(1:6)]§§
 repeat prompt-empty
 > /window.history.scroll down
@@ -598,7 +622,7 @@ repeat history-lines-1:8:16 +3
 repeat history-lines-1:16:24 +11
 repeat history-lines-1:24:25 +19
 repeat bookmark +20
-line 21 on_black,bright_white,reverse vvv [7] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
+line 21 on_black,bright_white,reverse vvv [6] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 line 22 on_black,bright_white foo.bar.baz:debug)====================================================(0 [(1:6)]§§
 repeat prompt-empty
 > /window.history.scroll down