경우에 따라 "가짜" 파일을 완성하기 위해 zsh의 완성 시스템을 어떻게 조정할 수 있습니까?
더 정확하게,AVFS파일 시스템은 각 아카이브 옆에 "가짜 디렉터리"를 생성하여 아카이브를 디렉터리로 노출합니다. 기본적으로 마운트 지점 아래의 전체 디렉터리 계층 구조를 복사합니다 ~/.avfs
. 또한 아래에는 ~/.avfs
각 아카이브 파일(예: )에 대해 /tmp/foo.zip
아카이브 파일 자체 외에도 아카이브의 내용을 노출하는 라는 ~/.avfs/tmp/foo.zip
디렉터리가 있습니다 . ~/.avfs/tmp/foo.zip#
그러나 이 추가 디렉터리는 목록에 나타나지 않으며 ~/.avfs/tmp
명시적으로 요청될 때만 존재합니다. (이는 일부 자동 설치 프로그램의 작동 방식과 유사합니다.)
mountavfs
cd ~/.avfs/tmp/foo.zip\#
위와 같은 명령어를 입력해도 해당 디렉터리가 없어 foo.zip#
완료로 표시되지 않습니다 . 전체 경로가 1 과 ~/.avfs/tmp/
일치하는 파일이 있을 때마다 라는 디렉터리가 있는 것처럼 가장해야 한다고 zsh에 어떻게 지시합니까 ?$arc
~/.avfs/**/*.(tgz|zip)
${arc}#
( 명령뿐만 아니라 _files
or 에 대한 모든 호출에 완성 기능을 적용하고 싶습니다 . 가능하다면 함수의 코드를 반복하지 않아도 됩니다 .)_dirs
cd
_files
그리고 나머지 모든 확장
답변1
이 가짜 질문에 대한 가짜 대답은 충분하지 않은 것 같습니다. zsh의 자동 마운트 디렉토리에 대한 내장 지원은 fake-files dir:names
디렉토리( ) 내의 파일 모드가 아니라 작동합니다. 이는 디렉터리에 특별히 이름이 지정된 파일을 추가하는 데 편리할 수 있으며, 이는 설치할 디렉터리가 알려진 정적 이름인 NetApp 유형 automount
설정 에 적합할 수 있습니다 .sshfs
.snapshot
ALAS
autoload -U compinit
compinit
zstyle ':completion:*' fake-files $HOME/.avfs:'ALAS POOR YORICK'
zshall(1)
"이름"이 문자열이라고 말하면 실험에 따르면 메타 문자(예: 또는 #
) 가 다양한 방식으로 "작동하지 않음"이 나타나므로 명령문의 이름 부분에 덩어리를 몰래 넣는 방법을 모르겠습니다 . (더 깊이 파고들면 이름이 정확히 무엇을 의미하는지 알 수 있지만 더 많은 작업이 필요합니다.) (또한 디렉토리 위치에서 재귀 글로브를 사용하여 아카이브 파일 이름을 지정하는 것은 가능하지 않지만 다시 C 다이빙을 통해 얼마나 많은지 확인해야 합니다. 당신을 탈출시킵니다.)\#
'*(e:"echo hi":)'
fake-files
Src/Zle/computil.c
fake-files
를 사용하면 디렉터리 완료 상태를 compdef
나열할 수 있습니다 ..avfs
compdef '_files -g $HOME/.avfs/\*' -p \^
function andthehash {
reply=($REPLY $REPLY\#)
}
compdef "_files -g $HOME/.avfs/'*(+andthehash)'" -p \^
그러나 이는 #
중요하지 않은 파일만 표시하여 완료할 수 없기 때문에 실패합니다. (이 양식은 생산적인 용도로 많이 사용되지만 이 예에는 적용되지 않습니다.)
다음과 같이 사용하면 zstyle
더 가까워질 수 있습니다 .zshrc
.
autoload -U compinit
compinit
function UnderAVFS {
local pdir
[[ -z $1 ]] && return 1
pdir=$1:a
[[ ! -d $pdir ]] && pdir=$pdir:h
[[ ! -d $pdir || $pdir == . ]] && return 1
while [[ $pdir != / ]]; do
[[ $pdir == $HOME/.avfs ]] && return 0
pdir=$pdir:h
done
return 1
}
function AVFSExtras {
if UnderAVFS $REPLY; then
reply=($REPLY)
# TODO embiggen list of archive suffixes
[[ $REPLY == *.(bz2|tbz2) ]] && reply+=($REPLY\#)
fi
}
# Try to match avfs, otherwise the default pattern. Probably could greatly
# benefit from caching, to avoid hits on UnderAVFS function.
zstyle ':completion:*' file-patterns '*(+AVFSExtras):avfs-files' '%p:all-files'
그러나 해당 \#/
비트(기본 avfs 설정을 사용하는 debian squeeze virt의 경우)만 완료할 수 있고 아카이브의 가상 파일 시스템은 완료할 수 없으므로 아카이브를 완료하려면 추가 작업이 필요합니다. 존재하지 않는 디렉토리가 실제로 존재한다고 믿을 수 있는 더 우아한 방법이 없다면 via _call_program ... ls
또는 이와 유사한 것이 비트를 수행할 수 있을 것으로 추측합니다 .\#
zsh
나쁜 소식! _path_files
가짜 디렉토리의 경우 완료가 성공하지 못합니다. 이는 zsh globbing과 관련이 있는 것 같습니다. 이 문제는 zsh 4.something on과 zsh 5.0.8 모두에서 발생합니다. 따라서 완전한 수정을 위해서는 패치를 적용 _path_files
하거나 이러한 가짜 디렉토리에 대해 수행할 수 있는 다른 내용을 작성해야 할 것으로 생각됩니다. 누구든지 실패의 원인을 파헤치고 싶다면 ls /root/.avfs/root/sometar.gz\#/
입력하고 해당 입력 끝에 입력한 다음 control-x
해당 키 조합을 ?
가정 하고 바인딩하여 완료 디버그 추적을 생성할 수 있습니다.bindkey -e
_complete_debug
답변2
zsh에서는 compctl -K
자체 함수 등록을 사용하여 완료 옵션을 생성할 수 있습니다. 예를 들어:
compctl -f -c -u -r -K myAVFScompletion "*" -tn
그런 다음 자신만의 함수를 정의해야 합니다.
myAVFScompletion () {
read -c COMMAND ARGS
# Decide what paths you want to suggest completion for
# by looking inside the ~/.avfs folder.
# Place your suggestions into an array:
reply=( a_path b_path ... )
}
분명히 위의 작업에는 더 많은 작업이 필요하지만 시작에 불과합니다.
유사하지만 다른 사용자 정의 완성 기능을 Bash에 등록할 수 있습니다.
이것은Bash 및 zsh 구현의 예. (명령 매뉴얼 페이지에서 옵션을 선택하여 명령줄 옵션을 완성합니다.)
다음은 완성 함수에서 작동할 수 있는 작업에 대한 몇 가지 빠른 추측입니다.
if [[ -d "$ARGS#" ]]
then reply=( "$ARGS#" )
else reply=
fi
아니면 다음과 같은 것일 수도 있습니다.
reply=( $(find ~/.avfs -type f -name "*.tgz" -or -name "*.zip" | sed 's+$+#+') )
행운을 빌어요!