def reload_config(self): old_theme = self.config.get("theme") self.config.reload() self.theme.reset() class event: theme_changed = self.config.get("theme") != old_theme for callback in self.config_callbacks: # without call_later this could cause # [NSMachPort sendBeforeDate:] destination port invalid # due to forced syntax highlighting taking a long time call_later(0, callback, event=event)
def reload_document(self): """Reload document with the given URL This implementation allows the user to undo beyond the reload. The down-side is that it may use a lot of memory if the document is very large. """ if not self.file_exists(): return textstore = self._text_storage self._text_storage = Text() try: ok = self._load() finally: tempstore = self._text_storage self._text_storage = textstore if not ok: return textview = None for editor in self.app.iter_editors_of_document(self): textview = editor.text_view if textview is not None: break text = tempstore.string() range = fn.NSRange(0, textstore.length()) if textview is None: textstore.replaceCharactersInRange_withString_(range, text) self.undo_manager.removeAllActions() elif textview.shouldChangeTextInRange_replacementString_(range, text): # state = self.documentState textstore.replaceCharactersInRange_withString_(range, text) # self.documentState = state textview.didChangeText() textview.breakUndoCoalescing() # HACK use timed invocation to allow didChangeText notification # to update change count before _clearUndo is invoked call_later(0, self.clear_dirty) textview.setSelectedRange_(fn.NSRange(0, 0)) self.reset_text_attributes() self.update_syntaxer()
def reload_document(self): """Reload document with the given URL This implementation allows the user to undo beyond the reload. The down-side is that it may use a lot of memory if the document is very large. """ if not self.file_exists(): return textstore = self._text_storage self._text_storage = Text() try: ok = self._load() finally: tempstore = self._text_storage self._text_storage = textstore if not ok: return editor = None for ed in self.app.iter_editors_of_document(self): if ed.text_view is not None: editor = ed break text = tempstore.string() range = fn.NSRange(0, textstore.length()) if editor is None: textstore[range] = text self.undo_manager.removeAllActions() elif editor.put(text, range): editor.text_view.breakUndoCoalescing() # HACK use timed invocation to allow didChangeText notification # to update change count before _clearUndo is invoked call_later(0, self.clear_dirty) editor.selection = (0, 0) self.reset_text_attributes() self.update_syntaxer()
def continue_scan(): store = text.store store.beginEditing() try: resume_at = next(scanner, None) except Exception: log.exception("syntax highlight error") resume_at = None finally: store.endEditing() if resume_at is None: try: del text.__cancel_incomplete_highlight except AttributeError: pass else: cancel_call = call_later(0.01, continue_scan) def cancel(): cancel_call() return resume_at, max(minend - resume_at, 0) text.__cancel_incomplete_highlight = cancel
def on_key_command(self, key, command_view, keys=CommandView.KEYS): """Handle key press in command view :param key: A command token corresponding to the key that was pressed. This is one of the command key contsants defined in `editxt.platform.views.CommandView.KEYS`. :param view: The CommandView object. :returns: True if the command was handled and should not be propagated to the text view, otherwise false. """ if key == keys.SELECTION_CHANGED: if command_view.completions and not self.completing: call_later(0, self.complete, command_view, auto_one=False) command_view.completions.select_range = command_view.command_text_selected_range return True if key == keys.TAB: word = command_view.completions.selected_item if command_view.completions and not word: words = command_view.completions.items word = self.common_prefix(words) if word: self._auto_complete(command_view, word) if len(words) == 1: command_view.completions.items = [] else: self.complete(command_view) return True if key == keys.UP: if command_view.completions: command_view.completions.select_prev() else: self.navigate_history(command_view) return True if key == keys.DOWN: if command_view.completions: command_view.completions.select_next() else: self.navigate_history(command_view, forward=True) return True if key == keys.ENTER: text = command_view.command_text # TODO send cursor position instead of len(text) if not self.should_insert_newline(text, len(text)): command_view.deactivate() self.execute(text) return True if key == keys.ESC: if command_view.completions: select_range = command_view.completions.select_range command_view.completions.items = [] if select_range is not None: command_view.command_text_selected_range = select_range elif command_view.output_text: command_view.message("") else: command_view.deactivate() return True if key == keys.BACK_TAB: # ignore return True return False
def cprofile(editor, delay, run_seconds, path): """Start cProfile after delay for run_seconds :param delay: Number of seconds to delay before starting profile. Once this delay is expired, the profile will start and its output file will be created in the given directory (`path`). Stop running profile if this value is `"stop"` or there is a profile in progress. :param run_seconds: Number of seconds to run profile. Run until next cprofile command if zero. :param path: A directory path in which to write profile output. """ import os from cProfile import Profile from datetime import datetime from pstats import Stats from os.path import expanduser, join if delay == "stop" or cprofile.stop_profile is not None: if cprofile.stop_profile is not None: cprofile.stop_profile() return try: delay = int(delay) except ValueError: editor.message("bad delay: {!r}".format(delay), msg_type=const.ERROR) return profile = Profile() filename = None def start_profile(): if profile is None: return nonlocal filename filename = join(expanduser(path), "profile-{:%Y%m%dT%H%M%S}.txt".format(datetime.now())) with open(filename, "w", encoding="utf8") as fh: fh.write("in progress...") log.info("starting profile %s", filename) profile.enable() def stop_profile(): cprofile.stop_profile = None nonlocal profile if filename is None: # cancel before start profile = None return profile.disable() log.info("stopped profile %s", filename) with open(filename, "w", encoding="utf8") as fh: try: stats = Stats(profile, stream=fh) except Exception as err: fh.write("{}: {}".format(type(err).__name__, err)) else: stats.sort_stats("ncalls") stats.print_stats() stats.sort_stats("cumtime") stats.print_stats() stats.sort_stats("tottime") stats.print_stats() call_later(delay, start_profile) cprofile.stop_profile = stop_profile if run_seconds > 0: def auto_stop(): if cprofile.stop_profile is not None: cprofile.stop_profile() call_later(delay + run_seconds, auto_stop)