From c0eae8b85c6e5c7e69688c60577775f5b13b7406 Mon Sep 17 00:00:00 2001 From: nvbn Date: Wed, 8 Jul 2015 21:30:24 +0300 Subject: [PATCH] #N/A Add `get_closest` utility function --- tests/test_utils.py | 11 ++++++++++- thefuck/rules/brew_install.py | 11 ++++++----- thefuck/rules/brew_unknown_command.py | 11 +++++------ thefuck/rules/mercurial.py | 9 ++------- thefuck/utils.py | 10 ++++++++++ 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index d180eb56..21488d28 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,6 +1,6 @@ import pytest from mock import Mock -from thefuck.utils import sudo_support, wrap_settings, memoize +from thefuck.utils import sudo_support, wrap_settings, memoize, get_closest from thefuck.types import Settings from tests.utils import Command @@ -32,3 +32,12 @@ def test_memoize(): memoized() memoized() fn.assert_called_once_with() + + +class TestGetClosest(object): + + def test_when_can_match(self): + assert 'branch' == get_closest('brnch', ['branch', 'status']) + + def test_when_cant_match(self): + assert 'status' == get_closest('st', ['status', 'reset']) diff --git a/thefuck/rules/brew_install.py b/thefuck/rules/brew_install.py index 39deb236..7fa56893 100644 --- a/thefuck/rules/brew_install.py +++ b/thefuck/rules/brew_install.py @@ -1,9 +1,10 @@ -import difflib import os import re from subprocess import check_output +from thefuck.utils import get_closest # Formulars are base on each local system's status + brew_formulas = [] try: brew_path_prefix = check_output(['brew', '--prefix'], @@ -17,8 +18,8 @@ except: pass -def _get_similar_formulars(formula_name): - return difflib.get_close_matches(formula_name, brew_formulas, 1, 0.85) +def _get_similar_formula(formula_name): + return get_closest(formula_name, brew_formulas, 1, 0.85) def match(command, settings): @@ -29,7 +30,7 @@ def match(command, settings): if is_proper_command: formula = re.findall(r'Error: No available formula for ([a-z]+)', command.stderr)[0] - has_possible_formulas = len(_get_similar_formulars(formula)) > 0 + has_possible_formulas = bool(_get_similar_formula(formula)) return has_possible_formulas @@ -37,6 +38,6 @@ def match(command, settings): def get_new_command(command, settings): not_exist_formula = re.findall(r'Error: No available formula for ([a-z]+)', command.stderr)[0] - exist_formula = _get_similar_formulars(not_exist_formula)[0] + exist_formula = _get_similar_formula(not_exist_formula) return command.script.replace(not_exist_formula, exist_formula, 1) diff --git a/thefuck/rules/brew_unknown_command.py b/thefuck/rules/brew_unknown_command.py index 26c0924f..81e4a678 100644 --- a/thefuck/rules/brew_unknown_command.py +++ b/thefuck/rules/brew_unknown_command.py @@ -1,8 +1,7 @@ -import difflib import os import re import subprocess - +from thefuck.utils import get_closest BREW_CMD_PATH = '/Library/Homebrew/cmd' TAP_PATH = '/Library/Taps' @@ -78,8 +77,8 @@ if brew_path_prefix: pass -def _get_similar_commands(command): - return difflib.get_close_matches(command, brew_commands) +def _get_similar_command(command): + return get_closest(command, brew_commands) def match(command, settings): @@ -90,7 +89,7 @@ def match(command, settings): if is_proper_command: broken_cmd = re.findall(r'Error: Unknown command: ([a-z]+)', command.stderr)[0] - has_possible_commands = len(_get_similar_commands(broken_cmd)) > 0 + has_possible_commands = bool(_get_similar_command(broken_cmd)) return has_possible_commands @@ -98,6 +97,6 @@ def match(command, settings): def get_new_command(command, settings): broken_cmd = re.findall(r'Error: Unknown command: ([a-z]+)', command.stderr)[0] - new_cmd = _get_similar_commands(broken_cmd)[0] + new_cmd = _get_similar_command(broken_cmd) return command.script.replace(broken_cmd, new_cmd, 1) diff --git a/thefuck/rules/mercurial.py b/thefuck/rules/mercurial.py index 934e3f1e..c9e7a1a1 100644 --- a/thefuck/rules/mercurial.py +++ b/thefuck/rules/mercurial.py @@ -1,6 +1,5 @@ import re - -from difflib import get_close_matches +from thefuck.utils import get_closest def extract_possisiblities(command): @@ -26,9 +25,5 @@ def match(command, settings): def get_new_command(command, settings): script = command.script.split(' ') possisiblities = extract_possisiblities(command) - matches = get_close_matches(script[1], possisiblities) - if matches: - script[1] = matches[0] - else: - script[1] = possisiblities[0] + script[1] = get_closest(script[1], possisiblities) return ' '.join(script) diff --git a/thefuck/utils.py b/thefuck/utils.py index 5c6b0264..91ef1ed3 100644 --- a/thefuck/utils.py +++ b/thefuck/utils.py @@ -1,3 +1,4 @@ +from difflib import get_close_matches from functools import wraps import os import pickle @@ -85,3 +86,12 @@ def memoize(fn): return memo[key] return wrapper + + +def get_closest(word, possibilities, n=3, cutoff=0.6): + """Returns closest match or just first from possibilities.""" + possibilities = list(possibilities) + try: + return get_close_matches(word, possibilities, n, cutoff)[0] + except IndexError: + return possibilities[0]