def scanForMultiPath (c): '''Return a dictionary whose keys are fileNames and whose values are lists of paths to which the fileName is to be written. New in version 0.6 of this plugin: use ';' to separate paths in @multipath statements.''' global multiprefix, multipath d, sep = {}, ';' for fileName in files: # Keys are fileNames, values are root positions. root = files[fileName] default_directory = g.os_path_dirname(fileName) fileName = g.os_path_join(default_directory, fileName) positions = [p.copy() for p in root.self_and_parents()] positions.reverse() prefix = '' for p in positions: lines = p.b.split('\n') # Calculate the prefix fisrt. for s in lines: if s.startswith(multiprefix): prefix = s[len(multiprefix):].strip() # Handle the paths after the prefix is in place. for s in lines: if s.startswith(multipath): s = s[len(multipath):].strip() paths = s.split(sep) paths = [z.strip() for z in paths] if prefix: paths = [g.os_path_join(default_directory,prefix,z) for z in paths] else: paths = [g.os_path_join(default_directory,z) for z in paths] aList = d.get(fileName,[]) aList.extend(paths) d[fileName] = aList return d
def __init__(self, *args, **kwargs): self.c = kwargs['c'] del kwargs['c'] QtWidgets.QWidget.__init__(self, *args, **kwargs) # were we opened by an @ rich node? Calling code will set self.at_rich = False # are we being closed by leaving an @ rich node? Calling code will set self.at_rich_close = False # read settings. self.reloadSettings() # load HTML template template_path = g.os_path_join(g.computeLeoDir(), 'plugins', 'cke_template.html') self.template = open(template_path).read() path = g.os_path_join(g.computeLeoDir(), 'external', 'ckeditor') self.template = self.template.replace( '[CKEDITOR]', QtCore.QUrl.fromLocalFile(path).toString()) # make widget containing QWebView self.setLayout(QtWidgets.QVBoxLayout()) self.layout().setSpacing(0) self.layout().setContentsMargins(0,0,0,0) # enable inspector, if this really is QtWebKit if real_webkit: QtWebKit.QWebSettings.globalSettings().setAttribute( QtWebKit.QWebSettings.DeveloperExtrasEnabled, True) self.webview = QtWebKitWidgets.QWebView() self.layout().addWidget(self.webview) g.registerHandler('select3', self.select_node) g.registerHandler('unselect1', self.unselect_node) # load current node self.select_node('', {'c': self.c, 'new_p': self.c.p})
def screen_capture_now(kwargs=None): """screen_capture_now - save a screenshot :Parameters: - `kwargs`: g.command arguments """ if kwargs is None: kwargs = {} if not hasattr(g, '_recorder'): g._recorder = Recorder() c = g.app.commanders()[0] dirname = c.config.getString("screen-capture-save-path") if not dirname: dirname = g.os_path_join( g.computeHomeDir(), '.leo', 'screen_captures' ) dirname = g.os_path_expanduser(dirname) if not g.os_path_isdir(dirname): os.makedirs(dirname) filename = g.os_path_join( dirname, time.strftime('%Y-%m-%dT%H-%M-%S')+'.png' ) g._recorder.grab_frame(filename=filename) # *only* print, don't want output messing up log view in screen shots print("Screenshot: %s"%filename)
def loadIcons(self, p, clear=False): com = self.c.editCommands allIcons = com.getIconList(p) icons = [i for i in allIcons if 'cleoIcon' not in i] if self.icon_order == 'pri-first': iterations = ['priority', 'progress', 'duedate'] else: iterations = ['progress', 'priority', 'duedate'] if clear: iterations = [] today = datetime.date.today() for which in iterations: if which == 'priority': pri = self.getat(p.v, 'priority') if pri: pri = int(pri) if pri in self.priorities: com.appendImageDictToList(icons, self.iconDir, g.os_path_join('cleo',self.priorities[pri]['icon']), 2, on='vnode', cleoIcon='1', where=self.icon_location) # Icon location defaults to 'beforeIcon' unless cleo_icon_location global defined. # Example: @strings[beforeIcon,beforeHeadline] cleo_icon_location = beforeHeadline elif which == 'progress': prog = self.getat(p.v, 'progress') if prog is not '': prog = int(prog) use = prog//10*10 use = 'prg%03d.png' % use com.appendImageDictToList(icons, self.iconDir, g.os_path_join('cleo',use), 2, on='vnode', cleoIcon='1', where=self.prog_location) elif which == 'duedate': duedate = self.getat(p.v, 'duedate') nextworkdate = self.getat(p.v, 'nextworkdate') icondate = min(duedate or NO_TIME, nextworkdate or NO_TIME) if icondate != NO_TIME: if icondate < today: icon = "date_past.png" elif icondate == today: icon = "date_today.png" else: icon = "date_future.png" com.appendImageDictToList(icons, self.iconDir, g.os_path_join('cleo', icon), 2, on='vnode', cleoIcon='1', where=self.prog_location) com.setIconList(p, icons)
def __init__(self, *args, **kwargs): self.c = kwargs['c'] del kwargs['c'] super().__init__(*args, **kwargs) # were we opened by an @ rich node? Calling code will set self.at_rich = False # are we being closed by leaving an @ rich node? Calling code will set self.at_rich_close = False # read settings. self.reloadSettings() # load HTML template template_path = g.os_path_join(g.computeLeoDir(), 'plugins', 'cke_template.html') self.template = open(template_path).read() path = g.os_path_join(g.computeLeoDir(), 'external', 'ckeditor') self.template = self.template.replace( '[CKEDITOR]', QtCore.QUrl.fromLocalFile(path).toString()) # make widget containing QWebView self.setLayout(QtWidgets.QVBoxLayout()) self.layout().setSpacing(0) self.layout().setContentsMargins(0, 0, 0, 0) # enable inspector, if this really is QtWebKit if real_webkit: QtWebKit.QWebSettings.globalSettings().setAttribute( QtWebKit.QWebSettings.DeveloperExtrasEnabled, True) self.webview = QtWebKitWidgets.QWebView() self.layout().addWidget(self.webview) g.registerHandler('select3', self.select_node) g.registerHandler('unselect1', self.unselect_node) # load current node self.select_node('', {'c': self.c, 'new_p': self.c.p})
def createMyLeoSettings(c): """createMyLeoSettings - Return true if myLeoSettings.leo created ok """ name = "myLeoSettings.leo" homeLeoDir = g.app.homeLeoDir loadDir = g.app.loadDir configDir = g.app.globalConfigDir # check it doesn't already exist for path in homeLeoDir, loadDir, configDir: fileName = g.os_path_join(path, name) if g.os_path_exists(fileName): return None ok = g.app.gui.runAskYesNoDialog(c, title='Create myLeoSettings.leo?', message=f"Create myLeoSettings.leo in {homeLeoDir}?", ) if ok == 'no': return None # get '@enabled-plugins' from g.app.globalConfigDir fileName = g.os_path_join(configDir, "leoSettings.leo") leosettings = g.openWithFileName(fileName, old_c=c) enabledplugins = g.findNodeAnywhere(leosettings, '@enabled-plugins') enabledplugins = enabledplugins.b leosettings.close() # now create "~/.leo/myLeoSettings.leo" fileName = g.os_path_join(homeLeoDir, name) c2 = g.openWithFileName(fileName, old_c=c) # add content to outline nd = c2.rootPosition() nd.h = "Settings README" nd.b = ( "myLeoSettings.leo personal settings file created {time}\n\n" "Only nodes that are descendants of the @settings node are read.\n\n" "Only settings you need to modify should be in this file, do\n" "not copy large parts of leoSettings.py here.\n\n" "For more information see http://leoeditor.com/customizing.html" "".format(time=time.asctime()) ) nd = nd.insertAfter() nd.h = '@settings' nd = nd.insertAsNthChild(0) nd.h = '@enabled-plugins' nd.b = enabledplugins nd = nd.insertAfter() nd.h = '@keys' nd = nd.insertAsNthChild(0) nd.h = '@shortcuts' nd.b = ( "# You can define keyboard shortcuts here of the form:\n" "#\n" "# some-command Shift-F5\n" ) c2.redraw() return c2
def createMyLeoSettings(c): """createMyLeoSettings - Return true if myLeoSettings.leo created ok """ name = "myLeoSettings.leo" homeLeoDir = g.app.homeLeoDir loadDir = g.app.loadDir configDir = g.app.globalConfigDir # check it doesn't already exist for path in homeLeoDir, loadDir, configDir: fileName = g.os_path_join(path, name) if g.os_path_exists(fileName): return None ok = g.app.gui.runAskYesNoDialog(c, title = 'Create myLeoSettings.leo?', message = 'Create myLeoSettings.leo in %s?' % (homeLeoDir), ) if ok == 'no': return # get '@enabled-plugins' from g.app.globalConfigDir fileName = g.os_path_join(configDir, "leoSettings.leo") leosettings = g.openWithFileName(fileName, old_c=c) enabledplugins = g.findNodeAnywhere(leosettings, '@enabled-plugins') enabledplugins = enabledplugins.b leosettings.close() # now create "~/.leo/myLeoSettings.leo" fileName = g.os_path_join(homeLeoDir, name) c2 = g.openWithFileName(fileName, old_c=c) # add content to outline nd = c2.rootPosition() nd.h = "Settings README" nd.b = ( "myLeoSettings.leo personal settings file created {time}\n\n" "Only nodes that are descendants of the @settings node are read.\n\n" "Only settings you need to modify should be in this file, do\n" "not copy large parts of leoSettings.py here.\n\n" "For more information see http://leoeditor.com/customizing.html" "".format(time=time.asctime()) ) nd = nd.insertAfter() nd.h = '@settings' nd = nd.insertAsNthChild(0) nd.h = '@enabled-plugins' nd.b = enabledplugins nd = nd.insertAfter() nd.h = '@keys' nd = nd.insertAsNthChild(0) nd.h = '@shortcuts' nd.b = ( "# You can define keyboard shortcuts here of the form:\n" "#\n" "# some-command Shift-F5\n" ) c2.redraw() return c2
def __init__(self, *args, **kwargs): self.c = kwargs['c'] del kwargs['c'] QtWidgets.QWidget.__init__(self, *args, **kwargs) # were we opened by an @ rich node? Calling code will set self.at_rich = False # are we being closed by leaving an @ rich node? Calling code will set self.at_rich_close = False # read autosave preference if not hasattr(self.c, '_ckeeditor_autosave'): auto = self.c.config.getBool("richtext_cke_autosave") or False self.c._ckeeditor_autosave = auto if auto: g.es("NOTE: automatic saving of rich text edits") # load HTML template template_path = g.os_path_join( g.computeLeoDir(), 'plugins', 'cke_template.html', ) self.template = open(template_path).read() path = g.os_path_join( g.computeLeoDir(), 'external', 'ckeditor' ) self.template = self.template.replace( '[CKEDITOR]', QtCore.QUrl.fromLocalFile(path).toString()) # load config self.config = self.c.config.getData("richtext_cke_config") if self.config: self.config = '\n'.join(self.config).strip() # make widget containing QWebView self.setLayout(QtWidgets.QVBoxLayout()) self.layout().setSpacing(0) self.layout().setContentsMargins(0,0,0,0) # enable inspector QtWebKit.QWebSettings.globalSettings().setAttribute( QtWebKit.QWebSettings.DeveloperExtrasEnabled, True) self.webview = QtWebKitWidgets.QWebView() self.layout().addWidget(self.webview) g.registerHandler('select3', self.select_node) g.registerHandler('unselect1', self.unselect_node) # load current node self.select_node('', {'c': self.c, 'new_p': self.c.p})
def __init__(self, *args, **kwargs): self.c = kwargs['c'] del kwargs['c'] QtWidgets.QWidget.__init__(self, *args, **kwargs) # were we opened by an @ rich node? Calling code will set self.at_rich = False # are we being closed by leaving an @ rich node? Calling code will set self.at_rich_close = False # read autosave preference if not hasattr(self.c, '_ckeeditor_autosave'): auto = self.c.config.getBool("richtext_cke_autosave") or False self.c._ckeeditor_autosave = auto if auto: g.es("NOTE: automatic saving of rich text edits") # load HTML template template_path = g.os_path_join( g.computeLeoDir(), 'plugins', 'cke_template.html', ) self.template = open(template_path).read() path = g.os_path_join(g.computeLeoDir(), 'external', 'ckeditor') self.template = self.template.replace( '[CKEDITOR]', QtCore.QUrl.fromLocalFile(path).toString()) # load config self.config = self.c.config.getData("richtext_cke_config") if self.config: self.config = '\n'.join(self.config).strip() # make widget containing QWebView self.setLayout(QtWidgets.QVBoxLayout()) self.layout().setSpacing(0) self.layout().setContentsMargins(0, 0, 0, 0) # enable inspector QtWebKit.QWebSettings.globalSettings().setAttribute( QtWebKit.QWebSettings.DeveloperExtrasEnabled, True) self.webview = QtWebKitWidgets.QWebView() self.layout().addWidget(self.webview) g.registerHandler('select3', self.select_node) g.registerHandler('unselect1', self.unselect_node) # load current node self.select_node('', {'c': self.c, 'new_p': self.c.p})
def onPostSave(tag=None, keywords=None): """After saving a nosentinels file, replace all tabs with spaces.""" global nosentNodes c = keywords.get('c') if c: at = c.atFileCommands for p in nosentNodes: g.red("node %s found" % p.h) at.scanAllDirectives(p) name = p.atNoSentinelsFileNodeName() fname = g.os_path_join(at.default_directory,name) f = open(fname,"r") lines = f.readlines() f.close() #@+<< add a newline before def or class >> #@+node:ekr.20040331151007.3: *3* << add a newline before def or class >> for i in range(len(lines)): ls = lines[i].lstrip() if ls.startswith("def ") or ls.startswith("class "): try: if lines[i-1].strip() != "": lines[i] = "\n" + lines[i] except IndexError: pass #@-<< add a newline before def or class >> #@+<< replace tabs with spaces >> #@+node:ekr.20040331151007.4: *3* << replace tabs with spaces >> s = ''.join(lines) fh = open(fname,"w") fh.write(s.replace("\t",NSPACES)) fh.close() #@-<< replace tabs with spaces >> nosentNodes = []
def _path_from_pos(c, p): """_path_from_pos - get folder for position FIXME: should be in Leo core somewhere. Args: p (position): position Returns: str: path """ p = p.copy() def atfile(p): word0 = p.h.split()[0] return ( word0 in g.app.atFileNames|set(['@auto']) or word0.startswith('@auto-') ) aList = g.get_directives_dict_list(p) path = c.scanAtPathDirectives(aList) while c.positionExists(p): if atfile(p): # see if it's a @<file> node of some sort nodepath = p.h.split(None, 1)[-1] nodepath = g.os_path_join(path, nodepath) if not g.os_path_isdir(nodepath): # remove filename nodepath = g.os_path_dirname(nodepath) if g.os_path_isdir(nodepath): # append if it's a directory path = nodepath break p.moveToParent() return path
def getIDFromFile(self): '''Attempt to set g.app.leoID from leoID.txt.''' g = self.g trace = False and not g.app.silentMode tag = ".leoID.txt" for theDir in (g.app.homeDir, g.app.globalConfigDir, g.app.loadDir): if not theDir: continue # do *not* use the current directory! fn = g.os_path_join(theDir, tag) try: with open(fn, 'r') as f: s = f.readline().strip() if not s: continue g.app.leoID = s if trace: g.es('leoID=%r (in %s)' % (s, theDir), color='red') else: g.es('leoID=%r' % (s), color='red') except IOError: g.app.leoID = None except Exception: g.app.leoID = None g.error('unexpected exception in app.setLeoID') g.es_exception()
def profile_leo(): """ Gather and print statistics about Leo. @ To gather statistics, do the following in a console window: python profileLeo.py <list of .leo files> > profile.txt """ # Work around a Python distro bug: can fail on Ubuntu. try: import pstats except ImportError: g.es_print('can not import pstats: this is a Python distro bug') g.es_print('https://bugs.launchpad.net/ubuntu/+source/python-defaults/+bug/123755') g.es_print('try installing pstats yourself') return import cProfile as profile import leo.core.leoGlobals as g import os theDir = os.getcwd() # On Windows, name must be a plain string. name = str(g.os_path_normpath(g.os_path_join(theDir, 'leoProfile'))) # This is a binary file. print('profiling binary stats to %s' % name) profile.run('import leo ; leo.run()', name) p = pstats.Stats(name) p.strip_dirs() p.sort_stats('tottime') p.print_stats(200)
def make_pointer(self): """make_pointer - Return a pixmap for a pointer """ path = g.computeLeoDir() path = g.os_path_join(path, 'Icons', 'recorder', 'pointer.png') return QtGui.QPixmap(path)
def runDebugScriptCommand(self, event=None): '''Called when user presses the 'debug-script' button or executes the debug-script command.''' c = self.c p = c.p script = g.getScript(c, p, useSelectedText=True, useSentinels=False) if script: #@+<< set debugging if debugger is active >> #@+node:ekr.20060523084441: *5* << set debugging if debugger is active >> g.trace(self.debuggerKind) if self.debuggerKind == 'winpdb': try: import rpdb2 debugging = rpdb2.g_debugger is not None except ImportError: debugging = False elif self.debuggerKind == 'idle': # import idlelib.Debugger.py as Debugger # debugging = Debugger.interacting debugging = True else: debugging = False #@-<< set debugging if debugger is active >> if debugging: #@+<< create leoScriptModule >> #@+node:ekr.20060524073716: *5* << create leoScriptModule >> (mod_scripting.py) target = g.os_path_join(g.app.loadDir, 'leoScriptModule.py') f = None try: f = file(target, 'w') f.write('# A module holding the script to be debugged.\n') if self.debuggerKind == 'idle': # This works, but uses the lame pdb debugger. f.write('import pdb\n') f.write('pdb.set_trace() # Hard breakpoint.\n') elif self.debuggerKind == 'winpdb': f.write('import rpdb2\n') f.write( 'if rpdb2.g_debugger is not None: # don\'t hang if the debugger isn\'t running.\n' ) f.write( ' rpdb2.start_embedded_debugger(pwd="",fAllowUnencrypted=True) # Hard breakpoint.\n' ) # f.write('# Remove all previous variables.\n') f.write('# Predefine c, g and p.\n') f.write('import leo.core.leoGlobals as g\n') f.write('c = g.app.scriptDict.get("c")\n') f.write('p = c.p\n') f.write('# Actual script starts here.\n') f.write(script + '\n') finally: if f: f.close() #@-<< create leoScriptModule >> # pylint: disable=no-name-in-module g.app.scriptDict['c'] = c if 'leoScriptModule' in sys.modules.keys(): del sys.modules['leoScriptModule'] # Essential. import leo.core.leoScriptModule as leoScriptModule else: g.error('No debugger active') c.bodyWantsFocus()
def __init__(self, owner): self.owner = owner QtGui.QWidget.__init__(self) uiPath = g.os_path_join(g.app.leoDir, 'plugins', 'Backlink.ui') form_class, base_class = uic.loadUiType(uiPath) self.owner.c.frame.log.createTab('Links', widget=self) self.UI = form_class() self.UI.setupUi(self) u = self.UI o = self.owner self.connect(u.markBtn, QtCore.SIGNAL("clicked()"), o.mark) self.connect(u.swapBtn, QtCore.SIGNAL("clicked()"), o.swap) self.connect(u.linkBtn, QtCore.SIGNAL("clicked()"), self.linkClicked) self.connect(u.rescanBtn, QtCore.SIGNAL("clicked()"), o.loadLinksInt) self.connect(u.dirLeftBtn, QtCore.SIGNAL("clicked()"), self.dirClicked) self.connect(u.dirRightBtn, QtCore.SIGNAL("clicked()"), self.dirClicked) self.connect(u.linkList, QtCore.SIGNAL("itemClicked(QListWidgetItem*)"), self.listClicked) self.connect(u.deleteBtn, QtCore.SIGNAL("stateChanged(int)"), o.deleteSet)
def OLD_parse_opml_file(self, inputFileName): if not inputFileName or not inputFileName.endswith(".opml"): return None c = self.c path = g.os_path_normpath(g.os_path_join(g.app.loadDir, inputFileName)) try: f = open(path) except IOError: g.trace("can not open %s" % path) return None try: try: node = None parser = xml.sax.make_parser() # Do not include external general entities. # The actual feature name is "http://xml.org/sax/features/external-general-entities" parser.setFeature(xml.sax.handler.feature_external_ges, 0) handler = SaxContentHandler(c, inputFileName) parser.setContentHandler(handler) parser.parse(f) node = handler.getNode() except xml.sax.SAXParseException: g.error("Error parsing %s" % (inputFileName)) g.es_exception() return None except Exception: g.error("Unexpected exception parsing %s" % (inputFileName)) g.es_exception() return None finally: f.close() return node
def __init__(self, owner): self.owner = owner QtGui.QWidget.__init__(self) uiPath = g.os_path_join(g.app.leoDir, 'plugins', 'Backlink.ui') form_class, base_class = uic.loadUiType(uiPath) self.owner.c.frame.log.createTab('Links', widget = self) self.UI = form_class() self.UI.setupUi(self) u = self.UI o = self.owner self.connect(u.markBtn, QtCore.SIGNAL("clicked()"), o.mark) self.connect(u.swapBtn, QtCore.SIGNAL("clicked()"), o.swap) self.connect(u.linkBtn, QtCore.SIGNAL("clicked()"), self.linkClicked) self.connect(u.rescanBtn, QtCore.SIGNAL("clicked()"), o.loadLinksInt) self.connect(u.dirLeftBtn, QtCore.SIGNAL("clicked()"), self.dirClicked) self.connect(u.dirRightBtn, QtCore.SIGNAL("clicked()"), self.dirClicked) self.connect(u.linkList, QtCore.SIGNAL("itemClicked(QListWidgetItem*)"), self.listClicked) self.connect(u.deleteBtn, QtCore.SIGNAL("stateChanged(int)"), o.deleteSet)
def profile_leo(): """Gather and print statistics about Leo""" # Work around a Python distro bug: can fail on Ubuntu. try: import pstats except ImportError: g.es_print('can not import pstats: this is a Python distro bug') g.es_print( 'https://bugs.launchpad.net/ubuntu/+source/python-defaults/+bug/123755' ) g.es_print('try installing pstats yourself') return import cProfile as profile import leo.core.leoGlobals as g import os theDir = os.getcwd() # On Windows, name must be a plain string. An apparent cProfile bug. name = str(g.os_path_normpath(g.os_path_join(theDir, 'leoProfile.txt'))) print('profiling to %s' % name) profile.run('import leo ; leo.run()', name) p = pstats.Stats(name) p.strip_dirs() # p.sort_stats('module','calls','time','name') p.sort_stats('cumulative', 'time') #reFiles='leoAtFile.py:|leoFileCommands.py:|leoGlobals.py|leoNodes.py:' #p.print_stats(reFiles) p.print_stats()
def parse_opml_file(self, fn): c = self.c if not fn or not fn.endswith('.opml'): return g.trace('bad file name: %s' % repr(fn)) c = self.c path = g.os_path_normpath(g.os_path_join(g.app.loadDir, fn)) try: f = open(path, 'rb') s = f.read() # type(s) is bytes for Python 3.x. s = self.cleanSaxInputString(s) except IOError: return g.trace('can not open %s' % path) # pylint:disable=catching-non-exception try: theFile = BytesIO(s) parser = xml.sax.make_parser() parser.setFeature(xml.sax.handler.feature_external_ges, 1) # Do not include external general entities. # The actual feature name is "http://xml.org/sax/features/external-general-entities" parser.setFeature(xml.sax.handler.feature_external_pes, 0) handler = SaxContentHandler(c, fn) parser.setContentHandler(handler) parser.parse(theFile) # expat does not support parseString sax_node = handler.getNode() except xml.sax.SAXParseException: g.error('error parsing', fn) g.es_exception() sax_node = None except Exception: g.error('unexpected exception parsing', fn) g.es_exception() sax_node = None return sax_node
def cmd_PickDir(event): """cmd_PickDir - Show user a folder picker to create """ c = event.get('c') p = c.p aList = g.get_directives_dict_list(p) path = c.scanAtPathDirectives(aList) if p.h.startswith('@'): # see if it's a @<file> node of some sort nodepath = p.h.split(None, 1)[-1] nodepath = g.os_path_join(path, nodepath) if not g.os_path_isdir(nodepath): # remove filename nodepath = g.os_path_dirname(nodepath) if g.os_path_isdir(nodepath): # append if it's a directory path = nodepath ocwd = os.getcwd() try: os.chdir(path) except OSError: g.es("Couldn't find path %s" % path) dir_ = g.app.gui.runOpenDirectoryDialog("Pick a folder", "Pick a folder") os.chdir(ocwd) if not dir_: g.es("No folder selected") return nd = c.p.insertAfter() nd.h = "@path %s" % dir_ c.redraw()
def _path_from_pos(c, p): """_path_from_pos - get folder for position FIXME: should be in Leo core somewhere. Args: p (position): position Returns: str: path """ p = p.copy() def atfile(p): word0 = p.h.split()[0] return (word0 in g.app.atFileNames | set(['@auto']) or word0.startswith('@auto-')) aList = g.get_directives_dict_list(p) path = c.scanAtPathDirectives(aList) while c.positionExists(p): if atfile(p): # see if it's a @<file> node of some sort nodepath = p.h.split(None, 1)[-1] nodepath = g.os_path_join(path, nodepath) if not g.os_path_isdir(nodepath): # remove filename nodepath = g.os_path_dirname(nodepath) if g.os_path_isdir(nodepath): # append if it's a directory path = nodepath break p.moveToParent() return path
def profile_leo(): """Gather and print statistics about Leo""" # Work around a Python distro bug: can fail on Ubuntu. try: import pstats except ImportError: g.es_print('can not import pstats: this is a Python distro bug') g.es_print('https://bugs.launchpad.net/ubuntu/+source/python-defaults/+bug/123755') g.es_print('try installing pstats yourself') return import cProfile as profile import leo.core.leoGlobals as g import os theDir = os.getcwd() # On Windows, name must be a plain string. An apparent cProfile bug. name = str(g.os_path_normpath(g.os_path_join(theDir, 'leoProfile.txt'))) print('profiling to %s' % name) profile.run('import leo ; leo.run()', name) p = pstats.Stats(name) p.strip_dirs() # p.sort_stats('module','calls','time','name') p.sort_stats('cumulative', 'time') #reFiles='leoAtFile.py:|leoFileCommands.py:|leoGlobals.py|leoNodes.py:' #p.print_stats(reFiles) p.print_stats()
def menuicon(self, pri, progress=False): """return icon from cache, placing it there if needed""" if progress: prog = pri pri = 'prog-%d'%pri if pri not in self.menuicons: if progress: fn = 'prg%03d.png' % prog else: fn = self.priorities[pri]["icon"] #X iconDir = g.os_path_abspath( #X g.os_path_normpath( #X g.os_path_join(g.app.loadDir,"..","Icons"))) #X fn = g.os_path_join(iconDir,'cleo',fn) # use getImageImage because it's theme aware fn = g.os_path_join('cleo', fn) self.menuicons[pri] = QtGui.QIcon(g.app.gui.getImageImage(fn)) return self.menuicons[pri]
def runDebugScriptCommand(self, event=None): """Called when user presses the 'debug-script' button or executes the debug-script command.""" c = self.c p = c.p script = g.getScript(c, p, useSelectedText=True, useSentinels=False) if script: # @+<< set debugging if debugger is active >> # @+node:ekr.20060523084441: *6* << set debugging if debugger is active >> g.trace(self.debuggerKind) if self.debuggerKind == "winpdb": try: import rpdb2 debugging = rpdb2.g_debugger is not None except ImportError: debugging = False elif self.debuggerKind == "idle": # import idlelib.Debugger.py as Debugger # debugging = Debugger.interacting debugging = True else: debugging = False # @-<< set debugging if debugger is active >> if debugging: # @+<< create leoScriptModule >> # @+node:ekr.20060524073716: *6* << create leoScriptModule >> target = g.os_path_join(g.app.loadDir, "leoScriptModule.py") f = None try: f = file(target, "w") f.write("# A module holding the script to be debugged.\n") if self.debuggerKind == "idle": # This works, but uses the lame pdb debugger. f.write("import pdb\n") f.write("pdb.set_trace() # Hard breakpoint.\n") elif self.debuggerKind == "winpdb": f.write("import rpdb2\n") f.write("if rpdb2.g_debugger is not None: # don't hang if the debugger isn't running.\n") f.write(' rpdb2.start_embedded_debugger(pwd="",fAllowUnencrypted=True) # Hard breakpoint.\n') # f.write('# Remove all previous variables.\n') f.write("# Predefine c, g and p.\n") f.write("import leo.core.leoGlobals as g\n") f.write('c = g.app.scriptDict.get("c")\n') f.write("p = c.p\n") f.write("# Actual script starts here.\n") f.write(script + "\n") finally: if f: f.close() # @-<< create leoScriptModule >> # pylint: disable=E0611 # E0611:runDebugScriptCommand: No name 'leoScriptModule' in module 'leo.core' g.app.scriptDict["c"] = c if "leoScriptModule" in sys.modules.keys(): del sys.modules["leoScriptModule"] # Essential. import leo.core.leoScriptModule as leoScriptModule else: g.error("No debugger active") c.bodyWantsFocus()
def cmd_PickDir(c): """cmd_PickDir - Show user a folder picker to create a new top level @path node :Parameters: - `c`: outline """ p = c.p aList = g.get_directives_dict_list(p) path = c.scanAtPathDirectives(aList) if p.h.startswith('@'): # see if it's a @<file> node of some sort nodepath = p.h.split(None, 1)[-1] nodepath = g.os_path_join(path, nodepath) if not g.os_path_isdir(nodepath): # remove filename nodepath = g.os_path_dirname(nodepath) if g.os_path_isdir(nodepath): # append if it's a directory path = nodepath ocwd = os.getcwd() try: os.chdir(path) except OSError: g.es("Couldn't find path %s"%path) dir_ = g.app.gui.runOpenDirectoryDialog("Pick a folder", "Pick a folder") os.chdir(ocwd) if not dir_: g.es("No folder selected") return nd = c.p.insertAfter() nd.h = "@path %s" % dir_ c.redraw()
def getConfiguration(): """Return the config object""" fileName = g.os_path_join(g.app.loadDir, "../", "plugins", "footprints.ini") config = ConfigParser.ConfigParser() config.read(fileName) return config
def profile_leo(): """ Gather and print statistics about Leo. @ To gather statistics, do the following in a console window: python profileLeo.py <list of .leo files> > profile.txt """ # Work around a Python distro bug: can fail on Ubuntu. try: import pstats except ImportError: g.es_print('can not import pstats: this is a Python distro bug') g.es_print( 'https://bugs.launchpad.net/ubuntu/+source/python-defaults/+bug/123755' ) g.es_print('try installing pstats yourself') return import cProfile as profile import leo.core.leoGlobals as g import os theDir = os.getcwd() # On Windows, name must be a plain string. name = str(g.os_path_normpath(g.os_path_join(theDir, 'leoProfile'))) # This is a binary file. print(f"profiling binary stats to {name}") profile.run('import leo ; leo.run()', name) p = pstats.Stats(name) p.strip_dirs() p.sort_stats('tottime') p.print_stats(200)
def onPostSave(tag=None, keywords=None): """After saving a nosentinels file, replace all tabs with spaces.""" global nosentNodes c = keywords.get('c') if c: at = c.atFileCommands for p in nosentNodes: g.red("node %s found" % p.h) at.scanAllDirectives(p) name = p.atNoSentinelsFileNodeName() fname = g.os_path_join(at.default_directory, name) f = open(fname, "r") lines = f.readlines() f.close() #@+<< add a newline before def or class >> #@+node:ekr.20040331151007.3: *3* << add a newline before def or class >> for i in range(len(lines)): ls = lines[i].lstrip() if ls.startswith("def ") or ls.startswith("class "): try: if lines[i - 1].strip() != "": lines[i] = "\n" + lines[i] except IndexError: pass #@-<< add a newline before def or class >> #@+<< replace tabs with spaces >> #@+node:ekr.20040331151007.4: *3* << replace tabs with spaces >> s = ''.join(lines) fh = open(fname, "w") fh.write(s.replace("\t", NSPACES)) fh.close() #@-<< replace tabs with spaces >> nosentNodes = []
def getConfiguration(): """Called when the user presses the "Apply" button on the Properties form""" fileName = g.os_path_join(g.app.loadDir,"../","plugins","word_export.ini") config = ConfigParser.ConfigParser() config.read(fileName) return config
def getConfiguration(): """Called when the user presses the "Apply" button on the Properties form""" fileName = g.os_path_join(g.app.loadDir, "../", "plugins", "word_export.ini") config = ConfigParser.ConfigParser() config.read(fileName) return config
def findDebugger(self): '''Find the debugger using settings.''' c = self.c pythonDir = g.os_path_dirname(sys.executable) debuggers = ( c.config.getString('debugger-path'), g.os_path_join(pythonDir, 'Lib', 'site-packages', 'winpdb.py'), # winpdb 1.1.2 or newer g.os_path_join(pythonDir, 'scripts', '_winpdb.py'), # oder version. ) for debugger in debuggers: if debugger: debugger = c.os_path_finalize(debugger) if g.os_path_exists(debugger): return debugger g.warning('debugger does not exist:', debugger) g.es('no debugger found.') return None
def loadIcons(self, p, clear=False): com = self.c.editCommands allIcons = com.getIconList(p) icons = [i for i in allIcons if 'cleoIcon' not in i] if clear: iterations = [] else: iterations = [True, False] for which in iterations: if which == (self.icon_order == 'pri-first'): pri = self.getat(p.v, 'priority') if pri: pri = int(pri) if pri in self.priorities: iconDir = g.os_path_abspath( g.os_path_normpath( g.os_path_join(g.app.loadDir,"..","Icons"))) com.appendImageDictToList(icons, iconDir, g.os_path_join('cleo',self.priorities[pri]['icon']), 2, on='vnode', cleoIcon='1', where=self.icon_location) # Icon location defaults to 'beforeIcon' unless cleo_icon_location global defined. # Example: @strings[beforeIcon,beforeHeadline] cleo_icon_location = beforeHeadline com.setIconList(p, icons) else: prog = self.getat(p.v, 'progress') if prog is not '': prog = int(prog) use = prog//10*10 use = 'prg%03d.png' % use iconDir = g.os_path_abspath( g.os_path_normpath( g.os_path_join(g.app.loadDir,"..","Icons"))) com.appendImageDictToList(icons, iconDir, g.os_path_join('cleo',use), 2, on='vnode', cleoIcon='1', where=self.prog_location) com.setIconList(p, icons) if len(allIcons) != len(icons): # something to add / remove com.setIconList(p, icons)
def setPaths(self): """Set paths to the plugin locations""" self.local_path = g.os_path_join(g.app.loadDir,"..","src") # self.remote_path = r"cvs.sourceforge.net/viewcvs.py/leo/leo/src" self.remote_path = r'leo.tigris.org/source/browse/leo/src' self.file_text = "File" self.has_enable_buttons = False self.has_conflict_buttons = False self.install_text = "Install all"
def findDebugger(self): '''Find the debugger using settings.''' c = self.c pythonDir = g.os_path_dirname(sys.executable) debuggers = ( c.config.getString('debugger_path'), g.os_path_join(pythonDir, 'Lib', 'site-packages', 'winpdb.py'), # winpdb 1.1.2 or newer g.os_path_join(pythonDir, 'scripts', '_winpdb.py'), # oder version. ) for debugger in debuggers: if debugger: debugger = c.os_path_finalize(debugger) if g.os_path_exists(debugger): return debugger else: g.warning('debugger does not exist:', debugger) g.es('no debugger found.') return None
def deleteit(result): if result is not None: # Remove old one tc = self.templateCollection tc.remove(tc.find(result)) filename = "%s.tpl" % result folder = g.os_path_abspath(self.folder) os.remove(g.os_path_join(folder, filename)) g.es('deleted template %s from %s' % (filename,folder),color='blue')
def runDebugScriptCommand (self,event=None): '''Called when user presses the 'debug-script' button or executes the debug-script command.''' c = self.c ; p = c.p script = g.getScript(c,p,useSelectedText=True,useSentinels=False) if script: #@+<< set debugging if debugger is active >> #@+node:ekr.20060523084441: *5* << set debugging if debugger is active >> g.trace(self.debuggerKind) if self.debuggerKind == 'winpdb': try: import rpdb2 debugging = rpdb2.g_debugger is not None except ImportError: debugging = False elif self.debuggerKind == 'idle': # import idlelib.Debugger.py as Debugger # debugging = Debugger.interacting debugging = True else: debugging = False #@-<< set debugging if debugger is active >> if debugging: #@+<< create leoScriptModule >> #@+node:ekr.20060524073716: *5* << create leoScriptModule >> (mod_scripting.py) target = g.os_path_join(g.app.loadDir,'leoScriptModule.py') f = None try: f = file(target,'w') f.write('# A module holding the script to be debugged.\n') if self.debuggerKind == 'idle': # This works, but uses the lame pdb debugger. f.write('import pdb\n') f.write('pdb.set_trace() # Hard breakpoint.\n') elif self.debuggerKind == 'winpdb': f.write('import rpdb2\n') f.write('if rpdb2.g_debugger is not None: # don\'t hang if the debugger isn\'t running.\n') f.write(' rpdb2.start_embedded_debugger(pwd="",fAllowUnencrypted=True) # Hard breakpoint.\n') # f.write('# Remove all previous variables.\n') f.write('# Predefine c, g and p.\n') f.write('import leo.core.leoGlobals as g\n') f.write('c = g.app.scriptDict.get("c")\n') f.write('p = c.p\n') f.write('# Actual script starts here.\n') f.write(script + '\n') finally: if f: f.close() #@-<< create leoScriptModule >> # pylint: disable=no-name-in-module g.app.scriptDict ['c'] = c if 'leoScriptModule' in sys.modules.keys(): del sys.modules ['leoScriptModule'] # Essential. import leo.core.leoScriptModule as leoScriptModule else: g.error('No debugger active') c.bodyWantsFocus()
def getLeoID(self): import os import sys g = self.g; tag = ".leoID.txt" homeDir = g.app.homeLeoDir globalConfigDir = g.app.globalConfigDir loadDir = g.app.loadDir verbose = False and not g.app.unitTesting #@+<< try to get leoID from sys.leoID >> #@+node:ekr.20070227094232.1: *5* << try to get leoID from sys.leoID>> # This would be set by in Python's sitecustomize.py file. # Use hasattr & getattr to suppress pylint warning. # We also have to use a "non-constant" attribute to suppress another warning! nonConstantAttr = "leoID" if hasattr(sys, nonConstantAttr): g.app.leoID = getattr(sys, nonConstantAttr) if verbose and not g.app.silentMode: g.red("leoID=", g.app.leoID, spaces=False) #@-<< try to get leoID from sys.leoID >> if not g.app.leoID: #@+<< try to get leoID from "leoID.txt" >> #@+node:ekr.20070227094232.2: *5* << try to get leoID from "leoID.txt" >> for theDir in (homeDir, globalConfigDir, loadDir): # N.B. We would use the _working_ directory if theDir is None! if theDir: try: fn = g.os_path_join(theDir, tag) f = open(fn, 'r') s = f.readline() f.close() if s and len(s) > 0: g.app.leoID = s.strip() if verbose and not g.app.silentMode: g.red('leoID=', g.app.leoID, ' (in ', theDir, ')', spaces=False) break elif verbose: g.red('empty ', tag, ' (in ', theDir, ')', spaces=False) except IOError: g.app.leoID = None except Exception: g.app.leoID = None g.error('unexpected exception in app.setLeoID') g.es_exception() #@-<< try to get leoID from "leoID.txt" >> if not g.app.leoID: #@+<< try to get leoID from os.getenv('USER') >> #@+node:ekr.20070227094232.3: *5* << try to get leoID from os.getenv('USER') >> try: theId = os.getenv('USER') if theId: if verbose: g.red("using os.getenv('USER'):", repr(theId)) g.app.leoID = theId except Exception: pass #@-<< try to get leoID from os.getenv('USER') >> return g.app.leoID
def save(self,c): """Save this template""" template_path = g.app.config.getString(c,'template_path') if template_path: filename = g.os_path_join(template_path, "%s.tpl" % self.name) else: filename = g.os_path_join( g.app.loadDir,"..","plugins", "templates", "%s.tpl" % self.name) f = file(filename, "w") g.es('writing template %s to %s' % (self.name,g.os_path_abspath(filename)),color='blue') try: f.write(repr(self)) finally: f.close()
def get_favicon(self): path = g.os_path_join(g.computeLeoDir(), 'Icons', 'LeoApp16.ico') try: f = StringIO() f2 = open(path) s = f2.read() f.write(s) return f except Exception: return None
def deleteit(result): if result is not None: # Remove old one tc = self.templateCollection tc.remove(tc.find(result)) filename = "%s.tpl" % result folder = g.os_path_abspath(self.folder) os.remove(g.os_path_join(folder, filename)) g.es('deleted template %s from %s' % (filename, folder), color='blue')
def loadTreeHandlers(self): """Load all the handler for tree items""" # # Paths for key folders plugin_path = g.os_path_join(g.app.loadDir, "..", "plugins") self.handler_path = handler_path = g.os_path_join( g.app.loadDir, "..", "plugins", "trees") # if not g.os_path_isdir(handler_path): g.es("No tree handler folder found", color="red") else: g.es("Scanning for tree handlers", color="blue") # # Add folder locations to path old_path = sys.path[:] sys.path.insert(0, plugin_path) sys.path.insert(0, handler_path) #@+<< Get plugin manager module >> #@+node:ekr.20050329082101.135: *4* << Get plugin manager module >> # Get the manager try: self.plugin_manager = __import__("plugin_manager") except ImportError as err: g.es("Autotrees did not load plugin manager: %s" % (err, ), color="red") self.plugin_manager = None #@-<< Get plugin manager module >> #@+<< Find all handlers >> #@+node:ekr.20050329082101.136: *4* << Find all handlers >> # Find all handlers for filename in glob.glob(g.os_path_join(handler_path, "*.py")): handler_name = g.os_path_splitext( g.os_path_split(filename)[1])[0] g.es("... looking in %s" % handler_name, color="blue") try: self.loadHandlersFrom(handler_name) except BadHandler as err: g.es("... unable to load '%s' handler: %s" % (handler_name, err), color="red") #@-<< Find all handlers >> # Restore sys.path = old_path
def __init__ (self,c): '''ctor for todoController class.''' self.c = c c.cleo = self self.donePriority = 100 self.menuicons = {} # menu icon cache self.recentIcons = [] #X self.smiley = None self.redrawLevels = 0 self.iconDir = g.os_path_abspath(g.os_path_normpath( g.os_path_join(g.app.loadDir,"..","Icons"))) #@+<< set / read default values >> #@+node:tbrown.20090119215428.12: *4* << set / read default values >> self.time_name = 'days' if c.config.getString('todo_time_name'): self.time_name = c.config.getString('todo_time_name') self.icon_location = 'beforeHeadline' if c.config.getString('todo_icon_location'): self.icon_location = c.config.getString('todo_icon_location') self.prog_location = 'beforeHeadline' if c.config.getString('todo_prog_location'): self.prog_location = c.config.getString('todo_prog_location') self.icon_order = 'pri-first' if c.config.getString('todo_icon_order'): self.icon_order = c.config.getString('todo_icon_order') #@-<< set / read default values >> self.handlers = [ ("close-frame",self.close), ('select3', self.updateUI), ('save2', self.loadAllIcons), ] # chdir so the Icons can be located, needed for uic resources owd = os.getcwd() os.chdir(g.os_path_join(g.app.loadDir, '..', 'plugins')) self.ui = todoQtUI(self) os.chdir(owd) for i in self.handlers: g.registerHandler(i[0], i[1]) self.loadAllIcons(setDirty=False)
def importDir(self, dir, compteurglobal): """ La routine récursive de lecture des fichiers """ if not g.os_path_exists(dir): if language == 'french': g.es("Ce répertoire n'existe pas: %s" + dir) else: g.es("No such Directory: %s" + dir) return compteurglobal head, tail = g.os_path_split(dir) c = self.c current = c.p try: #ici, on liste le contenu du répertoire body = "" #@+<< listdir >> #@+node:ekr.20050301083306.11: *4* << listdir >> try: fichiers = os.listdir(dir) dossiers = [] for f in fichiers: # mettre ici le code de création des noeuds path = g.os_path_join(dir, f) # est-ce un fichier ? if g.os_path_isfile(path): body += (f + "\n") else: # c'est alors un répertoire dossiers.append(path) compteurglobal += 1 except Exception: if language == 'french': g.es("erreur dans listage fichiers...") else: g.es("os.listdir error...") g.es_exception() #@-<< listdir >> p = c.importCommands.createHeadline(current, body, tail) c.selectPosition(p) if dossiers: for d in dossiers: compteurglobal = self.importDir(d, compteurglobal) c.setChanged() #sélectionne le noeud parent c.selectPosition(current) except Exception: if language == 'french': g.es("erreur d'insertion de noeud...") else: g.es("error while creating node...") g.es_exception() return compteurglobal
def importDir (self,dir,compteurglobal): """ La routine récursive de lecture des fichiers """ if not g.os_path_exists(dir): if language == 'french': g.es("Ce répertoire n'existe pas: %s" + dir) else: g.es("No such Directory: %s" + dir) return compteurglobal head,tail = g.os_path_split(dir) c = self.c ; current = c.p try: #ici, on liste le contenu du répertoire body="" #@+<< listdir >> #@+node:ekr.20050301083306.11: *4* << listdir >> try: fichiers = os.listdir(dir) dossiers = [] for f in fichiers: # mettre ici le code de création des noeuds path = g.os_path_join(dir,f) # est-ce un fichier ? if g.os_path_isfile(path): body += (f+"\n") else: # c'est alors un répertoire dossiers.append(path) compteurglobal += 1 except Exception: if language == 'french': g.es("erreur dans listage fichiers...") else: g.es("os.listdir error...") g.es_exception() #@-<< listdir >> p = c.importCommands.createHeadline(current,body,tail) c.selectPosition(p) if dossiers: for d in dossiers: compteurglobal = self.importDir(d,compteurglobal) c.setChanged(True) #sélectionne le noeud parent c.selectPosition(current) except Exception: if language == 'french': g.es("erreur d'insertion de noeud...") else: g.es("error while creating node...") g.es_exception() return compteurglobal
def _getpath(self, p): c = self.c dict = c.scanAllDirectives(p) d = dict.get("path") if p.isAnyAtFileNode(): filename = p.anyAtFileNodeName() filename = g.os_path_join(d, filename) if filename: d = g.os_path_dirname(filename) return '' if d is None else g.os_path_normpath(d)
def save(self, c): """Save this template""" template_path = g.app.config.getString(c, 'template_path') if template_path: filename = g.os_path_join(template_path, "%s.tpl" % self.name) else: filename = g.os_path_join(g.app.loadDir, "..", "plugins", "templates", "%s.tpl" % self.name) f = file(filename, "w") g.es('writing template %s to %s' % (self.name, g.os_path_abspath(filename)), color='blue') try: f.write(repr(self)) finally: f.close()
def get_favicon(self): path = g.os_path_join(g.computeLeoDir(), 'Icons', 'LeoApp16.ico') # g.trace(g.os_path_exists(path),path) try: f = StringIO() # f.write(open(path).read()) f2 = open(path) s = f.read() f.write(s) return f except Exception: return None
def openPythonWindow(self, event=None): '''Open Python's Idle debugger in a separate process.''' try: idlelib_path = imp.find_module('idlelib')[1] except ImportError: g.es_print('idlelib not found: can not open a Python window.') return idle = g.os_path_join(idlelib_path, 'idle.py') args = [sys.executable, idle] if 1: # Use present environment. os.spawnv(os.P_NOWAIT, sys.executable, args) else: # Use a pristine environment. os.spawnve(os.P_NOWAIT, sys.executable, args, os.environ)