Bagaimana cara saya mendapatkan penyelesaian bash untuk alias perintah?

57

Saya mencari penyelesaian tab pada alias baris perintah saya, misalnya, katakan saya mendefinisikan alias berikut:

alias apt-inst='sudo aptitude install'

Apakah ada cara untuk mendapatkan kelengkapan yang disediakan oleh aptitude ketika saya menekan tombol tab? yaitu ketika saya menulis 'sudo aptitude install gnumer' dan tekan tab, aptitude melengkapi ini ke gnumeric, atau jika ada ketidakpastian daftar semua paket yang tersedia dimulai dengan gnumer. Jika saya melakukannya menggunakan alias saya, tidak ada - tidak ada penyelesaian.

levesque
sumber

Jawaban:

30

Ada utas bagus tentang ini di forum Ubuntu . Ole J mengusulkan fungsi definisi penyelesaian alias berikut ini:

function make-completion-wrapper () {
  local function_name="$2"
  local arg_count=$(($#-3))
  local comp_function_name="$1"
  shift 2
  local function="
    function $function_name {
      ((COMP_CWORD+=$arg_count))
      COMP_WORDS=( "$@" \${COMP_WORDS[@]:1} )
      "$comp_function_name"
      return 0
    }"
  eval "$function"
  echo $function_name
  echo "$function"
}

Gunakan untuk mendefinisikan fungsi penyelesaian untuk alias Anda, lalu tentukan fungsi itu sebagai pelengkap alias:

make-completion-wrapper _apt_get _apt_get_install apt-get install
complete -F _apt_get_install apt-inst

Saya lebih suka menggunakan alias untuk menambahkan argumen yang selalu digunakan untuk program yang ada. Misalnya, dengan grep, saya selalu ingin melewatkan perangkat dan file biner, jadi saya membuat alias untuk grep. Untuk menambahkan perintah baru seperti grepbin, saya menggunakan skrip shell di ~/binfolder saya . Jika folder itu ada di jalur Anda, folder itu akan selesai secara otomatis.

Shawn J. Goff
sumber
2
Luar biasa, saya takut itu tidak mungkin.
levesque
Perhatikan kode ini memiliki beberapa masalah. Lihat jawaban saya untuk penjelasan dan resolusi mereka.
Tom Hale
Catatan: Saya menggunakan teknik ini untuk perintah lain, dan saya harus menggunakan complete -o default -F ...alih-alih complete -F ...untuk mendapatkan hal-hal seperti pelengkapan otomatis nama file yang berfungsi dengan benar ketika melewati argumen (Bash 4.3.46).
joelittlejohn
28

Coba alias lengkap , yang memecahkan masalah ini dengan tepat.

Setelah menginstalnya, Anda dapat menggunakan satu fungsi umum untuk menyelesaikan banyak alias seperti ini:

complete -F _complete_alias <myalias1>
complete -F _complete_alias <myalias2>
complete -F _complete_alias <myalias3>

Anda mungkin ingin mencari file complete_alias di setiap instance bash melalui .bash_profileatau serupa.

instalasi

mkdir ~/.bash_completion.d
curl https://raw.githubusercontent.com/cykerway/complete-alias/master/bash_completion.sh \
     > ~/.bash_completion.d/complete_alias

aplikasi

source ~/.bash_completion.d/complete_alias

alias container=docker\ container
complete -F _complete_alias container

containersekarang dapat dilengkapi secara otomatis oleh _docker()handler penyelesaian asli ;

$ container l<Tab>
logs  ls    

$ container s<Tab>
start  stats  stop   
Cyker
sumber
2
Mengingat bahwa perangkat lunak ini tampaknya menjadi milik Anda, Anda dapat melakukan lebih baik dari ini Tambahkan instruksi tentang cara menginstalnya. Jelaskan apa yang dilakukannya dan bagaimana menggunakannya. Kalau tidak, ini hanya spam.
muru
@muru Saya berpikir untuk menempelkan beberapa kode di sini, tetapi mungkin lebih lama daripada diterima di sini. Saya berasumsi orang tidak memiliki masalah membaca bagian Instal di file README, dan dalam hal ini hanya beberapa baris.
Cyker
2
intinya adalah untuk dapat menilai apakah kunjungan mengatakan README bermanfaat, hanya dari jawabannya.
muru
Ini adalah jawaban yang memadai dan itu memecahkan masalah dengan tepat.
Ярослав Рахматуллин
1
Ini adalah jawaban yang sangat bagus dan sangat komprehensif yang bekerja dengan sempurna, terima kasih !. Mungkin sudah diperbarui karena @muru bermasalah dengan itu.
Brian Topping
3

2018 menjawab

Anda harus menambahkan alias Anda ke program 'lengkap'. Tergantung jenis pelengkapan otomatis yang ingin Anda capai, Anda harus menggunakan -c atau -F.

Untuk pelengkapan otomatis paket:

complete -c name_of_your_alias

Untuk pelengkapan otomatis perintah:

complete -F name_of_your_alias

Untuk memeriksa apakah alias Anda ditambahkan dengan benar:

complete | grep name_of_your_alias

Akhirnya, untuk menghapus alias dari 'lengkap':

complete -r name_of_your_alias

Dalam kasus Anda:

complete -c apt-inst
Adrian Lopez
sumber
1
Tolong jangan melanjutkan jawaban Anda dalam komentar. Jika ada yang ingin Anda katakan, edit jawaban itu.
G-Man Mengatakan 'Reinstate Monica'
2
complete -F xxxtidak bekerja di OSX (Ini hanya menunjukkan penggunaan complete: usage: complete [-abcdefgjksuv] [-pr] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [name ...]). Apakah Anda memiliki pointer? Terima kasih.
Anthony Kong
Gunakan ini sebagai gantinya: unix.stackexchange.com/questions/224227/…
Rich
2

Berikut kode dari jawaban Shawn J. Goff dengan beberapa peningkatan:

  • Memperbaiki kesalahan sintaksis yang disorot oleh shell-check, misalnya yang pertama benar "- "$@"benar mengakhiri string definisi fungsi.
  • Dihapus return 0sehingga nilai kembali dari fungsi yang mendasarinya dapat diteruskan kembali ke pemanggil.

.

# Wraps a completion function, eg for use with an alias.
# Usage:
# make-completion-wrapper <actual completion function> <name of new func.>
#                         <command name> <list supplied arguments>
# eg.
#   alias agi='apt-get install'
#   make-completion-wrapper _apt_get _apt_get_install apt-get install
#     # defines a function called _apt_get_install (that's $2) that will
#     # complete the 'agi' alias. 
#   complete -F _apt_get_install agi
function make-completion-wrapper {
  local function_name="$2"
  local arg_count=$(( $#-3 ))
  local comp_function_name="$1"
  shift 2
  local function="function $function_name {
      (( COMP_CWORD += $arg_count ))
      COMP_WORDS=( \"\$@\" \${COMP_WORDS[@]:1} )
      \"$comp_function_name\"
    }"
  eval "$function"
  # echo "$function"
}
export -f make-completion-wrapper
Tom Hale
sumber
Tidak bekerja untuk saya di Bash 4.3.46 Saya khawatir. Jawabannya Shaun J. Goff ini tidak bekerja.
joelittlejohn
1
"Mengakhiri" string definisi fungsi sengaja; intinya adalah memasukkan argumen dari fungsi luar ke dalam COMP_WORDSarray. Jika kita gunakan make-completion-wrapper _apt_get _apt_get_install apt-get installsebagai contoh, setelah shift 2, $@berisi apt-get install. Definisi fungsi mencakup apt-get install(dua kata literal) saat menetapkan COMP_WORDS.
Jeffery To
0

Sebagai ekstensi ke @Giles menjawab, fungsi kenyamanan berikut memberi nama otomatis pada pembungkus yang dibuat make-completion-wrapperuntuk memungkinkan penyelesaian definisi dalam satu baris:

function complete-alias  {
    # uses make-completion-wrapper: https://unix.stackexchange.com/a/4220/50978
    # example usage
    # complete-alias _pass pshow pass show
    # complete-alias _pass pgen pass generate

    EXISTING_COMPLETION_FN=${1} && shift
    ALIAS=${1} && shift
    AUTOGEN_COMPLETION_FN="__autogen_completion_${ALIAS}"
    make-completion-wrapper ${EXISTING_COMPLETION_FN} ${AUTOGEN_COMPLETION_FN} ${*}
    complete -F ${AUTOGEN_COMPLETION_FN} ${ALIAS}
}
pengguna84207
sumber