/
confpage.py
440 lines (391 loc) · 20.1 KB
/
confpage.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
# -*- coding: utf-8 -*-
#
# Copyright © Spyder Project Contributors
# Licensed under the terms of the MIT License
# (see spyder/__init__.py for details)
"""IPython Console config page."""
# Standard library imports
import sys
# Third party imports
from qtpy.QtCore import Qt
from qtpy.QtWidgets import (QGridLayout, QGroupBox, QHBoxLayout, QLabel,
QTabWidget, QVBoxLayout)
# Local imports
from spyder.api.preferences import PluginConfigPage
from spyder.config.base import _
from spyder.py3compat import PY2
class IPythonConsoleConfigPage(PluginConfigPage):
def __init__(self, plugin, parent):
PluginConfigPage.__init__(self, plugin, parent)
self.get_name = lambda: _("IPython console")
def setup_page(self):
newcb = self.create_checkbox
# Interface Group
interface_group = QGroupBox(_("Interface"))
banner_box = newcb(_("Display initial banner"), 'show_banner',
tip=_("This option lets you hide the message "
"shown at\nthe top of the console when "
"it's opened."))
calltips_box = newcb(_("Show calltips"), 'show_calltips')
ask_box = newcb(_("Ask for confirmation before closing"),
'ask_before_closing')
reset_namespace_box = newcb(
_("Ask for confirmation before removing all user-defined "
"variables"),
'show_reset_namespace_warning',
tip=_("This option lets you hide the warning message shown\n"
"when resetting the namespace from Spyder."))
show_time_box = newcb(_("Show elapsed time"), 'show_elapsed_time')
ask_restart_box = newcb(
_("Ask for confirmation before restarting"),
'ask_before_restart',
tip=_("This option lets you hide the warning message shown\n"
"when restarting the kernel."))
interface_layout = QVBoxLayout()
interface_layout.addWidget(banner_box)
interface_layout.addWidget(calltips_box)
interface_layout.addWidget(ask_box)
interface_layout.addWidget(reset_namespace_box)
interface_layout.addWidget(show_time_box)
interface_layout.addWidget(ask_restart_box)
interface_group.setLayout(interface_layout)
comp_group = QGroupBox(_("Completion type"))
comp_label = QLabel(_("Decide what type of completion to use"))
comp_label.setWordWrap(True)
completers = [(_("Graphical"), 0), (_("Terminal"), 1), (_("Plain"), 2)]
comp_box = self.create_combobox(_("Completion:")+" ", completers,
'completion_type')
comp_layout = QVBoxLayout()
comp_layout.addWidget(comp_label)
comp_layout.addWidget(comp_box)
comp_group.setLayout(comp_layout)
# Source Code Group
source_code_group = QGroupBox(_("Source code"))
buffer_spin = self.create_spinbox(
_("Buffer: "), _(" lines"),
'buffer_size', min_=-1, max_=1000000, step=100,
tip=_("Set the maximum number of lines of text shown in the\n"
"console before truncation. Specifying -1 disables it\n"
"(not recommended!)"))
source_code_layout = QVBoxLayout()
source_code_layout.addWidget(buffer_spin)
source_code_group.setLayout(source_code_layout)
# --- Graphics ---
# Pylab Group
pylab_group = QGroupBox(_("Support for graphics (Matplotlib)"))
pylab_box = newcb(_("Activate support"), 'pylab')
autoload_pylab_box = newcb(
_("Automatically load Pylab and NumPy modules"),
'pylab/autoload',
tip=_("This lets you load graphics support without importing\n"
"the commands to do plots. Useful to work with other\n"
"plotting libraries different to Matplotlib or to develop\n"
"GUIs with Spyder."))
autoload_pylab_box.setEnabled(self.get_option('pylab'))
pylab_box.toggled.connect(autoload_pylab_box.setEnabled)
pylab_layout = QVBoxLayout()
pylab_layout.addWidget(pylab_box)
pylab_layout.addWidget(autoload_pylab_box)
pylab_group.setLayout(pylab_layout)
# Pylab backend Group
inline = _("Inline")
automatic = _("Automatic")
backend_group = QGroupBox(_("Graphics backend"))
bend_label = QLabel(_("Decide how graphics are going to be displayed "
"in the console. If unsure, please select "
"<b>%s</b> to put graphics inside the "
"console or <b>%s</b> to interact with "
"them (through zooming and panning) in a "
"separate window.") % (inline, automatic))
bend_label.setWordWrap(True)
backends = [(inline, 0), (automatic, 1), ("Qt5", 2), ("Qt4", 3)]
if sys.platform == 'darwin':
backends.append(("OS X", 4))
if sys.platform.startswith('linux'):
backends.append(("Gtk3", 5))
backends.append(("Gtk", 6))
if PY2:
backends.append(("Wx", 7))
backends.append(("Tkinter", 8))
backends = tuple(backends)
backend_box = self.create_combobox(
_("Backend:") + " ",
backends,
'pylab/backend', default=0,
tip=_("This option will be applied the next time a console is "
"opened."))
backend_layout = QVBoxLayout()
backend_layout.addWidget(bend_label)
backend_layout.addWidget(backend_box)
backend_group.setLayout(backend_layout)
backend_group.setEnabled(self.get_option('pylab'))
pylab_box.toggled.connect(backend_group.setEnabled)
# Inline backend Group
inline_group = QGroupBox(_("Inline backend"))
inline_label = QLabel(_("Decide how to render the figures created by "
"this backend"))
inline_label.setWordWrap(True)
formats = (("PNG", 0), ("SVG", 1))
format_box = self.create_combobox(_("Format:")+" ", formats,
'pylab/inline/figure_format',
default=0)
resolution_spin = self.create_spinbox(
_("Resolution:")+" ", " "+_("dpi"),
'pylab/inline/resolution', min_=50, max_=999, step=0.1,
tip=_("Only used when the format is PNG. Default is "
"72"))
width_spin = self.create_spinbox(
_("Width:")+" ", " "+_("inches"),
'pylab/inline/width', min_=2, max_=20, step=1,
tip=_("Default is 6"))
height_spin = self.create_spinbox(
_("Height:")+" ", " "+_("inches"),
'pylab/inline/height', min_=1, max_=20, step=1,
tip=_("Default is 4"))
bbox_inches_box = newcb(
_("Use a tight layout for inline plots"),
'pylab/inline/bbox_inches',
tip=_("Sets bbox_inches to \"tight\" when\n"
"plotting inline with matplotlib.\n"
"When enabled, can cause discrepancies\n"
"between the image displayed inline and\n"
"that created using savefig."))
inline_v_layout = QVBoxLayout()
inline_v_layout.addWidget(inline_label)
inline_layout = QGridLayout()
inline_layout.addWidget(format_box.label, 1, 0)
inline_layout.addWidget(format_box.combobox, 1, 1)
inline_layout.addWidget(resolution_spin.plabel, 2, 0)
inline_layout.addWidget(resolution_spin.spinbox, 2, 1)
inline_layout.addWidget(resolution_spin.slabel, 2, 2)
inline_layout.addWidget(width_spin.plabel, 3, 0)
inline_layout.addWidget(width_spin.spinbox, 3, 1)
inline_layout.addWidget(width_spin.slabel, 3, 2)
inline_layout.addWidget(height_spin.plabel, 4, 0)
inline_layout.addWidget(height_spin.spinbox, 4, 1)
inline_layout.addWidget(height_spin.slabel, 4, 2)
inline_layout.addWidget(bbox_inches_box, 5, 0, 1, 4)
inline_h_layout = QHBoxLayout()
inline_h_layout.addLayout(inline_layout)
inline_h_layout.addStretch(1)
inline_v_layout.addLayout(inline_h_layout)
inline_group.setLayout(inline_v_layout)
inline_group.setEnabled(self.get_option('pylab'))
pylab_box.toggled.connect(inline_group.setEnabled)
# --- Startup ---
# Run lines Group
run_lines_group = QGroupBox(_("Run code"))
run_lines_label = QLabel(_("You can run several lines of code when "
"a console is started. Please introduce "
"each one separated by semicolons and a "
"space, for example:<br>"
"<i>import os; import sys</i>"))
run_lines_label.setWordWrap(True)
run_lines_edit = self.create_lineedit(_("Lines:"), 'startup/run_lines',
'', alignment=Qt.Horizontal)
run_lines_layout = QVBoxLayout()
run_lines_layout.addWidget(run_lines_label)
run_lines_layout.addWidget(run_lines_edit)
run_lines_group.setLayout(run_lines_layout)
# Run file Group
run_file_group = QGroupBox(_("Run a file"))
run_file_label = QLabel(_("You can also run a whole file at startup "
"instead of just some lines (This is "
"similar to have a PYTHONSTARTUP file)."))
run_file_label.setWordWrap(True)
file_radio = newcb(_("Use the following file:"),
'startup/use_run_file', False)
run_file_browser = self.create_browsefile('', 'startup/run_file', '')
run_file_browser.setEnabled(False)
file_radio.toggled.connect(run_file_browser.setEnabled)
run_file_layout = QVBoxLayout()
run_file_layout.addWidget(run_file_label)
run_file_layout.addWidget(file_radio)
run_file_layout.addWidget(run_file_browser)
run_file_group.setLayout(run_file_layout)
# ---- Debug ----
# Pdb run lines Group
pdb_run_lines_group = QGroupBox(_("Run code while debugging"))
pdb_run_lines_label = QLabel(_(
"You can run several lines of code on each "
"new prompt while debugging. Please "
"introduce each one separated by semicolons "
"and a space, for example:<br>"
"<i>import matplotlib.pyplot as plt</i>"))
pdb_run_lines_label.setWordWrap(True)
pdb_run_lines_edit = self.create_lineedit(
_("Lines:"), 'startup/pdb_run_lines', '', alignment=Qt.Horizontal)
pdb_run_lines_layout = QVBoxLayout()
pdb_run_lines_layout.addWidget(pdb_run_lines_label)
pdb_run_lines_layout.addWidget(pdb_run_lines_edit)
pdb_run_lines_group.setLayout(pdb_run_lines_layout)
# Debug Group
debug_group = QGroupBox(_("Debug"))
debug_layout = QVBoxLayout()
prevent_closing_box = newcb(
_("Prevent editor from closing files while debugging"),
'pdb_prevent_closing',
tip=_("This option prevents the user from closing a file while"
" it is debugged."))
debug_layout.addWidget(prevent_closing_box)
continue_box = newcb(
_("Stop debugging on first line of files without breakpoints"),
'pdb_stop_first_line',
tip=_("This option lets you decide if the debugger should"
" stop on the first line while debugging if no breakpoints"
" are present."))
debug_layout.addWidget(continue_box)
libraries_box = newcb(
_("Ignore Python libraries while debugging"), 'pdb_ignore_lib',
tip=_("This option lets you decide if the debugger should "
"ignore the system libraries while debugging."))
debug_layout.addWidget(libraries_box)
execute_events_box = newcb(
_("Process execute events while debugging"), 'pdb_execute_events',
tip=_("This option lets you decide if the debugger should "
"process the 'execute events' after each prompt, such as "
"matplotlib 'show' command."))
debug_layout.addWidget(execute_events_box)
exclamation_mark_box = newcb(
_("Use exclamation mark prefix for Pdb commands"),
'pdb_use_exclamation_mark',
tip=_("This option lets you decide if the Pdb commands should "
"be prefixed by an exclamation mark. This helps in "
"separating Pdb commands from Python code."))
debug_layout.addWidget(exclamation_mark_box)
debug_group.setLayout(debug_layout)
# ---- Advanced settings ----
# Enable Jedi completion
jedi_group = QGroupBox(_("Jedi completion"))
jedi_label = QLabel(_("Enable Jedi-based <tt>Tab</tt> completion "
"in the IPython console; similar to the "
"greedy completer, but without evaluating "
"the code.<br>"
"<b>Warning:</b> Slows down your console "
"when working with large dataframes!"))
jedi_label.setWordWrap(True)
jedi_box = newcb(_("Use Jedi completion in the IPython console"),
"jedi_completer",
tip=_("<b>Warning</b>: "
"Slows down your console when working with "
"large dataframes!<br>"
"Allows completion of nested lists etc."))
jedi_layout = QVBoxLayout()
jedi_layout.addWidget(jedi_label)
jedi_layout.addWidget(jedi_box)
jedi_group.setLayout(jedi_layout)
# Greedy completer group
greedy_group = QGroupBox(_("Greedy completion"))
greedy_label = QLabel(_("Enable <tt>Tab</tt> completion on elements "
"of lists, results of function calls, etc, "
"<i>without</i> assigning them to a variable, "
"like <tt>li[0].<Tab></tt> or "
"<tt>ins.meth().<Tab></tt> <br>"
"<b>Warning:</b> Due to a bug, IPython's "
"greedy completer requires a leading "
"<tt><Space></tt> for some completions; "
"e.g. <tt>np.sin(<Space>np.<Tab>"
"</tt> works while <tt>np.sin(np.<Tab> "
"</tt> doesn't."))
greedy_label.setWordWrap(True)
greedy_box = newcb(_("Use greedy completion in the IPython console"),
"greedy_completer",
tip="<b>Warning</b>: It can be unsafe because the "
"code is actually evaluated when you press "
"<tt>Tab</tt>.")
greedy_layout = QVBoxLayout()
greedy_layout.addWidget(greedy_label)
greedy_layout.addWidget(greedy_box)
greedy_group.setLayout(greedy_layout)
# Autocall group
autocall_group = QGroupBox(_("Autocall"))
autocall_label = QLabel(_("Autocall makes IPython automatically call "
"any callable object even if you didn't "
"type explicit parentheses.<br>"
"For example, if you type <i>str 43</i> it "
"becomes <i>str(43)</i> automatically."))
autocall_label.setWordWrap(True)
smart = _('Smart')
full = _('Full')
autocall_opts = ((_('Off'), 0), (smart, 1), (full, 2))
autocall_box = self.create_combobox(
_("Autocall: "), autocall_opts, 'autocall', default=0,
tip=_("On <b>%s</b> mode, Autocall is not applied if "
"there are no arguments after the callable. On "
"<b>%s</b> mode, all callable objects are "
"automatically called (even if no arguments are "
"present).") % (smart, full))
autocall_layout = QVBoxLayout()
autocall_layout.addWidget(autocall_label)
autocall_layout.addWidget(autocall_box)
autocall_group.setLayout(autocall_layout)
# Sympy group
sympy_group = QGroupBox(_("Symbolic mathematics"))
sympy_label = QLabel(_("Perfom symbolic operations in the console "
"(e.g. integrals, derivatives, vector "
"calculus, etc) and get the outputs in a "
"beautifully printed style (it requires the "
"Sympy module)."))
sympy_label.setWordWrap(True)
sympy_box = newcb(_("Use symbolic math"), "symbolic_math",
tip=_("This option loads the Sympy library to work "
"with.<br>Please refer to its documentation "
"to learn how to use it."))
sympy_layout = QVBoxLayout()
sympy_layout.addWidget(sympy_label)
sympy_layout.addWidget(sympy_box)
sympy_group.setLayout(sympy_layout)
# Prompts group
prompts_group = QGroupBox(_("Prompts"))
prompts_label = QLabel(_("Modify how Input and Output prompts are "
"shown in the console."))
prompts_label.setWordWrap(True)
in_prompt_edit = self.create_lineedit(
_("Input prompt:"),
'in_prompt', '',
_('Default is<br>'
'In [<span class="in-prompt-number">'
'%i</span>]:'),
alignment=Qt.Horizontal)
out_prompt_edit = self.create_lineedit(
_("Output prompt:"),
'out_prompt', '',
_('Default is<br>'
'Out[<span class="out-prompt-number">'
'%i</span>]:'),
alignment=Qt.Horizontal)
prompts_layout = QVBoxLayout()
prompts_layout.addWidget(prompts_label)
prompts_g_layout = QGridLayout()
prompts_g_layout.addWidget(in_prompt_edit.label, 0, 0)
prompts_g_layout.addWidget(in_prompt_edit.textbox, 0, 1)
prompts_g_layout.addWidget(out_prompt_edit.label, 1, 0)
prompts_g_layout.addWidget(out_prompt_edit.textbox, 1, 1)
prompts_layout.addLayout(prompts_g_layout)
prompts_group.setLayout(prompts_layout)
# Windows adjustments
windows_group = QGroupBox(_("Windows adjustments"))
hide_cmd_windows = newcb(
_("Hide command line output windows "
"generated by the subprocess module."),
'hide_cmd_windows')
windows_layout = QVBoxLayout()
windows_layout.addWidget(hide_cmd_windows)
windows_group.setLayout(windows_layout)
# --- Tabs organization ---
self.tabs = QTabWidget()
self.tabs.addTab(self.create_tab(interface_group, comp_group,
source_code_group), _("Display"))
self.tabs.addTab(self.create_tab(
pylab_group, backend_group, inline_group), _("Graphics"))
self.tabs.addTab(self.create_tab(
run_lines_group, run_file_group), _("Startup"))
self.tabs.addTab(self.create_tab(
debug_group, pdb_run_lines_group), _("Debugger"))
self.tabs.addTab(self.create_tab(
jedi_group, greedy_group, autocall_group,
sympy_group, prompts_group,
windows_group), _("Advanced settings"))
vlayout = QVBoxLayout()
vlayout.addWidget(self.tabs)
self.setLayout(vlayout)