##// END OF EJS Templates
Add 'history_lock' setting to Qt console....
epatters -
Show More
@@ -652,13 +652,13 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
652 """
652 """
653 pass
653 pass
654
654
655 def _up_pressed(self):
655 def _up_pressed(self, shift_modifier):
656 """ Called when the up key is pressed. Returns whether to continue
656 """ Called when the up key is pressed. Returns whether to continue
657 processing the event.
657 processing the event.
658 """
658 """
659 return True
659 return True
660
660
661 def _down_pressed(self):
661 def _down_pressed(self, shift_modifier):
662 """ Called when the down key is pressed. Returns whether to continue
662 """ Called when the down key is pressed. Returns whether to continue
663 processing the event.
663 processing the event.
664 """
664 """
@@ -1040,14 +1040,14 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
1040 intercepted = True
1040 intercepted = True
1041
1041
1042 elif key == QtCore.Qt.Key_Up:
1042 elif key == QtCore.Qt.Key_Up:
1043 if self._reading or not self._up_pressed():
1043 if self._reading or not self._up_pressed(shift_down):
1044 intercepted = True
1044 intercepted = True
1045 else:
1045 else:
1046 prompt_line = self._get_prompt_cursor().blockNumber()
1046 prompt_line = self._get_prompt_cursor().blockNumber()
1047 intercepted = cursor.blockNumber() <= prompt_line
1047 intercepted = cursor.blockNumber() <= prompt_line
1048
1048
1049 elif key == QtCore.Qt.Key_Down:
1049 elif key == QtCore.Qt.Key_Down:
1050 if self._reading or not self._down_pressed():
1050 if self._reading or not self._down_pressed(shift_down):
1051 intercepted = True
1051 intercepted = True
1052 else:
1052 else:
1053 end_line = self._get_end_cursor().blockNumber()
1053 end_line = self._get_end_cursor().blockNumber()
@@ -2,6 +2,7 b''
2 from IPython.external.qt import QtGui
2 from IPython.external.qt import QtGui
3
3
4 # Local imports
4 # Local imports
5 from IPython.utils.traitlets import Bool
5 from console_widget import ConsoleWidget
6 from console_widget import ConsoleWidget
6
7
7
8
@@ -9,6 +10,13 b' class HistoryConsoleWidget(ConsoleWidget):'
9 """ A ConsoleWidget that keeps a history of the commands that have been
10 """ A ConsoleWidget that keeps a history of the commands that have been
10 executed and provides a readline-esque interface to this history.
11 executed and provides a readline-esque interface to this history.
11 """
12 """
13
14 #------ Configuration ------------------------------------------------------
15
16 # If enabled, the input buffer will become "locked" to history movement when
17 # an edit is made to a multi-line input buffer. To override the lock, use
18 # Shift in conjunction with the standard history cycling keys.
19 history_lock = Bool(False, config=True)
12
20
13 #---------------------------------------------------------------------------
21 #---------------------------------------------------------------------------
14 # 'object' interface
22 # 'object' interface
@@ -55,12 +63,15 b' class HistoryConsoleWidget(ConsoleWidget):'
55 # 'ConsoleWidget' abstract interface
63 # 'ConsoleWidget' abstract interface
56 #---------------------------------------------------------------------------
64 #---------------------------------------------------------------------------
57
65
58 def _up_pressed(self):
66 def _up_pressed(self, shift_modifier):
59 """ Called when the up key is pressed. Returns whether to continue
67 """ Called when the up key is pressed. Returns whether to continue
60 processing the event.
68 processing the event.
61 """
69 """
62 prompt_cursor = self._get_prompt_cursor()
70 prompt_cursor = self._get_prompt_cursor()
63 if self._get_cursor().blockNumber() == prompt_cursor.blockNumber():
71 if self._get_cursor().blockNumber() == prompt_cursor.blockNumber():
72 # Bail out if we're locked.
73 if self._history_locked() and not shift_modifier:
74 return False
64
75
65 # Set a search prefix based on the cursor position.
76 # Set a search prefix based on the cursor position.
66 col = self._get_input_buffer_cursor_column()
77 col = self._get_input_buffer_cursor_column()
@@ -88,21 +99,24 b' class HistoryConsoleWidget(ConsoleWidget):'
88
99
89 return True
100 return True
90
101
91 def _down_pressed(self):
102 def _down_pressed(self, shift_modifier):
92 """ Called when the down key is pressed. Returns whether to continue
103 """ Called when the down key is pressed. Returns whether to continue
93 processing the event.
104 processing the event.
94 """
105 """
95 end_cursor = self._get_end_cursor()
106 end_cursor = self._get_end_cursor()
96 if self._get_cursor().blockNumber() == end_cursor.blockNumber():
107 if self._get_cursor().blockNumber() == end_cursor.blockNumber():
108 # Bail out if we're locked.
109 if self._history_locked() and not shift_modifier:
110 return False
97
111
98 # Perform the search.
112 # Perform the search.
99 self.history_next(self._history_prefix)
113 replaced = self.history_next(self._history_prefix)
100
114
101 # Emulate readline: keep the cursor position fixed for a prefix
115 # Emulate readline: keep the cursor position fixed for a prefix
102 # search. (We don't need to move the cursor to the end of the buffer
116 # search. (We don't need to move the cursor to the end of the buffer
103 # in the other case because this happens automatically when the
117 # in the other case because this happens automatically when the
104 # input buffer is set.)
118 # input buffer is set.)
105 if self._history_prefix:
119 if self._history_prefix and replaced:
106 cursor = self._get_prompt_cursor()
120 cursor = self._get_prompt_cursor()
107 cursor.movePosition(QtGui.QTextCursor.Right,
121 cursor.movePosition(QtGui.QTextCursor.Right,
108 n=len(self._history_prefix))
122 n=len(self._history_prefix))
@@ -123,19 +137,26 b' class HistoryConsoleWidget(ConsoleWidget):'
123 -----------
137 -----------
124 prefix : str, optional
138 prefix : str, optional
125 If specified, search for an item with this prefix.
139 If specified, search for an item with this prefix.
140
141 Returns:
142 --------
143 Whether the input buffer was changed.
126 """
144 """
127 index = self._history_index
145 index = self._history_index
146 replace = False
128 while index > 0:
147 while index > 0:
129 index -= 1
148 index -= 1
130 history = self._get_edited_history(index)
149 history = self._get_edited_history(index)
131 if history.startswith(prefix):
150 if history.startswith(prefix):
151 replace = True
132 break
152 break
133 else:
134 history = None
135
153
136 if history is not None:
154 if replace:
137 self._set_edited_input_buffer(history)
155 self._store_edits()
138 self._history_index = index
156 self._history_index = index
157 self.input_buffer = history
158
159 return replace
139
160
140 def history_next(self, prefix=''):
161 def history_next(self, prefix=''):
141 """ If possible, set the input buffer to a subsequent history item.
162 """ If possible, set the input buffer to a subsequent history item.
@@ -144,19 +165,26 b' class HistoryConsoleWidget(ConsoleWidget):'
144 -----------
165 -----------
145 prefix : str, optional
166 prefix : str, optional
146 If specified, search for an item with this prefix.
167 If specified, search for an item with this prefix.
168
169 Returns:
170 --------
171 Whether the input buffer was changed.
147 """
172 """
148 index = self._history_index
173 index = self._history_index
174 replace = False
149 while self._history_index < len(self._history):
175 while self._history_index < len(self._history):
150 index += 1
176 index += 1
151 history = self._get_edited_history(index)
177 history = self._get_edited_history(index)
152 if history.startswith(prefix):
178 if history.startswith(prefix):
179 replace = True
153 break
180 break
154 else:
181
155 history = None
182 if replace:
156
183 self._store_edits()
157 if history is not None:
158 self._set_edited_input_buffer(history)
159 self._history_index = index
184 self._history_index = index
185 self.input_buffer = history
186
187 return replace
160
188
161 def history_tail(self, n=10):
189 def history_tail(self, n=10):
162 """ Get the local history list.
190 """ Get the local history list.
@@ -172,23 +200,35 b' class HistoryConsoleWidget(ConsoleWidget):'
172 # 'HistoryConsoleWidget' protected interface
200 # 'HistoryConsoleWidget' protected interface
173 #---------------------------------------------------------------------------
201 #---------------------------------------------------------------------------
174
202
203 def _history_locked(self):
204 """ Returns whether history movement is locked.
205 """
206 return (self.history_lock and
207 (self._get_edited_history(self._history_index) !=
208 self.input_buffer) and
209 (self._get_prompt_cursor().blockNumber() !=
210 self._get_end_cursor().blockNumber()))
211
175 def _get_edited_history(self, index):
212 def _get_edited_history(self, index):
176 """ Retrieves a history item, possibly with temporary edits.
213 """ Retrieves a history item, possibly with temporary edits.
177 """
214 """
178 if index in self._history_edits:
215 if index in self._history_edits:
179 return self._history_edits[index]
216 return self._history_edits[index]
217 elif index == len(self._history):
218 return unicode()
180 return self._history[index]
219 return self._history[index]
181
220
182 def _set_edited_input_buffer(self, source):
183 """ Sets the input buffer to 'source', saving the current input buffer
184 as a temporary history edit.
185 """
186 self._history_edits[self._history_index] = self.input_buffer
187 self.input_buffer = source
188
189 def _set_history(self, history):
221 def _set_history(self, history):
190 """ Replace the current history with a sequence of history items.
222 """ Replace the current history with a sequence of history items.
191 """
223 """
192 self._history = list(history)
224 self._history = list(history)
193 self._history_edits = {}
225 self._history_edits = {}
194 self._history_index = len(self._history)
226 self._history_index = len(self._history)
227
228 def _store_edits(self):
229 """ If there are edits to the current input buffer, store them.
230 """
231 current = self.input_buffer
232 if self._history_index == len(self._history) or \
233 self._history[self._history_index] != current:
234 self._history_edits[self._history_index] = current
General Comments 0
You need to be logged in to leave comments. Login now