##// 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 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 #---------------------------------------------------------------------------
@@ -16,8 +16,11 b' class HistoryConsoleWidget(ConsoleWidget):'
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
@@ -54,14 +57,31 b' class HistoryConsoleWidget(ConsoleWidget):'
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()
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 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):
@@ -70,38 +90,69 b' class HistoryConsoleWidget(ConsoleWidget):'
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 the previous item in the
116 """ If possible, set the input buffer to a previous item in the history.
83 history.
84 """
85 if self._history_index > 0:
86 self._history_index -= 1
87 self.input_buffer = self._history[self._history_index]
88
117
89 def history_next(self):
118 Parameters:
90 """ Set the input buffer to the next item in the history, or a blank
119 -----------
91 line if there is no subsequent item.
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 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):
97 else:
149 break
98 self.input_buffer = ''
150 else:
99
151 self._history_index = len(self._history)
100 #---------------------------------------------------------------------------
152 history = prefix
101 # 'HistoryConsoleWidget' protected interface
153 self.input_buffer = history
102 #---------------------------------------------------------------------------
103
154
104 def _set_history(self, history):
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)
General Comments 0
You need to be logged in to leave comments. Login now