From 067f653b506b96aed040243c1b770c60c39474ed Mon Sep 17 00:00:00 2001 From: William Ting Date: Tue, 17 Dec 2013 11:54:40 -0600 Subject: [PATCH] match consecutive needles to paths --- bin/autojump | 56 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/bin/autojump b/bin/autojump index 6781fed..f5d11c7 100755 --- a/bin/autojump +++ b/bin/autojump @@ -205,25 +205,55 @@ def find_matches(config, needles, count=1): needles = map(sanitize, needles) ignore_case = detect_smartcase(needles) - # if one needle, match only against the last directory of each path - if len(needles) == 1: - exact_matches = match_end(first(needles), data, ignore_case) - else: - exact_matches = match_regex(needles, data, ignore_case) + exact_matches = match_consecutive(needles, data, ignore_case) exists = lambda entry: os.path.exists(entry.path) result = first(ifilter(exists, exact_matches)) + + # TODO(ting|2013-12-17): remove debug print + print(result) + sys.exit(0) return result.path if result else u'' -def match_end(needle, haystack, ignore_case=False): - """Matches needle against the last directory of path.""" - get_last_dir = lambda entry: second(os.path.split(entry.path)) - if ignore_case: - has_needle = lambda entry: needle in get_last_dir(entry).lower() - else: - has_needle = lambda entry: needle in get_last_dir(entry) - return ifilter(has_needle, haystack) +def match_consecutive(needles, haystack, ignore_case=False): + """ + Matches consecutive needles at the end of a path. + + For example: + needles = ['foo', 'baz'] + haystack = [ + (path="/foo/bar/baz", 10), + (path="/foo/baz/moo", 10), + (path="/moo/foo/baz", 10), + (path="/foo/baz", 10)] + + regex needle = re.compile(r''' + foo # needle #1 + [^/]* # all characters except os.sep zero or more times + / # os.sep + [^/]* # all characters except os.sep zero or more times + baz # needle #2 + [^/]* # all characters except os.sep zero or more times + $ # end of string + ''' + + result = [ + (path="/moo/foo/baz", 10), + (path="/foo/baz", 10)] + """ + regex_no_sep = '[^' + os.sep + ']*' + regex_one_sep = regex_no_sep + os.sep + regex_no_sep + regex_no_sep_end = regex_no_sep + '$' + # can't use compiled regex because of flags + needle = regex_one_sep.join(needles) + regex_no_sep_end + regex_flags = re.IGNORECASE | re.UNICODE if ignore_case else re.UNICODE + + found = lambda haystack: re.search( + needle, + haystack.path, + flags=regex_flags) + return ifilter(found, haystack) def match_regex(needles, haystack, ignore_case=False):