feat(menu): network/bluetooth/capture/ask modules + keybindings cheatsheet
Build out the rofi menu system roadmap item: - New nomarchy-menu modules: network (nmtui), bluetooth (blueman-manager), capture (grim/slurp submenu → clipboard/file), ask (free-text → claude CLI in a terminal), and keybinds (the SUPER+? cheatsheet). - modules/home/keybinds.nix is now the single source of truth for both the Hyprland bind strings and the cheatsheet, so the two can't drift — hyprland.nix maps it into `bind`, rofi.nix renders the padded two-column sheet (generated/mouse binds live in its `extra` rows). - New binds: SUPER+Space (quick launch), SUPER+M (main menu), SUPER+? (cheatsheet). SUPER+D stays rofi -show drun. - Ask Claude pulls claude-code fresh from npm via `npx @anthropic-ai/claude-code@latest` (the nixpkgs package lags model releases); nodejs is bundled for npx. nix flake check passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,25 @@ let
|
||||
rasiOverride = cfg.themesDir + "/${t.slug}/rofi.rasi";
|
||||
hasRasiOverride = builtins.pathExists rasiOverride;
|
||||
|
||||
# Keybindings cheatsheet (SUPER+? → the `keybinds` menu module). Built
|
||||
# from the SAME ./keybinds.nix that hyprland.nix binds, so it can never
|
||||
# drift from the live shortcuts. "$mod" reads as SUPER; rows are padded
|
||||
# into two columns. extra[] carries the generated/mouse binds.
|
||||
keybinds = import ./keybinds.nix;
|
||||
padRight = w: s:
|
||||
let n = w - builtins.stringLength s;
|
||||
in s + (if n > 0 then lib.concatStrings (builtins.genList (_: " ") n) else " ");
|
||||
prettyKeys = b:
|
||||
let m = lib.replaceStrings [ "$mod" ] [ "SUPER" ] b.mods;
|
||||
prefix = if m == "" then "" else lib.concatStringsSep " + " (lib.splitString " " m) + " + ";
|
||||
key = lib.replaceStrings [ "question" "slash" ] [ "?" "/" ] b.key;
|
||||
in prefix + key;
|
||||
cheatRows =
|
||||
map (b: padRight 22 (prettyKeys b) + b.desc) keybinds.binds
|
||||
++ map (e: padRight 22 e.keys + e.desc) keybinds.extra;
|
||||
cheatsheetFile = pkgs.writeText "nomarchy-keybinds.txt"
|
||||
(lib.concatStringsSep "\n" cheatRows + "\n");
|
||||
|
||||
nomarchy-menu = pkgs.writeShellScriptBin "nomarchy-menu" ''
|
||||
# Nomarchy menu dispatcher — thin presentation layer over
|
||||
# `rofi -dmenu`; actions delegate to nomarchy-theme-sync, systemctl,
|
||||
@@ -89,6 +108,45 @@ let
|
||||
[ -n "$q" ] || exit 0
|
||||
exec xdg-open "https://duckduckgo.com/?q=$(urlencode "$q")" ;;
|
||||
|
||||
network)
|
||||
# nmtui in a terminal (NetworkManager is the system network stack).
|
||||
exec ${cfg.terminal} -e nmtui ;;
|
||||
|
||||
bluetooth)
|
||||
# blueman-manager GUI (services.blueman.enable, system-side).
|
||||
exec blueman-manager ;;
|
||||
|
||||
capture)
|
||||
choice=$(printf '%s\n' \
|
||||
" Region → clipboard" \
|
||||
" Region → file" \
|
||||
" Full screen → clipboard" \
|
||||
" Full screen → file" \
|
||||
| rofi -dmenu -p capture) || exit 0
|
||||
dir="$HOME/Pictures/Screenshots"
|
||||
file="$dir/$(date +%Y%m%d-%H%M%S).png"
|
||||
case "$choice" in
|
||||
*"Region → clipboard"*) grim -g "$(slurp)" - | wl-copy ;;
|
||||
*"Region → file"*) mkdir -p "$dir"; grim -g "$(slurp)" "$file" \
|
||||
&& notify-send "Screenshot saved" "$file" ;;
|
||||
*"Full screen → clipboard"*) grim - | wl-copy ;;
|
||||
*"Full screen → file"*) mkdir -p "$dir"; grim "$file" \
|
||||
&& notify-send "Screenshot saved" "$file" ;;
|
||||
esac ;;
|
||||
|
||||
keybinds)
|
||||
# Read-only cheatsheet, generated from keybinds.nix at build time.
|
||||
rofi -dmenu -i -p keys < ${cheatsheetFile} >/dev/null || exit 0 ;;
|
||||
|
||||
ask)
|
||||
# Free-text question → claude CLI in a terminal (OAuth, no API key).
|
||||
# Pulled fresh from npm via npx rather than nixpkgs' claude-code,
|
||||
# which lags behind model releases; npx caches after first run. The
|
||||
# REPL stays open for follow-ups.
|
||||
q=$(rofi -dmenu -p claude < /dev/null) || exit 0
|
||||
[ -n "$q" ] || exit 0
|
||||
exec ${cfg.terminal} -e npx --yes @anthropic-ai/claude-code@latest "$q" ;;
|
||||
|
||||
"")
|
||||
choice=$(printf '%s\n' \
|
||||
" Apps" \
|
||||
@@ -97,6 +155,11 @@ let
|
||||
" Calculator" \
|
||||
" Files" \
|
||||
" Web search" \
|
||||
" Network" \
|
||||
" Bluetooth" \
|
||||
" Capture" \
|
||||
" Keybindings" \
|
||||
" Ask Claude" \
|
||||
" Power" \
|
||||
| rofi -dmenu -p menu) || exit 0
|
||||
case "$choice" in
|
||||
@@ -106,11 +169,16 @@ let
|
||||
*Calc*) exec "$0" calc ;;
|
||||
*Files*) exec "$0" files ;;
|
||||
*Web*) exec "$0" web ;;
|
||||
*Network*) exec "$0" network ;;
|
||||
*Bluetooth*) exec "$0" bluetooth ;;
|
||||
*Capture*) exec "$0" capture ;;
|
||||
*Keybindings*) exec "$0" keybinds ;;
|
||||
*Ask*) exec "$0" ask ;;
|
||||
*Power*) exec "$0" power ;;
|
||||
esac ;;
|
||||
|
||||
*)
|
||||
echo "usage: nomarchy-menu [power|theme|clipboard|calc|files|web]" >&2
|
||||
echo "usage: nomarchy-menu [power|theme|clipboard|calc|files|web|network|bluetooth|capture|keybinds|ask]" >&2
|
||||
exit 64 ;;
|
||||
esac
|
||||
'';
|
||||
@@ -122,6 +190,7 @@ in
|
||||
pkgs.libqalculate # qalc, the calc module's engine
|
||||
pkgs.fd # files module
|
||||
pkgs.xdg-utils # xdg-open for files/web
|
||||
pkgs.nodejs # npx, for the Ask Claude module (claude-code from npm)
|
||||
];
|
||||
|
||||
programs.rofi = {
|
||||
|
||||
Reference in New Issue
Block a user