別のカテゴリで単一のコマンドを実行する機能があります。cd1 SOMEDIR MYCOMMAND ARG…
同様に(cd SOMEDIR && MYCOMMAND ARG…)
、2つの利点があります。入力が少し簡単で(コマンドライン中毒者の場合は、すべてのキーストロークが重要です)(ほとんど)SOMEDIR
。
つまり、完成関数を定義できますcd1
。親戚の完成をどのように準備できますかSOMEDIR
?
以下は変更しないと機能しません。
_files
ここでは、コマンドパラメータの変更されたパラメータを使用して一時呼び出しを実行することはお勧めできません。そこ)一般的な状況に合った完成をすべて適用したいからです。(cd $words[2] && shift 2 words && ((CURRENT-=2)) && _normal)
完成がサブシェルで動作する場合、正しいことをしますが、そうではありません。cd $words[2] && shift 2 words && ((CURRENT-=2)) && _normal; cd $OLDPWD
通常の状況では機能しますが、+キャンセルをSOMEDIR
押すと、完了するのに長い時間がかかるように、特定の状況では中断され、緊張しなくなります。CtrlC
これがの定義ですcd1
。ターゲットディレクトリのエイリアスと拡張ワイルドカードをサポートします(一方、コマンドの置き換えなどは元のディレクトリで引き続き実行されます)。
cd1_glob () {
if (($# <= 1)); then
cd -- "$1"
elif (($+aliases[$2])); then
( cd -- $1 && eval $2 '$~@[3,$#]' )
else
( cd -- $1 && $~@[2,$#] )
fi
}
alias cd1='noglob cd1_glob'
(私はこの関数を呼び出しません。呼び出す場合は、cd
関数の内部呼び出しをに変更してください。)cd
builtin cd
答え1
これが私が今まで持っているものです。完璧ではありませんが、次のようになります。
- ターゲットディレクトリに基づいて完了しました。
- 宛先ディレクトリがない場合、自動エラーが発生します。
- スキップして
chpwd
復元chpwd_functions
するのが正しいと思います。 - キャンセルが完了すると、現在のディレクトリが復元されます。
複雑で脆弱に見えるので、極端なケースにはまったく自分がいません。既知の問題:
- 補完が常にサフィックス文字(スペースやディレクトリなど)を追加するわけではありません
/
。たとえば、挿入のみを挿入cd1 / echo /bi
Tabします(挿入は)。n/
cd1 / echo bi
Tabn
echo bi
Tabn/
- 操作の完了中に元のディレクトリの名前が変更されると、シェルは新しい名前の古いディレクトリの代わりに古い名前の新しいディレクトリに戻ります。
#compdef cd1 cd1_glob
# cd for one command
_cd1_in () {
setopt local_options local_traps
# Cleanup:
# * Restore the old directory. We do this only if cd succeeded beause
# the restoration can do the wrong thing in corner cases (renamed
# directory).
# * Restore the chpwd hook function and the hook array.
trap 'if ((_cd1_cd_succeeded)); then cd $OLDPWD; fi
if [[ -n $_cd1_chpwd_function ]]; then
functions[chpwd]=$_cd1_chpwd_function
fi
' EXIT INT
builtin cd $words[2] 2>/dev/null || { _cd1_cd_succeeded=0; return 1; }
shift 2 words; ((CURRENT -= 2))
_normal
}
_cd1 () {
if ((CURRENT > 2)); then
setopt local_options no_auto_pushd unset
local _cd1_cd_succeeded=1
# Save the current directory and the chpwd hook. They will be restored
# by the exit trap in _cd1_in.
local _cd1_chpwd_function=$functions[chpwd]
# Save the current directory in $OLDPWD. _cd_in will call cd, which would
# generally call cd
local OLDPWD=$PWD
# Turn off the chpwd hook function and the associated hook array.
local chpwd_functions=
unset -f chpwd 2>/dev/null
# Call a separate function to do the work. Its exit trap will take care
# of cleanup. The reason to have a separate function is so that the
# local variables defined here can be used in the exit trap.
_cd1_in
else
_dirs
fi
}
_cd1 "$@"