Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion lib/completely/pattern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,16 @@ def compgen
def compgen!
result = []
result << actions.join(' ').to_s if actions.any?
result << %[-W "$(#{function_name} "#{words.join ' '}")"] if words.any?
result << %[-W "$(#{function_name} #{quoted_words.join ' '})"] if words.any?
result.any? ? result.join(' ') : nil
end

def quoted_words
@quoted_words ||= words.map { |word| %("#{escape_for_double_quotes word}") }
end

def escape_for_double_quotes(word)
word.gsub(/["\\]/, '\\\\\&')
end
end
end
31 changes: 15 additions & 16 deletions lib/completely/templates/template.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,37 @@
# Modifying it manually is not recommended

<%= function_name %>_filter() {
local words="$1"
local words=("$@")
local cur=${COMP_WORDS[COMP_CWORD]}
local result=()
local want_options=0

# words the user already typed (excluding the command itself)
local used=()
if ((COMP_CWORD > 1)); then
used=("${COMP_WORDS[@]:1:$((COMP_CWORD - 1))}")
fi

if [[ "${cur:0:1}" == "-" ]]; then
# Completing an option: offer everything (including options)
echo "$words"

else
# Completing a non-option: offer only non-options,
# and don't re-offer ones already used earlier in the line.
for word in $words; do
# Completing an option: offer everything.
# Completing a non-option: drop options and already-used words.
[[ "${cur:0:1}" == "-" ]] && want_options=1
for word in "${words[@]}"; do
if ((!want_options)); then
[[ "${word:0:1}" == "-" ]] && continue

local seen=0
for u in "${used[@]}"; do
if [[ "$u" == "$word" ]]; then
seen=1
break
continue 2
fi
done
((!seen)) && result+=("$word")
done
fi

echo "${result[*]}"
fi
# compgen -W expects shell-escaped words in one space-delimited string.
printf -v word '%q' "$word"
result+=("$word")
done

echo "${result[*]}"
}

<%= function_name %>() {
Expand Down
35 changes: 17 additions & 18 deletions spec/approvals/cli/generated-script
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,37 @@
# Modifying it manually is not recommended

_mygit_completions_filter() {
local words="$1"
local words=("$@")
local cur=${COMP_WORDS[COMP_CWORD]}
local result=()
local want_options=0

# words the user already typed (excluding the command itself)
local used=()
if ((COMP_CWORD > 1)); then
used=("${COMP_WORDS[@]:1:$((COMP_CWORD - 1))}")
fi

if [[ "${cur:0:1}" == "-" ]]; then
# Completing an option: offer everything (including options)
echo "$words"

else
# Completing a non-option: offer only non-options,
# and don't re-offer ones already used earlier in the line.
for word in $words; do
# Completing an option: offer everything.
# Completing a non-option: drop options and already-used words.
[[ "${cur:0:1}" == "-" ]] && want_options=1
for word in "${words[@]}"; do
if ((!want_options)); then
[[ "${word:0:1}" == "-" ]] && continue

local seen=0
for u in "${used[@]}"; do
if [[ "$u" == "$word" ]]; then
seen=1
break
continue 2
fi
done
((!seen)) && result+=("$word")
done
fi

echo "${result[*]}"
fi
# compgen -W expects shell-escaped words in one space-delimited string.
printf -v word '%q' "$word"
result+=("$word")
done

echo "${result[*]}"
}

_mygit_completions() {
Expand All @@ -59,15 +58,15 @@ _mygit_completions() {
;;

'status'*)
while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mygit_completions_filter "--help --verbose --branch -b")" -- "$cur")
while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mygit_completions_filter "--help" "--verbose" "--branch" "-b")" -- "$cur")
;;

'init'*)
while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -A directory -W "$(_mygit_completions_filter "--bare")" -- "$cur")
;;

*)
while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mygit_completions_filter "-h -v --help --version init status")" -- "$cur")
while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mygit_completions_filter "-h" "-v" "--help" "--version" "init" "status")" -- "$cur")
;;

esac
Expand Down
35 changes: 17 additions & 18 deletions spec/approvals/cli/generated-script-alt
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,37 @@
# Modifying it manually is not recommended

_mycomps_filter() {
local words="$1"
local words=("$@")
local cur=${COMP_WORDS[COMP_CWORD]}
local result=()
local want_options=0

# words the user already typed (excluding the command itself)
local used=()
if ((COMP_CWORD > 1)); then
used=("${COMP_WORDS[@]:1:$((COMP_CWORD - 1))}")
fi

if [[ "${cur:0:1}" == "-" ]]; then
# Completing an option: offer everything (including options)
echo "$words"

else
# Completing a non-option: offer only non-options,
# and don't re-offer ones already used earlier in the line.
for word in $words; do
# Completing an option: offer everything.
# Completing a non-option: drop options and already-used words.
[[ "${cur:0:1}" == "-" ]] && want_options=1
for word in "${words[@]}"; do
if ((!want_options)); then
[[ "${word:0:1}" == "-" ]] && continue

local seen=0
for u in "${used[@]}"; do
if [[ "$u" == "$word" ]]; then
seen=1
break
continue 2
fi
done
((!seen)) && result+=("$word")
done
fi

echo "${result[*]}"
fi
# compgen -W expects shell-escaped words in one space-delimited string.
printf -v word '%q' "$word"
result+=("$word")
done

echo "${result[*]}"
}

