diff --git a/README.md b/README.md index 17e7f04..e136392 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ cargo install rbw # requires rbw >= 1.14.0 # install bw-menu git clone https://git.navidsassan.ch/navid.sassan/bw-menu.git -cd bw-menu +cd bw-menu/python uv sync ``` @@ -94,7 +94,7 @@ keybindings: totp: Shift+Return ``` -Each entry maps a vault field to a [rofi key name](https://davatorium.github.io/rofi/current/rofi-keys.5/). Available fields: `password`, `username`, `totp`. +Each entry maps a vault field to a [rofi key name](https://davatorium.github.io/rofi/current/rofi-keys.5/). Available fields: `password`, `username`, `totp`, `name`. The **first** entry is bound to rofi's accept key (`kb-accept-entry`). Additional entries become custom keybindings (`kb-custom-1`, `kb-custom-2`, …). diff --git a/src/bw_menu/__main__.py b/src/bw_menu/__main__.py index 915aa3b..3ae64f7 100644 --- a/src/bw_menu/__main__.py +++ b/src/bw_menu/__main__.py @@ -9,12 +9,12 @@ def main(): args = parse_args() if args.command == "select": - __handle_select(args) + _handle_select(args) elif args.command == "history": - __handle_history(args) + _handle_history(args) -def __handle_select(args): +def _handle_select(args): selector = create_selector(args.selector) selection = selector.run(args) if selection is None: @@ -29,7 +29,7 @@ def __handle_select(args): clipboard.copy(value) -def __handle_history(args): +def _handle_history(args): if args.history_command == "list": for i, entry in enumerate(history.load()): print(f"{i}: {format_entry(entry)}") diff --git a/src/bw_menu/clipboard.py b/src/bw_menu/clipboard.py index 161106a..53ebbb1 100644 --- a/src/bw_menu/clipboard.py +++ b/src/bw_menu/clipboard.py @@ -8,7 +8,10 @@ def copy(text: str): if tool is None: print("No clipboard tool found (install wl-copy or xclip)", file=sys.stderr) sys.exit(5) - subprocess.run(tool, input=text, encoding="utf-8", check=True) + result = subprocess.run(tool, input=text, encoding="utf-8") + if result.returncode != 0: + print(f"Error copying to clipboard: {result.stderr}", file=sys.stderr) + sys.exit(5) def __detect_tool() -> list[str] | None: diff --git a/src/bw_menu/config.py b/src/bw_menu/config.py index 7da93e6..d85cfe3 100644 --- a/src/bw_menu/config.py +++ b/src/bw_menu/config.py @@ -54,9 +54,12 @@ def load() -> Config: keybindings = {str(k): str(v) for k, v in kb.items()} invalid = {k for k in keybindings if k not in VALID_FIELDS} if invalid: - raise ValueError( - f"Invalid keybinding field(s): {', '.join(sorted(invalid))}. Valid fields: {', '.join(sorted(VALID_FIELDS))}" + print( + f"Warning: invalid keybinding field(s): {', '.join(sorted(invalid))}. " + f"Valid fields: {', '.join(sorted(VALID_FIELDS))}. Using defaults", + file=sys.stderr, ) + return Config() return Config(keybindings=keybindings) except yaml.YAMLError: print( diff --git a/src/bw_menu/history.py b/src/bw_menu/history.py index 37014b5..a4610c6 100644 --- a/src/bw_menu/history.py +++ b/src/bw_menu/history.py @@ -1,5 +1,6 @@ import json import os +import sys from pathlib import Path from bw_menu.rbw import Entry @@ -21,6 +22,10 @@ def load() -> list[Entry]: data = json.loads(path.read_text()) return [Entry(e["name"], e["folder"], e["username"]) for e in data["entries"]] except (json.JSONDecodeError, KeyError): + print( + f"Warning: history file {path} could not be read, ignoring", + file=sys.stderr, + ) return [] diff --git a/src/bw_menu/selector/rofi.py b/src/bw_menu/selector/rofi.py index 01eeefc..9d94e77 100644 --- a/src/bw_menu/selector/rofi.py +++ b/src/bw_menu/selector/rofi.py @@ -1,4 +1,5 @@ import os +import shutil import subprocess import sys from pathlib import Path @@ -84,6 +85,9 @@ class RofiSelector: path.unlink(missing_ok=True) def __launch(self, keybindings: dict[str, str]): + if not shutil.which("rofi"): + print("rofi is not installed", file=sys.stderr) + sys.exit(5) script = str(Path(sys.argv[0]).resolve()) keys = list(keybindings.values())