# cnf - A "command not found" TUI-application ![application view](assets/cnf_screenshot.png) `cnf` provides the necessary translations to allow finding commands from various sources. Check out the [list of available providers][all-providers] and the [list of available environments][all-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`: ```bash # 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`: ```bash # 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][alias-docs]. ## Installation There are no pre-built application binaries yet, so you'll have to install via [`cargo`][cargo]: ```shell $ cargo install --locked cnf ``` If you want to automatically run `cnf` whenever a specific command isn't found, extend your `.bashrc`/`.zshrc` like this: ```shell # 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: ```shell 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-config]. ## 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: ```shell $ 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*. [all-providers]: https://docs.rs/cnf-lib/latest/cnf_lib/provider/enum.Provider.html [all-environments]: https://docs.rs/cnf-lib/latest/cnf_lib/environment/enum.Environment.html [cnf-config]: https://docs.rs/cnf/latest/cnf/config/index.html [cargo]: https://doc.rust-lang.org/cargo/ [alias-docs]: https://docs.rs/cnf/latest/cnf/alias/index.html