_mycomps() {
Expand All @@ -59,15 +58,15 @@ _mycomps() {
;;

'status'*)
while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mycomps_filter "--help --verbose --branch -b")" -- "$cur")
while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mycomps_filter "--help" "--verbose" "--branch" "-b")" -- "$cur")
;;

'init'*)
while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -A directory -W "$(_mycomps_filter "--bare")" -- "$cur")
;;

*)
while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mycomps_filter "-h -v --help --version init status")" -- "$cur")
while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mycomps_filter "-h" "-v" "--help" "--version" "init" "status")" -- "$cur")
;;

esac
Expand Down
35 changes: 17 additions & 18 deletions spec/approvals/cli/generated-wrapped-script
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,37 @@ give_comps() {
echo $'# Modifying it manually is not recommended'
echo $''
echo $'_mygit_completions_filter() {'
echo $' local words="$1"'
echo $' local words=("$@")'
echo $' local cur=${COMP_WORDS[COMP_CWORD]}'
echo $' local result=()'
echo $' local want_options=0'
echo $''
echo $' # words the user already typed (excluding the command itself)'
echo $' local used=()'
echo $' if ((COMP_CWORD > 1)); then'
echo $' used=("${COMP_WORDS[@]:1:$((COMP_CWORD - 1))}")'
echo $' fi'
echo $''
echo $' if [[ "${cur:0:1}" == "-" ]]; then'
echo $' # Completing an option: offer everything (including options)'
echo $' echo "$words"'
echo $''
echo $' else'
echo $' # Completing a non-option: offer only non-options,'
echo $' # and don\'t re-offer ones already used earlier in the line.'
echo $' for word in $words; do'
echo $' # Completing an option: offer everything.'
echo $' # Completing a non-option: drop options and already-used words.'
echo $' [[ "${cur:0:1}" == "-" ]] && want_options=1'
echo $' for word in "${words[@]}"; do'
echo $' if ((!want_options)); then'
echo $' [[ "${word:0:1}" == "-" ]] && continue'
echo $''
echo $' local seen=0'
echo $' for u in "${used[@]}"; do'
echo $' if [[ "$u" == "$word" ]]; then'
echo $' seen=1'
echo $' break'
echo $' continue 2'
echo $' fi'
echo $' done'
echo $' ((!seen)) && result+=("$word")'
echo $' done'
echo $' fi'
echo $''
echo $' echo "${result[*]}"'
echo $' fi'
echo $' # compgen -W expects shell-escaped words in one space-delimited string.'
echo $' printf -v word \'%q\' "$word"'
echo $' result+=("$word")'
echo $' done'
echo $''
echo $' echo "${result[*]}"'
echo $'}'
echo $''
echo $'_mygit_completions() {'
Expand All @@ -60,15 +59,15 @@ give_comps() {
echo $' ;;'
echo $''
echo $' \'status\'*)'
echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mygit_completions_filter "--help --verbose --branch -b")" -- "$cur")'
echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mygit_completions_filter "--help" "--verbose" "--branch" "-b")" -- "$cur")'
echo $' ;;'
echo $''
echo $' \'init\'*)'
echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -A directory -W "$(_mygit_completions_filter "--bare")" -- "$cur")'
echo $' ;;'
echo $''
echo $' *)'
echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mygit_completions_filter "-h -v --help --version init status")" -- "$cur")'
echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mygit_completions_filter "-h" "-v" "--help" "--version" "init" "status")" -- "$cur")'
echo $' ;;'
echo $''
echo $' esac'
Expand Down
35 changes: 17 additions & 18 deletions spec/approvals/cli/test/completely-tester-1.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,37 @@ fi
# Modifying it manually is not recommended

_mygit_completions_filter() {
local words="$1"
local words=("$@")
local cur=${COMP_WORDS[COMP_CWORD]}
local result=()
local want_options=0

# words the user already typed (excluding the command itself)
local used=()
if ((COMP_CWORD > 1)); then
used=("${COMP_WORDS[@]:1:$((COMP_CWORD - 1))}")
fi

if [[ "${cur:0:1}" == "-" ]]; then
# Completing an option: offer everything (including options)
echo "$words"

else
# Completing a non-option: offer only non-options,
# and don't re-offer ones already used earlier in the line.
for word in $words; do
# Completing an option: offer everything.
# Completing a non-option: drop options and already-used words.
[[ "${cur:0:1}" == "-" ]] && want_options=1
for word in "${words[@]}"; do
if ((!want_options)); then
[[ "${word:0:1}" == "-" ]] && continue

local seen=0
for u in "${used[@]}"; do
if [[ "$u" == "$word" ]]; then
seen=1
break
continue 2
fi
done
((!seen)) && result+=("$word")
done
fi

echo "${result[*]}"
fi
# compgen -W expects shell-escaped words in one space-delimited string.
printf -v word '%q' "$word"
result+=("$word")
done

echo "${result[*]}"
}

_mygit_completions() {
Expand All @@ -67,15 +66,15 @@ _mygit_completions() {
;;

'status'*)
while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mygit_completions_filter "--help --verbose --branch -b")" -- "$cur")
while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mygit_completions_filter "--help" "--verbose" "--branch" "-b")" -- "$cur")
;;

'init'*)
while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -A directory -W "$(_mygit_completions_filter "--bare")" -- "$cur")
;;

*)
while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mygit_completions_filter "-h -v --help --version init status")" -- "$cur")
while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_mygit_completions_filter "-h" "-v" "--help" "--version" "init" "status")" -- "$cur")
;;

esac
Expand Down
Loading