mirror of
				https://github.com/wting/autojump
				synced 2025-06-13 12:54:07 +00:00 
			
		
		
		
	reformat doc strings, move config into own function, add global variable for testing purposes
This commit is contained in:
		
							parent
							
								
									79e644bd63
								
							
						
					
					
						commit
						13e385a0ef
					
				
							
								
								
									
										145
									
								
								bin/autojump
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								bin/autojump
									
									
									
									
									
								
							| @ -35,49 +35,78 @@ MAX_STORED_PATHS = 1000 | ||||
| COMPLETION_SEPARATOR = '__' | ||||
| ARGS = None | ||||
| 
 | ||||
| # load config from environmental variables | ||||
| if 'AUTOJUMP_DATA_DIR' in os.environ: | ||||
|     CONFIG_DIR = os.environ.get('AUTOJUMP_DATA_DIR') | ||||
| else: | ||||
|     xdg_data_dir = os.environ.get('XDG_DATA_HOME') or os.path.join(os.environ['HOME'], '.local', 'share') | ||||
|     CONFIG_DIR = os.path.join(xdg_data_dir, 'autojump') | ||||
| CONFIG_DIR = None | ||||
| DB_FILE = None | ||||
| 
 | ||||
| TESTING = False | ||||
| KEEP_ALL_ENTRIES = False | ||||
| if 'AUTOJUMP_KEEP_ALL_ENTRIES' in os.environ and os.environ.get('AUTOJUMP_KEEP_ALL_ENTRIES') == '1': | ||||
|     KEEP_ALL_ENTRIES = True | ||||
| IGNORE_CASE = False | ||||
| 
 | ||||
| ALWAYS_IGNORE_CASE = False | ||||
| if 'AUTOJUMP_IGNORE_CASE' in os.environ and os.environ.get('AUTOJUMP_IGNORE_CASE') == '1': | ||||
|     ALWAYS_IGNORE_CASE = True | ||||
| def config(testing=False): | ||||
|     global TESTING, CONFIG_DIR, KEEP_ALL_ENTRIES, DB_FILE | ||||
|     TESTING = testing | ||||
| 
 | ||||
| if CONFIG_DIR == os.path.expanduser('~'): | ||||
|     DB_FILE = CONFIG_DIR + '/.autojump.txt' | ||||
| else: | ||||
|     DB_FILE = CONFIG_DIR + '/autojump.txt' | ||||
|     # load config from environmental variables | ||||
|     if 'AUTOJUMP_DATA_DIR' in os.environ: | ||||
|         CONFIG_DIR = os.environ.get('AUTOJUMP_DATA_DIR') | ||||
|     else: | ||||
|         xdg_data_dir = os.environ.get('XDG_DATA_HOME') or os.path.join(os.environ['HOME'], '.local', 'share') | ||||
|         CONFIG_DIR = os.path.join(xdg_data_dir, 'autojump') | ||||
| 
 | ||||
|     if 'AUTOJUMP_KEEP_ALL_ENTRIES' in os.environ and os.environ.get('AUTOJUMP_KEEP_ALL_ENTRIES') == '1': | ||||
|         KEEP_ALL_ENTRIES = True | ||||
| 
 | ||||
|     if 'AUTOJUMP_IGNORE_CASE' in os.environ and os.environ.get('AUTOJUMP_IGNORE_CASE') == '1': | ||||
|         ALWAYS_IGNORE_CASE = True | ||||
| 
 | ||||
|     if CONFIG_DIR == os.path.expanduser('~'): | ||||
|         DB_FILE = CONFIG_DIR + '/.autojump.txt' | ||||
|     else: | ||||
|         DB_FILE = CONFIG_DIR + '/autojump.txt' | ||||
| 
 | ||||
| class Database: | ||||
|     """ Object for interfacing with autojump database. """ | ||||
|     """ | ||||
|     Object for interfacing with autojump database. | ||||
|     """ | ||||
| 
 | ||||
|     def __init__(self, filename): | ||||
|         self.filename = filename | ||||
|         self.data = {} | ||||
|         self.load() | ||||
| 
 | ||||
|     def add(self, path, increment=1): | ||||
|         """ Increment existing paths or initialize new ones to 0. """ | ||||
|     def __len__(self): | ||||
|         return len(self.data) | ||||
| 
 | ||||
|     def add(self, path, increment = 10): | ||||
|         """ | ||||
|         Increment existing paths or initialize new ones to 0. | ||||
|         """ | ||||
|         if path not in self.data: | ||||
|             self.data[path] = 10 | ||||
|             self.data[path] = increment | ||||
|         else: | ||||
|             import math | ||||
|             self.data[path] = math.sqrt((self.data[path]**2)+100) | ||||
|             self.data[path] = math.sqrt((self.data[path]**2)+(increment**2)) | ||||
| 
 | ||||
