mirror of
https://github.com/nvbn/thefuck.git
synced 2025-01-31 18:21:10 +00:00
reimplemented using native string matching
This commit is contained in:
parent
252859e63a
commit
8fdcff776a
@ -5,50 +5,15 @@ __author__ = "mmussomele"
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import cd_mkdir
|
import cd_mkdir
|
||||||
|
from difflib import get_close_matches
|
||||||
from thefuck.utils import sudo_support
|
from thefuck.utils import sudo_support
|
||||||
|
|
||||||
MAX_ALLOWED_STR_DIST = 5
|
MAX_ALLOWED_DIFF = 0.6
|
||||||
|
|
||||||
def _get_sub_dirs(parent):
|
def _get_sub_dirs(parent):
|
||||||
"""Returns a list of the child directories of the given parent directory"""
|
"""Returns a list of the child directories of the given parent directory"""
|
||||||
return [child for child in os.listdir(parent) if os.path.isdir(os.path.join(parent, child))]
|
return [child for child in os.listdir(parent) if os.path.isdir(os.path.join(parent, child))]
|
||||||
|
|
||||||
def _dam_lev_dist():
|
|
||||||
"""Returns a Damerau-Levenshtein distance calculator."""
|
|
||||||
cache = {}
|
|
||||||
def _calculator(first, second):
|
|
||||||
"""
|
|
||||||
Calculates the Damerau-Levenshtein distance of two strings.
|
|
||||||
See: http://en.wikipedia.org/wiki/Damerau-Levenshtein_distance#Algorithm
|
|
||||||
"""
|
|
||||||
if (first, second) in cache:
|
|
||||||
return cache[(first, second)]
|
|
||||||
else:
|
|
||||||
l_first = len(first)
|
|
||||||
l_second = len(second)
|
|
||||||
distances = [[0 for _ in range(l_second + 1)] for _ in range(l_first + 1)]
|
|
||||||
for i in range(l_first + 1):
|
|
||||||
distances[i][0] = i
|
|
||||||
for j in range(1, l_second + 1):
|
|
||||||
distances[0][j] = j
|
|
||||||
for i in range(l_first):
|
|
||||||
for j in range(l_second):
|
|
||||||
if first[i] == second[j]:
|
|
||||||
cost = 0
|
|
||||||
else:
|
|
||||||
cost = 1
|
|
||||||
distances[i+1][j+1] = min(distances[i][j+1] + 1,
|
|
||||||
distances[i+1][j] + 1,
|
|
||||||
distances[i][j] + cost)
|
|
||||||
if i and j and first[i] == second[j-1] and first[i-1] == second[j]:
|
|
||||||
distances[i][j] = min(distances[i+1][j+1],
|
|
||||||
distances[i-1][j-1] + cost)
|
|
||||||
cache[(first, second)] = distances[l_first][l_second]
|
|
||||||
return distances[l_first][l_second]
|
|
||||||
return _calculator
|
|
||||||
|
|
||||||
_dam_lev_dist = _dam_lev_dist()
|
|
||||||
|
|
||||||
@sudo_support
|
@sudo_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
"""Match function copied from cd_mkdir.py"""
|
"""Match function copied from cd_mkdir.py"""
|
||||||
@ -62,8 +27,7 @@ def get_new_command(command, settings):
|
|||||||
Attempt to rebuild the path string by spellchecking the directories.
|
Attempt to rebuild the path string by spellchecking the directories.
|
||||||
If it fails (i.e. no directories are a close enough match), then it
|
If it fails (i.e. no directories are a close enough match), then it
|
||||||
defaults to the rules of cd_mkdir.
|
defaults to the rules of cd_mkdir.
|
||||||
Change sensitivity to matching by changing MAX_ALLOWED_STR_DIST.
|
Change sensitivity by changing MAX_ALLOWED_DIFF. Default value is 0.6
|
||||||
Higher values allow for larger discrepancies in path names.
|
|
||||||
"""
|
"""
|
||||||
dest = command.script.split()[1].split(os.sep)
|
dest = command.script.split()[1].split(os.sep)
|
||||||
if dest[-1] == '':
|
if dest[-1] == '':
|
||||||
@ -75,12 +39,11 @@ def get_new_command(command, settings):
|
|||||||
elif directory == "..":
|
elif directory == "..":
|
||||||
cwd = os.path.split(cwd)[0]
|
cwd = os.path.split(cwd)[0]
|
||||||
continue
|
continue
|
||||||
best_match = min(_get_sub_dirs(cwd), key=lambda x: _dam_lev_dist(directory, x))
|
best_matches = get_close_matches(directory, _get_sub_dirs(cwd), cutoff=MAX_ALLOWED_DIFF)
|
||||||
best_dist = _dam_lev_dist(directory, best_match)
|
if len(best_matches):
|
||||||
if best_dist > MAX_ALLOWED_STR_DIST or best_dist >= len(best_match):
|
cwd = os.path.join(cwd, best_matches[0])
|
||||||
return cd_mkdir.get_new_command(command, settings)
|
|
||||||
else:
|
else:
|
||||||
cwd = os.path.join(cwd, best_match)
|
return cd_mkdir.get_new_command(command, settings)
|
||||||
return "cd {0}".format(cwd)
|
return "cd {0}".format(cwd)
|
||||||
|
|
||||||
enabled_by_default = True
|
enabled_by_default = True
|
||||||
|
Loading…
x
Reference in New Issue
Block a user