33

Some commands (kill-session and kill-server) have the same prefix.
When I type (prefix:kill-seTab), tmux won't give me any result.
Is there a option to show wildmenu for auto-completion inside tmux?

I'm using Ubuntu 12.04

4
  • What shell are you using? You can find it with echo $SHELL Apr 8, 2013 at 5:31
  • 1
    It's /bin/bash
    – kev
    Apr 8, 2013 at 7:29
  • 6
    How is shell related? When you type Ctrl+B,: in tmux, you're given a tmux command prompt (just like when you type : in VIM, you're not given a bash prompt.) This is a tmux question, not a shell question.
    – bobpaul
    May 8, 2013 at 21:40
  • The bash completion answer is helpful, but doesn't answer the question for use inside tmux. I'm guessing that since tmux doesn't have an extra line of vertical space to work with, it just doesn't offer the tab completion options like bash does, though it does at least complete what you're typing up until there is ambiguity. So folks can use the bash option to learn, and use the tmux option for quickies where they know what they want.
    – nealmcb
    Dec 23, 2014 at 20:02

2 Answers 2

10

Current answer (command completion within tmux's command-prompt)

This simply works out-of-the-box as of version 3.2 (released April 2021), hence the other answer to this question is incorrect.

tmux command-prompt completion menu

You can use arrow-keys or press the corresponding number key to choose the desired completion. Caveat that this may not work with vi key mappings, which I haven't tested, but I can confirm it works with emacs mappings.

Original Answer (bash completion for tmux)

Obviously I misunderstood the question back when I originally answered, but I am leaving this part of the answer up because shell completions for tmux are a viable alternative to completions within tmux, particularly in scenarios where older versions of tmux are in use.

The following script provides a bash completion for tmux, and I tested it out on my box just now, and it works great. Just copy the script to a file on your computer, and put

   source /path/to/tmux_completion.sh

in your .bashrc and you should be ready to go.


#!/bin/bash

# tmux completion
# See: http://www.debian-administration.org/articles/317 for how to write more.
# Usage: Put "source bash_completion_tmux.sh" into your .bashrc
# Based upon the example at http://paste-it.appspot.com/Pj4mLycDE

_tmux_expand () 
{ 
    [ "$cur" != "${cur%\\}" ] && cur="$cur"'\';
    if [[ "$cur" == \~*/* ]]; then
        eval cur=$cur;
    else
        if [[ "$cur" == \~* ]]; then
            cur=${cur#\~};
            COMPREPLY=($( compgen -P '~' -u $cur ));
            return ${#COMPREPLY[@]};
        fi;
    fi
}

_tmux_filedir () 
{ 
    local IFS='
';
    _tmux_expand || return 0;
    if [ "$1" = -d ]; then
        COMPREPLY=(${COMPREPLY[@]} $( compgen -d -- $cur ));
        return 0;
    fi;
    COMPREPLY=(${COMPREPLY[@]} $( eval compgen -f -- \"$cur\" ))
}

function _tmux_complete_client() {
    local IFS=$'\n'
    local cur="${1}"
    COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "$(tmux -q list-clients | cut -f 1 -d ':')" -- "${cur}") )
}
function _tmux_complete_session() {
    local IFS=$'\n'
    local cur="${1}"
    COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "$(tmux -q list-sessions | cut -f 1 -d ':')" -- "${cur}") )
}
function _tmux_complete_window() {
    local IFS=$'\n'
    local cur="${1}"
    local session_name="$(echo "${cur}" | sed 's/\\//g' | cut -d ':' -f 1)"
    local sessions
    
    sessions="$(tmux -q list-sessions | sed -re 's/([^:]+:).*$/\1/')"
    if [[ -n "${session_name}" ]]; then
        sessions="${sessions}
$(tmux -q list-windows -t "${session_name}" | sed -re 's/^([^:]+):.*$/'"${session_name}"':\1/')"
    fi
    cur="$(echo "${cur}" | sed -e 's/:/\\\\:/')"
    sessions="$(echo "${sessions}" | sed -e 's/:/\\\\:/')"
    COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "${sessions}" -- "${cur}") )
}

_tmux() {
    local cur prev
    local i cmd cmd_index option option_index
    local opts=""
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    if [ ${prev} == -f ]; then
        _tmux_filedir
    else
    # Search for the command
    local skip_next=0
    for ((i=1; $i<=$COMP_CWORD; i++)); do
        if [[ ${skip_next} -eq 1 ]]; then
            #echo "Skipping"
            skip_next=0;
        elif [[ ${COMP_WORDS[i]} != -* ]]; then
            cmd="${COMP_WORDS[i]}"
            cmd_index=${i}
            break
        elif [[ ${COMP_WORDS[i]} == -f ]]; then
            skip_next=1
        fi
    done

    # Search for the last option command
    skip_next=0
    for ((i=1; $i<=$COMP_CWORD; i++)); do
        if [[ ${skip_next} -eq 1 ]]; then
            #echo "Skipping"
            skip_next=0;
        elif [[ ${COMP_WORDS[i]} == -* ]]; then
            option="${COMP_WORDS[i]}"
            option_index=${i}
            if [[ ${COMP_WORDS[i]} == -- ]]; then
                break;
            fi
        elif [[ ${COMP_WORDS[i]} == -f ]]; then
            skip_next=1
        fi
    done

    if [[ $COMP_CWORD -le $cmd_index ]]; then
        # The user has not specified a command yet
        local all_commands="$(tmux -q list-commands | cut -f 1 -d ' ')"
        COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "${all_commands}" -- "${cur}") )
    else        
        case ${cmd} in
            attach-session|attach)
            case "$prev" in
                -t) _tmux_complete_session "${cur}" ;;
                *) options="-t -d" ;;
            esac ;;
            detach-client|detach)
            case "$prev" in
                -t) _tmux_complete_client "${cur}" ;;
                *) options="-t" ;;
            esac ;;
            lock-client|lockc)
            case "$prev" in
                -t) _tmux_complete_client "${cur}" ;;
                *) options="-t" ;;
            esac ;;
            lock-session|locks)
            case "$prev" in
                -t) _tmux_complete_session "${cur}" ;;
                *) options="-t -d" ;;
            esac ;;
            new-session|new)
            case "$prev" in
                -t) _tmux_complete_session "${cur}" ;;
                -[n|d|s]) options="-d -n -s -t --" ;;
                *) 
                if [[ ${COMP_WORDS[option_index]} == -- ]]; then
                    _command_offset ${option_index}
                else
                    options="-d -n -s -t --"
                fi
                ;;
            esac
            ;;
            refresh-client|refresh)
            case "$prev" in
                -t) _tmux_complete_client "${cur}" ;;
                *) options="-t" ;;
            esac ;;
            rename-session|rename)
            case "$prev" in
                -t) _tmux_complete_session "${cur}" ;;
                *) options="-t" ;;
            esac ;;
            source-file|source) _tmux_filedir ;;
            has-session|has|kill-session)
            case "$prev" in
                -t) _tmux_complete_session "${cur}" ;;
                *) options="-t" ;;
            esac ;;
            suspend-client|suspendc)
            case "$prev" in
                -t) _tmux_complete_client "${cur}" ;;
                *) options="-t" ;;
            esac ;;
            switch-client|switchc)
            case "$prev" in
                -c) _tmux_complete_client "${cur}" ;;
                -t) _tmux_complete_session "${cur}" ;;
                *) options="-l -n -p -c -t" ;;
            esac ;;
            
            send-keys|send)
            case "$option" in
                -t) _tmux_complete_window "${cur}" ;;
                *) options="-t" ;;
            esac ;;
          esac # case ${cmd}
        fi # command specified
      fi # not -f 
            
      if [[ -n "${options}" ]]; then
          COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "${options}" -- "${cur}") )
      fi
            
      return 0

}
complete -F _tmux tmux

# END tmux completion

Script Source (GPL3 license)

9
  • 7
    I saved this script and sourced it from my .bashrc. I started tmux and hit "Ctrl+B, :" and then typed "detach-" and hit tab a bunch. Nothing. I added a c so it sayd "detach-c" and hit tab, it completed to "detach-client". This is the exact same behavior I experienced before the script. Nothing seems to have changed.
    – bobpaul
    May 8, 2013 at 21:38
  • 10
    @bobpaul is asking for tab completion within tmux, not from in the shell like bash. Oct 30, 2013 at 19:37
  • 1
    @kev is also asking for tab completion within tmux, not from bash. And note that some related (older?) code for this bash command completion approach is on github at github.com/aziz/dotfiles/blob/master/bash/completion/… but it isn't clear to me how their behavior differs. Perhaps luolimao might want to offer the diffs in a pull request?
    – nealmcb
    Dec 23, 2014 at 19:58
  • 8
    I voted the answer down because OP is asking for auto-completion from within tmux, not for bash. This answer might be totally reasonable for the second inquiry (completion for bash), but it misleads people who come here through search engines to try to find a completion from within tmux.
    – thiagowfx
    Mar 6, 2017 at 18:01
  • 1
    @thiagowfx You SHOULD NOT downvote a "totally reasonable" answer just because it is not exactly what "OP is asking". In that case you EDIT THE ANSWER and give it a better title. You only downvote an answer that is wrong, misleading, brittle, etc. Giving someone an alternative to what they asked for (especially when what they asked for is impossible) is not "misleading". I can't believe that 5 other people agreed with this! That's not the SO/SE culture. Jul 7, 2020 at 19:47
0

No, this is not possible. Tmux internal commands only allows for autocompletion when the typed string is unambiguous.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .