diff --git a/bin/autojump b/bin/autojump index 4f008fe..ce167bd 100755 --- a/bin/autojump +++ b/bin/autojump @@ -30,6 +30,7 @@ except ImportError: sys.path.pop() import collections +import difflib import math import operator import os @@ -387,22 +388,22 @@ def match(path, pattern, only_end=False, ignore_case=False): else: return (False, path[find_idx+len(pattern):]) -def find_matches(db, patterns, max_matches=1, ignore_case=False, fuzzy=False): +def find_matches(config, 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. + Find paths matching patterns up to max_matches. """ try: current_dir = decode(os.path.realpath(os.curdir)) except OSError: current_dir = None - dirs = list(db.data.items()) - dirs.sort(key=operator.itemgetter(1), reverse=True) + dirs = sorted(db.data.items(), key=operator.itemgetter(1), reverse=True) results = [] - if fuzzy: - from difflib import get_close_matches + if ignore_case: + patterns = [p.lower() for p in patterns] + + if fuzzy: # create dictionary of end paths to compare against end_dirs = {} for d in dirs: @@ -417,11 +418,11 @@ def find_matches(db, patterns, max_matches=1, ignore_case=False, fuzzy=False): # find the first match (heighest weight) while True: - found = get_close_matches(patterns[-1], end_dirs, n=1, cutoff=.6) + found = difflib.get_close_matches(patterns[-1], end_dirs, n=1, cutoff=.6) if not found: break # avoid jumping to current directory - if (os.path.exists(found[0]) or TESTING) and \ + if (os.path.exists(found[0]) or config['debug']) and \ current_dir != os.path.realpath(found[0]): break # continue with the last found directory removed @@ -445,7 +446,7 @@ def find_matches(db, patterns, max_matches=1, ignore_case=False, fuzzy=False): found, tmp = match(tmp, p, False, ignore_case) if not found: break - if found and (os.path.exists(path) or TESTING): + if found and (os.path.exists(path) or config['debug']): # avoid jumping to current directory # (call out to realpath this late to not stat all dirs) if current_dir == os.path.realpath(path): @@ -465,64 +466,66 @@ def find_matches(db, patterns, max_matches=1, ignore_case=False, fuzzy=False): def main(): config = parse_arg(parse_env(set_defaults())) - db = Database(config['db'], config) + db = Database(config) # if no directories, add empty string - if (ARGS.directory == ''): - patterns = [unico('')] + if config['args'].directory: + patterns = [decode(a) for a in config['args'].directory] else: - patterns = [decode(a) for a in ARGS.directory] + patterns = [unico('')] # check last pattern for full path # FIXME: disabled until zsh tab completion is fixed on the shell side - # if match_last(patterns): return True + # if match_last(patterns): + # return True # check for tab completion tab_choice = -1 - tab_match = re.search(COMPLETION_SEPARATOR+"([0-9]+)", patterns[-1]) + tab_match = re.search(config['separator']+"([0-9]+)", patterns[-1]) if tab_match: # user has selected a tab completion entry tab_choice = int(tab_match.group(1)) - patterns[-1] = re.sub(COMPLETION_SEPARATOR+"[0-9]+.*", "", patterns[-1]) + patterns[-1] = re.sub(config['separator']+"[0-9]+.*", "", patterns[-1]) else: # user hasn't selected a tab completion, display choices again - tab_match = re.match("(.*)"+COMPLETION_SEPARATOR, patterns[-1]) + tab_match = re.match("(.*)"+config['separator'], patterns[-1]) if tab_match: patterns[-1] = tab_match.group(1) # on tab completion always show all results - if ARGS.complete or tab_choice != -1: + if config['args'].complete or tab_choice != -1: max_matches = 9 else: max_matches = 1 results = [] - if not ALWAYS_IGNORE_CASE: - results = find_matches(db, patterns, max_matches, ignore_case=False) + if not config['ignore_case']: + results = find_matches(config, db, patterns, max_matches, ignore_case=False) # if no results, try ignoring case - if ARGS.complete or not results: - results = find_matches(db, patterns, max_matches, ignore_case=True) + if config['args'].complete or not results: + results = find_matches(config, db, patterns, max_matches, ignore_case=True) # if no results, try approximate matching if not results: - results = find_matches(db, patterns, max_matches, ignore_case=True, + results = find_matches(config, db, patterns, max_matches, ignore_case=True, fuzzy=True) quotes = "" - if ARGS.complete and ARGS.bash: quotes = "'" + if config['args'].complete and config['args'].bash: + quotes = "'" if tab_choice != -1: if len(results) > tab_choice-1: output(unico("%s%s%s") % (quotes,results[tab_choice-1],quotes)) - elif len(results) > 1 and ARGS.complete: + elif len(results) > 1 and config['args'].complete: output("\n".join(("%s%s%d%s%s" % (patterns[-1], - COMPLETION_SEPARATOR, n+1, COMPLETION_SEPARATOR, r) + config['separator'], n+1, config['separator'], r) for n, r in enumerate(results[:8])))) elif results: output(unico("%s%s%s")%(quotes,results[0],quotes)) else: - return False + return 1 - if not KEEP_ALL_ENTRIES: + if not config['keep_entries']: db.maintenance() return 0