from __future__ import annotations import os import sys import tomllib from pathlib import Path from . import Sort DEFAULT_KEYBINDS: dict[str, list[str]] = { "quit": ["q"], "down": ["j", "KEY_DOWN"], "up": ["k", "KEY_UP"], "enter": ["l", "KEY_RIGHT", "\n", "KEY_ENTER"], "back": ["-", "KEY_LEFT", "KEY_BACKSPACE", "\x7f", "\x08"], "parent": ["h"], "sort": ["i"], } DEFAULT_CURSOR_RESET = "top" class Config: def __init__(self, keybinds: dict[str, list[str]], cursor_reset: str, sort_mode: str) -> None: self._keybinds = keybinds self._cursor_reset = cursor_reset self._sort_mode = sort_mode self._key_to_action: dict[str, str] = { key: action for action, keys in keybinds.items() for key in keys } @classmethod def load(cls, path: Path | None = None) -> Config: path = path or cls._default_path() data: dict = {} if path.is_file(): try: with path.open("rb") as f: data = tomllib.load(f) except tomllib.TOMLDecodeError as e: print(f"pyexplorer: ignoring invalid config {path}: {e}", file=sys.stderr) data = {} keybinds = dict(DEFAULT_KEYBINDS) keybinds.update(data.get("keybinds", {})) cursor_reset = data.get("cursor", {}).get("reset", DEFAULT_CURSOR_RESET) sort_mode = data.get("sort", {}).get("mode", Sort.DEFAULT_MODE) if sort_mode not in Sort.MODES: print(f"pyexplorer: unknown sort mode {sort_mode!r}, " f"falling back to {Sort.DEFAULT_MODE!r}", file=sys.stderr) sort_mode = Sort.DEFAULT_MODE return cls(keybinds, cursor_reset, sort_mode) @staticmethod def _default_path() -> Path: base = os.environ.get("XDG_CONFIG_HOME") or str(Path.home() / ".config") return Path(base) / "pyexplorer" / "config.toml" def keys_for(self, action: str) -> list[str]: return self._keybinds.get(action, []) def action_for(self, key: str) -> str | None: return self._key_to_action.get(key) @property def cursor_reset(self) -> str: return self._cursor_reset @property def sort_mode(self) -> str: return self._sort_mode