bash 완성은 옵션이 아닌 첫 번째 단어에서만 작동합니까?

bash 완성은 옵션이 아닌 첫 번째 단어에서만 작동합니까?

foo다른 많은 프로그램과 마찬가지로 다음 형식의 명령줄 인수를 사용하는 프로그램이 있습니다 .

foo[옵션]주문하다...

어디옵션0개 이상의 짧은(예: -s) 또는 긴(예: --long) 스타일 옵션입니다.정확히 하나명령 키워드 뒤에는 명령에 대한 인수가 옵니다.

긴 옵션이나 명령을 완료할 수 있는 Bash 완성 기능을 원합니다. 편리하게도 옵션 목록과 명령 목록을 인쇄하는 옵션 foo도 있습니다 .--options--commands

제안을 제공할 수 있는 기능을 원합니다오직옵션이 아닌 첫 번째 단어(주문하다) 명령줄에서 다음을 제공합니다.아니요입력할 때 이어지는 단어에 대한 제안입니다 tab.

사용 부분이 답변COMP_CWORD, 값이 1 일 때만 사용하고 완료를 수행하려고 했습니다 . 이것은 지금까지 내 완성 기능입니다.

_foo() {
  local cur=${COMP_WORDS[COMP_CWORD]}

  if [[ "$cur" == -* ]]
  then COMPREPLY=($(compgen -W "$(foo --options)" -- $cur))
  else
    if (( COMP_CWORD == 1 ))
    then COMPREPLY=($(compgen -W "$(foo --commands)" -- $cur))
    else COMPREPLY=()
    fi
  fi
}

이것거의일하다. 그러나 사용자가 다음과 같은 경우주문하다좋다:

foo --long tab

그 다음에을 누르면 tab케이스에서 신호음이 울립니다. COMP_CWORD지금은 옵션과 비옵션을 구분하지 않기 때문에 2이기 때문인 것 같습니다 .

-좋아, 그래서 나는 현재 단어 앞의 모든 단어를 스캔하고 다음과 같이 시작하는 단어 수를 빼는 함수를 원합니다 .

_foo() {
  local cur=${COMP_WORDS[COMP_CWORD]}

  if [[ "$cur" == -* ]]
  then
    COMPREPLY=($(compgen -W "$(foo --options)" -- $cur))
  else
    local i=$COMP_CWORD
    while (( i > 1 ))
    do
      [[ "${COMP_WORDS[i-1]}" != -* ]] && break
      ((--i))
    done
    if (( i == 1 ))
    then COMPREPLY=($(compgen -W "$(foo --commands)" -- $cur))
    else COMPREPLY=()
    fi
  fi
}

이것은 작동하지만 문제는 사용자에게 인수를 허용하고 해당 인수를 다음 단어로 제공하는 짧은 옵션이 제공되는 경우입니다. 예를 들면 다음과 같습니다.

foo -s arg tab

그러면 인덱스가 1씩 감소합니다. 완성 함수는 인수를 사용하는지 여부에 관계없이 모든 옵션을 자세히 알아야 하며 올바른 인덱스를 얻기 위해 모든 옵션을 효율적으로 구문 분석해야 합니다.

이것은 많은 일인 것 같습니다. 내 완성 기능이 옵션이 아닌 첫 번째 단어에 대해서만 제안을 제공하도록 하는 더 쉬운 방법이 있습니까? 아니면 그냥 포기하고 항상 조언을 제공합니까?

관련 정보