# LibTmux::Selection

- **Module:** LibTmux
- **Package:** LibTmux
- **Language:** Perl
- **Kind:** class
- **Source:** https://github.com/libtmux/libtmux-perl/blob/352715a4fa66a96eed7763b90daaa536aa2f121d/packages/core/lib/LibTmux/Selection.pm#L1
- **Page:** https://libtmux.org/en/perl/latest/reference/libtmux-selection/

```
package LibTmux::Selection;
```

Native array selections with fixed query returns


## EXECUTION

All methods in this module operate on local captured data and perform no tmux I/O. Ordering is deterministic; public query methods do not mutate membership. Typed validation/evaluation errors propagate. See [`"snapshot" in LibTmux::Server`](/en/perl/latest/reference/libtmux-server-snapshot/) for explicit acquisition and [`LibTmux::X`](/en/perl/latest/reference/libtmux-x/) for machine-readable failures.



## Examples

Complete installed-package program with an owned tmux fixture and result/cleanup assertions.

[Source example](https://github.com/libtmux/libtmux-perl/blob/352715a4fa66a96eed7763b90daaa536aa2f121d/examples/selection.pl).

```perl
use v5.44;
use FindBin;
use lib "$FindBin::Bin/../scripts/lib";
use LibTmuxFixture;
use LibTmux::Filter;
use List::Util qw(any first);
LibTmuxFixture->run(
    sub ($server, $root) {
        my $session = $server->new_session(
            name    => 'example',
            command => ['/bin/sleep', '120']
        );
        my $initial = $session->window_links->one->window->panes->one;
        $server->split_pane(
            pane       => $initial,
            horizontal => true,
            command    => ['/bin/sleep', '120']
        );
        my $snapshot = $server->snapshot;
        my $panes    = $snapshot->panes->where({current_command => 'sleep'})
            ->grep(sub ($pane) { $pane->width >= 1 });
        die 'expected two panes' unless $panes->count == 2;
        for my $pane ($panes->@*) {
            say $pane->id . ' ' . $pane->current_command;
        }
        my $only_active = $panes->one({active => true});
        die 'active pane unavailable' unless defined $only_active;
        my $has_active   = any { $_->active } $panes->@*;
        my $first_active = first { $_->active } $panes->@*;
        die 'List::Util alternatives differ'
            unless $has_active && $first_active->id eq $only_active->id;
        my @ids      = map  { $_->id } $panes->@*;
        my @positive = grep { $_->width > 0 } $panes->@*;
        die 'ordinary Perl arrays differ' unless @ids == 2 && @positive == 2;
        my $filter =
            LibTmux::Filter->new(entity => 'pane', where => {active => true});
        my $decoded = LibTmux::Filter->from_json($filter->to_json);
        die 'wire filter changed meaning'
            unless $panes->where($decoded)->one->id eq $only_active->id;
        my $retained = do {
            my $observed = $server->snapshot;
            $observed->pane_by_id($only_active->id);
        };
        die 'retained graph lost a relationship'
            unless $retained->window->panes->count == 2;
        my $same_child = $snapshot->windows->where(
            {panes => {-some => {-and => [{index => 0}, {index => 1}]}}});
        my $different_children = $snapshot->windows->where(
            {
                -and => [
                    {panes => {-some => {index => 0}}},
                    {panes => {-some => {index => 1}}}
                ]
            }
        );
        die 'quantifiers conflated children'
            unless $same_child->count == 0 && $different_children->count == 1;
        my $where = {active => true, width => {-gte => 1}};
        my $local = $server->query_panes(where => $where, pushdown => 'never');
        my $verification;
        my $native = $server->query_panes(
            where           => $where,
            pushdown        => 'require',
            on_verification => sub ($report) { $verification = $report },
        );
        die 'native verification was not observed'
            unless $verification->{status} eq 'agreed'
            && $verification->{comparison} eq 'exact_ids';
        die 'native/local disagreement'
            unless join(',', map { $_->id } @$local) eq
            join(',', map { $_->id } @$native);
        say 'selection, wire, graph lifetime, quantifiers, and query: ok';
    }
);
```

## Members

### Other members

- [`count`](/en/perl/latest/reference/libtmux-selection-count/) (method): `count($criteria?)` returns an integer. Empty input returns zero. Validate all members before evaluating the optional criterion; count every matching occurrence, including duplicates.
- [`exists`](/en/perl/latest/reference/libtmux-selection-exists/) (method): `exists($criteria?)` returns a native Boolean. Empty input returns false. After validating the entire membership, stop at the first matching entity. A reference itself remains true even when empty.
- [`first`](/en/perl/latest/reference/libtmux-selection-first/) (method): `first($criteria?)` returns the first matching entity or undef. Input order determines first; after membership validation, later field reads may be skipped.
- [`grep`](/en/perl/latest/reference/libtmux-selection-grep/) (method): `grep($callback)` returns a new same-class selection. Invoke the callback in scalar context with exactly one entity argument and a localized `$_`. Both bindings hold copies of the reference: assignment cannot replace a source slot. Restore `$_` and propagate the original thrown value even on failure. Predicates must not edit the traversed sequence.
- [`iterator`](/en/perl/latest/reference/libtmux-selection-iterator-2bn1/) (method): Return a fresh local cursor with a copy of current membership. Its `next` returns an entity or undef only at exhaustion. Later native array edits do not alter this traversal; the selection remains replayable.
- [`new`](/en/perl/latest/reference/libtmux-selection-new/) (method): `new(@entities)` creates a concrete blessed array reference and validates every member. Construct an entity-specific selection such as [`LibTmux::PaneSelection`](/en/perl/latest/reference/libtmux-paneselection/); an empty instance retains that schema.
- [`one`](/en/perl/latest/reference/libtmux-selection-one/) (method): `one($criteria?)` returns one entity. Zero throws [`NoMatch`](/en/perl/latest/reference/libtmux-x-nomatch/); a second occurrence throws [`MultipleMatches`](/en/perl/latest/reference/libtmux-x-multiplematches/), reporting at least two and their IDs. Two occurrences of one identity are still ambiguous.
- [`one_or_undef`](/en/perl/latest/reference/libtmux-selection-one_or_undef/) (method): `one_or_undef($criteria?)` returns an entity or undef for absence. A second matching occurrence still throws [`MultipleMatches`](/en/perl/latest/reference/libtmux-x-multiplematches/).
- [`to_array`](/en/perl/latest/reference/libtmux-selection-to_array/) (method): Return a fresh, unblessed array reference containing the same entity references. Editing its membership cannot corrupt graph adjacency or this selection. Captured entity values remain read-only through public readers.
- [`where`](/en/perl/latest/reference/libtmux-selection-where/) (method): `where($criteria_or_filter)` eagerly returns a new selection of the same concrete class in scalar, list, or void context. Complete validation precedes evaluation, including on empty input. See [`"new" in LibTmux::Filter`](/en/perl/latest/reference/libtmux-filter-new/). Order and duplicate occurrences are preserved.
