I rely on guix shell $pkg -- $pkg
a lot to resolve situations where $pkg is not found on my system:
wilko@rembrandt ~$ hello
bash: hello: command not found
wilko@rembrandt ~$ guix shell hello -- hello
Hello, world!
but always having to type guix shell $pkg -- $pkg
is quite cumbersome. The comma-hack Ludo shared a few days ago (Ludovic Courtès : « # #Guix trick borrowed from Nix folks: the comma … » - Aquilepouet) would reduce this to , $pkg
which already seems better. So I took this as inspiration and came up with a command_not_found_handler
:
command_not_found_handler() {
printf "zsh: %s: command not found (trying to resolve)\n" "$1" >&2
pkg="$(guix locate "$1" 2>/dev/null | grep /bin/ | head -1 | cut -d@ -f1)"
guix shell ${pkg:-$1} -- "$@" || {
return 127
}
}
in my .zshrc, that:
- checks if a package providing a command is available in the local store (as
guix locate
is only able to query packages that are present there). - if it’s available it calls
guix shell
with the corresponding package, if it’s not, it tries to doguix shell $pkg -- $pkg
as a last resort; if both fails it exits non-zero with 127 as its exit-code (standard behaviour of the originalcommand_not_found_handler
). - so a command which is handled by this is either resolved and run by
guix shell
or ultimately not found.
In practice it looks like this:
[/home/wilko/Downloads]% hello
zsh: hello: command not found (trying to resolve)
Hello, world!
for packages that are already in store but not available in the current context. And:
[/home/wilko/Downloads]% xsv
zsh: xsv: command not found (trying to resolve)
substitute: updating substitutes from 'https://bordeaux.guix.gnu.org'... 100.0%
The following derivation will be built:
/gnu/store/38r81gvvwav6bfwa7hjga6afh16in33p-profile.drv
0.0 MB will be downloaded
xsv-0.13.0 936KiB 1.5MiB/s 00:01 ▕██████████████████▏ 100.0%
building CA certificate bundle...
listing Emacs sub-directories...
building fonts directory...
building directory of Info manuals...
building profile with 1 package...
xsv is a suite of CSV command line utilities.
Please choose one of the following commands:
cat Concatenate by row or column
count Count records
fixlengths Makes all records have same length
flatten Show one field per line
fmt Format CSV output (change field delimiter)
frequency Show frequency tables
headers Show header names
help Show this usage message.
index Create CSV index for faster access
input Read CSV data with special quoting rules
join Join CSV files
sample Randomly sample CSV data
search Search CSV data with regexes
select Select columns from CSV
slice Slice records from CSV
sort Sort CSV data
split Split CSV data into many files
stats Compute basic statistics
table Align CSV data into columns
for packages that aren’t available locally and have to be fetched first.
I should add a disclaimer that this unfortunately doesn’t cover all cases, as sometimes binaries are named differently than the package itself or are found in different outputs of a package. So:
[/home/wilko/Downloads]% guix shell bind:utils -- dig +short systemcrafters.net
188.114.96.3
188.114.97.3
works, but:
[/home/wilko/Downloads]% dig +short systemcrafters.net
zsh: dig: command not found (trying to resolve)
guix shell: error: dig: command not found
hint: Did you mean 'mdig'?
would not.
Hope this is helpful for other folks as well!