""" Generate Default.sublime-keymap """ import json import pathlib import string import sys sys.path.insert(0, str(pathlib.Path(__file__).parent.parent)) from vterm.keys import _MODIFIABLE_CSI # "setting.x" is evaluated natively by sublime; a plugin on_query_context would # cost an IPC round trip on every keystroke in every view CTX = [{"key": "setting.vterm_view"}] ESCAPE_CTX = [ {"key": "setting.vterm_view"}, {"key": "setting.vterm_view.finished", "operator": "not_equal", "operand": True}, {"key": "overlay_visible", "operator": "equal", "operand": False}, {"key": "popup_visible", "operator": "equal", "operand": False}, ] # derived from keys.py so a key added there cannot silently lack a binding NAV_KEYS = list(_MODIFIABLE_CSI) MODS = ["ctrl", "alt", "shift", "ctrl+shift", "alt+shift", "ctrl+alt"] def binding(keys, key, context=None, **flags): args = {"key": key} args.update(flags) return { "keys": [keys], "command": "vterm_keypress", "args": args, "context": context or CTX, } def mod_flags(mod): return {m: True for m in mod.split("+")} entries = [] # printable characters: bound like any other key so nothing is ever inserted into # the view. Uppercase must be a literal ("A", not shift+a): get_key_code returns # lowercase for the shift+ form. on_modified still covers IME and composed input. for c in string.ascii_lowercase + string.ascii_uppercase + string.digits + string.punctuation: entries.append(binding(c, c)) entries.append(binding("space", "space")) for key in ["enter", "tab", "backspace"] + NAV_KEYS: entries.append(binding(key, key)) entries.append(binding("escape", "escape", context=ESCAPE_CTX)) for i in range(1, 13): entries.append(binding("f{}".format(i), "f{}".format(i))) for mod in MODS: for key in NAV_KEYS: entries.append(binding("{}+{}".format(mod, key), key, **mod_flags(mod))) for key in ["enter", "backspace", "tab"]: for mod in ["ctrl", "alt", "shift"]: entries.append(binding("{}+{}".format(mod, key), key, **mod_flags(mod))) for c in "abcdefghijklmnopqrstuvwxyz": entries.append(binding("ctrl+{}".format(c), c, ctrl=True)) entries.append(binding("alt+{}".format(c), c, alt=True)) for c in ["`", "[", "]", "\\", "space", "_", "^", "/", "@"]: entries.append(binding("ctrl+{}".format(c if c != " " else "space"), c, ctrl=True)) # plugin-command bindings (everything above sends keys to the pty) entries.append({ "keys": ["super+shift+k"], "command": "vterm_clear_screen", "context": CTX, }) # one binding per line: indented JSON turns 150 bindings into 2000+ lines lines = ["[", " // generated by tools/gen_keymap.py - do not edit by hand"] lines += [" " + json.dumps(e, separators=(", ", ": ")) + "," for e in entries] lines[-1] = lines[-1].rstrip(",") lines.append("]") path = pathlib.Path(__file__).parent.parent / "Default.sublime-keymap" path.write_text("\n".join(lines) + "\n", encoding="utf-8") print("wrote {} bindings to {}".format(len(entries), path))