I recently wrote a handy Zsh function that creates a new tmux session with no arguments. If an argument is provided and the session already exists, it's attached. Otherwise, a new session is created with the provided name.
# If the session is in the list of current tmux sessions, it is attached. Otherwise, a new session
# is created and attached with the argument as its name.
ta() {
# create the session if it doesn't already exist
tmux has-session -t $1 2>/dev/null
if [[ $? != 0 ]]; then
tmux new-session -d -s $1
fi
# if a tmux session is already attached, switch to the new session; otherwise, attach the new
# session
if { [ "$TERM" = "screen" ] && [ -n "$TMUX" ]; } then
tmux switch -t $1
else
tmux attach -t $1
fi
}
This works great, but I'd like to add autocompletion to it, so when I hit the tab key it will list out the current sessions for me. Here's what I have so far:
# List all the the sessions' names.
tln() {
tmux list-sessions | perl -n -e'/^([^:]+)/ && print $1 . "\n"'
}
compctl -K tln ta
When I hit tab, it lists out the session names, but it doesn't let me switch between them. What am I missing?
You did not read documentation carefully:
Call the given function to get the completions. Unless the name starts with an underscore, the function is passed two arguments: the prefix and the suffix of the word on which completion is to be attempted, in other words those characters before the cursor position, and those from the cursor position onwards. The whole command line can be accessed with the -c and -l flags of the read builtin. The function should set the variable
reply
to an array containing the completions (one completion per element); note that reply should not be made local to the function. From such a function the command line can be accessed with the -c and -l flags to the read builtin. For example,
. You must not output anything to stdout from completion function. You must instead set the array variable reply
:
reply=( $(tmux list-sessions | cut -d: -f1) )
. Note that there is no reason for you to invoke perl here, cut
is more suitable. I do not see any lines not matching ^([^:]+)
in the tmux output.