Пример #1
0
def CloseProcess(c):

    global RunNode,ExitCode,WorkDir
    global In,OutThread,ErrThread

    # Close file and get error code.
    In.close()
    OutThread.File.close()
    ExitCode = ErrThread.File.close()

    # Unmark the node and reset it.
    RunNode.clearMarked()
    RunNode = None

    # Reset the working dir.
    if WorkDir != None:
        os.chdir(WorkDir)
        WorkDir = None

    # Write exit code.
    if ExitCode is None:
        g.blue("@run done")
    else:
        g.error("@run exits with code: %s" % (str(ExitCode)))	

    # Redraw.
    c.redraw()
Пример #2
0
def copyMarked(self, event=None):
    """Copy all marked nodes as children of a new node."""
    c = self; u = c.undoer; p1 = c.p.copy()
    # Create a new node to hold clones.
    parent = p1.insertAfter()
    parent.h = 'Copies of marked nodes'
    copied, n, p = [], 0, c.rootPosition()
    while p:
        # Careful: don't clone already-cloned nodes.
        if p == parent:
            p.moveToNodeAfterTree()
        elif p.isMarked() and p.v not in copied:
            copied.append(p.v)
            p2 = p.copyWithNewVnodes(copyMarked=True)
            p2._linkAsNthChild(parent, n)
            p.moveToNodeAfterTree()
            n += 1
        else:
            p.moveToThreadNext()
    if n:
        c.setChanged()
        parent.expand()
        c.selectPosition(parent)
        u.afterCopyMarkedNodes(p1)
    else:
        parent.doDelete()
        c.selectPosition(p1)
    if not g.unitTesting:
        g.blue(f"copied {n} nodes")
    c.redraw()
Пример #3
0
def stop(tag, keywords):

    c = keywords.get('c')
    if not c:
        g.trace('can not happen')
        return

    multi = scanForMultiPath(c)
    # g.trace(g.dictToString(multi))

    for fileName in multi.keys():
        paths = multi[fileName]
        for path in paths:
            try:
                if os.path.isdir(path):
                    shutil.copy2(fileName, path)
                    g.blue("multifile:\nWrote %s to %s" % (fileName, path))
                else:
                    g.error(
                        "multifile:\n%s is not a directory, not writing %s" %
                        (path, fileName))
            except:
                g.error("multifile:\nCant write %s to %s" % (fileName, path))
                g.es_exception_type()
    files.clear()
Пример #4
0
    def dtest(self, event):
        """The handler for dtest
        """

        import leo.core.leoGlobals as g


        # get a valid temporary filename
        createfile, tempfilename = g.create_temp_file()
        createfile.close()

        selected = False

        # if text is selected, only test selection
        if self.c.frame.body.hasTextSelection():
            selected = True
            selection = self.c.frame.body.getSelectedText()
            tempfile = open(tempfilename, 'w')
            tempfile.write(selection)
            tempfile.close()

        # if no selection, test this subtree
        else:
            self.c.importCommands.flattenOutline(tempfilename)

        tempfile = open(tempfilename)
        text = tempfile.readlines()
        tempfile.close()
        # strip trailing whitespace, an annoying source of doctest failures
        text = [line.rstrip() for line in text]
        text = "\n".join(text)
        tempfile = open(tempfilename, 'w')
        tempfile.write(text)
        tempfile.close()

        import copy

        # build globals dictionary
        globals = {'c':copy.copy(self.c), 'g':g}

        # run doctest on temporary file
        failures, tests = doctest.testfile(tempfilename, module_relative = False,
                            optionflags = doctest.ELLIPSIS, globs = globals)

        #@+<<report summary of results>>
        #@+node:ekr.20070119094733.10: *4* <<report summary of results>>
        if selected:
            g.es('Result of running doctest on selected text;')
        else:
            g.es('Result of running doctest on this subtree;')
        if failures == 0:
            g.blue("%s tests run successfully" % tests)
        if failures == 1:
            g.error("There was one failure in %s tests" % tests)
        if failures > 1:
            g.error("%s failures in %s tests" % (failures, tests))
        #@-<<report summary of results>>

        #clean up temp file
        os.remove(tempfilename)
def writeFileFromNode(self, event=None):
    """
    If node starts with @read-file-into-node, use the full path name in the headline.
    Otherwise, prompt for a file name.
    """
    c, p = self, self.p
    c.endEditing()
    h = p.h.rstrip()
    s = p.b
    tag = '@read-file-into-node'
    if h.startswith(tag):
        fileName = h[len(tag):].strip()
    else:
        fileName = None
    if not fileName:
        fileName = g.app.gui.runSaveFileDialog(c,
                                               title='Write File From Node',
                                               filetypes=[
                                                   ("All files", "*"),
                                                   ("Python files", "*.py"),
                                                   ("Leo files", "*.leo")
                                               ],
                                               defaultextension=None)
    if fileName:
        try:
            with open(fileName, 'w') as f:
                g.chdir(fileName)
                if s.startswith('@nocolor\n'):
                    s = s[len('@nocolor\n'):]
                f.write(s)
                f.flush()
                g.blue('wrote:', fileName)
        except IOError:
            g.error('can not write %s', fileName)
def writeFileFromNode(self, event=None):
    '''If node starts with @read-file-into-node, use the full path name in the headline.
    Otherwise, prompt for a file name.
    '''
    c = self; p = c.p
    c.endEditing()
    h = p.h.rstrip()
    s = p.b
    tag = '@read-file-into-node'
    if h.startswith(tag):
        fileName = h[len(tag):].strip()
    else:
        fileName = None
    if not fileName:
        filetypes = [("All files", "*"), ("Python files", "*.py"), ("Leo files", "*.leo"),]
        fileName = g.app.gui.runSaveFileDialog(c,
            initialfile=None,
            title='Write File From Node',
            filetypes=filetypes,
            defaultextension=None)
    if fileName:
        try:
            with open(fileName, 'w') as f:
                g.chdir(fileName)
                if s.startswith('@nocolor\n'):
                    s = s[len('@nocolor\n'):]
                if not g.isPython3: # 2010/08/27
                    s = g.toEncodedString(s, reportErrors=True)
                f.write(s)
                f.flush()
                g.blue('wrote:', fileName)
        except IOError:
            g.error('can not write %s', fileName)
