summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorDavid Rothlisberger <david@rothlis.net>2012-12-19 10:46:50 +0000
committerStefan Sauer <ensonic@users.sf.net>2013-04-29 21:12:42 +0200
commit020dd3bbf36eb17c2716b76bbd876d2f9d080f7a (patch)
tree51cf961ec478829b6d915837dba8199fbece3e11 /tools
parent271c707c45a7d46368eedba4f0d0539834b6a72a (diff)
tools/gstreamer-completion: Support gst-inspect, and gst-launch element properties
Completes options like "--gst-debug-level" and the values of some of those options; completes gst-launch pipeline element names, property names, and even property values (for enum or boolean properties only). Doesn't complete all caps specifications, nor element names specified earlier in the pipeline with "name=...". The GStreamer version number is hard-coded into the completion script: This patch is off the master branch and has the version hard-coded as "1.0"; it needs to be updated if backported to the 0.10 branch. You could always create a "gstreamer-completion.in" that has the appropriate version inserted by "configure", but I'd rather not do that. The hard-coded version is consistent with the previous implementation of gstreamer-completion, which had the registry path hard-coded as ~/.gstreamer-1.0/registry.xml. Note that GStreamer 0.10 installs "gst-inspect" and "gst-inspect-0.10". "gst-inspect --help" only prints 4 flags (--help, --print, --gst-mm, gst-list-mm) whereas "gst-inspect-0.10 --help-all" prints the full list of flags. The same applies to "gst-launch" and "gst-launch-0.10". GStreamer 1.0 only installs "gst-inspect-1.0", not "gst-inspect". Requires bash 4; only tested with bash 4.2. Requires "bash-completion" (which you install with your system's package manager). Put this in /etc/bash_completion.d/ or in `pkg-config --variable=compatdir bash-completion`, where it will be loaded at the beginning of every new terminal session; or in `pgk-config --variable=completionsdir bash-completion`, renamed to match the name of the command it completes (e.g. "gst-launch-1.0", with an additional symlink named "gst-inspect-1.0"), where it will be autoloaded when needed. test-gstreamer-completion.sh is (for now) in tests/misc -- it might be worth creating "tests/check/tools", with all the necessary automake boilerplate, and moving test-gstreamer-completion.sh there, and have it run automatically with "make check". IF YOU'RE NEW TO BASH COMPLETION SCRIPTS ---------------------------------------- "complete -F _gst_launch gst-launch-1.0" means that bash will run the function "_gst_launch" to generate possible completions for the command "gst-launch-1.0". "_gst_launch" must return the possible completions in the array variable COMPREPLY. (Note on bash syntax: "V=(a b c)" assigns three elements to the array "V"). "compgen" prints a list of possible completions to standard output. Try it: compgen -W "abc1 abc2 def" -- "a" compgen -f -- "/" The last argument is the word currently being completed; compgen uses it to filter out the non-matching completions. We put "--" first, in case the word currently being completed starts with "-" or "--", so that it isn't treated as a flag to compgen. For the documentation of COMP_WORDS, COMP_CWORD, etc see http://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html#index-COMP_005fCWORD-180 See also: * http://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.html * http://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html The bash-completion package provides the helper function "_init_completion" which populates variables "cur", "prev", and "words". See http://anonscm.debian.org/gitweb/?p=bash-completion/bash-completion.git;a=blob;f=bash_completion;h=870811b4;hb=HEAD#l634 Note that by default, bash appends a space to the completed word. When the completion is "property=" we don't want a trailing space; calling "compopt -o nospace" modifies the currently-executing completion accordingly. See http://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html#index-compopt
Diffstat (limited to 'tools')
-rw-r--r--tools/gstreamer-completion162
1 files changed, 156 insertions, 6 deletions
diff --git a/tools/gstreamer-completion b/tools/gstreamer-completion
index 5401af006..4489f7dac 100644
--- a/tools/gstreamer-completion
+++ b/tools/gstreamer-completion
@@ -1,13 +1,163 @@
-#
+# Bash tab-completion for GStreamer. -*- shell-script -*-
# Put this in /etc/bash_completion.d/
-#
+
+_gst_version=1.0
+
+_gst_inspect() {
+ local cur prev words cword split
+ _init_completion -n : -s || return
+ _gst_common_options || return
+
+ COMPREPLY=( $(compgen \
+ -W "$(_parse_help gst-inspect-$_gst_version --help-all) \
+ $(_gst_plugins) $(_gst_elements)" \
+ -- "$cur") )
+ [[ $COMPREPLY == *= ]] && compopt -o nospace 2>/dev/null
+} &&
+complete -F _gst_inspect gst-inspect-$_gst_version
_gst_launch() {
- local cur="${COMP_WORDS[COMP_CWORD]}"
- COMPREPLY=( $(compgen -W "$(_gst_elements)" -- "$cur") )
+ local cur cword prev words
+ _init_completion -n : || return
+
+ local curtype option element property
+ _gst_launch_parse
+ _gst_common_options || return
+
+ COMPREPLY=( $(_gst_launch_compgen) )
+ [[ $COMPREPLY == *= ]] && compopt -o nospace 2>/dev/null
} &&
-complete -F _gst_launch -o default gst-launch-1.0
+complete -o default -F _gst_launch gst-launch-$_gst_version
+
+_gst_common_options() {
+ if [[ -v curtype && -v option ]]; then # Called from _gst_launch
+ [[ $curtype == optionval ]] || return 0
+ else # Called from _gst_inspect
+ local option="$prev"
+ fi
+
+ case "$option" in
+ --gst-debug-level)
+ COMPREPLY=( $(compgen -W "0 1 2 3 4 5" -- "$cur") );;
+ --gst-debug) # TODO: comma-separated list of category_name:level pairs.
+ ;;
+ --gst-plugin-path) # TODO: support multiple (colon-separated) paths.
+ COMPREPLY=( $(compgen -d -- "$cur") );;
+ --gst-plugin-load) # TODO: comma-separated list of plugins (files?).
+ ;;
+ *) return 0;;
+ esac
+ return 1 # No need to attempt further completions.
+}
+
+_gst_launch_compgen() {
+ case $curtype in
+ option|option-or-element)
+ compgen \
+ -W "$(_parse_help gst-launch-$_gst_version --help-all)" \
+ -- "$cur"
+ ;;& # test next pattern too.
+ element|option-or-element)
+ compgen -W "$(_gst_elements)" -- "$cur" ;;
+ optionval)
+ case "$option" in
+ -o|--output) compgen -f -- "$cur" ;;
+ --exclude) ;; # TODO: comma-separated list of status information types.
+ esac ;;
+ \!)
+ compgen -W '!' -- "$cur" ;;
+ property)
+ compgen -W "$(_gst_properties $element) ! " -- "$cur" ;;
+ propertyval)
+ compgen -W "$(_gst_property_values $element $property)" -- "$cur" ;;
+ esac
+}
+
+_gst_plugins() {
+ gst-inspect-$_gst_version 2>/dev/null |
+ grep -v 'Total count' |
+ awk -F': +' '{print $1}' |
+ uniq
+}
_gst_elements() {
- gst-inspect-1.0 | grep -v 'Total count' | awk -F': +' '{print $2}'
+ gst-inspect-$_gst_version 2>/dev/null |
+ grep -v 'Total count' |
+ awk -F': +' '{print $2}'
+}
+
+_gst_properties() {
+ local element="$1"
+ gst-inspect-$_gst_version "$element" 2>/dev/null |
+ sed -n '/^Element Properties:$/,$ p' |
+ awk '/^ [a-z]/ { print $1 "=" }'
+}
+
+_gst_property_values() {
+ local element=$1 property=$2
+ gst-inspect-$_gst_version $element 2>/dev/null |
+ awk "
+ /^Element Properties:\$/ { inproperties = 1; next; }
+ inproperties && /^ $property / { inproperty = 1; next; }
+ inproperty && /^ *Boolean/ { printf \"true\nfalse\n\"; exit; }
+ inproperty && /^ *Enum/ { inenum = 1; next; }
+ inenum && /^ *\([0-9]+\): / { print \$2; next; }
+ inproperty && /^ [a-z]/ { exit; }"
+}
+
+# Walks over $words, sets $curtype to the string:
+#
+# 'option' if $cur is an option or flag like "-a" or "--abc".
+# 'optionval' if $cur is the value of an option
+# (which will be set in $option).
+# 'element' if $cur is a GStreamer element name.
+# '!' if $cur is '!'.
+# 'property' if $cur is the name of a property of a GStreamer element
+# (which will be set in $element).
+# 'propertyval' if $cur is the value of an element's property
+# (which will be set in $element and $property, respectively).
+#
+# ($cur is the word currently being completed.)
+#
+# Before calling this function make sure that $curtype, $option, $element and
+# $property are local, and that $cur, $cword and $words have been initialised
+# by calling _init_completion.
+#
+# See test cases in tests/misc/test-gstreamer-completion.sh in the
+# gstreamer source repository.
+#
+_gst_launch_parse() {
+ local i next state
+ curtype= i=1 state=start
+ while [[ $i -le $cword ]]; do
+ next="${words[i]}"
+ # Note that COMP_WORDBREAKS by default includes "=" and ":".
+ case "$state,$next" in
+ start,-*) curtype=option option="$next" state=option;;
+ start,) curtype=option-or-element;;
+ start,*) curtype=element element="$next" state=element;;
+ option,=) curtype=optionval state=option=;;
+ option,*) _gst_takes_arg "$option" &&
+ curtype=optionval state=start ||
+ # re-evaluate without incrementing i:
+ { curtype= state=start; continue; }
+ ;;
+ option=,*) curtype=optionval state=start;;
+ element,\!) curtype='!' state='!';;
+ \!,*) curtype=element element="$next" state=element;;
+ element,*) curtype=property property="$next" state=property;;
+ property,=) curtype=propertyval state=property=;;
+ property=,*) curtype=propertyval state=element;;
+ esac
+ i=$((i + 1))
+ done
+ [[ "$cur" == "=" ]] && cur=""
+}
+
+_gst_takes_arg() {
+ case "$1" in
+ -o|--output|--gst-debug-level|--gst-debug) true;;
+ --gst-plugin-path|--gst-plugin-load|--exclude) true;;
+ *) false;;
+ esac
}