65 lines
1.9 KiB
Python
Executable File
65 lines
1.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
from dataclasses import dataclass
|
|
from typing import List, Dict
|
|
from subprocess import run, PIPE
|
|
|
|
def strip_comments(line: str):
|
|
if (line[0] == ';'):
|
|
return ""
|
|
elif (comment_start := line.find("#")) >= 0:
|
|
line = line[:comment_start]
|
|
return line.rstrip()
|
|
|
|
def parse_keybind(lines: List[str]):
|
|
keybind = lines[0]
|
|
commands = []
|
|
end = len(lines) - 1
|
|
for i, line in enumerate(lines[1:]):
|
|
if line.startswith(" "):
|
|
commands.append(line)
|
|
else:
|
|
end = i
|
|
break
|
|
end += 1
|
|
return keybind, commands, lines[end:]
|
|
|
|
def parse_all_keybinds(lines: list[str]) -> Dict[str, list[str]]:
|
|
binds = dict()
|
|
while len(lines) != 0:
|
|
binding, commands, lines = parse_keybind(lines)
|
|
binds[binding] = commands
|
|
return binds
|
|
|
|
def get_config_data(filepath: str):
|
|
with open(filepath, "r") as fp:
|
|
lines = fp.readlines()
|
|
lines = map(strip_comments, lines)
|
|
lines = filter(lambda x : x != "", lines)
|
|
bindings = parse_all_keybinds(list(lines))
|
|
return bindings
|
|
|
|
|
|
def dmenu(prompt: str, items: list) -> str:
|
|
return run(["dmenu", "-p", "Choose binding: "],
|
|
input="\n".join(items),
|
|
capture_output=True,
|
|
text=True).stdout.strip()
|
|
|
|
def get_keybind(keybinds: Dict[str, list[str]]) -> str:
|
|
return dmenu("Choose binding: ", list(keybinds.keys())).replace("\n", "")
|
|
|
|
def get_command(keybinds: Dict[str, list[str]]) -> str:
|
|
reverse_map = dict()
|
|
for key in keybinds:
|
|
value = keybinds[key]
|
|
if reverse_map.get(value) is not None:
|
|
continue
|
|
reverse_map[value] = key
|
|
return dmenu("Choose binding: ", list(reverse_map.keys())).replace("\n", "")
|
|
|
|
bindings = get_config_data("/home/oreo/.config/sxhkd/sxhkdrc")
|
|
choice = get_command(bindings)
|
|
|
|
print(choice, bindings[choice])
|