##// END OF EJS Templates
The IPythonWidget now tries to be smart about choosing colors to use for ANSI color codes.
epatters -
Show More
@@ -1,177 +1,203 b''
1 1 # Standard library imports
2 2 import re
3 3
4 4 # System library imports
5 5 from PyQt4 import QtCore, QtGui
6 6
7 7
8 8 class AnsiAction(object):
9 9 """ Represents an action requested by an ANSI escape sequence.
10 10 """
11 11 def __init__(self, kind):
12 12 self.kind = kind
13 13
14 14 class MoveAction(AnsiAction):
15 15 """ An AnsiAction for cursor move requests (CUU, CUD, CUF, CUB, CNL, CPL,
16 16 CHA, and CUP commands).
17 17 """
18 18 def __init__(self):
19 19 raise NotImplementedError
20 20
21 21 class EraseAction(AnsiAction):
22 22 """ An AnsiAction for erase requests (ED and EL commands).
23 23 """
24 24 def __init__(self, area, erase_to):
25 25 super(EraseAction, self).__init__('erase')
26 26 self.area = area
27 27 self.erase_to = erase_to
28 28
29 29
30 30 class AnsiCodeProcessor(object):
31 31 """ Translates ANSI escape codes into readable attributes.
32 32 """
33 33
34 # Whether to increase intensity or set boldness for SGR code 1.
35 # (Different terminals handle this in different ways.)
36 bold_text_enabled = False
37
34 38 # Protected class variables.
35 39 _ansi_commands = 'ABCDEFGHJKSTfmnsu'
36 40 _ansi_pattern = re.compile('\x01?\x1b\[(.*?)([%s])\x02?' % _ansi_commands)
37 41
38 42 def __init__(self):
39 43 self.actions = []
40 44 self.reset_sgr()
41 45
42 46 def reset_sgr(self):
43 47 """ Reset graphics attributs to their default values.
44 48 """
45 49 self.intensity = 0
46 50 self.italic = False
47 51 self.bold = False
48 52 self.underline = False
49 53 self.foreground_color = None
50 54 self.background_color = None
51 55
52 56 def split_string(self, string):
53 57 """ Yields substrings for which the same escape code applies.
54 58 """
55 59 self.actions = []
56 60 start = 0
57 61
58 62 for match in self._ansi_pattern.finditer(string):
59 63 substring = string[start:match.start()]
60 64 if substring or self.actions:
61 65 yield substring
62 66 start = match.end()
63 67
64 68 self.actions = []
65 69 try:
66 70 params = []
67 71 for param in match.group(1).split(';'):
68 72 if param:
69 73 params.append(int(param))
70 74 except ValueError:
71 75 # Silently discard badly formed escape codes.
72 76 pass
73 77 else:
74 78 self.set_csi_code(match.group(2), params)
75 79
76 80 substring = string[start:]
77 81 if substring or self.actions:
78 82 yield substring
79 83
80 84 def set_csi_code(self, command, params=[]):
81 85 """ Set attributes based on CSI (Control Sequence Introducer) code.
82 86
83 87 Parameters
84 88 ----------
85 89 command : str
86 90 The code identifier, i.e. the final character in the sequence.
87 91
88 92 params : sequence of integers, optional
89 93 The parameter codes for the command.
90 94 """
91 95 if command == 'm': # SGR - Select Graphic Rendition
92 96 for code in params:
93 97 self.set_sgr_code(code)
94 98
95 99 elif (command == 'J' or # ED - Erase Data
96 100 command == 'K'): # EL - Erase in Line
97 101 code = params[0] if params else 0
98 102 if 0 <= code <= 2:
99 103 area = 'screen' if command == 'J' else 'line'
100 104 if code == 0:
101 105 erase_to = 'end'
102 106 elif code == 1:
103 107 erase_to = 'start'
104 108 elif code == 2:
105 109 erase_to = 'all'
106 110 self.actions.append(EraseAction(area, erase_to))
107 111
108 112 def set_sgr_code(self, code):
109 113 """ Set attributes based on SGR (Select Graphic Rendition) code.
110 114 """
111 115 if code == 0:
112 116 self.reset_sgr()
113 117 elif code == 1:
114 self.intensity = 1
115 self.bold = True
118 if self.bold_text_enabled:
119 self.bold = True
120 else:
121 self.intensity = 1
116 122 elif code == 2:
117 123 self.intensity = 0
118 124 elif code == 3:
119 125 self.italic = True
120 126 elif code == 4:
121 127 self.underline = True
122 128 elif code == 22:
123 129 self.intensity = 0
124 130 self.bold = False
125 131 elif code == 23:
126 132 self.italic = False
127 133 elif code == 24:
128 134 self.underline = False
129 135 elif code >= 30 and code <= 37:
130 136 self.foreground_color = code - 30
131 137 elif code == 39:
132 138 self.foreground_color = None
133 139 elif code >= 40 and code <= 47:
134 140 self.background_color = code - 40
135 141 elif code == 49:
136 142 self.background_color = None
137 143
138 144
139 145 class QtAnsiCodeProcessor(AnsiCodeProcessor):
140 146 """ Translates ANSI escape codes into QTextCharFormats.
141 147 """
142 148
143 149 # A map from color codes to RGB colors.
144 ansi_colors = (# Normal, Bright/Light ANSI color code
150 default_map = (# Normal, Bright/Light ANSI color code
145 151 ('black', 'grey'), # 0: black
146 152 ('darkred', 'red'), # 1: red
147 ('darkgreen', 'green'), # 2: green
148 ('gold', 'yellow'), # 3: yellow
149 ('darkblue', 'blue'), # 4: blue
153 ('darkgreen', 'lime'), # 2: green
154 ('brown', 'yellow'), # 3: yellow
155 ('darkblue', 'deepskyblue'), # 4: blue
150 156 ('darkviolet', 'magenta'), # 5: magenta
151 157 ('steelblue', 'cyan'), # 6: cyan
152 158 ('grey', 'white')) # 7: white
159
160 def __init__(self):
161 super(QtAnsiCodeProcessor, self).__init__()
162 self.color_map = self.default_map
153 163
154 164 def get_format(self):
155 165 """ Returns a QTextCharFormat that encodes the current style attributes.
156 166 """
157 167 format = QtGui.QTextCharFormat()
158 168
159 169 # Set foreground color
160 170 if self.foreground_color is not None:
161 color = self.ansi_colors[self.foreground_color][self.intensity]
171 color = self.color_map[self.foreground_color][self.intensity]
162 172 format.setForeground(QtGui.QColor(color))
163 173
164 174 # Set background color
165 175 if self.background_color is not None:
166 color = self.ansi_colors[self.background_color][self.intensity]
176 color = self.color_map[self.background_color][self.intensity]
167 177 format.setBackground(QtGui.QColor(color))
168 178
169 179 # Set font weight/style options
170 180 if self.bold:
171 181 format.setFontWeight(QtGui.QFont.Bold)
172 182 else:
173 183 format.setFontWeight(QtGui.QFont.Normal)
174 184 format.setFontItalic(self.italic)
175 185 format.setFontUnderline(self.underline)
176 186
177 187 return format
188
189 def set_background_color(self, color):
190 """ Given a background color (a QColor), attempt to set a color map
191 that will be aesthetically pleasing.
192 """
193 if color.value() < 127:
194 # Colors appropriate for a terminal with a dark background.
195 self.color_map = self.default_map
196
197 else:
198 # Colors appropriate for a terminal with a light background. For
199 # now, only use non-bright colors...
200 self.color_map = [ (pair[0], pair[0]) for pair in self.default_map ]
201
202 # ...and replace white with black.
203 self.color_map[7] = ('black', 'black')
@@ -1,372 +1,375 b''
1 1 """ A FrontendWidget that emulates the interface of the console IPython and
2 2 supports the additional functionality provided by the IPython kernel.
3 3
4 4 TODO: Add support for retrieving the system default editor. Requires code
5 5 paths for Windows (use the registry), Mac OS (use LaunchServices), and
6 6 Linux (use the xdg system).
7 7 """
8 8
9 9 # Standard library imports
10 10 from subprocess import Popen
11 11
12 12 # System library imports
13 13 from PyQt4 import QtCore, QtGui
14 14
15 15 # Local imports
16 16 from IPython.core.inputsplitter import IPythonInputSplitter
17 17 from IPython.core.usage import default_banner
18 18 from frontend_widget import FrontendWidget
19 19
20 20
21 21 class IPythonPromptBlock(object):
22 22 """ An internal storage object for IPythonWidget.
23 23 """
24 24 def __init__(self, block, length, number):
25 25 self.block = block
26 26 self.length = length
27 27 self.number = number
28 28
29 29
30 30 class IPythonWidget(FrontendWidget):
31 31 """ A FrontendWidget for an IPython kernel.
32 32 """
33 33
34 34 # Signal emitted when an editor is needed for a file and the editor has been
35 35 # specified as 'custom'. See 'set_editor' for more information.
36 36 custom_edit_requested = QtCore.pyqtSignal(object, object)
37 37
38 38 # The default stylesheet: black text on a white background.
39 39 default_stylesheet = """
40 40 .error { color: red; }
41 41 .in-prompt { color: navy; }
42 42 .in-prompt-number { font-weight: bold; }
43 43 .out-prompt { color: darkred; }
44 44 .out-prompt-number { font-weight: bold; }
45 45 """
46 46
47 47 # A dark stylesheet: white text on a black background.
48 48 dark_stylesheet = """
49 49 QPlainTextEdit, QTextEdit { background-color: black; color: white }
50 50 QFrame { border: 1px solid grey; }
51 51 .error { color: red; }
52 52 .in-prompt { color: lime; }
53 53 .in-prompt-number { color: lime; font-weight: bold; }
54 54 .out-prompt { color: red; }
55 55 .out-prompt-number { color: red; font-weight: bold; }
56 56 """
57 57
58 58 # Default prompts.
59 59 in_prompt = 'In [<span class="in-prompt-number">%i</span>]: '
60 60 out_prompt = 'Out[<span class="out-prompt-number">%i</span>]: '
61 61
62 62 # FrontendWidget protected class variables.
63 63 _input_splitter_class = IPythonInputSplitter
64 64
65 65 # IPythonWidget protected class variables.
66 66 _payload_source_edit = 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic'
67 67 _payload_source_page = 'IPython.zmq.page.page'
68 68
69 69 #---------------------------------------------------------------------------
70 70 # 'object' interface
71 71 #---------------------------------------------------------------------------
72 72
73 73 def __init__(self, *args, **kw):
74 74 super(IPythonWidget, self).__init__(*args, **kw)
75 75
76 76 # IPythonWidget protected variables.
77 77 self._previous_prompt_obj = None
78 78
79 79 # Set a default editor and stylesheet.
80 80 self.set_editor('default')
81 81 self.reset_styling()
82 82
83 83 #---------------------------------------------------------------------------
84 84 # 'BaseFrontendMixin' abstract interface
85 85 #---------------------------------------------------------------------------
86 86
87 87 def _handle_complete_reply(self, rep):
88 88 """ Reimplemented to support IPython's improved completion machinery.
89 89 """
90 90 cursor = self._get_cursor()
91 91 if rep['parent_header']['msg_id'] == self._complete_id and \
92 92 cursor.position() == self._complete_pos:
93 93 # The completer tells us what text was actually used for the
94 94 # matching, so we must move that many characters left to apply the
95 95 # completions.
96 96 text = rep['content']['matched_text']
97 97 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
98 98 self._complete_with_items(cursor, rep['content']['matches'])
99 99
100 100 def _handle_history_reply(self, msg):
101 101 """ Implemented to handle history replies, which are only supported by
102 102 the IPython kernel.
103 103 """
104 104 history_dict = msg['content']['history']
105 105 items = [ history_dict[key] for key in sorted(history_dict.keys()) ]
106 106 self._set_history(items)
107 107
108 108 def _handle_prompt_reply(self, msg):
109 109 """ Implemented to handle prompt number replies, which are only
110 110 supported by the IPython kernel.
111 111 """
112 112 content = msg['content']
113 113 self._show_interpreter_prompt(content['prompt_number'],
114 114 content['input_sep'])
115 115
116 116 def _handle_pyout(self, msg):
117 117 """ Reimplemented for IPython-style "display hook".
118 118 """
119 119 if not self._hidden and self._is_from_this_session(msg):
120 120 content = msg['content']
121 121 prompt_number = content['prompt_number']
122 122 self._append_plain_text(content['output_sep'])
123 123 self._append_html(self._make_out_prompt(prompt_number))
124 124 self._append_plain_text(content['data'] + '\n' +
125 125 content['output_sep2'])
126 126
127 127 def _started_channels(self):
128 128 """ Reimplemented to make a history request.
129 129 """
130 130 super(IPythonWidget, self)._started_channels()
131 131 # FIXME: Disabled until history requests are properly implemented.
132 132 #self.kernel_manager.xreq_channel.history(raw=True, output=False)
133 133
134 134 #---------------------------------------------------------------------------
135 135 # 'FrontendWidget' interface
136 136 #---------------------------------------------------------------------------
137 137
138 138 def execute_file(self, path, hidden=False):
139 139 """ Reimplemented to use the 'run' magic.
140 140 """
141 141 self.execute('%%run %s' % path, hidden=hidden)
142 142
143 143 #---------------------------------------------------------------------------
144 144 # 'FrontendWidget' protected interface
145 145 #---------------------------------------------------------------------------
146 146
147 147 def _complete(self):
148 148 """ Reimplemented to support IPython's improved completion machinery.
149 149 """
150 150 # We let the kernel split the input line, so we *always* send an empty
151 151 # text field. Readline-based frontends do get a real text field which
152 152 # they can use.
153 153 text = ''
154 154
155 155 # Send the completion request to the kernel
156 156 self._complete_id = self.kernel_manager.xreq_channel.complete(
157 157 text, # text
158 158 self._get_input_buffer_cursor_line(), # line
159 159 self._get_input_buffer_cursor_column(), # cursor_pos
160 160 self.input_buffer) # block
161 161 self._complete_pos = self._get_cursor().position()
162 162
163 163 def _get_banner(self):
164 164 """ Reimplemented to return IPython's default banner.
165 165 """
166 166 return default_banner + '\n'
167 167
168 168 def _process_execute_error(self, msg):
169 169 """ Reimplemented for IPython-style traceback formatting.
170 170 """
171 171 content = msg['content']
172 172 traceback = '\n'.join(content['traceback']) + '\n'
173 173 if False:
174 174 # FIXME: For now, tracebacks come as plain text, so we can't use
175 175 # the html renderer yet. Once we refactor ultratb to produce
176 176 # properly styled tracebacks, this branch should be the default
177 177 traceback = traceback.replace(' ', '&nbsp;')
178 178 traceback = traceback.replace('\n', '<br/>')
179 179
180 180 ename = content['ename']
181 181 ename_styled = '<span class="error">%s</span>' % ename
182 182 traceback = traceback.replace(ename, ename_styled)
183 183
184 184 self._append_html(traceback)
185 185 else:
186 186 # This is the fallback for now, using plain text with ansi escapes
187 187 self._append_plain_text(traceback)
188 188
189 189 def _process_execute_payload(self, item):
190 190 """ Reimplemented to handle %edit and paging payloads.
191 191 """
192 192 if item['source'] == self._payload_source_edit:
193 193 self._edit(item['filename'], item['line_number'])
194 194 return True
195 195 elif item['source'] == self._payload_source_page:
196 196 self._page(item['data'])
197 197 return True
198 198 else:
199 199 return False
200 200
201 201 def _show_interpreter_prompt(self, number=None, input_sep='\n'):
202 202 """ Reimplemented for IPython-style prompts.
203 203 """
204 204 # If a number was not specified, make a prompt number request.
205 205 if number is None:
206 206 self.kernel_manager.xreq_channel.prompt()
207 207 return
208 208
209 209 # Show a new prompt and save information about it so that it can be
210 210 # updated later if the prompt number turns out to be wrong.
211 211 self._prompt_sep = input_sep
212 212 self._show_prompt(self._make_in_prompt(number), html=True)
213 213 block = self._control.document().lastBlock()
214 214 length = len(self._prompt)
215 215 self._previous_prompt_obj = IPythonPromptBlock(block, length, number)
216 216
217 217 # Update continuation prompt to reflect (possibly) new prompt length.
218 218 self._set_continuation_prompt(
219 219 self._make_continuation_prompt(self._prompt), html=True)
220 220
221 221 def _show_interpreter_prompt_for_reply(self, msg):
222 222 """ Reimplemented for IPython-style prompts.
223 223 """
224 224 # Update the old prompt number if necessary.
225 225 content = msg['content']
226 226 previous_prompt_number = content['prompt_number']
227 227 if self._previous_prompt_obj and \
228 228 self._previous_prompt_obj.number != previous_prompt_number:
229 229 block = self._previous_prompt_obj.block
230 230
231 231 # Make sure the prompt block has not been erased.
232 232 if block.isValid() and not block.text().isEmpty():
233 233
234 234 # Remove the old prompt and insert a new prompt.
235 235 cursor = QtGui.QTextCursor(block)
236 236 cursor.movePosition(QtGui.QTextCursor.Right,
237 237 QtGui.QTextCursor.KeepAnchor,
238 238 self._previous_prompt_obj.length)
239 239 prompt = self._make_in_prompt(previous_prompt_number)
240 240 self._prompt = self._insert_html_fetching_plain_text(
241 241 cursor, prompt)
242 242
243 243 # When the HTML is inserted, Qt blows away the syntax
244 244 # highlighting for the line, so we need to rehighlight it.
245 245 self._highlighter.rehighlightBlock(cursor.block())
246 246
247 247 self._previous_prompt_obj = None
248 248
249 249 # Show a new prompt with the kernel's estimated prompt number.
250 250 next_prompt = content['next_prompt']
251 251 self._show_interpreter_prompt(next_prompt['prompt_number'],
252 252 next_prompt['input_sep'])
253 253
254 254 #---------------------------------------------------------------------------
255 255 # 'IPythonWidget' interface
256 256 #---------------------------------------------------------------------------
257 257
258 258 def reset_styling(self):
259 259 """ Restores the default IPythonWidget styling.
260 260 """
261 261 self.set_styling(self.default_stylesheet, syntax_style='default')
262 262 #self.set_styling(self.dark_stylesheet, syntax_style='monokai')
263 263
264 264 def set_editor(self, editor, line_editor=None):
265 265 """ Sets the editor to use with the %edit magic.
266 266
267 267 Parameters:
268 268 -----------
269 269 editor : str
270 270 A command for invoking a system text editor. If the string contains
271 271 a {filename} format specifier, it will be used. Otherwise, the
272 272 filename will be appended to the end the command.
273 273
274 274 This parameter also takes a special value:
275 275 'custom' : Emit a 'custom_edit_requested(str, int)' signal
276 276 instead of opening an editor.
277 277
278 278 line_editor : str, optional
279 279 The editor command to use when a specific line number is
280 280 requested. The string should contain two format specifiers: {line}
281 281 and {filename}. If this parameter is not specified, the line number
282 282 option to the %edit magic will be ignored.
283 283 """
284 284 self._editor = editor
285 285 self._editor_line = line_editor
286 286
287 287 def set_styling(self, stylesheet, syntax_style=None):
288 288 """ Sets the IPythonWidget styling.
289 289
290 290 Parameters:
291 291 -----------
292 292 stylesheet : str
293 293 A CSS stylesheet. The stylesheet can contain classes for:
294 294 1. Qt: QPlainTextEdit, QFrame, QWidget, etc
295 295 2. Pygments: .c, .k, .o, etc (see PygmentsHighlighter)
296 296 3. IPython: .error, .in-prompt, .out-prompt, etc.
297 297
298 298 syntax_style : str or None [default None]
299 299 If specified, use the Pygments style with given name. Otherwise,
300 300 the stylesheet is queried for Pygments style information.
301 301 """
302 302 self.setStyleSheet(stylesheet)
303 303 self._control.document().setDefaultStyleSheet(stylesheet)
304 304 if self._page_control:
305 305 self._page_control.document().setDefaultStyleSheet(stylesheet)
306 306
307 307 if syntax_style is None:
308 308 self._highlighter.set_style_sheet(stylesheet)
309 309 else:
310 310 self._highlighter.set_style(syntax_style)
311 311
312 bg_color = self._control.palette().background().color()
313 self._ansi_processor.set_background_color(bg_color)
314
312 315 #---------------------------------------------------------------------------
313 316 # 'IPythonWidget' protected interface
314 317 #---------------------------------------------------------------------------
315 318
316 319 def _edit(self, filename, line=None):
317 320 """ Opens a Python script for editing.
318 321
319 322 Parameters:
320 323 -----------
321 324 filename : str
322 325 A path to a local system file.
323 326
324 327 line : int, optional
325 328 A line of interest in the file.
326 329 """
327 330 if self._editor == 'custom':
328 331 self.custom_edit_requested.emit(filename, line)
329 332 elif self._editor == 'default':
330 333 self._append_plain_text('No default editor available.\n')
331 334 else:
332 335 try:
333 336 filename = '"%s"' % filename
334 337 if line and self._editor_line:
335 338 command = self._editor_line.format(filename=filename,
336 339 line=line)
337 340 else:
338 341 try:
339 342 command = self._editor.format()
340 343 except KeyError:
341 344 command = self._editor.format(filename=filename)
342 345 else:
343 346 command += ' ' + filename
344 347 except KeyError:
345 348 self._append_plain_text('Invalid editor command.\n')
346 349 else:
347 350 try:
348 351 Popen(command, shell=True)
349 352 except OSError:
350 353 msg = 'Opening editor with command "%s" failed.\n'
351 354 self._append_plain_text(msg % command)
352 355
353 356 def _make_in_prompt(self, number):
354 357 """ Given a prompt number, returns an HTML In prompt.
355 358 """
356 359 body = self.in_prompt % number
357 360 return '<span class="in-prompt">%s</span>' % body
358 361
359 362 def _make_continuation_prompt(self, prompt):
360 363 """ Given a plain text version of an In prompt, returns an HTML
361 364 continuation prompt.
362 365 """
363 366 end_chars = '...: '
364 367 space_count = len(prompt.lstrip('\n')) - len(end_chars)
365 368 body = '&nbsp;' * space_count + end_chars
366 369 return '<span class="in-prompt">%s</span>' % body
367 370
368 371 def _make_out_prompt(self, number):
369 372 """ Given a prompt number, returns an HTML Out prompt.
370 373 """
371 374 body = self.out_prompt % number
372 375 return '<span class="out-prompt">%s</span>' % body
@@ -1,92 +1,88 b''
1 1 #!/usr/bin/env python
2 2
3 3 """ A minimal application using the Qt console-style IPython frontend.
4 4 """
5 5
6 6 # Systemm library imports
7 7 from PyQt4 import QtCore, QtGui
8 8
9 9 # Local imports
10 10 from IPython.external.argparse import ArgumentParser
11 11 from IPython.frontend.qt.console.frontend_widget import FrontendWidget
12 12 from IPython.frontend.qt.console.ipython_widget import IPythonWidget
13 13 from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
14 14 from IPython.frontend.qt.kernelmanager import QtKernelManager
15 15
16 16 # Constants
17 17 LOCALHOST = '127.0.0.1'
18 18
19 19
20 20 def main():
21 21 """ Entry point for application.
22 22 """
23 23 # Parse command line arguments.
24 24 parser = ArgumentParser()
25 25 parser.add_argument('-r', '--rich', action='store_true',
26 26 help='use a rich text frontend')
27 27 parser.add_argument('-t', '--tab-simple', action='store_true',
28 28 help='do tab completion ala a Unix terminal')
29 29
30 30 parser.add_argument('--existing', action='store_true',
31 31 help='connect to an existing kernel')
32 32 parser.add_argument('--ip', type=str, default=LOCALHOST,
33 33 help='set the kernel\'s IP address [default localhost]')
34 34 parser.add_argument('--xreq', type=int, metavar='PORT', default=0,
35 35 help='set the XREQ channel port [default random]')
36 36 parser.add_argument('--sub', type=int, metavar='PORT', default=0,
37 37 help='set the SUB channel port [default random]')
38 38 parser.add_argument('--rep', type=int, metavar='PORT', default=0,
39 39 help='set the REP channel port [default random]')
40 40
41 41 group = parser.add_mutually_exclusive_group()
42 42 group.add_argument('--pure', action='store_true', help = \
43 43 'use a pure Python kernel instead of an IPython kernel')
44 44 group.add_argument('--pylab', action='store_true',
45 45 help='use a kernel with PyLab enabled')
46 46
47 47 args = parser.parse_args()
48 48
49 49 # Don't let Qt or ZMQ swallow KeyboardInterupts.
50 50 import signal
51 51 signal.signal(signal.SIGINT, signal.SIG_DFL)
52 52
53 53 # Create a KernelManager and start a kernel.
54 54 kernel_manager = QtKernelManager(xreq_address=(args.ip, args.xreq),
55 55 sub_address=(args.ip, args.sub),
56 56 rep_address=(args.ip, args.rep))
57 57 if args.ip == LOCALHOST and not args.existing:
58 58 if args.pure:
59 59 kernel_manager.start_kernel(ipython=False)
60 60 elif args.pylab:
61 61 if args.rich:
62 62 kernel_manager.start_kernel(pylab='payload-svg')
63 63 else:
64 64 kernel_manager.start_kernel(pylab='qt4')
65 65 else:
66 66 kernel_manager.start_kernel()
67 67 kernel_manager.start_channels()
68 68
69 69 # Create the widget.
70 70 app = QtGui.QApplication([])
71 71 if args.pure:
72 72 kind = 'rich' if args.rich else 'plain'
73 73 widget = FrontendWidget(kind=kind)
74 74 elif args.rich:
75 75 widget = RichIPythonWidget()
76 76 else:
77 77 widget = IPythonWidget()
78 78 widget.gui_completion = not args.tab_simple
79 79 widget.kernel_manager = kernel_manager
80 80 widget.setWindowTitle('Python' if args.pure else 'IPython')
81 81 widget.show()
82 82
83 # FIXME: This is a hack: set colors to lightbg by default in qt terminal
84 # unconditionally, regardless of user settings in config files.
85 widget.execute("%colors lightbg", hidden=True)
86
87 83 # Start the application main loop.
88 84 app.exec_()
89 85
90 86
91 87 if __name__ == '__main__':
92 88 main()
General Comments 0
You need to be logged in to leave comments. Login now