- handles the case where we are currently completing something that does not appear to be an option. For example, foamDictionary -expanded someD[TAB] should complete the filename, not present more options.
275 lines
7.5 KiB
Bash
Executable File
275 lines
7.5 KiB
Bash
Executable File
#!/bin/sh
|
|
#------------------------------------------------------------------------------
|
|
# ========= |
|
|
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
# \\ / O peration |
|
|
# \\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
|
|
# \\/ M anipulation |
|
|
#------------------------------------------------------------------------------
|
|
# License
|
|
# This file is part of OpenFOAM.
|
|
#
|
|
# OpenFOAM 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.
|
|
#
|
|
# OpenFOAM 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 OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
# Script
|
|
# foamCreateBashCompletions
|
|
#
|
|
# Description
|
|
# Create bash completions for OpenFOAM applications
|
|
#
|
|
#------------------------------------------------------------------------------
|
|
usage() {
|
|
exec 1>&2
|
|
while [ "$#" -ge 1 ]; do echo "$1"; shift; done
|
|
cat<<USAGE
|
|
|
|
Usage: ${0##*/} [OPTION] [appName .. [appNameN]]
|
|
options:
|
|
-d dir | -dir dir Directory to process
|
|
-u | -user Add \$FOAM_USER_APPBIN to the search directories
|
|
-head | -header Generate header
|
|
-h | -help Print the usage
|
|
|
|
Create bash completions for OpenFOAM applications and write to stdout.
|
|
By default searches \$FOAM_APPBIN only.
|
|
Alternatively, scan the output from individual applications for single completion
|
|
commands (using the '_of_complete_' backend).
|
|
|
|
USAGE
|
|
exit 1
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
searchDirs="$FOAM_APPBIN"
|
|
unset optHeader
|
|
while [ "$#" -gt 0 ]
|
|
do
|
|
case "$1" in
|
|
-h | -help)
|
|
usage
|
|
;;
|
|
-d | -dir)
|
|
searchDirs="$2"
|
|
[ -d $searchDirs ] || usage "directory not found '$searchDirs'"
|
|
shift
|
|
;;
|
|
-u | -user)
|
|
searchDirs="$searchDirs $FOAM_USER_APPBIN"
|
|
;;
|
|
-head | -header)
|
|
optHeader=true
|
|
;;
|
|
-*)
|
|
usage "unknown option: '$1'"
|
|
;;
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
# No applications given, then always generate a header
|
|
if [ "$#" -eq 0 ]
|
|
then
|
|
optHeader=true
|
|
fi
|
|
|
|
# Header requested or required
|
|
[ "$optHeader" = true ] && cat << HEADER
|
|
#----------------------------------*-sh-*--------------------------------------
|
|
# Bash completions for OpenFOAM applications
|
|
# Recreate with "${0##*/}"
|
|
#
|
|
# Formatted as "complete ... -F _of_APPNAME APPNAME
|
|
|
|
#
|
|
# Generic completion handler for OpenFOAM applications
|
|
# - arg1 = command-name
|
|
# - arg2 = current word
|
|
# - arg3 = previous word
|
|
# - arg4 = options with args
|
|
# - arg5 = boolean options
|
|
#
|
|
unset -f _of_complete_ 2>/dev/null
|
|
_of_complete_()
|
|
{
|
|
# Unused: local cmd=\$1
|
|
local cur=\$2
|
|
local prev=\$3
|
|
local optsWithArgs="\$4 " # Trailing space added for easier matching
|
|
local opts="\$5 "
|
|
local choices
|
|
|
|
case \${prev} in
|
|
-help|-doc|-srcDoc)
|
|
# These options are usage and we can stop here.
|
|
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}))
|
|
;;
|
|
*Dict)
|
|
# local dirs=\$(\ls -d s*/)
|
|
# local files=\$(\ls -f | grep Dict)
|
|
# COMPREPLY=(\$(compgen -W \"\$dirs \$files\" -- \${cur}))
|
|
COMPREPLY=(\$(compgen -f -- \${cur}))
|
|
;;
|
|
*)
|
|
if [ "\${optsWithArgs/\${prev} /}" != "\${optsWithArgs}" ]
|
|
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,
|
|
# use files 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 \${opts} \${optsWithArgs}
|
|
do
|
|
[ "\${COMP_LINE/\$o/}" = "\${COMP_LINE}" ] && echo \$o
|
|
done
|
|
)
|
|
COMPREPLY=(\$(compgen -W "\$choices" -- \${cur}))
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
return 0
|
|
}
|
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
HEADER
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Scans the output of the application -help to detect options with/without
|
|
# arguments. Dispatch via _of_complete_
|
|
#
|
|
generateCompletion()
|
|
{
|
|
local fullName="$1"
|
|
local appName="${1##*/}"
|
|
local appHelp
|
|
|
|
[ -f "$fullName" -a -x "$fullName" ] || {
|
|
echo "skip $fullName" 1>&2
|
|
return 1
|
|
}
|
|
if [ "$appName" = "complete_" ]
|
|
then
|
|
echo "skip $appName ... reserved name?" 1>&2
|
|
return 1
|
|
fi
|
|
|
|
appHelp=$($fullName -help) || {
|
|
echo "error calling $fullName" 1>&2
|
|
return 1
|
|
}
|
|
|
|
# Options with args - as array
|
|
local optsWithArgs=($(awk '/^ {0,4}-[a-z]/ && /</ {print $1}' <<< "$appHelp"))
|
|
|
|
# Options without args - as array
|
|
local opts=($(awk '/^ {0,4}-[a-z]/ && !/</ {print $1}' <<< "$appHelp"))
|
|
|
|
# See bash(1) for some details. Completion functions are called with
|
|
# arg1 = command-name, arg2 = current word, arg3 = previous word
|
|
#
|
|
# Append known option types and dispatch to _of_complete_
|
|
echo " $appName" 1>&2
|
|
cat << COMPLETION
|
|
|
|
# [$appName]
|
|
unset -f _of_${appName} 2>/dev/null
|
|
_of_${appName}() {
|
|
_of_complete_ "\$@" \\
|
|
"${optsWithArgs[@]}" \\
|
|
"${opts[@]}"
|
|
}
|
|
complete -o filenames -F _of_${appName} $appName
|
|
|
|
COMPLETION
|
|
}
|
|
#------------------------------------------------------------------------------
|
|
|
|
|
|
if [ "$#" -eq 0 ]
|
|
then
|
|
|
|
for dir in ${searchDirs}
|
|
do
|
|
if [ -d "$dir" ]
|
|
then
|
|
echo "Processing directory $dir" 1>&2
|
|
else
|
|
echo "No such directory: $dir" 1>&2
|
|
continue
|
|
fi
|
|
|
|
# Sort with ignore-case
|
|
set -- $(\ls $dir | sort -f)
|
|
for appName
|
|
do
|
|
generateCompletion "$dir/$appName"
|
|
done
|
|
done
|
|
|
|
else
|
|
|
|
for appName
|
|
do
|
|
if [ -f "$appName" -a -x "$appName" ]
|
|
then
|
|
generateCompletion "$appName"
|
|
elif fullName=$(command -v $appName 2>/dev/null)
|
|
then
|
|
generateCompletion "$fullName"
|
|
else
|
|
echo "No application found: $appName" 1>&2
|
|
fi
|
|
done
|
|
|
|
fi
|
|
|
|
|
|
# Generate footer
|
|
[ "$optHeader" = true ] && cat << FOOTER
|
|
|
|
#------------------------------------------------------------------------------
|
|
FOOTER
|
|
|
|
#------------------------------------------------------------------------------
|