web-dev-qa-db-ja.com

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

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

alias apt-inst='Sudo aptitude install'

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

69
levesque

buntuフォーラムにはこれに関する素晴らしいスレッド があります。 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フォルダー内のシェルスクリプトを使用します。そのフォルダーがパスにある場合、オートコンプリートされます。

35
Shawn J. Goff

この問題を正確に解決する complete-alias を試してください。 (免責事項:私は_complete_alias_の作成者です)

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

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

_complete_alias_または同様のものを使用して、すべてのbashインスタンスで_.bash_profile_ファイルをソースすることができます。

installation

_mkdir ~/.bash_completion.d
curl https://raw.githubusercontent.com/cykerway/complete-alias/master/complete_alias \
     > ~/.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   
_
37
Cyker

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
6
Adrian Lopez

これが 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
2
Tom Hale

この問題をグーグルすることで私はここに行き着いたので、私は他の答えのアプローチを試みました。私が実際に理解していないさまざまな理由で、それらは私のUbuntu 16.04では正しく動作しませんでした。

結局、私にとってうまくいったのは、予想よりもはるかに簡単なことでした。 rsyncmycommandに対して持っているのと同じオートコンプリートを使いたかった。そこで、オートコンプリート機能を調べ、それに応じてcompleteを呼び出しました。

# Lookup of name of autocompletion function used for rsync
complete -p rsync
# Returns: complete -o nospace -F _rsync rsync

# Sourcing the rsync functions before, then using the same function for 'mycommand'
. /usr/share/bash-completion/completions/rsync
complete -o nospace -F _rsync mycommand

免責事項:他の方法と比較して私のアプローチの欠点は何なのかわかりません。これは、この些細なアプローチで十分な場合に役立つ可能性があるため、主にこれを書きました。

2
M.Ermatinger

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

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}
}
1
user84207