Пример #7
0
def CloseProcess(c):

    global RunNode,ExitCode,WorkDir
    global In,OutThread,ErrThread

    # Close file and get error code.
    In.close()
    OutThread.File.close()
    ExitCode = ErrThread.File.close()

    # Unmark the node and reset it.
    RunNode.clearMarked()
    RunNode = None

    # Reset the working dir.
    if WorkDir is not None:
        os.chdir(WorkDir)
        WorkDir = None

    # Write exit code.
    if ExitCode is None:
        g.blue("@run done")
    else:
        g.error("@run exits with code: %s" % (str(ExitCode)))

    # Redraw.
    c.redraw()
Пример #8
0
 def reportDirectories(self):
     g = self.g
     for kind, theDir in (
         ("global config", g.app.globalConfigDir),
         ("home", g.app.homeDir),
     ):
         g.blue('', kind, 'directory', '', ':', theDir)
Пример #9
0
    def dtest(self, event):
        """The handler for dtest
        """

        import leo.core.leoGlobals as g


        # get a valid temporary filename
        createfile, tempfilename = g.create_temp_file()
        createfile.close()

        selected = False

        # if text is selected, only test selection
        if self.c.frame.body.hasTextSelection():
            selected = True
            selection = self.c.frame.body.getSelectedText()
            tempfile = open(tempfilename, 'w')
            tempfile.write(selection)
            tempfile.close()

        # if no selection, test this subtree
        else:
            self.c.importCommands.flattenOutline(tempfilename)

        tempfile = open(tempfilename)
        text = tempfile.readlines()
        tempfile.close()    
        # strip trailing whitespace, an annoying source of doctest failures
        text = [line.rstrip() for line in text]
        text = "\n".join(text)
        tempfile = open(tempfilename, 'w')
        tempfile.write(text)
        tempfile.close()

        import copy

        # build globals dictionary
        globals = {'c':copy.copy(self.c), 'g':g}

        # run doctest on temporary file
        failures, tests = doctest.testfile(tempfilename, module_relative = False, 
                            optionflags = doctest.ELLIPSIS, globs = globals)

        #@+<<report summary of results>>
        #@+node:ekr.20070119094733.10: *4* <<report summary of results>>
        if selected:
            g.es('Result of running doctest on selected text;')
        else:
            g.es('Result of running doctest on this subtree;')        
        if failures == 0:
            g.blue("%s tests run successfully" % tests)
        if failures == 1:
            g.error("There was one failure in %s tests" % tests)    
        if failures > 1:
            g.error("%s failures in %s tests" % (failures, tests))
        #@-<<report summary of results>>

        #clean up temp file
        os.remove(tempfilename)
Пример #10
0
def writeFileFromNode(self, event=None):
    '''If node starts with @read-file-into-node, use the full path name in the headline.
    Otherwise, prompt for a file name.
    '''
    c = self; p = c.p
    c.endEditing()
    h = p.h.rstrip()
    s = p.b
    tag = '@read-file-into-node'
    if h.startswith(tag):
        fileName = h[len(tag):].strip()
    else:
        fileName = None
    if not fileName:
        filetypes = [("All files", "*"), ("Python files", "*.py"), ("Leo files", "*.leo"),]
        fileName = g.app.gui.runSaveFileDialog(c,
            initialfile=None,
            title='Write File From Node',
            filetypes=filetypes,
            defaultextension=None)
    if fileName:
        try:
            with open(fileName, 'w') as f:
                g.chdir(fileName)
                if s.startswith('@nocolor\n'):
                    s = s[len('@nocolor\n'):]
                if not g.isPython3: # 2010/08/27
                    s = g.toEncodedString(s, reportErrors=True)
                f.write(s)
                f.flush()
                g.blue('wrote:', fileName)
        except IOError:
            g.error('can not write %s', fileName)
Пример #11
0
def init():
    '''Return True if the plugin has loaded successfully.'''
    g.blue("nodeActions: Init")
    ok = not g.app.unitTesting  # Dangerous for unit testing.
    if ok:
        g.registerHandler("icondclick1", onIconDoubleClickNA)
        g.plugin_signon(__name__)
    return ok
Пример #12
0
def init():

	 g.blue("nodeActions: Init")
	 ok = not g.app.unitTesting # Dangerous for unit testing.
	 if ok:
		  g.registerHandler("icondclick1", onIconDoubleClickNA)
		  g.plugin_signon(__name__)
	 return ok
Пример #13
0
 def enableGcTrace(self, event=None):
     '''Disable tracing of Python's Garbage Collector.'''
     g.trace_gc = True
     g.enable_gc_debug()
     if g.trace_gc_verbose:
         g.blue('enabled verbose gc stats')
     else:
         g.blue('enabled brief gc stats')
Пример #14
0
def init():
    '''Return True if the plugin has loaded successfully.'''
    g.blue("nodeActions: Init")
    ok = not g.app.unitTesting # Dangerous for unit testing.
    if ok:
        g.registerHandler("icondclick1", onIconDoubleClickNA)
        g.plugin_signon(__name__)
    return ok
Пример #15
0
 def enableGcTrace(self, event=None):
     '''Disable tracing of Python's Garbage Collector.'''
     g.trace_gc = True
     g.enable_gc_debug()
     if g.trace_gc_verbose:
         g.blue('enabled verbose gc stats')
     else:
         g.blue('enabled brief gc stats')
Пример #16
0
def doMinidomTest( c ):
    '''This def performs a simple test on a node.  Can the data be successfully parsed by minidom or not.  Results are output to the log'''
    s = getString( c )
    try:
        mdom = minidom.parseString( s )
    except Exception as x:
        g.error("Minidom could not parse node because of:\n %s" % x)
        return
    g.blue("Minidom could parse the node")
