The fuck

So I am notorious as a clumsy typist, especially in instances like demos or on stage at conferences. I’ve also been known to comment indelicately about my mistakes in front of large audiences. So when I stumbled across The Fuck it was like I had found my keyboard people.

Note
Yes. I know. To some of you “fuck” is a bad word. It’s not to me but see later about how you can alias it if you’re concerned.

The Fuck is a self-described “magnificent app”, inspired by a tweet from @liamosaur, that automatically corrects previous, invalid, console commands. Like so:

1
2
3
4
5
6
7
8
9
$ apt install vim                                                                                               E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
$ fuck
sudo apt install vim [enter/↑/↓/ctrl+c]
Reading package lists... Done
Building dependency tree
Reading state information... Done
vim is already the newest version (2:8.0.1453-1ubuntu1).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

You can see here we’ve run apt without sudo, which sensibly Ubuntu is like “nah dude”. We then run The Fuck, using its stock alias fuck, and it will correct our previous shell command, by prefixing sudo, and offer to re-run it. The Fuck works out how to correct commands based on rules (more on this later) and can correct a wide variety of mistakes including common mistypes of Git commands, binaries, flags, and arguments.

Installing The Fuck

The Fuck requires Python (3.4+) and can be installed via pip.

1
2
3
$ sudo apt update
$ sudo apt install python3-dev python3-pip
$ sudo pip3 install thefuck

Or on OS X

1
$ brew install thefuck

Configuring The Fuck

You then need to include it in your shell’s startup, for example add the following to .bashrc (or profile, or…):

1
eval $(thefuck --alias)

Alternatively, if you have Fish then you can add:

1
thefuck --alias fu | source

Other shells are also documented in the wiki.

The --alias option allows you to specify an alias other than the default fuck. In my Fish shell I alias fuck to fu, a shorter and more poignant reminder of my mistype. This also allows folks who don’t like the idea of an expletive on the command line rename it to something more palatable.

1
thefuck --alias sugar | source

After adding this to your shell, you’ll need to run or source the command or start a new shell to enable The Fuck.

You can also skip the confirmation step, if you’re feeling brave (I am generally not) by using the --yeah (or -y) flag.

1
thefuck --yeah --alias sugar | source

The Fuck is very configurable. You can create (or edit) a configuration file at: $XDG_CONFIG_HOME/thefuck/settings.py (generally ~/.config) and control The Fuck’s settings.

Adding you own rules

You can also add your own rules. You create rules in the ~/.config/thefuck/rules directory in a file suffixed with .py. For example, ~/.config/thefuck/rules/my_awesome_rules.py. Rules are defined as Python functions and must contain two functions: match, which matches specific output from a command, and get_new_command, which returns the restructured (fixed) command.

There are a variety of modifiers and other configuration you can also provide to tweak the rule too. You can also import a series of util functions and application- or OS-specific helpers that make writing a rule easier.

Here’s a rule that recognizes when you’ve mistyped a Microsoft Azure az binary sub-command.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import re

from thefuck.utils import for_app, replace_argument

INVALID_CHOICE = "(?=az)(?:.*): '(.*)' is not in the '.*' command group."
OPTIONS = "^The most similar choice to '.*' is:\n\s*(.*)$"


@for_app('az')

def match(command):
    return "is not in the" in command.output and "command group" in command.output


def get_new_command(command):
    mistake = re.search(INVALID_CHOICE, command.output).group(1)
    options = re.findall(OPTIONS, command.output, flags=re.MULTILINE)
    return [replace_argument(command.script, mistake, o) for o in options]

Our rule is Python, so we can import Python libraries, here the regex library re. We’ve also imported two utilities: for_app, which matches our rule only against a specific application, and replace_argument, which is a util for replacing a command line argument.

We then specify some regular expressions, one to match when an invalid choice is made and the second to match the correct choice which is specified in the incorrect command’s output.

We then use the for_app util to match only on the az binary.

Our match function ensures The Fuck is only triggered when you type in an incorrect az sub-command by matching text in the command’s output. The command itself is contained in the command variable, which The Fuck will pass to the rule, and the output is contained in command.output

Tip
The command.script variable contains the command actually executed.

The get_new_command function finds our mistake, finds the corrected command(s), and returns them. When you run The Fuck you’ll now be prompted with an updated command line, assuming it matched a correct option. If more than one option matched, you can use the up and down arrows to select the specific command returned by the suggested list of corrections.

Let’s see it in action.

1
2
3
4
$ az providers show -n Microsoft.ContainerService
az: 'providers' is not in the 'az' command group. See 'az --help'.
The most similar choice to 'providers' is:
    provider

And then running fuck:

1
$ fu                                                                                                                az provider show -n Microsoft.ContainerService [enter/↑/↓/ctrl+c]

Woot! Correct command returned. Whilst The Fuck is perhaps named a little oddly, it’s really useful for those of us who typo our way through the command line.