completion: add alias handling
Bash completion is now smarter about handling aliases. In particular, if all completions for some input command are aliased to the same thing, we'll just complete with that thing. If you've already *typed* the full alias for a command, we'll complete the alias. So, for example, here there's more than one real command involved, so all aliases are shown: ```console $ spack con concretise concretize config containerise containerize ``` Here, there are two possibilities: `concretise` and `concretize`, but both map to `concretize` so we just complete that: ```console $ spack conc concretize ``` And here, the user has already typed `concretis`, so we just go with it as there is only one option: ```console spack concretis concretise ```
This commit is contained in:
parent
a3ecd7efed
commit
396f219011
@ -812,6 +812,9 @@ def bash(args: Namespace, out: IO) -> None:
|
||||
parser = spack.main.make_argument_parser()
|
||||
spack.main.add_all_commands(parser)
|
||||
|
||||
aliases = ";".join(f"{key}:{val}" for key, val in spack.main.aliases.items())
|
||||
out.write(f'SPACK_ALIASES="{aliases}"\n\n')
|
||||
|
||||
writer = BashCompletionWriter(parser.prog, out, args.aliases)
|
||||
writer.write(parser)
|
||||
|
||||
|
@ -139,6 +139,9 @@ _bash_completion_spack() {
|
||||
$subfunction
|
||||
COMPREPLY=($(compgen -W "$SPACK_COMPREPLY" -- "$cur"))
|
||||
fi
|
||||
|
||||
# if every completion is an alias for the same thing, just return that thing.
|
||||
_spack_compress_aliases
|
||||
}
|
||||
|
||||
# Helper functions for subcommands
|
||||
@ -328,6 +331,49 @@ _spacktivate() {
|
||||
_spack_env_activate
|
||||
}
|
||||
|
||||
# Simple function to get the spack alias for a command
|
||||
_spack_get_alias() {
|
||||
local possible_alias="${1-}"
|
||||
local IFS=";"
|
||||
|
||||
# spack aliases are a ;-separated list of :-separated pairs
|
||||
for item in $SPACK_ALIASES; do
|
||||
# maps a possible alias to its command
|
||||
eval "local real_command=\"\${item#*${possible_alias}:}\""
|
||||
if [ "$real_command" != "$item" ]; then
|
||||
SPACK_ALIAS="$real_command"
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
# no alias found -- just return $1
|
||||
SPACK_ALIAS="$possible_alias"
|
||||
}
|
||||
|
||||
# If all commands in COMPREPLY alias to the same thing, set COMPREPLY to
|
||||
# just the real command, not the aliases.
|
||||
_spack_compress_aliases() {
|
||||
# if there's only one thing, don't bother compressing aliases; complete the alias
|
||||
if [ "${#COMPREPLY[@]}" == "1" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# get the alias of the first thing in the list of completions
|
||||
_spack_get_alias "${COMPREPLY[0]}"
|
||||
local first_alias="$SPACK_ALIAS"
|
||||
|
||||
# if anything in the list would alias to something different, stop
|
||||
for comp in "${COMPREPLY[@]:1}"; do
|
||||
_spack_get_alias "$comp"
|
||||
if [ "$SPACK_ALIAS" != "$first_alias" ]; then
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
# all commands alias to first alias; just return that
|
||||
COMPREPLY=("$first_alias")
|
||||
}
|
||||
|
||||
# Spack commands
|
||||
#
|
||||
# Everything below here is auto-generated.
|
||||
|
@ -61,6 +61,12 @@ contains 'python' _spack_completions spack extensions ''
|
||||
contains 'hdf5' _spack_completions spack -d install --jobs 8 ''
|
||||
contains 'hdf5' _spack_completions spack install -v ''
|
||||
|
||||
title 'Testing alias handling'
|
||||
contains 'concretize' _spack_completions spack c
|
||||
contains 'concretise' _spack_completions spack c
|
||||
contains 'concretize' _spack_completions spack conc
|
||||
does_not_contain 'concretise' _spack_completions spack conc
|
||||
|
||||
# XFAIL: Fails for Python 2.6 because pkg_resources not found?
|
||||
#contains 'compilers.py' _spack_completions spack unit-test ''
|
||||
|
||||
|
@ -139,6 +139,9 @@ _bash_completion_spack() {
|
||||
$subfunction
|
||||
COMPREPLY=($(compgen -W "$SPACK_COMPREPLY" -- "$cur"))
|
||||
fi
|
||||
|
||||
# if every completion is an alias for the same thing, just return that thing.
|
||||
_spack_compress_aliases
|
||||
}
|
||||
|
||||
# Helper functions for subcommands
|
||||
@ -328,9 +331,54 @@ _spacktivate() {
|
||||
_spack_env_activate
|
||||
}
|
||||
|
||||
# Simple function to get the spack alias for a command
|
||||
_spack_get_alias() {
|
||||
local possible_alias="${1-}"
|
||||
local IFS=";"
|
||||
|
||||
# spack aliases are a ;-separated list of :-separated pairs
|
||||
for item in $SPACK_ALIASES; do
|
||||
# maps a possible alias to its command
|
||||
eval "local real_command=\"\${item#*${possible_alias}:}\""
|
||||
if [ "$real_command" != "$item" ]; then
|
||||
SPACK_ALIAS="$real_command"
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
# no alias found -- just return $1
|
||||
SPACK_ALIAS="$possible_alias"
|
||||
}
|
||||
|
||||
# If all commands in COMPREPLY alias to the same thing, set COMPREPLY to
|
||||
# just the real command, not the aliases.
|
||||
_spack_compress_aliases() {
|
||||
# if there's only one thing, don't bother compressing aliases; complete the alias
|
||||
if [ "${#COMPREPLY[@]}" == "1" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# get the alias of the first thing in the list of completions
|
||||
_spack_get_alias "${COMPREPLY[0]}"
|
||||
local first_alias="$SPACK_ALIAS"
|
||||
|
||||
# if anything in the list would alias to something different, stop
|
||||
for comp in "${COMPREPLY[@]:1}"; do
|
||||
_spack_get_alias "$comp"
|
||||
if [ "$SPACK_ALIAS" != "$first_alias" ]; then
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
# all commands alias to first alias; just return that
|
||||
COMPREPLY=("$first_alias")
|
||||
}
|
||||
|
||||
# Spack commands
|
||||
#
|
||||
# Everything below here is auto-generated.
|
||||
SPACK_ALIASES="concretise:concretize;containerise:containerize;rm:remove"
|
||||
|
||||
|
||||
_spack() {
|
||||
if $list_options
|
||||
|
Loading…
Reference in New Issue
Block a user