Last active
July 4, 2022 12:40
-
-
Save EgZvor/7f346e20439420747a209e3a69096044 to your computer and use it in GitHub Desktop.
A script to convert specially constructed Vim log into a lines with raw key presses.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""See | |
https://hub.netzgemeinde.eu/channel/vim_sensei?mid=b64.aHR0cHM6Ly9odWIuaG90ZWxkYWFuLm5sL2l0ZW0vZGU2MjI1MDgtZjc1Ni00MGUzLWI1MTgtYjE1YTkwYTg2MWJi | |
for details on how to set up Vim to produce the log that this script parses. | |
""" | |
import fileinput | |
import os | |
import re | |
import signal | |
import sys | |
DEBUG = os.environ.get("DEBUG", False) | |
interrupted = False | |
def sigpipe_handler(_signo, _frame): | |
global interrupted | |
interrupted = True | |
signal.signal(signal.SIGPIPE, sigpipe_handler) | |
def main(): | |
timestamp_pattern = rb"\s*\d+.\d+\s+:\s+" | |
# Patterns to leave out irrelevant `modes`. | |
enter_command_line_window = re.compile( | |
timestamp_pattern + rb"::Entering command-line window::" | |
) | |
enter_command_line_mode = re.compile( | |
timestamp_pattern + rb"::Entering command-line mode::" | |
) | |
enter_insert_mode = re.compile(timestamp_pattern + rb"::Entering Insert Mode::") | |
leave_command_line_window = re.compile( | |
timestamp_pattern + rb"::Leaving command-line window::" | |
) | |
leave_command_line_mode = re.compile( | |
timestamp_pattern + rb"::Leaving command-line mode::" | |
) | |
leave_insert_mode = re.compile(timestamp_pattern + rb"::Leaving Insert Mode::") | |
raw_key_input = re.compile( | |
timestamp_pattern + rb'raw key input: "(?P<key>.{,10}?)"' | |
) | |
def match_enter(line) -> bool: | |
return bool( | |
enter_command_line_window.match(line) | |
or enter_command_line_mode.match(line) | |
or enter_insert_mode.match(line) | |
) | |
def match_leave(line) -> bool: | |
return bool( | |
leave_command_line_window.match(line) | |
or leave_command_line_mode.match(line) | |
or leave_insert_mode.match(line) | |
) | |
in_ignored_block = False | |
lineno = 0 | |
try: | |
for line in fileinput.input(mode="rb"): | |
if interrupted: | |
break | |
lineno += 1 | |
line: bytes | |
if match_enter(line): | |
in_ignored_block = True | |
continue | |
if match_leave(line): | |
in_ignored_block = False | |
continue | |
if in_ignored_block: | |
continue | |
if (m := raw_key_input.match(line)) is not None: | |
if DEBUG: | |
print(f'{lineno} {m.group("key")}') | |
else: | |
print(repr(m.group("key"))[2:-1]) | |
sys.stdout.flush() | |
except BrokenPipeError: | |
# Python flushes standard streams on exit; redirect remaining output | |
# to devnull to avoid another BrokenPipeError at shutdown | |
devnull = os.open(os.devnull, os.O_WRONLY) | |
os.dup2(devnull, sys.stdout.fileno()) | |
sys.exit(1) # Python exits with error code 1 on EPIPE | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment