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

Python code coverage for Lib/idlelib/IdleHistory.py

#countcontent
1n/a"Implement Idle Shell history mechanism with History class"
2n/a
3n/afrom idlelib.configHandler import idleConf
4n/a
5n/aclass History:
6n/a ''' Implement Idle Shell history mechanism.
7n/a
8n/a store - Store source statement (called from PyShell.resetoutput).
9n/a fetch - Fetch stored statement matching prefix already entered.
10n/a history_next - Bound to <<history-next>> event (default Alt-N).
11n/a history_prev - Bound to <<history-prev>> event (default Alt-P).
12n/a '''
13n/a def __init__(self, text, output_sep = "\n"):
14n/a '''Initialize data attributes and bind event methods.
15n/a
16n/a .text - Idle wrapper of tk Text widget, with .bell().
17n/a .history - source statements, possibly with multiple lines.
18n/a .prefix - source already entered at prompt; filters history list.
19n/a .pointer - index into history.
20n/a .cyclic - wrap around history list (or not).
21n/a '''
22n/a self.text = text
23n/a self.history = []
24n/a self.prefix = None
25n/a self.pointer = None
26n/a self.output_sep = output_sep
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 _get_source(self, start, end):
42n/a # Get source code from start index to end index. Lines in the
43n/a # text control may be separated by sys.ps2 .
44n/a lines = self.text.get(start, end).split(self.output_sep)
45n/a return "\n".join(lines)
46n/a
47n/a def _put_source(self, where, source):
48n/a output = self.output_sep.join(source.split("\n"))
49n/a self.text.insert(where, output)
50n/a
51n/a def fetch(self, reverse):
52n/a "Fetch statememt and enter into text at cursor."
53n/a nhist = len(self.history)
54n/a pointer = self.pointer
55n/a prefix = self.prefix
56n/a if pointer is not None and prefix is not None:
57n/a if self.text.compare("insert", "!=", "end-1c") or \
58n/a self._get_source("iomark", "end-1c") != self.history[pointer]:
59n/a pointer = prefix = None
60n/a if pointer is None or prefix is None:
61n/a prefix = self._get_source("iomark", "end-1c")
62n/a if reverse:
63n/a pointer = nhist # will be decremented
64n/a else:
65n/a if self.cyclic:
66n/a pointer = -1 # will be incremented
67n/a else:
68n/a self.text.bell()
69n/a return
70n/a nprefix = len(prefix)
71n/a while 1:
72n/a if reverse:
73n/a pointer = pointer - 1
74n/a else:
75n/a pointer = pointer + 1
76n/a if pointer < 0 or pointer >= nhist:
77n/a self.text.bell()
78n/a if not self.cyclic and pointer < 0:
79n/a return
80n/a else:
81n/a if self._get_source("iomark", "end-1c") != prefix:
82n/a self.text.delete("iomark", "end-1c")
83n/a self._put_source("iomark", prefix)
84n/a pointer = prefix = None
85n/a break
86n/a item = self.history[pointer]
87n/a if item[:nprefix] == prefix and len(item) > nprefix:
88n/a self.text.delete("iomark", "end-1c")
89n/a self._put_source("iomark", item)
90n/a break
91n/a self.text.mark_set("insert", "end-1c")
92n/a self.text.see("insert")
93n/a self.text.tag_remove("sel", "1.0", "end")
94n/a self.pointer = pointer
95n/a self.prefix = prefix
96n/a
97n/a def store(self, source):
98n/a "Store Shell input statement into history list."
99n/a source = source.strip()
100n/a if len(source) > 2:
101n/a # avoid duplicates
102n/a try:
103n/a self.history.remove(source)
104n/a except ValueError:
105n/a pass
106n/a self.history.append(source)
107n/a self.pointer = None
108n/a self.prefix = None