#!/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 . # # Script # foamCreateBashCompletions # # Description # Create bash completions for OpenFOAM applications # #------------------------------------------------------------------------------ usage() { exec 1>&2 while [ "$#" -ge 1 ]; do echo "$1"; shift; done cat</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 " case \${prev} in -help|-doc|-srcDoc) COMPREPLY=() ;; -case) COMPREPLY=(\$(compgen -d -- \${cur})) ;; -time) # Could use "foamListTimes -withZero", but still doesn't address ranges COMPREPLY=(\$(compgen -d -X '![-0-9]*' -- \${cur})) ;; -region) local list=\$(\ls -d system/*/ 2>/dev/null | sed -e 's#/\$##' -e 's#^.*/##') COMPREPLY=(\$(compgen -W "\$list" -- \${cur})) ;; -fileHandler) COMPREPLY=(\$(compgen -W "collated uncollated masterUncollated" -- \${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})) else # Catchall # - Present remaining options (not already seen in $COMP_LINE) opts=\$( for o in \${opts} \${optsWithArgs} do [ "\${COMP_LINE/\$o/}" = "\${COMP_LINE}" ] && echo \$o done ) COMPREPLY=(\$(compgen -W "\${opts}" -- \${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 } echo " $appName" 1>&2 # Options with args - as array local optsWithArgs=($(awk '/^ {0,4}-[a-z]/ && //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 #------------------------------------------------------------------------------