|     def decay(self): | ||||
|         """ Decay database entries. """ | ||||
|         """ | ||||
|         Decay database entries. | ||||
|         """ | ||||
|         for k in self.data.keys(): | ||||
|             self.data[k] *= 0.9 | ||||
| 
 | ||||
|     def get_weight(self, path): | ||||
|         """ | ||||
|         Return path weight. | ||||
|         """ | ||||
|         if path in self.data: | ||||
|             return self.data[path] | ||||
|         else: | ||||
|             return 0 | ||||
| 
 | ||||
|     def load(self, error_recovery = False): | ||||
|         """ Try to open the database file, recovering from backup if needed. """ | ||||
|         """ | ||||
|         Try to open the database file, recovering from backup if needed. | ||||
|         """ | ||||
|         try: | ||||
|             with open(self.filename, 'r') as aj_file: | ||||
|                 for line in aj_file.readlines(): | ||||
| @ -116,7 +145,9 @@ class Database: | ||||
|                 return {} # if everything fails, return an empty dictionary | ||||
| 
 | ||||
|     def maintenance(self): | ||||
|         """ Trims and decays database entries when exceeding settings. """ | ||||
|         """ | ||||
|         Trims and decays database entries when exceeding settings. | ||||
|         """ | ||||
|         if sum(self.data.values()) > MAX_KEYWEIGHT: | ||||
|             self.decay() | ||||
|         if len(self.data) > MAX_STORED_PATHS: | ||||
| @ -124,7 +155,9 @@ class Database: | ||||
|         self.save() | ||||
| 
 | ||||
|     def purge(self): | ||||
|         """ Deletes all entries that no longer exist on system. """ | ||||
|         """ | ||||
|         Deletes all entries that no longer exist on system. | ||||
|         """ | ||||
|         removed = [] | ||||
|         for path in self.data.keys(): | ||||
|             if not os.path.exists(path): | ||||
| @ -134,7 +167,9 @@ class Database: | ||||
|         return removed | ||||
| 
 | ||||
