#!/usr/bin/env python3
"""Dump Blender's 2.7x key-map (left-click select) as JSON — THE REFERENCE the
gate_keymap_blender gate holds our build-mode Keymap to (docs/keymap-blender-279.md §1, §5).
Blender ships its own 2.7x reproduction: scripts/presets/keyconfig/Blender_27x.py runs
keymap_data/blender_default.py with legacy=True, spacebar_action='SEARCH',
use_select_all_toggle=True, use_gizmo_drag=False. blender_default.py imports only `math`,
so it runs outside Blender. The one setting we change: select_mouse='LEFT' (user decision
2026-10-12, "left click select").
python3 -I tools/keymap/blender_dump.py \
<blender-source>/scripts/presets/keyconfig/keymap_data/blender_default.py \
> tools/keymap/blender_279_left.json
Output: {"source", "params", "keymaps": {name: [{"op", "type", "value", "shift", "ctrl",
"alt", "oskey", "any", "props"}...]}} for the key-maps build mode borrows from.
"""
import json
import runpy
import sys
KEYMAPS = ["Window", "Screen", "3D View Generic", "3D View", "Object Mode", "Object Non-modal",
"Mesh", "View3D Fly Modal"]
PARAMS = dict(select_mouse="LEFT", legacy=True, spacebar_action="SEARCH",
use_select_all_toggle=True, use_gizmo_drag=False)
def _plain(v):
"""Property values as JSON: tuples -> lists, everything else as is."""
if isinstance(v, tuple):
return [_plain(x) for x in v]
return v
def main(path: str) -> None:
ns = runpy.run_path(path)
data = ns["generate_keymaps"](ns["Params"](**PARAMS))
out = {}
for name, _space, body in data:
if name not in KEYMAPS:
continue
rows = []
for item in body.get("items", []):
op, ev, extra = item
props = {}
if extra and extra.get("properties"):
props = {k: _plain(v) for k, v in extra["properties"]}
rows.append({
"op": op, "type": ev.get("type"), "value": ev.get("value"),
"shift": bool(ev.get("shift", False)), "ctrl": bool(ev.get("ctrl", False)),
"alt": bool(ev.get("alt", False)), "oskey": bool(ev.get("oskey", False)),
"any": bool(ev.get("any", False)), "props": props,
})
out[name] = rows
json.dump({"source": "blender_default.py (Blender_27x.py params, select_mouse=LEFT)",
"params": PARAMS, "keymaps": out}, sys.stdout, indent=1, sort_keys=True)
sys.stdout.write("\n")
if __name__ == "__main__":
main(sys.argv[1])