[systemd-commits] 2 commits - Makefile.am shell-completion/bash shell-completion/systemd-bash-completion.sh TODO

Michael Biebl mbiebl at kemper.freedesktop.org
Sun Mar 3 05:42:38 PST 2013


 Makefile.am                                 |   19 
 TODO                                        |    3 
 shell-completion/bash/hostnamectl           |   60 ++
 shell-completion/bash/journalctl            |  105 ++++
 shell-completion/bash/localectl             |   75 +++
 shell-completion/bash/loginctl              |  108 ++++
 shell-completion/bash/systemctl             |  202 +++++++++
 shell-completion/bash/systemd-coredumpctl   |   84 +++
 shell-completion/bash/timedatectl           |   75 +++
 shell-completion/bash/udevadm               |  103 ++++
 shell-completion/systemd-bash-completion.sh |  624 ----------------------------
 11 files changed, 829 insertions(+), 629 deletions(-)

New commits:
commit b8fe3faf9fa6b95ca0413e7dbe0bbdc1d6ab4d7c
Author: Michael Biebl <biebl at debian.org>
Date:   Sun Mar 3 14:40:49 2013 +0100

    Update TODO

diff --git a/TODO b/TODO
index 168913b..5f351b2 100644
--- a/TODO
+++ b/TODO
@@ -57,9 +57,6 @@ Features:
 
 * remove any syslog support from log.c -- we probably can't do this before split-off udev is gone for good
 
-* convert /etc/bash_completion.d/ to /usr/share/bash-completion/
-  (systemd (and everything else) should install zero static data in /etc)
-
 * tmpfiles: when traversing the tree, check for bind mount points with nametohandle()
 
 * fedora: connect the timer units of a service to the service via Also= in [Install], and maybe introduce timers.target

commit d611dadcc74db10ba533ee6859308f5fc505aee1
Author: Michael Biebl <biebl at debian.org>
Date:   Sat Mar 2 22:34:01 2013 +0100

    bash-completion: split completions and move to new location
    
    Split the large bash completion script into separate, smaller files each
    named after the binary it is used for and move the files to
    /usr/share/bash-completion/completions. This way the completions can be
    loaded on demand and we only install the completions for the tools we
    actually build. The old path /etc/bash_completion.d/ is deprecated and
    will disappear in the future.

diff --git a/Makefile.am b/Makefile.am
index b697949..6e12a43 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -64,7 +64,7 @@ pamlibdir=@pamlibdir@
 pkgconfigdatadir=$(datadir)/pkgconfig
 pkgconfiglibdir=$(libdir)/pkgconfig
 polkitpolicydir=$(datadir)/polkit-1/actions
-bashcompletiondir=$(sysconfdir)/bash_completion.d
+bashcompletiondir=$(datadir)/bash-completion/completions
 rpmmacrosdir=$(sysconfdir)/rpm
 sysvinitdir=$(SYSTEM_SYSVINIT_PATH)
 sysvrcnddir=$(SYSTEM_SYSVRCND_PATH)
@@ -316,7 +316,10 @@ systemd_analyze_LDADD = \
 	libsystemd-dbus.la
 
 dist_bashcompletion_DATA = \
-	shell-completion/systemd-bash-completion.sh
+	shell-completion/bash/journalctl \
+	shell-completion/bash/systemctl \
+	shell-completion/bash/systemd-coredumpctl \
+	shell-completion/bash/udevadm
 
 dist_tmpfiles_DATA = \
 	tmpfiles.d/systemd.conf \
@@ -2972,6 +2975,9 @@ hostnamectl_LDADD = \
 bin_PROGRAMS += \
 	hostnamectl
 
+dist_bashcompletion_DATA += \
+	shell-completion/bash/hostnamectl
+
 endif
 
 polkitpolicy_in_files += \
@@ -3045,6 +3051,9 @@ localectl_LDADD = \
 bin_PROGRAMS += \
 	localectl
 
+dist_bashcompletion_DATA += \
+	shell-completion/bash/localectl
+
 endif
 
 polkitpolicy_in_files += \
@@ -3111,6 +3120,9 @@ timedatectl_LDADD = \
 
 bin_PROGRAMS += \
 	timedatectl
+
+dist_bashcompletion_DATA += \
+	shell-completion/bash/timedatectl
 endif
 
 polkitpolicy_in_files += \
@@ -3233,6 +3245,9 @@ loginctl_LDADD = \
 rootbin_PROGRAMS += \
 	loginctl
 
+dist_bashcompletion_DATA += \
+	shell-completion/bash/loginctl
+
 systemd_inhibit_SOURCES = \
 	src/login/inhibit.c
 
