summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2023-08-18 16:53:00 -0700
committerTodd Gamblin <tgamblin@llnl.gov>2023-08-30 12:42:31 -0700
commit396f21901160afd54adf21970f22f92c38006bef (patch)
treefe9c9cfdc8fd2b7d9c5c46e140d4c1936c47c5d8
parenta3ecd7efed6d667cec3ac861e854a92d759b4390 (diff)
downloadspack-396f21901160afd54adf21970f22f92c38006bef.tar.gz
spack-396f21901160afd54adf21970f22f92c38006bef.tar.bz2
spack-396f21901160afd54adf21970f22f92c38006bef.tar.xz
spack-396f21901160afd54adf21970f22f92c38006bef.zip
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 ```
-rw-r--r--lib/spack/spack/cmd/commands.py3
-rwxr-xr-xshare/spack/bash/spack-completion.bash46
-rwxr-xr-xshare/spack/qa/completion-test.sh6
-rwxr-xr-xshare/spack/spack-completion.bash48
4 files changed, 103 insertions, 0 deletions
diff --git a/lib/spack/spack/cmd/commands.py b/lib/spack/spack/cmd/commands.py
index 61be25f036..9ebaa62239 100644
--- a/lib/spack/spack/cmd/commands.py
+++ b/lib/spack/spack/cmd/commands.py
@@ -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)
diff --git a/share/spack/bash/spack-completion.bash b/share/spack/bash/spack-completion.bash
index 0d740101fa..c0ead13813 100755
--- a/share/spack/bash/spack-completion.bash
+++ b/share/spack/bash/spack-completion.bash
@@ -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.
diff --git a/share/spack/qa/completion-test.sh b/share/spack/qa/completion-test.sh
index 9559c56d0a..494a1b1235 100755
--- a/share/spack/qa/completion-test.sh
+++ b/share/spack/qa/completion-test.sh
@@ -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 ''
diff --git a/share/spack/spack-completion.bash b/share/spack/spack-completion.bash
index 22365df54a..91e34045b4 100755
--- a/share/spack/spack-completion.bash
+++ b/share/spack/spack-completion.bash
@@ -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