Tech Nuggets (3) 日本語版はこちら

Disable fish_command_not_found

Posted:

tl;dr

When a command is not found, the new built-in command fish_command_not_found query package manager every time. It's a kind of nice but I don't need it. To prevent this, I created empty function file ~/.config/fish/functions/fish_command_not_found.fish.

All you need to know is written in here:
fish_command_not_found - what to do when a command wasn't found — fish-shell 3.2.1 documentation

Log

Done with the following environment.

$ uname -srmo
Linux 5.11.9-arch1-1 x86_64 GNU/Linux

$ fish --version
fish, version 3.2.1

Background

When a command is not found, below warnings are now displayed.

$ FBReader
fish: Unknown command: FBReader
warning: database file for 'core' does not exist (use '-Fy' to download)
warning: database file for 'extra' does not exist (use '-Fy' to download)
warning: database file for 'community' does not exist (use '-Fy' to download)
warning: database file for 'multilib' does not exist (use '-Fy' to download)

By executing # pacman -Fy as written, these warnings disappear and message will look like this:

$ FBReader
fish: Unknown command: FBReader
usr/bin/FBReader is owned by community/fbreader 0.99.4-9

Initially, I was satisfied with this, but then I wondered who was printing and querying. I looked it up and found it all in the official documentation.

When fish tries to execute a command and can't find it, it invokes this function.

It can print a message to tell you about it, and it often also checks for a missing package that would include the command.

...

This command was introduced in fish 3.2.0. Previous versions of fish used the "fish_command_not_found" event instead.

fish_command_not_found - what to do when a command wasn't found — fish-shell 3.2.1 documentation

In my system, fish_command_not_found is defined as below:

$ type fish_command_not_found
fish_command_not_found is a function with definition
# Defined in /usr/share/fish/functions/fish_command_not_found.fish @ line 61
function fish_command_not_found
        set -l paths $argv[1]
        # If we've not been given an absolute path, try $PATH as the starting point,
        # otherwise pacman will try *every path*, and e.g. bash-completion
        # isn't helpful.
        string match -q '/*' -- $argv[1]; or set paths $PATH/$argv[1]
        # Pacman only prints the path, so we still need to print the error.
        __fish_default_command_not_found_handler $argv[1]
        pacman -F $paths

end

Disabling

Querying package manager is nice user friendly feature, but I don't need it. The delay due to querying is more disturbing to me.

According to the document:

When you leave fish_command_not_found undefined (e.g. by adding an empty function file) or explicitly call __fish_default_command_not_found_handler, fish will just print a simple error.

fish_command_not_found - what to do when a command wasn't found — fish-shell 3.2.1 documentation


$ touch ~/.config/fish/functions/fish_command_not_found.fish

$ FBReader
fish: Unknown command: FBReader

🎉