foot-scripts/foot-command.py
2025-07-17 22:42:32 -04:00

107 lines
2.7 KiB
Python
Executable file

#!/bin/env python3
# Depends: wtype
import os
import subprocess
from argparse import ArgumentParser
from configparser import ConfigParser
ENV_CONFIG = "FOOT_CONFIG"
ENV_PICKER = "FOOT_PICKER"
DEFAULT_CONFIG = "$HOME/.config/foot.ini"
def parse_config(path: str):
config = ConfigParser(allow_unnamed_section=True)
config.read(path)
section = "key-bindings"
pairs: list[tuple[str, str]] = config.items(section, raw=True)
out: dict[str, str] = {}
for pair in pairs:
command = pair[0]
bindings = pair[1].split(" ")
if bindings[0] == "none":
continue
elif bindings[0][0] == "[":
out[command] = bindings[1]
else:
out[command] = bindings[0]
return out
def get_query_string(mapping: dict[str, str]) -> str:
return "\n".join(mapping.keys())
def spawn_picker(cmd, query_string):
process = subprocess.Popen(
cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE
)
selection = process.communicate(input=query_string.encode("UTF-8"))
if process.returncode != 2:
return selection[0].decode("UTF-8").strip("\n")
else:
return None
MOD_MAP = {
"Control": "ctrl",
"Shift": "shift",
"Mod1": "alt",
}
def get_wtype_args(selection: str, mapping: dict[str, str]):
binding = mapping[selection]
args: list[str] = ["wtype"]
for k in binding.split("+"):
if k in MOD_MAP:
args += ["-M", MOD_MAP[k]]
else:
args += ["-k", k]
return args
def send_keys(args):
process = subprocess.run(args)
process.check_returncode()
def validate_path(path: str) -> str:
if path == DEFAULT_CONFIG:
return str(os.environ["HOME"]) + "/.config/foot/foot.ini"
else:
return path
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument(
"-c",
"--config",
required=False,
help="Absolute path to foot.ini file. (default: %(default)s)",
default=DEFAULT_CONFIG,
type=str,
metavar=ENV_CONFIG,
)
parser.add_argument(
"-p",
"--picker",
required=False,
help="Picker command to be used. (default: %(default)s)",
type=str,
default="fuzzel --dmenu --placeholder=Select a command:",
metavar=ENV_PICKER,
)
args = parser.parse_args()
picker = args.picker
foot_path = validate_path(args.config)
mapping = parse_config(foot_path)
query = get_query_string(mapping)
selection = spawn_picker(picker, query)
if selection is not None:
wtype_args = get_wtype_args(selection, mapping)
print(wtype_args)
send_keys(wtype_args)