Show More
@@ -1,108 +1,159 | |||||
1 | # System library imports |
|
1 | # System library imports | |
2 | from PyQt4 import QtGui |
|
2 | from PyQt4 import QtGui | |
3 |
|
3 | |||
4 | # Local imports |
|
4 | # Local imports | |
5 | from console_widget import ConsoleWidget |
|
5 | from console_widget import ConsoleWidget | |
6 |
|
6 | |||
7 |
|
7 | |||
8 | class HistoryConsoleWidget(ConsoleWidget): |
|
8 | class HistoryConsoleWidget(ConsoleWidget): | |
9 | """ A ConsoleWidget that keeps a history of the commands that have been |
|
9 | """ A ConsoleWidget that keeps a history of the commands that have been | |
10 | executed. |
|
10 | executed and provides a readline-esque interface to this history. | |
11 | """ |
|
11 | """ | |
12 |
|
12 | |||
13 | #--------------------------------------------------------------------------- |
|
13 | #--------------------------------------------------------------------------- | |
14 | # 'object' interface |
|
14 | # 'object' interface | |
15 | #--------------------------------------------------------------------------- |
|
15 | #--------------------------------------------------------------------------- | |
16 |
|
16 | |||
17 | def __init__(self, *args, **kw): |
|
17 | def __init__(self, *args, **kw): | |
18 | super(HistoryConsoleWidget, self).__init__(*args, **kw) |
|
18 | super(HistoryConsoleWidget, self).__init__(*args, **kw) | |
|
19 | ||||
|
20 | # HistoryConsoleWidget protected variables. | |||
19 | self._history = [] |
|
21 | self._history = [] | |
20 | self._history_index = 0 |
|
22 | self._history_index = 0 | |
|
23 | self._history_prefix = '' | |||
21 |
|
24 | |||
22 | #--------------------------------------------------------------------------- |
|
25 | #--------------------------------------------------------------------------- | |
23 | # 'ConsoleWidget' public interface |
|
26 | # 'ConsoleWidget' public interface | |
24 | #--------------------------------------------------------------------------- |
|
27 | #--------------------------------------------------------------------------- | |
25 |
|
28 | |||
26 | def execute(self, source=None, hidden=False, interactive=False): |
|
29 | def execute(self, source=None, hidden=False, interactive=False): | |
27 | """ Reimplemented to the store history. |
|
30 | """ Reimplemented to the store history. | |
28 | """ |
|
31 | """ | |
29 | if not hidden: |
|
32 | if not hidden: | |
30 | history = self.input_buffer if source is None else source |
|
33 | history = self.input_buffer if source is None else source | |
31 |
|
34 | |||
32 | executed = super(HistoryConsoleWidget, self).execute( |
|
35 | executed = super(HistoryConsoleWidget, self).execute( | |
33 | source, hidden, interactive) |
|
36 | source, hidden, interactive) | |
34 |
|
37 | |||
35 | if executed and not hidden: |
|
38 | if executed and not hidden: | |
36 | # Save the command unless it was an empty string or was identical |
|
39 | # Save the command unless it was an empty string or was identical | |
37 | # to the previous command. |
|
40 | # to the previous command. | |
38 | history = history.rstrip() |
|
41 | history = history.rstrip() | |
39 | if history and (not self._history or self._history[-1] != history): |
|
42 | if history and (not self._history or self._history[-1] != history): | |
40 | self._history.append(history) |
|
43 | self._history.append(history) | |
41 |
|
44 | |||
42 | # Move the history index to the most recent item. |
|
45 | # Move the history index to the most recent item. | |
43 | self._history_index = len(self._history) |
|
46 | self._history_index = len(self._history) | |
44 |
|
47 | |||
45 | return executed |
|
48 | return executed | |
46 |
|
49 | |||
47 | #--------------------------------------------------------------------------- |
|
50 | #--------------------------------------------------------------------------- | |
48 | # 'ConsoleWidget' abstract interface |
|
51 | # 'ConsoleWidget' abstract interface | |
49 | #--------------------------------------------------------------------------- |
|
52 | #--------------------------------------------------------------------------- | |
50 |
|
53 | |||
51 | def _up_pressed(self): |
|
54 | def _up_pressed(self): | |
52 | """ Called when the up key is pressed. Returns whether to continue |
|
55 | """ Called when the up key is pressed. Returns whether to continue | |
53 | processing the event. |
|
56 | processing the event. | |
54 | """ |
|
57 | """ | |
55 | prompt_cursor = self._get_prompt_cursor() |
|
58 | prompt_cursor = self._get_prompt_cursor() | |
56 | if self._get_cursor().blockNumber() == prompt_cursor.blockNumber(): |
|
59 | if self._get_cursor().blockNumber() == prompt_cursor.blockNumber(): | |
57 | self.history_previous() |
|
|||
58 |
|
60 | |||
59 | # Go to the first line of prompt for seemless history scrolling. |
|
61 | # Set a search prefix based on the cursor position. | |
|
62 | col = self._get_input_buffer_cursor_column() | |||
|
63 | input_buffer = self.input_buffer | |||
|
64 | if self._history_index == len(self._history) or \ | |||
|
65 | (self._history_prefix and col != len(self._history_prefix)): | |||
|
66 | self._history_index = len(self._history) | |||
|
67 | self._history_prefix = input_buffer[:col] | |||
|
68 | ||||
|
69 | # Perform the search. | |||
|
70 | self.history_previous(self._history_prefix) | |||
|
71 | ||||
|
72 | # Go to the first line of the prompt for seemless history scrolling. | |||
|
73 | # Emulate readline: keep the cursor position fixed for a prefix | |||
|
74 | # search. | |||
60 | cursor = self._get_prompt_cursor() |
|
75 | cursor = self._get_prompt_cursor() | |
|
76 | if self._history_prefix: | |||
|
77 | cursor.movePosition(QtGui.QTextCursor.Right, | |||
|
78 | n=len(self._history_prefix)) | |||
|
79 | else: | |||
61 | cursor.movePosition(QtGui.QTextCursor.EndOfLine) |
|
80 | cursor.movePosition(QtGui.QTextCursor.EndOfLine) | |
62 | self._set_cursor(cursor) |
|
81 | self._set_cursor(cursor) | |
63 |
|
82 | |||
64 | return False |
|
83 | return False | |
|
84 | ||||
65 | return True |
|
85 | return True | |
66 |
|
86 | |||
67 | def _down_pressed(self): |
|
87 | def _down_pressed(self): | |
68 | """ Called when the down key is pressed. Returns whether to continue |
|
88 | """ Called when the down key is pressed. Returns whether to continue | |
69 | processing the event. |
|
89 | processing the event. | |
70 | """ |
|
90 | """ | |
71 | end_cursor = self._get_end_cursor() |
|
91 | end_cursor = self._get_end_cursor() | |
72 | if self._get_cursor().blockNumber() == end_cursor.blockNumber(): |
|
92 | if self._get_cursor().blockNumber() == end_cursor.blockNumber(): | |
73 | self.history_next() |
|
93 | ||
|
94 | # Perform the search. | |||
|
95 | self.history_next(self._history_prefix) | |||
|
96 | ||||
|
97 | # Emulate readline: keep the cursor position fixed for a prefix | |||
|
98 | # search. (We don't need to move the cursor to the end of the buffer | |||
|
99 | # in the other case because this happens automatically when the | |||
|
100 | # input buffer is set.) | |||
|
101 | if self._history_prefix: | |||
|
102 | cursor = self._get_prompt_cursor() | |||
|
103 | cursor.movePosition(QtGui.QTextCursor.Right, | |||
|
104 | n=len(self._history_prefix)) | |||
|
105 | self._set_cursor(cursor) | |||
|
106 | ||||
74 | return False |
|
107 | return False | |
|
108 | ||||
75 | return True |
|
109 | return True | |
76 |
|
110 | |||
77 | #--------------------------------------------------------------------------- |
|
111 | #--------------------------------------------------------------------------- | |
78 | # 'HistoryConsoleWidget' public interface |
|
112 | # 'HistoryConsoleWidget' public interface | |
79 | #--------------------------------------------------------------------------- |
|
113 | #--------------------------------------------------------------------------- | |
80 |
|
114 | |||
81 | def history_previous(self): |
|
115 | def history_previous(self, prefix=''): | |
82 |
""" If possible, set the input buffer to |
|
116 | """ If possible, set the input buffer to a previous item in the history. | |
83 | history. |
|
117 | ||
|
118 | Parameters: | |||
|
119 | ----------- | |||
|
120 | prefix : str, optional | |||
|
121 | If specified, search for an item with this prefix. | |||
84 | """ |
|
122 | """ | |
85 |
i |
|
123 | index = self._history_index | |
86 | self._history_index -= 1 |
|
124 | while index > 0: | |
87 | self.input_buffer = self._history[self._history_index] |
|
125 | index -= 1 | |
|
126 | history = self._history[index] | |||
|
127 | if history.startswith(prefix): | |||
|
128 | break | |||
|
129 | else: | |||
|
130 | history = None | |||
|
131 | ||||
|
132 | if history is not None: | |||
|
133 | self._history_index = index | |||
|
134 | self.input_buffer = history | |||
88 |
|
135 | |||
89 | def history_next(self): |
|
136 | def history_next(self, prefix=''): | |
90 |
""" Set the input buffer to |
|
137 | """ Set the input buffer to a subsequent item in the history, or to the | |
91 |
|
|
138 | original search prefix if there is no such item. | |
|
139 | ||||
|
140 | Parameters: | |||
|
141 | ----------- | |||
|
142 | prefix : str, optional | |||
|
143 | If specified, search for an item with this prefix. | |||
92 | """ |
|
144 | """ | |
93 |
|
|
145 | while self._history_index < len(self._history) - 1: | |
94 | self._history_index += 1 |
|
146 | self._history_index += 1 | |
95 | if self._history_index < len(self._history): |
|
147 | history = self._history[self._history_index] | |
96 | self.input_buffer = self._history[self._history_index] |
|
148 | if history.startswith(prefix): | |
|
149 | break | |||
97 |
|
|
150 | else: | |
98 | self.input_buffer = '' |
|
151 | self._history_index = len(self._history) | |
99 |
|
152 | history = prefix | ||
100 | #--------------------------------------------------------------------------- |
|
153 | self.input_buffer = history | |
101 | # 'HistoryConsoleWidget' protected interface |
|
|||
102 | #--------------------------------------------------------------------------- |
|
|||
103 |
|
154 | |||
104 |
def |
|
155 | def set_history(self, history): | |
105 | """ Replace the current history with a sequence of history items. |
|
156 | """ Replace the current history with a sequence of history items. | |
106 | """ |
|
157 | """ | |
107 | self._history = list(history) |
|
158 | self._history = list(history) | |
108 | self._history_index = len(self._history) |
|
159 | self._history_index = len(self._history) |
General Comments 0
You need to be logged in to leave comments.
Login now