Obtain one snapshot, then select its observed panes:
alias LibTmux.{Selection, Snapshot}
editors =
snapshot
|> Snapshot.panes()
|> Selection.where(active: true, current_command: [in: ["nvim", "vim"]])
Enum.map(editors, & &1.id)Selections retain their immutable graph and order. Enumerable delegates to
the materialized list, including suspension and early halt. size/1 uses
the cached count; ordinary Enum.member?/2 compares elements. Use
Selection.member_id?/2 for native ID membership. Enumeration performs no I/O.
Selection.filter/2 accepts only unary functions and uses Enum truthiness.
Predicate exceptions propagate. where/2 accepts validated data: keywords
are shorthand for maps, with duplicate keys rejected at every nesting level.
Both validate before scanning, including when no items remain.
one/2 returns {:ok, item} or a structured :no_match / :multiple_matches
error. one_or_nil/2 permits zero matches. Their bang variants raise the
same error; both stop at the second match. exists?/2 stops at its first
match. count/2 counts matching items; size/1 returns the cached total.
Predicate grammar
A bare scalar means equality. Explicit %{equals: value} is equivalent.
The generated schema lists each field's type and operators.
Numbers compare numerically, strings compare case-sensitively without
normalization, and nullable numeric ordering against known nil is false.
not negates equality; not_in negates membership, including known nil.
Portable regex is not supported. Native predicates may use Regex directly.
Fields in one object conjoin. Boolean and and or accept lists of
criteria; not accepts one criteria object. Empty and is true and empty
or is false. Normalization never combines separate relation quantifiers:
Selection.where(Snapshot.sessions(snapshot), %{
panes: %{some: %{active: true, current_command: "nvim"}}
})That predicate requires one pane to satisfy both conditions. Two separate
some clauses can match different panes. every and none are true for
a known-empty relation; some is false. count counts that relation's
identities: physical windows/panes deduplicate, window links retain memberships.
To-one is: criteria is false for known absence and is_not negates it.
is: nil means absent; is_not: nil means present. Session active_window
is derived from a complete link domain and loaded active flags. Zero active
links means known absence; multiple active links raise :ambiguous_relation.
An unresolved active target remains unloaded. Coverage checks run before
evaluation, including fields behind a Boolean branch that cannot match.
External filters
Filter.new/3 returns a validated portable value, and new!/3 raises its
structured error. Applying that value retains its constructor validation;
explicit new limits validate the normalized tree without generating extra
criteria objects. Prepared predicates may contain
sets and closures; portable filters contain data only.
Filter.from_json/3 uses built-in JSON and rejects duplicate keys before
map conversion, trailing data and unknown names. from_wire/3 accepts an
already decoded map; that map cannot reveal discarded duplicate keys.
Neither decoder creates atoms from external keys. Encode through
Filter.to_wire/1, then JSON.encode!/1.
{"version":1,"entity":"pane","where":{"active":true,"currentCommand":{"in":["nvim","vim"]}}}Default ceilings are 65,536 bytes, depth 16, 1024 value nodes, 256 array
elements and 8192 bytes per string. Wire depth starts at root zero and
counts every member/element; the ceiling is inclusive. Positive integer
options max_bytes, max_depth, max_nodes, max_list and
max_string_bytes can narrow or widen the constructor budget. JSON object
members have a fixed ceiling of 256. Native input depth counts criteria
objects and also bounds the normalized tree. A normalized conjunction does
not add relation/Boolean nesting; disjunctions, negations and relation
children do. Wire budgets additionally cover the full versioned envelope.
Errors carry the affected path, including Boolean and membership indexes;
early parser-limit errors can identify the root before a path is available.
Selections and filters operate on captured values. Server query planning and pushdown remain under implementation.