mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
- this reduces the number of functions and allows lazy loading of
completion options, which makes it easy to quickly add any other
OpenFOAM application in completion.
The generic '_of_complete_' function handles (bash) completion for
any OpenFOAM application. On the first call for any particular
application, it retrieves the available options from the application
help output and adds this information to its environmental cache for
subsequent use.
- Tcsh completion uses the same function via a bash wrapper.
But since its wrapper is transient, the on-the-fly generation would
be less efficient. For this case, a pre-generated completion_cache
can be used, which is generated with
bin/tools/foamCreateCompletionCache
204 lines
6.5 KiB
Bash
204 lines
6.5 KiB
Bash
#----------------------------------*-sh-*--------------------------------------
|
|
# ========= |
|
|
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
# \\ / O peration |
|
|
# \\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
|
|
# \\/ M anipulation |
|
|
#------------------------------------------------------------------------------
|
|
# This file is part of OpenFOAM, licensed under the GNU General Public License
|
|
# <http://www.gnu.org/licenses/>.
|
|
#
|
|
# File
|
|
# etc/config.sh/bash_completion
|
|
#
|
|
# Description
|
|
# Bash completion handler for OpenFOAM applications and automatic
|
|
# generation of completion associations
|
|
#
|
|
# Provides
|
|
# foamAddCompletion
|
|
# _of_complete_
|
|
#
|
|
# Uses
|
|
# _of_complete_cache_
|
|
#
|
|
#------------------------------------------------------------------------------
|
|
|
|
# Add completion for command or directory of commands
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
unset -f foamAddCompletion 2>/dev/null
|
|
foamAddCompletion()
|
|
{
|
|
[ "$#" -gt 0 ] || \
|
|
echo "Usage: foamAddCompletion -clear | -list | dir(s) | app(s)" 1>&2
|
|
|
|
local appName choices
|
|
for appName
|
|
do
|
|
if [ "$appName" = "-clear" ]
|
|
then
|
|
# Clear cached values
|
|
echo "clear cached values"
|
|
_of_complete_cache_=()
|
|
|
|
elif [ "$appName" = "-list" ]
|
|
then
|
|
# List cached keys
|
|
choices="${#_of_complete_cache_[@]}"
|
|
echo "$choices cached values:"
|
|
[ "$choices" = 0 ] || echo ${!_of_complete_cache_[@]} # keys
|
|
|
|
elif [ -d "$appName" ]
|
|
then
|
|
# Process directory for applications
|
|
choices="$(find $appName -maxdepth 1 -executable -type f 2>/dev/null)"
|
|
for appName in $choices
|
|
do
|
|
complete -o filenames -F _of_complete_ "${appName##*/}"
|
|
# echo "complete ${appName##*/}" 1>&2
|
|
done
|
|
|
|
elif command -v "$appName" > /dev/null 2>&1
|
|
then
|
|
complete -o filenames -F _of_complete_ "${appName##*/}"
|
|
# echo "complete ${appName##*/}" 1>&2
|
|
else
|
|
echo "No completion added for $appName" 1>&2
|
|
fi
|
|
done
|
|
}
|
|
|
|
|
|
# Generic completion handler for OpenFOAM applications
|
|
#
|
|
# Dispatch via "complete ... -F _of_complete_ APPNAME
|
|
# - arg1 = command-name
|
|
# - arg2 = current word
|
|
# - arg3 = previous word
|
|
#
|
|
# The respective options are generated on-the-fly from the application's -help
|
|
# output and cached to the _of_complete_cache_ global associative array with
|
|
# entries formatted as "argOpts.. | boolOpts ..".
|
|
# The '|' character separates options with and without arguments.
|
|
#
|
|
unset -f _of_complete_ 2>/dev/null
|
|
_of_complete_()
|
|
{
|
|
local appName=$1
|
|
local cur=$2
|
|
local prev=$3
|
|
local choices
|
|
|
|
case ${prev} in
|
|
-help|-doc|-srcDoc)
|
|
# These options are usage - we can stop now.
|
|
COMPREPLY=()
|
|
return 0
|
|
;;
|
|
-case)
|
|
COMPREPLY=($(compgen -d -- ${cur}))
|
|
;;
|
|
-time)
|
|
# Could use "foamListTimes -withZero", but still doesn't address ranges
|
|
COMPREPLY=($(compgen -d -X '![-0-9]*' -- ${cur}))
|
|
;;
|
|
-region)
|
|
choices=$(\ls -d system/*/ 2>/dev/null | sed -e 's#/$##' -e 's#^.*/##')
|
|
COMPREPLY=($(compgen -W "$choices" -- ${cur}))
|
|
;;
|
|
-fileHandler)
|
|
choices="collated uncollated masterUncollated"
|
|
COMPREPLY=($(compgen -W "$choices" -- ${cur}))
|
|
;;
|
|
*)
|
|
# All options
|
|
choices="${_of_complete_cache_[$appName]}"
|
|
|
|
# Not in cache, obtain by parsing application -help
|
|
if [ -z "$choices" ]
|
|
then
|
|
local helpText=$($appName -help 2>/dev/null | sed -ne '/^ *-/p')
|
|
|
|
if [ -n "$helpText" ]
|
|
then
|
|
# Array of options with args
|
|
local argOpts=($(awk '/^ {0,4}-[a-z]/ && /</ {print $1}' <<< "$helpText"))
|
|
|
|
# Array of options without args
|
|
local boolOpts=($(awk '/^ {0,4}-[a-z]/ && !/</ {print $1}' <<< "$helpText"))
|
|
|
|
choices="${argOpts[@]} | ${boolOpts[@]}"
|
|
else
|
|
echo "Error calling $appName" 1>&2
|
|
choices="false" # Mark failure to prevent repeating again
|
|
fi
|
|
_of_complete_cache_[$appName]="$choices"
|
|
## echo "generated $appName = $choices" 1>&2 # Debugging
|
|
fi
|
|
if [ "${choices:-false}" = false ]
|
|
then
|
|
COMPREPLY=($(compgen -f -- ${cur}))
|
|
else
|
|
# Everything before the '|' ==> options with args.
|
|
local argOpts="${choices%|*}"
|
|
|
|
if [ "${argOpts/${prev} /}" != "${argOpts}" ]
|
|
then
|
|
# Option with unknown type of arg - set to files.
|
|
# Not always correct but can still navigate path if needed...
|
|
COMPREPLY=($(compgen -f -- ${cur}))
|
|
elif [ -n "$cur" -a "${cur#-}" = "${cur}" ]
|
|
then
|
|
# Already started a (non-empty) word that isn't an option,
|
|
# in which case revert to filenames.
|
|
COMPREPLY=($(compgen -f -- ${cur}))
|
|
else
|
|
# Catchall
|
|
# - Present remaining options (not already seen in $COMP_LINE)
|
|
choices=$(
|
|
for o in ${choices}
|
|
do
|
|
[ "${COMP_LINE/$o/}" = "${COMP_LINE}" ] && echo "${o#|}"
|
|
done
|
|
)
|
|
|
|
COMPREPLY=($(compgen -W "$choices" -- ${cur}))
|
|
fi
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
return 0
|
|
}
|
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
# Global associative array (cached options for OpenFOAM applications)
|
|
declare -gA _of_complete_cache_;
|
|
|
|
# Clear existing cache and reassign bash completions.
|
|
# But for tcsh wrapper make use of caching and avoid this overhead.
|
|
if [ -z "$_of_complete_tcsh" ]
|
|
then
|
|
_of_complete_cache_=()
|
|
|
|
# Remove old completions, which look like:
|
|
# "complete ... -F _of_complete_ APPNAME
|
|
# For economy, obtain list first
|
|
foamOldDirs="$(complete 2>/dev/null | sed -ne 's/^.*-F _of_.* \(..*\)$/\1/p')"
|
|
for cleaned in $foamOldDirs
|
|
do
|
|
complete -r $cleaned 2>/dev/null
|
|
done
|
|
|
|
# Generate completions for predefined directories
|
|
foamAddCompletion $FOAM_APPBIN
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Intermediate variables (do as last for a clean exit code)
|
|
|
|
unset cleaned foamOldDirs
|
|
|
|
#------------------------------------------------------------------------------
|