##// END OF EJS Templates
First cut at support readline-esque history filtering in ConsoleWidget.
epatters -
Show More
@@ -7,7 +7,7 b' from console_widget import ConsoleWidget'
7 7
8 8 class HistoryConsoleWidget(ConsoleWidget):
9 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 #---------------------------------------------------------------------------
@@ -16,8 +16,11 b' class HistoryConsoleWidget(ConsoleWidget):'
16 16
17 17 def __init__(self, *args, **kw):
18 18 super(HistoryConsoleWidget, self).__init__(*args, **kw)
19
20 # HistoryConsoleWidget protected variables.
19 21 self._history = []
20 22 self._history_index = 0
23 self._history_prefix = ''
21 24
22 25 #---------------------------------------------------------------------------
23 26 # 'ConsoleWidget' public interface
@@ -54,14 +57,31 b' class HistoryConsoleWidget(ConsoleWidget):'
54 57 """
55 58 prompt_cursor = self._get_prompt_cursor()
56 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 75 cursor = self._get_prompt_cursor()
61 cursor.movePosition(QtGui.QTextCursor.EndOfLine)
76 if self._history_prefix:
77 cursor.movePosition(QtGui.QTextCursor.Right,
78 n=len(self._history_prefix))
79 else:
80 cursor.movePosition(QtGui.QTextCursor.EndOfLine)
62 81 self._set_cursor(cursor)
63 82
64 83 return False
84
65 85 return True
66 86
67 87 def _down_pressed(self):
@@ -70,38 +90,69 b' class HistoryConsoleWidget(ConsoleWidget):'
70 90 """
71 91 end_cursor = self._get_end_cursor()
72 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 107 return False
108
75 109 return True
76 110
77 111 #---------------------------------------------------------------------------
78 112 # 'HistoryConsoleWidget' public interface
79 113 #---------------------------------------------------------------------------
80 114
81 def history_previous(self):
82 """ If possible, set the input buffer to the previous item in the
83 history.
84 """
85 if self._history_index > 0:
86 self._history_index -= 1
87 self.input_buffer = self._history[self._history_index]
115 def history_previous(self, prefix=''):
116 """ If possible, set the input buffer to a previous item in the history.
88 117
89 def history_next(self):
90 """ Set the input buffer to the next item in the history, or a blank
91 line if there is no subsequent item.
118 Parameters:
119 -----------
120 prefix : str, optional
121 If specified, search for an item with this prefix.
92 122 """
93 if self._history_index < len(self._history):
123 index = self._history_index
124 while index > 0:
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
135
136 def history_next(self, prefix=''):
137 """ Set the input buffer to a subsequent item in the history, or to the
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.
144 """
145 while self._history_index < len(self._history) - 1:
94 146 self._history_index += 1
95 if self._history_index < len(self._history):
96 self.input_buffer = self._history[self._history_index]
97 else:
98 self.input_buffer = ''
99
100 #---------------------------------------------------------------------------
101 # 'HistoryConsoleWidget' protected interface
102 #---------------------------------------------------------------------------
147 history = self._history[self._history_index]
148 if history.startswith(prefix):
149 break
150 else:
151 self._history_index = len(self._history)
152 history = prefix
153 self.input_buffer = history
103 154
104 def _set_history(self, history):
155 def set_history(self, history):
105 156 """ Replace the current history with a sequence of history items.
106 157 """
107 158 self._history = list(history)
General Comments 0
You need to be logged in to leave comments. Login now