From 70a18828b365ceae6708878d200280958b30bdf4 Mon Sep 17 00:00:00 2001 From: "Simen A. W. Olsen" Date: Sun, 16 Aug 2026 18:31:16 +0200 Subject: feat(herdr): declarative config with tmux prefix and repo/nav keymaps - ctrl+s prefix to match tmux - prefix+f: fzf ~/ghq repos into a workspace (twm replacement) - prefix+shift+f: prompt for ghq get, clone, and open - prefix+g: lazygit in the current repo - prefix+j/k and shift+j/k: navigate spaces/agents --- modules/home/herdr.nix | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 modules/home/herdr.nix (limited to 'modules/home/herdr.nix') diff --git a/modules/home/herdr.nix b/modules/home/herdr.nix new file mode 100644 index 0000000..aa14d30 --- /dev/null +++ b/modules/home/herdr.nix @@ -0,0 +1,85 @@ +{ pkgs, ... }: + +let + # twm replacement: fuzzy-pick a repo under ~/ghq and open it as a herdr + # workspace, reusing an already-open workspace with the same name. + repoPicker = pkgs.writeShellApplication { + name = "herdr-repo-picker"; + runtimeInputs = [ pkgs.ghq pkgs.fzf pkgs.jq pkgs.herdr ]; + text = '' + sel=$(ghq list -p | fzf --prompt 'repo ❯ ' --reverse) || exit 0 + [ -n "''${sel:-}" ] || exit 0 + + label=''${sel##*/} + existing=$(herdr workspace list \ + | jq -r --arg l "$label" '.result.workspaces[] | select(.label == $l) | .workspace_id' \ + | head -n1) + + if [ -n "$existing" ]; then + herdr workspace focus "$existing" >/dev/null + else + herdr workspace create --cwd "$sel" --label "$label" --focus >/dev/null + fi + ''; + }; + + # Prompt for a `ghq get` target, clone it, then open the clone as a workspace. + repoGet = pkgs.writeShellApplication { + name = "herdr-repo-get"; + runtimeInputs = [ pkgs.ghq pkgs.herdr ]; + text = '' + read -r -p 'ghq get ❯ ' q || exit 0 + [ -n "''${q:-}" ] || exit 0 + + before=$(ghq list -p | sort) + ghq get "$q" + + # Prefer the repo that appeared; fall back to matching the query. + dir=$(comm -13 <(printf '%s\n' "$before") <(ghq list -p | sort) | head -n1) + [ -n "$dir" ] || dir=$(ghq list -p "$q" | head -n1) + [ -n "$dir" ] || exit 0 + + label=''${dir##*/} + herdr workspace create --cwd "$dir" --label "$label" --focus >/dev/null + ''; + }; +in +{ + home.packages = [ repoPicker repoGet ]; + + home.file.".config/herdr/config.toml".text = '' + [keys] + # Match the tmux prefix (see modules/home/tmux.nix). + prefix = "ctrl+s" + + # Vim-style movement through the sidebar: j/k for spaces, shift+j/k for agents. + next_workspace = "prefix+j" + previous_workspace = "prefix+k" + next_agent = "prefix+shift+j" + previous_agent = "prefix+shift+k" + + # prefix+f: fuzzy-pick a ~/ghq repo and open it as a workspace (replaces `twm`). + [[keys.command]] + key = "prefix+f" + type = "popup" + command = "${repoPicker}/bin/herdr-repo-picker" + width = "70%" + height = "60%" + + # prefix+shift+f: prompt for `ghq get `, clone it, and open it. + [[keys.command]] + key = "prefix+shift+f" + type = "popup" + command = "${repoGet}/bin/herdr-repo-get" + width = "70%" + height = "40%" + + # prefix+g: lazygit in the current pane's repo (replaces tmux `bind g`). + [[keys.command]] + key = "prefix+g" + type = "popup" + command = "${pkgs.lazygit}/bin/lazygit -p \"$HERDR_ACTIVE_PANE_CWD\"" + width = "90%" + height = "90%" + ''; +} -- cgit v1.3.1