fish-shell/share/functions/__fish_print_apt_packages.fish
Mahmoud Al-Qudsi 96deaae7d8 completions/apt: Read from the dpkg cache directly
I have no idea why `apt-cache --no-generate show` is so slow since it basically
dumps the contents of the cache file located at `/var/lib/dpkg/status`. We are
technically bypassing any waits on the cache lock file so this may produce
incorrect results if the cache is being regenerated in the moment, but that's a
small price to pay and the results are likely confined to simply not generating
comprehensive results.

With this change, we no longer need to truncate results to the first n matches
and we no longer only print packages beginning with the commandline argument
enabling fish's partial completions logic to offer less-perfect suggestions when
no better options are available.

Even though we are generating more usable completions, we still trounce the old
performance by leaps and bounds:

```
Benchmark #1: fish -c "complete -C\"apt install ac\""
  Time (mean ± σ):      2.165 s ±  0.033 s    [User: 267.0 ms, System: 1932.2 ms]
  Range (min … max):    2.136 s …  2.256 s    10 runs

Benchmark #2: build/fish -c "complete -C\"apt install ac\""
  Time (mean ± σ):     111.1 ms ±   1.8 ms    [User: 38.9 ms, System: 72.9 ms]
  Range (min … max):   108.2 ms … 114.9 ms    26 runs

Summary
  'build/fish -c "complete -C\"apt install ac\""' ran
   19.49 ± 0.44 times faster than 'fish -c "complete -C\"apt install ac\""'
```
2023-02-05 16:30:34 -06:00

60 lines
1.1 KiB
Fish

function __fish_print_apt_packages
argparse --name=__fish_print_packages i/installed -- $argv
or return
switch (commandline -ct)
case '-**'
return
end
set -l search_term (commandline -ct | string replace -ar '[\'"\\\\]' '' | string lower)
if ! test -f /var/lib/dpkg/status
return 1
end
# Do not not use `apt-cache` as it is sometimes inexplicably slow (by multiple orders of magnitude).
if not set -q _flag_installed
awk -e '
BEGIN {
FS=": "
}
/^Package/ {
pkg=$2
}
/^Description(-[a-zA-Z]+)?:/ {
desc=$2
if (index(pkg, "'$search_term'") > 0) {
print pkg "\t" desc
}
pkg="" # Prevent multiple description translations from being printed
}' < /var/lib/dpkg/status
else
awk -e '
BEGIN {
FS=": "
}
/^Package/ {
pkg=$2
}
/^Status/ {
installed=0
if ($2 ~ /(^|\s)installed/) {
installed=1
}
}
/^Description(-[a-zA-Z]+)?:/ {
desc=$2
if (installed == 1 && index(pkg, "'$search_term'") > 0) {
print pkg "\t" desc
installed=0 # Prevent multiple description translations from being printed
}
}' < /var/lib/dpkg/status
end
end