1 from idlelib.configHandler import idleConf 2 3 class History: 4 5 def __init__(self, text, output_sep = "\n"): 6 self.text = text 7 self.history = [] 8 self.history_prefix = None 9 self.history_pointer = None 10 self.output_sep = output_sep 11 self.cyclic = idleConf.GetOption("main", "History", "cyclic", 1, "bool") 12 text.bind("<<history-previous>>", self.history_prev) 13 text.bind("<<history-next>>", self.history_next) 14 15 def history_next(self, event): 16 self.history_do(0) 17 return "break" 18 19 def history_prev(self, event): 20 self.history_do(1) 21 return "break" 22 23 def _get_source(self, start, end): 24 # Get source code from start index to end index. Lines in the 25 # text control may be separated by sys.ps2 . 26 lines = self.text.get(start, end).split(self.output_sep) 27 return "\n".join(lines) 28 29 def _put_source(self, where, source): 30 output = self.output_sep.join(source.split("\n")) 31 self.text.insert(where, output) 32 33 def history_do(self, reverse): 34 nhist = len(self.history) 35 pointer = self.history_pointer 36 prefix = self.history_prefix 37 if pointer is not None and prefix is not None: 38 if self.text.compare("insert", "!=", "end-1c") or \ 39 self._get_source("iomark", "end-1c") != self.history[pointer]: 40 pointer = prefix = None 41 if pointer is None or prefix is None: 42 prefix = self._get_source("iomark", "end-1c") 43 if reverse: 44 pointer = nhist 45 else: 46 if self.cyclic: 47 pointer = -1 48 else: 49 self.text.bell() 50 return 51 nprefix = len(prefix) 52 while 1: 53 if reverse: 54 pointer = pointer - 1 55 else: 56 pointer = pointer + 1 57 if pointer < 0 or pointer >= nhist: 58 self.text.bell() 59 if not self.cyclic and pointer < 0: 60 return 61 else: 62 if self._get_source("iomark", "end-1c") != prefix: 63 self.text.delete("iomark", "end-1c") 64 self._put_source("iomark", prefix) 65 pointer = prefix = None 66 break 67 item = self.history[pointer] 68 if item[:nprefix] == prefix and len(item) > nprefix: 69 self.text.delete("iomark", "end-1c") 70 self._put_source("iomark", item) 71 break 72 self.text.mark_set("insert", "end-1c") 73 self.text.see("insert") 74 self.text.tag_remove("sel", "1.0", "end") 75 self.history_pointer = pointer 76 self.history_prefix = prefix 77 78 def history_store(self, source): 79 source = source.strip() 80 if len(source) > 2: 81 # avoid duplicates 82 try: 83 self.history.remove(source) 84 except ValueError: 85 pass 86 self.history.append(source) 87 self.history_pointer = None 88 self.history_prefix = None 89