¿Cómo completar la pestaña al escribir el comando en tmux?

22

Algunos comandos ( kill-sessiony kill-server) tienen el mismo prefijo.
Cuando prefix:kill-seTabescribo ( ), tmux no me dará ningún resultado.
¿Existe una opción para mostrar wildmenu para autocompletar dentro de tmux?

Estoy usando Ubuntu 12.04

kev
fuente
¿Qué caparazón estás usando? Puede encontrarlo con echo $ SHELL
éclairevoyant
1
Es/bin/bash
kev
44
¿Cómo se relaciona el shell? Cuando escribe Ctrl + B ,: en tmux, se le da un símbolo del sistema tmux (al igual que cuando escribe: en VIM, no se le da un símbolo bash). Esta es una pregunta tmux, no una pregunta de shell.
bobpaul
La respuesta de finalización de bash es útil, pero no responde la pregunta para usar dentro de tmux. Supongo que dado que tmux no tiene una línea extra de espacio vertical para trabajar, simplemente no ofrece las opciones de finalización de pestañas como bash, aunque al menos completa lo que está escribiendo hasta que haya ambigüedad. Entonces, la gente puede usar la opción bash para aprender, y usar la opción tmux para quickies donde saben lo que quieren.
nealmcb

Respuestas:

8

El siguiente script proporciona una finalización de bash para tmux, y lo probé en mi caja justo ahora, y funciona muy bien. Simplemente copie el script en un archivo en su computadora y coloque

   source /path/to/tmux_completion.sh

en tu .bashrcy deberías estar listo para ir.


#!/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

Fuente de script

éclairevoyant
fuente
55
Guardé este script y lo obtuve de mi .bashrc. Comencé tmux y presioné "Ctrl + B,:" y luego escribí "detach-" y presioné la tecla un montón. Nada. Agregué ac para que dijera "detach-c" y presioné la pestaña, se completó a "detach-client". Este es exactamente el mismo comportamiento que experimenté antes del script. Nada parece haber cambiado.
bobpaul
66
@bobpaul está pidiendo que se complete la pestaña dentro de tmux, no desde el shell como bash.
Jason Axelson
1
@kev también está pidiendo completar la pestaña dentro de tmux, no desde bash. Y tenga en cuenta que algunos códigos relacionados (¿antiguos?) Para este enfoque de finalización de comandos bash están en github en github.com/aziz/dotfiles/blob/master/bash/completion/… pero no me queda claro cómo difiere su comportamiento. ¿Quizás luolimao podría querer ofrecer los diferenciales en una solicitud de extracción?
nealmcb
¡Este script de autocompletado funciona muy bien en Bash! Gracias @luolimao!
Trevor Sullivan
2
Voté la respuesta porque OP está pidiendo que se complete automáticamente desde tmux, no para bash. Esta respuesta puede ser totalmente razonable para la segunda consulta (finalización de bash), pero engaña a las personas que vienen a través de motores de búsqueda para tratar de encontrar una finalización desde tmux.
thiagowfx