blob: aa41b7319868843066f00e94569b93cac8805838 [file] [log] [blame]
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +00001import string
2
3class History:
Guido van Rossum504b0bf1999-01-02 21:28:54 +00004
Guido van Rossum17090411999-06-02 12:06:47 +00005 def __init__(self, text, output_sep = "\n"):
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +00006 self.text = text
7 self.history = []
8 self.history_prefix = None
9 self.history_pointer = None
Guido van Rossum17090411999-06-02 12:06:47 +000010 self.output_sep = output_sep
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000011 text.bind("<<history-previous>>", self.history_prev)
12 text.bind("<<history-next>>", self.history_next)
13
14 def history_next(self, event):
15 self.history_do(0)
16 return "break"
17
18 def history_prev(self, event):
19 self.history_do(1)
20 return "break"
21
Guido van Rossum17090411999-06-02 12:06:47 +000022 def _get_source(self, start, end):
23 # Get source code from start index to end index. Lines in the
24 # text control may be separated by sys.ps2 .
25 lines = string.split(self.text.get(start, end), self.output_sep)
26 return string.join(lines, "\n")
27
28 def _put_source(self, where, source):
29 output = string.join(string.split(source, "\n"), self.output_sep)
30 self.text.insert(where, output)
31
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000032 def history_do(self, reverse):
33 nhist = len(self.history)
34 pointer = self.history_pointer
35 prefix = self.history_prefix
36 if pointer is not None and prefix is not None:
37 if self.text.compare("insert", "!=", "end-1c") or \
Guido van Rossum17090411999-06-02 12:06:47 +000038 self._get_source("iomark", "end-1c") != self.history[pointer]:
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000039 pointer = prefix = None
40 if pointer is None or prefix is None:
Guido van Rossum17090411999-06-02 12:06:47 +000041 prefix = self._get_source("iomark", "end-1c")
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000042 if reverse:
43 pointer = nhist
44 else:
45 pointer = -1
46 nprefix = len(prefix)
47 while 1:
48 if reverse:
49 pointer = pointer - 1
50 else:
51 pointer = pointer + 1
52 if pointer < 0 or pointer >= nhist:
53 self.text.bell()
Guido van Rossum17090411999-06-02 12:06:47 +000054 if self._get_source("iomark", "end-1c") != prefix:
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000055 self.text.delete("iomark", "end-1c")
Guido van Rossum17090411999-06-02 12:06:47 +000056 self._put_source("iomark", prefix)
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000057 pointer = prefix = None
58 break
59 item = self.history[pointer]
60 if item[:nprefix] == prefix and len(item) > nprefix:
61 self.text.delete("iomark", "end-1c")
Guido van Rossum17090411999-06-02 12:06:47 +000062 self._put_source("iomark", item)
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000063 break
64 self.text.mark_set("insert", "end-1c")
65 self.text.see("insert")
66 self.text.tag_remove("sel", "1.0", "end")
67 self.history_pointer = pointer
68 self.history_prefix = prefix
69
70 def history_store(self, source):
71 source = string.strip(source)
72 if len(source) > 2:
Guido van Rossum17090411999-06-02 12:06:47 +000073 # avoid duplicates
74 try:
75 self.history.remove(source)
76 except ValueError:
77 pass
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000078 self.history.append(source)
79 self.history_pointer = None
80 self.history_prefix = None
81
82 def recall(self, s):
83 s = string.strip(s)
84 self.text.tag_remove("sel", "1.0", "end")
85 self.text.delete("iomark", "end-1c")
86 self.text.mark_set("insert", "end-1c")
87 self.text.insert("insert", s)
88 self.text.see("insert")
89