Bagaimana cara menuntaskan penyelesaian ketika mengetik perintah di tmux?

22

Beberapa perintah ( kill-sessiondan kill-server) memiliki awalan yang sama.
Saat saya mengetik ( prefix:kill-seTab), tmux tidak akan memberi saya hasil apa pun.
Apakah ada opsi untuk menampilkan wildmenu untuk pelengkapan otomatis di dalam tmux?

Saya menggunakan Ubuntu 12.04

kev
sumber
Shell apa yang Anda gunakan? Anda dapat menemukannya dengan echo $ SHELL
éclairevoyant
1
Ini/bin/bash
kev
4
Bagaimana shell terkait? Saat Anda mengetikkan Ctrl + B ,: di tmux, Anda diberikan prompt perintah tmux (seperti saat Anda mengetik: di VIM, Anda tidak diberi bash prompt.) Ini adalah pertanyaan tmux, bukan pertanyaan shell.
bobpaul
Jawaban penyelesaian bash sangat membantu, tetapi tidak menjawab pertanyaan untuk digunakan di dalam tmux. Saya menduga bahwa karena tmux tidak memiliki garis ekstra ruang vertikal untuk dikerjakan, itu hanya tidak menawarkan opsi penyelesaian tab seperti yang dilakukan bash, meskipun setidaknya melengkapi apa yang Anda ketikkan sampai ada kemenduaan. Jadi orang-orang dapat menggunakan opsi bash untuk belajar, dan menggunakan opsi tmux untuk quickies di mana mereka tahu apa yang mereka inginkan.
nealmcb

Jawaban:

8

Script berikut memberikan penyelesaian bash untuk tmux, dan saya mengujinya di kotak saya sekarang, dan itu berfungsi dengan baik. Cukup salin skrip ke file di komputer Anda, dan masukkan

   source /path/to/tmux_completion.sh

di Anda .bashrcdan Anda harus siap untuk pergi.


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

Sumber Skrip

éclairevoyant
sumber
5
Saya menyimpan skrip ini dan mengambilnya dari .bashrc saya. Saya mulai tmux dan menekan "Ctrl + B,:" dan kemudian mengetik "detach-" dan tekan tab a bunch. Tidak ada. Saya menambahkan ac jadi sayd "detach-c" dan tekan tab, itu selesai untuk "detach-client". Ini adalah perilaku yang persis sama yang saya alami sebelum naskah. Sepertinya tidak ada yang berubah.
bobpaul
6
@ bobpaul meminta penyelesaian tab dalam tmux, bukan dari dalam shell seperti bash.
Jason Axelson
1
@ kev juga meminta penyelesaian tab dalam tmux, bukan dari bash. Dan perhatikan bahwa beberapa kode terkait (lebih lama?) Untuk pendekatan penyelesaian perintah bash ini ada di github di github.com/aziz/dotfiles/blob/master/bash/completion/... tetapi tidak jelas bagi saya bagaimana perilaku mereka berbeda. Mungkin luolimao mungkin ingin menawarkan diff dalam permintaan tarik?
nealmcb
Skrip pelengkapan otomatis ini berfungsi sangat baik di Bash !! Terima kasih @luolimao!
Trevor Sullivan
2
Saya memilih jawabannya karena OP meminta penyelesaian otomatis dari dalam tmux, bukan untuk bash. Jawaban ini mungkin benar-benar masuk akal untuk pertanyaan kedua (penyelesaian untuk bash), tetapi menyesatkan orang yang datang ke sini melalui mesin pencari untuk mencoba menemukan penyelesaian dari dalam tmux.
thiagowfx