Пример #17
0
def doMinidomTest(c):
    '''This def performs a simple test on a node.  Can the data be successfully parsed by minidom or not.  Results are output to the log'''
    s = getString(c)
    try:
        mdom = minidom.parseString(s)
    except Exception as x:
        g.error("Minidom could not parse node because of:\n %s" % x)
        return
    g.blue("Minidom could parse the node")
Пример #18
0
 def update_open_with_node(self, ef):
     """Update the body text of ef.p to the contents of ef.path."""
     assert isinstance(ef, ExternalFile), ef
     c, p = ef.c, ef.p.copy()
     g.blue(f"updated {p.h}")
     s, e = g.readFileIntoString(ef.path)
     p.b = s
     if c.config.getBool('open-with-goto-node-on-update'):
         c.selectPosition(p)
     if c.config.getBool('open-with-save-on-update'):
         c.save()
     else:
         p.setDirty()
         c.setChanged()
Пример #19
0
 def executeScriptFromButton (self,b,buttonText,gnx):
     '''Called from callbacks to execute the script in node p whose gnx is given.'''
     c = self.c
     if c.disableCommandsMessage:
         g.blue(c.disableCommandsMessage)
     else:
         g.app.scriptDict = {}
         p = self.find_gnx(gnx)
         if p:
             args = self.getArgs(p.h)
             c.executeScript(args=args,p=p,silent=True)
             # Remove the button if the script asks to be removed.
             if g.app.scriptDict.get('removeMe'):
                 g.es("Removing '%s' button at its request" % buttonText)
                 self.deleteButton(b)
Пример #20
0
 def handleAtScriptNode(self, p):
     '''Handle @script nodes.'''
     c = self.c
     tag = "@script"
     assert (g.match(p.h, 0, tag))
     name = p.h[len(tag):].strip()
     args = self.getArgs(p)
     if self.atScriptNodes:
         g.blue("executing script %s" % (name))
         c.executeScript(args=args, p=p, useSelectedText=False, silent=True)
     else:
         g.warning("disabled @script: %s" % (name))
     if 0:
         # Do not assume the script will want to remain in this commander.
         c.bodyWantsFocus()
Пример #21
0
 def handleAtScriptNode (self,p):
     '''Handle @script nodes.'''
     c = self.c
     tag = "@script"
     assert(g.match(p.h,0,tag))
     name = p.h[len(tag):].strip()
     args = self.getArgs(p)
     if self.atScriptNodes:
         g.blue("executing script %s" % (name))
         c.executeScript(args=args,p=p,useSelectedText=False,silent=True)
     else:
         g.warning("disabled @script: %s" % (name))
     if 0:
         # Do not assume the script will want to remain in this commander.
         c.bodyWantsFocus()
Пример #22
0
 def update_open_with_node(self, ef):
     '''Update the body text of ef.p to the contents of ef.path.'''
     trace = False and not g.unitTesting
     assert isinstance(ef, ExternalFile), ef
     if trace: g.trace(repr(ef))
     c, p = ef.c, ef.p.copy()
     # Ask the user how to resolve the conflict.
     if self.ask(c, ef.path, p=p):
         g.blue('updated %s' % p.h)
         s, e = g.readFileIntoString(ef.path)
         p.b = s
         if c.config.getBool('open_with_goto_node_on_update'):
             c.selectPosition(p)
         if c.config.getBool('open_with_save_on_update'):
             c.save()
Пример #23
0
 def update_open_with_node(self, ef):
     '''Update the body text of ef.p to the contents of ef.path.'''
     trace = False and not g.unitTesting
     assert isinstance(ef, ExternalFile), ef
     if trace: g.trace(repr(ef))
     c, p = ef.c, ef.p.copy()
     # Ask the user how to resolve the conflict.
     if self.ask(c, ef.path, p=p):
         g.blue('updated %s' % p.h)
         s, e = g.readFileIntoString(ef.path)
         p.b = s
         if c.config.getBool('open_with_goto_node_on_update'):
             c.selectPosition(p)
         if c.config.getBool('open_with_save_on_update'):
             c.save()
Пример #24
0
 def update_open_with_node(self, ef):
     '''Update the body text of ef.p to the contents of ef.path.'''
     assert isinstance(ef, ExternalFile), ef
     c, p = ef.c, ef.p.copy()
     # Ask the user how to resolve the conflict.
     if self.ask(c, ef.path, p=p):
         g.blue('updated %s' % p.h)
         s, e = g.readFileIntoString(ef.path)
         p.b = s
         if c.config.getBool('open-with-goto-node-on-update'):
             c.selectPosition(p)
         if c.config.getBool('open-with-save-on-update'):
             c.save()
         else:
             p.setDirty()
             c.setChanged(True)
Пример #25
0
 def update_open_with_node(self, ef):
     '''Update the body text of ef.p to the contents of ef.path.'''
     assert isinstance(ef, ExternalFile), ef
     c, p = ef.c, ef.p.copy()
     # Ask the user how to resolve the conflict.
     if self.ask(c, ef.path, p=p):
         g.blue(f"updated {p.h}")
         s, e = g.readFileIntoString(ef.path)
         p.b = s
         if c.config.getBool('open-with-goto-node-on-update'):
             c.selectPosition(p)
         if c.config.getBool('open-with-save-on-update'):
             c.save()
         else:
             p.setDirty()
             c.setChanged()
Пример #26
0
    def loadHandlers(self, tag, keys):
        """Load all enabled plugins from the plugins directory"""
        def pr(*args, **keys):
            if not g.app.unitTesting:
                g.es_print(*args, **keys)

        s = g.app.config.getEnabledPlugins()
        if not s: return
        if tag == 'open0' and not g.app.silentMode and not g.app.batchMode:
            if 0:
                s2 = '@enabled-plugins found in %s' % (
                    g.app.config.enabledPluginsFileName)
                g.blue(s2)
        for plugin in s.splitlines():
            if plugin.strip() and not plugin.lstrip().startswith('#'):
                self.loadOnePlugin(plugin.strip(), tag=tag)
