이것은 완벽하지는 않지만 다시 bash 완성은 매우 까다로운 것입니다 ...
가장 간단한 방법은 명령별로 FIGNORE
수행하는 것입니다. 보다 유연합니다 .
complete -f -X "/myproject/data/*" vi
이렇게하면 자동 완성이 vi
파일 완성임을 알리고 -X
필터 와 일치하는 패턴을 제거합니다 . 단점은 패턴이 정규화 ../data
되지 않아 변형이 일치하지 않는다는 것입니다.
다음으로 가장 좋은 것은 사용자 정의 PROMPT_COMMAND
함수 일 수 있습니다 .
# 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
이렇게 하면 디렉토리에있을 때 완료 (완전히)가 비활성화 되지만 해당 디렉토리의 파일뿐만 아니라 모든 경로에 대해 완료가 비활성화됩니다.
정의 된 경로에 대해 이것을 선택적으로 비활성화하는 것이 더 일반적으로 유용하지만 유일한 방법은 기본 완료 기능 (bash-4.1 이상과 함께 complete -D
)을 사용하고 많은 혼란을 일으키는 것입니다.
이것은 해야 당신을 위해 작동하지만 수 있습니다 의도하지 않은 부작용 (즉, 경우에 따라 예상되는 완료로 변경)이 있습니다
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
이것은 완료를 위해 작동 vi
하며 필요에 따라 다른 명령을 추가 할 수 있습니다. 경로 또는 작업 디렉토리에 관계없이 명명 된 디렉토리의 파일에 대한 완료를 중지해야합니다.
일반적인 접근 방식 complete -D
은 각 명령마다 완료 기능을 동적으로 추가하는 것입니다. 추가해야 할 수도 있습니다 complete -E
(입력 버퍼가 비어있을 때 명령 이름 완성).
업데이트PROMPT_COMMAND
및 완료 기능 솔루션
의 하이브리드 버전은 다음 과 같습니다. 이해하고 해킹하는 것이 조금 더 쉽습니다.
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
이 프롬프트 기능 nocomplete
은 구성된 디렉토리 중 하나를 입력 할 때 변수를 설정합니다 . 수정 된 완료 동작은 해당 변수가 비어 있지 않은 경우 와 빈 문자열에서 완료하려고 할 때만 시작 되므로 부분 이름을 완료 할 수 있습니다 (완료 -z "$cur"
되지 않도록 조건을 제거하십시오 ). printf
자동 조작을 위해 두 줄을 주석 처리하십시오.
다른 옵션으로는 필요에 따라 디렉토리에서 .noautocomplete
할 수 touch
있는 디렉토리 별 플래그 파일이 있습니다 . GNU를 사용한 디렉토리 크기 추측 stat
. 이 세 가지 옵션 중 하나 또는 모두를 사용할 수 있습니다.
(이 stat
방법 은 추측에 불과하며 ,보고 된 디렉토리 크기는 내용과 함께 증가합니다. "높은 워터 마크"는 관리 개입없이 파일을 삭제해도 일반적으로 줄어들지 않습니다. 디렉토리. 파일 당 정확한 동작과 증가는 기본 파일 시스템에 달려 있습니다. 리눅스 ext2 / 3 / 4 시스템에서 신뢰할 수있는 지표라고 생각합니다.)
bash는 비어있는 완료가 리턴 될 때에도 추가 공간을 추가합니다 (이는 행 끝에서 완료 할 때만 발생 함). 이를 방지하기 위해 명령에 추가 -o nospace
할 수 있습니다 complete
.
하나의 남은 문제는 커서를 토큰의 시작 부분에 백업하고 탭을 누르면 기본 완료가 다시 시작된다는 것입니다. 기능을 고려하십시오 ;-)
(또는 ${COMP_LINE:$COMP_POINT-1:1}
오버 엔지니어링을 좋아한다면 문제를 해결할 수는 있지만 명령 중간에 백업을 완료하고 완료하려고 할 때 bash 자체가 완료 변수를 안정적으로 설정하지 못한다는 것을 알았습니다.)