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씩 감소합니다. 완성 함수는 인수를 사용하는지 여부에 관계없이 모든 옵션을 자세히 알아야 하며 올바른 인덱스를 얻기 위해 모든 옵션을 효율적으로 구문 분석해야 합니다.
이것은 많은 일인 것 같습니다. 내 완성 기능이 옵션이 아닌 첫 번째 단어에 대해서만 제안을 제공하도록 하는 더 쉬운 방법이 있습니까? 아니면 그냥 포기하고 항상 조언을 제공합니까?