Skip to content

Commit

Permalink
completions: add completions for bash and fish (#629)
Browse files Browse the repository at this point in the history
For later:
- Add completions for zsh and PowerShell.
- Make `fetch-configlet` detect the user's shell and explain how to
  install completions.
- Make `configlet completion -s <shell>` print the corresponding
  completion script to stdout.

This commit also refactors `create-artifact` slightly.

Closes: #615

Co-authored-by: ee7 <45465154+ee7@users.noreply.github.com>
  • Loading branch information
glennj and ee7 authored Aug 4, 2022
1 parent e5423a0 commit 690e9e2
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 5 deletions.
6 changes: 1 addition & 5 deletions .github/bin/create-artifact
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@ case "${OS}" in
artifact_file="${artifacts_dir}/${binary_name}-${OS}-${ARCH}.zip"
7z a "${artifact_file}" "${binary_name}.exe"
;;
linux)
artifact_file="${artifacts_dir}/${binary_name}-${OS}-${ARCH}.tgz"
tar -cvzf "${artifact_file}" "${binary_name}"
;;
mac)
linux | mac)
artifact_file="${artifacts_dir}/${binary_name}-${OS}-${ARCH}.tgz"
tar -cvzf "${artifact_file}" "${binary_name}"
;;
Expand Down
114 changes: 114 additions & 0 deletions completions/configlet.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# completions for the configlet command, bash flavour

# remove any prior completions
complete -r bin/configlet configlet 2>/dev/null
# and install this one
complete -F _configlet_completion_ configlet

# @(pattern1|pattern2|...) is bash extended pattern matching meaning
# "one of pattern1 or pattern2 or ..."
# ref: https://www.gnu.org/software/bash/manual/bash.html#Pattern-Matching

_configlet_completion_() {
local global_opts='-h --help --version -t --track-dir -v --verbosity'
local cur=${COMP_WORDS[COMP_CWORD]}
local prev=${COMP_WORDS[COMP_CWORD - 1]}

# Check for global options that take a value
if _configlet_complete_global_option_; then
return
fi

local i
for ((i = 1; i < COMP_CWORD; i++)); do
if [[ ${COMP_WORDS[i]} == @(lint|generate|info|uuid|fmt|sync) ]]; then
"_configlet_complete_${COMP_WORDS[i]}_"
return
fi
done

_configlet_complete_options_ "fmt generate info lint sync uuid $global_opts"
}

_configlet_complete_global_option_() {
case $prev in
'-v' | '--verbosity')
_configlet_complete_options_ "quiet normal detailed"
return 0
;;
'-t' | '--track-dir')
# Complete a directory based on what the user's typed so far
mapfile -t COMPREPLY < <(compgen -A directory -- "$cur")
return 0
;;
esac
return 1
}

_configlet_complete_lint_() {
_configlet_complete_options_ "$global_opts"
}

_configlet_complete_generate_() {
_configlet_complete_options_ "$global_opts"
}

_configlet_complete_info_() {
_configlet_complete_options_ "-o --offline $global_opts"
}

_configlet_complete_uuid_() {
_configlet_complete_options_ "-n --num $global_opts"
}

_configlet_complete_fmt_() {
case $prev in
'-e' | '--exercise')
_configlet_complete_slugs_ "practice" "concept"
;;
*)
_configlet_complete_options_ "-e --exercise -u --update -y --yes $global_opts"
;;
esac
}

_configlet_complete_sync_() {
case $prev in
'--tests')
_configlet_complete_options_ "choose include exclude"
;;
'-e' | '--exercise')
_configlet_complete_slugs_ "practice"
;;
*)
local options=(
-e --exercise
-o --offline
-u --update
-y --yes
--docs
--filepaths
--metadata
--tests
)
_configlet_complete_options_ "${options[*]} $global_opts"
;;
esac
}

# Note that configlet expects to be called from the track's root dir.
_configlet_complete_slugs_() {
local subdir
mapfile -t COMPREPLY < <(
for subdir in "$@"; do
if [[ -d "./exercises/$subdir" ]]; then
( cd "./exercises/$subdir" && compgen -A directory -- "$cur" )
fi
done
)
}

_configlet_complete_options_() {
local choices=$1
mapfile -t COMPREPLY < <(compgen -o nosort -W "$choices" -- "$cur")
}
36 changes: 36 additions & 0 deletions completions/configlet.fish
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# global options
complete -c configlet -s h -l help -f -d "Show help"
complete -c configlet -l version -f -d "Show version info"
complete -c configlet -s t -l track-dir -d "Select a track directory"
complete -c configlet -s v -l verbosity -x -a "quiet normal detailed" -d "Verbose level"

# subcommands with no options
complete -c configlet -n "__fish_use_subcommand" -a lint -f -d "Check the track configuration for correctness"
complete -c configlet -n "__fish_use_subcommand" -a generate -f -d "Generate concept exercise introductions"

# info subcommand
complete -c configlet -n "__fish_use_subcommand" -a info -f -d "Track info"
complete -c configlet -n "__fish_seen_subcommand_from info" -s o -l offline -f -d "Do not update prob-specs cache"

# uuid subcommand
complete -c configlet -n "__fish_use_subcommand" -a uuid -f -d "Output a UUID"
complete -c configlet -n "__fish_seen_subcommand_from uuid" -s n -l num -f -d "How many UUIDs"

# fmt subcommand
complete -c configlet -n "__fish_use_subcommand" -a fmt -f -d "Format the exercise '.meta/config.json' files"
complete -c configlet -n "__fish_seen_subcommand_from fmt" -s u -l update -d "Write changes"
complete -c configlet -n "__fish_seen_subcommand_from fmt" -s y -l yes -d "Auto-confirm update"
complete -c configlet -n "__fish_seen_subcommand_from fmt" -s e -l exercise -d "exercise slug" \
-x -a "(find ./exercises/{concept,practice} -maxdepth 1 -mindepth 1 -type d -printf '%P\n' | sort)"

# sync subcommand
complete -c configlet -n "__fish_use_subcommand" -a sync -d "Check or update Practice Exercise docs, metadata, and tests"
complete -c configlet -n "__fish_seen_subcommand_from sync" -s o -l offline -f -d "Do not update prob-specs cache"
complete -c configlet -n "__fish_seen_subcommand_from sync" -s u -l update -d "Write changes"
complete -c configlet -n "__fish_seen_subcommand_from sync" -s y -l yes -d "Auto-confirm update"
complete -c configlet -n "__fish_seen_subcommand_from sync" -l docs -d "Sync docs only"
complete -c configlet -n "__fish_seen_subcommand_from sync" -l filepaths -f -d 'Populate .meta/config.json "files" entry'
complete -c configlet -n "__fish_seen_subcommand_from sync" -l metadata -d "Sync metadata only"
complete -c configlet -n "__fish_seen_subcommand_from sync" -l tests -d "For auto-confirming" -x -a "choose include exclude"
complete -c configlet -n "__fish_seen_subcommand_from sync" -s e -l exercise -d "exercise slug" \
-x -a "(find ./exercises/practice -maxdepth 1 -mindepth 1 -type d -printf '%P\n' | sort)"

0 comments on commit 690e9e2

Please sign in to comment.