コマンドエイリアスのbash補完を取得するにはどうすればよいですか?


57

コマンドラインエイリアスでタブ補完を取得したいと考えています。たとえば、次のエイリアスを定義したとします。

alias apt-inst='sudo aptitude install'

タブキーを押したときにaptitudeが提供する補完を取得する方法はありますか?すなわち、「sudo aptitude install gnumer」と書いてタブを押すと、aptitudeはこれをgnumericに完了させます。不確実性がある場合は、gnumerで始まるすべての利用可能なパッケージをリストします。私のエイリアスを使用してそれを行う場合、何もありません-完了しません。


回答:


30

Ubuntuフォーラムには、これに関するすばらしいスレッドがあります。Ole Jは、次のエイリアス補完定義関数を提案します。

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"
}

これを使用してエイリアスの補完関数を定義し、その関数をエイリアスの補完として指定します。

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

既存のプログラムに常に使用される引数を追加するためにエイリアスを使用することを好みます。たとえば、ではgrep、デバイスとバイナリファイルを常にスキップしたいので、のエイリアスを作成しgrepます。などの新しいコマンドを追加するためgrepbinに、~/binフォルダ内のシェルスクリプトを使用します。そのフォルダーがパスにある場合、オートコンプリートされます。


2
恐ろしいことに、私はそれが不可能になるのではないかと心配しました。
レベスク

このコードにはいくつかの問題があることに注意してください。彼らの説明と解決策については私の答えをご覧ください。
トム・ヘイル

注:私は別のコマンドにこの手法を使用していましたが、complete -o default -F ...代わりにcomplete -F ...引数を渡すときにファイル名の自動補完などが正しく機能するようにする必要がありました(Bash 4.3.46)。
joelittlejohn

28

この問題を正確に解決するcomplete-aliasを試してください。

インストール後、1つの汎用関数を使用して、次のような多くのエイリアスを完成できます。

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

すべてのbashインスタンスでcomplete_aliasファイルをソース.bash_profileまたは同様のものにしたい場合があります。

設置

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

応用

source ~/.bash_completion.d/complete_alias

alias container=docker\ container
complete -F _complete_alias container

container元の_docker()完了ハンドラーによって自動完了できるようになりました。

$ container l<Tab>
logs  ls    

$ container s<Tab>
start  stats  stop   

2
このソフトウェアはあなたのものであると思われるので、これよりもうまくやることができます。インストール手順を追加します。その機能と使用方法を説明します。それ以外の場合、これは単なるスパムです。
ムル16

@muruここにいくつかのコードを貼り付けることを考えていましたが、おそらくここで受け入れられるよりも長いでしょう。READMEファイルのInstallセクションを読むのに問題はないと思いますが、この場合は数行だけです。
サイカー16

2
重要なのは、答えから、READMEにアクセスする価値があるかどうかを判断できることです。
ムル16

これは適切な答えであり、問​​題を正確に解決します。
ЯрославРахматуллин

1
これは、完璧に機能する優れた非常に包括的な回答です。@muruに問題があったため、おそらく更新されています。
ブライアントッピング

3

2018年の回答

エイリアスをプログラム「complete」に追加する必要があります。達成するオートコンプリートの種類に応じて、-cまたは-Fを使用する必要があります。

パッケージのオートコンプリートの場合:

complete -c name_of_your_alias

コマンドのオートコンプリートの場合:

complete -F name_of_your_alias

エイリアスが正しく追加されたかどうかを確認するには:

complete | grep name_of_your_alias

最後に、「complete」からエイリアスを削除するには:

complete -r name_of_your_alias

あなたの場合:

complete -c apt-inst

1
コメントで回答を続けないでください。発言することがある場合は、それらを編集して回答にします。
G-Manが「Reinstate Monica」と言う

2
complete -F xxxOSXでは動作しません(使用法を示しているだけcomplete: usage: complete [-abcdefgjksuv] [-pr] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [name ...]です)。ポインターはありますか?ありがとう。
アンソニーコング

代わりにこれを使用します。unix.stackexchange.com/questions/224227/...を
リッチ

2

以下に、Shawn J. Goffの回答からのコードといくつかの改善点を示します。

  • で強調表示された構文エラーを修正しましたshell-check。たとえば、最初"の関数定義文字列が"$@"実際に終了しました。
  • 削除されたreturn 0基本的な関数の戻り値は、呼び出し元に渡すことができるようになっています。

# 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

Bash 4.3.46では動作しません。怖いです。ショーンJ.ゴフの答えはうまくいきます。
joelittlejohn

1
関数定義文字列の「終了」は意図的なものです。ポイントは、外部関数からの引数をCOMP_WORDS配列に含めることです。make-completion-wrapper _apt_get _apt_get_install apt-get install例として使用する場合、after shift 2$@contains apt-get install。をapt-get install割り当てる場合、関数定義には(2つのリテラルワード)が含まれCOMP_WORDSます。
ジェフリー、

0

@Gilesの答えの拡張として、次の便利な関数は生成されたラッパーに自動的に名前を付け、make-completion-wrapper1行で補完を定義できるようにします。

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}
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.