최근 bash 완성을 통해 기존 완성을 재사용하는 방법은 무엇입니까?

최근 bash 완성을 통해 기존 완성을 재사용하는 방법은 무엇입니까?

나는 사용한다별명일부 프로그램에 일부 매개변수를 추가합니다.

예를 들어:

alias git.home='git --git-dir=$HOME/.git.home/'

complete -o bashdefault -o default -o nospace -F _git git.home \
  2>/dev/null || complete -o default -o nospace -F _git git.home

bash-completion v.1:2.0-1("debian 7 wheezy") 에서 작동합니다 :
tab전체 매개변수 및 옵션별명 git.home그리고 "원본" git.

하지만 ("debian 8 jessie")를 입력하고 누르면 bash-completion v.1:2.1-4다음 오류가 발생합니다:git.hometab

bash: 완료: '_git' 함수를 찾을 수 없습니다.

git최신 버전의 패키지에 기존 완성(예: for )을 재사용하려면 어떻게 해야 합니까 bash-completion?


고쳐 쓰다

부분적인 해결책 찾기: source /usr/share/bash-completion/completions/git이전에 수행complete ...

하지만 또 다른 오류가 발생합니다. - git.home log+ space+ tab결과:

치명적: git 저장소(또는 상위 디렉터리)가 아님: .git HEAD

답변1

최신 버전의 bash-completion 패키지(예: git)를 통해 기존 완성을 재사용하는 방법

다음 줄을 다음 줄에 추가하세요 ~/.bashrc.

_completion_loader git
eval $(complete -p git | perl -pe 's/(\s)git$/$1git.home/')

설명하다:

bash-completion이는 동적 로딩을 사용하여 수행됩니다.1.90. 따라서 , 를 git입력할 때까지 compspec을 사용할 수 없습니다 git.SpaceTab

노력하다:

bash
complete -p git # bash: complete: git: no completion specification
git<space><tab>
complete -p git # complete -o bashdefault -o default -o nospace -F __git_wrap__git_main git

_completion_loader git모방 git, Space, Tab(즉, 로드된 compspec git)

complete -p git | perl -pe 's/(\s)git$/$1git.home/'다음에 대한 compspec 빌드 ( a 의 compspec git.home대체 )gitgit.homegit

eval생성된 compspec을 실행합니다.

유형 git.home, Space, pTab. 넌 봐야 해:

popt   pull   push

하지만 git.home log,, Space생산하다 Tab:

치명적: git 저장소(또는 상위 디렉터리)가 아님: .git HEAD

이 메시지는 git 완료 오류의 결과입니다. 업스트림에 수정 사항이 있습니다.완료: "치명적: git 저장소가 아님" 오류를 중지합니다.

또 다른 질문인 것 같습니다 :)

_githome(){ 
   GIT_DIR=$HOME/.git.home
   complete -o default -o nospace -F _git git.home
 }

예상대로 작동하지 않습니다. GIT_DIR현재 세션에 대해 설정했습니다 . 해결 방법을 시도해 보십시오.

bash
git clone git://git.debian.org/git/bash-completion/bash-completion.git ~/bash-completion
cd ~/bash-completion
git log<space><tab> # completion for current repo
git.home log<space><tab> # completion for GIT_DIR
git log<space><tab> # completion for GIT_DIR

답변2

고쳐 쓰다

해결책별명 git.home, repo와 함께 실행됩니다 ~/.git.home.

부분적으로 기반이 답변.

다음에 추가 ~/.bashrc:

alias git.home='git --git-dir=$HOME/.git.home/'

_completion_loader git
eval "$(complete -p git | sed -r 's/(\s)git$/\1git.home/')"

eval "$(type __gitdir | 
  sed '1d;1,/if/s|if|if [[ "$COMP_LINE" == "git.home "* ]]; then\necho "$HOME/.git.home"\nelif|')"

최종 설명eval(다른 노선에 대해서는 다음을 참조하세요.답변):

__gitdir()우리는 git repo 디렉토리에 대한 경로를 반환하는 함수를 패치하고 있습니다 . 에서:

$ type __gitdir | head -n 4
__gitdir is a function
__gitdir () 
{ 
    if [ -z "${1-}" ]; then

도착하다:

$ type __gitdir | head -n 7
__gitdir is a function
__gitdir () 
{ 
    if [[ "$COMP_LINE" == "git.home "* ]]; then
        echo "$HOME/.git.home";
    else
        if [ -z "${1-}" ]; then

즉, 명령이 a로 시작하면 "git.home "함수는 를 반환합니다 $HOME/.git.home.

답변3

이것은 모든 완성 기능에 적용되는 일반적인 답변입니다. 한 줄 출력이 sedOR로 구문 분석 perl되고 외부 호출 없이 구현할 수 있다고 가정하면 다른 답변의 안전성이 걱정됩니다 .

# Usage: complete_as TARGET COMMAND [COMMAND...]
# Tab-complete one or more COMMANDs like TARGET
complete_as() {
  _completion_loader "$1"
  local completion="$(complete -p "$1")"
  completion="${completion%[[:space:]]$1}"
  shift
  eval "$completion $@"
}
complete_as git git.home

이전 답변의 코드와 마찬가지로 sed이는 대상 명령( )의 마지막 인스턴스를 새 명령( )으로 대체하지만 저는perl$1$2매개변수 대체, 출력의 각 줄에서 작업하는 대신 전체 내용을 살펴봅니다. 완성 함수의 출력에는 때때로 ( 의 경우처럼) 끝에 개행 문자가 있기 때문에 이는 중요합니다 complete -W "$(_parse_help foo)" foo. 외부 통화를 제거하면 속도도 빨라지는데, 자주 수행하면 알 수 있습니다.

__gitdir유사한 기능을 수정하기 위해 이와 같은 보안을 유사하게 구축하고 bash 대체를 사용할 수 있습니다.알렉산더 발라킨의 답변하다.

당신은 또한 볼 수 있습니다이 zsh 솔루션같은 문제에 대해.

관련 정보