See https://github.com/nvbn/thefuck/pull/744 for context. I'm personally okay with dropping Python 3.3 support, but I'd like to at least get the tests working while we decide on that.
The Fuck
Magnificent app which corrects your previous console command, inspired by a @liamosaur tweet.
The Fuck is too slow? Try experimental instant mode!
Few more examples:
➜ apt-get 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-get install vim [enter/↑/↓/ctrl+c]
[sudo] password for nvbn:
Reading package lists... Done
...
➜ git push
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin master
➜ fuck
git push --set-upstream origin master [enter/↑/↓/ctrl+c]
Counting objects: 9, done.
...
➜ puthon
No command 'puthon' found, did you mean:
Command 'python' from package 'python-minimal' (main)
Command 'python' from package 'python3' (main)
zsh: command not found: puthon
➜ fuck
python [enter/↑/↓/ctrl+c]
Python 3.4.2 (default, Oct 8 2014, 13:08:17)
...
➜ git brnch
git: 'brnch' is not a git command. See 'git --help'.
Did you mean this?
branch
➜ fuck
git branch [enter/↑/↓/ctrl+c]
* master
➜ lein rpl
'rpl' is not a task. See 'lein help'.
Did you mean this?
repl
➜ fuck
lein repl [enter/↑/↓/ctrl+c]
nREPL server started on port 54848 on host 127.0.0.1 - nrepl://127.0.0.1:54848
REPL-y 0.3.1
...
If you are not scared to blindly run the changed command, there is a require_confirmation
settings option:
➜ apt-get 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-get install vim
[sudo] password for nvbn:
Reading package lists... Done
...
Requirements
- python (3.3+)
- pip
- python-dev
Installation
On OS X you can install The Fuck
with Homebrew:
brew install thefuck
On Ubuntu you can install The Fuck
with:
sudo apt update
sudo apt install python3-dev python3-pip
sudo pip3 install thefuck
On other systems you can install The Fuck
with pip
:
pip install thefuck
Or using an OS package manager (OS X, Ubuntu, Arch).
#
You should place this command in your .bash_profile
, .bashrc
, .zshrc
or other startup script:
eval $(thefuck --alias)
# You can use whatever you want as an alias, like for Mondays:
eval $(thefuck --alias FUCK)
Or in your shell config (Bash, Zsh, Fish, Powershell, tcsh).
Changes will be available only in a new shell session.
To make them available immediately, run source ~/.bashrc
(or your shell config file like .zshrc
).
If you want to run fixed command without confirmation you can use -y
option:
fuck -y
If you want to fix commands recursively until success you can use -r
option:
fuck -r
Update
pip install thefuck --upgrade
Aliases changed in 1.34.
How it works
The Fuck tries to match a rule for the previous command, creates a new command using the matched rule and runs it. Rules enabled by default are as follows:
ag_literal
– adds-Q
toag
when suggested;aws_cli
– fixes misspelled commands likeaws dynamdb scan
;cargo
– runscargo build
instead ofcargo
;cargo_no_command
– fixes wrongs commands likecargo buid
;cd_correction
– spellchecks and correct failed cd commands;cd_mkdir
– creates directories before cd'ing into them;cd_parent
– changescd..
tocd ..
;chmod_x
– add execution bit;composer_not_command
– fixes composer command name;cp_omitting_directory
– adds-a
when youcp
directory;cpp11
– adds missing-std=c++11
tog++
orclang++
;dirty_untar
– fixestar x
command that untarred in the current directory;dirty_unzip
– fixesunzip
command that unzipped in the current directory;django_south_ghost
– adds--delete-ghost-migrations
to failed because ghosts django south migration;django_south_merge
– adds--merge
to inconsistent django south migration;docker_not_command
– fixes wrong docker commands likedocker tags
;dry
– fixes repetitions likegit git push
;fab_command_not_found
– fix misspelled fabric commands;fix_alt_space
– replaces Alt+Space with Space character;fix_file
– opens a file with an error in your$EDITOR
;gem_unknown_command
– fixes wronggem
commands;git_add
– fixes "pathspec 'foo' did not match any file(s) known to git.";git_add_force
– adds--force
togit add <pathspec>...
when paths are .gitignore'd;git_bisect_usage
– fixesgit bisect strt
,git bisect goood
,git bisect rset
, etc. when bisecting;git_branch_delete
– changesgit branch -d
togit branch -D
;git_branch_exists
– offersgit branch -d foo
,git branch -D foo
orgit checkout foo
when creating a branch that already exists;git_branch_list
– catchesgit branch list
in place ofgit branch
and removes created branch;git_checkout
– fixes branch name or creates new branch;git_diff_no_index
– adds--no-index
to previousgit diff
on untracked files;git_diff_staged
– adds--staged
to previousgit diff
with unexpected output;git_fix_stash
– fixesgit stash
commands (misspelled subcommand and missingsave
);git_flag_after_filename
– fixesfatal: bad flag '...' after filename
git_help_aliased
– fixesgit help <alias>
commands replacing with the aliased command;git_not_command
– fixes wrong git commands likegit brnch
;git_pull
– sets upstream before executing previousgit pull
;git_pull_clone
– clones instead of pulling when the repo does not exist;git_pull_uncommitted_changes
– stashes changes before pulling and pops them afterwards;git_push
– adds--set-upstream origin $branch
to previous failedgit push
;git_push_different_branch_names
– fixes pushes when local brach name does not match remote branch name;git_push_pull
– runsgit pull
whenpush
was rejected;git_push_without_commits
– Creates an initial commit if you forget and onlygit add .
, when setting up a new project;git_rebase_no_changes
– runsgit rebase --skip
instead ofgit rebase --continue
when there are no changes;git_remote_delete
– replacesgit remote delete remote_name
withgit remote remove remote_name
;git_rm_local_modifications
– adds-f
or--cached
when you try torm
a locally modified file;git_rm_recursive
– adds-r
when you try torm
a directory;git_rm_staged
– adds-f
or--cached
when you try torm
a file with staged changesgit_rebase_merge_dir
– offersgit rebase (--continue | --abort | --skip)
or removing the.git/rebase-merge
dir when a rebase is in progress;git_remote_seturl_add
– runsgit remote add
whengit remote set_url
on nonexistant remote;git_stash
– stashes your local modifications before rebasing or switching branch;git_stash_pop
– adds your local modifications before popping stash, then resets;git_tag_force
– adds--force
togit tag <tagname>
when the tag already exists;git_two_dashes
– adds a missing dash to commands likegit commit -amend
orgit rebase -continue
;go_run
– appends.go
extension when compiling/running Go programs;gradle_no_task
– fixes not found or ambiguousgradle
task;gradle_wrapper
– replacesgradle
with./gradlew
;grep_arguments_order
– fixes grep arguments order for situations likegrep -lir . test
;grep_recursive
– adds-r
when you trying togrep
directory;grunt_task_not_found
– fixes misspelledgrunt
commands;gulp_not_task
– fixes misspelledgulp
tasks;has_exists_script
– prepends./
when script/binary exists;heroku_multiple_apps
– add--app <app>
toheroku
commands likeheroku pg
;heroku_not_command
– fixes wrongheroku
commands likeheroku log
;history
– tries to replace command with most similar command from history;hostscli
– tries to fixhostscli
usage;ifconfig_device_not_found
– fixes wrong device names likewlan0
towlp2s0
;java
– removes.java
extension when running Java programs;javac
– appends missing.java
when compiling Java files;lein_not_task
– fixes wronglein
tasks likelein rpl
;ln_no_hard_link
– catches hard link creation on directories, suggest symbolic link;ln_s_order
– fixesln -s
arguments order;ls_all
– adds-A
tols
when output is empty;ls_lah
– adds-lah
tols
;man
– changes manual section;man_no_space
– fixes man commands without spaces, for examplemandiff
;mercurial
– fixes wronghg
commands;missing_space_before_subcommand
– fixes command with missing space likenpminstall
;mkdir_p
– adds-p
when you trying to create directory without parent;mvn_no_command
– addsclean package
tomvn
;mvn_unknown_lifecycle_phase
– fixes misspelled lifecycle phases withmvn
;npm_missing_script
– fixesnpm
custom script name innpm run-script <script>
;npm_run_script
– adds missingrun-script
for customnpm
scripts;npm_wrong_command
– fixes wrong npm commands likenpm urgrade
;no_command
– fixes wrong console commands, for examplevom/vim
;no_such_file
– creates missing directories withmv
andcp
commands;open
– either prependshttp://
to address passed toopen
or create a new file or directory and passes it toopen
;pip_unknown_command
– fixes wrongpip
commands, for examplepip instatl/pip install
;php_s
– replaces-s
by-S
when trying to run a local php server;port_already_in_use
– kills process that bound port;prove_recursively
– adds-r
when called with directory;python_command
– prependspython
when you trying to run not executable/without./
python script;python_execute
– appends missing.py
when executing Python files;quotation_marks
– fixes uneven usage of'
and"
when containing args';path_from_history
– replaces not found path with similar absolute path from history;react_native_command_unrecognized
– fixes unrecognizedreact-native
commands;remove_trailing_cedilla
– remove trailling cedillasç
, a common typo for european keyboard layouts;rm_dir
– adds-rf
when you trying to remove directory;scm_correction
– corrects wrong scm likehg log
togit log
;sed_unterminated_s
– adds missing '/' tosed
'ss
commands;sl_ls
– changessl
tols
;ssh_known_hosts
– removes host fromknown_hosts
on warning;sudo
– prependssudo
to previous command if it failed because of permissions;sudo_command_from_user_path
– runs commands from users$PATH
withsudo
;switch_lang
– switches command from your local layout to en;systemctl
– correctly orders parameters of confusingsystemctl
;test.py
– runspy.test
instead oftest.py
;touch
– creates missing directories before "touching";tsuru_login
– runstsuru login
if not authenticated or session expired;tsuru_not_command
– fixes wrongtsuru
commands liketsuru shell
;tmux
– fixestmux
commands;unknown_command
– fixes hadoop hdfs-style "unknown command", for example adds missing '-' to the command onhdfs dfs ls
;vagrant_up
– starts up the vagrant instance;whois
– fixeswhois
command;workon_doesnt_exists
– fixesvirtualenvwrapper
env name os suggests to create new.yarn_alias
– fixes aliasedyarn
commands likeyarn ls
;yarn_command_not_found
– fixes misspelledyarn
commands;yarn_command_replaced
– fixes replacedyarn
commands;yarn_help
– makes it easier to openyarn
documentation;
Enabled by default only on specific platforms:
apt_get
– installs app from apt if it not installed (requirespython-commandnotfound
/python3-commandnotfound
);apt_get_search
– changes trying to search usingapt-get
with searching usingapt-cache
;apt_invalid_operation
– fixes invalidapt
andapt-get
calls, likeapt-get isntall vim
;apt_list_upgradable
– helps you runapt list --upgradable
afterapt update
;brew_cask_dependency
– installs cask dependencies;brew_install
– fixes formula name forbrew install
;brew_link
– adds--overwrite --dry-run
if linking fails;brew_uninstall
– adds--force
tobrew uninstall
if multiple versions were installed;brew_unknown_command
– fixes wrong brew commands, for examplebrew docto/brew doctor
;brew_update_formula
– turnsbrew update <formula>
intobrew upgrade <formula>
;dnf_no_such_command
– fixes mistyped DNF commands;pacman
– installs app withpacman
if it is not installed (usesyaourt
if available);pacman_not_found
– fixes package name withpacman
oryaourt
.
Bundled, but not enabled by default:
git_push_force
– adds--force-with-lease
to agit push
(may conflict withgit_push_pull
);rm_root
– adds--no-preserve-root
torm -rf /
command.
Creating your own rules
For adding your own rule you should create your-rule-name.py
in ~/.config/thefuck/rules
. The rule should contain two functions:
match(command: Command) -> bool
get_new_command(command: Command) -> str | list[str]
Also the rule can contain an optional function
side_effect(old_command: Command, fixed_command: str) -> None
and optional enabled_by_default
, requires_output
and priority
variables.
Command
has three attributes: script
, output
and script_parts
.
Rule shouldn't change Command
.
Rules api changed in 3.0: For accessing settings in rule you need to import it with from thefuck.conf import settings
.
settings
is a special object filled with ~/.config/thefuck/settings.py
and values from env (see more below).
Simple example of the rule for running script with sudo
:
def match(command):
return ('permission denied' in command.output.lower()
or 'EACCES' in command.output)
def get_new_command(command):
return 'sudo {}'.format(command.script)
# Optional:
enabled_by_default = True
def side_effect(command, fixed_command):
subprocess.call('chmod 777 .', shell=True)
priority = 1000 # Lower first, default is 1000
requires_output = True
More examples of rules, utility functions for rules, app/os-specific helpers.
Settings
The Fuck has a few settings parameters which can be changed in $XDG_CONFIG_HOME/thefuck/settings.py
($XDG_CONFIG_HOME
defaults to ~/.config
):
rules
– list of enabled rules, by defaultthefuck.conf.DEFAULT_RULES
;exclude_rules
– list of disabled rules, by default[]
;require_confirmation
– requires confirmation before running new command, by defaultTrue
;wait_command
– max amount of time in seconds for getting previous command output;no_colors
– disable colored output;priority
– dict with rules priorities, rule with lowerpriority
will be matched first;debug
– enables debug output, by defaultFalse
;history_limit
– numeric value of how many history commands will be scanned, like2000
;alter_history
– push fixed command to history, by defaultTrue
;wait_slow_command
– max amount of time in seconds for getting previous command output if it inslow_commands
list;slow_commands
– list of slow commands.
Example of settings.py
:
rules = ['sudo', 'no_command']
exclude_rules = ['git_push']
require_confirmation = True
wait_command = 10
no_colors = False
priority = {'sudo': 100, 'no_command': 9999}
debug = False
history_limit = 9999
wait_slow_command = 20
slow_commands = ['react-native', 'gradle']
Or via environment variables:
THEFUCK_RULES
– list of enabled rules, likeDEFAULT_RULES:rm_root
orsudo:no_command
;THEFUCK_EXCLUDE_RULES
– list of disabled rules, likegit_pull:git_push
;THEFUCK_REQUIRE_CONFIRMATION
– require confirmation before running new command,true/false
;THEFUCK_WAIT_COMMAND
– max amount of time in seconds for getting previous command output;THEFUCK_NO_COLORS
– disable colored output,true/false
;THEFUCK_PRIORITY
– priority of the rules, likeno_command=9999:apt_get=100
, rule with lowerpriority
will be matched first;THEFUCK_DEBUG
– enables debug output,true/false
;THEFUCK_HISTORY_LIMIT
– how many history commands will be scanned, like2000
;THEFUCK_ALTER_HISTORY
– push fixed command to historytrue/false
;THEFUCK_WAIT_SLOW_COMMAND
– max amount of time in seconds for getting previous command output if it inslow_commands
list;THEFUCK_SLOW_COMMANDS
– list of slow commands, likelein:gradle
.
For example:
export THEFUCK_RULES='sudo:no_command'
export THEFUCK_EXCLUDE_RULES='git_pull:git_push'
export THEFUCK_REQUIRE_CONFIRMATION='true'
export THEFUCK_WAIT_COMMAND=10
export THEFUCK_NO_COLORS='false'
export THEFUCK_PRIORITY='no_command=9999:apt_get=100'
export THEFUCK_HISTORY_LIMIT='2000'
Third-party packages with rules
If you want to make very specific rules or rules, that you don't want to make public,
but share with other people.
You can create a special package with name thefuck_contrib_*
with following structure:
thefuck_contrib_foo
thefuck_contrib_foo
rules
__init__.py
*third-party rules*
__init__.py
*third-party-utils*
setup.py
And thefuck will find all rules from rules
module.
Experimental instant mode
By default The Fuck reruns a previous command and that takes time, in instant mode The Fuck logs output with script and just reads the log.
At the moment only Python 3 with bash or zsh is supported.
For enabling instant mode you need to add --enable-experimental-instant-mode
to alias initialization in your .bashrc
, .bash_profile
or .zshrc
like:
eval $(thefuck --alias --enable-experimental-instant-mode)
Developing
Install The Fuck
for development:
pip install -r requirements.txt
python setup.py develop
Run code style checks:
flake8
Run unit tests:
py.test
Run unit and functional tests (requires docker):
py.test --enable-functional
For sending package to pypi:
sudo apt-get install pandoc
./release.py
License MIT
Project License can be found here.