Configurable hotkeys for recording

This commit is contained in:
Marcin Kulik
2020-04-19 18:53:13 +02:00
committed by Marcin Kulik
parent 4093b42f35
commit c85a4a7acd
5 changed files with 66 additions and 16 deletions

View File

@@ -329,6 +329,14 @@ yes = true
; Be quiet, suppress all notices/warnings, default: no ; Be quiet, suppress all notices/warnings, default: no
quiet = true quiet = true
; Define hotkey for pausing recording (suspending capture of output),
; default: C-\
pause_key = C-p
; Define hotkey prefix key - when defined other recording hotkeys must
; be preceeded by it, default: no prefix
prefix_key = C-a
[play] [play]
; Playback speed (can be fractional), default: 1 ; Playback speed (can be fractional), default: 1

View File

@@ -28,6 +28,10 @@ class RecordCommand(Command):
self.writer = raw.writer if args.raw else v2.writer self.writer = raw.writer if args.raw else v2.writer
self.notifier = notifier.get_notifier(config.notifications_enabled, config.notifications_command) self.notifier = notifier.get_notifier(config.notifications_enabled, config.notifications_command)
self.env = env self.env = env
self.key_bindings = {
'prefix': config.record_prefix_key,
'pause': config.record_pause_key
}
def execute(self): def execute(self):
upload = False upload = False
@@ -78,7 +82,8 @@ class RecordCommand(Command):
capture_env=vars, capture_env=vars,
rec_stdin=self.rec_stdin, rec_stdin=self.rec_stdin,
writer=self.writer, writer=self.writer,
notifier=self.notifier notifier=self.notifier,
key_bindings=self.key_bindings
) )
except v2.LoadError: except v2.LoadError:
self.print_error("can only append to asciicast v2 format recordings") self.print_error("can only append to asciicast v2 format recordings")

View File

@@ -109,6 +109,14 @@ class Config:
def record_quiet(self): def record_quiet(self):
return self.config.getboolean('record', 'quiet', fallback=False) return self.config.getboolean('record', 'quiet', fallback=False)
@property
def record_prefix_key(self):
return self.__get_key('record', 'prefix')
@property
def record_pause_key(self):
return self.__get_key('record', 'pause', 'C-\\')
@property @property
def play_idle_time_limit(self): def play_idle_time_limit(self):
fallback = self.config.getfloat('play', 'maxwait', fallback=None) # pre 2.0 fallback = self.config.getfloat('play', 'maxwait', fallback=None) # pre 2.0
@@ -126,6 +134,20 @@ class Config:
def notifications_command(self): def notifications_command(self):
return self.config.get('notifications', 'command', fallback=None) return self.config.get('notifications', 'command', fallback=None)
def __get_key(self, section, name, default=None):
key = self.config.get(section, f'{name}_key', fallback=default)
if key:
if len(key) == 3:
upper_key = key.upper()
if upper_key[0] == 'C' and upper_key[1] == '-':
return bytes([ord(upper_key[2]) - 0x40])
else:
raise ConfigError(f'invalid {name} key definition \'{key}\' - use: {name}_key = C-x (with control key modifier), or {name}_key = x (with no modifier)')
else:
return key.encode('utf-8')
def get_config_home(env=os.environ): def get_config_home(env=os.environ):
env_asciinema_config_home = env.get("ASCIINEMA_CONFIG_HOME") env_asciinema_config_home = env.get("ASCIINEMA_CONFIG_HOME")

View File

@@ -15,10 +15,13 @@ import time
from asciinema.term import raw from asciinema.term import raw
def record(command, writer, env=os.environ, rec_stdin=False, time_offset=0, notifier=None): def record(command, writer, env=os.environ, rec_stdin=False, time_offset=0, notifier=None, key_bindings={}):
master_fd = None master_fd = None
start_time = None start_time = None
pause_time = None pause_time = None
prefix_mode = False
prefix_key = key_bindings.get('prefix')
pause_key = key_bindings.get('pause')
def _notify(text): def _notify(text):
if notifier: if notifier:
@@ -64,20 +67,30 @@ def record(command, writer, env=os.environ, rec_stdin=False, time_offset=0, noti
nonlocal pause_time nonlocal pause_time
nonlocal start_time nonlocal start_time
nonlocal prefix_mode
if data == b'\x10': # ctrl+p if not prefix_mode and prefix_key and data == prefix_key:
if pause_time: prefix_mode = True
start_time = start_time + (time.time() - pause_time) return
pause_time = None
_notify('Resumed recording')
else:
pause_time = time.time()
_notify('Paused recording')
else:
_write_master(data)
if rec_stdin and not pause_time: if prefix_mode or (not prefix_key and data in [pause_key]):
writer.write_stdin(time.time() - start_time, data) prefix_mode = False
if data == pause_key:
if pause_time:
start_time = start_time + (time.time() - pause_time)
pause_time = None
_notify('Resumed recording')
else:
pause_time = time.time()
_notify('Paused recording')
return
_write_master(data)
if rec_stdin and not pause_time:
writer.write_stdin(time.time() - start_time, data)
def _signals(signal_list): def _signals(signal_list):
old_handlers = [] old_handlers = []

View File

@@ -9,7 +9,8 @@ from asciinema.async_worker import async_worker
def record(path, command=None, append=False, idle_time_limit=None, def record(path, command=None, append=False, idle_time_limit=None,
rec_stdin=False, title=None, metadata=None, command_env=None, rec_stdin=False, title=None, metadata=None, command_env=None,
capture_env=None, writer=v2.writer, record=pty.record, notifier=None): capture_env=None, writer=v2.writer, record=pty.record, notifier=None,
key_bindings={}):
if command is None: if command is None:
command = os.environ.get('SHELL') or 'sh' command = os.environ.get('SHELL') or 'sh'
@@ -53,7 +54,8 @@ def record(path, command=None, append=False, idle_time_limit=None,
command_env, command_env,
rec_stdin, rec_stdin,
time_offset, time_offset,
n n,
key_bindings
) )