2011-02-18 5 views
1

명령 줄 플래그와 적절한 플래그 값을 제안하는 배시 완료 루틴을 생성하려고합니다. 예를 들어 아래 fstcompose 명령의 경우, 먼저 경쟁 루틴에 compose_filter = 플래그를 제안한 다음 [alt_sequence, auto, match, sequence]에서 가능한 값을 제안하십시오. 나는 경쟁이 경로 나 파일이 제안의 기본 모드로 후퇴 할 값의 관련된 세트가없는 모든 플래그를 들어등호 부호와 열거 형 플래그 값을 가진 Bash 완료

fstcompose --compose_filter= 

.

제가 직면 한 한 가지 문제는 = 등호가 개별 토큰으로 취급되며 이전 COMP_WORD로 설정됩니다. 이전 = 문자를 포함하기 전에 전체 플래그를 탐지하는 기술이 있습니까? 또는이 유형의 플래그를 열거 형 값으로 구현하는 더 좋은 방법이 있습니까? 아래는 내가 작업하고있는 완료 루틴의 샘플이다.

_fstcompose() 
{ 
    local cur prev opts filters pprev 
    COMPREPLY=() 
    cur="${COMP_WORDS[COMP_CWORD]}" 
    prev="${COMP_WORDS[COMP_CWORD-1]}" 
    opts="--compose_filter= --connect" 
    filters="alt_sequence auto match sequence" 

    if [[ ${cur} == -* ]] ; then 
    COMPREPLY=($(compgen -W "${opts}" -- ${cur})) 
    return 0 
    fi 

    if [[ ${prev} == "--compose_filter=" ]] ; then 
    COMPREPLY=($(compgen -W "${filters}" -- ${cur})) 
    return 0 
    fi 
    _filedir 
} 
complete -o nospace -F _fstcompose fstcompose 

답변

2

return 0 평가되는 제 if 않도록 제. 가장 구체적인 것으로부터 최소로 특정 된 순서로 case 문을 사용하거나 적어도 if 문을 순서대로 주문하십시오.

"="은 $COMP_WORDBREAKS에 포함되어 있으므로 ${prev}은 "--compose_filter"이며 "="는 붙지 않습니다.

"="을 $COMP_WORDBREAKS에서 제거하면 --compose_filter${prev}이 아닌 여전히 ${cur}입니다. 가치를 보존하고 복원하지 않고 그렇게하면 다른 완료를 깨뜨릴 수 있습니다.

다른 문제가 있을지 잘 모르겠습니다.

echo 문을 디버깅을 돕기 위해 다른 터미널로 리디렉션 할 수 있습니다. 예 :

echo "cur: $cur, prev: $prev" > /dev/pts/2 
+0

= COMP_WORDBREAKS에서 제거 = 전혀 작동하지 않습니다. – bioinfornatics

0

이것은 내가 생각하는 사람들에게 도움이 될 것입니다. 작동해야 아래 코드

have fstcompose &&{ 
    function elementExists(){ 
     local i isRunning result 
     i=0 
     isRunning=1 
     result=0 
     #~ for i in ${opts_with_equal[@]}; do 
     while [ "$isRunning" -eq 1 ]; do 
      if [ "$i" -ge "${#opts_with_equal[@]}" ]; then 
       isRunning=0 
      elif [ "${opts_with_equal[$i]}" == "$1" ]; then 
       result=1 
       isRunning=0 
      fi 
      ((i++)) 
     done 
     echo $result 
    } 
    function _fstcompose(){ 
     local prev cur opts opts_with_equal isEqualOptions 
     COMPREPLY=() 
     _get_comp_words_by_ref -n : cur prev 
     opts="--compose_filter --connect" 
     opts_with_equal=(--compose_filter) 

     case ${cur} in 
      '--compose_filter'*) 
       prev="${cur%%=*}=" 
       cur=${cur#*=} 
       COMPREPLY=(${prev}$(compgen -W "alt_sequence auto match sequence" -- "${cur}")) 
       return 0 
       ;; 
     esac 

     if [[ "${cur}" != -* ]]; then 
      _filedir 
     else 
      isEqualOptions=$(elementExists "${cur}") 
      if [ "${isEqualOptions:-0}" -eq 1 ]; then 
       COMPREPLY=($(compgen -W "${opts}" -S '=' -- "${cur}")) 
      else 
       COMPREPLY=($(compgen -W "${opts}" -- "${cur}")) 
      fi 
     fi 

    } 
    complete -o nospace -F _fstcompose fstcompose 
} 
# Local variables: 
# mode: shell-script 
# sh-basic-offset: 4 
# sh-indent-comment: t 
# indent-tabs-mode: nil 
# End: 
# ex: ts=4 sw=4 et filetype=sh 

주 (즉석에서 작성) :이 예에서 배열 인 opts_with_equal 단지 하나의 파라미터를 포함한다. '='를 사용하는 각 매개 변수에 넣기