diff --git a/thefuck/const.py b/thefuck/const.py index 0cc0e7ef..41534982 100644 --- a/thefuck/const.py +++ b/thefuck/const.py @@ -71,3 +71,5 @@ CONFIGURATION_TIMEOUT = 60 USER_COMMAND_MARK = u'\u200B' * 10 LOG_SIZE = 1000 + +DIFF_WITH_ALIAS = 0.5 diff --git a/thefuck/main.py b/thefuck/main.py index 38721753..bdacad72 100644 --- a/thefuck/main.py +++ b/thefuck/main.py @@ -4,26 +4,43 @@ from .system import init_output init_output() from pprint import pformat # noqa: E402 +import os # noqa: E402 import sys # noqa: E402 +from difflib import SequenceMatcher # noqa: E402 import six # noqa: E402 -from . import logs, types # noqa: E402 +from . import logs, types, const # noqa: E402 from .shells import shell # noqa: E402 from .conf import settings # noqa: E402 from .corrector import get_corrected_commands # noqa: E402 from .exceptions import EmptyCommand # noqa: E402 from .ui import select_command # noqa: E402 from .argument_parser import Parser # noqa: E402 -from .utils import get_installation_info # noqa: E402 +from .utils import (get_installation_info, get_alias, + get_all_executables) # noqa: E402 from .logs import warn # noqa: E402 +def _get_raw_command(known_args): + if known_args.force_command: + return known_args.force_command + elif 'TF_HISTORY' not in os.environ: + return known_args.command + else: + history = os.environ['TF_HISTORY'].split('\n')[::-1] + alias = get_alias() + executables = get_all_executables() + for command in history: + diff = SequenceMatcher(a=alias, b=command).ratio() + if diff < const.DIFF_WITH_ALIAS or command in executables: + return [command] + + def fix_command(known_args): """Fixes previous command. Used when `thefuck` called without arguments.""" settings.init(known_args) with logs.debug_time('Total'): logs.debug(u'Run with settings: {}'.format(pformat(settings))) - raw_command = ([known_args.force_command] if known_args.force_command - else known_args.command) + raw_command = _get_raw_command(known_args) try: command = types.Command.from_raw_script(raw_command) @@ -49,7 +66,7 @@ def main(): elif known_args.version: logs.version(get_installation_info().version, sys.version.split()[0]) - elif known_args.command: + elif known_args.command or 'TF_HISTORY' in os.environ: fix_command(known_args) elif known_args.alias: if six.PY2: diff --git a/thefuck/shells/bash.py b/thefuck/shells/bash.py index 52eb06ef..e0e6ea79 100644 --- a/thefuck/shells/bash.py +++ b/thefuck/shells/bash.py @@ -11,14 +11,15 @@ class Bash(Generic): # It is VERY important to have the variables declared WITHIN the function return ''' function {name} () {{ - TF_PREVIOUS=$(fc -ln -1); TF_PYTHONIOENCODING=$PYTHONIOENCODING; export TF_ALIAS={name}; export TF_SHELL_ALIASES=$(alias); + export TF_HISTORY=$(fc -ln -10); export PYTHONIOENCODING=utf-8; TF_CMD=$( - thefuck $TF_PREVIOUS {argument_placeholder} $@ + thefuck {argument_placeholder} $@ ) && eval $TF_CMD; + unset TF_HISTORY; export PYTHONIOENCODING=$TF_PYTHONIOENCODING; {alter_history} }} diff --git a/thefuck/shells/zsh.py b/thefuck/shells/zsh.py index aafbd00a..8492e9f7 100644 --- a/thefuck/shells/zsh.py +++ b/thefuck/shells/zsh.py @@ -12,12 +12,13 @@ class Zsh(Generic): # It is VERY important to have the variables declared WITHIN the function return ''' {name} () {{ - TF_PREVIOUS=$(fc -ln -1 | tail -n 1); + TF_HISTORY=$(fc -ln -10) TF_CMD=$( TF_ALIAS={name} TF_SHELL_ALIASES=$(alias) + TF_HISTORY=$TF_HISTORY PYTHONIOENCODING=utf-8 - thefuck $TF_PREVIOUS {argument_placeholder} $* + thefuck {argument_placeholder} $* ) && eval $TF_CMD; {alter_history} }}