Пример #27
0
    def executeScriptFromButton(self, b, buttonText, gnx):
        '''Called from callbacks to execute the script in node p whose gnx is given.'''

        c = self.c
        if c.disableCommandsMessage:
            g.blue(c.disableCommandsMessage)
        else:
            g.app.scriptDict = {}
            p = self.find_gnx(gnx)
            if p:
                args = self.getArgs(p.h)
                c.executeScript(args=args, p=p, silent=True)
                # Remove the button if the script asks to be removed.
                if g.app.scriptDict.get('removeMe'):
                    g.es("Removing '%s' button at its request" % buttonText)
                    self.deleteButton(b)
Пример #28
0
def goToNextClone(self, event=None):
    """
    Select the next node that is a clone of the selected node.
    If the selected node is not a clone, do find-next-clone.
    """
    c, p = self, self.p
    cc = c.chapterController; p = c.p
    if not p:
        return
    if not p.isCloned():
        c.findNextClone()
        return
    v = p.v
    p.moveToThreadNext()
    wrapped = False
    while 1:
        if p and p.v == v:
            break
        elif p:
            p.moveToThreadNext()
        elif wrapped:
            break
        else:
            wrapped = True
            p = c.rootPosition()
    if p:
        c.expandAllAncestors(p)
        if cc:
            # #252: goto-next clone activate chapter.
            chapter = cc.getSelectedChapter()
            old_name = chapter and chapter.name
            new_name = cc.findChapterNameForPosition(p)
            if new_name == old_name:
                # Always do a full redraw.
                c.redraw(p)
            else:
                if 1:
                    cc.selectChapterByName(new_name)
                    c.redraw(p)
                else:  # Old code.
                    c.selectPosition(p)
                    cc.selectChapterByName(new_name)
        else:
            # Always do a full redraw.
            c.redraw(p)
    else:
        g.blue('done')
Пример #29
0
    def executeScriptFromSettingButton(self, args, b, script, buttonText):
        '''Called from callbacks to execute the script in node p.'''

        c = self.c

        if c.disableCommandsMessage:
            g.blue(c.disableCommandsMessage)
        else:
            g.app.scriptDict = {}
            c.executeScript(args=args, script=script, silent=True)
            # Remove the button if the script asks to be removed.
            if g.app.scriptDict.get('removeMe'):
                g.es("Removing '%s' button at its request" % buttonText)
                self.deleteButton(b)

        if 0:  # Do *not* set focus here: the script may have changed the focus.
            c.frame.bodyWantsFocus()
Пример #30
0
    def loadHandlers(self, tag, keys):
        """Load all enabled plugins from the plugins directory"""

        def pr(*args, **keys):
            if not g.app.unitTesting:
                g.es_print(*args, **keys)

        s = g.app.config.getEnabledPlugins()
        if not s: return
        if tag == 'open0' and not g.app.silentMode and not g.app.batchMode:
            if 0:
                s2 = '@enabled-plugins found in %s' % (
                    g.app.config.enabledPluginsFileName)
                g.blue(s2)
        for plugin in s.splitlines():
            if plugin.strip() and not plugin.lstrip().startswith('#'):
                self.loadOnePlugin(plugin.strip(), tag=tag)
Пример #31
0
def markChangedHeadlines(self, event=None):
    """Mark all nodes that have been changed."""
    c = self; u = c.undoer; undoType = 'Mark Changed'
    current = c.p
    c.endEditing()
    u.beforeChangeGroup(current, undoType)
    for p in c.all_unique_positions():
        if p.isDirty() and not p.isMarked():
            bunch = u.beforeMark(p, undoType)
            # c.setMarked calls a hook.
            c.setMarked(p)
            p.setDirty()
            c.setChanged()
            u.afterMark(p, undoType, bunch)
    u.afterChangeGroup(current, undoType)
    if not g.unitTesting:
        g.blue('done')
    c.redraw_after_icons_changed()
Пример #32
0
    def executeScriptFromSettingButton (self,args,b,script,buttonText):

        '''Called from callbacks to execute the script in node p.'''

        c = self.c

        if c.disableCommandsMessage:
            g.blue(c.disableCommandsMessage)
        else:
            g.app.scriptDict = {}
            c.executeScript(args=args,script=script,silent=True)
            # Remove the button if the script asks to be removed.
            if g.app.scriptDict.get('removeMe'):
                g.es("Removing '%s' button at its request" % buttonText)
                self.deleteButton(b)

        if 0: # Do *not* set focus here: the script may have changed the focus.
            c.bodyWantsFocus()
Пример #33
0
 def executeScriptFromButton (self,b,buttonText,p,script):
     '''Execute an @button script in p.b or script.'''
     c = self.c
     if c.disableCommandsMessage:
         g.blue(c.disableCommandsMessage)
         return None
     if not p and not script:
         g.trace('can not happen: no p and no script')
         return
     g.app.scriptDict = {}
     args = self.getArgs(p)
     if not script:
         script = self.getScript(p)
     c.executeScript(args=args,p=p,script=script,silent=True)
     # Remove the button if the script asks to be removed.
     if g.app.scriptDict.get('removeMe'):
         g.es("Removing '%s' button at its request" % buttonText)
         self.deleteButton(b)
Пример #34
0
 def executeScriptFromButton(self, b, buttonText, p, script):
     '''Execute an @button script in p.b or script.'''
     c = self.c
     if c.disableCommandsMessage:
         g.blue(c.disableCommandsMessage)
         return None
     if not p and not script:
         g.trace('can not happen: no p and no script')
         return
     g.app.scriptDict = {}
     args = self.getArgs(p)
     if not script:
         script = self.getScript(p)
     c.executeScript(args=args, p=p, script=script, silent=True)
     # Remove the button if the script asks to be removed.
     if g.app.scriptDict.get('removeMe'):
         g.es("Removing '%s' button at its request" % buttonText)
         self.deleteButton(b)
