Public/Invoke-DFPicker.ps1
|
#Requires -Version 7.0 function Invoke-DFPicker { <# .SYNOPSIS Generalized fzf picker. Handles list -> fzf -> parse -> action skeleton. .PARAMETER List Scriptblock that produces the items to display in fzf. .PARAMETER Header Header text shown at the top of the fzf window. .PARAMETER Preview fzf --preview string. Use {} as placeholder for the selected item. .PARAMETER PreviewWindow fzf --preview-window value. Default: 'right:60%'. .PARAMETER Ansi Pass --ansi to fzf (for ANSI-colored input). .PARAMETER Multi Pass --multi to fzf; Action is called once per selected item. .PARAMETER Delimiter fzf --delimiter value. .PARAMETER WithNth fzf --with-nth value (which fields to display). .PARAMETER Parse Scriptblock to transform the raw fzf output line. $_ is the raw line. If omitted, the raw line is used as-is. .PARAMETER Action Scriptblock invoked with the parsed value as param($v). If omitted, the parsed value is written to the output stream. .DESCRIPTION Invokes fzf with the provided list, optional preview, header, and flags. The selected item is optionally transformed by -Parse, then passed to -Action or returned on the output stream. Uses the private Invoke-DFFzf wrapper so callers can mock fzf in tests without spawning a real process. .EXAMPLE Invoke-DFPicker -List { git branch } -Header 'Select branch' -Action { param($b) git checkout $b } Fuzzy-selects a git branch and checks it out. .EXAMPLE $file = Invoke-DFPicker -List { Get-ChildItem -Name } -Preview 'cat {}' Fuzzy-selects a file from the current directory; returns the selected name. .OUTPUTS System.String — selected (and optionally parsed) item when -Action is omitted. None — when -Action is provided (side-effect only). #> [CmdletBinding()] param( [Parameter(Mandatory)][scriptblock]$List, [string]$Header = '', [string]$Preview = '', [string]$PreviewWindow = 'right:60%', [switch]$Ansi, [switch]$Multi, [string]$Delimiter = '', [string]$WithNth = '', [scriptblock]$Parse, [scriptblock]$Action ) $fzfArgs = [System.Collections.Generic.List[string]]@('--preview-window', $PreviewWindow) if ($Preview) { $fzfArgs.AddRange([string[]]@('--preview', $Preview)) } if ($Header) { $fzfArgs.AddRange([string[]]@('--header', $Header)) } if ($Ansi) { $fzfArgs.Add('--ansi') } if ($Multi) { $fzfArgs.Add('--multi') } if ($Delimiter) { $fzfArgs.AddRange([string[]]@('--delimiter', $Delimiter)) } if ($WithNth) { $fzfArgs.AddRange([string[]]@('--with-nth', $WithNth)) } $items = @(& $List) $selected = Invoke-DFFzf -InputItems $items -FzfArgs $fzfArgs if (-not $selected) { return } foreach ($item in @($selected)) { $value = if ($Parse) { $item | ForEach-Object $Parse } else { $item } if ($Action) { & $Action $value } else { $value } } } |