Как добавить табуляцию при вводе команды в tmux?

22

Некоторые команды ( kill-sessionи kill-server) имеют одинаковый префикс.
Когда я набираю ( prefix:kill-seTab), tmux не даст мне никакого результата.
Есть ли возможность показать wildmenu для автозаполнения внутри tmux?

Я использую Ubuntu 12.04

кэв
источник
Какую оболочку вы используете? Вы можете найти его с помощью echo $ SHELL
éclairevoyant
1
Это/bin/bash
Кев
4
Какое отношение имеет оболочка? Когда вы набираете Ctrl + B ,: в tmux, вы получаете командную строку tmux (так же, как когда вы набираете: в VIM, вы не получаете приглашение bash.) Это вопрос tmux, а не вопрос оболочки.
Бобпол
Ответ на завершение bash полезен, но не отвечает на вопрос для использования внутри tmux. Я предполагаю, что, поскольку tmux не имеет дополнительной строки вертикального пространства для работы, он просто не предлагает опции завершения вкладки, как это делает bash, хотя он, по крайней мере, завершает то, что вы печатаете, пока не появится неоднозначность. Таким образом, люди могут использовать опцию bash для обучения и опцию tmux для быстрого доступа, где они знают, чего хотят.
nealmcb

Ответы:

8

Следующий скрипт предоставляет завершение bash для tmux, и я только что проверил его на своем компьютере, и он прекрасно работает. Просто скопируйте скрипт в файл на вашем компьютере и вставьте

   source /path/to/tmux_completion.sh

в вашем, .bashrcи вы должны быть готовы к работе.


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

Источник скрипта

éclairevoyant
источник
5
Я сохранил этот скрипт и получил его из моего .bashrc. Я запустил tmux и нажал «Ctrl + B,:», а затем набрал «detach-» и нажал на кнопку tab. Ничего такого. Я добавил ac, так что он сказал "detach-c" и нажал "tab", он завершился до "detach-client". Это то же самое поведение, которое я испытал перед сценарием. Кажется, ничего не изменилось.
Бобпол
6
@bobpaul запрашивает завершение табуляции в tmux, а не в оболочке, такой как bash.
Джейсон Аксельсон
1
@kev также запрашивает завершение табуляции в tmux, а не в bash. И обратите внимание, что некоторый связанный (более старый?) Код для этого подхода завершения команд bash находится на github по адресу github.com/aziz/dotfiles/blob/master/bash/completion/…, но мне не ясно, как их поведение отличается. Возможно, luolimao, возможно, захочет предложить различия в запросе на получение доступа?
nealmcb
Этот скрипт автозаполнения отлично работает в Bash !! Спасибо @luolimao!
Тревор Салливан
2
Я отказался от ответа, потому что OP запрашивает автозавершение изнутри tmux, а не bash. Этот ответ может быть вполне обоснованным для второго запроса (завершение для bash), но он вводит в заблуждение людей, которые приходят сюда через поисковые системы, чтобы попытаться найти завершение изнутри tmux.
thiagowfx