Пример #35
0
def goToNextDirtyHeadline(self, event=None):
    """Select the node that is marked as changed."""
    c = self; p = c.p
    if not p: return
    p.moveToThreadNext()
    wrapped = False
    while 1:
        if p and p.isDirty():
            break
        elif p:
            p.moveToThreadNext()
        elif wrapped:
            break
        else:
            wrapped = True
            p = c.rootPosition()
    if not p: g.blue('done')
    c.treeSelectHelper(p)  # Sets focus.
Пример #36
0
def goToPrevMarkedHeadline(self, event=None):
    """Select the next marked node."""
    c = self; p = c.p
    if not p: return
    p.moveToThreadBack()
    wrapped = False
    while 1:
        if p and p.isMarked():
            break
        elif p:
            p.moveToThreadBack()
        elif wrapped:
            break
        else:
            wrapped = True
            p = c.rootPosition()
    if not p: g.blue('done')
    c.treeSelectHelper(p)  # Sets focus.
Пример #37
0
def on_open (tag,keywords):

    c = keywords.get("c")
    if not c: return

    p = c.rootPosition()
    g.blue("scanning for @read-only nodes...")
    while p:
        h = p.h
        if g.match_word(h,0,"@read-only"):
            changed = insert_read_only_node(c,p,h[11:])
            g.red("changing %s" % p.h)
            if changed:
                if not p.isDirty():
                    p.setDirty()
                if not c.isChanged():
                    c.setChanged(changed)
        p.moveToThreadNext()
    c.redraw()
Пример #38
0
def on_open(tag, keywords):

    c = keywords.get("c")
    if not c: return

    p = c.rootPosition()
    g.blue("scanning for @read-only nodes...")
    while p:
        h = p.h
        if g.match_word(h, 0, "@read-only"):
            changed = insert_read_only_node(c, p, h[11:])
            g.red("changing %s" % p.h)
            if changed:
                if not p.isDirty():
                    p.setDirty()
                if not c.isChanged():
                    c.setChanged()
        p.moveToThreadNext()
    c.redraw()
Пример #39
0
def cmd_Export(event):
    '''Export the current node to Word'''
    c = event.get('c')
    try:
        word = getWordConnection()
        if word:
            header_style = getConfiguration().get("Main", "Header_Style")
            # Based on the rst plugin
            g.blue("Writing tree to Word")
            config = getConfiguration()
            writeNodeAndTree(
                c, word,
                config.get("Main", "header_style").strip(), 1,
                int(config.get("Main", "max_headings")),
                config.get("Main", "use_section_numbers") == "Yes", "")
            g.es("Done!")
    except Exception as err:
        g.error("Exception writing Word")
        g.es_exception()
Пример #40
0
def markChangedRoots(self, event=None):
    """Mark all changed @root nodes."""
    c = self; u = c.undoer; undoType = 'Mark Changed'
    current = c.p
    c.endEditing()
    u.beforeChangeGroup(current, undoType)
    for p in c.all_unique_positions():
        if p.isDirty() and not p.isMarked():
            s = p.b
            flag, i = g.is_special(s, "@root")
            if flag:
                bunch = u.beforeMark(p, undoType)
                c.setMarked(p)  # Calls a hook.
                p.setDirty()
                c.setChanged()
                u.afterMark(p, undoType, bunch)
    u.afterChangeGroup(current, undoType)
    if not g.unitTesting:
        g.blue('done')
    c.redraw_after_icons_changed()
Пример #41
0
def findNextClone(self, event=None):
    """Select the next cloned node."""
    c = self; p = c.p; cc = c.chapterController
    if not p: return
    if p.isCloned():
        p.moveToThreadNext()
    flag = False
    while p:
        if p.isCloned():
            flag = True; break
        else:
            p.moveToThreadNext()
    if flag:
        if cc:
            # name = cc.findChapterNameForPosition(p)
            cc.selectChapterByName('main')
        c.selectPosition(p)
        c.redraw_after_select(p)
    else:
        g.blue('no more clones')
Пример #42
0
def stop (tag,keywords):

    c = keywords.get('c')
    if not c:
        g.trace('can not happen')
        return
    multi = scanForMultiPath(c)
    for fileName in multi:
        paths = multi.get(fileName)
        for path in paths:
            try:
                if os.path.isdir(path):
                    shutil.copy2(fileName,path)
                    g.blue("multifile:\nWrote %s to %s" % (fileName,path))
                else:
                    g.error("multifile:\n%s is not a directory, not writing %s" % (path,fileName))
            except Exception:
                g.error("multifile:\nCant write %s to %s" % (fileName,path))
                g.es_exception_type()
    files.clear()
Пример #43
0
    def loadHandlers(self, tag, keys):
        """
        Load all enabled plugins.

        Using a module name (without the trailing .py) allows a plugin to
        be loaded from outside the leo/plugins directory.
        """
        def pr(*args, **keys):
            if not g.app.unitTesting:
                g.es_print(*args, **keys)

        s = g.app.config.getEnabledPlugins()
        if not s: return
        if tag == 'open0' and not g.app.silentMode and not g.app.batchMode:
            if 0:
                s2 = f"@enabled-plugins found in {g.app.config.enabledPluginsFileName}"
                g.blue(s2)
        for plugin in s.splitlines():
            if plugin.strip() and not plugin.lstrip().startswith('#'):
                self.loadOnePlugin(plugin.strip(), tag=tag)
Пример #44
0
def cmd_Export(event):
    '''Export the current node to Word'''
    c = event.get('c')
    try:
        word = getWordConnection()
        if word:
            # header_style = getConfiguration().get("Main", "Header_Style")
            # Based on the rst plugin
            g.blue("Writing tree to Word")
            config = getConfiguration()
            writeNodeAndTree(c,word,
                config.get("Main", "header_style").strip(),
                1,
                int(config.get("Main", "max_headings")),
                config.get("Main", "use_section_numbers") == "Yes",
                "")
            g.es("Done!")
    except Exception:
        g.error("Exception writing Word")
        g.es_exception()
