zsh에서 avfs 가짜 디렉토리 완성

zsh에서 avfs 가짜 디렉토리 완성

경우에 따라 "가짜" 파일을 완성하기 위해 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}#

( 명령뿐만 아니라 _filesor 에 대한 모든 호출에 완성 기능을 적용하고 싶습니다 . 가능하다면 함수의 코드를 반복하지 않아도 됩니다 .)_dirscd_files

그리고 나머지 모든 확장

답변1

이 가짜 질문에 대한 가짜 대답은 충분하지 않은 것 같습니다. zsh의 자동 마운트 디렉토리에 대한 내장 지원은 fake-files dir:names디렉토리( ) 내의 파일 모드가 아니라 작동합니다. 이는 디렉터리에 특별히 이름이 지정된 파일을 추가하는 데 편리할 수 있으며, 이는 설치할 디렉터리가 알려진 정적 이름인 NetApp 유형 automount설정 에 적합할 수 있습니다 .sshfs.snapshotALAS

autoload -U compinit
compinit
zstyle ':completion:*' fake-files $HOME/.avfs:'ALAS POOR YORICK'

zshall(1)"이름"이 문자열이라고 말하면 실험에 따르면 메타 문자(예: 또는 #) 가 다양한 방식으로 "작동하지 않음"이 나타나므로 명령문의 이름 부분에 덩어리를 몰래 넣는 방법을 모르겠습니다 . (더 깊이 파고들면 이름이 정확히 무엇을 의미하는지 알 수 있지만 더 많은 작업이 필요합니다.) (또한 디렉토리 위치에서 재귀 글로브를 사용하여 아카이브 파일 이름을 지정하는 것은 가능하지 않지만 다시 C 다이빙을 통해 얼마나 많은지 확인해야 합니다. 당신을 탈출시킵니다.)\#'*(e:"echo hi":)'fake-filesSrc/Zle/computil.cfake-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+$+#+') )

행운을 빌어요!

관련 정보