私はこれを機能させるために何時間も努力しましたが、どこにも近づいていないように感じます。
Mac OS Xターミナルからディレクトリ名をタブで入力して、ワークフローを短縮しようとしています。
Gitサブモジュールでコマンドを自動的に実行する内部ツールをbob
と呼びましょう。私がやりたいのは、サブディレクトリ名をオートコンプリートすることです。問題は、これらのサブディレクトリが静的な場所に存在することです。
project directory
->public
->submodules
->a-module
->another-module
->other-module
->some-module
コマンドは、次のようにプロジェクトの最上位ディレクトリから実行されます。
bob start bugfix anothermodule
現在行っている「anothermodule」を完全に入力するのではなく、タブのオートコンプリートを機能させたいと思います。私たちはこのワークフローを1日に何度も使用しており、数秒を短縮することは素晴らしいことであり、タイプミスを回避します。
最終目標は次のとおりです。
bob start bugfix an<tab>
オートコンプリートします
bob start bugfix anothermodule
CDPATH
を試しましたが、これはcd
コマンドではなく、カスタムコマンドのみであるため、これが私が求めているものではないことにすぐに気付きました。
私が持っています bash_completion
インストールされていますが、一般的にbashはあまり得意ではありません。それが解決策の一部になる可能性がある場合に備えて、これに言及してください!
これは Kamilの優れた回答 の拡張であり、各サブディレクトリ名の-module
部分からハイフンを取り除きます。
bugfix)
curdir=$(pwd)
cd public/submodules/ 2>/dev/null && _filedir -d
# Strip the hyphen from `-module` in each sub-directory name.
for ((i=0; i<${#COMPREPLY[@]}; i++)); do
COMPREPLY[$i]="${COMPREPLY[$i]/-module/module}"
done
cd "$curdir"
;;
このセクションを改善する余地はまだあります。ハイフンを入力する必要がある場合があります。つまり、 a-Tabamodule
とamodule
のどちらかを選択する代わりに、anothermodule
まで完了するようにします(ハイフンは完了関数によって削除されます)。
そうです、_bash_completion
_は解決策です。私のUbuntuに何があるかをお話しできます。 Macでも少なくとも似ているといいのですが。
_/etc/bash_completion
_をソースとする_/usr/share/bash-completion/bash_completion
_ファイルがあります。
ディレクトリ_/usr/share/bash-completion
_には、completions
サブディレクトリもあります。これはスクリプトの場所です。 eject
スクリプトを見てみましょう。
_# bash completion for eject(1) -*- Shell-script -*- _eject() { local cur prev words cword _init_completion || return case $prev in -h|--help|-V|--version|-c|--changerslot|-x|--cdspeed) return ;; -a|--auto|-i|--manualeject) COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) ) return ;; esac if [[ $cur == -* ]]; then COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) return Elif [[ $prev == @(-d|--default) ]]; then return fi _cd_devices _dvd_devices } && complete -F _eject eject # ex: ts=4 sw=4 et filetype=sh
_
ドキュメントを読まなくても、少しリバースエンジニアリングして、ケースに合わせることができます。私たちにとって、上記のコードの最も重要な部分は、_-a
_、_--auto
_ _-i
_または_--manualeject
_の後にon
またはoff
のいずれかが存在する可能性があることを示しています。あなたの場合、bugfix
の後に、ディレクトリ名が必要です。
(またはそうではありません。_another-module
_ディレクトリがありますが、anothermodule
引数を使用します。今のところ、タイプミスだと思います。そうでない場合は、 Anthonyの答え が正しい方向を示していると思います。 。)
どういうわけか、必要なこれらのディレクトリを抽出して_'on off'
_を置き換えることができますが、既存のコードを利用する方がよい場合があります。 cd
と入力すると、bash
はディレクトリをオートコンプリートし、スペースや特殊文字があってもうまく機能します。それでは、_cd()
関数を見てみましょう。 _/usr/share/bash-completion/bash_completion
_にあるので、ここに貼り付けません。次に、この関数の重要な部分は__filedir -d
_呼び出しであるようです。 _filedir()
が定義される直前に、次のようになります。
_# This function performs file and directory completion. It's better than # simply using 'compgen -f', because it honours spaces in filenames.
_
ビンゴ。
そこで、eject
スクリプトをbob
という名前でコピーし、次の形式に編集しました。
_# bash completion for bob -*- Shell-script -*-
_bob()
{
local cur prev words cword curdir
_init_completion || return
case $prev in
bob)
COMPREPLY=( $( compgen -W 'start stop foo bar' -- "$cur" ) )
return
;;
start)
COMPREPLY=( $( compgen -W 'bugfix' -- "$cur" ) )
return
;;
bugfix)
curdir=$(pwd)
cd public/submodules/ 2>/dev/null && _filedir -d
cd "$curdir"
;;
esac
} &&
complete -F _bob bob
_
既存のbash
セッションはこのファイルに気付かないため、新しいbash
を実行してテストする必要があります。
はい、それは迅速で汚いブードゥープログラミングです、ごめんなさい。
_public/submodules/
_に降りて戻ってきたことに注意してください。通常、私はサブシェルを使用します:
_export -f _filedir
( cd … && _filedir -d )
_
しかし、__filedir
_はこのようには機能しないようです。