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
43 changes: 43 additions & 0 deletions lib/complete
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,53 @@
# Automatic command and argument completion utilities
#
# Exports:
# @go.compgen
# Wrapper around the `compgen` to ensure compatibility with `./go complete`
#
# @go.complete_remove_completions_already_present
# Removes completion values already present in an argument array

# Wrapper around the `compgen` to ensure compatibility with `./go complete`
#
# Use this instead of using `compgen` directly, especially if you are using the
# `-f` or `-d` options to generate file or directory paths.
#
# Arguments:
# ...: Arguments passed directly ot the builtin `compgen`
@go.compgen() {
local add_slashes
local compreply=()
local reply_item
local compgen_exit_index

while IFS= read -r reply_item; do
compreply+=("$reply_item")
done < <(trap 'echo "$?"' EXIT; compgen "$@"; exit "$?")

compgen_exit_index="$((${#compreply[@]} - 1))"

if [[ "${compreply[$compgen_exit_index]}" -ne '0' ]]; then
return "${compreply[$compgen_exit_index]}"
fi
unset "compreply[$compgen_exit_index]"

if [[ "$1" =~ ^-[df]$ ]]; then
add_slashes='true'
fi

for reply_item in "${compreply[@]}"; do
# Since we're not using -o filenames, we must add slashes to dir names.
# Since we're using -o nospace, we must add a space to a single match.
if [[ -n "$add_slashes" && -d "$reply_item" ]]; then
printf -- '%s/\n' "$reply_item"
elif [[ "${#compreply[@]}" -eq '1' && ! $reply_item =~ [\ /]$ ]]; then
printf -- '%s \n' "$reply_item"
else
printf -- '%s\n' "$reply_item"
fi
done
}

# Removes completion values already present in an argument array
#
# NOTE: The word being completed should already be removed from the argument
Expand Down
8 changes: 5 additions & 3 deletions lib/internal/env/bash
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

__go_func() {
unset 'COMP_WORDS[0]'
COMPREPLY=($("$_GO_SCRIPT" 'complete' "$((COMP_CWORD-1))" "${COMP_WORDS[@]}"))
cd "$_GO_ROOTDIR"
local item
while IFS= read -r item; do
COMPREPLY+=("$item")
done < <("$_GO_SCRIPT" 'complete' "$((COMP_CWORD-1))" "${COMP_WORDS[@]}")
}

_go_func() {
Expand All @@ -25,4 +27,4 @@ _go_func() {
esac
}

complete -o filenames -F __go_func _go_func
complete -o nospace -F __go_func _go_func
24 changes: 16 additions & 8 deletions libexec/complete
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
#
# * Notes on implementing argument completion:
#
# - Considering calling `. "$_GO_USE_MODULES" 'complete'` to make use of common
# helper functions.
#
# - If you need to call `compgen -f` or `compgen -d`, you must use `@go.compgen`
# from `lib/complete` or otherwise ensure that directory names end with `/`.
#
# - If you wish to implement custom argument completion in your own command
# scripts, your script must contain a `# Tab completions` comment and respond to
# the `--complete` command line interface described above.
Expand All @@ -38,6 +44,8 @@
# added to the argument completions for `{{go}} <parent>` and do not need to be
# explicitly implemented.

. "$_GO_USE_MODULES" 'complete'

_@go.complete_command() {
local __go_complete_word_index
local __go_cmd_path
Expand Down Expand Up @@ -66,28 +74,28 @@ _@go.complete_args() {
if [[ "$word_index" -eq '0' ]]; then
case "$cmd_name" in
-h)
echo '-h'
printf -- '-h \n'
;;
-he*)
echo '-help'
printf -- '-help \n'
;;
-|--*)
echo '--help'
printf -- '--help \n'
;;
*)
compgen -W "$(_@go.complete_top_level_commands)" -- "$cmd_name"
@go.compgen -W "$(_@go.complete_top_level_commands)" -- "$cmd_name"
;;
esac
return
fi