Пример #45
0
 def executeScriptFromButton(self, b, buttonText, p, script):
     """
     Called in various contexts to execute an @button script.
     1. If p is given, use the script in p.b.
     2. If script is given, use that.
     3. Finally, search for the node whose gnx is given.
     qt_frame.py call this method, so it must be a method of this class.
     """
     c = self.c
     if c.disableCommandsMessage:
         g.blue(c.disableCommandsMessage)
         return None
     g.app.scriptDict = {}
     args = self.getArgs(p)
     # Note: use c.p, not p!
     c.executeScript(args=args, p=p, script=script, silent=True)
     # Remove the button if the script asks to be removed.
     if g.app.scriptDict.get("removeMe"):
         g.es("Removing '%s' button at its request" % buttonText)
         self.deleteButton(b)
Пример #46
0
def deleteMarked(self, event=None):
    """Delete all marked nodes."""
    c = self; u = c.undoer; p1 = c.p.copy()
    undo_data, p = [], c.rootPosition()
    while p:
        if p.isMarked():
            undo_data.append(p.copy())
            next = p.positionAfterDeletedTree()
            p.doDelete()
            p = next
        else:
            p.moveToThreadNext()
    if undo_data:
        u.afterDeleteMarkedNodes(undo_data, p1)
        if not g.unitTesting:
            g.blue(f"deleted {len(undo_data)} nodes")
        c.setChanged()
    # Don't even *think* about restoring the old position.
    c.contractAllHeadlines()
    c.selectPosition(c.rootPosition())
    c.redraw()
Пример #47
0
    def loadHandlers(self, tag, keys):
        '''
        Load all enabled plugins.

        Using a module name (without the trailing .py) allows a plugin to
        be loaded from outside the leo/plugins directory.
        '''

        def pr(*args, **keys):
            if not g.app.unitTesting:
                g.es_print(*args, **keys)

        s = g.app.config.getEnabledPlugins()
        if not s: return
        if tag == 'open0' and not g.app.silentMode and not g.app.batchMode:
            if 0:
                s2 = '@enabled-plugins found in %s' % (
                    g.app.config.enabledPluginsFileName)
                g.blue(s2)
        for plugin in s.splitlines():
            if plugin.strip() and not plugin.lstrip().startswith('#'):
                self.loadOnePlugin(plugin.strip(), tag=tag)
Пример #48
0
def cloneMarked(self, event=None):
    """Clone all marked nodes as children of a new node."""
    c = self; u = c.undoer; p1 = c.p.copy()
    # Create a new node to hold clones.
    parent = p1.insertAfter()
    parent.h = 'Clones of marked nodes'
    cloned, n, p = [], 0, c.rootPosition()
    while p:
        # Careful: don't clone already-cloned nodes.
        if p == parent:
            p.moveToNodeAfterTree()
        elif p.isMarked() and p.v not in cloned:
            cloned.append(p.v)
            if 0:  # old code
                # Calling p.clone would cause problems
                p.clone().moveToLastChildOf(parent)
            else:  # New code.
                # Create the clone directly as a child of parent.
                p2 = p.copy()
                n = parent.numberOfChildren()
                p2._linkAsNthChild(parent, n)
            p.moveToNodeAfterTree()
            n += 1
        else:
            p.moveToThreadNext()
    if n:
        c.setChanged()
        parent.expand()
        c.selectPosition(parent)
        u.afterCloneMarkedNodes(p1)
    else:
        parent.doDelete()
        c.selectPosition(p1)
    if not g.unitTesting:
        g.blue(f"cloned {n} nodes")
    c.redraw()
Пример #49
0
def OpenProcess(p):

    global RunNode,WorkDir
    global In,OutThread,ErrThread,ExitCode

    command = p.h[4:].strip() # Remove @run
    if not command: return
    #@+<< set the working directory or return >>
    #@+node:ekr.20040910094754: *3* << set the working directory or return >>
    args = command.split(' ')

    path,fname = os.path.split(args[0])

    if g.match(fname,0,'#'):
        return

    if path:
        if os.access(path,os.F_OK) == 1:
            WorkDir=os.getcwd()
            os.chdir(path)
        else:
            g.error("@run: invalid path: %s" % (path))
            return
    #@-<< set the working directory or return >>
    #@+<< set the command, removing all args following '#' >>
    #@+node:ekr.20040910100935: *3* << set the command, removing all args following '#' >>
    command = fname

    for arg in args[1:]:
        if g.match(arg,0,'#'):
            break
        else:
            command += ' ' + arg.strip()
    #@-<< set the command, removing all args following '#' >>
    if not command.strip():
        return
    RunNode=p
    args = []
    #@+<< append arguments from child nodes to command >>
    #@+node:ekr.20040910095147: *3* << append arguments from child nodes to command >>
    for child in p.children():
        h = child.h
        if g.match_word(h,0,"@arg"):
            arg = h[4:].strip()
            args.append(arg)
        else:
            if (
                not g.match_word(h,0,"@run") and
                not g.match_word(h,0,"@in") and
                not g.match_word(h,0,"@input")
            ):
                args.append(child.b.strip())
    #@-<< append arguments from child nodes to command >>

    g.blue("@run %s>%s" % (os.getcwd(),command))
    for arg in args:
        g.blue("@arg %s" % arg)
    command += ' ' + ' '.join(args)

    # Start the threads and open the pipe.
    OutThread = readingThread()
    ErrThread = readingThread()		
				
    # In,OutThread.File,ErrThread.File	= os.popen3(command,"t")
    #### OutThread.File,In,ErrThread.File = os.popen3(command,"t")
    
    PIPE = subprocess.PIPE
    proc = subprocess.Popen(command, shell=True) # , # bufsize=bufsize,
    #     stdin=PIPE,stdout=PIPE,stderr=PIPE) # ,close_fds=True)
        
    In             = proc.stdin
    OutThread.File = proc.stdout
    ErrThread.File = proc.stderr
    	
    OutThread.start()
    ErrThread.start()	

    # Mark and select the node.
    RunNode.setMarked()
    c = RunNode.v.context
    c.selectPosition(RunNode)
    if os.name in ("nt","dos"):
        c.redraw()
