Bashbash 中任何目錄的
bash 中任何目錄的 ~/bin/*
文件名的命令參數完成
一個基本的 bash 功能是完成儲存在各種 bin 目錄中的命令,而不管目前工作目錄如何。這允許使用者保持命令和二進製文件的組織,而不需要他們從需要執行的任何目錄中指定完整路徑。
在我執行這些 bin 文件之前,bash 究竟是如何提供這個命令完成的,我認為,從設計的角度來看,在我編輯它們之前期望相同的命令完成是有意義的。
在我的特殊情況下,這意味著修改我的編輯器的完成功能
vi
,因此它不僅包括來自我目前工作目錄的文件名,還包括來自我的文件名~/bin/
(我實際上並不關心從其他 bin 添加命令)。對此SO答案的簡單修改可以做到這一點:
$ source _vi $ complete -f -F _vi vi
其中 _vi 定義為:
_vi () { local word=${COMP_WORDS[COMP_CWORD]}; local pat="~/bin/*" COMPREPLY=($(compgen -f -G "$pat" -- "~/bin/${word}")); i=0 for item in "${COMPREPLY[@]}"; do COMPREPLY[$i]="${item##*/}" i+=1 done; return 0; }
但是 vi 需要傳遞完整路徑才能打開文件!
所以我的問題是:我怎樣才能從製表符完成文件名
~/bin/
但仍將完整路徑傳遞給vi
?這只是一個|
夢嗎?我應該嘗試完全不同的方法嗎?如果您可以幫助我
~/bin/*
在使用vi (TAB)(TAB)
!編輯:
以下是我正在使用的功能,基於@roaima 的回答和他們對下面概括的建議。為我關心的兩個(二進製文件和配置文件)以外的目錄中的文件添加與目錄無關的完成訪問很容易。
_vi () { local word=${COMP_WORDS[COMP_CWORD]}; local bin_dir="~/bin/" local dot_dir="~/dotfiles/" COMPREPLY=($(compgen -f -G "$bin_dir*" -- "$bin_dir${word}")); COMPREPLY+=($(compgen -f -G "$dot_dir*" -- "$dot_dir${word}")); return 0; }
最簡單的方法是避免將路徑從
$item
添加到$COMPREPLY[$i]
:_vi () { local word=${COMP_WORDS[COMP_CWORD]}; local pat="~/bin/*" COMPREPLY=($(compgen -f -G "$pat" -- "~/bin/${word}")); return 0; }
顯示的可能列表沒有路徑組件,但在成功完成後會插入路徑。
另一種方法是使用 shell 腳本擴展
vi
自身,該腳本在目前目錄中查找文件名,如果未找到,則檢查~/bin/
.$CDPATH
但是在這一點上,讓編輯器等效於完成目錄而不是將程式碼限制為搜尋~/bin
/開始變得有意義。