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. -Animated demo of the zp session picker +Animated demo of the zp session picker [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)'" \