등호 뒤에 경로를 자동 완성하는 bash 완료 스크립트를 작성 하시겠습니까?


11

나는 형태의 인수를 인식하는 bash는 완료 스크립트를 만들려면 --arg--some-arg=file.

이 튜토리얼 과 예제를 읽은 후 /usr/share/bash_completion/completions/Chromium으로 플래그를 입력 할 때 시간을 절약하기 위해 다음 스크립트를 작성했습니다.

_chromium() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    # Some interesting options
    opts="
--disable-web-security
--easy-off-store-extension-install
--incognito
--load-extension=
--pack-extension=
--pack-extension-key=
--user-data-dir=
"
    # Handle --xxxxxx=file
    if [[ ${cur} == "--"*"=" ]] ; then
        # Removed failures (is my logic OK?)
        return 0
    fi

    # Handle other options
    if [[ ${cur} == -* ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi
}
complete -F _chromium chromium

에 저장 ~/bash_completions/chromium하고을 사용하여 심볼릭 링크를 만들었습니다 sudo ln -s ~/bash_completions/chromium /usr/share/bash_completion/completions/chromium.
그런 다음을 사용하여로드했습니다 . /usr/share/bash_completions/completions/chromium.

이제 두 가지 문제가 있습니다.

  • chromium --u<TAB>chromium --user-data-dir=<SPACE>(나는 공간을 원하지 않는다)로 확장합니다 .
  • 경로 (디렉토리 및 파일)가 더 이상 완료되지 않습니다.

이러한 문제를 어떻게 해결할 수 있습니까?


zsh로 전환하는 것이 옵션입니까?
Gilles 'SO- 악마 그만해

답변:


11

두 가지 문제에 대한 해결책을 찾았습니다!

  1. 공백을 추가하지 않으려면 nospace옵션을 사용하십시오 . 이것은 두 가지 방법으로 수행 할 수 있습니다.

    • 에 전달하십시오 complete:
      complete -o nospace -F _chromium chromium
    • 사용하여 compopt내장 :
      compopt -o nospace(이 옵션을 사용하기)
      compopt +o nospace(옵션을 사용하지 않으려면)

    나는 gnu.org의 Bash 문서, 8.7 Programmable Completion Builtins 에서 찾았습니다 .

  2. 파일 완성.
    • peterph는와-f 함께 플래그 를 사용하도록 제안 했습니다 compgen. 나는 그 조언을 따르고로 구현했습니다 COMPREPLY=( $(compgen -f "$cur") ). 공백이 포함 된 경로를 완료하려고 할 때까지 이것은 잘 작동했습니다.
      스택 오버플 로에서 완료 목록을 수동으로 생성하도록 권장하는 이 답변 을 찾았습니다 (을 사용하지 않고 compgen). 이 접근법은 잘 작동했습니다.
    • filenamesreadspec에게 compspec이 파일 이름을 생성한다고 알리 려면 다음 옵션을 사용하십시오 .
      • 디렉토리 이름에 슬래시 추가, 특수 문자 인용 또는 후행 공백 억제와 같은 파일 이름 별 처리 수행
      • 다른 색상을 사용하여 파일 형식을 나타냅니다 ( colored-stats활성화 된 상태)

의 도움으로 배쉬의 문자열 조작 (확장하려면 ~공백 처리), I는 질문에 명시된 모든 기준을 충족하는 bash는 완료 스크립트를 건설했다.

_chromium() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    # Some interesting options
    opts="
--disable-web-security
--easy-off-store-extension-install
--incognito
--load-extension=
--pack-extension=
--pack-extension-key=
--user-data-dir=
"
    # Handle --xxxxxx=
    if [[ ${prev} == "--"* && ${cur} == "=" ]] ; then
        compopt -o filenames
        COMPREPLY=(*)
        return 0
    fi
    # Handle --xxxxx=path
    if [[ ${prev} == '=' ]] ; then
        # Unescape space
        cur=${cur//\\ / }
        # Expand tilder to $HOME
        [[ ${cur} == "~/"* ]] && cur=${cur/\~/$HOME}
        # Show completion if path exist (and escape spaces)
        compopt -o filenames
        local files=("${cur}"*)
        [[ -e ${files[0]} ]] && COMPREPLY=( "${files[@]// /\ }" )
        return 0
    fi

    # Handle other options
    COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
    if [[ ${#COMPREPLY[@]} == 1 && ${COMPREPLY[0]} != "--"*"=" ]] ; then
        # If there's only one option, without =, then allow a space
        compopt +o nospace
    fi
    return 0
}
complete -o nospace -F _chromium chromium

멋진 답변입니다. 감사합니다. 당신은 내 시간을 많이 절약했습니다. -f파일 경로 완성을 위해 스위치를 사용 했지만 /디렉토리 인 경우 char을 완료하지 않습니다 ...하지만 작은 것입니다.
Jiri Kremser

1

파일 이름을 완성하려면으로 전달 -f하십시오 compgen.

옵션이 완료된 후에는 공백을 제거 할 수 없을 것입니다. 완료가 작동하는 방식이기 때문입니다. 고유 한 일치 항목을 찾으면 완전히 완료합니다.


의 제안에 감사드립니다 -f. 나는 그것을 시도하지만 제대로 공백으로 취급하지 않습니다 경로 /tmp/foo bar이 개 완료 항목의 결과 /tmp/foobar. 원치 않는 정보 --arg=<SPACE>: 나는 그 해결책을 찾아서 아래 답변에 게시했습니다 .
Rob W
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.