home · contact · privacy
For testing "repeat" directive, start offsets at lowest int in targeted regions'... master
authorChristian Heller <c.heller@plomlompom.de>
Mon, 20 Oct 2025 19:30:35 +0000 (21:30 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Mon, 20 Oct 2025 19:30:35 +0000 (21:30 +0200)
src/ircplom/testing.py
src/tests/test.test
src/tests/tui_draw.test

index f161c71e91a4577f56fcbb8786e018a1c07cf0ba..d5b1aa1fcf2480bda2e72eca50e50fa9e185dc56 100644 (file)
@@ -215,25 +215,43 @@ class _Playbook:
                    anchors: dict[str, int],
                    **__
                    ) -> list[tuple[str, str]]:
-            inserts: list[tuple[str, str]] = []
-            for inserted_t in self._lines_t[int(anchors[args[0]+'-in']):
-                                            int(anchors[args[0]+'-out'])]:
-                insert = inserted_t[1]
-                cmd_name, remains = insert.split(_SEP_0, maxsplit=1)
-                if cmd_name == _MARK_ANCHOR:  # anchors should be unique,
-                    continue                  # so avoid their repittion
-                args_idx = _SIGNATURE_FOR_CMD[cmd_name][1]
-                args_ = list(self._args_for_cmd(cmd_name, remains))
-                if len(args) == 2\
-                        and args_idx is not None\
-                        and len(args_) > args_idx:
-                    args_[args_idx] = _SEP_1.join(
-                            str(int(n) + int(args[1]))
-                            for n in args_[args_idx].split(_SEP_1) if n
-                            ) or ','
-                    insert = _SEP_0.join([cmd_name] + args_)
-                inserts += [(index_str + ':r:' + inserted_t[0], insert)]
-            return inserts
+            candidates = [
+                lt for lt in self._lines_t[int(anchors[args[0]+'-in']):
+                                           int(anchors[args[0]+'-out'])]
+                if not lt[1].startswith(_MARK_ANCHOR)]  # keep anchors unique
+            idx_rep_offset = _SIGNATURE_FOR_CMD[_MARK_REPEAT][1]
+            assert idx_rep_offset is not None
+            if len(args) <= idx_rep_offset:
+                return candidates
+            rep_offset = int(args[idx_rep_offset])
+            lowest_int: Optional[int] = None
+            inserts = []
+            for candidate in candidates:
+                cmd_name, remains = candidate[1].split(_SEP_0, maxsplit=1)
+                cmd_args_idx = _SIGNATURE_FOR_CMD[cmd_name][1]
+                cmd_args: list[str | tuple[int, ...]]\
+                    = list(self._args_for_cmd(cmd_name, remains))
+                if cmd_args_idx is not None and len(cmd_args) > cmd_args_idx:
+                    cmd_arg = cmd_args[cmd_args_idx]
+                    assert isinstance(cmd_arg, str)
+                    vals = tuple(int(n) for n in cmd_arg.split(_SEP_1) if n)
+                    if len(vals) > 0:
+                        lowest_int = min(vals if lowest_int is None
+                                         else (vals + (lowest_int,)))
+                    cmd_args[cmd_args_idx] = vals
+                inserts += [(candidate[0], cmd_name, cmd_args)]
+            line_offset = 0 - (lowest_int or 0)
+            return [
+                (index_str + ':r:' + insert_t[0],
+                 _SEP_0.join(
+                     [insert_t[1]]
+                     + [arg if isinstance(arg, str)
+                        else (_SEP_1.join(str(n + line_offset + rep_offset)
+                                          for n in arg
+                                          ) or ',')
+                        for arg in insert_t[2]]
+                     )
+                 ) for insert_t in inserts]
 
         self._lines_t = [line_t for line_t in self._lines_t
                          if line_t[1]
index d234057fbaf5cc4239dfe047fb104478b59785e2..b24b436e5ec27fe70821063c099015f45fa8849c 100644 (file)
@@ -354,18 +354,18 @@ log 1 $!. not sending, since not in channel
 
 # test setting up second client, but 432 irrecoverably
 > /connect baz.bar.foo ?foo foo:foo
-repeat standard-clears +7
+repeat standard-clears +8
 log 8 $.. hostname set to: [baz.bar.foo]
 log 8 $.. port set to: [-1]
 log 8 $.. nick_wanted set to: [?foo]
 log 8 $.. user_wanted set to: [foo]
 log 8 $.. realname set to: [foo]
-repeat conn +7
+repeat conn +8
 log 8 >.. USER foo 0 * :foo
 log 8 >.. NICK :?foo
 loggedservermsg 1 8 <.. :*.?.net 432 * ?foo :Erroneous nickname
 | disconnect-in
-repeat isupport-clear +7
+repeat isupport-clear +8
 log 8 $.. connection_state set to: []
 log , $.. DISCONNECTED
 | disconnect-out
@@ -373,18 +373,18 @@ log 8 $!. nickname refused for bad format, giving up
 
 # test failing third connection
 > /connect baz.baz.baz baz baz:baz
-repeat standard-clears +8
+repeat standard-clears +9
 log 9 $.. hostname set to: [baz.baz.baz]
 log 9 $.. port set to: [-1]
 log 9 $.. nick_wanted set to: [baz]
 log 9 $.. user_wanted set to: [baz]
 log 9 $.. realname set to: [baz]
-repeat conn +8
+repeat conn +9
 log 9 >.. USER baz 0 * :baz
 log 9 >.. NICK :baz
 servermsg 2 FAKE_IRC_CONN_ABORT_EXCEPTION
 log 9 $.. connection_state set to: [broken: FAKE_IRC_CONN_ABORT_EXCEPTION]
-repeat disconnect +1
+repeat disconnect +9
 log 9 $!. will retry connecting in 1 seconds
 
 # check that (save TUI tests assuming start on window 0, and no 4 yet) on reconnect, all the same effects can be expected
index b240133ed94ea17ed292a804e2282727118686b1..38a5df76c10a7dfb99ce6f4b75fde382d97f236e 100644 (file)
@@ -6,7 +6,7 @@
 | lines-empty-1-in
 line 0 on_black,bright_white §§
 | lines-empty-1-out
-repeat lines-empty-1 1
+repeat lines-empty-1 +1
 | lines-empty-2-out
 repeat lines-empty-1 +2
 repeat lines-empty-1 +3
@@ -35,14 +35,14 @@ repeat empty-init
 # non-empty command input starts log at bottom, with date above it
 > foo
 log 0 #!. invalid prompt command: not prefixed by /
-repeat lines-empty-16
+repeat lines-empty-16 +0
 repeat lines-empty-4 +16
-| history-lines-0:0:2-at-20-in
-| history-lines-0:0:1-at-20-in
+| history-lines-0:0:2-in
+| history-lines-0:0:1-in
 line 20 on_black,bright_white 20§§-§§-§§ §§
-| history-lines-0:0:1-at-20-out
+| history-lines-0:0:1-out
 line 21 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: not prefixed by / §§
-| history-lines-0:0:2-at-20-out
+| history-lines-0:0:2-out
 repeat status-prompt-empty
 
 # further inputs grow log upwards
@@ -51,15 +51,15 @@ log 0 #!. invalid prompt command: /foo unknown
 > /bar
 log 0 #!. invalid prompt command: /bar unknown
 | before-1st-scroll-in
-repeat lines-empty-16
+repeat lines-empty-16 +0
 repeat lines-empty-2 +16
-| history-lines-0:0:4-at-18-in
-repeat history-lines-0:0:2-at-20 -2
-| history-lines-0:2:4-at-20-in
+| 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-at-20-out
-| history-lines-0:0:4-at-18-out
+| history-lines-0:2:4-out
+| history-lines-0:0:4-out
 repeat status-prompt-empty
 | before-1st-scroll-out
 
@@ -67,9 +67,9 @@ repeat status-prompt-empty
 > /window.history.scroll up
 | after-1st-scroll-in
 | topmost-scroll-in
-repeat lines-empty-16
+repeat lines-empty-16 +0
 repeat lines-empty-4 +16
-repeat history-lines-0:0:1-at-20
+repeat history-lines-0:0:1 +20
 | topmost-scroll-out
 line 21 on_black,bright_white,reverse vvv [4] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-empty
@@ -104,31 +104,31 @@ repeat status-prompt-empty
 # check scroll-down on newer history longer than half a screen width does not fully land at bottom
 > /window.history.scroll down
 | after-scrolldown-not-to-bottom-in
-repeat lines-empty-8
+repeat lines-empty-8 +0
 repeat lines-empty-1 +8
-| history-lines-0:0:8-at-9-in
-repeat history-lines-0:0:4-at-18 -9
-| history-lines-0:4:8-at-13-in
-| history-lines-0:4:5-at-13-in
+| history-lines-0:0:8-in
+repeat history-lines-0:0:4 +9
+| history-lines-0:4:8-in
+| history-lines-0:4:5-in
 line 13 on_black,bright_cyan #.. §§:§§:§§ commands available in this window:§§
-| history-lines-0:4:5-at-13-out
-| history-lines-0:5:6-at-14-in
+| history-lines-0:4:5-out
+| history-lines-0:5:6-in
 line 14 on_black,bright_cyan #.. §§:§§:§§   /connect HOST_PORT [NICKNAME_PW] [REALNAME_USERNAME]§§
-| history-lines-0:5:6-at-14-out
-| history-lines-0:6:8-at-15-in
+| history-lines-0:5:6-out
+| history-lines-0:6:8-in
 line 15 on_black,bright_cyan #.. §§:§§:§§   /help§§
 line 16 on_black,bright_cyan #.. §§:§§:§§   /list§§
-| history-lines-0:6:8-at-15-out
-| history-lines-0:4:8-at-13-out
-| history-lines-0:0:8-at-9-out
-| history-lines-0:8:12-at-17-in
+| history-lines-0:6:8-out
+| history-lines-0:4:8-out
+| history-lines-0:0:8-out
+| history-lines-0:8:12-in
 line 17 on_black,bright_cyan #.. §§:§§:§§   /prompt_enter§§
 line 18 on_black,bright_cyan #.. §§:§§:§§   /quit§§
 line 19 on_black,bright_cyan #.. §§:§§:§§   /window TOWARDS§§
-| history-lines-0:11:12-at-20-in
+| history-lines-0:11:12-in
 line 20 on_black,bright_cyan #.. §§:§§:§§   /window.history.scroll DIRECTION§§
-| history-lines-0:11:12-at-20-out
-| history-lines-0:8:12-at-17-out
+| history-lines-0:11:12-out
+| history-lines-0:8:12-out
 line 21 on_black,bright_white,reverse vvv [5] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-empty
 | after-scrolldown-not-to-bottom-out
@@ -141,20 +141,20 @@ repeat after-scrolldown-not-to-bottom
 
 # scroll to bottom, check history still growing up even beyond upper fold
 > /window.history.scroll down
-repeat lines-empty-4
+repeat lines-empty-4 +0
 repeat lines-empty-2 +4
-| history-lines-0:0:16-at-6-in
-repeat history-lines-0:0:8-at-9 -3
-repeat history-lines-0:8:12-at-17 -3
-| history-lines-0:12:16-at-18-in
-| history-lines-0:12:13-at-18-in
+| history-lines-0:0:16-in
+repeat history-lines-0:0:8 +6
+repeat history-lines-0:8:12 +14
+| history-lines-0:12:16-in
+| history-lines-0:12:13-in
 line 18 on_black,bright_cyan #.. §§:§§:§§   /window.paste§§
-| history-lines-0:12:13-at-18-out
+| history-lines-0:12:13-out
 line 19 on_black,bright_cyan #.. §§:§§:§§   /window.prompt.backspace§§
 line 20 on_black,bright_cyan #.. §§:§§:§§   /window.prompt.move_cursor DIRECTION§§
 line 21 on_black,bright_cyan #.. §§:§§:§§   /window.prompt.scroll DIRECTION§§
-| history-lines-0:12:16-at-18-out
-| history-lines-0:0:16-at-6-out
+| history-lines-0:12:16-out
+| history-lines-0:0:16-out
 repeat status-prompt-empty
 > /0
 log 0 #!. invalid prompt command: /0 unknown
@@ -173,39 +173,39 @@ log 0 #!. invalid prompt command: /6 unknown
 > /7
 log 0 #!. invalid prompt command: /7 unknown
 | at-bottom-before-wrapped-in
-repeat history-lines-0:2:4-at-20 -20
-repeat history-lines-0:4:8-at-13 -11
-repeat history-lines-0:8:12-at-17 -11
-repeat history-lines-0:12:16-at-18 -8
-| history-lines-0:16:24-at-14-in
-| history-lines-0:16:20-at-14-in
-| history-lines-0:16:18-at-14-in
+repeat history-lines-0:2:4 +0
+repeat history-lines-0:4:8 +2
+repeat history-lines-0:8:12 +6
+repeat history-lines-0:12:16 +10
+| history-lines-0:16:24-in
+| history-lines-0:16:20-in
+| history-lines-0:16:18-in
 line 14 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /0 unknown§§
 line 15 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /1 unknown§§
-| history-lines-0:16:18-at-14-out
-| history-lines-0:18:19-at-16-in
+| history-lines-0:16:18-out
+| history-lines-0:18:19-in
 line 16 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /2 unknown§§
-| history-lines-0:18:19-at-16-out
+| history-lines-0:18:19-out
 line 17 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /3 unknown§§
-| history-lines-0:16:20-at-14-out
-| history-lines-0:20:22-at-18-in
+| history-lines-0:16:20-out
+| history-lines-0:20:22-in
 line 18 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /4 unknown§§
 line 19 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /5 unknown§§
-| history-lines-0:20:22-at-18-out
-| history-lines-0:22:23-at-20-in
+| history-lines-0:20:22-out
+| history-lines-0:22:23-in
 line 20 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /6 unknown§§
-| history-lines-0:22:23-at-20-out
+| history-lines-0:22:23-out
 line 21 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /7 unknown§§
-| history-lines-0:16:24-at-14-out
+| history-lines-0:16:24-out
 repeat status-prompt-empty
 | at-bottom-before-wrapped-out
 
 # 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-at-9 -1
-repeat history-lines-0:8:12-at-17 -1
-repeat history-lines-0:12:13-at-18 +2
+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§§
 repeat status-prompt-empty
 > /window.history.scroll down
@@ -217,29 +217,29 @@ log 0 #!. invalid prompt command: /foo_0123456789_0123456789_01234567 unknown
 > /foo_0123456789_0123456789_012345678
 log 0 #!. invalid prompt command: /foo_0123456789_0123456789_012345678 unknown
 | at-bottom-after-wrapped-in
-repeat history-lines-0:5:6-at-14 -14
-repeat history-lines-0:6:8-at-15 -14
-| history-lines-0:8:16-at-3-in
-repeat history-lines-0:8:12-at-17 -14
-repeat history-lines-0:12:16-at-18 -11
-| history-lines-0:8:16-at-3-out
-repeat history-lines-0:16:24-at-14 -3
-| history-lines-0:24:26-at-19-in
+repeat history-lines-0:5:6 +0
+repeat history-lines-0:6:8 +1
+| history-lines-0:8:16-in
+repeat history-lines-0:8:12 +3
+repeat history-lines-0:12:16 +7
+| history-lines-0:8:16-out
+repeat history-lines-0:16:24 +11
+| history-lines-0:24:26-in
 line 19 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /foo_0123456789_0123456789_01234567 unknown§§
 line 20 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /foo_0123456789_0123456789_012345678§§
-| history-lines-0:24:26-at-19-out
-| history-lines-0:26:27-at-21-in
+| history-lines-0:24:26-out
+| history-lines-0:26:27-in
 line 21 on_black,bright_red,bold     unknown§§
-| history-lines-0:26:27-at-21-out
+| history-lines-0:26:27-out
 repeat status-prompt-empty
 | at-bottom-after-wrapped-out
 
 # check scroll-up over wrapped moves up less history lines than screen lines
 > /window.history.scroll up
 | scrollup-after-wrapped-in
-repeat lines-empty-4
+repeat lines-empty-4 +0
 repeat lines-empty-1 +4
-repeat history-lines-0:0:16-at-6 -1
+repeat history-lines-0:0:16 +5
 | scrollup-after-wrapped-out
 line 21 on_black,bright_white,reverse vvv [11] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-empty
@@ -261,11 +261,11 @@ repeat status-prompt-empty
 
 # check scroll-down over wrapped will snap down to bottom of wrapped
 > /window.history.scroll down
-repeat history-lines-0:6:8-at-15 -15
-repeat history-lines-0:8:16-at-3 -1
-repeat history-lines-0:16:24-at-14 -4
-repeat history-lines-0:24:26-at-19 -1
-repeat history-lines-0:26:27-at-21 -1
+repeat history-lines-0:6:8 +0
+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§§
 repeat status-prompt-empty
 
@@ -275,9 +275,9 @@ repeat scrollup-after-wrapped
 line 21 on_black,bright_white,reverse vvv [12] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-empty
 > /window.history.scroll up
-repeat lines-empty-16
-repeat history-lines-0:0:4-at-18 -2
-repeat history-lines-0:4:5-at-13 +7
+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§§
 repeat status-prompt-empty
 > /window.history.scroll up
@@ -314,53 +314,53 @@ repeat prompt-empty
 
 # check switch to other window, updates to status line (movement of brackets, clearing of own unread-lines count)
 > /window 1
-repeat lines-empty-2
+repeat lines-empty-2 +0
 repeat lines-empty-1 +2
-| history-lines-1:0:16-at-3-in
-| history-lines-1:0:8-at-3-in
-repeat history-lines-0:0:1-at-20 -17
+| history-lines-1:0:16-in
+| history-lines-1:0:8-in
+repeat history-lines-0:0:1 +3
 line 4 on_black,bright_yellow $.. §§:§§:§§ isupport cleared
 line 5 on_black,bright_yellow $.. §§:§§:§§ isupport:CHANTYPES set to: [#&]
 line 6 on_black,bright_yellow $.. §§:§§:§§ isupport:PREFIX set to: [(ov)@+]
-| history-lines-1:4:8-at-7-in
+| history-lines-1:4:8-in
 line 7 on_black,bright_yellow $.. §§:§§:§§ isupport:USERLEN set to: [10]
-| history-lines-1:5:6-at-8-in
+| history-lines-1:5:6-in
 line 8 on_black,bright_yellow $.. §§:§§:§§ caps cleared
-| history-lines-1:5:6-at-8-out
-| history-lines-1:6:8-at-9-in
+| history-lines-1:5:6-out
+| history-lines-1:6:8-in
 line 9 on_black,bright_yellow $.. §§:§§:§§ users cleared
 line 10 on_black,bright_yellow $.. §§:§§:§§ channels cleared
-| history-lines-1:6:8-at-9-out
-| history-lines-1:4:8-at-7-out
-| history-lines-1:0:8-at-3-out
-| history-lines-1:8:16-at-11-in
-| history-lines-1:8:12-at-11-in
+| history-lines-1:6:8-out
+| history-lines-1:4:8-out
+| history-lines-1:0:8-out
+| history-lines-1:8:16-in
+| history-lines-1:8:12-in
 line 11 on_black,bright_yellow $.. §§:§§:§§ hostname set to: [foo.bar.baz]
 line 12 on_black,bright_yellow $.. §§:§§:§§ port set to: [-1]
-| history-lines-1:10:12-at-13-in
+| history-lines-1:10:12-in
 line 13 on_black,bright_yellow $.. §§:§§:§§ nick_wanted set to: [foo]
 line 14 on_black,bright_yellow $.. §§:§§:§§ user_wanted set to: [baz]
-| history-lines-1:10:12-at-13-out
-| history-lines-1:8:12-at-11-out
-| history-lines-1:12:16-at-15-in
-| history-lines-1:12:14-at-15-in
+| history-lines-1:10:12-out
+| history-lines-1:8:12-out
+| history-lines-1:12:16-in
+| history-lines-1:12:14-in
 line 15 on_black,bright_yellow $.. §§:§§:§§ realname set to: [bar]
 line 16 on_black,bright_yellow $.. §§:§§:§§ port set to: [6697]
-| history-lines-1:12:14-at-15-out
-| history-lines-1:14:15-at-17-in
+| history-lines-1:12:14-out
+| history-lines-1:14:15-in
 line 17 on_black,bright_yellow $.. §§:§§:§§ connection_state set to: [connecting]
-| history-lines-1:14:15-at-17-out
+| history-lines-1:14:15-out
 line 18 on_black,bright_yellow $.. §§:§§:§§ connection_state set to: [connected]
-| history-lines-1:12:16-at-15-out
-| history-lines-1:8:16-at-11-out
-| history-lines-1:0:16-at-3-out
-| history-lines-1:16:18-at-19-in
+| history-lines-1:12:16-out
+| history-lines-1:8:16-out
+| history-lines-1:0:16-out
+| history-lines-1:16:18-in
 line 19 on_black,bright_green >.. §§:§§:§§ CAP LS :302§§
 line 20 on_black,bright_green >.. §§:§§:§§ USER baz 0 * :bar§§
-| history-lines-1:16:18-at-19-out
-| history-lines-1:18:19-at-21-in
+| history-lines-1:16:18-out
+| history-lines-1:18:19-in
 line 21 on_black,bright_green >.. §§:§§:§§ NICK :foo§§
-| history-lines-1:18:19-at-21-out
+| history-lines-1:18:19-out
 line 22 on_black,bright_white foo.bar.baz:debug)====================================================((0:1) [1]§§
 repeat prompt-empty
 
@@ -376,47 +376,47 @@ repeat prompt-empty
 
 # check that on full scroll-down, we now have a bookmark above the newest lines not previously scrolled into
 > /window.history.scroll down
-repeat lines-empty-8
+repeat lines-empty-8 +0
 repeat lines-empty-1 +8
-repeat history-lines-0:0:8-at-9
-repeat history-lines-0:8:12-at-17
+repeat history-lines-0:0:8 +9
+repeat history-lines-0:8:12 +17
 line 21 on_black,bright_white,reverse vvv [16] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv§§
 repeat status-prompt-after-first-return
 > /window.history.scroll down
 | before-first-sight-of-bookmark-in
-repeat history-lines-0:2:4-at-20 -20
-repeat history-lines-0:4:8-at-13 -11
-repeat history-lines-0:8:16-at-3 +3
-repeat history-lines-0:16:20-at-14
-repeat history-lines-0:20:22-at-18
-repeat history-lines-0:22:23-at-20
+repeat history-lines-0:2:4 +0
+repeat history-lines-0:4:8 +2
+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§§
 repeat status-prompt-after-first-return
 | before-first-sight-of-bookmark-out
 > /window.history.scroll down
 | first-sight-of-bookmark-in
-repeat history-lines-0:8:16-at-3 -3
-repeat history-lines-0:16:24-at-14 -6
-repeat history-lines-0:24:26-at-19 -3
-repeat history-lines-0:26:27-at-21 -3
-| bookmark-at-19-in
+repeat history-lines-0:8:16 +0
+repeat history-lines-0:16:24 +8
+repeat history-lines-0:24:26 +16
+repeat history-lines-0:26:27 +18
+| bookmark-in
 line 19 on_black,bright_white --------------------------------------------------------------------------------§§
-| bookmark-at-19-out
-| history-lines-0:27:28-at-20-in
+| bookmark-out
+| history-lines-0:27:28-in
 line 20 on_black,bright_red,bold #!. §§:§§:§§ invalid prompt command: /bar_0123456789_0123456789_012345678§§
-| history-lines-0:27:28-at-20-out
-| history-lines-0:28:29-at-21-in
+| history-lines-0:27:28-out
+| history-lines-0:28:29-in
 line 21 on_black,bright_red,bold     unknown§§
-| history-lines-0:28:29-at-21-out
+| history-lines-0:28:29-out
 repeat status-prompt-after-first-return
 | first-sight-of-bookmark-out
 
 # check that scrolling non-bottom bookmark out of sight, then scrolling it back into view again does not by itself move its position in the log history
 > /window.history.scroll up
-repeat lines-empty-2
-repeat history-lines-0:0:16-at-6 -4
-repeat history-lines-0:16:18-at-14 +4
-repeat history-lines-0:18:19-at-16 +4
+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§§
 repeat status-prompt-after-first-return
 > /window.history.scroll down
@@ -424,11 +424,11 @@ repeat first-sight-of-bookmark
 
 # check that second switch to new window, previously left on bottom of history, establishes bookmark at bottom of log
 > /window 1
-repeat lines-empty-2
-repeat history-lines-1:0:16-at-3 -1
-repeat history-lines-1:16:18-at-19 -1
-repeat history-lines-1:18:19-at-21 -1
-repeat bookmark-at-19 +2
+repeat lines-empty-2 +0
+repeat history-lines-1:0:16 +2
+repeat history-lines-1:16:18 +18
+repeat history-lines-1:18:19 +20
+repeat bookmark +21
 | status-prompt-both-empty-in
 line 22 on_black,bright_white foo.bar.baz:debug)========================================================(0 [1]§§
 repeat prompt-empty
@@ -436,15 +436,15 @@ repeat prompt-empty
 
 # check second switch-back places bookmark at bottom there too, since the newest lines previously succeeding it have now been read by us
 > /window 0
-repeat history-lines-0:8:16-at-3 -3
-repeat history-lines-0:16:24-at-14 -6
-| history-lines-0:24:28-at-16-in
-repeat history-lines-0:24:26-at-19 -3
-repeat history-lines-0:26:27-at-21 -3
-repeat history-lines-0:27:28-at-20 -1
-| history-lines-0:24:28-at-16-out
-repeat history-lines-0:28:29-at-21 -1
-repeat bookmark-at-19 +2
+repeat history-lines-0:8:16 +0
+repeat history-lines-0:16:24 +8
+| history-lines-0:24:28-in
+repeat history-lines-0:24:26 +16
+repeat history-lines-0:26:27 +18
+repeat history-lines-0:27:28 +19
+| history-lines-0:24:28-out
+repeat history-lines-0:28:29 +20
+repeat bookmark +21
 line 22 on_black,bright_white :start)===================================================================([0] 1§§
 repeat prompt-empty
 
@@ -454,19 +454,19 @@ log 0 #.. windows available via /window:
 log 0 #..   0) :start
 log 0 #..   1) foo.bar.baz:debug
 | before-first-server-responses-in
-repeat history-lines-0:11:12-at-20 -20
-repeat history-lines-0:12:16-at-18 -17
-repeat history-lines-0:16:24-at-14 -9
-repeat history-lines-0:24:28-at-16 -3
-repeat history-lines-0:28:29-at-21 -4
-repeat bookmark-at-19 -1
-| history-lines-0:29:30-at-19-in
+repeat history-lines-0:11:12 +0
+repeat history-lines-0:12:16 +1
+repeat history-lines-0:16:24 +5
+repeat history-lines-0:24:28 +13
+repeat history-lines-0:28:29 +17
+repeat bookmark +18
+| history-lines-0:29:30-in
 line 19 on_black,bright_cyan #.. §§:§§:§§ windows available via /window:§§
-| history-lines-0:29:30-at-19-out
-| history-lines-0:30:32-at-20-in
+| history-lines-0:29:30-out
+| history-lines-0:30:32-in
 line 20 on_black,bright_cyan #.. §§:§§:§§   0) :start§§
 line 21 on_black,bright_cyan #.. §§:§§:§§   1) foo.bar.baz:debug§§
-| history-lines-0:30:32-at-20-out
+| history-lines-0:30:32-out
 | before-first-server-responses-out
 line 22 on_black,bright_white :start)===================================================================([0] 1§§
 repeat prompt-empty
@@ -482,23 +482,23 @@ repeat prompt-empty
 
 # check that switching to window with new lines, but left scroll-to-bottom, keeps the scroll-to-bottom, keeps bookmark after last line previously seen there
 > /window 1
-repeat history-lines-1:4:8-at-7 -7
-repeat history-lines-1:8:16-at-11 -7
-repeat history-lines-1:16:18-at-19 -7
-repeat history-lines-1:18:19-at-21 -7
-repeat bookmark-at-19 -4
-| history-lines-1:19:20-at-16-in
+repeat history-lines-1:4:8 +0
+repeat history-lines-1:8:16 +4
+repeat history-lines-1:16:18 +12
+repeat history-lines-1:18:19 +14
+repeat bookmark +15
+| history-lines-1:19:20-in
 line 16 on_black,bright_white <.. §§:§§:§§ PING :?
-| history-lines-1:19:20-at-16-out
-| history-lines-1:20:24-at-17-in
+| history-lines-1:19:20-out
+| history-lines-1:20:24-in
 line 17 on_black,bright_green >.. §§:§§:§§ PONG :?
 line 18 on_black,bright_white <.. §§:§§:§§ PING :123456789 123456789 123456789 123456789 123456789 123456789§§
 line 19 on_black,bright_white     123456789 123456789§§
 line 20 on_black,bright_green >.. §§:§§:§§ PONG :123456789 123456789 123456789 123456789 123456789 123456789§§
-| history-lines-1:20:24-at-17-out
-| history-lines-1:24:25-at-21-in
+| history-lines-1:20:24-out
+| history-lines-1:24:25-in
 line 21 on_black,bright_green     123456789 123456789§§
-| history-lines-1:24:25-at-21-out
+| history-lines-1:24:25-out
 repeat status-prompt-both-empty
 
 # check that growth below scroll does not by itself re-position bookmark in history
@@ -506,55 +506,55 @@ repeat status-prompt-both-empty
 loggedservermsg 0 1 <.. PING :foo
 log 1 >.. PONG :foo
 | early-win1-upscroll-in
-repeat lines-empty-4
+repeat lines-empty-4 +0
 repeat lines-empty-2 +4
-repeat history-lines-1:0:8-at-3 +3
-repeat history-lines-1:8:12-at-11 +3
-repeat history-lines-1:12:14-at-15 +3
-repeat history-lines-1:14:15-at-17 +3
+repeat history-lines-1:0:8 +6
+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§§
 repeat status-prompt-both-empty
 > /window.history.scroll down
-repeat history-lines-1:5:6-at-8 -8
-repeat history-lines-1:6:8-at-9 -8
-repeat history-lines-1:8:16-at-11 -8
-repeat history-lines-1:16:18-at-19 -8
-repeat history-lines-1:18:19-at-21 -8
-repeat bookmark-at-19 -5
-repeat history-lines-1:19:20-at-16 -1
-repeat history-lines-1:20:24-at-17 -1
-repeat history-lines-1:24:25-at-21 -1
+repeat history-lines-1:5:6 +0
+repeat history-lines-1:6:8 +1
+repeat history-lines-1:8:16 +3
+repeat history-lines-1:16:18 +11
+repeat history-lines-1:18:19 +13
+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§§
 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
 > /window 0
 | win-0-only-for-win-1-tests-in
-repeat history-lines-0:11:12-at-20 -20
-repeat history-lines-0:12:16-at-18 -17
-repeat history-lines-0:16:24-at-14 -9
-repeat history-lines-0:24:28-at-16 -3
-repeat history-lines-0:28:29-at-21 -4
-repeat history-lines-0:29:30-at-19 -1
-repeat history-lines-0:30:32-at-20 -1
-repeat bookmark-at-19 +2
+repeat history-lines-0:11:12 +0
+repeat history-lines-0:12:16 +1
+repeat history-lines-0:16:24 +5
+repeat history-lines-0:24:28 +13
+repeat history-lines-0:28:29 +17
+repeat history-lines-0:29:30 +18
+repeat history-lines-0:30:32 +19
+repeat bookmark +21
 | win-0-only-for-win-1-tests-out
 line 22 on_black,bright_white :start)===============================================================([0] (1:2)§§
 repeat prompt-empty
 > /window 1
 | keep-bookmark-on-outside-growth-test-in
-repeat history-lines-1:5:6-at-8 -8
-repeat history-lines-1:6:8-at-9 -8
-repeat history-lines-1:8:16-at-11 -8
-| history-lines-1:16:24-at-11-in
-repeat history-lines-1:16:18-at-19 -8
-repeat history-lines-1:18:19-at-21 -8
-repeat history-lines-1:19:20-at-16 -2
-repeat history-lines-1:20:24-at-17 -2
-| history-lines-1:16:24-at-11-out
-repeat history-lines-1:24:25-at-21 -2
-repeat bookmark-at-19 +1
+repeat history-lines-1:5:6 +0
+repeat history-lines-1:6:8 +1
+repeat history-lines-1:8:16 +3
+| history-lines-1:16:24-in
+repeat history-lines-1:16:18 +11
+repeat history-lines-1:18:19 +13
+repeat history-lines-1:19:20 +14
+repeat history-lines-1:20:24 +15
+| history-lines-1:16:24-out
+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 22 on_black,bright_white foo.bar.baz:debug)====================================================(0 [(1:2)]§§
@@ -592,21 +592,21 @@ line 21 on_black,bright_white,reverse vvv [15] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
 line 22 on_black,bright_white foo.bar.baz:debug)====================================================(0 [(1:6)]§§
 repeat prompt-empty
 > /window.history.scroll down
-repeat history-lines-1:5:6-at-8 -8
-repeat history-lines-1:6:8-at-9 -8
-repeat history-lines-1:8:16-at-11 -8
-repeat history-lines-1:16:24-at-11
-repeat history-lines-1:24:25-at-21 -2
-repeat bookmark-at-19 +1
+repeat history-lines-1:5:6 +0
+repeat history-lines-1:6:8 +1
+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 22 on_black,bright_white foo.bar.baz:debug)====================================================(0 [(1:6)]§§
 repeat prompt-empty
 > /window.history.scroll down
-repeat history-lines-1:10:12-at-13 -13
-repeat history-lines-1:12:16-at-15 -13
-repeat history-lines-1:16:24-at-11 -5
-repeat history-lines-1:24:25-at-21 -7
-repeat bookmark-at-19 -4
+repeat history-lines-1:10:12 +0
+repeat history-lines-1:12:16 +2
+repeat history-lines-1:16:24 +6
+repeat history-lines-1:24:25 +14
+repeat bookmark +15
 line 16 on_black,bright_white <.. §§:§§:§§ PING :foo
 line 17 on_black,bright_green >.. §§:§§:§§ PONG :foo
 line 18 on_black,bright_white <.. §§:§§:§§ PING :bar