9 unstable releases (4 breaking)

0.5.1 Feb 11, 2024
0.5.0 Dec 27, 2023
0.4.2 Aug 24, 2023
0.3.0 May 20, 2023
0.1.0 Jan 31, 2022

#6 in #shell-environment

GPL-3.0-or-later

295KB
5K SLoC

cnf - A "command not found" TUI-application

application view

cnf provides the necessary translations to allow finding commands from various sources. Check out the list of available providers and the list of available environments to get an idea of how cnf may help you.

The basic working principle is that cnf, once invoked, will query all configured providers (see above) in all configured environments (see above) and show the results in an interactive terminal-based UI, organized in a tree-like structure. This list can be navigated to inspect, install and execute results.

This process can be invoked by explicitly calling the cnf executable, or implicitly/automatically by hooking into your shell (currently supports bash and zsh). Refer to the output of cnf --hooks bash/zsh for further information.

Usage examples

The examples below assume you have already installed cnf and the necessary shell hooks, described below. If you haven't, you must prepend cnf to the relevant command lines.

cnf with toolbx

If you are a toolbx user, cnf can support you in transparently forwarding commands between your host and a chosen toolbx container. Here's an example of how cnf can replace toolbox run:

# Before
$ htop
htop: command not found
$ toolbox run htop
# After
$ htop
# ... navigate the UI and execute

It also works the other way around. Assume you're currently inside your toolbx and want to execute a command on your host. Here's an example of how cnf can replace flatpak-spawn --host:

# Before
⬢ $ podman run hello-world
podman: command not found
⬢ $ flatpak-spawn --host podman run hello-world
# After
⬢ $ podman run hello-world
# ... navigate the UI and execute

Command aliases

By default, cnf shows an interactive TUI with all results, allowing the user to browse results and select the appropriate one. When calling the same command repeatedly, interacting with the UI each time quickly becomes annoying.

Command aliases are a mechanism that aims to solve two problems:

  1. Eliminate user-interaction with the UI for certain commands (according to user choice)
  2. Provide commands that aren't available in the current environment (e.g. your host OS) by calling them in another environment (e.g. toolbx/distrobox).

To learn more, visit the alias documentation.

Installation

There are no pre-built application binaries yet, so you'll have to install via cargo:

$ cargo install --locked cnf

If you want to automatically run cnf whenever a specific command isn't found, extend your .bashrc/.zshrc like this:

# If you're using bash, append this to '~/.bashrc'
eval "$(cnf --hooks bash)"
# Likewise for zsh, append this to '~/.zshrc'
eval "$(cnf --hooks zsh)"

If you don't know which shell you're currently using, the output of the following command should tell you:

basename $(readlink -f /proc/$$/exe)

Now restart your shell or open a new shell tab/window and try it out!

Configuration

When you run this command for the first time, it will create a default configuration file in ~/.config/cnf/cnf.yml. The options should be self-explanatory. If not, refer to the cnf config module.

CNF and sudo

When running commands with sudo, you will realize that the default "command not found" text is displayed. That is because sudo performs its own executable lookups, and if it can't find the command you were asking it to execute, it will print this error and exit. To fix this, you must call sudo through cnf manually:

$ sudo foobar
sudo: foobar: command not found
$ cnf !!

The !! will be expanded by your shell to the last command you executed, verbatim, including all of its arguments. This way you're forwarding the command to cnf directly. In other words: You're doing the shell hooks job, but manually.

Dependencies

~17–31MB
~449K SLoC