Пример #50
0
    def message (self,s):

        g.blue(s)
Пример #51
0
def editnode_on_idle (tag,keywords):

    #g.trace(tag,keywords)

    import os
    a = g.app
    if a.killed: return
    # g.trace('open with plugin')
    for dict in a.openWithFiles:
        path = dict.get("path")
        c = dict.get("c")
        encoding = dict.get("encoding",None)
        p = dict.get("p")
        old_body = dict.get("body")
        if path and os.path.exists(path):
            try:
                time = os.path.getmtime(path)
                # g.trace(path,time,dict.get('time'))
                if time and time != dict.get("time"):
                    dict["time"] = time # inhibit endless dialog loop.
                    # The file has changed.
                    #@+<< set s to the file text >>
                    #@+node:ville.20090701142447.5474: *3* << set s to the file text >>
                    try:
                        # Update v from the changed temp file.
                        f=open(path)
                        s=f.read()
                        f.close()
                    except:
                        g.es("can not open " + g.shortFileName(path))
                        break
                    #@-<< set s to the file text >>
                    #@+<< update p's body text >>
                    #@+node:ville.20090701142447.5475: *3* << update p's body text >>
                    # Convert body and s to whatever encoding is in effect.
                    body = p.b
                    body = g.toEncodedString(body,encoding,reportErrors=True)
                    s = g.toEncodedString(s,encoding,reportErrors=True)

                    conflict = body != old_body and body != s

                    # Set update if we should update the outline from the file.
                    if conflict:
                        # 2012/02/04: Don't raise dialog for files opened with vim.py, xemacs.py, etc.
                        paths = [z.get('path') for z in g.app.openWithFiles]
                        if path in paths:
                            update = True
                        else:
                            # See how the user wants to resolve the conflict.
                            g.error("conflict in " + g.shortFileName(path))
                            message = "Replace changed outline with external changes?"
                            result = g.app.gui.runAskYesNoDialog(c,"Conflict!",message)
                            update = result.lower() == "yes"
                    else:
                        update = s != body

                    if update:
                        g.blue("updated from: " + g.shortFileName(path))
                        s = g.toUnicode(s,encoding=encoding)
                        c.setBodyString(p,s)
                        #TL - 7/2/08 Converted to configurable 'goto node...'
                        if c.config.getBool('open_with_goto_node_on_update'):
                            c.selectPosition(p)
                        dict["body"] = s
                        # A patch by Terry Brown.
                        if c.config.getBool('open_with_save_on_update'):
                            c.save()
                    elif conflict:
                        g.blue("not updated from: " + g.shortFileName(path))
                    #@-<< update p's body text >>
            except Exception:
                # g.es_exception()
                pass
Пример #52
0
def doNodeAction(pClicked, c):

    hClicked = pClicked.h.strip()

    #Display messages based on 'messageLevel'.  Valid values:
    #    0 = log no messages
    #    1 = log that the plugin was triggered and each matched patterns
    #    2 = log 1 & 'event passed'
    #    3 = log 1,2 & 'no match to pattern'
    #    4 = log 1,2,3, & any code debugging messages,
    #              matched pattern's 'directives', and '@file saved' settings
    messageLevel = c.config.getInt('nodeActions_message_level')

    if messageLevel >= 1:
        g.es( "nodeActions: triggered" )

    #Save @file type nodes before running script if enabled
    saveAtFile = c.config.getBool('nodeActions_save_atFile_nodes')
    if messageLevel >= 4:
        g.blue( "nA: Global nodeActions_save_atFile_nodes=",saveAtFile)
    #Find the "nodeActions" node
    pNA = g.findNodeAnywhere(c,"nodeActions")
    if not pNA:
        pNA = g.findNodeAnywhere(c,"NodeActions")

    if pNA:
        #Found "nodeActions" node
        foundPattern = False
        passEventExternal = False  #No pass to next plugin after pattern matched
        #Check entire subtree under the "nodeActions" node for pattern
        for pScript in pNA.subtree():

            #Nodes with subnodes are not tested for a match
            if pScript.hasChildren():
                continue

            #Don't trigger on double click of a nodeActions' pattern node
            if pClicked == pScript:
                continue

            pattern = pScript.h.strip()    #Pattern node's header
            if messageLevel >= 4:
                g.blue( "nA: Checking pattern '" + pattern)

            #if directives exist, parse them and set directive flags for later use
            # pylint: disable=anomalous-backslash-in-string
            directiveExists = re.search( " \[[V>X],?[V>X]?,?[V>X]?]$", pattern )
            if directiveExists:
                directives = directiveExists.group(0)
            else:
                directives = "[]"
            #What directives exist?
            useRegEx = re.search("X", directives) != None
            passEventInternal = re.search("V", directives) != None
            if not passEventExternal: #don't disable once enabled.
                passEventExternal = re.search(">", directives) != None
            #Remove the directives from the end of the pattern (if they exist)
            pattern = re.sub( " \[.*]$", "", pattern, 1)
            if messageLevel >= 4:
                g.blue( "nA:    Pattern='" + pattern + "' " + "(after directives removed)")

            #Keep copy of pattern without directives for message log
            patternOriginal = pattern

            #if pattern begins with "@files" and clicked node is an @file type
            #node then replace "@files" in pattern with clicked node's @file type
            patternBeginsWithAtFiles = re.search( "^@files ", pattern )
            clickedAtFileTypeNode = False #assume @file type node not clicked
            if patternBeginsWithAtFiles:
                #Check if first word in clicked header is in list of @file types
                firstWordInClickedHeader = hClicked.split()[0]
                if firstWordInClickedHeader in atFileTypes:
                    clickedAtFileTypeNode = True #Tell "write @file type nodes" code
                    #Replace "@files" in pattern with clicked node's @file type
                    pattern = re.sub( "^@files", firstWordInClickedHeader, pattern)
                    if messageLevel >= 4:
                        g.blue( "nA:    Pattern='" + pattern + "' " + "(after @files substitution)")

            #Check for pattern match to clicked node's header
            if useRegEx:
                match = re.search(pattern, hClicked)
            else:
                match = fnmatch.fnmatchcase(hClicked, pattern)
            if match:
                if messageLevel >= 1:
                    g.blue( "nA: Matched pattern '" + patternOriginal + "'")
                if messageLevel >= 4:
                    g.blue( "nA:    Directives: X=",useRegEx, "V=",passEventInternal,
                          ">=",passEventExternal,)
                #if @file type node, save node to disk (if configured)
                if clickedAtFileTypeNode:
                    if saveAtFile:
                        #Problem - No way found to just save clicked node, saving all
                        c.fileCommands.writeAtFileNodes()
                        c.requestRedrawFlag = True
                        c.redraw()
                        if messageLevel >= 3:
                            g.blue( "nA:    Saved '" + hClicked + "'")
                #Run the script
                applyNodeAction(pScript, pClicked, c)
                #Indicate that at least one pattern was matched
                foundPattern = True
                #Don't trigger more patterns unless enabled in patterns' headline
                if passEventInternal == False:
                    break
            else:
                if messageLevel >= 3:
                    g.blue("nA: Did not match '" + patternOriginal + "'")

        #Finished checking headline against patterns
        if not foundPattern:
            #no match to any pattern, always pass event to next plugin
            if messageLevel >= 1:
                g.blue("nA: No patterns matched to """ + hClicked + '"')
            return False #TL - Inform onIconDoubleClick that no action was taken
        elif passEventExternal == True:
            #last matched pattern has directive to pass event to next plugin
            if messageLevel >= 2:
                g.blue("nA: Event passed to next plugin")
            return False #TL - Inform onIconDoubleClick to pass double-click event
        else:
            #last matched pattern did not have directive to pass event to plugin
            if messageLevel >= 2:
                g.blue("nA: Event not passed to next plugin")
            return True #TL - Inform onIconDoubleClick to not pass double-click
    else:
        #nodeActions plugin enabled without a 'nodeActions' node
        if messageLevel >= 4:
            g.blue("nA: The ""nodeActions"" node does not exist")
        return False #TL - Inform onIconDoubleClick that no action was taken
