def toggle_codecompletion(self, checked): """Toggle code completion""" if self.tabwidget is None: return for shell in self.shells: shell.shell.set_codecompletion(checked) CONF.set(self.ID, 'autocompletion/enabled', checked)
def open_interpreter_at_startup(self): """Open an interpreter at startup, IPython if module is available""" if CONF.get(self.ID, 'open_ipython_at_startup') \ and programs.is_module_installed("IPython"): self.open_ipython() if CONF.get(self.ID, 'open_python_at_startup'): self.open_interpreter()
def toggle_codecompletion_enter(self, checked): """Toggle Enter key for code completion""" if self.tabwidget is None: return for shell in self.shells: shell.shell.set_codecompletion_enter(checked) CONF.set(self.ID, 'autocompletion/enter-key', checked)
def toggle_wrap_mode(self, checked): """Toggle wrap mode""" if self.tabwidget is None: return for shell in self.shells: shell.shell.toggle_wrap_mode(checked) CONF.set(self.ID, 'wrap', checked)
def option_changed(self, option, value): """ Change a plugin option in configuration file Use a SIGNAL to call it, e.g.: self.emit(SIGNAL('option_changed'), 'show_all', checked) """ CONF.set(self.ID, option, value)
def toggle_wrap_mode(self, checked): """Toggle wrap mode""" if self.tabwidget is None: return for editor in self.editors: editor.toggle_wrap_mode(checked) CONF.set(self.ID, 'wrap', checked)
def __init__(self, parent): PluginWidget.__init__(self, parent) # Read-only editor self.editor = QsciEditor(self) self.editor.setup_editor(linenumbers=False, language='py', code_folding=True) self.connect(self.editor, SIGNAL("focus_changed()"), lambda: self.emit(SIGNAL("focus_changed()"))) self.editor.setReadOnly(True) self.editor.set_font( get_font(self.ID) ) self.editor.toggle_wrap_mode( CONF.get(self.ID, 'wrap') ) # Add entries to read-only editor context-menu font_action = create_action(self, translate("Editor", "&Font..."), None, 'font.png', translate("Editor", "Set font style"), triggered=self.change_font) wrap_action = create_action(self, translate("Editor", "Wrap lines"), toggled=self.toggle_wrap_mode) wrap_action.setChecked( CONF.get(self.ID, 'wrap') ) self.editor.readonly_menu.addSeparator() add_actions(self.editor.readonly_menu, (font_action, wrap_action)) # Find/replace widget self.find_widget = FindReplace(self) self.find_widget.set_editor(self.editor) self.find_widget.hide()
def __init__(self, parent): PydocBrowser.__init__(self, parent) SpyderPluginMixin.__init__(self, parent) self.set_zoom_factor(CONF.get(self.ID, 'zoom_factor')) self.url_combo.setMaxCount(CONF.get(self.ID, 'max_history_entries')) self.url_combo.addItems( self.load_history() )
def run(self, session): from spyderlib import spyder from spyderlib.config import CONF cs.exit_if_not_exists(session) app = spyder.initialize() # This should come from our command line parser, however, Spyder does # not provide a way to get the argument parser but only the parsed # arguments. opts = {'working_directory': cs.path(), 'debug': False, 'profile': False, 'multithreaded': False, 'light': False, 'new_instance': True} # The python executable is set explicitly here, because Spyder tends # not to pick up the one used in a virtualenv. This should be set in a # profile in order to not mess with the user's settings. CONF.set('console', 'pythonexecutable', sys.executable) main = spyder.MainWindow(Bunch(opts)) main.setup() main.show() main.open_file(cs.path(session)) app.exec_()
def toggle_calltips(self, checked): """Toggle calltips""" if self.tabwidget is None: return for shell in self.shells: shell.shell.set_calltips(checked) CONF.set(self.ID, 'calltips', checked)
def toggle_codecompletion(self, checked): """Toggle automatic code completion""" if self.tabwidget is None: return for shell in self.shells: shell.shell.set_codecompletion_auto(checked) CONF.set(self.ID, 'codecompletion/auto', checked)
def long_banner(self): """Banner for IPython widgets with pylab message""" from IPython.core.usage import default_gui_banner banner = default_gui_banner pylab_o = CONF.get('ipython_console', 'pylab', True) autoload_pylab_o = CONF.get('ipython_console', 'pylab/autoload', True) mpl_installed = programs.is_module_installed('matplotlib') if mpl_installed and (pylab_o and autoload_pylab_o): pylab_message = ("\nPopulating the interactive namespace from " "numpy and matplotlib") banner = banner + pylab_message sympy_o = CONF.get('ipython_console', 'symbolic_math', True) if sympy_o: lines = """ These commands were executed: >>> from __future__ import division >>> from sympy import * >>> x, y, z, t = symbols('x y z t') >>> k, m, n = symbols('k m n', integer=True) >>> f, g, h = symbols('f g h', cls=Function) """ banner = banner + lines return banner
def show_banner(self): """Banner for IPython widgets with pylab message""" from IPython.core.usage import default_gui_banner banner = default_gui_banner pylab_o = CONF.get('ipython_console', 'pylab', True) autoload_pylab_o = CONF.get('ipython_console', 'pylab/autoload', True) mpl_installed = programs.is_module_installed('matplotlib') if mpl_installed and (pylab_o and autoload_pylab_o): backend_o = CONF.get('ipython_console', 'pylab/backend', 0) backends = {0: 'module://IPython.zmq.pylab.backend_inline', 1: 'Qt4Agg', 2: 'Qt4Agg', 3: 'MacOSX', 4: 'GTKAgg', 5: 'WXAgg', 6: 'TKAgg'} pylab_013_message = """ Welcome to pylab, a matplotlib-based Python environment [backend: %s]. For more information, type 'help(pylab)'.\n""" % backends[backend_o] pylab_1_message = """ Populating the interactive namespace from numpy and matplotlib""" if programs.is_module_installed('IPython', '>=1.0'): banner = banner + pylab_1_message else: banner = banner + pylab_013_message sympy_o = CONF.get('ipython_console', 'symbolic_math', True) if sympy_o: lines = """ These commands were executed: >>> from __future__ import division >>> from sympy import * >>> x, y, z, t = symbols('x y z t') >>> k, m, n = symbols('k m n', integer=True) >>> f, g, h = symbols('f g h', cls=Function) """ banner = banner + lines return banner
def set_option(self, option, value): """ Set a plugin option in configuration file Use a SIGNAL to call it, e.g.: plugin.sig_option_changed.emit('show_all', checked) """ CONF.set(self.CONF_SECTION, str(option), value)
def change_history_depth(self): "Change history max entries""" depth, valid = QInputDialog.getInteger(self, self.tr('History'), self.tr('Maximum entries'), CONF.get(self.ID, 'max_entries'), 10, 10000) if valid: CONF.set(self.ID, 'max_entries', depth)
def change_exteditor(self): """Change external editor path""" path, valid = QInputDialog.getText(self, self.tr('External editor'), self.tr('External editor executable path:'), QLineEdit.Normal, CONF.get(self.ID, 'external_editor/path')) if valid: CONF.set(self.ID, 'external_editor/path', unicode(path))
def save_config(self): """Save configuration: opened projects & tree widget state""" data = self.get_project_config() cPickle.dump(data, file(self.DATAPATH, 'w')) CONF.set(self.ID, 'expanded_state', self.treewidget.get_expanded_state()) CONF.set(self.ID, 'scrollbar_position', self.treewidget.get_scrollbar_position())
def setup(self): """Configure QTextEdit""" # Calltips self.calltip_size = CONF.get('shell_appearance', 'calltips/size') self.calltip_font = get_font('shell_appearance', 'calltips') # Completion self.completion_size = CONF.get('shell_appearance', 'completion/size') self.completion_font = get_font('shell_appearance', 'completion')
def _get_run_configurations(): history_count = CONF.get('run', 'history', 20) try: return [(filename, options) for filename, options in CONF.get('run', 'configurations', []) if osp.isfile(filename)][:history_count] except ValueError: CONF.set('run', 'configurations', []) return []
def change_max_line_count(self): "Change maximum line count""" mlc, valid = QInputDialog.getInteger(self, self.tr('Buffer'), self.tr('Maximum line count'), CONF.get(self.ID, 'max_line_count'), 10, 1000000) if valid: self.shell.setMaximumBlockCount(mlc) CONF.set(self.ID, 'max_line_count', mlc)
def update_margins(self): layout = self.layout() if self.default_margins is None: self.default_margins = layout.getContentsMargins() if CONF.get('main', 'use_custom_margin'): margin = CONF.get('main', 'custom_margin') layout.setContentsMargins(*[margin]*4) else: layout.setContentsMargins(*self.default_margins)
def setup(self): """Configure QPlainTextEdit""" # Calltips self.calltip_size = CONF.get('shell_appearance', 'calltips/size') self.calltip_font = get_font('shell_appearance', 'calltips') # Completion size = CONF.get('shell_appearance', 'completion/size') font = get_font('shell_appearance', 'completion') self.completion_widget.setup_appearance(size, font)
def set_ipython_options(self): """Set IPython interpreter arguments""" arguments, valid = QInputDialog.getText(self, self.tr('IPython'), self.tr('IPython command line options:\n' '(Qt4 support: -q4thread)\n' '(Qt4 and matplotlib support: -q4thread -pylab)'), QLineEdit.Normal, CONF.get(self.ID, 'ipython_options')) if valid: CONF.set(self.ID, 'ipython_options', unicode(arguments))
def toggle_rollbackimporter(self, checked): """Toggle rollback importer""" CONF.set(self.ID, 'rollback_importer', checked) if checked and self.isVisible(): QMessageBox.warning(self, self.get_widget_title(), self.tr("The rollback importer requires a restart " "of Spyder to be fully functionnal " "(otherwise only newly imported modules " "will be reloaded when executing scripts)."), QMessageBox.Ok)
def toggle_icontext(self, checked): """Toggle icon text""" CONF.set(self.ID, 'show_icontext', checked) if self.tabwidget is None: return for index in range(self.tabwidget.count()): for widget in self.tabwidget.widget(index).get_toolbar_buttons(): if checked: widget.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) else: widget.setToolButtonStyle(Qt.ToolButtonIconOnly)
def __init__(self, parent): ReadOnlyEditor.__init__(self, parent) self.shell = None self.external_console = None # locked = disable link with Console self.locked = False self._last_text = None # Object name layout_edit = QHBoxLayout() layout_edit.addWidget(QLabel(self.tr("Object"))) self.combo = ObjectComboBox(self) layout_edit.addWidget(self.combo) self.combo.setMaxCount(CONF.get(self.ID, 'max_history_entries')) self.combo.addItems( self.load_history() ) self.connect(self.combo, SIGNAL("valid(bool)"), lambda valid: self.force_refresh()) # Doc/source option help_or_doc = create_action(self, self.tr("Show source"), toggled=self.toggle_help) help_or_doc.setChecked(False) self.docstring = True # Automatic import option auto_import = create_action(self, self.tr("Automatic import"), toggled=self.toggle_auto_import) auto_import_state = CONF.get('inspector', 'automatic_import') auto_import.setChecked(auto_import_state) # Lock checkbox self.locked_button = create_toolbutton(self, triggered=self.toggle_locked) layout_edit.addWidget(self.locked_button) self._update_lock_icon() # Option menu options_button = create_toolbutton(self, text=self.tr("Options"), icon=get_icon('tooloptions.png')) options_button.setPopupMode(QToolButton.InstantPopup) menu = QMenu(self) add_actions(menu, [help_or_doc, auto_import]) options_button.setMenu(menu) layout_edit.addWidget(options_button) # Main layout layout = QVBoxLayout() layout.addLayout(layout_edit) layout.addWidget(self.editor) layout.addWidget(self.find_widget) self.setLayout(layout)
def wsfilter(input_dict, itermax=ITERMAX, filters=FILTERS): """Keep only objects that can be pickled""" exclude_private = CONF.get('workspace', 'exclude_private') exclude_upper = CONF.get('workspace', 'exclude_upper') exclude_unsupported = CONF.get('workspace', 'exclude_unsupported') excluded_names = CONF.get('workspace', 'excluded_names') return globalsfilter(input_dict, itermax=itermax, filters=filters, exclude_private=exclude_private, exclude_upper=exclude_upper, exclude_unsupported=exclude_unsupported, excluded_names=excluded_names)
def __init__(self, parent=None): QDialog.__init__(self, parent) self.main = parent # Widgets self.pages_widget = QStackedWidget() self.contents_widget = QListWidget() self.button_reset = QPushButton(_('Reset to defaults')) bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) # Widgets setup # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.setWindowTitle(_('Preferences')) self.setWindowIcon(ima.icon('configure')) self.contents_widget.setMovement(QListView.Static) self.contents_widget.setSpacing(1) self.contents_widget.setCurrentRow(0) # Layout hsplitter = QSplitter() hsplitter.addWidget(self.contents_widget) hsplitter.addWidget(self.pages_widget) btnlayout = QHBoxLayout() btnlayout.addWidget(self.button_reset) btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(hsplitter) vlayout.addLayout(btnlayout) self.setLayout(vlayout) # Signals and slots self.button_reset.clicked.connect(self.main.reset_spyder) self.pages_widget.currentChanged.connect(self.current_page_changed) self.contents_widget.currentRowChanged.connect( self.pages_widget.setCurrentIndex) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) bbox.clicked.connect(self.button_clicked) # Ensures that the config is present on spyder first run CONF.set('main', 'interface_language', load_lang_conf())
def __init__(self, parent, history_filename, debug=False, profile=False): """ parent : specifies the parent widget """ ConsoleBaseWidget.__init__(self, parent) # Prompt position: tuple (line, index) self.current_prompt_pos = None self.new_input_line = True # History self.histidx = None self.hist_wholeline = False assert isinstance(history_filename, (str, unicode)) self.history_filename = history_filename self.history = self.load_history() # Session self.historylog_filename = CONF.get('main', 'historylog_filename', get_conf_path('history.log')) # Context menu self.menu = None self.setup_context_menu() # Debug mode self.debug = debug # Simple profiling test self.profile = profile # Buffer to increase performance of write/flush operations self.__buffer = [] self.__timestamp = 0.0 self.__flushtimer = QTimer(self) self.__flushtimer.setSingleShot(True) self.connect(self.__flushtimer, SIGNAL('timeout()'), self.flush) # Give focus to widget self.setFocus() # Calltips calltip_size = CONF.get('shell_appearance', 'calltips/size') calltip_font = get_font('shell_appearance', 'calltips') self.setup_calltips(calltip_size, calltip_font) # Completion completion_size = CONF.get('shell_appearance', 'completion/size') completion_font = get_font('shell_appearance', 'completion') self.completion_widget.setup_appearance(completion_size, completion_font) # Cursor width self.setCursorWidth( CONF.get('shell_appearance', 'cursor/width') )
def external_editor(self, filename, goto=-1): """Edit in an external editor Recommended: SciTE (e.g. to go to line where an error did occur)""" editor_path = CONF.get('internal_console', 'external_editor/path') goto_option = CONF.get('internal_console', 'external_editor/gotoline') try: if goto > 0 and goto_option: Popen(r'%s "%s" %s%d' % (editor_path, filename, goto_option, goto)) else: Popen(r'%s "%s"' % (editor_path, filename)) except OSError: self.write_error("External editor was not found:" " %s\n" % editor_path)
def setup_api(self): """Load and prepare API""" if self.lexer() is None: return self.api = QsciAPIs(self.lexer()) is_api_ready = False api_path = CONF.get('editor', 'api') if not os.path.isfile(api_path): return False api_stat = CONF.get('editor', 'api_stat', None) current_api_stat = os.stat(api_path) if (api_stat is not None) and (api_stat == current_api_stat): if self.api.isPrepared(): is_api_ready = self.api.loadPrepared() else: CONF.set('editor', 'api_stat', current_api_stat) if not is_api_ready: if self.api.load(api_path): self.api.prepare() self.connect(self.api, SIGNAL("apiPreparationFinished()"), self.api.savePrepared) return is_api_ready
def __init__(self, parent=None, namespace=None, commands=None, message="", font=None, debug=False, exitfunc=None, profile=False): PythonShellWidget.__init__(self, parent, get_conf_path('.history_ic.py'), debug, profile) if font is not None: self.set_font(font) # Capture all interactive input/output self.initial_stdout = sys.stdout self.initial_stderr = sys.stderr self.initial_stdin = sys.stdin self.stdout = IOHandler('<spyder_stdout>', 'w', write_func=self.write, flush_func=lambda: self.flush(error=False)) self.stderr = IOHandler('<spyder_stderr>', 'w', write_func=self.write_error, flush_func=lambda: self.flush(error=True)) self.stdin = IOHandler('<spyder_stdin>', 'r', read_func=self.wait_input) self.redirect_stds() # KeyboardInterrupt support self.interrupted = False self.connect(self, SIGNAL("keyboard_interrupt()"), self.keyboard_interrupt) # Code completion / calltips getcfg = lambda option: CONF.get('shell', option) case_sensitive = getcfg('autocompletion/case-sensitivity') show_single = getcfg('autocompletion/select-single') from_document = getcfg('autocompletion/from-document') self.setup_code_completion(case_sensitive, show_single, from_document) # keyboard events management self.busy = False self.eventqueue = [] # Execution Status self.more = False # Init interpreter self.exitfunc = exitfunc self.commands = commands self.message = message self.interpreter = None self.start_interpreter(namespace) # Clear status bar self.emit(SIGNAL("status(QString)"), QString())
def main(): """Start Spyder application. If single instance mode is turned on (default behavior) and an instance of Spyder is already running, this will just parse and send command line options to the application.""" # Renaming old configuration files (the '.' prefix has been removed) # (except for .spyder.ini --> spyder.ini, which is done in userconfig.py) if DEV is None: cpath = get_conf_path() for fname in os.listdir(cpath): if fname.startswith('.'): old, new = osp.join(cpath, fname), osp.join(cpath, fname[1:]) try: os.rename(old, new) except OSError: pass # Parse command line options options, args = get_options() # Check if we are running from our Mac app if sys.platform == "darwin" and 'Spyder.app' in __file__: mac_app = True else: mac_app = False if CONF.get('main', 'single_instance') and not options.new_instance \ and not mac_app: # Minimal delay (0.1-0.2 secs) to avoid that several # instances started at the same time step in their # own foots while trying to create the lock file time.sleep(random.randrange(1000, 2000, 90)/10000.) # Lock file creation lockf = get_conf_path('spyder.lock') lock = lockfile.FilesystemLock(lockf) # lock.lock() tries to lock spyder.lock. If it fails, # it returns False and so we try to start the client if not lock.lock(): if args: send_args_to_spyder(args) else: if TEST is None: atexit.register(lock.unlock) from spyderlib import spyder spyder.main() else: from spyderlib import spyder spyder.main()
def icon(name, resample=False): theme = CONF.get('main', 'icon_theme') if theme == 'spyder 3': if not _resource['loaded']: qta.load_font('spyder', 'spyder.ttf', 'spyder-charmap.json', directory=_resource['directory']) _resource['loaded'] = True args, kwargs = _qtaargs[name] return qta.icon(*args, **kwargs) elif theme == 'spyder 2': icon = get_icon(name + '.png', resample=resample) return icon if icon is not None else QIcon()
def remove_deprecated_shortcuts(data): """Remove deprecated shortcuts (shortcuts in CONF but not registered)""" section = 'shortcuts' options = [('%s/%s' % (context, name)).lower() for (context, name) in data] for option, _ in CONF.items(section, raw=CONF.raw): if option not in options: CONF.remove_option(section, option) if len(CONF.items(section, raw=CONF.raw)) == 0: CONF.remove_section(section)
def __init__(self, parent=None, namespace=None, commands=[], message=None, max_line_count=300, font=None, exitfunc=None, profile=False, multithreaded=True, light_background=True): PythonShellWidget.__init__(self, parent, get_conf_path('history_internal.py'), profile) self.set_light_background(light_background) self.multithreaded = multithreaded self.setMaximumBlockCount(max_line_count) # For compatibility with ExtPythonShellWidget self.is_ipykernel = False if font is not None: self.set_font(font) # Allow raw_input support: self.input_loop = None self.input_mode = False # KeyboardInterrupt support self.interrupted = False # used only for not-multithreaded mode self.connect(self, SIGNAL("keyboard_interrupt()"), self.keyboard_interrupt) # Code completion / calltips getcfg = lambda option: CONF.get('internal_console', option) case_sensitive = getcfg('codecompletion/case_sensitive') self.set_codecompletion_case(case_sensitive) # keyboard events management self.eventqueue = [] # Init interpreter self.exitfunc = exitfunc self.commands = commands self.message = message self.interpreter = None self.start_interpreter(namespace) # Clear status bar self.emit(SIGNAL("status(QString)"), '') # Embedded shell -- requires the monitor (which installs the # 'open_in_spyder' function in builtins) if hasattr(builtins, 'open_in_spyder'): self.connect(self, SIGNAL("go_to_error(QString)"), self.open_with_external_spyder)
def __init__(self, parent=None): supported_encodings = CONF.get(self.ID, 'supported_encodings') search_path = CONF.get(self.ID, 'search_path', None) self.search_text_samples = CONF.get(self.ID, 'search_text_samples') search_text = CONF.get(self.ID, 'search_text') search_text = [txt for txt in search_text \ if txt not in self.search_text_samples] search_text += self.search_text_samples search_text_regexp = CONF.get(self.ID, 'search_text_regexp') include = CONF.get(self.ID, 'include') include_regexp = CONF.get(self.ID, 'include_regexp') exclude = CONF.get(self.ID, 'exclude') exclude_regexp = CONF.get(self.ID, 'exclude_regexp') FindInFilesWidget.__init__(self, parent, search_text, search_text_regexp, search_path, include, include_regexp, exclude, exclude_regexp, supported_encodings) PluginMixin.__init__(self, parent) self.connect(self, SIGNAL('toggle_visibility(bool)'), self.toggle)
def set_color_scheme(name, color_scheme, replace=True): """Set syntax color scheme""" section = "color_schemes" names = CONF.get("color_schemes", "names", []) for key in sh.COLOR_SCHEME_KEYS: option = "%s/%s" % (name, key) value = CONF.get(section, option, default=None) if value is None or replace or name not in names: CONF.set(section, option, color_scheme[key]) names.append(to_text_string(name)) CONF.set(section, "names", sorted(list(set(names))))
def __init__(self, parent=None, namespace=None, commands=None, message="", debug=False, exitfunc=None, profile=False): # Shell self.shell = InteractiveShell(parent, namespace, commands, message, get_font(self.ID), debug, exitfunc, profile) self.connect( self.shell, SIGNAL('status(QString)'), lambda msg: self.emit(SIGNAL('show_message(QString,int)'), msg, 0)) self.connect(self.shell, SIGNAL("go_to_error(QString)"), self.go_to_error) self.connect(self.shell, SIGNAL("focus_changed()"), lambda: self.emit(SIGNAL("focus_changed()"))) # Redirecting some SIGNALs: self.connect( self.shell, SIGNAL('redirect_stdio(bool)'), lambda state: self.emit(SIGNAL('redirect_stdio(bool)'), state)) PluginWidget.__init__(self, parent) # Find/replace widget self.find_widget = FindReplace(self) self.find_widget.set_editor(self.shell) self.find_widget.hide() # Main layout layout = QVBoxLayout() layout.addWidget(self.shell) layout.addWidget(self.find_widget) self.setLayout(layout) # Parameters self.shell.toggle_wrap_mode(CONF.get(self.ID, 'wrap')) self.connect(self, SIGNAL("executing_command(bool)"), self.change_cursor) # Accepting drops self.setAcceptDrops(True)
def setup(self): """Reimplement TextEditBaseWidget method""" TextEditBaseWidget.setup(self) # Wrapping if CONF.get('editor', 'wrapflag'): self.setWrapVisualFlags(QsciScintilla.WrapFlagByBorder) # Indentation self.setIndentationGuides(True) self.setIndentationGuidesForegroundColor(Qt.lightGray) # 80-columns edge self.setEdgeColumn(80) self.setEdgeMode(QsciScintilla.EdgeLine) # Auto-completion self.setAutoCompletionSource(QsciScintilla.AcsAll)
def set_actions(self): """Setup actions""" history_action = create_action(self, self.tr("History..."), None, 'history.png', self.tr("Set history maximum entries"), triggered=self.change_history_depth) font_action = create_action(self, self.tr("&Font..."), None, 'font.png', self.tr("Set shell font style"), triggered=self.change_font) wrap_action = create_action(self, self.tr("Wrap lines"), toggled=self.toggle_wrap_mode) wrap_action.setChecked(CONF.get(self.ID, 'wrap')) self.menu_actions = [history_action, font_action, wrap_action] return (self.menu_actions, None)
def setup(self): """Configure Scintilla""" # UTF-8 self.setUtf8(True) # Indentation self.setAutoIndent(True) self.setIndentationsUseTabs(False) self.setIndentationWidth(4) self.setTabIndents(True) self.setBackspaceUnindents(True) self.setTabWidth(4) # Enable brace matching self.setBraceMatching(QsciScintilla.SloppyBraceMatch) self.setMatchedBraceBackgroundColor(Qt.yellow) # Calltips self.calltip_size = CONF.get('shell_appearance', 'calltips/size') self.calltip_font = get_font('shell_appearance', 'calltips')
def set_pythonshell_font(self, font=None): """Python Shell only""" if font is None: font = QFont() for format in self.formats: format.setFont(font) getstyleconf = lambda name, prop: CONF.get('shell_appearance', name+'/'+prop) for format, stylestr in self.formats.iteritems(): foreground = getstyleconf(stylestr, 'foregroundcolor') format.setForeground(QColor(foreground)) background = getstyleconf(stylestr, 'backgroundcolor') format.setBackground(QColor(background)) font = format.font() font.setBold(getstyleconf(stylestr, 'bold')) font.setItalic(getstyleconf(stylestr, 'italic')) font.setUnderline(getstyleconf(stylestr, 'underline')) format.setFont(font)
def load_history(self): """Load history from a .py file in user home directory""" if osp.isfile(self.history_filename): rawhistory, _ = encoding.readlines(self.history_filename) rawhistory = [line.replace('\n', '') for line in rawhistory] if rawhistory[1] != self.INITHISTORY[1]: rawhistory = self.INITHISTORY else: rawhistory = self.INITHISTORY history = [line for line in rawhistory \ if line and not line.startswith('#')] # Truncating history to X entries: while len(history) >= CONF.get('historylog', 'max_entries'): del history[0] while rawhistory[0].startswith('#'): del rawhistory[0] del rawhistory[0] # Saving truncated history: encoding.writelines(rawhistory, self.history_filename) return history
def set_pythonshell_font(self, font): """Python Shell only""" family = str(font.family()) size = font.pointSize() for style in self.STYLES: self.SendScintilla(QsciScintilla.SCI_STYLESETFONT, style, family) self.SendScintilla(QsciScintilla.SCI_STYLESETSIZE, style, size) getstyleconf = lambda name, prop: CONF.get('shell_appearance', name+'/'+prop) for style, stylestr in self.STYLES.iteritems(): foreground = colorfix(getstyleconf(stylestr, 'foregroundcolor')) background = colorfix(getstyleconf(stylestr, 'backgroundcolor')) self.SendScintilla(QsciScintilla.SCI_STYLESETFORE, style, foreground) self.SendScintilla(QsciScintilla.SCI_STYLESETBACK, style, background) self.SendScintilla(QsciScintilla.SCI_STYLESETBOLD, style, getstyleconf(stylestr, 'bold')) self.SendScintilla(QsciScintilla.SCI_STYLESETITALIC, style, getstyleconf(stylestr, 'italic')) self.SendScintilla(QsciScintilla.SCI_STYLESETUNDERLINE, style, getstyleconf(stylestr, 'underline'))
def setup_page(self): settings_group = QGroupBox(_("Settings")) hist_spin = self.create_spinbox(_("History depth: "), _(" entries"), 'max_entries', min_=10, max_=10000, step=10, tip=_("Set maximum line count")) sourcecode_group = QGroupBox(_("Source code")) wrap_mode_box = self.create_checkbox(_("Wrap lines"), 'wrap') go_to_eof_box = self.create_checkbox( _("Scroll automatically to last entry"), 'go_to_eof') font_group = self.create_fontgroup( option=None, text=_("Font style"), fontfilters=QFontComboBox.MonospacedFonts) names = CONF.get('color_schemes', 'names') choices = list(zip(names, names)) cs_combo = self.create_combobox(_("Syntax color scheme: "), choices, 'color_scheme_name') settings_layout = QVBoxLayout() settings_layout.addWidget(hist_spin) settings_group.setLayout(settings_layout) sourcecode_layout = QVBoxLayout() sourcecode_layout.addWidget(wrap_mode_box) sourcecode_layout.addWidget(go_to_eof_box) sourcecode_layout.addWidget(cs_combo) sourcecode_group.setLayout(sourcecode_layout) vlayout = QVBoxLayout() vlayout.addWidget(settings_group) vlayout.addWidget(font_group) vlayout.addWidget(sourcecode_group) vlayout.addStretch(1) self.setLayout(vlayout)
def __init__(self, parent): ReadOnlyEditor.__init__(self, parent) self.shell = None # locked = disable link with Console self.locked = False self._last_text = None # Object name layout_edit = QHBoxLayout() layout_edit.addWidget(QLabel(self.tr("Object"))) self.combo = DocComboBox(self) layout_edit.addWidget(self.combo) self.combo.setMaxCount(CONF.get(self.ID, 'max_history_entries')) dvhistory = self.load_dvhistory() self.combo.addItems(dvhistory) # Doc/source checkbox self.help_or_doc = QCheckBox(self.tr("Show source")) self.connect(self.help_or_doc, SIGNAL("stateChanged(int)"), self.toggle_help) layout_edit.addWidget(self.help_or_doc) self.docstring = None self.autosource = False self.toggle_help(Qt.Unchecked) # Lock checkbox self.locked_button = create_toolbutton(self, triggered=self.toggle_locked) layout_edit.addWidget(self.locked_button) self._update_lock_icon() # Main layout layout = QVBoxLayout() layout.addLayout(layout_edit) layout.addWidget(self.editor) layout.addWidget(self.find_widget) self.setLayout(layout)
def __init__(self, parent, history_filename, debug=False, profile=False): """ parent : specifies the parent widget """ ConsoleBaseWidget.__init__(self, parent) # Prompt position: tuple (line, index) self.current_prompt_pos = None self.new_input_line = True # History self.histidx = None self.hist_wholeline = False assert isinstance(history_filename, (str, unicode)) self.history_filename = history_filename self.history = self.load_history() # Session self.historylog_filename = CONF.get('main', 'historylog_filename', get_conf_path('history.log')) # Context menu self.menu = None self.setup_context_menu() # Debug mode self.debug = debug # Simple profiling test self.profile = profile # write/flush self.__buffer = [] self.__timestamp = 0.0 # Give focus to widget self.setFocus()
def set(self, options): self.args = options.get('args', '') self.args_enabled = options.get('args/enabled', False) if CONF.get('run', WDIR_USE_FIXED_DIR_OPTION, False): default_wdir = CONF.get('run', WDIR_FIXED_DIR_OPTION, getcwd()) self.wdir = options.get('workdir', default_wdir) self.wdir_enabled = True else: self.wdir = options.get('workdir', getcwd()) self.wdir_enabled = options.get('workdir/enabled', False) self.current = options.get( 'current', CONF.get('run', CURRENT_INTERPRETER_OPTION, True)) self.systerm = options.get( 'systerm', CONF.get('run', SYSTERM_INTERPRETER_OPTION, False)) self.interact = options.get('interact', CONF.get('run', 'interact', False)) self.show_kill_warning = options.get( 'show_kill_warning', CONF.get('run', 'show_kill_warning', False)) self.post_mortem = options.get('post_mortem', CONF.get('run', 'post_mortem', False)) self.python_args = options.get('python_args', '') self.python_args_enabled = options.get('python_args/enabled', False)
def send_args_to_spyder(args): """Simple socket client used to send the args passed to the Spyder executable to an already running instance. Args can be Python scripts or files with these extensions: .spydata, .mat, .npy, or .h5, which can be imported by the Variable Explorer.""" port = CONF.get('main', 'open_files_port') # Wait ~50 secs for the server to be up # Taken from http://stackoverflow.com/a/4766598/438386 for _x in range(200): try: for arg in args: client = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) client.connect(("127.0.0.1", port)) if is_unicode(arg): arg = arg.encode('utf-8') client.send(osp.abspath(arg)) client.close() except socket.error: time.sleep(0.25) continue break
def add_history(self, filename): """ Add new history tab Slot for SIGNAL('add_history(QString)') emitted by shell instance """ filename = encoding.to_unicode(filename) if filename in self.filenames: return editor = QsciEditor(self) if osp.splitext(filename)[1] == '.py': language = 'py' icon = get_icon('python.png') else: language = 'bat' icon = get_icon('cmdprompt.png') editor.setup_editor(linenumbers=False, language=language, code_folding=True) self.connect(editor, SIGNAL("focus_changed()"), lambda: self.emit(SIGNAL("focus_changed()"))) editor.setReadOnly(True) editor.set_font(get_font(self.ID)) editor.toggle_wrap_mode(CONF.get(self.ID, 'wrap')) text, _ = encoding.read(filename) editor.set_text(text) editor.set_cursor_position('eof') self.editors.append(editor) self.filenames.append(filename) self.icons.append(icon) index = self.tabwidget.addTab(editor, osp.basename(filename)) self.find_widget.set_editor(editor) self.tabwidget.setTabToolTip(index, filename) self.tabwidget.setTabIcon(index, icon) self.tabwidget.setCurrentIndex(index)
def register_client(self, client, name, restart=False, give_focus=True): """Register new client""" self.connect_client_to_kernel(client) client.show_shellwidget(give_focus=give_focus) client.name = name # Local vars shellwidget = client.shellwidget control = shellwidget._control page_control = shellwidget._page_control # Handle kernel interrupts extconsoles = self.extconsole.shellwidgets kernel_widget = None if extconsoles: if extconsoles[-1].connection_file == client.connection_file: kernel_widget = extconsoles[-1] if restart: shellwidget.custom_interrupt_requested.disconnect() shellwidget.custom_interrupt_requested.connect( kernel_widget.keyboard_interrupt) if kernel_widget is None: shellwidget.custom_interrupt_requested.connect( client.interrupt_message) # If we are restarting the kernel we need to rename # the client tab and do no more from here on if restart: self.rename_client_tab(client) return # For tracebacks self.connect(control, SIGNAL("go_to_error(QString)"), self.go_to_error) # Handle kernel restarts asked by the user if kernel_widget is not None: shellwidget.custom_restart_requested.connect( lambda cl=client: self.restart_kernel(client)) else: shellwidget.custom_restart_requested.connect( client.restart_message) # Print a message if kernel dies unexpectedly shellwidget.custom_restart_kernel_died.connect( lambda t: client.if_kernel_dies(t)) # Connect text widget to our inspector if kernel_widget is not None and self.inspector is not None: control.set_inspector(self.inspector) control.set_inspector_enabled( CONF.get('inspector', 'connect/ipython_console')) # Connect to our variable explorer if kernel_widget is not None and self.variableexplorer is not None: nsb = self.variableexplorer.currentWidget() # When the autorefresh button is active, our kernels # start to consume more and more CPU during time # Fix Issue 1450 # ---------------- # When autorefresh is off by default we need the next # line so that kernels don't start to consume CPU # Fix Issue 1595 nsb.auto_refresh_button.setChecked(True) nsb.auto_refresh_button.setChecked(False) nsb.auto_refresh_button.setEnabled(False) nsb.set_ipyclient(client) client.set_namespacebrowser(nsb) # Connect client to our history log if self.historylog is not None: self.historylog.add_history(client.history_filename) self.connect(client, SIGNAL('append_to_history(QString,QString)'), self.historylog.append_to_history) # Set font for client client.set_font(self.get_plugin_font()) # Connect focus signal to client's control widget self.connect(control, SIGNAL('focus_changed()'), lambda: self.emit(SIGNAL('focus_changed()'))) # Update the find widget if focus changes between control and # page_control self.find_widget.set_editor(control) if page_control: self.connect(page_control, SIGNAL('focus_changed()'), lambda: self.emit(SIGNAL('focus_changed()'))) self.connect(control, SIGNAL('visibility_changed(bool)'), self.refresh_plugin) self.connect(page_control, SIGNAL('visibility_changed(bool)'), self.refresh_plugin) self.connect(page_control, SIGNAL('show_find_widget()'), self.find_widget.show) # Update client name self.rename_client_tab(client)
def run_c2p(self): """Prompt the user to load a combine archive, translate to Python, and display in a new window""" editorwindow = None #Used in editor.load processevents = True #Used in editor.load editor = self.main.editor basedir = getcwd() if CONF.get('workingdir', 'editor/open/browse_scriptdir'): c_fname = editor.get_current_filename() if c_fname is not None and c_fname != editor.TEMPFILE_PATH: basedir = os.path.dirname(c_fname) editor.emit(SIGNAL('redirect_stdio(bool)'), False) parent_widget = editor.get_current_editorstack() selectedfilter = '' filters = 'Combine archives (*.zip *.omex);;All files (*.*)' filenames, _selfilter = getopenfilenames(parent_widget, _("Open combine archive"), basedir, filters, selectedfilter=selectedfilter) editor.emit(SIGNAL('redirect_stdio(bool)'), True) if filenames: filenames = [os.path.normpath(fname) for fname in filenames] if CONF.get('workingdir', 'editor/open/auto_set_to_basedir'): directory = os.path.dirname(filenames[0]) editor.emit(SIGNAL("open_dir(QString)"), directory) else: #The file dialog box was closed without selecting a file. return focus_widget = QApplication.focusWidget() if editor.dockwidget and not editor.ismaximized and\ (not editor.dockwidget.isAncestorOf(focus_widget)\ and not isinstance(focus_widget, CodeEditor)): editor.dockwidget.setVisible(True) editor.dockwidget.setFocus() editor.dockwidget.raise_() def _convert(fname): fname = os.path.abspath(encoding.to_unicode_from_fs(fname)) if os.name == 'nt' and len(fname) >= 2 and fname[1] == ':': fname = fname[0].upper() + fname[1:] return fname if hasattr(filenames, 'replaceInStrings'): # This is a QStringList instance (PyQt API #1), converting to list: filenames = list(filenames) if not isinstance(filenames, list): filenames = [_convert(filenames)] else: filenames = [_convert(fname) for fname in list(filenames)] for index, filename in enumerate(filenames): p = re.compile('(.zip$|.omex$)') pythonfile = p.sub('.py', filename) if (pythonfile == filename): pythonfile = filename + ".py" current_editor = editor.set_current_filename( pythonfile, editorwindow) if current_editor is not None: # -- TODO: Do not open an already opened file pass else: # -- Not an existing opened file: if not os.path.isfile(filename): continue # -- current_es = editor.get_current_editorstack(editorwindow) # Creating the editor widget in the first editorstack (the one # that can't be destroyed), then cloning this editor widget in # all other editorstacks: finfo, newname = self.load_and_translate( filename, pythonfile, editor) finfo.path = editor.main.get_spyder_pythonpath() editor._clone_file_everywhere(finfo) current_editor = current_es.set_current_filename(newname) #if (current_editor is not None): # editor.register_widget_shortcuts("Editor", current_editor) current_es.analyze_script() if (current_editor is not None): current_editor.clearFocus() current_editor.setFocus() current_editor.window().raise_() if processevents: QApplication.processEvents()
def get_shortcut(context, name, default=NoDefault): """Get keyboard shortcut (key sequence string)""" return CONF.get('shortcuts', '%s/%s' % (context, name), default=default)
def set_background_color(self): lightbg_o = CONF.get('ipython_console', 'light_color') if not lightbg_o: self.set_default_style(colors='linux')
def get_option(self, option, default=NoDefault): """Get a plugin option from configuration file""" return CONF.get(self.CONF_SECTION, option, default)
def set_firstrun_o(self): CONF.set('run', ALWAYS_OPEN_FIRST_RUN_OPTION, self.firstrun_cb.isChecked())
def __init__(self, parent=None): QWidget.__init__(self, parent) self.current_radio = None self.dedicated_radio = None self.systerm_radio = None self.runconf = RunConfiguration() firstrun_o = CONF.get('run', ALWAYS_OPEN_FIRST_RUN_OPTION, False) # --- General settings ---- common_group = QGroupBox(_("General settings")) common_layout = QGridLayout() common_group.setLayout(common_layout) self.clo_cb = QCheckBox(_("Command line options:")) common_layout.addWidget(self.clo_cb, 0, 0) self.clo_edit = QLineEdit() self.clo_cb.toggled.connect(self.clo_edit.setEnabled) self.clo_edit.setEnabled(False) common_layout.addWidget(self.clo_edit, 0, 1) self.wd_cb = QCheckBox(_("Working directory:")) common_layout.addWidget(self.wd_cb, 1, 0) wd_layout = QHBoxLayout() self.wd_edit = QLineEdit() self.wd_cb.toggled.connect(self.wd_edit.setEnabled) self.wd_edit.setEnabled(False) wd_layout.addWidget(self.wd_edit) browse_btn = QPushButton(get_std_icon('DirOpenIcon'), "", self) browse_btn.setToolTip(_("Select directory")) browse_btn.clicked.connect(self.select_directory) wd_layout.addWidget(browse_btn) common_layout.addLayout(wd_layout, 1, 1) self.post_mortem_cb = QCheckBox(_("Enter post mortem debugging" " for uncaught exceptions")) common_layout.addWidget(self.post_mortem_cb) # --- Interpreter --- interpreter_group = QGroupBox(_("Console")) interpreter_layout = QVBoxLayout() interpreter_group.setLayout(interpreter_layout) self.current_radio = QRadioButton(CURRENT_INTERPRETER) interpreter_layout.addWidget(self.current_radio) self.dedicated_radio = QRadioButton(DEDICATED_INTERPRETER) interpreter_layout.addWidget(self.dedicated_radio) self.systerm_radio = QRadioButton(SYSTERM_INTERPRETER) interpreter_layout.addWidget(self.systerm_radio) # --- Dedicated interpreter --- new_group = QGroupBox(_("Dedicated Python console")) self.current_radio.toggled.connect(new_group.setDisabled) new_layout = QGridLayout() new_group.setLayout(new_layout) self.interact_cb = QCheckBox(_("Interact with the Python " "console after execution")) new_layout.addWidget(self.interact_cb, 1, 0, 1, -1) self.show_kill_warning_cb = QCheckBox(_("Show warning when killing" " running process")) new_layout.addWidget(self.show_kill_warning_cb, 2, 0, 1, -1) self.pclo_cb = QCheckBox(_("Command line options:")) new_layout.addWidget(self.pclo_cb, 3, 0) self.pclo_edit = QLineEdit() self.pclo_cb.toggled.connect(self.pclo_edit.setEnabled) self.pclo_edit.setEnabled(False) self.pclo_edit.setToolTip(_("<b>-u</b> is added to the " "other options you set here")) new_layout.addWidget(self.pclo_edit, 3, 1) # Checkbox to preserve the old behavior, i.e. always open the dialog # on first run hline = QFrame() hline.setFrameShape(QFrame.HLine) hline.setFrameShadow(QFrame.Sunken) self.firstrun_cb = QCheckBox(ALWAYS_OPEN_FIRST_RUN % _("this dialog")) self.firstrun_cb.clicked.connect(self.set_firstrun_o) self.firstrun_cb.setChecked(firstrun_o) layout = QVBoxLayout() layout.addWidget(interpreter_group) layout.addWidget(common_group) layout.addWidget(new_group) layout.addWidget(hline) layout.addWidget(self.firstrun_cb) self.setLayout(layout)
def _set_run_configurations(configurations): history_count = CONF.get('run', 'history', 20) CONF.set('run', 'configurations', configurations[:history_count])
def set_shortcut(context, name, keystr): """Set keyboard shortcut (key sequence string)""" CONF.set('shortcuts', '%s/%s' % (context, name), keystr)