Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH] update _dnf



This is a rather large update of the completion for dnf command.
I tried to include (almost) all the (sub)commands and options, but
I've ever used only small part of them.

Basic structure of the script, i.e., _dnf for general options and
_dnf_command for commands and their args/opts, is not modified.


_dnf: Add missing (general) options (--color, --repo, may others).

_dnf_command: Add missing completions for dnf commands (module,
repoquery, repository-packages, etc.), and improve some others.

_dnf_groups: New helper for 'package groups'. Cache for the groups is
also added because _dnf_group can be rather slow depending on the
repositories in use.
(But I don't know whether there is a reliable way to validate the cache)

Refactor helpers for 'repositories' and 'packages'.
Add missing descriptions.
Some other improvements.




diff --git a/Completion/Redhat/Command/_dnf b/Completion/Redhat/Command/_dnf
index 82b9b188f..5b721edd8 100644
--- a/Completion/Redhat/Command/_dnf
+++ b/Completion/Redhat/Command/_dnf
@@ -1,78 +1,268 @@
 #compdef dnf dnf-2 dnf-3
+#
+# based on dnf-4.2.18
+#
 
 _dnf_helper() {
-  compadd $($python_exec $helper "$@" -d 0 -q -C 2>/dev/null)
+  # Get the pathame of the python executable from the 1st line of dnf-2/dnf-3.
+  # Probably /usr/bin/python{2,3} or /usr/libexec/platform-python.
+  local shebang
+  read -u0 shebang < $(readlink -f /usr/bin/dnf)
+  local python_exec=${${shebang##\#! #}%% *}
+  local -a helper_script=(
+    'import sys'
+    'from dnf.cli.completion_helper import main'
+    'main(sys.argv[1:])'
+  )
+  $python_exec -c ${(j.;.)helper_script} "$@" "$PREFIX" \
+               -d 0 -q -C --assumeno --nogpgcheck 2>/dev/null </dev/null
 }
 
 _dnf_query_db() {
-  sqlite3 -batch -init /dev/null "$cache_file" "$1"
+  # $1: table name in the database ('available' or 'installed')
+  sqlite3 -batch -init /dev/null "$cache_file" \
+          "select pkg from $1 WHERE pkg LIKE '$PREFIX%$SUFFIX'"
 }
 
-_dnf_disabled_repos() {
-  _dnf_helper repolist disabled ""
+_dnf_repositories() {
+  # rquired option: -T (all|disabled|enabled)
+  local selected expl
+  zparseopts -D -E - T:=selected
+  selected=$selected[2]
+  _wanted $selected-repositories expl "$selected repository" \
+          compadd "$@" - $(_dnf_helper repolist --$selected)
 }
 
-_dnf_enabled_repos() {
-  _dnf_helper repolist enabled ""
+_dnf_packages() {
+  # rquired option: -T (all|available|installed|upgradable)
+  local selected pkgs expl
+  zparseopts -D -E - T:=selected
+  selected=$selected[2]
+  if [[ $selected = upgradable ]]; then
+    pkgs=( $(_dnf_helper upgrade) )
+  elif [[ -r $cache_file ]]; then
+    local table=$selected
+    # 'available' table contains both 'available' and 'installed' packages
+    [[ $selected = all ]] && table=available
+    pkgs=( $(_dnf_query_db $table) )
+    if [[ $selected = available ]]; then
+      local inst=( $(_dnf_query_db installed) )
+      pkgs=( ${pkgs:|inst} )  # remove installed packages
+    fi
+  else
+    pkgs=( $(_dnf_helper list --$selected) )
+  fi
+  _wanted $selected-packages expl "$selected package" compadd "$@" -a pkgs
 }
 
-_dnf_available_packages() {
-  if [ -r $cache_file ]; then
-    compadd $(_dnf_query_db "select pkg from available WHERE pkg LIKE \"$1%\"")
+_dnf_rpm_files() {
+  local expl
+  _wanted rpm-files expl 'rpm file' _files -g '(#i)*.rpm(-.)'
+}
+
+_dnf_packages_or_rpms() {
+  if [[ "$words[CURRENT]" = (*/*|\~*) ]]; then # if looks like a path name
+    _dnf_rpm_files
   else
-    _dnf_helper install "$1"
+    _dnf_packages "$@"
   fi
 }
 
-_dnf_installed_packages() {
-  if [ -r $cache_file ]; then
-    compadd $(_dnf_query_db "select pkg from installed WHERE pkg LIKE \"$1%\"")
-  else
-    _dnf_helper remove "$1"
+_dnf_groups_caching_policy() {
+  # TODO: Are there any reliable ways to validate the cache?
+  local -a newer=( "$1"(Nmw-1) )    # rebuild if more than a week old
+  return $#newer
+}
+
+_dnf_groups() {
+  local package_groups update_policy expl
+  zstyle -s ":completion:${curcontext}:" cache-policy update_policy
+  if [[ -z "$update_policy" ]]; then
+    zstyle ":completion:${curcontext}:" cache-policy _dnf_groups_caching_policy
+  fi
+  if _cache_invalid dnf-groups || ! _retrieve_cache dnf-groups; then
+    # this can be very slow
+    package_groups=( ${${${(M)${(f)"$(_call_program package-groups \
+                     $service group list -v 2>/dev/null)"}:# *}#*\(}%\)*} )
+    _store_cache dnf-groups package_groups
   fi
+  _wanted package-groups expl 'package group' compadd "$@" -a package_groups
 }
 
-_dnf_local_packages() {
-  _files -/ -g '(#i)*.rpm(-.)'
+_dnf_repoquery() {
+  local _h=''
+  # 'dnf deplist' is an alias for 'dnf repoquery --deplist'
+  [[ $words[1] = deplist ]] && _h='!'
+  local -a opts=( '(- *)--querytags[list tags recognized by --queryformat]' )
+  # Select options
+  opts+=(
+    '(-a --all)'{-a,--all}'[query all packages]'
+    '--arch=[limit results to specified architectures]:list of archs: '
+    '--available[limit results to available packages]'
+    '--disable-modular-filtering[include packages of inactive module streams]'
+    '(-f --file)'{-f+,--file=}'[limit results to packages which own specified file]:file:_files'
+    '--latest-limit=[limit results to latest packages of specified number]:number: '
+    '--recent[limit results to recently edited packages]'
+    '(--exactdeps)--alldeps[with --what{depends,requires}, also check non-explicit dependencies]'
+    '(--alldeps)--exactdeps[with --what{depends,requires}, check only explicit dependencies]'
+    '*--repo=[limit result to packages from the specified repo]: : _sequence _dnf_repositories -T all'
+    '--srpm[operate on the corresponding source RPM]'
+    '--whatdepends=[limit result to packages that require, enhance, recommend, suggest or supplement specified capability]:capability: '
+  )
+  for v in conflict enhance obsolete provide recommend require suggest supplement; do
+    opts+=( "--what${v}s=[limit result to packages that $v specified capability]:capability: " )
+  done
+  # Query options
+  opts+=(
+    '--location[show a location where package could be downloaded from]'
+    '--tree[display recursive tree of packages]'
+    $_h'--deplist[display list of all direct dependencies and their providers]'
+    '--recursive[query packages recursively]'
+    '--resolve[resolve capabilities to originating package(s)]'
+  )
+  # mutually exclusive Select options
+  opts+=(
+    + '(pkg_filter)'
+    '--duplicates[limit results to installed duplicate packages]'
+    '--installonly[limit results to installed installonly packages]'
+    '--unsatisfied[limit results to installed packages with unsatisfied dependencies]'
+    + '(list_group)'
+    '--installed[limit results to installed packages]'
+    '--extras[limit results to extra packages (not in any repos)]'
+    '--upgrades[limit results to upgrades for installed packages]'
+    '--unneeded[limit results to packages which are no longer needed]'
+    '--userinstalled[limit results to packages installed by user]'
+  )
+  # mutually exclusive Query options
+  opts+=(
+    + '(output_format)'
+    {-i,--info}'[show detailed info about the package]'
+    {-l,--list}'[show list of files in the packages]'
+    {-s,--source}'[show source RPM name]'
+    '--changelogs[print package changelogs]'
+    '--nvr[show found packages in name-version-release format]'
+    '--nevra[show found packages in name-epoch:version-release.architecture format]'
+    '--envra[show found packages in epoch:name-version-release.architecture format]'
+    {--qf=,--queryformat=}'[specify custom output format]:format: '
+    '--groupmember[display groups in which the package belongs]'
+    + '(pkg_attr)'
+    '--conflicts[display capabilities that the package conflicts with]'
+    '--depends[display capabilities that the package depends on, enhances, recommends, suggests or supplements]'
+    '--enhances[display capabilities that the package enhance]'
+    '--provides[display capabilities that the package provides]'
+    '--recommends[display capabilities that the package recommends]'
+    '--requires[display capabilities that the package depends on]'
+    '--requires-pre[display capabilities that the package depends on for running %pre script]'
+    '--suggests[display capabilities that the package suggests]'
+    '--supplements[display capabilities that the package supplements]'
+    '--obsoletes[display capabilities that the package obsoletes]'
+  )
+  _arguments : '*: : _dnf_packages -T all' $opts
 }
 
-_dnf() {
-  if [[ "$(readlink /usr/bin/dnf)" == "dnf-2" ]]; then
-    local python_exec="/usr/bin/python2"
+_dnf_repository_packages() {
+  if (( CURRENT == 2 )); then
+    _dnf_repositories -T all
+  elif (( CURRENT == 3 )); then
+    local -a subcmds=(
+      'check-update:check if updates are available in the repository'
+      'info:list description of packages in the repository'
+      'install:install all packages in the repository'
+      'list:list packages in the repository'
+      'move-to:reinstall all packages that are available in the repository'
+      'reinstall:run reinstall-old, or move-to if it fails'
+      'reinstall-old:reinstall all packages that were installed from the repository'
+      'remove:remove all packages installed from the repository'
+      'remove-or-distro-sync:sync packages with other repo if available there, or remove otherwise'
+      'remove-or-reinstall:reinstall packages if available in other repo, or remove otherwise'
+      'upgrade:update all packages in the repository'
+    )
+    _describe -t subcommands 'subcommand' subcmds && ret=0
+  elif [[ $words[3] = (info|list) ]]; then
+    if (( CURRENT == 4 )); then
+      _wanted options expl "option" compadd - --all --installed --available \
+                                    --extras --obsoletes --recent --upgrades
+    else
+      _dnf_packages -T all
+    fi
+  elif [[ $words[3] = install ]]; then
+      _dnf_packages -T available
+  elif [[ $words[3] = upgrade* ]]; then
+      _dnf_packages -T upgradable
   else
-    local python_exec="/usr/bin/python3"
+      _dnf_packages -T installed
   fi
-  local helper=$(${python_exec} -c "import dnf.cli; print('{}/completion_helper.py'.format(dnf.cli.__path__[0]))")
-  local cache_file="/var/cache/dnf/packages.db"
+}
 
-  _arguments -s \
-    '(- *)'{-h,--help}'[show the help message]' \
-    '--version[show dnf version]' \
-    '(-v --verbose)'{-v,--verbose}'[set verbose, show debug messages]' \
-    '(-q --quiet)'{-q,--quiet}'[show just the relevant content]' \
-    '--allowerasing[allow erasing of installed  packages]' \
-    '(-y --assumeyes)'{-y,--assumeyes}'[answer yes for all questions]' \
-    '(-C --cacheonly)'{-C,--cacheonly}'[run entirely from cache]' \
-    '(-c --config)'{-c,--config=}'[config file location]:config file:_files' \
-    '(-R --randomwait)'{-R,--randomwait=}'[maximum command wait time (in minutes)]:max wait time' \
-    '--releasever=[configure DNF for another release]:release' \
-    '--refresh[set metadata as expired before running the command]' \
-    '--nogpgcheck[skip checking GPG signatures on package]' \
-    '--installroot=[set install root]:install root:_files -/' \
-    '*--enablerepo=[enable one or more repositories]:repos to enable:_dnf_disabled_repos' \
-    '*--disablerepo=[disable one or more repositories]:disable repos:_dnf_enabled_repos' \
-    '*::dnf command:_dnf_command'
+_dnf() {
+  local cache_file="/var/cache/dnf/packages.db"
+  local -a opts=(
+    '(-6)-4[resolve to IPv4 addresses only]'
+    '(-4)-6[resolve to IPv6 addresses only]'
+    '*--advisory=[include packages for specified advisory]:advisory: '
+    '--allowerasing[allow erasing installed packages to resolve dependencies]'
+    '(-y --assumeyes)--assumeno[answer no for all questions]'
+    '(-b --best)'{-b,--best}'[try the best available package version]'
+    '--bugfix[include bugfix relevant packages]'
+    '*'{--bz=,--bzs=}'[include packages needed to fix the specified Bugzilla]:BZ ID: '
+    '(-C --cacheonly)'{-C,--cacheonly}"[run entirely from system cache, don't update cache]"
+    '--color=[control whether color is used]:when:(always never auto)'
+    '--comment=[add comment to transaction history]:comment: '
+    '(-c --config)'{-c+,--config=}'[specify configuration file]:config file:_files'
+    '*'{--cve=,--cves=}'[include packages needed to fix the specified CVE]:CVE ID: '
+    '(-d --debuglevel)'{-d+,--debuglevel=}'[specify debugging output level]:level (0-10): '
+    '--debugsolver[dump detailed solving results in file ./debugdata]'
+    '*--disableexcludes=[disable config file excludes]: : _alternative "sections\:section\:(all main)" "repositories\:repository\:_dnf_repositories -T all"'
+    '(--disable --set-disabled)'{--disable,--set-disabled}'[disable repos with config-manager command]'
+    '*--disableplugin=[disable specified plugins]:list of plugin names: '
+    '(--repo)*--disablerepo=[disable specified repos]: : _sequence _dnf_repositories -T enabled'
+    '(--downloaddir --destdir)'{--downloaddir=,--destdir=}'[redirect downloaded packages to the specified dir]:directory:_files -/'
+    '--downloadonly[only download the resolved packages]'
+    '(-e --errorlevel)'{-e+,--errorlevel=}'[specify error output level]:level (0-10): '
+    '(--enable --set-enabled)'{--enable,--set-enabled}'[enable repos with config-manager command]'
+    '--enableplugin=[enable specified plugins]:list of plugin names: '
+    '*--enablerepo=[enable additional repos]: : _sequence _dnf_repositories -T disabled'
+    '--enhancement[include enhancement relevant packages]'
+    '*'{-x+,--exclude=}'[exclude specified packages]: : _sequence _dnf_packages -T all'
+    '--forcearch=[force the use of the specified arch]:arch: '
+    '(-)'{-h,--help}'[show the help message]'
+    '--installroot=[set install root]:directory:_files -/'
+    '--newpackage[include newpackage relevant packages]'
+    '--noautoremove[disable removal of dependencies that are no longer used]'
+    '--nobest[do not limit transactions to best candidates]'
+    '--nodocs[do not install documentation]'
+    '--nogpgcheck[skip checking GPG signatures on packages]'
+    '--noplugins[disable all plugins]'
+    '--obsoletes[enable obsoletes processing logic]'
+    '(-q --quiet)'{-q,--quiet}'[show just the relevant content]'
+    '(-R --randomwait)'{-R+,--randomwait=}'[maximum command wait time]:max wait time (minutes): '
+    '--refresh[set metadata as expired before running the command]'
+    '--releasever=[configure DNF for another release]:release: '
+    '*--repofrompath=[specify additional repos]:repository_label,path_or_url: '
+    '(--disablerepo)*'{--repo=,--repoid=}'[enable just the specified repo]: : _sequence _dnf_repositories -T all'
+    '--rpmverbosity=[set RPM debug scriptlet output level]:debug level:(critical emergency error warn info debug)' 
+    '*--sec-severity=[include security relevant packages matching specified severity]:severity:(Critical Important Moderate Low)'
+    '--security[include security relevant packages]'
+    '*--setopt=[override config option]:repoid.option=value: '
+    '--skip-broken[resolve depsolve problems by skipping packages]'
+    '--show-duplicates[show duplicate packages in repos]'
+    '(-v --verbose)'{-v,--verbose}'[set verbose, show debug messages]'
+    '(- *)--version[show dnf version]'
+    '(-y --assumeyes --assumeno)'{-y,--assumeyes}'[answer yes for all questions]'
+  )
+  _arguments -s : $opts '*::dnf command:_dnf_command'
 }
 
 _dnf_command() {
-  local -a _dnf_cmds
-  _dnf_cmds=(
+  local -a dnf_cmds=(
+    'alias:define and manage aliases'
     "autoremove:automatically remove no longer required packages"
+    'check:report problems in local packagedb if any'
     "check-update:check for available package upgrades"
     "clean:remove cached data"
+    'deplist:alias for "repoquery --deplist"'
     "distro-sync:synchronize installed packages to the latest available versions"
     "downgrade:downgrade a package"
-    "erase:deprecated alias for remove"
     "group:display, or use, the groups information"
     "help:display a helpful usage message"
     "history:display, or use, the transaction history"
@@ -81,117 +271,280 @@ _dnf_command() {
     "list:list a package or groups of packages"
     "makecache:generate the metadata cache"
     "mark:mark or unmark installed packages as installed by user"
+    'module:interact with modules'
     "provides:find what package provides the given value"
     "reinstall:reinstall a package"
     "remove:remove a package or packages from your system"
     "repolist:display the configured software repositories"
+    'repoquery:search repos for packages and display info about them'
     "repository-packages:run commands on top of all packages in given repository"
     "search:search package details for the given string"
-    "update:deprecated alias for upgrade"
+    'shell:open an interactive shell'
+    'swap:replace a package by another'
     "updateinfo:display advisories about packages"
     "upgrade:upgrade a package or packages on your system"
-    "upgrade-to:upgrade a package on your system to the specified version"
+    'upgrade-minimal:upgrade only bugfix, enhancement or security fix'
   )
 
   if (( CURRENT == 1 )); then
-    _describe -t commands 'dnf command' _dnf_cmds || compadd "$@"
+    _describe -t dnf-commands 'dnf command' dnf_cmds
   else
-    local command="${${_dnf_cmds[(r)$words[1]:*]%%:*}}"
-    # Deal with any aliases
-    case $command in
-      erase) command="remove";;
-      whatprovides) command="provides";;
-      update) command="upgrade";;
+    local curcontext=$curcontext cur=$words[CURRENT] cmd tmp expl ret=1
+    # Deal with aliases (not comprehensive)
+    case $words[1] in
+      check-updgrade) cmd=check-update;;
+      distrosync|dsync) cmd=distro-sync;;
+      dg) cmd=downgrade;;
+      erase|rm) cmd=remove;;
+      groups|grp) cmd=group;;
+      hist) cmd=history;;
+      in) cmd=install;;
+      mc) cmd=makecache;;
+      prov|whatprovides) cmd=provides;;
+      rei) cmd=reinstall;;
+      repoinfo) cmd=repolist;;
+      rq) cmd=repoquery;;
+      se) cmd=search;;
+      sh) cmd=shell;;
+      update|up) cmd=upgrade;;
+      update-minimal|up-min) cmd=upgrade-minimal;;
+      *) cmd="${${dnf_cmds[(r)$words[1]:*]%%:*}}";;
     esac
+    (( $#cmd )) && curcontext="${curcontext%:*:*}:dnf-${cmd}:"
 
-    _is_path() {
-      [[ "$1" == *\/* ]] || [[ "$1" == \~* ]]
-    }
-
-    local cur=$words[CURRENT]
-    local prev=""
-    [[ $CURRENT > 2 ]] && prev=$words[$((CURRENT - 1))]
-
-    case $command in
-      install|upgrade|reinstall|info|check-update|distro-sync)
-        if ! _is_path "$cur"; then
-          _dnf_available_packages "$cur"
+    case $cmd in
+      alias)
+        if (( CURRENT == 2 )); then
+          _wanted subcommands expl 'subcommand' \
+                  compadd - list add delete && ret=0
+        elif [[ $words[2] = add ]]; then
+          _message "name='value'" && ret=0
         else
-          _dnf_local_packages
+          _message "alias name" && ret=0
         fi
         ;;
-      remove|downgrade)
-        if ! _is_path "$cur"; then
-          _dnf_installed_packages "$cur"
-        elif [[ "$command" == downgrade ]]; then
-          _dnf_local_packages
+      autoremove|downgrade|reinstall)
+        _dnf_packages_or_rpms -T installed && ret=0
+        ;;
+      check)
+        tmp=(
+          '--all:show all problems (default)'
+          '--dependencies:show dependency problems'
+          '--duplicates:show duplicate problems'
+          '--obsoleted:show obsoleted packages'
+          '--provides:show problems with provides'
+        )
+        _describe -t options 'option' tmp && ret=0
+        ;;
+      check-update)
+        if [[ $cur = -* ]]; then
+          _wanted options expl 'option' compadd - --changelogs && ret=0
+        else
+          _dnf_packages -T installed && ret=0
         fi
         ;;
-      list|clean)
-        _dnf_helper $command "$prev" "$cur"
+      clean)
+        tmp=(
+          'dbcache:remove chache files generated from the repository metadata'
+          'expire-cache:mark the repository metadata expired'
+          'metadata:remove the repository metadata'
+          'packages:remove any cached packages'
+          'all:clean all'
+        )
+        _describe -t targets 'clean target' tmp && ret=0
+        ;;
+      distro-sync)
+        _dnf_packages -T installed && ret=0
         ;;
       group)
-        local -a _dnf_group_cmds
-        _dnf_group_cmds=(
-          "summary:display groups overview"
-          "info:display package lists of a group"
-          "install:install packages from a group"
-          "list:list all matching groups"
-          "remove:mark the group removed"
-          "upgrade:upgrades the group and its packages"
-          "mark:mark a group for installation or removal"
-        )
         if (( CURRENT == 2 )); then
-          _describe -t commands 'dnf group command' _dnf_group_cmds
+          tmp=(
+            "summary:display groups overview"
+            "info:display package lists of a group"
+            "install:install packages from a group"
+            "list:list all matching groups"
+            "remove:remove packages in a group not used by other groups"
+            "upgrade:upgrade the group and its packages"
+            "mark:mark a group for installation or removal"
+          )
+          _describe -t subcommands 'subcommand' tmp && ret=0
+        elif (( CURRENT == 3 )) && [[ $cur = -* ]]; then
+          if [[ $words[2] == install ]]; then
+            _wanted options expl 'option' compadd - --with-optional && ret=0
+          elif [[ $words[2] == list ]]; then
+            tmp=(
+              '--available:show only available groups'
+              '--installed:show only installed groups'
+              '--hidden:show also hidden groups'
+              '--ids:show also ID of groups'
+            )
+            _describe -t options 'option' tmp && ret=0
+          fi
+        elif (( CURRENT == 3 )) && [[ $words[2] == mark ]]; then
+          _wanted subcommands expl 'subcommand' \
+                  compadd - install remove && ret=0
+        else
+          _dnf_groups && ret=0
         fi
         ;;
       help)
         if (( CURRENT == 2 )); then
-          _dnf_helper '_cmds' ''
+          _wanted commands expl 'dnf command or alias' \
+                  compadd - $(_dnf_helper '_cmds') && ret=0
         fi
         ;;
       history)
-        local -a _dnf_history_cmds
-        _dnf_history_cmds=(
-          "list:list transactions"
-          "info:describe the given transactions"
-          "redo:repeat the specified transaction"
-          "rollback:undo all since the given transaction"
-          "undo:undo transactions"
-          "userinstalled:list names of all packages installed by a user"
-        )
         if (( CURRENT == 2 )); then
-          _describe -t commands 'dnf history command' _dnf_history_cmds
+          tmp=(
+            "list:list transactions"
+            "info:describe the given transactions"
+            "redo:repeat the specified transaction"
+            "rollback:undo all since the given transaction"
+            "undo:undo transactions"
+            "userinstalled:list all packages installed by users"
+          )
+          _describe -t subcommands 'subcommand' tmp && ret=0
+        elif [[ $words[2] != userinstalled ]]; then
+          _message 'transaction' && ret=0
+        fi
+        ;;
+      info|list)
+        if (( CURRENT == 2 )); then
+          if [[ $cur = -* ]]; then
+            tmp=( --all --available --installed --extras
+                  --obsoletes --upgrades --autoremove --recent )
+            _wanted options expl 'option' compadd -a tmp
+          else
+            _dnf_packages -T all && ret=0
+          fi
+        elif [[ $words[2] == --(all|recent) ]]; then
+          _dnf_packages -T all && ret=0
+        elif [[ $words[2] == --available ]]; then
+          _dnf_packages -T available && ret=0
+        elif [[ $words[2] == --upgrades ]]; then
+          _dnf_packages -T upgradable && ret=0
         else
-          _dnf_helper $command "$prev" "$cur"
+          _dnf_packages -T installed && ret=0
         fi
         ;;
+      install)
+        _dnf_packages_or_rpms -T available && ret=0
+        ;;
       makecache)
         if (( CURRENT == 2 )); then
-          _values 'make cache' 'timer'
+          _describe -t options 'option' \
+                    '(--timer:"be more resource-aware")' && ret=0
         fi
         ;;
       mark)
         if (( CURRENT == 2 )); then
-          _values 'mark' 'install' 'remove'
+          _wanted subcommands expl 'mark as' \
+                  compadd - install remove group && ret=0
+        else
+          _dnf_packages -T installed && ret=0
+        fi
+        ;;
+      module)
+        if (( CURRENT == 2 )); then
+          tmp=(
+            'install:install a module profile including its packages'
+            'update:update packages associated with an active module stream'
+            'remove:remove installed module profiles and their packages'
+            'enable:enable a module stream'
+            'disable:disable a module with all its streams'
+            'reset:reset module state, no longer enabled or disabled'
+            'provides:list modular packages, with modules they belong to'
+            'list:list all (or selected) module streams, profiles and states'
+            'info:print detailed information about a module'
+            'repoquery:list packages belonging to a module'
+          )
+          _describe -t subcommands 'subcommand' tmp && ret=0
+        elif (( CURRENT == 3 )) && [[ $cur = -* ]]; then
+          if [[ $words[2] = remove ]]; then
+            tmp=( --all )
+          elif [[ $words[2] = list ]]; then
+            tmp=( --all --enabled --disabled --installed )
+          elif [[ $words[2] = info ]]; then
+            tmp=( --profile )
+          elif [[ $words[2] = repoquery ]]; then
+            tmp=( --available --installed )
+          fi
+          _wanted options expl 'option' compadd -a tmp && ret=0
         else
-          _dnf_installed_packages "$cur"
+          # TODO: complete module name or spec
+          if [[ $words[2] = provides ]]; then
+            _dnf_packages -T all && ret=0
+          elif [[ $words[2] = (disable|reset|list) ]]; then
+            _message 'module name' && ret=0
+          else
+            _message 'module spec' && ret=0
+          fi
         fi
         ;;
       provides)
-        _files
+        _files && ret=0
+        ;;
+      remove)
+        if (( CURRENT == 2 )) && [[ $cur = -* ]]; then
+          _wanted options expl 'option' \
+                  compadd - --duplicates --oldinstallonly && ret=0
+        elif [[ $words[2] != -* ]]; then
+          _dnf_packages_or_rpms -T installed && ret=0
+        fi
         ;;
       repolist)
         if (( CURRENT == 2 )); then
-          _values 'repolist' 'enabled' 'disabled' 'all'
+          _wanted options expl 'option' \
+                  compadd - --enabled --disabled --all && ret=0
         fi
         ;;
+      repoquery|deplist)
+        _dnf_repoquery && ret=0
+        ;;
+      repository-packages)
+        _dnf_repository_packages
+        ;;
       search)
+        if [[ $cur = -* ]]; then
+          _wanted options expl 'option' compadd - --all && ret=0
+        else
+          _message 'keywords' && ret=0
+        fi
+        ;;
+      shell)
         if (( CURRENT == 2 )); then
-          _values 'search' 'all'
+          _wanted script-files expl 'script file' _files && ret=0
         fi
         ;;
+      swap)
+        case $CURRENT in
+          2) _dnf_packages -T installed && ret=0 ;;
+          3) _dnf_packages -T available && ret=0 ;;
+        esac
+        ;;
+      updateinfo)
+        tmp=(
+          '--with-cve[print only advisories referencing CVE]'
+          '--with-bz[print only advisories referencing bugzilla]'
+          + '(output-type)'
+          '--summary[display just counts of advisories of each type]'
+          '--list[display llit of advisories]'
+          '--info[display detailed information of advisories]'
+          + '(availability)'
+          '--avaiable[limit to advisories about newer versions of installed packages]'
+          '--installed[limit to advisories about equal or older versions of installed packages]'
+          '--updates[limit to advisories about newer and available versions of installed packages]'
+        )
+        _arguments '*: : _dnf_packages -T installed' $tmp && ret=0
+        ;;
+      upgrade)
+        _dnf_packages_or_rpms -T upgradable && ret=0
+        ;;
+      upgrade-minimal)
+        _dnf_packages -T upgradable && ret=0
+        ;;
     esac
+    return ret
   fi
 }
 





Messages sorted by: Reverse Date, Date, Thread, Author