ยปCore Development>Code coverage>Lib/idlelib/history.py

Python code coverage for Lib/idlelib/history.py

#countcontent
1n/a"Implement Idle Shell history mechanism with History class"
2n/a
3n/afrom idlelib.config import idleConf
4n/a
5n/a
6n/aclass History:
7n/a ''' Implement Idle Shell history mechanism.
8n/a
9n/a store - Store source statement (called from pyshell.resetoutput).
10n/a fetch - Fetch stored statement matching prefix already entered.
11n/a history_next - Bound to <<history-next>> event (default Alt-N).
12n/a history_prev - Bound to <<history-prev>> event (default Alt-P).
13n/a '''
14n/a def __init__(self, text):
15n/a '''Initialize data attributes and bind event methods.
16n/a
17n/a .text - Idle wrapper of tk Text widget, with .bell().
18n/a .history - source statements, possibly with multiple lines.
19n/a .prefix - source already entered at prompt; filters history list.
20n/a .pointer - index into history.
21n/a .cyclic - wrap around history list (or not).
22n/a '''
23n/a self.text = text
24n/a self.history = []
25n/a self.prefix = None
26n/a self.pointer = None
27n/a self.cyclic = idleConf.GetOption("main", "History", "cyclic", 1, "bool")
28n/a text.bind("<<history-previous>>", self.history_prev)
29n/a text.bind("<<history-next>>", self.history_next)
30n/a
31n/a def history_next(self, event):
32n/a "Fetch later statement; start with ealiest if cyclic."
33n/a self.fetch(reverse=False)
34n/a return "break"
35n/a
36n/a def history_prev(self, event):
37n/a "Fetch earlier statement; start with most recent."
38n/a self.fetch(reverse=True)
39n/a return "break"
40n/a
41n/a def fetch(self, reverse):
42n/a '''Fetch statememt and replace current line in text widget.
43n/a
44n/a Set prefix and pointer as needed for successive fetches.
45n/a Reset them to None, None when returning to the start line.
46n/a Sound bell when return to start line or cannot leave a line
47n/a because cyclic is False.
48n/a '''
49n/a nhist = len(self.history)
50n/a pointer = self.pointer
51n/a prefix = self.prefix
52n/a if pointer is not None and prefix is not None:
53n/a if self.text.compare("insert", "!=", "end-1c") or \
54n/a self.text.get("iomark", "end-1c") != self.history[pointer]:
55n/a pointer = prefix = None
56n/a self.text.mark_set("insert", "end-1c") # != after cursor move
57n/a if pointer is None or prefix is None:
58n/a prefix = self.text.get("iomark", "end-1c")
59n/a if reverse:
60n/a pointer = nhist # will be decremented
61n/a else:
62n/a if self.cyclic:
63n/a pointer = -1 # will be incremented
64n/a else: # abort history_next
65n/a self.text.bell()
66n/a return
67n/a nprefix = len(prefix)
68n/a while 1:
69n/a pointer += -1 if reverse else 1
70n/a if pointer < 0 or pointer >= nhist:
71n/a self.text.bell()
72n/a if not self.cyclic and pointer < 0: # abort history_prev
73n/a return
74n/a else:
75n/a if self.text.get("iomark", "end-1c") != prefix:
76n/a self.text.delete("iomark", "end-1c")
77n/a self.text.insert("iomark", prefix)
78n/a pointer = prefix = None
79n/a break
80n/a item = self.history[pointer]
81n/a if item[:nprefix] == prefix and len(item) > nprefix:
82n/a self.text.delete("iomark", "end-1c")
83n/a self.text.insert("iomark", item)
84n/a break
85n/a self.text.see("insert")
86n/a self.text.tag_remove("sel", "1.0", "end")
87n/a self.pointer = pointer
88n/a self.prefix = prefix
89n/a
90n/a def store(self, source):
91n/a "Store Shell input statement into history list."
92n/a source = source.strip()
93n/a if len(source) > 2:
94n/a # avoid duplicates
95n/a try:
96n/a self.history.remove(source)
97n/a except ValueError:
98n/a pass
99n/a self.history.append(source)
100n/a self.pointer = None
101n/a self.prefix = None
102n/a
103n/a
104n/aif __name__ == "__main__":
105n/a from unittest import main
106n/a main('idlelib.idle_test.test_history', verbosity=2, exit=False)