case "$cmd_name" in
cd|pushd)
compgen -d -- "$word"
@go.compgen -d -- "$word"
return
;;
edit|run)
compgen -f -- "$word"
@go.compgen -f -- "$word"
return
;;
-h|-help|--help)
Expand All @@ -99,12 +107,12 @@ _@go.complete_args() {
esac

if _@go.source_builtin 'aliases' --exists "$cmd_name"; then
compgen -f -- "$word"
@go.compgen -f -- "$word"
return
fi

unset 'args[0]'
compgen -W \
@go.compgen -W \
"$(_@go.complete_command "$word_index" "$cmd_name" "${args[@]}")" -- "$word"
}

Expand Down
3 changes: 2 additions & 1 deletion libexec/fullpath
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ _@go.fullpath_tab_completion() {
if [[ "$word_index" -eq '0' ]]; then
echo '--existing'
fi
compgen -f -- "$word"
. "$_GO_USE_MODULES" 'complete'
@go.compgen -f -- "$word"
}

_@go.fullpath() {
Expand Down
3 changes: 2 additions & 1 deletion libexec/get.d/file
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ _@go.get_file_tab_completions() {
;;
1)
if [[ "$1" == '-f' ]]; then
compgen -f -- "$2"
. "$_GO_USE_MODULES" 'complete'
@go.compgen -f -- "$2"
fi
;;
esac
Expand Down
3 changes: 2 additions & 1 deletion libexec/get.d/git-repo
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ _@go.get_git_repo() {
if [[ "$1" == '--complete' ]]; then
# Tab completions
if [[ "$2" -eq '2' ]]; then
compgen -f -- "$3"
. "$_GO_USE_MODULES" 'complete'
@go.compgen -f -- "$3"
fi
return
fi
Expand Down
3 changes: 2 additions & 1 deletion libexec/glob
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ _@go.glob_tab_completion() {
return
elif [[ -z "$__go_glob_rootdir" ]]; then
echo "${__go_glob_flags[@]}"
compgen -d -- "$__go_glob_complete_word"
. "$_GO_USE_MODULES" 'complete'
@go.compgen -d -- "$__go_glob_complete_word"
return
fi

Expand Down
4 changes: 2 additions & 2 deletions tests/aliases.bats
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ load environment

@test "$SUITE: tab completions" {
run ./go complete 1 aliases ''
assert_success '--exists'
assert_success '--exists '

run ./go complete 1 aliases -
assert_success '--exists'
assert_success '--exists '

run ./go complete 2 aliases --exists
assert_failure ''
Expand Down
4 changes: 2 additions & 2 deletions tests/changes.bats
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ teardown() {
assert_success "${versions[*]}"

run ./go complete 1 changes 'v1.0'
assert_success 'v1.0.0'
assert_success 'v1.0.0 '

run ./go complete 2 changes 'v1.0.0' 'v1.1'
assert_success 'v1.1.0'
assert_success 'v1.1.0 '

run ./go complete 3 changes 'v1.0.0' 'v1.1.0' ''
assert_failure ''
Expand Down
42 changes: 17 additions & 25 deletions tests/commands/main.bats
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ load ../environment
load helpers

setup() {
test_filter
@go.create_test_go_script '@go "$@"'
find_builtins

Expand All @@ -22,25 +23,24 @@ teardown() {
run "$TEST_GO_SCRIPT" complete 1 commands ''
local flags=('--paths' '--summaries')
local expected=("${flags[@]}" "${BUILTIN_CMDS[@]}")
local IFS=$'\n'
assert_success "${expected[*]}"
assert_success "${expected[@]}"

run "$TEST_GO_SCRIPT" complete 1 commands --
local flags=('--paths' '--summaries')
assert_success "${flags[*]}"
assert_success "${flags[@]}"

run "$TEST_GO_SCRIPT" complete 1 commands --p
local flags=('--paths')
assert_success '--paths'
assert_success '--paths '

run "$TEST_GO_SCRIPT" complete 1 commands --foo
assert_failure

run "$TEST_GO_SCRIPT" complete 2 commands --paths
assert_success "${BUILTIN_CMDS[*]}"
assert_success "${BUILTIN_CMDS[@]}"

run "$TEST_GO_SCRIPT" complete 2 commands --summaries
assert_success "${BUILTIN_CMDS[*]}"
assert_success "${BUILTIN_CMDS[@]}"
}

@test "$SUITE: no tab completions for or after search paths" {
Expand All @@ -63,12 +63,11 @@ teardown() {
done

run "$TEST_GO_SCRIPT" complete 2 commands foo
local IFS=$'\n'
assert_success "${expected[*]}"
assert_success "${expected[@]}"

run "$TEST_GO_SCRIPT" complete 2 commands foo b
expected=('bar' 'baz')
assert_success "${expected[*]}"
assert_success "${expected[@]}"

run "$TEST_GO_SCRIPT" complete 2 commands foo g
assert_failure
Expand All @@ -90,8 +89,7 @@ teardown() {

run "$TEST_GO_SCRIPT" complete 1 commands '' foo
expected=('--paths' '--summaries')
local IFS=$'\n'
assert_success "${expected[*]}"
assert_success "${expected[@]}"

run "$TEST_GO_SCRIPT" complete 2 commands foo '' bar
assert_failure
Expand Down Expand Up @@ -148,8 +146,7 @@ teardown() {
@go.create_test_command_script 'plugins/xyzzy.d/child5'

run "$TEST_GO_SCRIPT" commands
local IFS=$'\n'
assert_success "${__all_scripts[*]##*/}"
assert_success "${__all_scripts[@]##*/}"
}

@test "$SUITE: specify plugins and user search paths, omit builtins" {
Expand All @@ -159,12 +156,10 @@ teardown() {

add_scripts "$TEST_GO_SCRIPTS_DIR" "${user_commands[@]}"
add_scripts "$TEST_GO_SCRIPTS_DIR/plugins" "${plugin_commands[@]}"
local IFS=':'
local search_paths=("$TEST_GO_SCRIPTS_DIR/plugins" "$TEST_GO_SCRIPTS_DIR")
local search_paths="$TEST_GO_SCRIPTS_DIR/plugins:$TEST_GO_SCRIPTS_DIR"

run "$TEST_GO_SCRIPT" commands "${search_paths[*]}"
IFS=$'\n'
assert_success "${__all_scripts[*]##*/}"
assert_success "${__all_scripts[@]##*/}"
}

generate_expected_paths() {
Expand Down Expand Up @@ -197,8 +192,7 @@ generate_expected_paths() {
generate_expected_paths

run "$TEST_GO_SCRIPT" commands --paths
local IFS=$'\n'
assert_success "${__expected_paths[*]}"
assert_success "${__expected_paths[@]}"
}

create_script_with_description() {
Expand All @@ -218,12 +212,11 @@ create_script_with_description() {
done

run "$TEST_GO_SCRIPT" commands --summaries "$TEST_GO_SCRIPTS_DIR"
local IFS=$'\n'
local expected=(
' bar Does bar stuff'
' baz Does baz stuff'
' foo Does foo stuff')
assert_success "${expected[*]}"
assert_success "${expected[@]}"
}

@test "$SUITE: subcommand list, paths, and summaries" {
Expand All @@ -244,21 +237,20 @@ create_script_with_description() {
done

run "$TEST_GO_SCRIPT" commands 'foo'
local IFS=$'\n'
assert_success "${subcommands[*]}"
assert_success "${subcommands[@]}"

local expected_paths=(
'plugh scripts/foo.d/plugh'
'quux scripts/foo.d/quux'
'xyzzy scripts/foo.d/xyzzy')

run "$TEST_GO_SCRIPT" commands --paths 'foo'
assert_success "${expected_paths[*]}"
assert_success "${expected_paths[@]}"

local expected_summaries=(
' plugh Does plugh stuff'
' quux Does quux stuff'
' xyzzy Does xyzzy stuff')
run "$TEST_GO_SCRIPT" commands --summaries 'foo'
assert_success "${expected_summaries[*]}"
assert_success "${expected_summaries[@]}"
}
Loading