---
source: src/shell/mod.rs
expression: output
---
# worktrunk shell integration for zsh
#
# Completions require zsh's completion system (compinit). If completions don't work:
# autoload -Uz compinit && compinit # add before this line in .zshrc
# Only initialize if wt is available (in PATH or via WORKTRUNK_BIN)
if command -v wt >/dev/null 2>&1 || [[ -n "${WORKTRUNK_BIN:-}" ]]; then
# Override wt command with split directive passing.
# Creates two temp files: one for cd (raw path) and one for exec (shell).
# WORKTRUNK_BIN can override the binary path (for testing dev builds).
wt() {
local use_source=false
local -a args
for arg in "$@"; do
if [[ "$arg" == "--source" ]]; then use_source=true; else args+=("$arg"); fi
done
# Completion mode: call binary directly, no directive files needed.
# This check MUST be here (not in the binary) because clap's completion
# handler runs before argument parsing.
if [[ -n "${COMPLETE:-}" ]]; then
command "${WORKTRUNK_BIN:-wt}" "${args[@]}"
return
fi
local cd_file exec_file exit_code=0
cd_file="$(mktemp)"
exec_file="$(mktemp)"
# --source: use cargo run (builds from source)
if [[ "$use_source" == true ]]; then
WORKTRUNK_DIRECTIVE_CD_FILE="$cd_file" WORKTRUNK_DIRECTIVE_EXEC_FILE="$exec_file" \
cargo run --bin wt --quiet -- "${args[@]}" || exit_code=$?
else
WORKTRUNK_DIRECTIVE_CD_FILE="$cd_file" WORKTRUNK_DIRECTIVE_EXEC_FILE="$exec_file" \
command "${WORKTRUNK_BIN:-wt}" "${args[@]}" || exit_code=$?
fi
# cd file holds a raw path (no shell escaping needed)
if [[ -s "$cd_file" ]]; then
cd -- "$(<"$cd_file")"
local cd_exit=$?
if [[ $exit_code -eq 0 ]]; then
exit_code=$cd_exit
fi
fi
# exec file holds arbitrary shell (e.g. from --execute)
if [[ -s "$exec_file" ]]; then
source "$exec_file"
local src_exit=$?
if [[ $exit_code -eq 0 ]]; then
exit_code=$src_exit
fi
fi
rm -f "$cd_file" "$exec_file"
return "$exit_code"
}
# Lazy completions - generate on first TAB, then delegate to clap's completer
_wt_lazy_complete() {
# Generate completions function once (check if clap's function exists)
if ! (( $+functions[_clap_dynamic_completer_wt] )); then
# Use `command` to bypass the shell function and call the binary directly.
# Without this, `wt` would call the shell function which evals
# the completion script internally but doesn't re-emit it.
#
# The -V flag creates an unsorted group, preserving our recency-based
# ordering instead of zsh's default alphabetical sort.
# Note: _describe's -V does NOT take an argument - it just sets a flag.
# The _describe function internally passes -o nosort to compadd.
# TODO(clap): Ideally clap_complete would preserve ordering natively.
# See: https://github.com/clap-rs/clap/issues/5752
eval "$(COMPLETE=zsh command "${WORKTRUNK_BIN:-wt}" 2>/dev/null | sed "s/_describe 'values'/_describe -V 'values'/")" || return
fi
_clap_dynamic_completer_wt "$@"
}
# Register completion (silently skip if compinit hasn't run yet).
# We don't warn here because this script runs on every shell startup - users
# shouldn't see warnings every time they open a terminal. Instead, `wt config
# shell install` detects missing compinit and shows a one-time advisory.
if (( $+functions[compdef] )); then
compdef _wt_lazy_complete wt
# Single-column display keeps descriptions visually associated with each branch.
# Users can override: zstyle ':completion:*:wt:*' list-max ''
zstyle ':completion:*:wt:*' list-max 1
# Prevent grouping branches with identical descriptions (same timestamp) on one line.
# Without this, "release main -- + 12m" instead of separate lines per branch.
zstyle ':completion:*:*:wt:*' list-grouped false
fi
fi