PSFuzzyMenu.ps1

<#PSScriptInfo
 
.VERSION 0.1.3
 
.GUID 9213ef55-5768-4b35-81a0-56476af9e248
 
.AUTHOR littleboyharry@qq.com
 
.COMPANYNAME
 
.COPYRIGHT MIT
 
.TAGS fzf menu CUI
 
.LICENSEURI
 
.PROJECTURI https://gist.github.com/LittleboyHarry/529c3e91e292ec918a9c8a3920a694ae
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
 
.PRIVATEDATA
 
#>
 



<#
 
.DESCRIPTION
 a script to make an interactive menu requiring fzf by PowerShell.
#>


class _FuzzyMenuItem {

    [string]$Name
    [scriptblock]$Action

    _FuzzyMenuItem(
        $n,
        $a
    ) {
        $this.Name = $n
        $this.Action = $a
    }
}

class FuzzyMenu {
    hidden [string]$content
    hidden [scriptblock[]]$actions = @()

    [string]$header = "Please select a action:"
    [int]$item_count = 10
    [string]$other_args = ""

    [void]Show() {
        $selected = $this.content | & fzf `
            --cycle `
            --info=hidden `
            --height=$($this.item_count+2) `
            --header="$($this.header) (1..$($this.actions.Length))" `
            --layout=reverse `
            $this.other_args;

        if ($selected ) {
            & $this.actions[([int]($selected.Split(".", 2)[0]) - 1)] | Write-Host
        }
    }
}

class FuzzyMenuInflater {
    [_FuzzyMenuItem[]] $items = @()

    [void]AddItem([string]$name, [scriptblock]$action) {
        $this.items += [_FuzzyMenuItem]::new($name, $action)
    }

    [void]inflate([FuzzyMenu]$menu) {
        $buffer = [System.Text.StringBuilder]::new()
        $actions = @()
        for ($index = 0; $index -lt $this.items.Length; $index++) {
            $item = $this.items[$index]
            $buffer.AppendLine("$($index+1). $($item.Name)")
            $actions += $item.Action
        }
        $menu.content = $buffer.ToString()
        $menu.actions = $actions
    }
}