# Completion for eselect [] [] # Author: Wilke Schwiedop # Distributed under the terms of the GNU General Public License v2 _eselect() { local curr=${COMP_WORDS[COMP_CWORD]} possibles module_index=1 # Unset default completion COMPREPLY=() # Unfortunatly we can't source eselect to get to the variables directly, so this is a bit more complicated local ESELECT_DATA_PATH ESELECT_MODULES_PATH # Obtain ESELECT_DATA_PATH and ESELECT_MODULES_PATH . See eselect for more info ESELECT_DATA_PATH=$(sed -n -e 's/^ESELECT_DATA_PATH="\(.\+\)"$/\1/p' $(which eselect)) ESELECT_MODULES_PATH=( "${HOME}/.eselect/modules" "${ESELECT_DATA_PATH}/modules" ) # Hard-coded Actions. # Note: list-modules is hardcoded aswell, but not used in the modules. list-modules is added only when needed. ESELECT_KNOWN_ACTIONS="help usage version" # Hard-coded Options # TODO These could be read from ESELECT_KNOWN_OPTIONS ESELECT_KNOWN_OPTIONS="--no-colour" # Skip all global-options while [[ ${COMP_WORDS[module_index]} == -* ]] ; do ((++module_index)) done # If any word in ${COMP_WORDS[@]} is a default-action, we don't need further completion for i in ${COMP_WORDS[@]} ; do [[ $i == @(${ESELECT_KNOWN_ACTIONS//[[:space:]]/"|"}) ]] && return 0 done # If this is true we're looking for a module name or an eselect-option. In short: "eselect " if [[ $((COMP_CWORD-module_index)) -eq 0 ]] ; then local path file for path in "${ESELECT_MODULES_PATH[@]}" ; do [[ -d ${path} ]] || continue for file in ${path}/*.eselect ; do [[ -f ${file} ]] || continue file=${file##*/} # strip path file=${file%%.eselect} # strip extension possibles+=" ${file}" done done possibles+=" list-modules ${ESELECT_KNOWN_ACTIONS}" # Include default actions and list-modules possibles+=" ${ESELECT_KNOWN_OPTIONS}" # Include default options # We already have a module, so we're looking for an action or even and option # In short: "eselect somemodule " else local modname=${COMP_WORDS[module_index]} modpath="" modfile="" for modpath in "${ESELECT_MODULES_PATH[@]}" ; do modfile="${modpath}/${modname}.eselect" [[ -f ${modfile} ]] && break done #[[ -f ${modfile} ]] || return 1 # 404 File not found, so theres no way we get the info we need # We're looking for an action; In short: "eselect somemodule " if [[ $((COMP_CWORD-module_index)) -eq 1 ]] ; then possibles+=" ${ESELECT_KNOWN_ACTIONS}" # Include default actions # module-actions follow the pattern "do_${action}()" and "do_${action} ()" respectively possibles+=" " possibles+=$(sed -n -e 's/^do_\([^ _\(]\+\).*/\1/p' ${modfile}) # We're looking for an option. # In short: "eselect somemodule someaction " else local action=${COMP_WORDS[module_index+1]} possibles+=" " possibles+=$( source ${modfile} &> /dev/null # functions describing options follow the pattern "describe_${action}_options()" and "describe_${action}_options ()" if [[ $(type -t "describe_${action}_options" ) == "function" ]] ; then # we're only interested in --options-like-this # TODO The regexp could be improved to match only single "-" between letters echo $(describe_${action}_options | sed -n -e 's/^.*--\([[:alpha:]-]\+\).*/--\1/p') fi ) fi fi COMPREPLY=( $(compgen -W "${possibles}" -- ${curr}) ) return 0 } complete -F _eselect eselect