|     def save(self): | ||||
|         """ Save database atomically and preserve backup. """ | ||||
|         """ | ||||
|         Save database atomically and preserve backup. | ||||
|         """ | ||||
|         # check file existence and permissions | ||||
|         if ((not os.path.exists(self.filename)) or | ||||
|                 os.name == 'nt' or | ||||
| @ -166,17 +201,21 @@ class Database: | ||||
|                 print("Error while creating backup autojump file. (%s)" % | ||||
|                         ex, file=sys.stderr) | ||||
| 
 | ||||
|     def trim(self): | ||||
|         """ If database has exceeded MAX_STORED_PATHS, removes bottom 10%. """ | ||||
|     def trim(self, percent=0.1): | ||||
|         """ | ||||
|         If database has exceeded MAX_STORED_PATHS, removes bottom 10%. | ||||
|         """ | ||||
|         dirs = list(self.data.items()) | ||||
|         dirs.sort(key=itemgetter(1)) | ||||
|         remove_cnt = .1 * MAX_STORED_PATHS | ||||
|         remove_cnt = int(percent * len(dirs)) | ||||
|         for path, _ in dirs[:remove_cnt]: | ||||
|             del self.data[path] | ||||
| 
 | ||||
| 
 | ||||
| def get_db_file(filename = "autojump.txt"): | ||||
|     """ Retrieve full database path. """ | ||||
|     """ | ||||
|     Retrieve full database path. | ||||
|     """ | ||||
|     # TODO: Remove when migration code is removed. | ||||
|     if CONFIG_DIR == os.path.expanduser("~"): | ||||
|         return CONFIG_DIR + "/." + filename | ||||
| @ -184,9 +223,9 @@ def get_db_file(filename = "autojump.txt"): | ||||
|         return CONFIG_DIR + "/" + filename | ||||
| 
 | ||||
| def options(): | ||||
|     """ Parse command line options. """ | ||||
|     global ARGS | ||||
| 
 | ||||
|     """ | ||||
|     Parse command line options. | ||||
|     """ | ||||
|     parser = argparse.ArgumentParser(description='Automatically jump to directory passed as an argument.', | ||||
|             epilog="Please see autojump(1) man pages for full documentation.") | ||||
|     parser.add_argument('directory', metavar='DIR', nargs='*', default='', | ||||
| @ -235,7 +274,9 @@ def options(): | ||||
|     return False | ||||
| 
 | ||||
| def decode(text, encoding=None, errors="strict"): | ||||
|     """ Decoding step for Python 2 which does not default to unicode. """ | ||||
|     """ | ||||
|     Decoding step for Python 2 which does not default to unicode. | ||||
|     """ | ||||
|     if sys.version_info[0] > 2: | ||||
|         return text | ||||
|     else: | ||||
| @ -244,8 +285,10 @@ def decode(text, encoding=None, errors="strict"): | ||||
|         return text.decode(encoding, errors) | ||||
| 
 | ||||
| def output(unicode_text, encoding=None): | ||||
|     """ Wrapper for the print function, using the filesystem encoding by default | ||||
|     to minimize encoding mismatch problems in directory names. """ | ||||
|     """ | ||||
|     Wrapper for the print function, using the filesystem encoding by default | ||||
|     to minimize encoding mismatch problems in directory names. | ||||
|     """ | ||||
|     if sys.version_info[0] > 2: | ||||
|         print(unicode_text) | ||||
|     else: | ||||
| @ -254,16 +297,20 @@ def output(unicode_text, encoding=None): | ||||
|         print(unicode_text.encode(encoding)) | ||||
| 
 | ||||
| def unico(text): | ||||
|     """ If Python 2, convert to a unicode object. """ | ||||
|     """ | ||||
|     If Python 2, convert to a unicode object. | ||||
|     """ | ||||
|     if sys.version_info[0] > 2: | ||||
|         return text | ||||
|     else: | ||||
|         return unicode(text) | ||||
| 
 | ||||
| def match_last(pattern): | ||||
|     """ If the last pattern contains a full path, jump there. | ||||
|     """ | ||||
|     If the last pattern contains a full path, jump there. | ||||
|     The regexp is because we need to support stuff like | ||||
|     "j wo jo__3__/home/joel/workspace/joel" for zsh. """ | ||||
|     "j wo jo__3__/home/joel/workspace/joel" for zsh. | ||||
|     """ | ||||
|     last_pattern_path = re.sub("(.*)"+COMPLETION_SEPARATOR, "", pattern[-1]) | ||||
|     if (len(last_pattern_path) > 0 and | ||||
|             last_pattern_path[0] == "/" and | ||||
| @ -274,8 +321,10 @@ def match_last(pattern): | ||||
|     return False | ||||
| 
 | ||||
| def match(path, pattern, only_end=False, ignore_case=False): | ||||
|     """ Check whether a path matches a particular pattern, and return | ||||
|        the remaining part of the string. """ | ||||
|     """ | ||||
|     Check whether a path matches a particular pattern, and return | ||||
|     the remaining part of the string. | ||||
|     """ | ||||
|     if only_end: | ||||
|         match_path = "/".join(path.split('/')[-1-pattern.count('/'):]) | ||||
|     else: | ||||
| @ -293,7 +342,9 @@ def match(path, pattern, only_end=False, ignore_case=False): | ||||
|         return (False, path[find_idx+len(pattern):]) | ||||
| 
 | ||||
| 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. """ | ||||
|     """ | ||||
|     Find max_matches paths that match the pattern, and add them to the result_list. | ||||
|     """ | ||||
|     try: | ||||
|         current_dir = decode(os.path.realpath(os.curdir)) | ||||
|     except OSError: | ||||
| @ -314,7 +365,7 @@ def find_matches(db, patterns, max_matches=1, ignore_case=False, fuzzy=False): | ||||
|                 end = d[0].split('/')[-1] | ||||
| 
 | ||||
|             # collisions: ignore lower weight paths | ||||
|             if end not in end_dirs and os.path.exists(d[0]): | ||||
|             if end not in end_dirs and (os.path.exists(d[0]) or TESTING): | ||||
|                 end_dirs[end] = d[0] | ||||
| 
 | ||||
|         # find the first match (heighest weight) | ||||
| @ -340,7 +391,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): | ||||
|         if found and (os.path.exists(path) or TESTING): | ||||
|             if path not in results: | ||||
|                 results.append(path) | ||||
|             if len(results) >= max_matches: | ||||
| @ -348,8 +399,14 @@ def find_matches(db, patterns, max_matches=1, ignore_case=False, fuzzy=False): | ||||
|     return results | ||||
| 
 | ||||
| def shell_utility(): | ||||
|     """ Run this when autojump is called as a shell utility. """ | ||||
|     """ | ||||
|     Run this when autojump is called as a shell utility. | ||||
|     """ | ||||
|     if options(): return True | ||||
|     config() | ||||
| 
 | ||||
|     global ARGS, COMPLETION_SEPARATOR, DB_FILE, \ | ||||
|             ALWAYS_IGNORE_CASE, KEEP_ALL_ENTRIES | ||||
|     db = Database(DB_FILE) | ||||
| 
 | ||||
|     # if no directories, add empty string | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user