diff --git a/README.md b/README.md
index c818976..df4e97a 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ scrollback previews. When given root directories to search, it also lists any
git or jj repositories beneath them. Selecting a session attaches to it;
selecting a repository starts a numbered session inside it.
-
+
[zmx]: https://github.com/neurosnap/zmx
[fzf]: https://github.com/junegunn/fzf
@@ -85,6 +85,10 @@ Sessions created from a repository are named `.` with the next free
number and start in the repository's directory; sessions created from a query
start in the current directory.
+Any [zmx] session labels (`zmx set key=value`) are shown alongside each
+session and are fuzzy-searchable, so typing `key=value` narrows the picker to
+the sessions that carry that label.
+
## License
zmx-picker is released under the [Zero Clause BSD License](LICENSE) (SPDX:
diff --git a/tests/bin/zmx b/tests/bin/zmx
index 33df6f7..23c402d 100755
--- a/tests/bin/zmx
+++ b/tests/bin/zmx
@@ -19,7 +19,10 @@ sessions() {
fi
printf '\342\206\222 name=alpha.1\tpid=11\tclients=1\tcreated=1\tstart_dir=/tmp\n'
printf ' name=alpha.2\tpid=12\tclients=0\tcreated=2\tstart_dir=/tmp\n'
- printf ' name=beta\tpid=13\tclients=0\tcreated=3\tstart_dir=%s\n' \
+ # beta carries labels (trailing tab-separated key=value fields)
+ # and lives in a repo, so it also guards against those fields
+ # leaking into start_dir and breaking the repo-association count.
+ printf ' name=beta\tpid=13\tclients=0\tcreated=3\tstart_dir=%s\tproject=zp\tenv=work\n' \
"$ZP_TEST_DIR/root/plain"
printf ' name=d.gamma\tpid=14\tclients=0\tcreated=4\tstart_dir=/tmp\n'
printf ' name=d.omega.9\tpid=15\tclients=0\tcreated=5\tstart_dir=/tmp\n'
diff --git a/tests/run.sh b/tests/run.sh
index 5aa82b0..deae899 100755
--- a/tests/run.sh
+++ b/tests/run.sh
@@ -130,6 +130,16 @@ else
not_ok 'candidates strips list markers and annotates session counts' "$out"
fi
+reset_log
+out=$("$zp" --candidates "$root")
+beta_line=$(grep $'^session\tbeta\t' <<<"$out")
+if [[ $beta_line == *'project=zp env=work'* ]]; then
+ ok 'session labels are surfaced in the searchable display column'
+else
+ not_ok 'session labels are surfaced in the searchable display column' \
+ "$beta_line"
+fi
+
reset_log
ZMX_SESSION_PREFIX=d. run '' 'gamma' "$enter" >/dev/null || true
assert_log 'attaching a listed session never re-applies ZMX_SESSION_PREFIX' \
diff --git a/zp b/zp
index 6bd142c..bde5482 100755
--- a/zp
+++ b/zp
@@ -58,9 +58,9 @@ tilde() {
}
candidates() {
- local name clients dir repo count note sdir width i
+ local name clients dir labels repo count note labelcol sdir width i
local session_dirs=()
- local names=() notes=() session_clients=()
+ local names=() notes=() session_clients=() session_labels=()
# Existing zmx sessions. Lines carry a marker prefix before
# name= (e.g. "→ " on the attached session), so strip through
@@ -68,10 +68,16 @@ candidates() {
# so the name column can be padded to the widest name instead
# of a fixed width.
width=0
- while IFS=$'\t' read -r name _ clients _ dir; do
+ while IFS=$'\t' read -r name _ clients _ dir labels; do
name=${name#*name=}
clients=${clients#*clients=}
dir=${dir#*start_dir=}
+ # Any session labels arrive as extra tab-separated key=value
+ # fields after start_dir; slurping them into their own field
+ # keeps a stray tab out of $dir, which would corrupt the path
+ # and the start_dir match behind repo session counts. Join
+ # them with spaces for display; absent labels leave it empty.
+ labels=${labels//$'\t'/ }
[[ -n $name ]] || continue
@@ -88,6 +94,7 @@ candidates() {
names+=("$name")
notes+=("$note")
session_clients+=("$clients")
+ session_labels+=("$labels")
if [[ ${#name} -gt $width ]]; then
width=${#name}
fi
@@ -95,9 +102,15 @@ candidates() {
for ((i = 0; i < ${#names[@]}; i++)); do
tilde "${session_dirs[i]}"
- printf 'session\t%s\t%s%-*s clients:%-2s %s\n' \
+ # Trailing label column, shown only when the session has
+ # labels so unlabeled rows keep their current shape.
+ labelcol=''
+ if [[ -n ${session_labels[i]} ]]; then
+ labelcol=" ${session_labels[i]}"
+ fi
+ printf 'session\t%s\t%s%-*s clients:%-2s %s%s\n' \
"${names[i]}" "${notes[i]}" "$width" "${names[i]}" \
- "${session_clients[i]}" "$tilded"
+ "${session_clients[i]}" "$tilded" "$labelcol"
done
# Repositories, when any search roots are configured: git
@@ -276,7 +289,7 @@ select_session() {
--tiebreak=index \
--ellipsis='…' \
--prompt='zmx> ' \
- --header=$'Enter: select/create | Tab: mark\n^N: new from query | ^X: kill' \
+ --header=$'Enter: select/create | Tab: mark\n^N: new from query | ^X: kill' \
--bind='enter:clear-selection+accept' \
--bind="ctrl-x:execute-silent(printf '%s\n' {+} | $kill_cmd)+reload($reload_cmd)" \
--bind="focus:transform:test {1} = session && echo 'change-preview-window(follow)' || echo 'change-preview-window(nofollow)'" \