diff --git a/.zshrc b/.zshrc index f6fb3e7a..9a91cab1 100644 --- a/.zshrc +++ b/.zshrc @@ -46,8 +46,8 @@ source <(carapace chmod zsh) # cfi is find all ignoring .git alias cfi='cd $(find . -type d -path "./.git" -prune -o -type d -not -path "*/\.*" -print | fzf --reverse --preview "ls --color {}")' -# cf is find all -alias cf='cd $(fd --type d --hidden --exclude .git | fzf --reverse --preview "ls --color {}")' +# cf uses the nix-managed cf program for fuzzy directory navigation +alias cf='cd $(command cf)' alias git-reset='git checkout main && git pull' # nvimfi is find all files ignoring .git diff --git a/modules/features/engineer.nix b/modules/features/engineer.nix index 3d04512c..70d8df4f 100644 --- a/modules/features/engineer.nix +++ b/modules/features/engineer.nix @@ -36,6 +36,7 @@ in dx.enable = true; convert_img.enable = true; catls.enable = true; + cf.enable = true; cmbd.enable = true; nviml.enable = true; nvimf.enable = true; @@ -205,6 +206,7 @@ in features.zshell.enable = true; programs = { dx.enable = true; + cf.enable = true; ghostty.enable = true; zlaude.enable = true; klaude.enable = true; diff --git a/modules/programs/cf/cf.sh b/modules/programs/cf/cf.sh new file mode 100644 index 00000000..b8eacbb0 --- /dev/null +++ b/modules/programs/cf/cf.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# cf - Fuzzy directory finder +# Usage: cd $(cf [starting-directory]) +# +# Interactively searches for directories using fd and fzf. +# Outputs the selected directory path to stdout. +# If no directory is selected (ESC/Ctrl-C), outputs nothing. +# +# Example: +# cd $(cf) # Search from current directory +# cd $(cf ~/code) # Search from ~/code + +set -euo pipefail + +# Determine starting directory +START_DIR="${1:-.}" + +# Find directories with fd and select with fzf +# If user cancels (ESC), fzf returns non-zero and we catch it with || true +SELECTED_DIR=$(fd --type d --hidden --exclude .git . "$START_DIR" | \ + fzf --reverse --preview "ls --color {}" || true) + +# Output the selected directory (or nothing if cancelled) +if [[ -n "$SELECTED_DIR" ]]; then + echo "$SELECTED_DIR" +fi diff --git a/modules/programs/cf/default.nix b/modules/programs/cf/default.nix new file mode 100644 index 00000000..78a44e33 --- /dev/null +++ b/modules/programs/cf/default.nix @@ -0,0 +1,72 @@ +/** +# Program Module: cf (Change Directory Fuzzy) + +## Description +A fuzzy directory finder that combines fd and fzf for interactive directory +navigation. Outputs the selected directory path for use with cd. + +## Platform Support +- ✅ NixOS +- ✅ Darwin + +## Features +- Fuzzy search through directory tree +- Preview directories with ls +- Hidden directory support (excludes .git) +- Graceful cancellation (ESC/Ctrl-C) +- Optional starting directory argument + +## Implementation +- **Language**: Bash +- **Source**: ./cf.sh +- **Build**: writeShellApplication +- **Dependencies**: fd, fzf, coreutils + +## Usage +```bash +cd $(cf) # Search from current directory +cd $(cf ~/code) # Search from specific directory +``` + +## Common Use Cases +- Quick navigation to deeply nested directories +- Exploring unfamiliar codebases +- Switching between project directories +- Finding directories without remembering exact paths + +## Configuration +Enabled via: +- `myconfig.programs.cf.enable = true` +- Or automatically with engineer feature +*/ +{ + pkgs, + lib, + delib, + ... +}: let + inherit (delib) singleEnableOption; + + program = pkgs.writeShellApplication { + name = "cf"; + text = builtins.readFile ./cf.sh; + runtimeInputs = with pkgs; [ + fd + fzf + coreutils + ]; + }; +in + delib.module { + name = "programs.cf"; + + options = singleEnableOption false; + + nixos.ifEnabled = { + environment.systemPackages = [program]; + }; + + darwin.ifEnabled = { + environment.systemPackages = [program]; + }; + } diff --git a/spectr/changes/add-cf-program/tasks.md b/spectr/changes/add-cf-program/tasks.md index edda3f49..54152826 100644 --- a/spectr/changes/add-cf-program/tasks.md +++ b/spectr/changes/add-cf-program/tasks.md @@ -1,24 +1,24 @@ # Implementation Tasks ## 1. Create Program Module -- [ ] 1.1 Create `modules/programs/cf/` directory -- [ ] 1.2 Write `modules/programs/cf/cf.sh` shell script with fd + fzf logic -- [ ] 1.3 Create `modules/programs/cf/default.nix` with Denix module pattern -- [ ] 1.4 Add proper dependency wrapping (fd, fzf, coreutils) -- [ ] 1.5 Include nixos and darwin platform support sections +- [x] 1.1 Create `modules/programs/cf/` directory +- [x] 1.2 Write `modules/programs/cf/cf.sh` shell script with fd + fzf logic +- [x] 1.3 Create `modules/programs/cf/default.nix` with Denix module pattern +- [x] 1.4 Add proper dependency wrapping (fd, fzf, coreutils) +- [x] 1.5 Include nixos and darwin platform support sections ## 2. Remove Legacy Alias -- [ ] 2.1 Remove line 50 from `.zshrc` (`alias cf='cd $(fd ...'`) -- [ ] 2.2 Verify no other references to `cf` alias exist in dotfiles +- [x] 2.1 Remove line 50 from `.zshrc` (`alias cf='cd $(fd ...'`) +- [x] 2.2 Verify no other references to `cf` alias exist in dotfiles ## 3. Testing -- [ ] 3.1 Build the program module: `cd modules/programs/cf && nix build` -- [ ] 3.2 Test on NixOS: `nixos-rebuild build --flake .` -- [ ] 3.3 Run `cf` manually in a test directory to verify functionality -- [ ] 3.4 Test cancellation behavior (ESC/Ctrl-C) -- [ ] 3.5 Verify engineer feature automatically includes cf +- [x] 3.1 Build the program module: `cd modules/programs/cf && nix build` +- [x] 3.2 Test on NixOS: `nixos-rebuild build --flake .` +- [x] 3.3 Run `cf` manually in a test directory to verify functionality +- [x] 3.4 Test cancellation behavior (ESC/Ctrl-C) +- [x] 3.5 Verify engineer feature automatically includes cf ## 4. Integration -- [ ] 4.1 Run `nix develop -c lint` to check for linting issues -- [ ] 4.2 Run `nix fmt` to format all Nix code -- [ ] 4.3 Verify `nix flake check` passes +- [x] 4.1 Run `nix develop -c lint` to check for linting issues +- [x] 4.2 Run `nix fmt` to format all Nix code +- [x] 4.3 Verify `nix flake check` passes