Пример #53
0
    def loadOnePlugin (self,moduleOrFileName,tag='open0',verbose=False):

        trace = False and not g.unitTesting
        verbose = False or verbose
        
        if not g.app.enablePlugins:
            if trace: g.trace('plugins disabled')
            return None

        if moduleOrFileName.startswith('@'):
            if trace: g.trace('ignoring Leo directive')
            return None
                # Return None, not False, to keep pylint happy.
                # Allow Leo directives in @enabled-plugins nodes.

        moduleName = self.regularizeName(moduleOrFileName)

        if self.isLoaded(moduleName):
            module = self.loadedModules.get(moduleName)
            if trace and verbose:
                g.warning('loadOnePlugin: plugin',moduleName,'already loaded')
            return module

        assert g.app.loadDir

        moduleName = g.toUnicode(moduleName)

        # This import will typically result in calls to registerHandler.
        # if the plugin does _not_ use the init top-level function.
        self.loadingModuleNameStack.append(moduleName)

        try:
            toplevel = __import__(moduleName)
            # need to look up through sys.modules, __import__ returns toplevel package
            result = sys.modules[moduleName]

        except g.UiTypeException:
            if not g.unitTesting and not g.app.batchMode:
                g.es_print('Plugin %s does not support %s gui' % (
                    moduleName,g.app.gui.guiName()))
            result = None

        except ImportError:
            if trace or tag == 'open0': # Just give the warning once.
                g.error('error importing plugin:',moduleName)
                g.es_exception()
            result = None
        except SyntaxError:
            if trace or tag == 'open0': # Just give the warning once.
                g.error('syntax error importing plugin:',moduleName)
                # g.es_exception()
            result = None

        except Exception as e:
            g.error('exception importing plugin ' + moduleName)
            g.es_exception()
            result = None

        self.loadingModuleNameStack.pop()

        if result:
            self.signonModule = result # for self.plugin_signon.
            self.loadingModuleNameStack.append(moduleName)

            if tag == 'unit-test-load':
                pass # Keep the result, but do no more.
            elif hasattr(result,'init'):
                try:
                    # Indicate success only if init_result is True.
                    init_result = result.init()
                    if init_result not in (True,False):
                        g.error('Error: %s.init did not return a bool' % (moduleName))
                    if init_result:
                        self.loadedModules[moduleName] = result
                        self.loadedModulesFilesDict[moduleName] = g.app.config.enabledPluginsFileName
                    else:
                        if verbose and not g.app.initing:
                            g.error('loadOnePlugin: failed to load module',moduleName)
                        result = None
                except Exception:
                    g.error('exception loading plugin')
                    g.es_exception()
                    result = None
            else:
                # No top-level init function.
                # Guess that the module was loaded correctly,
                # but do *not* load the plugin if we are unit testing.

                if g.app.unitTesting:
                    result = None
                    self.loadedModules[moduleName] = None
                else:
                    g.trace('no init()',moduleName)
                    self.loadedModules[moduleName] = result
            self.loadingModuleNameStack.pop()

        if g.app.batchMode or g.app.inBridge: # or g.unitTesting
            pass
        elif result:
            if trace or verbose:
                g.blue('loadOnePlugin: loaded',moduleName)
        else:
            if trace or self.warn_on_failure or (verbose and not g.app.initing):
                if trace or tag == 'open0':
                    g.error('loadOnePlugin: can not load enabled plugin:',moduleName)

        return result