diff --git a/README.md b/README.md index 6ec6189..6f0c87e 100644 --- a/README.md +++ b/README.md @@ -381,6 +381,9 @@ Breakpoints can be added to a recording in several ways: - for existing recording, by inserting breakpoint events (`"b"`) in the asciicast file, see [breakpoint event](doc/asciicast-v2.md#b---breakpoint) +When replaying a recording with `asciinema play` you can fast-forward to the +next breakpoint by pressing `]` key (when paused). + Breakpoints can be useful in e.g. live demos: you can create a recording with breakpoints, then play it back during presentation, and have it stop wherever you want to explain terminal contents in more detail. @@ -463,8 +466,12 @@ idle_time_limit = 1 pause_key = p ; Define hotkey for stepping through playback, a frame at a time, -; default: . -step_key = ] +; default: . (dot) +step_key = s + +; Define hotkey for jumping to next breakpoint, +; default: ] +next_breakpoint_key = b [notifications] ; Desktop notifications are displayed on certain occasions, e.g. when diff --git a/asciinema/commands/play.py b/asciinema/commands/play.py index 5c47136..585e628 100644 --- a/asciinema/commands/play.py +++ b/asciinema/commands/play.py @@ -26,6 +26,7 @@ class PlayCommand(Command): self.key_bindings = { "pause": config.play_pause_key, "step": config.play_step_key, + "next_breakpoint": config.play_next_breakpoint_key, } def execute(self) -> int: diff --git a/asciinema/config.py b/asciinema/config.py index 2f15195..80e9708 100644 --- a/asciinema/config.py +++ b/asciinema/config.py @@ -161,6 +161,10 @@ class Config: def play_step_key(self) -> Any: return self.__get_key("play", "step", ".") + @property + def play_next_breakpoint_key(self) -> Any: + return self.__get_key("play", "next_breakpoint", "]") + @property def notifications_enabled(self) -> bool: return self.config.getboolean( diff --git a/asciinema/player.py b/asciinema/player.py index 9910f2b..6e8dfc4 100644 --- a/asciinema/player.py +++ b/asciinema/player.py @@ -101,6 +101,7 @@ class Player: # pylint: disable=too-few-public-methods idle_time_limit = idle_time_limit or asciicast.idle_time_limit pause_key = key_bindings.get("pause") step_key = key_bindings.get("step") + next_breakpoint_key = key_bindings.get("next_breakpoint") events = asciicast.events() events = ev.to_relative_time(events) @@ -148,6 +149,16 @@ class Player: # pylint: disable=too-few-public-methods pause_elapsed_time = time_ output.write(time_, event_type, text) time_, event_type, text = next_event() + + elif key == next_breakpoint_key: + while time_ is not None and event_type != "b": + output.write(time_, event_type, text) + time_, event_type, text = next_event() + + if time_ is not None: + output.write(time_, event_type, text) + pause_elapsed_time = time_ + time_, event_type, text = next_event() else: while time_ is not None: elapsed_wall_time = time.time() - start_time