#!/usr/bin/env python3 import re # Path to your Hyprland config config_path = "/home/megnas/.config/hypr/hyprland.conf" # replace USERNAME variables = {} bind_lines = [] # 1️⃣ Read config with open(config_path) as f: for line in f: line = line.strip() if not line or line.startswith("#"): continue # Parse variables if line.startswith("$"): m = re.match(r"(\$\w+)\s*=\s*(.*)", line) if m: var, val = m.groups() val = val.split("#")[0].strip() # remove comment variables[var] = val # Parse binds if line.startswith(("bind =","bindm =")): #"bindl =","bindel =" bind_lines.append(line.split("=",1)[1].strip()) # 2️⃣ Map commands to readable actions def command_to_text(parts): cmd = " ".join(parts[2:]).strip() # movefocus mapping movefocus_map = {"l":"left","r":"right","u":"up","d":"down"} if cmd.startswith("movefocus"): dir_key = cmd.split()[-1] dir_text = movefocus_map.get(dir_key, dir_key) return f"Move focus {dir_text}" if "split-workspace" in cmd: return f"Changes workspace to {parts[-1]}" if "exit" in cmd: return "Exits Hyprland" if "killactive" in cmd: return "Closes active window" if "exec" in cmd: # handle known variables cmd = cmd.replace("$fileManager", "Filemanager").replace("$menu", "Menu").replace("$terminal","Terminal") # remove leading "exec " if cmd.startswith("exec "): cmd_body = cmd[5:] else: cmd_body = cmd # Special case for screenshot script if "~/.scripts/screenshot.sh" in cmd_body: return "Takes screenshot" if "~/.scripts/hypr-help.sh" in cmd_body: return "Shows this help menu" return f"Runs {cmd_body}" if "togglefloating" in cmd: return "Toggles floating for window" if "fullscreen" in cmd: return "Toggles fullscreen" if "pseudo" in cmd: return "Pseudotiles window (dwindle)" if "togglesplit" in cmd: return "Toggles split (dwindle)" if "focusmonitor" in cmd: return "Changes focused monitor" if "split-changemonitor" in cmd: return "Moves window to next monitor" if "togglespecialworkspace" in cmd: return f"Toggles special workspace {parts[-1]}" if "movetoworkspace" in cmd: return f"Moves window to {parts[-1]}" if "split-cycleworkspacesnowrap" in cmd: return f"Cycles workspace {parts[-1]}" if "movewindow" in cmd: return "Move window with mouse" if "resizewindow" in cmd: return "Resize window with mouse" # fallback return cmd # 3️⃣ Resolve variables in combos and rename mouse keys def resolve_combo(combo): combo = combo.replace("$mainMod", variables.get("$mainMod","")) combo = combo.replace("#"," + ") # ALT#SUPER -> ALT + SUPER # Mouse key mapping mouse_map = { "mouse:272": "Mouse (left click)", "mouse:273": "Mouse (right click)", "mouse_down": "Mouse (scroll down)", "mouse_up": "Mouse (scroll up)", "Print": "PrintScreen" } combo = mouse_map.get(combo, combo) return combo.strip(" +") # 4️⃣ Format each bind formatted = [] for b in bind_lines: parts = [p.strip() for p in b.split(",")] if len(parts) < 2: continue combo = resolve_combo(parts[0]) key = resolve_combo(parts[1]) # combine combo + key if combo and key: combo_text = f"{combo} + {key}" elif combo: combo_text = combo else: combo_text = key action = command_to_text(parts) formatted.append(f"{combo_text} -> {action}") # 5️⃣ Print results for line in formatted: print(line)