##// 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 653 pass
654 654
655 def _up_pressed(self):
655 def _up_pressed(self, shift_modifier):
656 656 """ Called when the up key is pressed. Returns whether to continue
657 657 processing the event.
658 658 """
659 659 return True
660 660
661 def _down_pressed(self):
661 def _down_pressed(self, shift_modifier):
662 662 """ Called when the down key is pressed. Returns whether to continue
663 663 processing the event.
664 664 """
@@ -1040,14 +1040,14 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
1040 1040 intercepted = True
1041 1041
1042 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 1044 intercepted = True
1045 1045 else:
1046 1046 prompt_line = self._get_prompt_cursor().blockNumber()
1047 1047 intercepted = cursor.blockNumber() <= prompt_line
1048 1048
1049 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 1051 intercepted = True
1052 1052 else:
1053 1053 end_line = self._get_end_cursor().blockNumber()
@@ -2,6 +2,7 b''
2 2 from IPython.external.qt import QtGui
3 3
4 4 # Local imports
5 from IPython.utils.traitlets import Bool
5 6 from console_widget import ConsoleWidget
6 7
7 8
@@ -10,6 +11,13 b' class HistoryConsoleWidget(ConsoleWidget):'
10 11 executed and provides a readline-esque interface to this history.
11 12 """
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)
20
13 21 #---------------------------------------------------------------------------
14 22 # 'object' interface
15 23 #---------------------------------------------------------------------------
@@ -55,12 +63,15 b' class HistoryConsoleWidget(ConsoleWidget):'
55 63 # 'ConsoleWidget' abstract interface
56 64 #---------------------------------------------------------------------------
57 65
58 def _up_pressed(self):
66 def _up_pressed(self, shift_modifier):
59 67 """ Called when the up key is pressed. Returns whether to continue
60 68 processing the event.
61 69 """
62 70 prompt_cursor = self._get_prompt_cursor()
63 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 76 # Set a search prefix based on the cursor position.
66 77 col = self._get_input_buffer_cursor_column()
@@ -88,21 +99,24 b' class HistoryConsoleWidget(ConsoleWidget):'
88 99
89 100 return True
90 101
91 def _down_pressed(self):
102 def _down_pressed(self, shift_modifier):
92 103 """ Called when the down key is pressed. Returns whether to continue
93 104 processing the event.
94 105 """
95 106 end_cursor = self._get_end_cursor()
96 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 112 # Perform the search.
99 self.history_next(self._history_prefix)
113 replaced = self.history_next(self._history_prefix)
100 114
101 115 # Emulate readline: keep the cursor position fixed for a prefix
102 116 # search. (We don't need to move the cursor to the end of the buffer
103 117 # in the other case because this happens automatically when the
104 118 # input buffer is set.)
105 if self._history_prefix:
119 if self._history_prefix and replaced:
106 120 cursor = self._get_prompt_cursor()
107 121 cursor.movePosition(QtGui.QTextCursor.Right,
108 122 n=len(self._history_prefix))
@@ -123,19 +137,26 b' class HistoryConsoleWidget(ConsoleWidget):'
123 137 -----------
124 138 prefix : str, optional
125 139 If specified, search for an item with this prefix.
140
141 Returns:
142 --------
143 Whether the input buffer was changed.
126 144 """
127 145 index = self._history_index
146 replace = False
128 147 while index > 0:
129 148 index -= 1
130 149 history = self._get_edited_history(index)
131 150 if history.startswith(prefix):
151 replace = True
132 152 break
133 else:
134 history = None
135 153
136 if history is not None:
137 self._set_edited_input_buffer(history)
154 if replace:
155 self._store_edits()
138 156 self._history_index = index
157 self.input_buffer = history
158
159 return replace
139 160
140 161 def history_next(self, prefix=''):
141 162 """ If possible, set the input buffer to a subsequent history item.
@@ -144,19 +165,26 b' class HistoryConsoleWidget(ConsoleWidget):'
144 165 -----------
145 166 prefix : str, optional
146 167 If specified, search for an item with this prefix.
168
169 Returns:
170 --------
171 Whether the input buffer was changed.
147 172 """
148 173 index = self._history_index
174 replace = False
149 175 while self._history_index < len(self._history):
150 176 index += 1
151 177 history = self._get_edited_history(index)
152 178 if history.startswith(prefix):
179 replace = True
153 180 break
154 else:
155 history = None
156 181
157 if history is not None:
158 self._set_edited_input_buffer(history)
182 if replace:
183 self._store_edits()
159 184 self._history_index = index
185 self.input_buffer = history
186
187 return replace
160 188
161 189 def history_tail(self, n=10):
162 190 """ Get the local history list.
@@ -172,23 +200,35 b' class HistoryConsoleWidget(ConsoleWidget):'
172 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 212 def _get_edited_history(self, index):
176 213 """ Retrieves a history item, possibly with temporary edits.
177 214 """
178 215 if index in self._history_edits:
179 216 return self._history_edits[index]
217 elif index == len(self._history):
218 return unicode()
180 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 221 def _set_history(self, history):
190 222 """ Replace the current history with a sequence of history items.
191 223 """
192 224 self._history = list(history)
193 225 self._history_edits = {}
194 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