mantas6/fzf-php

Interactive fzf command line menus in PHP

v0.4.0 2025-02-17 10:27 UTC

This package is auto-updated.

Last update: 2025-04-24 10:24:00 UTC


README

Fzf Php

GitHub Workflow Status (main) Total Downloads Latest Version License

This package allows you to create fzf powered menus straight from your PHP code.

Demo

Features

  • Automatic fzf binary download
  • Inline fzf configuration
  • Option list styling
  • Selected option preview
  • Live option list reload
  • Laravel support

Installation

Install the package:

composer require mantas6/fzf-php

Usage

Options

Options can be provided in a multitude of ways.

Strings

<?php
use function Mantas6\FzfPhp\fzf;

$selected = fzf(['Apple', 'Orange', 'Grapefruit']);

// returns 'Apple'
  • Returns null if user cancels the prompt

Arrays

<?php

$selected = fzf(
    options: [
        ['Apples', '1kg'],
        ['Oranges', '2kg'],
        ['Grapefruits', '3kg'],
    ]
);

// returns ['Apples', '1kg']
  • Each array element represents different column in the finder

Objects

<?php

$selected = fzf(
    options: [
        new Model('Apple'), // must implement toArray or PresentsForFinder interface
        new Model('Orange'),
        new Model('Grapefruit'),
    ]
);

// returns new Model('Apple')

To use objects as options, at least one is required:

  • Implement toArray
  • Implement PresentsForFinder interface
  • Provide presenter callback

Options presentation

Callback can be provided for presentation. This will work for any options type.

<?php

$selected = fzf(
    options: [
        'Apple',
        'Orange',
        'Grapefruits',
    ],

    present: fn (string $item): string => strtoupper($item),
);

Multiple columns can be present by returning an array.

<?php

$selected = fzf(
    // ...

    present: fn (string $item): array => [
        $item,
        strtoupper($item),
    ],
);

Implementing PresentsForFinder interface

Option objects can implement a special interface, that would work the same as providing a presenter callback.

<?php

use Mantas6\FzfPhp\Concerns\PresentsForFinder;

class Model implements PresentsForFinder
{
    protected string $name;

    public function presentForFinder(): array|string
    {
        return $this->name;
    }
}

Styling

Option columns can be styling using cell() helper function in the presenter callback.

<?php

use function Mantas6\FzfPhp\cell;

$selected = fzf(
    options: [
        ['name' => 'Apples', 'weight' => 1000],
        ['name' => 'Oranges', 'weight' => 2000],
        ['name' => 'Grapefruits', 'weight' => 3000],
    ],

    // Styling individual items
    present: fn (array $item): array => [
        $item['name'],

        cell(
            value: $item['weight'],
            fg: $item['weight'] > 2000 ? 'red' : 'green',
        ),
    ],
);

Formatting options are:

<?php

cell(
    // Text of the cell
    value: 'Text displayed',

    // Alignment in the table (left, right, center)
    align: 'right',

    // Foreground color
    fg: 'white',

    // Background color
    bg: 'red',

    // Column span
    colspan: 2,
);
  • Available colors: red, green, yellow, blue, magenta, cyan, white, default, gray, bright-red, bright-green, bright-yellow, bright-blue, bright-magenta, bright-cyan, bright-white

More information can be found at Symfony Docs: Table

Preview

Preview window can be enabled for each selected option.

<?php

$selected = fzf(
    options: ['Apple', 'Orange', 'Grapefruit'],

    preview: fn (string $item) => strtoupper($item),
);

If more advanced styling is needed, style() helper can be used.

<?php
use function Mantas6\FzfPhp\style;

$selected = fzf(
    // ...
    preview: function (string $item) {
        return style()
            ->table([
                ['Original', $item],
                ['Uppercase', strtoupper($item)],
            ]);
    }
);
  • Use ->table() for creating compact tables
  • Use ->block() for creating text blocks

Additional variables

fzf provides additional variables to the preview (and other) child processes.

<?php
use Mantas6\FzfPhp\ValueObjects\FinderEnv;

$selected = fzf(
    // ...
    preview: function (string $item, FinderEnv $env) {
        // ...
        $env->key, // The name of the last key pressed
        $env->action, // The name of the last action performed
        // ...
    }
);

Full set of variables are available at fzf Reference - Environment variables exported to child processes

Live reload

If options argument is callable, when input value is changed, the options list will be re-fetched.

Input query can be accessed through the FinderEnv object.

<?php
use Mantas6\FzfPhp\ValueObjects\FinderEnv;

$selected = fzf(
    options: function (FinderEnv $env) {
        return [
            $env->query,
            strtoupper($env->query),
            strtolower($env->query),
        ];
    }
);

Headers

Fixed header will be displayed if header list is passed.

<?php

$selected = fzf(
    options: ['Apple', 'Orange', 'Grapefruit'],
    headers: ['Fruit'],
);

Options as object

Instead of passing options as array, object can be used.

<?php

$selected = fzf(
    options: new MyCustomCollection,
);

The class needs to meet one of the following requirements:

  • Must implement the native Traversable interface
  • Needs to implement toArray() method

Multi mode

Retrieve multiple options from a list.

<?php

$selected = fzf(
    options: ['Apple', 'Orange', 'Grapefruit'],
    arguments: ['multi' => true],
);

// ['Apple', 'Orange']
  • Returns [] if user cancels the prompt

Arguments

Pass any other fzf configuration arguments:

<?php

$selected = fzf(
    options: ['Apple', 'Orange', 'Grapefruit'],
    arguments: [
        'height' => '40%',
        'cycle' => true,
    ],
);
  • Arguments delimiter (or d), with-nth are used internally, and will be overridden if specified
  • Arguments that transform output may not be supported
  • Consult fzf Reference for all available options

Reusable object approach

Class instance can be created directly for more reusable approach.

<?php

use Mantas6\FzfPhp\FuzzyFinder;

$finder = new FuzzyFinder;

$fruit = $finder->ask(['Apple', 'Orange', 'Grapefruit']);

// ...

$weight = $finder->ask(['250g', '500g', '1kg']);

Additional configuration is available through the class methods.

<?php

$finder->present(...);

$finder->arguments(...);

Configuration

Use system fzf binary instead of fetching it.

<?php
// YourAppServiceProvider.php

use Mantas6\FzfPhp\FuzzyFinder;

FuzzyFinder::usingCommand(['/usr/bin/env', 'fzf']);
  • Automatic binary download will be disabled when custom command is set

Set global arguments for all prompts.

<?php
// YourAppServiceProvider.php

FuzzyFinder::usingDefaultArguments(['pointer' => '->']);

Binary download

The fzf binary is downloaded automatically on the first use, however you can initiate the download manually.

./vendor/bin/fzf-php-install

Automatic update

To optimize the initial start, especially when CI/CD is used, it is recommended to add this to your composer.json file.

{
    "scripts": {
        "post-update-cmd": [
            "./vendor/bin/fzf-php-install"
        ],
        "post-install-cmd": [
            "./vendor/bin/fzf-php-install"
        ]
    }
}

See also: