mirror of
https://github.com/asciinema/asciinema.git
synced 2025-12-16 11:48:13 +01:00
Rename breakpoints to markers
This commit is contained in:
47
README.md
47
README.md
@@ -296,7 +296,7 @@ Available options:
|
|||||||
- `-i, --idle-time-limit=<sec>` - Limit replayed terminal inactivity to max `<sec>` seconds
|
- `-i, --idle-time-limit=<sec>` - Limit replayed terminal inactivity to max `<sec>` seconds
|
||||||
- `-s, --speed=<factor>` - Playback speed (can be fractional)
|
- `-s, --speed=<factor>` - Playback speed (can be fractional)
|
||||||
- `-l, --loop` - Play in a loop
|
- `-l, --loop` - Play in a loop
|
||||||
- `-b, --breakpoints` - Automatically pause on [breakpoints](#breakpoints)
|
- `-m, --pause-on-markers` - Automatically pause on [markers](#markers)
|
||||||
- `--stream=<stream>` - Select stream to play (see below)
|
- `--stream=<stream>` - Select stream to play (see below)
|
||||||
- `--out-fmt=<format>` - Select output format (see below)
|
- `--out-fmt=<format>` - Select output format (see below)
|
||||||
|
|
||||||
@@ -362,31 +362,28 @@ happen in any order.
|
|||||||
> asciinema versions prior to 2.0 confusingly referred to install ID as "API
|
> asciinema versions prior to 2.0 confusingly referred to install ID as "API
|
||||||
> token".
|
> token".
|
||||||
|
|
||||||
## Breakpoints
|
## Markers
|
||||||
|
|
||||||
Breakpoints are markers that you can set in a recording to pause the playback at
|
Markers allow marking specific time locations in a recording, which can be used
|
||||||
a specific point.
|
for navigation, as well as for automatic pausing of the playback.
|
||||||
|
|
||||||
When a breakpoint is reached, the playback automatically pauses and can be
|
Markers can be added to a recording in several ways:
|
||||||
resumed by pressing space bar key. The playback continues until next breakpoint
|
|
||||||
is encountered.
|
|
||||||
|
|
||||||
To enable auto-pause-on-breakpoint behaviour when replaying with `asciinema
|
- while you are recording, by pressing a configured hotkey, see [add_marker_key
|
||||||
play` use `-b`/`--breakpoints` option. It's off by default.
|
config option](#configuration-file)
|
||||||
|
- for existing recording, by inserting marker events (`"m"`) in the asciicast
|
||||||
|
file, see [marker event](doc/asciicast-v2.md#m---marker)
|
||||||
|
|
||||||
Breakpoints can be added to a recording in several ways:
|
When replaying a recording with `asciinema play` you can enable
|
||||||
|
auto-pause-on-marker behaviour with `-m`/`--pause-on-markers` option (it's off
|
||||||
|
by default). When a marker is encountered, the playback automatically pauses and
|
||||||
|
can be resumed by pressing space bar key. The playback continues until next
|
||||||
|
marker is encountered. You can also fast-forward to the next marker by pressing
|
||||||
|
`]` key (when paused).
|
||||||
|
|
||||||
- during recording session, by pressing a configured hotkey, see
|
Markers can be useful in e.g. live demos: you can create a recording with
|
||||||
[add_breakpoint_key config option](#configuration-file)
|
markers, then play it back during presentation, and have it stop wherever you
|
||||||
- for existing recording, by inserting breakpoint events (`"b"`) in the
|
want to explain terminal contents in more detail.
|
||||||
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.
|
|
||||||
|
|
||||||
## Hosting the recordings on the web
|
## Hosting the recordings on the web
|
||||||
|
|
||||||
@@ -446,8 +443,8 @@ quiet = true
|
|||||||
; default: C-\ (control + backslash)
|
; default: C-\ (control + backslash)
|
||||||
pause_key = C-p
|
pause_key = C-p
|
||||||
|
|
||||||
; Define hotkey for adding a breakpoint, default: none
|
; Define hotkey for adding a marker, default: none
|
||||||
add_breakpoint_key = C-b
|
add_marker_key = C-x
|
||||||
|
|
||||||
; Define hotkey prefix key - when defined other recording hotkeys must
|
; Define hotkey prefix key - when defined other recording hotkeys must
|
||||||
; be preceeded by it, default: no prefix
|
; be preceeded by it, default: no prefix
|
||||||
@@ -469,9 +466,9 @@ pause_key = p
|
|||||||
; default: . (dot)
|
; default: . (dot)
|
||||||
step_key = s
|
step_key = s
|
||||||
|
|
||||||
; Define hotkey for jumping to the next breakpoint,
|
; Define hotkey for jumping to the next marker,
|
||||||
; default: ]
|
; default: ]
|
||||||
next_breakpoint_key = b
|
next_marker_key = m
|
||||||
|
|
||||||
[notifications]
|
[notifications]
|
||||||
; Desktop notifications are displayed on certain occasions, e.g. when
|
; Desktop notifications are displayed on certain occasions, e.g. when
|
||||||
|
|||||||
@@ -197,9 +197,9 @@ For help on a specific command run:
|
|||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
parser_play.add_argument(
|
parser_play.add_argument(
|
||||||
"-b",
|
"-m",
|
||||||
"--breakpoints",
|
"--pause-on-markers",
|
||||||
help="automatically pause on breakpoints",
|
help="automatically pause on markers",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class writer(file_writer):
|
|||||||
def write_stdin(self, ts: float, data: Any) -> None:
|
def write_stdin(self, ts: float, data: Any) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def write_breakpoint(self, ts: float) -> None:
|
def write_marker(self, ts: float) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# pylint: disable=consider-using-with
|
# pylint: disable=consider-using-with
|
||||||
|
|||||||
@@ -145,8 +145,8 @@ class writer(file_writer):
|
|||||||
data = self.stdin_decoder.decode(data)
|
data = self.stdin_decoder.decode(data)
|
||||||
self.__write_event(ts, "i", data)
|
self.__write_event(ts, "i", data)
|
||||||
|
|
||||||
def write_breakpoint(self, ts: float) -> None:
|
def write_marker(self, ts: float) -> None:
|
||||||
self.__write_event(ts, "b", "")
|
self.__write_event(ts, "m", "")
|
||||||
|
|
||||||
# pylint: disable=consider-using-with
|
# pylint: disable=consider-using-with
|
||||||
def _open_file(self) -> None:
|
def _open_file(self) -> None:
|
||||||
|
|||||||
@@ -21,12 +21,12 @@ class PlayCommand(Command):
|
|||||||
self.loop = args.loop
|
self.loop = args.loop
|
||||||
self.out_fmt = args.out_fmt
|
self.out_fmt = args.out_fmt
|
||||||
self.stream = args.stream
|
self.stream = args.stream
|
||||||
self.breakpoints = args.breakpoints
|
self.pause_on_markers = args.pause_on_markers
|
||||||
self.player = player if player is not None else Player()
|
self.player = player if player is not None else Player()
|
||||||
self.key_bindings = {
|
self.key_bindings = {
|
||||||
"pause": config.play_pause_key,
|
"pause": config.play_pause_key,
|
||||||
"step": config.play_step_key,
|
"step": config.play_step_key,
|
||||||
"next_breakpoint": config.play_next_breakpoint_key,
|
"next_marker": config.play_next_marker_key,
|
||||||
}
|
}
|
||||||
|
|
||||||
def execute(self) -> int:
|
def execute(self) -> int:
|
||||||
@@ -48,7 +48,7 @@ class PlayCommand(Command):
|
|||||||
key_bindings=self.key_bindings,
|
key_bindings=self.key_bindings,
|
||||||
out_fmt=self.out_fmt,
|
out_fmt=self.out_fmt,
|
||||||
stream=self.stream,
|
stream=self.stream,
|
||||||
pause_on_breakpoints=self.breakpoints,
|
pause_on_markers=self.pause_on_markers,
|
||||||
)
|
)
|
||||||
|
|
||||||
except asciicast.LoadError as e:
|
except asciicast.LoadError as e:
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class RecordCommand(Command): # pylint: disable=too-many-instance-attributes
|
|||||||
self.key_bindings = {
|
self.key_bindings = {
|
||||||
"prefix": config.record_prefix_key,
|
"prefix": config.record_prefix_key,
|
||||||
"pause": config.record_pause_key,
|
"pause": config.record_pause_key,
|
||||||
"add_breakpoint": config.record_add_breakpoint_key,
|
"add_marker": config.record_add_marker_key,
|
||||||
}
|
}
|
||||||
|
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
|
|||||||
@@ -137,8 +137,8 @@ class Config:
|
|||||||
return self.__get_key("record", "pause", "C-\\")
|
return self.__get_key("record", "pause", "C-\\")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def record_add_breakpoint_key(self) -> Any:
|
def record_add_marker_key(self) -> Any:
|
||||||
return self.__get_key("record", "add_breakpoint")
|
return self.__get_key("record", "add_marker")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def play_idle_time_limit(self) -> Optional[float]:
|
def play_idle_time_limit(self) -> Optional[float]:
|
||||||
@@ -162,8 +162,8 @@ class Config:
|
|||||||
return self.__get_key("play", "step", ".")
|
return self.__get_key("play", "step", ".")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def play_next_breakpoint_key(self) -> Any:
|
def play_next_marker_key(self) -> Any:
|
||||||
return self.__get_key("play", "next_breakpoint", "]")
|
return self.__get_key("play", "next_marker", "]")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def notifications_enabled(self) -> bool:
|
def notifications_enabled(self) -> bool:
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class Player: # pylint: disable=too-few-public-methods
|
|||||||
key_bindings: Optional[Dict[str, Any]] = None,
|
key_bindings: Optional[Dict[str, Any]] = None,
|
||||||
out_fmt: str = "raw",
|
out_fmt: str = "raw",
|
||||||
stream: Optional[str] = None,
|
stream: Optional[str] = None,
|
||||||
pause_on_breakpoints: bool = False,
|
pause_on_markers: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
if key_bindings is None:
|
if key_bindings is None:
|
||||||
key_bindings = {}
|
key_bindings = {}
|
||||||
@@ -75,7 +75,7 @@ class Player: # pylint: disable=too-few-public-methods
|
|||||||
stdin,
|
stdin,
|
||||||
key_bindings,
|
key_bindings,
|
||||||
output,
|
output,
|
||||||
pause_on_breakpoints,
|
pause_on_markers,
|
||||||
)
|
)
|
||||||
except IOError:
|
except IOError:
|
||||||
self._play(
|
self._play(
|
||||||
@@ -96,12 +96,12 @@ class Player: # pylint: disable=too-few-public-methods
|
|||||||
stdin: Optional[TextIO],
|
stdin: Optional[TextIO],
|
||||||
key_bindings: Dict[str, Any],
|
key_bindings: Dict[str, Any],
|
||||||
output: Output,
|
output: Output,
|
||||||
pause_on_breakpoints: bool,
|
pause_on_markers: bool,
|
||||||
) -> None:
|
) -> None:
|
||||||
idle_time_limit = idle_time_limit or asciicast.idle_time_limit
|
idle_time_limit = idle_time_limit or asciicast.idle_time_limit
|
||||||
pause_key = key_bindings.get("pause")
|
pause_key = key_bindings.get("pause")
|
||||||
step_key = key_bindings.get("step")
|
step_key = key_bindings.get("step")
|
||||||
next_breakpoint_key = key_bindings.get("next_breakpoint")
|
next_marker_key = key_bindings.get("next_marker")
|
||||||
|
|
||||||
events = asciicast.events()
|
events = asciicast.events()
|
||||||
events = ev.to_relative_time(events)
|
events = ev.to_relative_time(events)
|
||||||
@@ -150,8 +150,8 @@ class Player: # pylint: disable=too-few-public-methods
|
|||||||
output.write(time_, event_type, text)
|
output.write(time_, event_type, text)
|
||||||
time_, event_type, text = next_event()
|
time_, event_type, text = next_event()
|
||||||
|
|
||||||
elif key == next_breakpoint_key:
|
elif key == next_marker_key:
|
||||||
while time_ is not None and event_type != "b":
|
while time_ is not None and event_type != "m":
|
||||||
output.write(time_, event_type, text)
|
output.write(time_, event_type, text)
|
||||||
time_, event_type, text = next_event()
|
time_, event_type, text = next_event()
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ class Player: # pylint: disable=too-few-public-methods
|
|||||||
else:
|
else:
|
||||||
output.write(time_, event_type, text)
|
output.write(time_, event_type, text)
|
||||||
|
|
||||||
if event_type == "b" and pause_on_breakpoints:
|
if event_type == "m" and pause_on_markers:
|
||||||
pause_elapsed_time = time_
|
pause_elapsed_time = time_
|
||||||
time_, event_type, text = next_event()
|
time_, event_type, text = next_event()
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ def record(
|
|||||||
prefix_mode: bool = False
|
prefix_mode: bool = False
|
||||||
prefix_key = key_bindings.get("prefix")
|
prefix_key = key_bindings.get("prefix")
|
||||||
pause_key = key_bindings.get("pause")
|
pause_key = key_bindings.get("pause")
|
||||||
add_breakpoint_key = key_bindings.get("add_breakpoint")
|
add_marker_key = key_bindings.get("add_marker")
|
||||||
|
|
||||||
def set_pty_size() -> None:
|
def set_pty_size() -> None:
|
||||||
cols, rows = get_tty_size()
|
cols, rows = get_tty_size()
|
||||||
@@ -60,7 +60,7 @@ def record(
|
|||||||
return
|
return
|
||||||
|
|
||||||
if prefix_mode or (
|
if prefix_mode or (
|
||||||
not prefix_key and data in [pause_key, add_breakpoint_key]
|
not prefix_key and data in [pause_key, add_marker_key]
|
||||||
):
|
):
|
||||||
prefix_mode = False
|
prefix_mode = False
|
||||||
|
|
||||||
@@ -74,10 +74,10 @@ def record(
|
|||||||
pause_time = time.time()
|
pause_time = time.time()
|
||||||
notify("Paused recording")
|
notify("Paused recording")
|
||||||
|
|
||||||
elif data == add_breakpoint_key:
|
elif data == add_marker_key:
|
||||||
assert start_time is not None
|
assert start_time is not None
|
||||||
writer.write_breakpoint(time.time() - start_time)
|
writer.write_marker(time.time() - start_time)
|
||||||
notify("Breakpoint added")
|
notify("Marker added")
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -131,8 +131,8 @@ class async_writer(async_worker):
|
|||||||
def write_stdout(self, ts: float, data: Any) -> None:
|
def write_stdout(self, ts: float, data: Any) -> None:
|
||||||
self.enqueue([ts, "o", data])
|
self.enqueue([ts, "o", data])
|
||||||
|
|
||||||
def write_breakpoint(self, ts: float) -> None:
|
def write_marker(self, ts: float) -> None:
|
||||||
self.enqueue([ts, "b", None])
|
self.enqueue([ts, "m", None])
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
try:
|
try:
|
||||||
@@ -146,8 +146,8 @@ class async_writer(async_worker):
|
|||||||
w.write_stdout(self.time_offset + ts, data)
|
w.write_stdout(self.time_offset + ts, data)
|
||||||
elif etype == "i":
|
elif etype == "i":
|
||||||
w.write_stdin(self.time_offset + ts, data)
|
w.write_stdin(self.time_offset + ts, data)
|
||||||
elif etype == "b":
|
elif etype == "m":
|
||||||
w.write_breakpoint(self.time_offset + ts)
|
w.write_marker(self.time_offset + ts)
|
||||||
except IOError:
|
except IOError:
|
||||||
for event in iter(self.queue.get, None):
|
for event in iter(self.queue.get, None):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Example file:
|
|||||||
{"version": 2, "width": 80, "height": 24, "timestamp": 1504467315, "title": "Demo", "env": {"TERM": "xterm-256color", "SHELL": "/bin/zsh"}}
|
{"version": 2, "width": 80, "height": 24, "timestamp": 1504467315, "title": "Demo", "env": {"TERM": "xterm-256color", "SHELL": "/bin/zsh"}}
|
||||||
[0.248848, "o", "\u001b[1;31mHello \u001b[32mWorld!\u001b[0m\n"]
|
[0.248848, "o", "\u001b[1;31mHello \u001b[32mWorld!\u001b[0m\n"]
|
||||||
[1.001376, "o", "That was ok\rThis is better."]
|
[1.001376, "o", "That was ok\rThis is better."]
|
||||||
[1.500000, "b", ""]
|
[1.500000, "m", ""]
|
||||||
[2.143733, "o", "Now... "]
|
[2.143733, "o", "Now... "]
|
||||||
[6.541828, "o", "Bye!"]
|
[6.541828, "o", "Bye!"]
|
||||||
```
|
```
|
||||||
@@ -115,7 +115,7 @@ Where:
|
|||||||
|
|
||||||
* `time` (float) - indicates when this event happened, represented as the number
|
* `time` (float) - indicates when this event happened, represented as the number
|
||||||
of seconds since the beginning of the recording session,
|
of seconds since the beginning of the recording session,
|
||||||
* `event-type` (string) - one of: `"o"`, `"i"`, `"b"`
|
* `event-type` (string) - one of: `"o"`, `"i"`, `"m"`
|
||||||
* `event-data` (any) - event specific data, described separately for each event
|
* `event-data` (any) - event specific data, described separately for each event
|
||||||
type.
|
type.
|
||||||
|
|
||||||
@@ -165,16 +165,16 @@ non-printable Unicode codepoints encoded as `\uXXXX`.
|
|||||||
> implementations of asciicast-compatible terminal recorder should not capture
|
> implementations of asciicast-compatible terminal recorder should not capture
|
||||||
> it either unless explicitly permitted by the user.
|
> it either unless explicitly permitted by the user.
|
||||||
|
|
||||||
#### "b" - breakpoint
|
#### "m" - marker
|
||||||
|
|
||||||
Event of type `"b"` represents a breakpoint.
|
Event of type `"m"` represents a marker.
|
||||||
|
|
||||||
When breakpoint is encountered in the event stream and "pause on breakpoint"
|
When marker is encountered in the event stream and "pause on markers"
|
||||||
functionality of the player is enabled, the playback should pause, and wait for
|
functionality of the player is enabled, the playback should pause, and wait for
|
||||||
the user to resume.
|
the user to resume.
|
||||||
|
|
||||||
`event-data` can be used to annotate a breakpoint. Annotations may be used to
|
`event-data` can be used to annotate a marker. Annotations may be used to e.g.
|
||||||
e.g. show a list of named "chapters".
|
show a list of named "chapters".
|
||||||
|
|
||||||
## Notes on compatibility
|
## Notes on compatibility
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ asciinema rec --raw -c 'bash -c "echo t3st; sleep 1; echo ok"' "${TMP_DATA_DIR}/
|
|||||||
asciinema rec -c 'echo allright!; sleep 0.1' "${TMP_DATA_DIR}/7.cast"
|
asciinema rec -c 'echo allright!; sleep 0.1' "${TMP_DATA_DIR}/7.cast"
|
||||||
asciinema rec --append -c uptime "${TMP_DATA_DIR}/7.cast"
|
asciinema rec --append -c uptime "${TMP_DATA_DIR}/7.cast"
|
||||||
|
|
||||||
# adding a breakpoint
|
# adding a marker
|
||||||
printf "[record]\nadd_breakpoint_key = C-b\n" >> "${ASCIINEMA_CONFIG_HOME}/config"
|
printf "[record]\nadd_marker_key = C-b\n" >> "${ASCIINEMA_CONFIG_HOME}/config"
|
||||||
(bash -c "sleep 1; printf '.'; sleep 0.5; printf '\x08'; sleep 0.5; printf '\x02'; sleep 0.5; printf '\x04'") | asciinema rec -c /bin/bash "${TMP_DATA_DIR}/8.cast"
|
(bash -c "sleep 1; printf '.'; sleep 0.5; printf '\x08'; sleep 0.5; printf '\x02'; sleep 0.5; printf '\x04'") | asciinema rec -c /bin/bash "${TMP_DATA_DIR}/8.cast"
|
||||||
grep '"b",' "${TMP_DATA_DIR}/8.cast"
|
grep '"m",' "${TMP_DATA_DIR}/8.cast"
|
||||||
|
|||||||
Reference in New Issue
Block a user