Public/Tools/Enable-Fd.ps1
|
function Enable-Fd { <# .SYNOPSIS Installs (if necessary) and activates fd, a fast and friendly `find` alternative, for the session. .DESCRIPTION Runs two nested Invoke-Step substeps: - Install: if fd.exe isn't on PATH, installs it with winget (sharkdp.fd, a portable package) and patches the current session's PATH so the Initialize substep can see it immediately. - Initialize (guarded by Get-Command fd.exe): configures fd for the session: * When -LsColors is non-empty, sets $env:LS_COLORS so fd's output (directories, symlinks, executables, …) is colored to match the active oh-my-posh theme. Initialize-PwshProfile resolves this from the theme's branding. fd has no fd-specific color variable — LS_COLORS is the mechanism it (and ls/eza) read — so an empty value leaves LS_COLORS untouched. * Registers fd's PowerShell tab completion. fd emits a Register-ArgumentCompleter script via `fd --gen-completions powershell`; it is run through Invoke-InGlobalScope (not a bare Invoke-Expression) so the registered completer lands in the true global scope and isn't tagged to this module — see Private/Core/Invoke-InGlobalScope.ps1. * When -IntegrateFzf is set and fzf.exe is on PATH, points fzf at fd as its source by setting $env:FZF_DEFAULT_COMMAND, so a bare `fzf` lists files via fd (respecting .gitignore). The Ctrl+T file picker is driven by PSFzf's own fd provider (Set-PsFzfOption -EnableFd, set by Enable-Fzf), so no FZF_CTRL_T_COMMAND is needed. fzf's own picker palette is themed separately by Enable-Fzf (which owns $env:FZF_DEFAULT_OPTS, including the --ansi that renders fd's `--color=always` output in the picker). fd is a STANDALONE utility: it never aliases or replaces Get-ChildItem, `ls`, or any other configured command. Enabling it only puts `fd` on PATH (plus colors and completion). If the install doesn't produce fd.exe on PATH, a warning is emitted (with winget's captured output) and Initialize is skipped (guarded by Get-Command) so profile startup continues. .PARAMETER LsColors An LS_COLORS spec assigned to $env:LS_COLORS for the session (e.g. 'di=1;38;2;201;170;255:ln=38;2;95;215;255'), coloring fd's output. Initialize-PwshProfile resolves this from the active theme's branding so fd's colors match the prompt. An empty value leaves $env:LS_COLORS untouched. Note: LS_COLORS is a shared variable also read by ls and eza. .PARAMETER IntegrateFzf When set (and fzf.exe is on PATH), wires fzf to use fd as its file source by setting $env:FZF_DEFAULT_COMMAND (the command a bare `fzf` runs). Off by default. Initialize-PwshProfile passes this when fzf is not skipped; the inner Get-Command fzf.exe guard means it is a no-op when fzf isn't installed. .EXAMPLE Enable-Fd Installs fd if needed and registers its tab completion, leaving colors and fzf alone. .EXAMPLE Enable-Fd -LsColors 'di=1;38;2;201;170;255:ln=38;2;95;215;255' -IntegrateFzf Colors fd's output to match the Screw City palette and points fzf at fd as its source. .NOTES Standalone file finder (https://github.com/sharkdp/fd). fd is clap-based, so it ships its own PowerShell completer (`fd --gen-completions powershell`), registered here in the Initialize substep (run in the global scope so it isn't attributed to the module). Call after Enable-Fzf so fzf.exe is already on PATH when -IntegrateFzf is evaluated. #> [CmdletBinding()] param( [Parameter()] [string]$LsColors = '', [Parameter()] [switch]$IntegrateFzf ) Invoke-Step "Install" { # fd is a winget portable: its exe lands in the default Links dir. Install-WingetPackageSafe -Id 'sharkdp.fd' -Exe 'fd.exe' -CallerName 'Enable-Fd' } Invoke-Step "Initialize" { if (Get-Command fd.exe -ErrorAction SilentlyContinue) { # fd colors come from $env:LS_COLORS (process-global already, so a plain assignment — # no Invoke-InGlobalScope needed for env vars). if (-not [string]::IsNullOrWhiteSpace($LsColors)) { $env:LS_COLORS = $LsColors } # Register fd's completer in the global scope (not this module's) so it isn't tagged to # the module — see Private/Core/Invoke-InGlobalScope.ps1. Invoke-InGlobalScope ((fd --gen-completions powershell) | Out-String) # When asked, point fzf at fd as its source (only if fzf is actually present). A bare # `fzf` reads $env:FZF_DEFAULT_COMMAND directly; fzf's own palette/--ansi is set by # Enable-Fzf. The Ctrl+T widget is driven by PSFzf's own fd provider (Set-PsFzfOption # -EnableFd), so there's no FZF_CTRL_T_COMMAND to set here. if ($IntegrateFzf -and (Get-Command fzf.exe -ErrorAction SilentlyContinue)) { $env:FZF_DEFAULT_COMMAND = 'fd --type file --color=always --hidden --follow --exclude .git' } } } } |