Current section
Files
Jump to
Current section
Files
src/i3_client_trees.erl
-module(i3_client_trees).
-moduledoc """
Functions for processing i3 layout trees.
All functions assume they receive the whole tree, as returned by
`i3_client:get_tree/1,2`.
""".
-export([table/1, table/2]).
-include_lib("stdlib/include/qlc.hrl").
-doc """
Equivalent to [`table(Tree, dfs)`](`table/2`).
""".
-spec table(Table) -> QueryHandle when
Table :: map(),
QueryHandle :: qlc:query_handle().
table(Tree) ->
table(Tree, dfs).
-doc """
Returns a Query List Comprehension (QLC) query handle.
The `m:qlc` module provides a query language, very similar to list
comprehensions, which allows iterator style traversal of data
structures. Calling `table/1,2` is the means to make the i3 tree
`Tree` usable to QLC.
The `Algo` argument can be either `dfs` or `bfs` which stand for
depth-first and breadth-first traversal respectively. Usually,
depth-first traversal is preferred so it's the default when calling
`table/1`.
_Examples:_
An example query for the focused node:
```erlang
0> {ok, Pid} = i3_client:start_link([]),
1> {ok, Tree} = i3_client:get_tree(Pid),
2> QH = qlc:q([Node || #{~"focused" := true} = Node <- i3_client_trees:table(Tree)]).
3> [#{~"focused" := true}] = qlc:eval(QH)
```
> #### Info {: .info }
> It is necessary to add the following line to the source code:
> ```
> -include_lib("stdlib/include/qlc.hrl").
> ```
""".
-spec table(Table, Algo) -> QueryHandle when
Table :: map(),
Algo :: dfs | bfs,
QueryHandle :: qlc:query_handle().
table(Tree, Algo) when (Algo =:= dfs) or (Algo =:= bfs) ->
TraverseFun = fun() -> next([[Tree]], Algo) end,
qlc:table(TraverseFun, []).
next([], _) ->
[];
next([[] | Rest], Algo) ->
next(Rest, Algo);
next([[Node | Siblings] | Rest], dfs = Algo) ->
#{~"nodes" := Nodes, ~"floating_nodes" := FloatingNodes} = Node,
[Node | fun() -> next([Nodes, FloatingNodes, Siblings | Rest], Algo) end];
next([[Node | Siblings] | Rest], bfs = Algo) ->
#{~"nodes" := Nodes, ~"floating_nodes" := FloatingNodes} = Node,
[Node | fun() -> next([Siblings, Nodes, FloatingNodes | Rest], Algo) end].