diff --git a/shell-completion/bash/hostnamectl b/shell-completion/bash/hostnamectl
new file mode 100644
index 0000000..a57bffe
--- /dev/null
+++ b/shell-completion/bash/hostnamectl
@@ -0,0 +1,60 @@
+# hostnamectl(1) completion                               -*- shell-script -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2010 Ran Benita
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd 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 Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+__contains_word () {
+        local word=$1; shift
+        for w in $*; do [[ $w = $word ]] && return 0; done
+        return 1
+}
+
+_hostnamectl() {
+        local i verb comps
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local OPTS='-h --help --version --transient --static --pretty
+                    --no-ask-password -H --host'
+
+        if [[ $cur = -* ]]; then
+                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+                return 0
+        fi
+
+        local -A VERBS=(
+                [STANDALONE]='status'
+                     [ICONS]='set-icon-name'
+                      [NAME]='set-hostname'
+        )
+
+        for ((i=0; i <= COMP_CWORD; i++)); do
+                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
+                        verb=${COMP_WORDS[i]}
+                        break
+                fi
+        done
+
+        if [[ -z $verb ]]; then
+                comps=${VERBS[*]}
+        elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[ICONS]} ${VERBS[NAME]}; then
+                comps=''
+        fi
+
+        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+        return 0
+}
+
+complete -F _hostnamectl hostnamectl
diff --git a/shell-completion/bash/journalctl b/shell-completion/bash/journalctl
new file mode 100644
index 0000000..1fca5ad
--- /dev/null
+++ b/shell-completion/bash/journalctl
@@ -0,0 +1,105 @@
+# journalctl(1) completion                                -*- shell-script -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2010 Ran Benita
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd 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 Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+__contains_word () {
+        local word=$1; shift
+        for w in $*; do [[ $w = $word ]] && return 0; done
+        return 1
+}
+
+__journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC}
+                  ERRNO SYSLOG_{FACILITY,IDENTIFIER,PID} COREDUMP_EXE
+                  _{P,U,G}ID _COMM _EXE _CMDLINE
+                  _AUDIT_{SESSION,LOGINUID}
+                  _SYSTEMD_{CGROUP,SESSION,UNIT,OWNER_UID}
+                  _SELINUX_CONTEXT _SOURCE_REALTIME_TIMESTAMP
+                  _{BOOT,MACHINE}_ID _HOSTNAME _TRANSPORT
+                  _KERNEL_{DEVICE,SUBSYSTEM}
+                  _UDEV_{SYSNAME,DEVNODE,DEVLINK}
+                  __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP)
+
+_journalctl() {
+        local field_vals= cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local -A OPTS=(
+                [STANDALONE]='-a --all --full
+                              -b --this-boot --disk-usage -f --follow --header
+                              -h --help -l --local --new-id128 -m --merge --no-pager
+                              --no-tail -q --quiet --setup-keys --this-boot --verify
+                              --version --list-catalog --update-catalog'
+                       [ARG]='-D --directory -F --field -o --output -u --unit --user-unit'
+                [ARGUNKNOWN]='-c --cursor --interval -n --lines -p --priority --since --until
+                              --verify-key'
+        )
+
+        if __contains_word "$prev" ${OPTS[ARG]} ${OPTS[ARGUNKNOWN]}; then
+                case $prev in
+                        --directory|-D)
+                                comps=$(compgen -d -- "$cur")
+                                compopt -o filenames
+                        ;;
+                        --output|-o)
+                                comps='short short-monotonic verbose export json cat'
+                        ;;
+                        --field|-F)
+                                comps=${__journal_fields[*]}
+                        ;;
+                        --unit|-u)
+                                comps=$(journalctl -F '_SYSTEMD_UNIT')
+                        ;;
+                        --user-unit)
+                                comps=$(journalctl -F '_SYSTEMD_USER_UNIT')
+                        ;;
+                        *)
+                                return 0
+                        ;;
+                esac
+                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+                return 0
+        fi
+
+        if [[ $cur = -* ]]; then
+                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+                return 0
+        elif [[ $cur = *=* ]]; then
+                mapfile -t field_vals < <(journalctl -F "${prev%=}" 2>/dev/null)
+                COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "${cur#=}") )
+        elif [[ $cur = /dev* ]]; then
+                compopt -o filenames
+                COMPREPLY=( $(compgen -f -- "${cur}") )
+        elif [[ $cur = /* ]]; then
+                # Append /dev/ to the list of completions, so that
+                # after typing /<TAB><TAB> the user sees /dev/ as one
+                # of the alternatives. Later on the rule above will
+                # take care of showing device files in /dev/.
+                mapfile -t field_vals < <(journalctl -F "_EXE" 2>/dev/null; echo '/dev/')
+                COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "${cur}") )
+                if [[ "${COMPREPLY[@]}" = '/dev/' ]]; then
+                    compopt -o filenames
+                    COMPREPLY=( $(compgen -f -- "${cur}") )
+                fi
+        elif [[ $prev = '=' ]]; then
+                mapfile -t field_vals < <(journalctl -F "${COMP_WORDS[COMP_CWORD-2]}" 2>/dev/null)
+                COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "$cur") )
+        else
+                compopt -o nospace
+                COMPREPLY=( $(compgen -W '${__journal_fields[*]}' -S= -- "$cur") )
+        fi
+}
+
+complete -F _journalctl journalctl
diff --git a/shell-completion/bash/localectl b/shell-completion/bash/localectl
new file mode 100644
index 0000000..ef19f01
--- /dev/null
+++ b/shell-completion/bash/localectl
@@ -0,0 +1,75 @@
+# localectl(1) completion                                 -*- shell-script -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2010 Ran Benita
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd 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 Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+__contains_word () {
+        local word=$1; shift
+        for w in $*; do [[ $w = $word ]] && return 0; done
+        return 1
+}
+
+_localectl() {
+        local i verb comps
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local OPTS='-h --help --version --no-convert --no-pager --no-ask-password
+                    -H --host'
+
+        if __contains_word "$prev" $OPTS; then
+                case $prev in
+                        --host|-H)
+                                comps=''
+                        ;;
+                esac
+                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+                return 0
+        fi
+
+        if [[ $cur = -* ]]; then
+                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+                return 0
+        fi
+
+        local -A VERBS=(
+               [STANDALONE]='status list-locales list-keymaps'
+                  [LOCALES]='set-locale'
+                  [KEYMAPS]='set-keymap'
+                      [X11]='set-x11-keymap'
+        )
+
+        for ((i=0; i <= COMP_CWORD; i++)); do
+                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
+                        verb=${COMP_WORDS[i]}
+                        break
+                fi
+        done
+
+        if [[ -z $verb ]]; then
+                comps=${VERBS[*]}
+        elif __contains_word "$verb" ${VERBS[LOCALES]}; then
+                comps=$(command localectl list-locales)
+        elif __contains_word "$verb" ${VERBS[KEYMAPS]}; then
+                comps=$(command localectl list-keymaps)
+        elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[X11]}; then
+                comps=''
+        fi
+
+        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+        return 0
+}
+
+complete -F _localectl localectl
diff --git a/shell-completion/bash/loginctl b/shell-completion/bash/loginctl
new file mode 100644
index 0000000..1844085
--- /dev/null
+++ b/shell-completion/bash/loginctl
@@ -0,0 +1,108 @@
+# loginctl(1) completion                                  -*- shell-script -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2010 Ran Benita
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd 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 Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+__contains_word () {
+        local word=$1; shift
+        for w in $*; do [[ $w = $word ]] && return 0; done
+        return 1
+}
+
+__get_all_sessions () { loginctl list-sessions | { while read -r a b; do printf "%s\n" "$a"; done; } ; }
+__get_all_users    () { loginctl list-users    | { while read -r a b; do printf "%s\n" "$b"; done; } ; }
+__get_all_seats    () { loginctl list-seats    | { while read -r a b; do printf "%s\n" "$a"; done; } ; }
+
+_loginctl () {
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local i verb comps
+
+        local -A OPTS=(
+               [STANDALONE]='--all -a --help -h --no-pager --privileged -P --version'
+                      [ARG]='--host -H --kill-who --property -p --signal -s'
+        )
+
+        if __contains_word "$prev" ${OPTS[ARG]}; then
+                case $prev in
+                        --signal|-s)
+                                comps=$(compgen -A signal)
+                        ;;
+                        --kill-who)
+                                comps='all leader'
+                        ;;
+                        --host|-H)
+                                comps=$(compgen -A hostname)
+                        ;;
+                        --property|-p)
+                                comps=''
+                        ;;
+                esac
+                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+                return 0
+        fi
+
+
+        if [[ "$cur" = -* ]]; then
+                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+                return 0
+        fi
+
+        local -A VERBS=(
+                [SESSIONS]='session-status show-session activate lock-session unlock-session terminate-session kill-session'
+                [USERS]='user-status show-user enable-linger disable-linger terminate-user kill-user'
+                [SEATS]='seat-status show-seat terminate-seat'
+                [STANDALONE]='list-sessions list-users list-seats flush-devices'
+                [ATTACH]='attach'
+        )
+
+        for ((i=0; $i <= $COMP_CWORD; i++)); do
+                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
+                 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
+                        verb=${COMP_WORDS[i]}
+                        break
+                fi
+        done
+
+        if   [[ -z $verb ]]; then
+                comps="${VERBS[*]}"
+
+        elif __contains_word "$verb" ${VERBS[SESSIONS]}; then
+                comps=$( __get_all_sessions )
+
+        elif __contains_word "$verb" ${VERBS[USERS]}; then
+                comps=$( __get_all_users )
+
+        elif __contains_word "$verb" ${VERBS[SEATS]}; then
+                comps=$( __get_all_seats )
+
+        elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
+                comps=''
+
+        elif __contains_word "$verb" ${VERBS[ATTACH]}; then
+                if [[ $prev = $verb ]]; then
+                        comps=$( __get_all_seats )
+                else
+                        comps=$(compgen -A file -- "$cur" )
+                        compopt -o filenames
+                fi
+        fi
+
+        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+        return 0
+}
+
+complete -F _loginctl loginctl
diff --git a/shell-completion/bash/systemctl b/shell-completion/bash/systemctl
new file mode 100644
index 0000000..27d89ec
--- /dev/null
+++ b/shell-completion/bash/systemctl
@@ -0,0 +1,202 @@
+# systemctl(1) completion                                 -*- shell-script -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2010 Ran Benita
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd 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 Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+__systemctl() {
+        systemctl --full --no-legend "$@"
+}
+
+__contains_word () {
+        local word=$1; shift
+        for w in $*; do [[ $w = $word ]] && return 0; done
+        return 1
+}
+
+__filter_units_by_property () {
+        local property=$1 value=$2 ; shift 2
+        local units=("$@")
+        local props
+        IFS=$'\n' read -rd '' -a props < \
+            <(__systemctl show --property "$property" -- "${units[@]}")
+        for ((i=0; $i < ${#units[*]}; i++)); do
+                if [[ "${props[i]}" = "$property=$value" ]]; then
+                        printf "%s\n" "${units[i]}"
+                fi
+        done
+}
+
+__get_all_units      () { __systemctl list-units --all \
+        | { while read -r a b; do printf "%s\n" "$a"; done; }; }
+__get_active_units   () { __systemctl list-units       \
+        | { while read -r a b; do printf "%s\n" "$a"; done; }; }
+__get_inactive_units () { __systemctl list-units --all \
+        | { while read -r a b c d; do [[ $c == "inactive" ]] && printf "%s\n" "$a"; done; }; }
+__get_failed_units   () { __systemctl list-units       \
+        | { while read -r a b c d; do [[ $c == "failed"   ]] && printf "%s\n" "$a"; done; }; }
+__get_enabled_units  () { __systemctl list-unit-files  \
+        | { while read -r a b c  ; do [[ $b == "enabled"  ]] && printf "%s\n" "$a"; done; }; }
+__get_disabled_units () { __systemctl list-unit-files  \
+        | { while read -r a b c  ; do [[ $b == "disabled" ]] && printf "%s\n" "$a"; done; }; }
+__get_masked_units   () { __systemctl list-unit-files  \
+        | { while read -r a b c  ; do [[ $b == "masked"   ]] && printf "%s\n" "$a"; done; }; }
+
+_systemctl () {
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local i verb comps
+
+        local -A OPTS=(
+               [STANDALONE]='--all -a --defaults --fail --ignore-dependencies --failed --force -f --full --global
+                             --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall
+                             --quiet -q --privileged -P --system --user --version --runtime'
+                      [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --root'
+        )
+
+        if __contains_word "$prev" ${OPTS[ARG]}; then
+                case $prev in
+                        --signal|-s)
+                                comps=$(compgen -A signal)
+                        ;;
+                        --type|-t)
+                                comps='automount device mount path service snapshot socket swap target timer'
+                        ;;
+                        --kill-who)
+                                comps='all control main'
+                        ;;
+                        --kill-mode)
+                                comps='control-group process'
+                        ;;
+                        --root)
+                                comps=$(compgen -A directory -- "$cur" )
+                                compopt -o filenames
+                        ;;
+                        --host|-H)
+                                comps=$(compgen -A hostname)
+                        ;;
+                        --property|-p)
+                                comps=''
+                        ;;
+                esac
+                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+                return 0
+        fi
+
+
+        if [[ "$cur" = -* ]]; then
+                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+                return 0
+        fi
+
+        local -A VERBS=(
+                [ALL_UNITS]='is-active is-failed is-enabled status show mask preset'
+            [ENABLED_UNITS]='disable reenable'
+           [DISABLED_UNITS]='enable'
+             [FAILED_UNITS]='reset-failed'
+          [STARTABLE_UNITS]='start'
+          [STOPPABLE_UNITS]='stop condstop kill try-restart condrestart'
+         [ISOLATABLE_UNITS]='isolate'
+         [RELOADABLE_UNITS]='reload condreload reload-or-try-restart force-reload'
+        [RESTARTABLE_UNITS]='restart reload-or-restart'
+             [MASKED_UNITS]='unmask'
+                     [JOBS]='cancel'
+                [SNAPSHOTS]='delete'
+                     [ENVS]='set-environment unset-environment'
+               [STANDALONE]='daemon-reexec daemon-reload default dump
+                             emergency exit halt hibernate hybrid-sleep kexec list-jobs
+                             list-units list-unit-files poweroff reboot rescue
+                             show-environment suspend'
+                     [NAME]='snapshot load'
+                     [FILE]='link'
+        )
+
+        for ((i=0; $i <= $COMP_CWORD; i++)); do
+                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
+                 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
+                        verb=${COMP_WORDS[i]}
+                        break
+                fi
+        done
+
+        if   [[ -z $verb ]]; then
+                comps="${VERBS[*]}"
+
+        elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then
+                comps=$( __get_all_units )
+
+        elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then
+                comps=$( __get_enabled_units )
+
+        elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then
+                comps=$( __get_disabled_units )
+
+        elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then
+                comps=$( __filter_units_by_property CanStart yes \
+                      $( __get_inactive_units \
+                        | while read -r line; do \
+                                [[ "$line" =~ \.(device|snapshot)$ ]] || printf "%s\n" "$line"; \
+                        done ))
+
+        elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then
+                comps=$( __filter_units_by_property CanStart yes \
+                      $( __get_all_units \
+                        | while read -r line; do \
+                                [[ "$line" =~ \.(device|snapshot|socket|timer)$ ]] || printf "%s\n" "$line"; \
+                        done ))
+
+        elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then
+                comps=$( __filter_units_by_property CanStop yes \
+                      $( __get_active_units ) )
+
+        elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then
+                comps=$( __filter_units_by_property CanReload yes \
+                      $( __get_active_units ) )
+
+        elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then
+                comps=$( __filter_units_by_property AllowIsolate yes \
+                      $( __get_all_units ) )
+
+        elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then
+                comps=$( __get_failed_units )
+
+        elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then
+                comps=$( __get_masked_units )
+
+        elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then
+                comps=''
+
+        elif __contains_word "$verb" ${VERBS[JOBS]}; then
+                comps=$( __systemctl list-jobs | { while read -r a b; do printf "%s\n" "$a"; done; } )
+
+        elif __contains_word "$verb" ${VERBS[SNAPSHOTS]}; then
+                comps=$( __systemctl list-units --type snapshot --full --all \
+                        | { while read -r a b; do printf "%s\n" "$a"; done; } )
+
+        elif __contains_word "$verb" ${VERBS[ENVS]}; then
+                comps=$( __systemctl show-environment \
+                    | while read -r line; do printf "%s\n" "${line%%=*}=";done )
+                compopt -o nospace
+
+        elif __contains_word "$verb" ${VERBS[FILE]}; then
+                comps=$( compgen -A file -- "$cur" )
+                compopt -o filenames
+        fi
+
+        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+        return 0
+}
+
+complete -F _systemctl systemctl
diff --git a/shell-completion/bash/systemd-coredumpctl b/shell-completion/bash/systemd-coredumpctl
new file mode 100644
index 0000000..4bbece7
--- /dev/null
+++ b/shell-completion/bash/systemd-coredumpctl
@@ -0,0 +1,84 @@
+# systemd-coredumpctl(1) completion                       -*- shell-script -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2010 Ran Benita
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd 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 Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+__contains_word () {
+        local word=$1; shift
+        for w in $*; do [[ $w = $word ]] && return 0; done
+        return 1
+}
+
+__journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC}
+                  ERRNO SYSLOG_{FACILITY,IDENTIFIER,PID} COREDUMP_EXE
+                  _{P,U,G}ID _COMM _EXE _CMDLINE
+                  _AUDIT_{SESSION,LOGINUID}
+                  _SYSTEMD_{CGROUP,SESSION,UNIT,OWNER_UID}
+                  _SELINUX_CONTEXT _SOURCE_REALTIME_TIMESTAMP
+                  _{BOOT,MACHINE}_ID _HOSTNAME _TRANSPORT
+                  _KERNEL_{DEVICE,SUBSYSTEM}
+                  _UDEV_{SYSNAME,DEVNODE,DEVLINK}
+                  __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP)
+_coredumpctl() {
+        local i verb comps
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local OPTS='-h --help --version --no-pager --no-legend -o --output -F --field'
+
+        local -A VERBS=(
+            [LIST]='list'
+            [DUMP]='dump gdb'
+        )
+
+        if __contains_word "$prev" '--output -o'; then
+                comps=$( compgen -A file -- "$cur" )
+                compopt -o filenames
+        elif __contains_word "$prev" '--FIELD -F'; then
+                comps=$( compgen -W '${__journal_fields[*]}' -- "$cur" )
+        elif [[ $cur = -* ]]; then
+                comps=${OPTS}
+        elif __contains_word "$prev" ${VERBS[*]} &&
+           ! __contains_word ${COMP_WORDS[COMP_CWORD-2]} '--output -o -F --field'; then
+                compopt -o nospace
+                COMPREPLY=( $(compgen -W '${__journal_fields[*]}' -S= -- "$cur") )
+               return 0
+        elif [[ $cur = *=* ]]; then
+                mapfile -t field_vals < <(systemd-coredumpctl -F "${prev%=}" 2>/dev/null)
+                COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "${cur#=}") )
+                return 0
+        elif [[ $prev = '=' ]]; then
+                mapfile -t field_vals < <(systemd-coredumpctl -F "${COMP_WORDS[COMP_CWORD-2]}" 2>/dev/null)
+                comps=${field_vals[*]}
+        else
+                for ((i=0; i <= COMP_CWORD; i++)); do
+                        if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
+                                verb=${COMP_WORDS[i]}
+                                break
+                        fi
+                done
+
+                if [[ -z $verb ]]; then
+                        comps=${VERBS[*]}
+                elif __contains_word "$verb" ${VERBS[LIST]} ${VERBS[DUMP]}; then
+                        comps=''
+                fi
+        fi
+
+        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+        return 0
+}
+
+complete -F _coredumpctl systemd-coredumpctl
diff --git a/shell-completion/bash/timedatectl b/shell-completion/bash/timedatectl
new file mode 100644
index 0000000..2842b31
--- /dev/null
+++ b/shell-completion/bash/timedatectl
@@ -0,0 +1,75 @@
+# timedatectl(1) completion                               -*- shell-script -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2010 Ran Benita
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd 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 Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+__contains_word () {
+        local word=$1; shift
+        for w in $*; do [[ $w = $word ]] && return 0; done
+        return 1
+}
+
+_timedatectl() {
+        local i verb comps
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local OPTS='-h --help --version --adjust-system-clock --no-pager
+                    --no-ask-password -H --host'
+
+        if __contains_word "$prev" $OPTS; then
+                case $prev in
+                        --host|-H)
+                                comps=''
+                        ;;
+                esac
+                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+                return 0
+        fi
+
+        if [[ $cur = -* ]]; then
+                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+                return 0
+        fi
+
+        local -A VERBS=(
+                  [BOOLEAN]='set-local-rtc set-ntp'
+               [STANDALONE]='status set-time list-timezones'
+                [TIMEZONES]='set-timezone'
+                     [TIME]='set-time'
+        )
+
+        for ((i=0; i <= COMP_CWORD; i++)); do
+                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
+                        verb=${COMP_WORDS[i]}
+                        break
+                fi
+        done
+
+        if [[ -z $verb ]]; then
+                comps=${VERBS[*]}
+        elif __contains_word "$verb" ${VERBS[BOOLEAN]}; then
+                comps='true false'
+        elif __contains_word "$verb" ${VERBS[TIMEZONES]}; then
+                comps=$(command timedatectl list-timezones)
+        elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[TIME]}; then
+                comps=''
+        fi
+
+        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+        return 0
+}
+
+complete -F _timedatectl timedatectl
diff --git a/shell-completion/bash/udevadm b/shell-completion/bash/udevadm
new file mode 100644
index 0000000..a31d465
--- /dev/null
+++ b/shell-completion/bash/udevadm
@@ -0,0 +1,103 @@
+# udevadm(8) completion                                   -*- shell-script -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2010 Ran Benita
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd 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 Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+__contains_word () {
+        local word=$1; shift
+        for w in $*; do [[ $w = $word ]] && return 0; done
+        return 1
+}
+
+__get_all_sysdevs() {
+        local -a devs=(/sys/bus/*/devices/*/ /sys/class/*/*/)
+        printf '%s\n' "${devs[@]%/}"
+}
+
+_udevadm() {
+        local i verb comps
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local OPTS='-h --help --version --debug'
+
+        local -A VERBS=(
+                [INFO]='info'
+                [TRIGGER]='trigger'
+                [SETTLE]='settle'
+                [CONTROL]='control'
+                [MONITOR]='monitor'
+                [HWDB]='hwdb'
+                [TESTBUILTIN]='test-builtin'
+                [TEST]='test'
+        )
+
+        for ((i=0; $i <= $COMP_CWORD; i++)); do
+                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
+                 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
+                        verb=${COMP_WORDS[i]}
+                        break
+                fi
+        done
+
+        if [[ -z $verb  && $cur = -* ]]; then
+                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+                return 0
+        fi
+
+        if [[ -z $verb ]]; then
+                comps=${VERBS[*]}
+
+        elif __contains_word "$verb" ${VERBS[INFO]}; then
+                if [[ $cur = -* ]]; then
+                        comps='--help --query= --path= --name= --root --attribute-walk --export-db --cleanup-db'
+                else
+                        comps=$( __get_all_sysdevs )
+                fi
+
+        elif __contains_word "$verb" ${VERBS[TRIGGER]}; then
+                comps='--help --verbose --dry-run --type= --action= --subsystem-match=
+                       --subsystem-nomatch= --attr-match= --attr-nomatch= --property-match=
+                       --tag-match= --sysname-match= --parent-match='
+
+        elif __contains_word "$verb" ${VERBS[SETTLE]}; then
+                comps='--help --timeout= --seq-start= --seq-end= --exit-if-exists= --quiet'
+
+        elif __contains_word "$verb" ${VERBS[CONTROL]}; then
+                comps='--help --exit --log-priority= --stop-exec-queue --start-exec-queue
+                       --reload --property= --children-max= --timeout='
+
+        elif __contains_word "$verb" ${VERBS[MONITOR]}; then
+                comps='--help --kernel --udev --property --subsystem-match= --tag-match='
+
+        elif __contains_word "$verb" ${VERBS[HWDB]}; then
+                comps='--help --update --test='
+
+        elif __contains_word "$verb" ${VERBS[TEST]}; then
+                if [[ $cur = -* ]]; then
+                        comps='--help --action='
+                else
+                        comps=$( __get_all_sysdevs )
+                fi
+
+        elif __contains_word "$verb" ${VERBS[TESTBUILTIN]}; then
+                      comps='blkid btrfs firmware hwdb input_id kmod net_id path_id usb_id uaccess'
+        fi
+
+        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+        return 0
+}
+
+complete -F _udevadm udevadm
diff --git a/shell-completion/systemd-bash-completion.sh b/shell-completion/systemd-bash-completion.sh
deleted file mode 100644
index 40e66e9..0000000
--- a/shell-completion/systemd-bash-completion.sh
+++ /dev/null
@@ -1,624 +0,0 @@
-# This file is part of systemd.
-#
-# Copyright 2010 Ran Benita
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# systemd 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 Lesser General Public License
-# along with systemd; If not, see <http://www.gnu.org/licenses/>.
-
-__systemctl() {
-        systemctl --full --no-legend "$@"
-}
-
-__contains_word () {
-        local word=$1; shift
-        for w in $*; do [[ $w = $word ]] && return 0; done
-        return 1
-}
-
-__filter_units_by_property () {
-        local property=$1 value=$2 ; shift 2
-        local units=("$@")
-        local props
-        IFS=$'\n' read -rd '' -a props < \
-            <(__systemctl show --property "$property" -- "${units[@]}")
-        for ((i=0; $i < ${#units[*]}; i++)); do
-                if [[ "${props[i]}" = "$property=$value" ]]; then
-                        printf "%s\n" "${units[i]}"
-                fi
-        done
-}
-
-__get_all_units      () { __systemctl list-units --all \
-        | { while read -r a b; do printf "%s\n" "$a"; done; }; }
-__get_active_units   () { __systemctl list-units       \
-        | { while read -r a b; do printf "%s\n" "$a"; done; }; }
-__get_inactive_units () { __systemctl list-units --all \
-        | { while read -r a b c d; do [[ $c == "inactive" ]] && printf "%s\n" "$a"; done; }; }
-__get_failed_units   () { __systemctl list-units       \
-        | { while read -r a b c d; do [[ $c == "failed"   ]] && printf "%s\n" "$a"; done; }; }
-__get_enabled_units  () { __systemctl list-unit-files  \
-        | { while read -r a b c  ; do [[ $b == "enabled"  ]] && printf "%s\n" "$a"; done; }; }
-__get_disabled_units () { __systemctl list-unit-files  \
-        | { while read -r a b c  ; do [[ $b == "disabled" ]] && printf "%s\n" "$a"; done; }; }
-__get_masked_units   () { __systemctl list-unit-files  \
-        | { while read -r a b c  ; do [[ $b == "masked"   ]] && printf "%s\n" "$a"; done; }; }
-
-_systemctl () {
-        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
-        local i verb comps
-
-        local -A OPTS=(
-               [STANDALONE]='--all -a --defaults --fail --ignore-dependencies --failed --force -f --full --global
-                             --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall
-                             --quiet -q --privileged -P --system --user --version --runtime'
-                      [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --root'
-        )
-
-        if __contains_word "$prev" ${OPTS[ARG]}; then
-                case $prev in
-                        --signal|-s)
-                                comps=$(compgen -A signal)
-                        ;;
-                        --type|-t)
-                                comps='automount device mount path service snapshot socket swap target timer'
-                        ;;
-                        --kill-who)
-                                comps='all control main'
-                        ;;
-                        --kill-mode)
-                                comps='control-group process'
-                        ;;
-                        --root)
-                                comps=$(compgen -A directory -- "$cur" )
-                                compopt -o filenames
-                        ;;
-                        --host|-H)
-                                comps=$(compgen -A hostname)
-                        ;;
-                        --property|-p)
-                                comps=''
-                        ;;
-                esac
-                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
-                return 0
-        fi
-
-
-        if [[ "$cur" = -* ]]; then
-                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
-                return 0
-        fi
-
-        local -A VERBS=(
-                [ALL_UNITS]='is-active is-failed is-enabled status show mask preset'
-            [ENABLED_UNITS]='disable reenable'
-           [DISABLED_UNITS]='enable'
-             [FAILED_UNITS]='reset-failed'
-          [STARTABLE_UNITS]='start'
-          [STOPPABLE_UNITS]='stop condstop kill try-restart condrestart'
-         [ISOLATABLE_UNITS]='isolate'
-         [RELOADABLE_UNITS]='reload condreload reload-or-try-restart force-reload'
-        [RESTARTABLE_UNITS]='restart reload-or-restart'
-             [MASKED_UNITS]='unmask'
-                     [JOBS]='cancel'
-                [SNAPSHOTS]='delete'
-                     [ENVS]='set-environment unset-environment'
-               [STANDALONE]='daemon-reexec daemon-reload default dump
-                             emergency exit halt hibernate hybrid-sleep kexec list-jobs
-                             list-units list-unit-files poweroff reboot rescue
-                             show-environment suspend'
-                     [NAME]='snapshot load'
-                     [FILE]='link'
-        )
-
-        for ((i=0; $i <= $COMP_CWORD; i++)); do
-                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
-                 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
-                        verb=${COMP_WORDS[i]}
-                        break
-                fi
-        done
-
-        if   [[ -z $verb ]]; then
-                comps="${VERBS[*]}"
-
-        elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then
-                comps=$( __get_all_units )
-
-        elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then
-                comps=$( __get_enabled_units )
-
-        elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then
-                comps=$( __get_disabled_units )
-
-        elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then
-                comps=$( __filter_units_by_property CanStart yes \
-                      $( __get_inactive_units \
-                        | while read -r line; do \
-                                [[ "$line" =~ \.(device|snapshot)$ ]] || printf "%s\n" "$line"; \
-                        done ))
-
-        elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then
-                comps=$( __filter_units_by_property CanStart yes \
-                      $( __get_all_units \
-                        | while read -r line; do \
-                                [[ "$line" =~ \.(device|snapshot|socket|timer)$ ]] || printf "%s\n" "$line"; \
-                        done ))
-
-        elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then
-                comps=$( __filter_units_by_property CanStop yes \
-                      $( __get_active_units ) )
-
-        elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then
-                comps=$( __filter_units_by_property CanReload yes \
-                      $( __get_active_units ) )
-
-        elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then
-                comps=$( __filter_units_by_property AllowIsolate yes \
-                      $( __get_all_units ) )
-
-        elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then
-                comps=$( __get_failed_units )
-
-        elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then
-                comps=$( __get_masked_units )
-
-        elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then
-                comps=''
-
-        elif __contains_word "$verb" ${VERBS[JOBS]}; then
-                comps=$( __systemctl list-jobs | { while read -r a b; do printf "%s\n" "$a"; done; } )
-
-        elif __contains_word "$verb" ${VERBS[SNAPSHOTS]}; then
-                comps=$( __systemctl list-units --type snapshot --full --all \
-                        | { while read -r a b; do printf "%s\n" "$a"; done; } )
-
-        elif __contains_word "$verb" ${VERBS[ENVS]}; then
-                comps=$( __systemctl show-environment \
-                    | while read -r line; do printf "%s\n" "${line%%=*}=";done )
-                compopt -o nospace
-
-        elif __contains_word "$verb" ${VERBS[FILE]}; then
-                comps=$( compgen -A file -- "$cur" )
-                compopt -o filenames
-        fi
-
-        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
-        return 0
-}
-complete -F _systemctl systemctl
-
-__get_all_sessions () { loginctl list-sessions | { while read -r a b; do printf "%s\n" "$a"; done; } ; }
-__get_all_users    () { loginctl list-users    | { while read -r a b; do printf "%s\n" "$b"; done; } ; }
-__get_all_seats    () { loginctl list-seats    | { while read -r a b; do printf "%s\n" "$a"; done; } ; }
-
-_loginctl () {
-        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
-        local i verb comps
-
-        local -A OPTS=(
-               [STANDALONE]='--all -a --help -h --no-pager --privileged -P --version'
-                      [ARG]='--host -H --kill-who --property -p --signal -s'
-        )
-
-        if __contains_word "$prev" ${OPTS[ARG]}; then
-                case $prev in
-                        --signal|-s)
-                                comps=$(compgen -A signal)
-                        ;;
-                        --kill-who)
-                                comps='all leader'
-                        ;;
-                        --host|-H)
-                                comps=$(compgen -A hostname)
-                        ;;
-                        --property|-p)
-                                comps=''
-                        ;;
-                esac
-                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
-                return 0
-        fi
-
-
-        if [[ "$cur" = -* ]]; then
-                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
-                return 0
-        fi
-
-        local -A VERBS=(
-                [SESSIONS]='session-status show-session activate lock-session unlock-session terminate-session kill-session'
-                [USERS]='user-status show-user enable-linger disable-linger terminate-user kill-user'
-                [SEATS]='seat-status show-seat terminate-seat'
-                [STANDALONE]='list-sessions list-users list-seats flush-devices'
-                [ATTACH]='attach'
-        )
-
-        for ((i=0; $i <= $COMP_CWORD; i++)); do
-                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
-                 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
-                        verb=${COMP_WORDS[i]}
-                        break
-                fi
-        done
-
-        if   [[ -z $verb ]]; then
-                comps="${VERBS[*]}"
-
-        elif __contains_word "$verb" ${VERBS[SESSIONS]}; then
-                comps=$( __get_all_sessions )
-
-        elif __contains_word "$verb" ${VERBS[USERS]}; then
-                comps=$( __get_all_users )
-
-        elif __contains_word "$verb" ${VERBS[SEATS]}; then
-                comps=$( __get_all_seats )
-
-        elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
-                comps=''
-
-        elif __contains_word "$verb" ${VERBS[ATTACH]}; then
-                if [[ $prev = $verb ]]; then
-                        comps=$( __get_all_seats )
-                else
-                        comps=$(compgen -A file -- "$cur" )
-                        compopt -o filenames
-                fi
-        fi
-
-        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
-        return 0
-}
-complete -F _loginctl loginctl
-
-__journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC}
-                  ERRNO SYSLOG_{FACILITY,IDENTIFIER,PID} COREDUMP_EXE
-                  _{P,U,G}ID _COMM _EXE _CMDLINE
-                  _AUDIT_{SESSION,LOGINUID}
-                  _SYSTEMD_{CGROUP,SESSION,UNIT,OWNER_UID}
-                  _SELINUX_CONTEXT _SOURCE_REALTIME_TIMESTAMP
-                  _{BOOT,MACHINE}_ID _HOSTNAME _TRANSPORT
-                  _KERNEL_{DEVICE,SUBSYSTEM}
-                  _UDEV_{SYSNAME,DEVNODE,DEVLINK}
-                  __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP)
-
-_journalctl() {
-        local field_vals= cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
-        local -A OPTS=(
-                [STANDALONE]='-a --all --full
-                              -b --this-boot --disk-usage -f --follow --header
-                              -h --help -l --local --new-id128 -m --merge --no-pager
-                              --no-tail -q --quiet --setup-keys --this-boot --verify
-                              --version --list-catalog --update-catalog'
-                       [ARG]='-D --directory -F --field -o --output -u --unit --user-unit'
-                [ARGUNKNOWN]='-c --cursor --interval -n --lines -p --priority --since --until
-                              --verify-key'
-        )
-
-        if __contains_word "$prev" ${OPTS[ARG]} ${OPTS[ARGUNKNOWN]}; then
-                case $prev in
-                        --directory|-D)
-                                comps=$(compgen -d -- "$cur")
-                                compopt -o filenames
-                        ;;
-                        --output|-o)
-                                comps='short short-monotonic verbose export json cat'
-                        ;;
-                        --field|-F)
-                                comps=${__journal_fields[*]}
-                        ;;
-                        --unit|-u)
-                                comps=$(journalctl -F '_SYSTEMD_UNIT')
-                        ;;
-                        --user-unit)
-                                comps=$(journalctl -F '_SYSTEMD_USER_UNIT')
-                        ;;
-                        *)
-                                return 0
-                        ;;
-                esac
-                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
-                return 0
-        fi
-
-        if [[ $cur = -* ]]; then
-                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
-                return 0
-        elif [[ $cur = *=* ]]; then
-                mapfile -t field_vals < <(journalctl -F "${prev%=}" 2>/dev/null)
-                COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "${cur#=}") )
-        elif [[ $cur = /dev* ]]; then
-                compopt -o filenames
-                COMPREPLY=( $(compgen -f -- "${cur}") )
-        elif [[ $cur = /* ]]; then
-                # Append /dev/ to the list of completions, so that
-                # after typing /<TAB><TAB> the user sees /dev/ as one
-                # of the alternatives. Later on the rule above will
-                # take care of showing device files in /dev/.
-                mapfile -t field_vals < <(journalctl -F "_EXE" 2>/dev/null; echo '/dev/')
-                COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "${cur}") )
-                if [[ "${COMPREPLY[@]}" = '/dev/' ]]; then
-                    compopt -o filenames
-                    COMPREPLY=( $(compgen -f -- "${cur}") )
-                fi
-        elif [[ $prev = '=' ]]; then
-                mapfile -t field_vals < <(journalctl -F "${COMP_WORDS[COMP_CWORD-2]}" 2>/dev/null)
-                COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "$cur") )
-        else
-                compopt -o nospace
-                COMPREPLY=( $(compgen -W '${__journal_fields[*]}' -S= -- "$cur") )
-        fi
-}
-complete -F _journalctl journalctl
-
-_coredumpctl() {
-        local i verb comps
-        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
-        local OPTS='-h --help --version --no-pager --no-legend -o --output -F --field'
-
-        local -A VERBS=(
-            [LIST]='list'
-            [DUMP]='dump gdb'
-        )
-
-        if __contains_word "$prev" '--output -o'; then
-                comps=$( compgen -A file -- "$cur" )
-                compopt -o filenames
-        elif __contains_word "$prev" '--FIELD -F'; then
-                comps=$( compgen -W '${__journal_fields[*]}' -- "$cur" )
-        elif [[ $cur = -* ]]; then
-                comps=${OPTS}
-        elif __contains_word "$prev" ${VERBS[*]} &&
-           ! __contains_word ${COMP_WORDS[COMP_CWORD-2]} '--output -o -F --field'; then
-                compopt -o nospace
-                COMPREPLY=( $(compgen -W '${__journal_fields[*]}' -S= -- "$cur") )
-               return 0
-        elif [[ $cur = *=* ]]; then
-                mapfile -t field_vals < <(systemd-coredumpctl -F "${prev%=}" 2>/dev/null)
-                COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "${cur#=}") )
-                return 0
-        elif [[ $prev = '=' ]]; then
-                mapfile -t field_vals < <(systemd-coredumpctl -F "${COMP_WORDS[COMP_CWORD-2]}" 2>/dev/null)
-                comps=${field_vals[*]}
-        else
-                for ((i=0; i <= COMP_CWORD; i++)); do
-                        if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
-                                verb=${COMP_WORDS[i]}
-                                break
-                        fi
-                done
-
-                if [[ -z $verb ]]; then
-                        comps=${VERBS[*]}
-                elif __contains_word "$verb" ${VERBS[LIST]} ${VERBS[DUMP]}; then
-                        comps=''
-                fi
-        fi
-
-        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
-        return 0
-}
-complete -F _coredumpctl systemd-coredumpctl
-
-_timedatectl() {
-        local i verb comps
-        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
-        local OPTS='-h --help --version --adjust-system-clock --no-pager
-                    --no-ask-password -H --host'
-
-        if __contains_word "$prev" $OPTS; then
-                case $prev in
-                        --host|-H)
-                                comps=''
-                        ;;
-                esac
-                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
-                return 0
-        fi
-
-        if [[ $cur = -* ]]; then
-                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
-                return 0
-        fi
-
-        local -A VERBS=(
-                  [BOOLEAN]='set-local-rtc set-ntp'
-               [STANDALONE]='status set-time list-timezones'
-                [TIMEZONES]='set-timezone'
-                     [TIME]='set-time'
-        )
-
-        for ((i=0; i <= COMP_CWORD; i++)); do
-                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
-                        verb=${COMP_WORDS[i]}
-                        break
-                fi
-        done
-
-        if [[ -z $verb ]]; then
-                comps=${VERBS[*]}
-        elif __contains_word "$verb" ${VERBS[BOOLEAN]}; then
-                comps='true false'
-        elif __contains_word "$verb" ${VERBS[TIMEZONES]}; then
-                comps=$(command timedatectl list-timezones)
-        elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[TIME]}; then
-                comps=''
-        fi
-
-        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
-        return 0
-}
-complete -F _timedatectl timedatectl
-
-_localectl() {
-        local i verb comps
-        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
-        local OPTS='-h --help --version --no-convert --no-pager --no-ask-password
-                    -H --host'
-
-        if __contains_word "$prev" $OPTS; then
-                case $prev in
-                        --host|-H)
-                                comps=''
-                        ;;
-                esac
-                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
-                return 0
-        fi
-
-        if [[ $cur = -* ]]; then
-                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
-                return 0
-        fi
-
-        local -A VERBS=(
-               [STANDALONE]='status list-locales list-keymaps'
-                  [LOCALES]='set-locale'
-                  [KEYMAPS]='set-keymap'
-                      [X11]='set-x11-keymap'
-        )
-
-        for ((i=0; i <= COMP_CWORD; i++)); do
-                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
-                        verb=${COMP_WORDS[i]}
-                        break
-                fi
-        done
-
-        if [[ -z $verb ]]; then
-                comps=${VERBS[*]}
-        elif __contains_word "$verb" ${VERBS[LOCALES]}; then
-                comps=$(command localectl list-locales)
-        elif __contains_word "$verb" ${VERBS[KEYMAPS]}; then
-                comps=$(command localectl list-keymaps)
-        elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[X11]}; then
-                comps=''
-        fi
-
-        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
-        return 0
-}
-complete -F _localectl localectl
-
-_hostnamectl() {
-        local i verb comps
-        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
-        local OPTS='-h --help --version --transient --static --pretty
-                    --no-ask-password -H --host'
-
-        if [[ $cur = -* ]]; then
-                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
-                return 0
-        fi
-
-        local -A VERBS=(
-                [STANDALONE]='status'
-                     [ICONS]='set-icon-name'
-                      [NAME]='set-hostname'
-        )
-
-        for ((i=0; i <= COMP_CWORD; i++)); do
-                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
-                        verb=${COMP_WORDS[i]}
-                        break
-                fi
-        done
-
-        if [[ -z $verb ]]; then
-                comps=${VERBS[*]}
-        elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[ICONS]} ${VERBS[NAME]}; then
-                comps=''
-        fi
-
-        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
-        return 0
-}
-complete -F _hostnamectl hostnamectl
-
-__get_all_sysdevs() {
-        local -a devs=(/sys/bus/*/devices/*/ /sys/class/*/*/)
-        printf '%s\n' "${devs[@]%/}"
-}
-
-_udevadm() {
-        local i verb comps
-        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
-        local OPTS='-h --help --version --debug'
-
-        local -A VERBS=(
-                [INFO]='info'
-                [TRIGGER]='trigger'
-                [SETTLE]='settle'
-                [CONTROL]='control'
-                [MONITOR]='monitor'
-                [HWDB]='hwdb'
-                [TESTBUILTIN]='test-builtin'
-                [TEST]='test'
-        )
-
-        for ((i=0; $i <= $COMP_CWORD; i++)); do
-                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
-                 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
-                        verb=${COMP_WORDS[i]}
-                        break
-                fi
-        done
-
-        if [[ -z $verb  && $cur = -* ]]; then
-                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
-                return 0
-        fi
-
-        if [[ -z $verb ]]; then
-                comps=${VERBS[*]}
-
-        elif __contains_word "$verb" ${VERBS[INFO]}; then
-                if [[ $cur = -* ]]; then
-                        comps='--help --query= --path= --name= --root --attribute-walk --export-db --cleanup-db'
-                else
-                        comps=$( __get_all_sysdevs )
-                fi
-
-        elif __contains_word "$verb" ${VERBS[TRIGGER]}; then
-                comps='--help --verbose --dry-run --type= --action= --subsystem-match=
-                       --subsystem-nomatch= --attr-match= --attr-nomatch= --property-match=
-                       --tag-match= --sysname-match= --parent-match='
-
-        elif __contains_word "$verb" ${VERBS[SETTLE]}; then
-                comps='--help --timeout= --seq-start= --seq-end= --exit-if-exists= --quiet'
-
-        elif __contains_word "$verb" ${VERBS[CONTROL]}; then
-                comps='--help --exit --log-priority= --stop-exec-queue --start-exec-queue
-                       --reload --property= --children-max= --timeout='
-
-        elif __contains_word "$verb" ${VERBS[MONITOR]}; then
-                comps='--help --kernel --udev --property --subsystem-match= --tag-match='
-
-        elif __contains_word "$verb" ${VERBS[HWDB]}; then
-                comps='--help --update --test='
-
-        elif __contains_word "$verb" ${VERBS[TEST]}; then
-                if [[ $cur = -* ]]; then
-                        comps='--help --action='
-                else
-                        comps=$( __get_all_sysdevs )
-                fi
-
-        elif __contains_word "$verb" ${VERBS[TESTBUILTIN]}; then
-                      comps='blkid btrfs firmware hwdb input_id kmod net_id path_id usb_id uaccess'
-        fi
-
-        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
-        return 0
-}
-complete -F _udevadm udevadm



More information about the systemd-commits mailing list