Home | History | Annotate | Download | only in idlelib
      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