about summary refs log tree commit diff
path: root/Completion/Debian/Type/_deb_packages
blob: d82515cef9c14533a9141de228ee50274b142b9f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#autoload

# Usage: _deb_packages expl...  (installed|deinstalled|xinstalled|held|uninstalled|avail|available|source)

_deb_packages_update_avail () {
  if ( [[ ${+_deb_packages_cache_avail} -eq 0 ]] ||
      _cache_invalid DEBS_avail ) && ! _retrieve_cache DEBS_avail;
  then
    _deb_packages_cache_avail=(
      ${(f)"$(apt-cache --generate pkgnames 2>/dev/null)"}
    )

    _store_cache DEBS_avail _deb_packages_cache_avail
  fi
  cachevar=_deb_packages_cache_avail
}

_deb_packages_update_installed () {
  if ( [[ ${+_deb_packages_cache_installed} -eq 0 ]] ||
      _cache_invalid DEBS_installed ) && ! _retrieve_cache DEBS_installed;
  then
    _deb_packages_cache_installed=()
    dpkg --get-selections | while read package state ; do
        [[ $state = (install|hold) ]] && _deb_packages_cache_installed+=$package
    done
    _store_cache DEBS_installed _deb_packages_cache_installed
  fi
  cachevar=_deb_packages_cache_installed
}

_deb_packages_update_held () {
  if ( [[ ${+_deb_packages_cache_held} -eq 0 ]] ||
      _cache_invalid DEBS_held ) && ! _retrieve_cache DEBS_held;
  then
    _deb_packages_cache_held=()
    dpkg --get-selections | while read package state ; do
        [[ $state = hold ]] && _deb_packages_cache_held+=$package
    done
    _store_cache DEBS_held _deb_packages_cache_held
  fi
  cachevar=_deb_packages_cache_held
}

_deb_packages_update_deinstalled () {
  if ( [[ ${+_deb_packages_cache_deinstalled} -eq 0 ]] ||
      _cache_invalid DEBS_deinstalled ) && ! _retrieve_cache DEBS_deinstalled;
  then
    _deb_packages_cache_deinstalled=()
    dpkg --get-selections | while read package state ; do
        [[ $state = deinstall ]] && _deb_packages_cache_deinstalled+=$package
    done
    _store_cache DEBS_deinstalled _deb_packages_cache_deinstalled
  fi
  cachevar=_deb_packages_cache_deinstalled
}

_deb_packages_update_xinstalled () {
  if ( [[ ${+_deb_packages_cache_xinstalled} -eq 0 ]] ||
      _cache_invalid DEBS_xinstalled ) && ! _retrieve_cache DEBS_xinstalled;
  then
    _deb_packages_cache_xinstalled=()
    dpkg --get-selections | while read package state ; do
        _deb_packages_cache_xinstalled+=$package
    done
    _store_cache DEBS_xinstalled _deb_packages_cache_xinstalled
  fi
  cachevar=_deb_packages_cache_xinstalled
}

_deb_packages_update_uninstalled () {
  _deb_packages_update_avail
  _deb_packages_update_installed
  if (( ! $+_deb_packages_cache_uninstalled )); then
    # Package lists too large to efficiently diff with zsh expansion
    _deb_packages_cache_uninstalled=(
      $( print -l $_deb_packages_cache_avail |
         fgrep -xvf =(print -l $_deb_packages_cache_installed) )
    )
  fi
  cachevar=_deb_packages_cache_uninstalled
}

_deb_packages_update_source () {
  if ( [[ ${+_deb_packages_cache_source} -eq 0 ]] ||
      _cache_invalid DEBS_source ) && ! _retrieve_cache DEBS_source;
  then
    _deb_packages_cache_source=(
      # requires apt >= 1.1.8
      # if dpkg --compare-versions "$(dpkg-query --show --showformat '${Version}\n' apt)" '>=' '1.1.8' ; then ...; else ...; fi
      ${(f)"$(/usr/lib/apt/apt-helper cat-file $(apt-get indextargets --format '$(FILENAME)' 'Created-By: Sources' 2>/dev/null) 2>/dev/null | sed -ne 's/^Package: //p' | uniq)"}
    )

    _store_cache DEBS_source _deb_packages_cache_source
  fi
  cachevar=_deb_packages_cache_source
}

_deb_packages () {
  local command="$argv[$#]" expl cachevar pkgset update_policy

  zstyle -s ":completion:*:*:$service:*" cache-policy update_policy
  if [[ -z "$update_policy" ]]; then
    zstyle ":completion:*:*:$service:*" cache-policy _debs_caching_policy
  fi

  [[ "$command" = (installed|deinstalled|xinstalled|held|uninstalled|avail|available|source) ]] || {
    _message "unknown command: $command"
    return
  }

  zstyle -s ":completion:${curcontext}:" packageset pkgset

  [[ "$pkgset" = (installed|deinstalled|xinstalled|held|uninstalled|avail|available|source) ]] || {
    pkgset="$command"
  }

  [[ "$pkgset" = "available" ]] && pkgset="avail"

  expl=("${(@)argv[1,-2]}")

  _deb_packages_update_$pkgset

  typeset -gH $cachevar

  _tags packages && compadd "$expl[@]" - "${(@P)cachevar}"
}

_debs_caching_policy () {
  # rebuild if cache is more than a week old
  local -a oldp
  oldp=( "$1"(mw+1) )
  (( $#oldp )) && return 0

  [[ /var/cache/apt/pkgcache.bin -nt "$1" ||
     /var/lib/dpkg/available -nt "$1" ]]
}

_deb_packages "$@"