mirror of
https://github.com/wting/autojump
synced 2024-10-27 20:34:07 +00:00
implement basic fuzzy search
This commit is contained in:
parent
f98b13641f
commit
d7cea40619
40
bin/autojump
40
bin/autojump
@ -2,7 +2,6 @@
|
||||
from __future__ import division, print_function
|
||||
|
||||
import argparse
|
||||
import math
|
||||
from operator import itemgetter
|
||||
import os
|
||||
import re
|
||||
@ -10,7 +9,7 @@ import shutil
|
||||
import sys
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
VERSION = 'release-v20'
|
||||
VERSION = 'release-v20-3'
|
||||
MAX_KEYWEIGHT = 1000
|
||||
MAX_STORED_PATHS = 1000
|
||||
COMPLETION_SEPARATOR = '__'
|
||||
@ -40,6 +39,7 @@ class Database:
|
||||
if path not in self.data:
|
||||
self.data[path] = 10
|
||||
else:
|
||||
import math
|
||||
self.data[path] = math.sqrt((self.data[path]**2)+100)
|
||||
|
||||
def decay(self):
|
||||
@ -234,17 +234,17 @@ def match(path, pattern, only_end=False, ignore_case=False):
|
||||
match_path = path
|
||||
|
||||
if ignore_case:
|
||||
find_idx = match_path.lower().find(pattern.lower())
|
||||
else:
|
||||
find_idx = match_path.find(pattern)
|
||||
match_path = match_path.lower()
|
||||
pattern = pattern.lower()
|
||||
|
||||
find_idx = match_path.find(pattern)
|
||||
# truncate path to avoid matching a pattern multiple times
|
||||
if find_idx != -1:
|
||||
return (True, path)
|
||||
else:
|
||||
return (False, path[find_idx+len(pattern):])
|
||||
|
||||
def find_matches(db, patterns, max_matches=1, ignore_case=False):
|
||||
def find_matches(db, patterns, max_matches=1, ignore_case=False, fuzzy=False):
|
||||
""" Find max_matches paths that match the pattern, and add them to the result_list. """
|
||||
try:
|
||||
current_dir = decode(os.path.realpath(os.curdir))
|
||||
@ -254,6 +254,30 @@ def find_matches(db, patterns, max_matches=1, ignore_case=False):
|
||||
dirs = list(db.data.items())
|
||||
dirs.sort(key=itemgetter(1), reverse=True)
|
||||
results = []
|
||||
if fuzzy:
|
||||
from difflib import get_close_matches
|
||||
|
||||
# create dictionary of end paths to compare against
|
||||
end_dirs = {}
|
||||
for d in dirs:
|
||||
if ignore_case:
|
||||
end = d[0].split('/')[-1].lower()
|
||||
else:
|
||||
end = d[0].split('/')[-1]
|
||||
|
||||
# collisions: ignore lower weight paths
|
||||
if end not in end_dirs and os.path.exists(d[0]):
|
||||
end_dirs[end] = d[0]
|
||||
|
||||
# find the first match (heighest weight)
|
||||
found = get_close_matches(patterns[-1], end_dirs, 1, .6)
|
||||
if found:
|
||||
found = found[0]
|
||||
results.append(end_dirs[found])
|
||||
return results
|
||||
else:
|
||||
return []
|
||||
|
||||
for path, _ in dirs:
|
||||
# avoid jumping to current directory
|
||||
if current_dir == path :
|
||||
@ -312,6 +336,10 @@ def shell_utility():
|
||||
if ARGS.complete or not results:
|
||||
results = find_matches(db, patterns, max_matches, True)
|
||||
|
||||
# if no results, try approximate matching
|
||||
if not results:
|
||||
results = find_matches(db, patterns, max_matches, True, True)
|
||||
|
||||
quotes = ""
|
||||
if ARGS.complete and ARGS.bash: quotes = "'"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user