diff --git a/ChangeLog.completion.bash b/ChangeLog.completion.bash
new file mode 100644
index 0000000..8b1fea9
--- /dev/null
+++ b/ChangeLog.completion.bash
@@ -0,0 +1,3 @@
+2010-08-11 Yves Blusseau
+
+ * util/integration/completion/grub-completion.bash: New script
diff --git a/Makefile.in b/Makefile.in
index 39061be..53b1ecd 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -366,6 +366,10 @@ install-local: all
dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
$(INSTALL_DATA) $$dir$$file $(DESTDIR)$(sysconfdir)/grub.d/$$dest; \
done
+ $(SHELL) $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/bash_completion.d
+ @file="grub-completion.bash"; dest="grub"; \
+ if test -f "$$file"; then dir=; else dir="$(srcdir)/util/integration/completion/"; fi; \
+ $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(sysconfdir)/bash_completion.d/$$dest
$(SHELL) $(mkinstalldirs) $(DESTDIR)$(libdir)/grub
@list='$(lib_SCRIPTS)'; \
for file in $$list; do \
diff --git a/util/integration/completion/grub-completion.bash b/util/integration/completion/grub-completion.bash
new file mode 100644
index 0000000..48d859d
--- /dev/null
+++ b/util/integration/completion/grub-completion.bash
@@ -0,0 +1,450 @@
+#
+# Bash completion for grub
+#
+# Copyright (C) 2010 Free Software Foundation, Inc.
+#
+# GRUB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GRUB. If not, see .
+# bash completion for grub
+
+__grub_dir() {
+ local i c=1 root_dir boot_dir grub_dir
+
+ for (( c=1; c <= address@hidden; c++ )); do
+ i="${COMP_WORDS[c]}"
+ case "$i" in
+ --root-directory)
+ c=$((++c))
+ i="${COMP_WORDS[c]}"
+ root_dir="${i##*=}";
+ break
+ ;;
+ esac
+ done
+ root_dir=${root_dir-/}
+ if [[ -d "$root_dir/boot" ]]; then
+ boot_dir="$root_dir/boot"
+ else
+ boot_dir="$root_dir"
+ fi
+ echo "${boot_dir%/}/grub"
+}
+
+
+# This function generates completion reply with compgen
+# - arg: accepts 1, 2, 3, or 4 arguments
+# $1 wordlist separate by space, tab or newline
+# $2 (optional) prefix to add
+# $3 (optional) current word to complete
+# $4 (optional) suffix to add
+__grubcomp () {
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ if [ $# -gt 2 ]; then
+ cur="$3"
+ fi
+ case "$cur" in
+ --*=)
+ COMPREPLY=()
+ ;;
+ *)
+ local IFS=' '$'\t'$'\n'
+ COMPREPLY=($(compgen -P "${2-}" -W "${1-}" -S "${4-}" -- "$cur"))
+ ;;
+ esac
+}
+
+# Function that return long options from the help
+# - arg: $1 command to get the long options from
+__grub_get_options_from_help () {
+ local i IFS=" "$'\t'$'\n'
+ for i in $($1 --help)
+ do
+ case $i in
+ --*) echo "${i%=*}";;
+ esac
+ done
+}
+
+__grub_get_last_option () {
+ local i
+ for (( i=$COMP_CWORD-1; i > 0; i-- )); do
+ if [[ "${COMP_WORDS[i]}" == -* ]]; then
+ echo "${COMP_WORDS[i]}"
+ break;
+ fi
+ done
+}
+
+__grub_list_menuentries () {
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ local config_file=$(__grub_dir)/grub.cfg
+
+ if [ -f "$config_file" ];then
+ local IFS=$'\n'
+ COMPREPLY=( $(compgen \
+ -W "$( awk -F "[\"']" '/menuentry/ { print $2 }' $config_file )" \
+ -- "$cur" )) #'# Help emacs syntax highlighting
+ fi
+}
+
+__grub_list_modules () {
+ local grub_dir=$(__grub_dir)
+ local IFS=$'\n'
+ COMPREPLY=( $( compgen -f -X '!*/*.mod' -- "${grub_dir}/$cur" | {
+ while read -r tmp; do
+ [ -n $tmp ] && {
+ tmp=${tmp##*/}
+ printf '%s\n' ${tmp%.mod}
+ }
+ done
+ }
+ ))
+}
+
+#
+# grub-set-default & grub-reboot
+#
+_grub_set_entry () {
+ local cur prev split=false
+
+ COMPREPLY=()
+ cur=`_get_cword`
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ _split_longopt && split=true
+
+ case "$prev" in
+ --root-directory)
+ _filedir -d
+ return
+ ;;
+ esac
+
+ $split && return 0
+
+ if [[ "$cur" == -* ]]; then
+ __grubcomp "--help --version --root-directory"
+ else
+ # Default complete with a menuentry
+ __grub_list_menuentries
+ fi
+}
+
+have grub-set-default && \
+ complete -F _grub_set_entry -o filenames grub-set-default
+have grub-reboot && \
+ complete -F _grub_set_entry -o filenames grub-reboot
+
+#
+# grub-editenv
+#
+_grub_editenv () {
+ local cur prev
+
+ COMPREPLY=()
+ cur=`_get_cword`
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ case "$prev" in
+ create|list|set|unset)
+ COMPREPLY=( "" )
+ return
+ ;;
+ esac
+
+ __grubcomp "$(__grub_get_options_from_help 'grub-editenv')
+ create list set unset"
+}
+have grub-editenv && \
+ complete -F _grub_editenv -o filenames grub-editenv
+
+#
+# grub-mkconfig
+#
+_grub_mkconfig () {
+ local cur prev
+
+ COMPREPLY=()
+ cur=`_get_cword`
+
+ if [[ "$cur" == -* ]]; then
+ __grubcomp "$(__grub_get_options_from_help 'grub-mkconfig')"
+ else
+ _filedir
+ fi
+}
+have grub-mkconfig && \
+ complete -F _grub_mkconfig -o filenames grub-mkconfig
+
+#
+# grub-setup
+#
+_grub_setup () {
+ local cur prev split=false
+
+ COMPREPLY=()
+ cur=`_get_cword`
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ _split_longopt && split=true
+
+ case "$prev" in
+ -d|--directory)
+ _filedir -d
+ return
+ ;;
+ esac
+
+ $split && return 0
+
+ if [[ "$cur" == -* ]]; then
+ __grubcomp "$(__grub_get_options_from_help 'grub-setup')"
+ else
+ # Default complete with a filename
+ _filedir
+ fi
+}
+have grub-setup && \
+ complete -F _grub_setup -o filenames grub-setup
+
+#
+# grub-install
+#
+_grub_install () {
+ local cur prev last split=false
+
+ COMPREPLY=()
+ cur=`_get_cword`
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+ last=$(__grub_get_last_option)
+
+ _split_longopt && split=true
+
+ case "$prev" in
+ --root-directory)
+ _filedir -d
+ return
+ ;;
+ --disk-module)
+ __grubcomp "biosdisk ata"
+ return
+ ;;
+ esac
+
+ $split && return 0
+
+ if [[ "$cur" == -* ]]; then
+ __grubcomp "$(__grub_get_options_from_help 'grub-install')"
+ else
+ case "$last" in
+ --modules)
+ __grub_list_modules
+ return
+ ;;
+ esac
+
+ # Default complete with a filename
+ _filedir
+ fi
+}
+have grub-install && \
+ complete -F _grub_install -o filenames grub-install
+
+#
+# grub-mkfont
+#
+_grub_mkfont () {
+ local cur
+
+ COMPREPLY=()
+ cur=`_get_cword`
+
+ if [[ "$cur" == -* ]]; then
+ __grubcomp "$(__grub_get_options_from_help 'grub-mkfont')"
+ else
+ # Default complete with a filename
+ _filedir
+ fi
+}
+have grub-mkfont && \
+ complete -F _grub_mkfont -o filenames grub-mkfont
+
+#
+# grub-mkrescue
+#
+_grub_mkrescue () {
+ local cur prev last
+
+ COMPREPLY=()
+ cur=`_get_cword`
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+ last=$(__grub_get_last_option)
+
+ if [[ "$cur" == -* ]]; then
+ __grubcomp "$(__grub_get_options_from_help 'grub-mkrescue')"
+ else
+ case "$last" in
+ --modules)
+ __grub_list_modules
+ return
+ ;;
+ esac
+
+ # Default complete with a filename
+ _filedir
+ fi
+}
+have grub-mkrescue && \
+ complete -F _grub_mkrescue -o filenames grub-mkrescue
+
+#
+# grub-mkelfimage
+#
+_grub_mkelfimage () {
+ local cur prev split=false
+
+ COMPREPLY=()
+ cur=`_get_cword`
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ _split_longopt && split=true
+
+ case "$prev" in
+ -d|--directory|-p|--prefix)
+ _filedir -d
+ return
+ ;;
+ esac
+
+ $split && return 0
+
+ if [[ "$cur" == -* ]]; then
+ __grubcomp "$(__grub_get_options_from_help 'grub-mkelfimage')"
+ else
+ # Default complete with a filename
+ _filedir
+ fi
+}
+have grub-mkelfimage && \
+ complete -F _grub_mkelfimage -o filenames grub-mkelfimage
+
+#
+# grub-mkimage
+#
+_grub_mkimage () {
+ local cur prev split=false
+
+ COMPREPLY=()
+ cur=`_get_cword`
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ _split_longopt && split=true
+
+ case "$prev" in
+ -d|--directory|-p|--prefix)
+ _filedir -d
+ return
+ ;;
+ esac
+
+ $split && return 0
+
+ if [[ "$cur" == -* ]]; then
+ __grubcomp "$(__grub_get_options_from_help 'grub-mkimage')"
+ else
+ # Default complete with a filename
+ _filedir
+ fi
+}
+have grub-mkimage && \
+ complete -F _grub_mkimage -o filenames grub-mkimage
+
+#
+# grub-mkpasswd-pbkdf2
+#
+_grub_mkpasswd-pbkdf2 () {
+ local cur
+
+ COMPREPLY=()
+ cur=`_get_cword`
+
+ if [[ "$cur" == -* ]]; then
+ __grubcomp "$(__grub_get_options_from_help 'grub-mkpasswd-pbkdf2')"
+ else
+ # Default complete with a filename
+ _filedir
+ fi
+}
+have grub-mkpasswd-pbkdf2 && \
+ complete -F _grub_mkpasswd-pbkdf2 -o filenames grub-mkpasswd-pbkdf2
+
+#
+# grub-probe
+#
+_grub_probe () {
+ local cur prev split=false
+
+ COMPREPLY=()
+ cur=`_get_cword`
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ _split_longopt && split=true
+
+ case "$prev" in
+ -t|--target)
+ # Get target type from help
+ __grubcomp "$(grub-probe --help | \
+ awk -F "[()]" '/--target=/ { print $2 }' | \
+ sed 's/|/ /g')"
+ return
+ ;;
+ esac
+
+ $split && return 0
+
+ if [[ "$cur" == -* ]]; then
+ __grubcomp "$(__grub_get_options_from_help 'grub-probe')"
+ else
+ # Default complete with a filename
+ _filedir
+ fi
+}
+have grub-probe && \
+ complete -F _grub_probe -o filenames grub-probe
+
+#
+# grub-script-check
+#
+_grub_script-check () {
+ local cur
+
+ COMPREPLY=()
+ cur=`_get_cword`
+
+ if [[ "$cur" == -* ]]; then
+ __grubcomp "$(__grub_get_options_from_help 'grub-script-check')"
+ else
+ # Default complete with a filename
+ _filedir
+ fi
+}
+have grub-script-check && \
+ complete -F _grub_script-check -o filenames grub-script-check
+
+# Local variables:
+# mode: shell-script
+# sh-basic-offset: 4
+# sh-indent-comment: t
+# indent-tabs-mode: nil
+# End:
+# ex: ts=4 sw=4 et filetype=sh