zsh에서 avfs fake 디렉토리 완성


37

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#아래에 완료로 표시되지 않습니다 ~/.avfs/tmp/. 전체 경로 $arc~/.avfs/**/*.(tgz|zip)¹ 인 파일이있을 때마다 z 라는 디렉토리가있는 것처럼 가장해야한다고 zsh에 어떻게 알 수 ${arc}#있습니까?

(나는 모든에 전화로 작업을 완료 할 것을주의 _files또는 _dirs뿐만 아니라위한 cd명령을. 나는의 코드를 복제 할 필요가하고 싶지 않은 것 _files, 가능하면 기능.)

¹ 및 나머지 모든 확장


~ / .avfs에 전체 파일 시스템의 "복사본"이 포함되어 있습니까?
ctrl-alt-delor

@richard 예, 모두 /path/to/foo로 표시됩니다 ~/.avfs/path/to/foo.
Gilles 'SO- 악마 그만'

이 문제는에서 더 쉽게 해결 될 수 있습니다 avfs. #그것이 지원하는 문자열과 일치하는 파일에 대한 기본 디렉토리 항목을 제시 했거나 디렉토리에있는 파일에서 #항목 이 필요한 항목 을 매직 테스트 한 경우 완료가 작동합니다. find압축 파일을 통해 트롤링하는 것과 같은 성능 저하가있을 것으로 생각 합니다.
Matt

답변:


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)"이름"은 문자열이며 실험 결과 메타 문자 (예 : #또는 \#또는 '*(e:"echo hi":)')가 다양한 방식으로 "작동하지 않음"을 나타내 므로 fake-files명령문 의 이름 부분에 글 을 몰래 넣을 방법을 알 수 없습니다 . (디스플레이를 통해 Src/Zle/computil.c이름이 정확히 무엇인지 알 수 있지만 더 효과가 있습니다.) (또한 디렉토리 위치에서 재귀 글로브를 사용하여 아카이브 파일 이름을 지정하지는 않았지만 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 설정의 데비안 스퀴즈 virt 에서만 비트 를 완료 할 수 있지만 아카이브의 가상 파일 시스템에서는 완료 할 수 없으므로 아카이브를 완료하려면 추가 작업이 필요합니다. 존재하지 않는 디렉토리가 있다고 생각 하는 더 우아한 방법이 없다면, _call_program ... ls그 줄을 따라 또는 그 줄을 따라 무언가를 \#조금씩 추측 하고 zsh있습니다.

나쁜 소식! 완성은 _path_files가짜 디렉토리를 통과시키지 않습니다 . 이것이 zsh globbing과 관련이 있다고 생각합니다. zsh 4.something on 및 zsh 5.0.8 모두 문제가 있습니다. 따라서 완전한 수정에는 패치가 필요 _path_files하거나 이러한 가짜 dirs에서 완료되는 다른 것을 작성 해야한다고 생각합니다 . 누군가가 이것이 왜 실패 하는지를 조사하기를 원한다면, ls /root/.avfs/root/sometar.gz\#/그 입력의 끝에서 타자를 입력 control-x하고 그 콤보에 묶여 ?있다고 가정 bindkey -e하고 완료 디버깅 추적을 생성 할 수 있습니다 _complete_debug.


0

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+$+#+') )

행운을 빕니다!


완성 기능을 작성하는 방법을 알고 있습니다. 대단히 감사합니다. 문제는 파일의 기존 완료 메커니즘을 수정하는 방법입니다. 나는 "새로운"완성 메커니즘을 사용한다 compctl. 즉, 무엇을 바꾸고 싶다 _files. 당신의 대답은 전혀 도움이되지 않습니다.
Gilles 'SO- 악마 그만'

@Gilles 화염 전쟁을 시작하지 말고 잘못 이탈 할 위험이있는 경우 적어도 그는 시도했습니다 ... 이것은 대답하지 않은 "다락방"에 2 년을 더한 것입니다. .
eyoung100

@ eyoung100 노력에 +1을주지 마십시오 (여기에는 노력이 분명하지 않습니다). 도움이되지 않는 답변을 피하는 것은 사이트에 해 롭습니다.
Gilles 'SO- 악한 중지'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.