TheFuck - Magnificent App Which Corrects Your Previous Console Command
Few 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
...
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 (2.7+ or 3.3+)
- pip
- python-dev
Installation [ experimental ]
On Ubuntu and OS X you can install
The Fuck
with installation script: wget -O - https://raw.githubusercontent.com/nvbn/thefuck/master/install.sh | sh - && $0
Manual installation
Install
The Fuck
with pip
: sudo pip install thefuck
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)"
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
). Update
sudo pip install thefuck --upgrade
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:
-
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 ..
; -
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
; -
fix_alt_space
– replaces Alt+Space with Space character; -
fix_file
– opens a file with an error in your$EDITOR
; -
git_add
– fixes "Did you forget to 'git add'?" ; -
git_branch_delete
– changesgit branch -d
togit branch -D
; -
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_staged
– adds--staged
to previousgit diff
with unexpected output; -
git_fix_stash
– fixesgit stash
commands (misspelled subcommand and missingsave
); -
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_push
– adds--set-upstream origin $branch
to previous failedgit push
; -
git_push_pull
– runsgit pull
whenpush
was rejected; -
git_stash
– stashes you local modifications before rebasing or switching branch; -
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 -
grep_recursive
– adds-r
when you trying togrep
directory; -
gulp_not_task
– fixes misspelledgulp
tasks; -
has_exists_script
– prepends./
when script/binary exists; -
heroku_not_command
– fixes wrongheroku
commands likeheroku log
; -
history
– tries to replace command with most similar command from history; -
java
– removes.java
extension when running Java programs; -
javac
– appends missing.java
when compiling Java files; -
lein_not_task
– fixes wronglein
tasks likelein rpl
; -
ls_lah
– adds-lah
tols
; -
man
– changes manual section; -
man_no_space
– fixes man commands without spaces, for examplemandiff
; -
mercurial
– fixes wronghg
commands; -
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
; -
no_command
– fixes wrong console commands, for examplevom/vim
; -
no_such_file
– creates missing directories withmv
andcp
commands; -
open
– prependshttp
to address passed toopen
; -
pip_unknown_command
– fixes wrongpip
commands, for examplepip instatl/pip install
; -
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'; -
rm_dir
– adds-rf
when you trying to remove directory; -
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; -
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.
-
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
; -
brew_install
– fixes formula name forbrew install
; -
brew_unknown_command
– fixes wrong brew commands, for examplebrew docto/brew doctor
; -
brew_upgrade
– appends--all
tobrew upgrade
as per Homebrew's new behaviour; -
pacman
– installs app withpacman
if it is not installed (usesyaourt
if available); -
pacman_not_found
– fixes package name withpacman
oryaourt
.
-
git_push_force
– adds--force
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 ~/.thefuck/rules
. The rule should contain two functions: match(command: Command) -> bool
get_new_command(command: Command) -> str | list[str]
side_effect(old_command: Command, fixed_command: str) -> None
enabled_by_default
, requires_output
and priority
variables. Command
has three attributes: script
, stdout
and stderr
. 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 ~/.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.stderr.lower()
or 'EACCES' in command.stderr)
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
Settings
The Fuck has a few settings parameters which can be changed in
~/.thefuck/settings.py
: -
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
.
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
-
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
.
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'
Developing
Install
The Fuck
for development: pip install -r requirements.txt
python setup.py develop
py.test
py.test --enable-functional
sudo apt-get install pandoc
./release.py