88 lines
3.0 KiB
Python
88 lines
3.0 KiB
Python
""" 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))
|