내가 여기서 어리석은 짓을 했다면 용서하세요. 문서는 방대하고 검색해도 아직 아무것도 나오지 않았습니다.
이라는 사용자 정의 스크립트에 대한 셸 완성 기능을 만들려고 합니다 fab
. bash를 사용하면 쉽습니다. 그냥 넣기만 하면 /etc/bash_completion.d
작동합니다. 하지만 맙소사, zsh는 PITA인가요?
완성 기능이 있는데 _fab
활성화되면 제대로 작동합니다 compdef _fab fab
. /usr/share/zsh/vendor-completions/_fab
이미 내 에 배치했습니다 $fpath
. 파일은 로 시작 #compdef fab
하고 로 끝납니다 compdef _fab fab
. 좋아 보인다:
$ type _fab
_fab is an autoload shell function
하지만 새 셸을 시작할 때마다 fab
완성이 작동하지 않습니다( vendor-completions
예를 들어 의 다른 기능은 _docker
괜찮습니다). compinit
이 특정 셸의 문제를 해결했습니다. 나는 그것이 rm ~/.zcompdump ~/.zcompdump-$(hostname)-5.1.1; compinit
영구적으로 작동한다는 것을 알았습니다(5.1.1 = 내 zsh 버전).
질문:
~/.zcompdump
초기 완료를 설정하기 위해 언제, 무엇을 읽어야 합니까 ?man zshall
설명하다:다음 compinit 호출에서는 전체 초기화를 수행하는 대신 덤프된 파일을 읽습니다.
그렇다면
compinit
삭제하기 전에 완성도가 수정되지~/.zcompdump
는 않겠죠? 내가 뭐 놓친 거 없니?- 그것은 무엇
~/.zcompdump-$(hostname)-5.1.1
과 어떻게 관련되어 있습니까.zcompdump
? 유일한 차이점은 완료 중 하나~/.oh-my-zsh/completions
($ZSH
를 가리키 므로~/.oh-my-zsh
)가 완료 중 하나라는 것입니다. 이게 oh-my-zsh 일인가요? - 이러한 완성 항목을 재배포 가능 패키지로 패키징하거나 설치 프로그램 스크립트를 생성하려면 zsh 완성 항목을 어디에 두어야 합니까? 모든 것이 제대로 작동하는지 확인하려면 설치 과정에서 또 무엇을 해야 합니까?
Ubuntu 16.04, 18.04 및 19.04를 대상으로 하고 있지만 distro 관련 정보가 아닌 경우 환영합니다. 저는 zsh 5.1.1과 최근 oh-my-zsh를 사용하여 Ubuntu 16.04에서 테스트하고 있습니다.
답변1
TL,DR: 일반적인 작업에서는 파일을 해당 디렉터리에 놓기만 하면 됩니다. 테스트할 때 캐시 파일을 삭제해야 합니다( .zcompdump
기본적으로 사용자는 이를 다른 위치에 저장할 수 있지만 oh-my-zsh는 이를 다른 위치에 저장합니다).
간단한 대답은 첫 번째 줄이 있는 파일에 완성 함수를 작성하는 것입니다.#compdef fab
. 파일은 의 디렉터리에 있어야 합니다 $fpath
.
파일에는 함수 본문이 포함될 수도 있고 함수 정의와 함수 호출이 포함될 수도 있습니다. 즉, 파일에는 다음과 같은 내용이 포함되어 있습니다.
#compdef fab
_arguments …
또는
#compdef fab
function _fab {
_arguments …
}
_fab "$@"
$fpath
이 파일은 실행하기 전에 존재해야 합니다 compinit
. 이는 순서에 주의를 기울여야 함을 의미합니다 .zshrc
. 먼저 사용자 정의 디렉토리를 추가한 $fpath
다음 호출하십시오 compinit
. oh-my-zsh와 같은 프레임워크를 사용하는 경우 $fpath
oh-my-zsh 코드 앞에 사용자 지정 디렉터리를 추가해야 합니다.
compinit
시스템을 초기화하고 완료하는 기능입니다. 모든 파일을 읽고 $fpath
첫 번째 줄에 마법 명령이 있는지 확인합니다.#autoload
그리고#compdef
.
.zcompdump
기본 위치입니다. 런타임 시 다른 위치 compinit
를 ~/.zcompdump
선택할 수 있습니다 compinit
. Oh-my-zsh를 호출할 compinit
때 -d
변수에 의해 제공되는 다른 캐시 파일 이름을 사용하도록 선택할 수 있습니다 ZSH_COMPDUMP
.기본값은
ZSH_COMPDUMP="${ZDOTDIR:-${HOME}}/.zcompdump-${SHORT_HOST}-${ZSH_VERSION}"
호스트 이름은 컴퓨터 간에 홈 디렉토리가 공유되고 다른 컴퓨터에 다른 소프트웨어가 설치된 사용자를 위해 포함됩니다. 캐시 파일이 버전 간 호환되지 않기 때문에 zsh 버전이 포함되었습니다(버전마다 다른 코드가 포함되어 있음).
귀하의 모든 문제는 오래된 캐시 파일로 인해 발생한다고 생각합니다(이로 인해 상황이 지나치게 복잡해집니다). 안타깝게도,캐시된 파일이 오래된 것인지 확인하는 Zsh 알고리즘완벽하지는 않습니다. 아마도 속도 때문일 것입니다. 파일의 내용이나 타임스탬프를 확인하지 않고 $fpath
단지 개수만 계산합니다. 파일은 .zcompdump
다음 줄로 시작됩니다.
#files: 858 version: 5.1.1
zsh 버전과 파일 수가 올바른 경우 zsh는 캐시된 파일을 로드합니다.
캐시 파일에는 완료 기능에 대한 코드가 아닌 명령 이름 간의 연결만 포함됩니다. 캐시 투명성이 작동하는 몇 가지 일반적인 시나리오는 다음과 같습니다.
- 새 파일이 추가되면
$fpath
캐시가 무효화됩니다 . - 보다 일반적으로 에서 파일을 추가 및 제거하고
$fpath
제거된 총 파일 수가 제거된 총 파일 수와 다른 경우 캐시가 무효화됩니다. - 이름을 변경하지 않고 파일을 다른 디렉터리로 이동하면
$fpath
캐시의 어떤 항목에도 영향을 미치지 않으므로 캐시가 올바르게 유지됩니다. - 첫 번째 줄을 변경하지 않고 파일을 수정하면
$fpath
캐시의 어떤 항목에도 영향을 주지 않으므로 캐시는 올바른 상태로 유지됩니다.
캐시가 무효화되었지만 zsh가 이를 인식하지 못하는 몇 가지 일반적인 시나리오는 다음과 같습니다.
- 일부 파일을 추가
$fpath
하고 정확히 동일한 수의 파일을 삭제합니다. - 파일 이름을
$fpath
. #compdef
파일 상단에 (또는) 줄을 추가하거나 수정할 수 있습니다 .#autoload
이 마지막 지점은 테스트 중에 가장 까다로운 문제입니다. 이 줄을 변경하는 경우 파일을 삭제하고 zsh를 다시 시작(또는 다시 실행 ) #compdef
해야 합니다 ..zcompdump
compinit
재배포 가능 패키지에 완성 파일을 넣는 경우 완성 파일을 시스템 전체 디렉터리에 넣기만 하면 됩니다 $fpath
. Ubuntu 패키지 /usr/share/zsh/vendor-completions
의 경우 적절한 위치는 입니다 /usr/local
. /usr/local/share/zsh/site-functions
그게 당신이해야 할 전부입니다.
투명하지 않은 한 가지는 #compdef
업그레이드에서 줄을 변경해야 하는지, 특정 파일을 삭제하거나 이름을 바꿔야 하는지 여부입니다. 이 경우 사용자는 캐시 파일을 삭제해야 하며 이는 다중 사용자 컴퓨터에 설치된 패키지에서는 수행할 수 없는 작업입니다.