Điều này không hoàn hảo, nhưng sau đó một lần nữa hoàn thành bash là một điều khá khó khăn ...
Cách đơn giản nhất là trên cơ sở mỗi lệnh, nó linh hoạt hơn một chút so với FIGNORE
, bạn có thể làm:
complete -f -X "/myproject/data/*" vi
Điều này hướng dẫn tự động hoàn thành mà hoàn thành cho vi
cho các tệp và để loại bỏ các mẫu phù hợp với -X
bộ lọc. Nhược điểm là mẫu không được chuẩn hóa, do đó ../data
và các biến thể sẽ không khớp.
Điều tốt nhất tiếp theo có thể là một PROMPT_COMMAND
chức năng tùy chỉnh :
# associative arrays of non-autocomplete directories
declare -A noacdirs=([/myproject/data]=1 )
function _myprompt {
[[ -n "${noacdirs[$PWD]}" ]] && {
echo autocomplete off
bind 'set disable-completion on'
} || {
echo autocomplete on
bind 'set disable-completion off'
}
}
PROMPT_COMMAND=_myprompt
Điều này vô hiệu hóa hoàn thành (hoàn toàn) khi bạn đang ở trong thư mục, nhưng nó vô hiệu hóa nó cho mọi đường dẫn không chỉ các tệp trong thư mục đó.
Nhìn chung sẽ hữu ích hơn khi vô hiệu hóa một cách chọn lọc điều này cho các đường dẫn đã xác định, nhưng tôi tin rằng cách duy nhất là sử dụng chức năng hoàn thành mặc định (bash-4.1 trở lên với complete -D
) và rất nhiều điều sai lầm.
Điều này sẽ làm việc cho bạn, nhưng nó có thể có tác dụng phụ ngoài ý muốn (nghĩa là thay đổi hoàn thành dự kiến trong một số trường hợp):
declare -A noacdirs=([/myproject/data]=1 )
_xcomplete() {
local cur=${COMP_WORDS[COMP_CWORD]} # the current token
name=$(readlink -f "${cur:-./}") # poor man's path canonify
dirname=$(dirname "$name/.")
[[ -n "${noacdirs[$dirname]}" ]] && {
COMPREPLY=( "" ) # dummy to prevent completion
return
}
# let default kick in
COMPREPLY=()
}
complete -o bashdefault -o default -F _xcomplete vi
Điều này hoạt động để hoàn thành vi
, các lệnh khác có thể được thêm vào khi cần thiết. Nó sẽ dừng hoàn thành cho các tập tin trong các thư mục được đặt tên bất kể đường dẫn hoặc thư mục làm việc.
Tôi tin rằng cách tiếp cận chung complete -D
là tự động thêm các hàm hoàn thành cho mỗi lệnh khi nó gặp phải. Người ta cũng có thể cần thêm complete -E
(hoàn thành tên lệnh khi bộ đệm đầu vào trống).
Cập nhật
Đây là phiên bản kết hợp của các PROMPT_COMMAND
giải pháp chức năng và hoàn thành, tôi nghĩ dễ hiểu hơn và hack:
declare -A noacdirs=([/myproject/data]=1 [/project2/bigdata]=1)
_xcomplete() {
local cmd=${COMP_WORDS[0]}
local cur=${COMP_WORDS[COMP_CWORD]} # the current token
[[ -z "$cur" && -n "$nocomplete" ]] && {
printf "\n(restricted completion for $cmd in $nocomplete)\n"
printf "$PS2 $COMP_LINE"
COMPREPLY=( "" ) # dummy to prevent completion
return
}
COMPREPLY=() # let default kick in
}
function _myprompt {
nocomplete=
# uncomment next line for hard-coded list of directories
[[ -n "${noacdirs[$PWD]}" ]] && nocomplete=$PWD
# uncomment next line for per-directory ".noautocomplete"
# [[ -f ./.noautocomplete ]] && nocomplete=$PWD
# uncomment next line for size-based guessing of large directories
# [[ $(stat -c %s .) -gt 512*1024 ]] && nocomplete=$PWD
}
PROMPT_COMMAND=_myprompt
complete -o bashdefault -o default -F _xcomplete vi cp scp diff
Hàm nhắc này đặt nocomplete
biến khi bạn nhập một trong các thư mục được cấu hình. Hành vi hoàn thành đã sửa đổi chỉ khởi động khi biến đó không trống và chỉ khi bạn cố gắng hoàn thành từ một chuỗi trống, do đó cho phép hoàn thành tên một phần (loại bỏ -z "$cur"
điều kiện để ngăn chặn hoàn thành). Nhận xét hai printf
dòng cho hoạt động im lặng.
Các tùy chọn khác bao gồm .noautocomplete
tệp cờ trên mỗi thư mục mà bạn có thể có touch
trong một thư mục khi cần; và đoán kích thước thư mục bằng GNU stat
. Bạn có thể sử dụng bất kỳ hoặc tất cả ba tùy chọn đó.
( stat
Phương pháp chỉ là phỏng đoán , kích thước thư mục được báo cáo tăng theo nội dung của nó, đó là "dấu nước cao" thường không co lại khi các tệp bị xóa mà không có sự can thiệp của chính quyền. Nó rẻ hơn so với việc xác định nội dung thực sự của một tiềm năng lớn thư mục. Hành vi chính xác và gia tăng trên mỗi tệp phụ thuộc vào hệ thống tệp cơ bản. Tôi thấy đó là một chỉ báo đáng tin cậy trên các hệ thống linux ext2 / 3/4.)
bash thêm một khoảng trắng ngay cả khi trả về hoàn thành trống (điều này chỉ xảy ra khi hoàn thành ở cuối dòng). Bạn có thể thêm -o nospace
vàocomplete
lệnh để ngăn chặn điều này.
Một điều khó khăn còn lại là nếu bạn sao lưu con trỏ vào đầu mã thông báo và nhấn tab, việc hoàn thành mặc định sẽ khởi động lại. Hãy coi đó là một tính năng ;-)
(Hoặc bạn có thể futz xung quanh với ${COMP_LINE:$COMP_POINT-1:1}
nếu bạn thích quá kỹ thuật, nhưng tôi tìm bash bản thân thất bại trong việc thiết lập các biến hoàn đáng tin cậy khi bạn sao lưu và cố gắng hoàn thành vào giữa một lệnh.)