Commit 9dcb6bdc6e1d
Changed files (4)
home
common
modules
systems
kyushu
home/common/dev/default.nix
@@ -3,6 +3,7 @@
imports = [
./ai.nix
./go.nix
+ ./lazyworktree.nix
./lua.nix
./nix.nix
./python.nix
home/common/dev/lazyworktree.nix
@@ -0,0 +1,44 @@
+{ config, ... }:
+{
+ imports = [ ../../modules/lazyworktree.nix ];
+
+ programs.lazyworktree = {
+ enable = true;
+ enableZshIntegration = true;
+
+ settings = {
+ # UI settings
+ icon_set = "nerd-font-v3";
+ max_name_length = 95;
+ sort_mode = "switched";
+
+ # Use delta for diffs (matches git.nix configuration)
+ git_pager = "delta";
+ git_pager_args = "--paging=never --dark --line-numbers";
+
+ # Editor (matches your typical setup)
+ editor = "emacsclient -t";
+
+ # Workflow settings
+ auto_fetch_prs = false; # Enable manually when needed
+ auto_refresh = true;
+ refresh_interval = 10;
+
+ # Git settings (matches git.nix)
+ merge_method = "rebase";
+
+ # Session management
+ session_prefix = "wt-";
+
+ # Branch naming
+ issue_branch_name_template = "{{.IssueNumber}}-{{.Slug}}";
+ pr_branch_name_template = "pr-{{.PRNumber}}-{{.Slug}}";
+ };
+
+ # Quick aliases for commonly used repositories
+ aliases = {
+ # Home configuration
+ wh = "${config.home.homeDirectory}/src/home";
+ };
+ };
+}
home/modules/lazyworktree.nix
@@ -0,0 +1,242 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ inherit (lib) mkIf types;
+
+ cfg = config.programs.lazyworktree;
+
+ yamlFormat = pkgs.formats.yaml { };
+
+ configDir =
+ if pkgs.stdenv.hostPlatform.isDarwin && !config.xdg.enable then
+ "Library/Application Support"
+ else
+ config.xdg.configHome;
+
+ worktreeDir =
+ if cfg.worktreeDirectory != null then
+ cfg.worktreeDirectory
+ else
+ "${config.home.homeDirectory}/.local/share/worktrees";
+in
+{
+ options.programs.lazyworktree = {
+ enable = lib.mkEnableOption "lazyworktree, a TUI for managing Git worktrees";
+
+ package = lib.mkPackageOption pkgs "lazyworktree" { nullable = true; };
+
+ worktreeDirectory = lib.mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "~/worktrees";
+ description = ''
+ Override the default worktree root directory.
+ Defaults to `~/.local/share/worktrees`.
+ '';
+ };
+
+ settings = lib.mkOption {
+ type = yamlFormat.type;
+ default = { };
+ defaultText = lib.literalExpression "{ }";
+ example = lib.literalExpression ''
+ {
+ theme = "nord";
+ icon_set = "nerd-font-v3";
+ editor = "nvim";
+ auto_fetch_prs = true;
+ git_pager = "delta";
+ }
+ '';
+ description = ''
+ Configuration written to
+ {file}`$XDG_CONFIG_HOME/lazyworktree/config.yaml`
+ on Linux or on Darwin if [](#opt-xdg.enable) is set, otherwise
+ {file}`~/Library/Application Support/lazyworktree/config.yaml`.
+ See
+ <https://github.com/chmouel/lazyworktree>
+ for supported values.
+ '';
+ };
+
+ enableZshIntegration = lib.mkEnableOption "zsh integration" // {
+ default = true;
+ };
+
+ enableBashIntegration = lib.mkEnableOption "bash integration";
+
+ shellWrapperName = lib.mkOption {
+ type = types.str;
+ default = "lwt";
+ example = "wt";
+ description = ''
+ Name of the shell wrapper function for jumping to worktrees.
+ '';
+ };
+
+ aliases = lib.mkOption {
+ type = types.attrsOf types.str;
+ default = { };
+ example = lib.literalExpression ''
+ {
+ pm = "~/git/myrepo";
+ home = "~/src/home";
+ }
+ '';
+ description = ''
+ Repository aliases for quick worktree jumping.
+ Each key becomes a shell function that jumps to that repository's worktrees.
+ '';
+ };
+ };
+
+ config = mkIf cfg.enable {
+ home.packages = mkIf (cfg.package != null) [ cfg.package ];
+
+ home.file."${configDir}/lazyworktree/config.yaml" = {
+ enable = cfg.settings != { };
+ source = yamlFormat.generate "lazyworktree-config" cfg.settings;
+ };
+
+ programs =
+ let
+ # Helper to extract repo slug from git remote
+ gitRepoSlugFunction = ''
+ _lwt_git_repo_slug() {
+ local dir="$1"
+ local url slug
+
+ url=$(cd "$dir" 2>/dev/null && git remote get-url origin 2>/dev/null) || return 1
+ slug=$(echo "$url" | sed -E 's#^.*[:/]([^/]+/[^/]+)(\.git)?$#\1#')
+ [[ -n "$slug" ]] || return 1
+ echo "$slug"
+ }
+ '';
+
+ # Shell function to jump to worktrees with directory change on exit
+ shellWrapperFunction = ''
+ ${cfg.shellWrapperName}() {
+ local dir="$1"; shift
+ local repo slug
+
+ if [[ -z "$dir" || ! -d "$dir" ]]; then
+ echo >&2 "${cfg.shellWrapperName}: invalid directory: $dir"
+ return 1
+ fi
+
+ slug=$(_lwt_git_repo_slug "$dir" 2>/dev/null)
+ repo="''${slug:-$(basename "$dir")}"
+
+ local wt_root="${worktreeDir}/$repo"
+
+ # Direct jump if worktree name provided
+ if [[ -n "$1" && -d "$wt_root/$1" ]]; then
+ cd "$wt_root/$1" || return 1
+ return
+ fi
+
+ cd "$dir" || return 1
+
+ local tmp selected
+ tmp=$(mktemp "''${TMPDIR:-/tmp}/lazyworktree.selection.XXXXXX") || return 1
+ lazyworktree --output-selection="$tmp"
+ local rc=$?
+ if [[ $rc -ne 0 ]]; then
+ rm -f "$tmp"
+ return $rc
+ fi
+
+ if [[ -s "$tmp" ]]; then
+ selected=$(<"$tmp")
+ [[ -n "$selected" && -d "$selected" ]] && cd "$selected" || true
+ fi
+ rm -f "$tmp"
+ }
+ '';
+
+ # Function to jump to last selected worktree
+ goLastFunction = ''
+ ${cfg.shellWrapperName}_go_last() {
+ local dir="$1"
+ local repo slug last_selected selected
+
+ if [[ -z "$dir" || ! -d "$dir" ]]; then
+ echo >&2 "${cfg.shellWrapperName}_go_last: invalid directory: $dir"
+ return 1
+ fi
+
+ slug=$(_lwt_git_repo_slug "$dir" 2>/dev/null)
+ repo="''${slug:-$(basename "$dir")}"
+
+ last_selected="${worktreeDir}/$repo/.last-selected"
+ if [[ -f "$last_selected" ]]; then
+ selected=$(<"$last_selected")
+ if [[ -n "$selected" && -d "$selected" ]]; then
+ cd "$selected" || return 1
+ return
+ fi
+ fi
+
+ echo >&2 "No last selected worktree found"
+ return 1
+ }
+ '';
+
+ shellFunctions = ''
+ # lazyworktree shell integration
+ ${gitRepoSlugFunction}
+ ${shellWrapperFunction}
+ ${goLastFunction}
+ '';
+
+ # Zsh completion for alias functions (completes worktree names)
+ zshAliasCompletion = ''
+ _lwt_complete_worktrees() {
+ local dir="$1"
+ local repo slug wt_root
+
+ slug=$(_lwt_git_repo_slug "$dir" 2>/dev/null)
+ repo="''${slug:-$(basename "$dir")}"
+
+ wt_root="${worktreeDir}/$repo"
+ [[ -d "$wt_root" ]] || return
+
+ local -a dirs
+ dirs=(''${wt_root}/*(/:t))
+ _describe 'worktree' dirs
+ }
+ '';
+
+ aliasDefinitions = lib.concatStringsSep "\n" (
+ lib.mapAttrsToList (name: dir: ''
+ ${name}() { ${cfg.shellWrapperName} ${dir} "$@" }
+ '') cfg.aliases
+ );
+
+ zshAliasCompletions = lib.concatStringsSep "\n" (
+ lib.mapAttrsToList (name: dir: ''
+ _${name}() { _lwt_complete_worktrees ${dir} }
+ compdef _${name} ${name}
+ '') cfg.aliases
+ );
+
+ in
+ {
+ bash.initExtra = mkIf cfg.enableBashIntegration ''
+ ${shellFunctions}
+ ${aliasDefinitions}
+ '';
+
+ zsh.initContent = mkIf cfg.enableZshIntegration ''
+ ${shellFunctions}
+ ${zshAliasCompletion}
+ ${aliasDefinitions}
+ ${zshAliasCompletions}
+ '';
+ };
+ };
+}
systems/kyushu/home.nix
@@ -9,6 +9,7 @@ in
{
imports = [
../../home/common/dev/containers.nix
+ ../../home/common/dev/lazyworktree.nix
../../home/common/dev/tektoncd.nix
../../home/common/services/color-scheme-timer.nix
../../home/common/services/gcal-to-org.nix
@@ -51,7 +52,6 @@ in
qmk_hid
wip.voxtype
- lazyworktree
startpaac