diff --git a/ChangeLog.completion.bash b/ChangeLog.completion.bash new file mode 100644 index 0000000..e57374a --- /dev/null +++ b/ChangeLog.completion.bash @@ -0,0 +1,6 @@ +Bash completion script for util commands + + * Makefile.am: Add util/bash-completion.d directory + * configure.ac: Likewise. + * util/bash-completion.d/Makefile.am: New file. + * util/bash-completion.d/grub-completion.bash.in: Likewise. diff --git a/Makefile.am b/Makefile.am index 1cf2297..c05d352 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = subdir-objects DEPDIR = .deps-util -SUBDIRS = . grub-core po docs +SUBDIRS = . grub-core po docs util/bash-completion.d include $(top_srcdir)/conf/Makefile.common include $(top_srcdir)/conf/Makefile.extra-dist diff --git a/configure.ac b/configure.ac index b167408..fa96af7 100644 --- a/configure.ac +++ b/configure.ac @@ -933,6 +933,7 @@ AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([grub-core/Makefile]) AC_CONFIG_FILES([po/Makefile]) AC_CONFIG_FILES([docs/Makefile]) +AC_CONFIG_FILES([util/bash-completion.d/Makefile]) AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h]) AC_OUTPUT diff --git a/util/bash-completion.d/Makefile.am b/util/bash-completion.d/Makefile.am new file mode 100644 index 0000000..774e1a3 --- /dev/null +++ b/util/bash-completion.d/Makefile.am @@ -0,0 +1,15 @@ + +bash_completion_source = grub-completion.bash.in +bash_completion_script = $(grubname) + +EXTRA_DIST = $(bash_completion_source) + +CLEANFILES = $(bash_completion_script) + +DISTCLEANFILES = *~ + +bashcompletiondir = $(sysconfdir)/bash_completion.d +bashcompletion_DATA = $(bash_completion_script) + +$(bash_completion_script): $(bash_completion_source) $(top_builddir)/config.status + $(top_builddir)/config.status --file=$@:$< diff --git a/util/bash-completion.d/grub-completion.bash.in b/util/bash-completion.d/grub-completion.bash.in new file mode 100644 index 0000000..4d9a96f --- /dev/null +++ b/util/bash-completion.d/grub-completion.bash.in @@ -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 + address@hidden@_dir() { + local i c=1 root_dir boot_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 address@hidden@comp () { + 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 address@hidden@_get_options_from_help () { + local i IFS=" "$'\t'$'\n' + for i in $($1 --help) + do + case $i in + --*) echo "${i%=*}";; + esac + done +} + address@hidden@_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 +} + address@hidden@_list_menuentries () { + local cur="${COMP_WORDS[COMP_CWORD]}" + local config_file=$(address@hidden@_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 +} + address@hidden@_list_modules () { + local grub_dir=$(address@hidden@_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 + } + )) +} + +# +# @address@hidden & @address@hidden +# address@hidden@_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 + address@hidden@comp "--help --version --root-directory" + else + # Default complete with a menuentry + address@hidden@_list_menuentries + fi +} + +have @address@hidden && \ + complete -F address@hidden@_set_entry -o filenames @address@hidden +have @address@hidden && \ + complete -F address@hidden@_set_entry -o filenames @address@hidden + +# +# @address@hidden +# address@hidden@_editenv () { + local cur prev + + COMPREPLY=() + cur=`_get_cword` + prev=${COMP_WORDS[COMP_CWORD-1]} + + case "$prev" in + create|list|set|unset) + COMPREPLY=( "" ) + return + ;; + esac + + address@hidden@comp "$(address@hidden@_get_options_from_help '@address@hidden') + create list set unset" +} +have @address@hidden && \ + complete -F address@hidden@_editenv -o filenames @address@hidden + +# +# @address@hidden +# address@hidden@_mkconfig () { + local cur prev + + COMPREPLY=() + cur=`_get_cword` + + if [[ "$cur" == -* ]]; then + address@hidden@comp "$(address@hidden@_get_options_from_help '@address@hidden')" + else + _filedir + fi +} +have @address@hidden && \ + complete -F address@hidden@_mkconfig -o filenames @address@hidden + +# +# @address@hidden +# address@hidden@_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 + address@hidden@comp "$(address@hidden@_get_options_from_help '@address@hidden')" + else + # Default complete with a filename + _filedir + fi +} +have @address@hidden && \ + complete -F address@hidden@_setup -o filenames @address@hidden + +# +# @address@hidden +# address@hidden@_install () { + local cur prev last split=false + + COMPREPLY=() + cur=`_get_cword` + prev=${COMP_WORDS[COMP_CWORD-1]} + last=$(address@hidden@_get_last_option) + + _split_longopt && split=true + + case "$prev" in + --root-directory) + _filedir -d + return + ;; + --disk-module) + address@hidden@comp "biosdisk ata" + return + ;; + esac + + $split && return 0 + + if [[ "$cur" == -* ]]; then + address@hidden@comp "$(address@hidden@_get_options_from_help '@address@hidden')" + else + case "$last" in + --modules) + address@hidden@_list_modules + return + ;; + esac + + # Default complete with a filename + _filedir + fi +} +have @address@hidden && \ + complete -F address@hidden@_install -o filenames @address@hidden + +# +# @address@hidden +# address@hidden@_mkfont () { + local cur + + COMPREPLY=() + cur=`_get_cword` + + if [[ "$cur" == -* ]]; then + address@hidden@comp "$(address@hidden@_get_options_from_help '@address@hidden')" + else + # Default complete with a filename + _filedir + fi +} +have @address@hidden && \ + complete -F address@hidden@_mkfont -o filenames @address@hidden + +# +# @address@hidden +# address@hidden@_mkrescue () { + local cur prev last + + COMPREPLY=() + cur=`_get_cword` + prev=${COMP_WORDS[COMP_CWORD-1]} + last=$(address@hidden@_get_last_option) + + if [[ "$cur" == -* ]]; then + address@hidden@comp "$(address@hidden@_get_options_from_help '@address@hidden')" + else + case "$last" in + --modules) + address@hidden@_list_modules + return + ;; + esac + + # Default complete with a filename + _filedir + fi +} +have @address@hidden && \ + complete -F address@hidden@_mkrescue -o filenames @address@hidden + +# +# @address@hidden +# address@hidden@_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 + address@hidden@comp "$(address@hidden@_get_options_from_help '@address@hidden')" + else + # Default complete with a filename + _filedir + fi +} +have @address@hidden && \ + complete -F address@hidden@_mkelfimage -o filenames @address@hidden + +# +# @address@hidden +# address@hidden@_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 + address@hidden@comp "$(address@hidden@_get_options_from_help '@address@hidden')" + else + # Default complete with a filename + _filedir + fi +} +have @address@hidden && \ + complete -F address@hidden@_mkimage -o filenames @address@hidden + +# +# @address@hidden +# address@hidden@_mkpasswd-pbkdf2 () { + local cur + + COMPREPLY=() + cur=`_get_cword` + + if [[ "$cur" == -* ]]; then + address@hidden@comp "$(address@hidden@_get_options_from_help '@address@hidden')" + else + # Default complete with a filename + _filedir + fi +} +have @address@hidden && \ + complete -F address@hidden@_mkpasswd-pbkdf2 -o filenames @address@hidden + +# +# @address@hidden +# address@hidden@_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 + address@hidden@comp "$(@address@hidden --help | \ + awk -F "[()]" '/--target=/ { print $2 }' | \ + sed 's/|/ /g')" + return + ;; + esac + + $split && return 0 + + if [[ "$cur" == -* ]]; then + address@hidden@comp "$(address@hidden@_get_options_from_help '@address@hidden')" + else + # Default complete with a filename + _filedir + fi +} +have @address@hidden && \ + complete -F address@hidden@_probe -o filenames @address@hidden + +# +# @address@hidden +# address@hidden@_script-check () { + local cur + + COMPREPLY=() + cur=`_get_cword` + + if [[ "$cur" == -* ]]; then + address@hidden@comp "$(address@hidden@_get_options_from_help '@address@hidden')" + else + # Default complete with a filename + _filedir + fi +} +have @address@hidden && \ + complete -F address@hidden@_script-check -o filenames @address@hidden + +# 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