Example #1
0
    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()
Example #2
0
 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()
Example #3
0
def shellScriptInWindow(c,script):

    if sys.platform == 'darwin':
        #@+<< write script to temporary MacOS file >>
        #@+node:ekr.20040915105758.22: *3* << write script to temporary MacOS file >>
        handle, path = tempfile.mkstemp(text=True)
        directory = c.frame.openDirectory
        script = ("cd %s\n" % directory) + script + '\n' + ("rm -f %s\n" % path)
        os.write(handle, script)
        os.close(handle)
        os.chmod(path,0x700)
        #@-<< write script to temporary MacOS file >>
        os.system("open -a /Applications/Utilities/Terminal.app " + path)

    elif sys.platform == 'win32':
        g.error("shellScriptInWindow not ready for Windows")

    else:
        #@+<< write script to temporary Unix file >>
        #@+node:ekr.20040915105758.25: *3* << write script to temporary Unix file >>
        handle, path = tempfile.mkstemp(text=True)
        directory = c.frame.openDirectory
        script = ("cd %s\n" % directory) + script + '\n' + ("rm -f %s\n" % path)
        os.write(handle, script)
        os.close(handle)
        os.chmod(path,0x700)
        #@-<< write script to temporary Unix file >>
        os.system("xterm -e sh  " + path)
Example #4
0
 def error(self, s, silent=False):
     x = self
     if not silent:
         g.error(s)
     # For unit testing.
     x.last_error = s
     x.errors += 1
Example #5
0
        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
Example #6
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)
Example #7
0
 def reportChangedClone(self, child_v, b, h, gnx):
     trace = (False or g.app.debug) and not g.unitTesting
     c = self.c
     fileName = c.cacheListFileName
     old, new = child_v.b, b
     same = (
         old == new or
         new.endswith('\n') and old == new[: -1] or
         old.endswith('\n') and new == old[: -1])
     # if trace and not same:
     if trace and (not same or h == 'writeException'):
         g.trace('same %s old %s new %s %s %s' % (
             same, len(old), len(new), h, fileName))
     # This would make it impossible to clear nodes!
     # if not new: return same
     if same: return
     c.nodeConflictList.append(g.bunch(
         tag='(cached)',
         fileName=fileName,
         gnx=gnx,
         b_old=child_v.b,
         h_old=child_v.h,
         b_new=b,
         h_new=h,
     ))
     # Always issue the warning.
     g.error("cached read node changed:", child_v.h)
     child_v.h, child_v.b = h, b
     child_v.setDirty()
     c.changed = True # Tell getLeoFile to propegate dirty nodes.
Example #8
0
 def open_dict(self, fn, language):
     '''Open or create the dict with the given fn.'''
     trace = False and not g.unitTesting
     if not fn or not language:
         return
     d = g.app.spellDict
     if d:
         self.d = d
         if trace: g.trace('already open', self.c.fileName(), fn)
         return
     if not g.os_path_exists(fn):
         # Fix bug 1175013: leo/plugins/spellpyx.txt is both source controlled and customized.
         self.create(fn)
     if g.os_path_exists(fn):
         # Merge the local and global dictionaries.
         try:
             self.clean_dict(fn)
             self.d = enchant.DictWithPWL(language, fn)
             if trace: g.trace('open', g.shortFileName(self.c.fileName()), fn)
         except Exception:
             g.es_exception()
             g.error('not a valid dictionary file', fn)
             self.d = enchant.Dict(language)
     else:
         # A fallback.  Unlikely to happen.
         self.d = enchant.Dict(language)
     # Use only a single copy of the dict.
     g.app.spellDict = self.d
Example #9
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()
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)
Example #11
0
 def scan(self, s, parent):
     '''Create an outline from a MindMap (.csv) file.'''
     # pylint: disable=no-member
     # pylint confuses this module with the stdlib json module
     c = self.c
     self.gnx_dict = {}
     try:
         d = json.loads(s)
         for d2 in d.get('nodes', []):
             gnx = d2.get('gnx')
             self.gnx_dict[gnx] = d2
         top_d = d.get('top')
         if top_d:
             # Don't set parent.h or parent.gnx or parent.v.u.
             parent.b = top_d.get('b') or ''
             self.create_nodes(parent, top_d)
             c.redraw()
         return bool(top_d)
     except Exception:
         # Fix #1098
         try:
             obj = json.loads(s)
         except Exception:
             g.error('Bad .json file: %s' % parent.h)
             g.es_exception()
             obj = s
         parent.b = g.objToString(obj)
         c.redraw()
         return True
 def create_temp_file(self, c, ext, p):
     '''
     Create the temp file used by open-with if necessary.
     Add the corresponding ExternalFile instance to self.files
     '''
     trace = False and not g.unitTesting
     if trace: g.trace(len(p.b), p.h)
     path = self.temp_file_path(c, p, ext)
     exists = g.os_path_exists(path)
     if trace:
         kind = 'recreating:' if exists else 'creating: '
         g.trace(kind, path)
     # Compute encoding and s.
     d2 = c.scanAllDirectives(p)
     encoding = d2.get('encoding', None)
     if encoding is None:
         encoding = c.config.default_derived_file_encoding
     s = g.toEncodedString(p.b, encoding, reportErrors=True)
     # Write the file *only* if it doesn't exist.
     # No need to read the file: recomputing s above suffices.
     if not exists:
         try:
             f = open(path, 'wb')
             f.write(s)
             f.flush()
             f.close()
         except IOError:
             g.error('exception creating temp file: %s' % path)
             g.es_exception()
             return None
     # Add or update the external file entry.
     time = self.get_mtime(path)
     self.files = [z for z in self.files if z.path != path]
     self.files.append(ExternalFile(c, ext, p, path, time))
     return path
Example #13
0
 def compute_temp_file_path(self, c, p, ext):
     '''Return the path to the temp file for p and ext.'''
     if c.config.getBool('open-with-clean-filenames'):
         path = self.clean_file_name(c, ext, p)
     else:
         path = self.legacy_file_name(c, ext, p)
     if not path:
         g.error('c.temp_file_path failed')
     return path
Example #14
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")
Example #15
0
    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()
Example #16
0
 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
Example #17
0
def OnQuit(tag,keywords=None):

    global RunNode,RunList

    if RunList:
        RunList = None
        g.disableIdleTimeHook()
        if RunNode:
            CloseProcess()
        g.error("@run: forced quit!")
Example #18
0
    def loadLinksInt(self):
        """load links after file opened or reload on request from UI"""

        c = self.c  # checked in loadLinks()

        self.initIvars()  # clears self.vnode

        idsSeen = set()  # just the vnodes with link info.

        # make map from linked node's ids to their vnodes
        for p in c.all_positions():
            v = p.v
            self.vnode[v.gnx] = v
            if v.u and '_bklnk' in v.u:
                idsSeen.add(v.gnx)

        for vnode in idsSeen:  # just the vnodes with link info.
            if 'links' not in self.vnode[vnode].u['_bklnk']:
                g.trace(self.vnode[vnode].u)
                # graphcanvas.py will only init x and y keys
                self.vnode[vnode].u['_bklnk']['links'] = []
            links = self.vnode[vnode].u['_bklnk']['links']
            newlinks = []  # start with empty list and include only good links
            for link in links:

                if link[1] not in self.vnode:
                    # other end if missing
                    lt = ('to', 'from')
                    if link[0] == 'S':
                        lt = ('from', 'to')
                    # use g.es rather than showMessage here
                    g.error('backlink: link %s %s %s ??? lost' % (
                        lt[0], self.vnode[vnode].h, lt[1]))
                    continue

                # check other end has link
                other = self.vnode[link[1]]
                if '_bklnk' not in other.u or 'links' not in other.u['_bklnk']:
                    self.initBacklink(other)
                if not [
                    i for i in other.u['_bklnk']['links']
                        if i[1] == vnode
                ]:
                    # we are not in the other's list
                    direc = {'U':'U', 'S':'D', 'D':'S'}[link[0]]
                    other.u['_bklnk']['links'].append((direc, vnode))

                newlinks.append((link[0], link[1]))

            self.vnode[vnode].u['_bklnk']['links'] = newlinks

        self.showMessage('Link info. loaded on %d nodes' % len(idsSeen))
Example #19
0
    def createIconButton (self,text,command,statusLine,bg=None,kind=None):

        '''Create an icon button.  All icon buttons get created using this utility.

        - Creates the actual button and its balloon.
        - Adds the button to buttonsDict.
        - Registers command with the shortcut.
        - Creates x amd delete-x-button commands, where x is the cleaned button name.
        - Binds a right-click in the button to a callback that deletes the button.'''

        c = self.c ; k = c.k
        # Create the button and add it to the buttons dict.
        commandName = self.cleanButtonText(text)
        # Truncate only the text of the button, not the command name.
        truncatedText = self.truncateButtonText(commandName)
        if not truncatedText.strip():
            g.error('%s ignored: no cleaned text' % (text.strip() or ''))
            return None
        # Command may be None.
        b = self.iconBar.add(text=truncatedText,command=command,kind=kind)
        if not b:
            return None
        if bg:
            if not bg.startswith('#'):
                d = leoColor.leo_color_database
                bg2 = d.get(bg.lower())
                if not bg2:
                    print('bad color? %s' % bg)
                bg = bg2
            if bg:
                try:
                    b.button.setStyleSheet("QPushButton{background-color: %s}" % (bg))
                except Exception:
                    # g.es_exception()
                    pass # Might not be a valid color.
        self.buttonsDict[b] = truncatedText
        if statusLine:
            self.createBalloon(b,statusLine)
        # Register the command name if it exists.
        if command:
            self.registerTwoCommands(text,func=command,
                pane='button',tag='icon button')
        # Define the callback used to delete the button.
        def deleteButtonCallback(event=None,self=self,b=b):
            self.deleteButton(b, event=event)
        # Register the delete-x-button command.
        deleteCommandName= 'delete-%s-button' % commandName
        k.registerCommand(deleteCommandName,shortcut=None,
            func=deleteButtonCallback,pane='button',verbose=False)
            # Reporting this command is way too annoying.
        return b
Example #20
0
    def createIconButton(self, args, text, command, statusLine, bg=None, kind=None):
        '''
        Create one icon button.
        This method creates all scripting icon buttons.

        - Creates the actual button and its balloon.
        - Adds the button to buttonsDict.
        - Registers command with the shortcut.
        - Creates x amd delete-x-button commands, where x is the cleaned button name.
        - Binds a right-click in the button to a callback that deletes the button.
        '''
        c = self.c
        # Create the button and add it to the buttons dict.
        commandName = self.cleanButtonText(text)
        # Truncate only the text of the button, not the command name.
        truncatedText = self.truncateButtonText(commandName)
        if not truncatedText.strip():
            g.error('%s ignored: no cleaned text' % (text.strip() or ''))
            return None
        # Command may be None.
        b = self.iconBar.add(text=truncatedText, command=command, kind=kind)
        if not b:
            return None
        self.setButtonColor(b, bg)
        self.buttonsDict[b] = truncatedText
        if statusLine:
            self.createBalloon(b, statusLine)
        if command:
            self.registerAllCommands(
                args=args,
                func=command,
                h=text,
                pane='button',
                source_c=c,
                tag='icon button')

        def deleteButtonCallback(event=None, self=self, b=b):
            self.deleteButton(b, event=event)
        # Register the delete-x-button command.

        deleteCommandName = 'delete-%s-button' % commandName
        c.k.registerCommand(
            # allowBinding=True,
            commandName=deleteCommandName,
            func=deleteButtonCallback,
            pane='button',
            shortcut=None,
        )
            # Reporting this command is way too annoying.
        return b
Example #21
0
 def get_script_node_info(self, s, delim2):
     '''Return the gnx and headline of a #@+node.'''
     i = s.find(':', 0)
     j = s.find(':', i + 1)
     if i == -1 or j == -1:
         g.error("bad @+node sentinel", s)
         return None, None
     else:
         gnx = s[i + 1: j]
         h = s[j + 1:]
         h = self.remove_level_stars(h).strip()
         if delim2:
             h = h.rstrip(delim2)
         return gnx, h
Example #22
0
 def create(self, fn):
     '''Create the given file with empty contents.'''
     theDir = g.os_path_dirname(fn)
     g.makeAllNonExistentDirectories(theDir, c=self.c, force=True, verbose=True)
         # Make the directories as needed.
     try:
         f = open(fn, mode='wb')
         f.close()
         g.note('created: %s' % (fn))
     except IOError:
         g.error('can not create: %s' % (fn))
     except Exception:
         g.error('unexpected error creating: %s' % (fn))
         g.es_exception()
Example #23
0
    def createOpenWithMenuFromTable(self, table):
        '''
        Table is a list of dictionaries, created from @openwith settings nodes.

        This menu code uses these keys:

            'name':     menu label.
            'shortcut': optional menu shortcut.

        efc.open_temp_file uses these keys:

            'args':     the command-line arguments to be used to open the file.
            'ext':      the file extension.
            'kind':     the method used to open the file, such as subprocess.Popen.
        '''
        # trace = False and not g.unitTesting
        k = self.c.k
        if not table: return
        g.app.openWithTable = table # Override any previous table.
        # Delete the previous entry.
        parent = self.getMenu("File")
        # if trace: g.trace('parent',parent)
        if not parent:
            if not g.app.batchMode:
                g.error('', 'createOpenWithMenuFromTable:', 'no File menu')
            return
        label = self.getRealMenuName("Open &With...")
        amp_index = label.find("&")
        label = label.replace("&", "")
        try:
            index = parent.index(label)
            parent.delete(index)
        except Exception:
            try:
                index = parent.index("Open With...")
                parent.delete(index)
            except Exception:
                g.trace('unexpected exception')
                g.es_exception()
                return
        # Create the Open With menu.
        openWithMenu = self.createOpenWithMenu(parent, label, index, amp_index)
        if not openWithMenu:
            g.trace('openWithMenu returns None')
            return
        self.setMenu("Open With...", openWithMenu)
        # Create the menu items in of the Open With menu.
        self.createOpenWithMenuItemsFromTable(openWithMenu, table)
        for d in table:
            k.bindOpenWith(d)
Example #24
0
def createFile(c, parent, d):
    """Ask if we should create a new file"""
    directory = os.path.dirname(d)
    if not os.path.isdir(directory):
        g.error("Create parent directories first")
        return False

    d = os.path.basename(d)
    atType = c.config.getString("active_path_attype") or "auto"
    ok = g.app.gui.runAskYesNoDialog(c, "Create / load file?", "Create file @" + atType + " " + d + "?")
    if ok == "no":
        return False
    c.setHeadString(parent, "@" + atType + " " + d)
    c.bodyWantsFocus()
    return True
Example #25
0
 def pickle(self, p):
     '''Pickle val and return the hexlified result.'''
     try:
         ua = p.v.u
         s = pickle.dumps(ua, protocol=1)
         s2 = binascii.hexlify(s)
         s3 = g.ue(s2, 'utf-8')
         return s3
     except pickle.PicklingError:
         g.warning("ignoring non-pickleable value", ua, "in", p.h)
         return ''
     except Exception:
         g.error("pd.pickle: unexpected exception in", p.h)
         g.es_exception()
         return ''
Example #26
0
def createFile(c,parent,d):
    """Ask if we should create a new file"""
    directory = os.path.dirname(d)
    if not os.path.isdir(directory):
        g.error('Create parent directories first')
        return False

    d = os.path.basename(d)
    atType = c.config.getString('active_path_attype') or 'auto'
    ok = g.app.gui.runAskYesNoDialog(c, 'Create / load file?',
        'Create file @'+atType+' '+d+'?')
    if ok == 'no':
        return False
    c.setHeadString(parent, '@'+atType+' '+d)
    c.bodyWantsFocus()
    return True
Example #27
0
    def create_temp_file(self, c, d, p):
        '''
        Create the temp file used by open-with if necessary.
        Add the corresponding ExternalFile instance to self.files
        
        d is a dictionary created from an @openwith settings node.

        'args':     the command-line arguments to be used to open the file.
        'ext':      the file extension.
        'kind':     the method used to open the file, such as subprocess.Popen.
        'name':     menu label (used only by the menu code).
        'shortcut': menu shortcut (used only by the menu code).
        '''
        trace = False and not g.unitTesting
        assert isinstance(d, dict), d
        ext = d.get('ext')
        path = self.temp_file_path(c, p, ext)
        exists = g.os_path_exists(path)
        if trace:
            kind = 'recreating:' if exists else 'creating: '
            g.trace(kind, path)
        # Compute encoding and s.
        d2 = c.scanAllDirectives(p)
        encoding = d2.get('encoding', None)
        if encoding is None:
            encoding = c.config.default_derived_file_encoding
        s = g.toEncodedString(p.b, encoding, reportErrors=True)
        # Write the file *only* if it doesn't exist.
        # No need to read the file: recomputing s above suffices.
        if not exists:
            try:
                f = open(path, 'wb')
                f.write(s)
                f.flush()
                f.close()
            except IOError:
                g.error('exception creating temp file: %s' % path)
                g.es_exception()
                return None
        # Add or update the external file entry.
        time = self.get_mtime(path)
        self.files = [z for z in self.files if z.path != path]
        self.files.append(ExternalFile(c, ext, p, path, time))
        return path
Example #28
0
 def pickle (self,p):
     '''Pickle val and return the hexlified result.'''
     trace = False and g.unitTesting
     try:
         ua = p.v.u
         s = pickle.dumps(ua,protocol=1)
         s2 = binascii.hexlify(s)
         s3 = g.ue(s2,'utf-8')
         if trace: g.trace('\n',
             type(ua),ua,'\n',type(s),repr(s),'\n',
             type(s2),s2,'\n',type(s3),s3)
         return s3
     except pickle.PicklingError:
         g.warning("ignoring non-pickleable value",ua,"in",p.h)
         return ''
     except Exception:
         g.error("pd.pickle: unexpected exception in",p.h)
         g.es_exception()
         return ''
Example #29
0
 def pickle(self, p):
     '''Pickle val and return the hexlified result.'''
     trace = False and g.unitTesting
     try:
         ua = p.v.u
         s = pickle.dumps(ua, protocol=1)
         s2 = binascii.hexlify(s)
         s3 = g.ue(s2, 'utf-8')
         if trace:
             g.trace('\n', type(ua), ua, '\n', type(s), repr(s), '\n',
                     type(s2), s2, '\n', type(s3), s3)
         return s3
     except pickle.PicklingError:
         g.warning("ignoring non-pickleable value", ua, "in", p.h)
         return ''
     except Exception:
         g.error("pd.pickle: unexpected exception in", p.h)
         g.es_exception()
         return ''
Example #30
0
    def write(self, name, data, basedir=None, path=None):
        """Write a single file.

        The `name` can be a file name or a ralative path which will be
        added to basedir and path to create a full path for the file to be
        written.

        If basedir is None self.basedir will be used and if path is none
        self.path will be used.

        """

        if basedir is None:
            basedir = self.basedir

        if path is None:
            path = self.path

        filepath = abspath(basedir,path,name)

        # g.trace('basedir',basedir,'path',path,'name',name)

        try:
            f = open(filepath, 'wb')
        except Exception:
            g.error('can not open: %s' % (filepath))
            g.es_exception(full=False,c=self.c)
            return False

        try:
            try:
                f.write(data.encode('utf-8'))
                self.announce('output file: %s' % (filepath),
                    color=self.fileColor)
                ok = True
            except Exception:
                g.error('write failed: %s' % (filepath))
                g.es_exception(full=False,c=self.c)
                ok = False
        finally:
            f.close()
            
        return ok
Example #31
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()
Example #32
0
    def write(self, name, data, basedir=None, path=None):
        """Write a single file.

        The `name` can be a file name or a ralative path which will be
        added to basedir and path to create a full path for the file to be
        written.

        If basedir is None self.basedir will be used and if path is none
        self.path will be used.

        """

        if basedir is None:
            basedir = self.basedir

        if path is None:
            path = self.path

        filepath = abspath(basedir, path, name)

        # g.trace('basedir',basedir,'path',path,'name',name)

        try:
            f = open(filepath, 'wb')
        except Exception:
            g.error('can not open: %s' % (filepath))
            g.es_exception(full=False, c=self.c)
            return False

        try:
            try:
                f.write(data.encode('utf-8'))
                self.announce('output file: %s' % (filepath),
                              color=self.fileColor)
                ok = True
            except Exception:
                g.error('write failed: %s' % (filepath))
                g.es_exception(full=False, c=self.c)
                ok = False
        finally:
            f.close()

        return ok
Example #33
0
    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)

        try:
            if g.isPython3:
                theFile = BytesIO(s)
            else:
                theFile = cStringIO.StringIO(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
Example #34
0
    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)

        try:
            if g.isPython3:
                theFile = BytesIO(s)
            else:
                theFile = cStringIO.StringIO(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
Example #35
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()
Example #36
0
    def createDirectoryForFile(self, fn):
        """
        Create the directory for fn if
        a) it doesn't exist and
        b) the user options allow it.

        Return True if the directory existed or was made.
        """
        c, ok = self.c, False  # 1815.
        # Create the directory if it doesn't exist.
        theDir, junk = g.os_path_split(fn)
        theDir = g.os_path_finalize(theDir)  # 1341
        if g.os_path_exists(theDir):
            return True
        if c and c.config and c.config.create_nonexistent_directories:
            theDir = c.expand_path_expression(theDir)
            ok = g.makeAllNonExistentDirectories(theDir)
            if not ok:
                g.error('did not create:', theDir)
        return ok
Example #37
0
def OnBodyKey(tag,keywords):

    global RunNode,In

    c=keywords.get('c')
    if not c or not c.exists: return
    p=c.p
    h=p.h
    ch=keywords.get("ch")

    # handle the @run "\r" body key
    if ch == "\r" and g.match_word(h,0,"@run") and RunNode and RunNode==p:
        try:
            In.write(p.b.encode(Encoding))
            In.flush()
            g.es(p.b)
        except IOError as ioerr:
            g.error("[@run] IOError: "+str(ioerr))
            return
        c.setBodyText(p,"")
Example #38
0
def OnIconDoubleClick(tag, keywords):

    global RunNode, RunList, OwnIdleHook, ExitCode

    c = keywords.get('c')
    if not c or not c.exists: return
    p = c.p

    # g.trace(c.shortFileName())

    h = p.h
    if g.match_word(h, 0, "@run"):
        if RunNode or RunList:
            g.error("@run already running!")
        else:
            #@+<< handle double click in @run icon >>
            #@+node:ekr.20040910102554: *4* << handle double click in @run icon >>
            RunList = []

            for p2 in p.self_and_subtree():
                if g.match_word(p2.h, 0, "@run"):
                    # g.trace(p2.h)
                    # 2009/10/30: don't use iter copy arg.
                    RunList.append(p2.copy())

            ExitCode = None
            OwnIdleHook = True
            ### g.enableIdleTimeHook()
            #@-<< handle double click in @run icon >>
    elif g.match_word(h, 0, "@in"):
        if RunNode:
            #@+<< handle double click in @in icon >>
            #@+node:ekr.20040910102554.1: *4* << handle double click in @in icon >>
            b = p.b

            try:
                In.write(b.encode(Encoding) + "\n")
                In.flush()
                g.es(b)
            except IOError as ioerr:
                g.error("@run IOError: " + str(ioerr))
Example #39
0
    def createAttrib(self, event=None, readonly=False):

        ans = []

        for getter, isOn in self.getsetters:
            if not isOn:
                continue

            if getter.helpCreate() is True:
                ans.append(getter)
            else:
                g.es("For '%s' attributes:\n  %s" % (getter.name(), getter.helpCreate()))

        if len(ans) > 1:
            g.error('Eror: more than one attribute type (%s) active' %
            ', '.join([i.name() for i in ans]))
        elif ans:
            ans[0].createAttrib(self.c.currentPosition().v, gui_parent=self.parent)
            self.updateEditorInt()
            self.c.currentPosition().v.setDirty()
            self.c.redraw()
Example #40
0
    def reportChangedClone (self,child_v,b,h,gnx):

        trace = False and not g.unitTesting
        c = self.c
        fileName=c.cacheListFileName
        old,new = child_v.b,b

        same = (
            old == new or
            new.endswith('\n') and old == new[:-1] or
            old.endswith('\n') and new == old[:-1])

        # if trace and not same:
        if trace and (not same or h == 'writeException'):
            g.trace('same %s old %s new %s %s %s' % (
                same,len(old),len(new),h,fileName))

        # This would make it impossible to clear nodes!
        # if not new: return same

        if same: return

        c.nodeConflictList.append(g.bunch(
            tag='(cached)',
            fileName=fileName,
            gnx=gnx,
            b_old=child_v.b,
            h_old=child_v.h,
            b_new=b,
            h_new=h,
        ))

        # Always issue the warning.
        g.error("cached read node changed:",child_v.h)

        child_v.h,child_v.b = h,b
        child_v.setDirty()
        c.changed = True # Tell getLeoFile to propegate dirty nodes.
Example #41
0
        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:
                # pylint:disable=catching-non-exception
                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()
                    node = None
                except Exception:
                    g.error('Unexpected exception parsing %s' %
                            (inputFileName))
                    g.es_exception()
                    node = None
            finally:
                f.close()
            return node
Example #42
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)
 def open_with_helper(self, c, ext, p):
     '''
     Reopen a temp file for p if it exists in self.files.
     Otherwise, open a new temp file.
     '''
     path = self.temp_file_path(c, p, ext)
     if not path:
         return g.error('c.temp_file_path failed')
     #
     # Return a path if a temp file already refers to p.v
     for ef in self.files:
         if path and path == ef.path and p.v == ef.p.v:
             return ef.path
     #
     # Not found: create the temp file.
     return self.create_temp_file(c, ext, p)
Example #44
0
 def open_with_helper(self, c, ext, p):
     '''
     Reopen a temp file for p if it exists in self.files.
     Otherwise, open a new temp file.
     '''
     trace = False and not g.unitTesting
     path = self.temp_file_path(c, p, ext)
     if not path:
         return g.error('c.temp_file_path failed')
     # Return a path if a temp file already refers to p.v
     for ef in self.files:
         if path and path == ef.path and p.v == ef.p.v:
             if trace: g.trace('found!', path)
             return ef.path
     # Not found: create the temp file.
     if trace: g.trace('not found', path)
     return self.create_temp_file(c, ext, p)
Example #45
0
 def open_with_helper(self, c, d, p):
     '''
     Reopen a temp file for p if it exists in self.files.
     Otherwise, open a new temp file.
     '''
     trace = False and not g.unitTesting
     assert isinstance(d, dict), d
     # May be over-ridden by mod_tempfname plugin.
     path = self.temp_file_path(c, p, d.get('ext'))
     if not path:
         # Check the mod_tempfname plugin.
         return g.error('c.temp_file_path failed')
     # Return a path if a temp file already refers to p.v
     for ef in self.files:
         if path and path == ef.path and p.v == ef.p.v:
             if trace: g.trace('found!', path)
             return ef.path
     # Not found: create the temp file.
     if trace: g.trace('not found', path)
     return self.create_temp_file(c, d, p)
Example #46
0
 def create(self, fn):
     """Create the given file with empty contents."""
     # Make the directories as needed.
     theDir = g.os_path_dirname(fn)
     if theDir:
         ok = g.makeAllNonExistentDirectories(theDir)
         # #1453: Don't assume the directory exists.
         if not ok:
             g.error(f"did not create directory: {theDir}")
             return
     # Create the file.
     try:
         f = open(fn, mode='wb')
         f.close()
         g.note(f"created: {fn}")
     except IOError:
         g.error(f"can not create: {fn}")
     except Exception:
         g.error(f"unexpected error creating: {fn}")
         g.es_exception()
Example #47
0
 def run_sphinx(self, i_path, o_path):
     """Process i_path and o_path with sphinx."""
     trace = True
     # cd to the command directory, or i_path's directory.
     command_dir = g.os_path_finalize(self.sphinx_command_dir
                                      or os.path.dirname(i_path))
     if os.path.exists(command_dir):
         if trace:
             g.trace(f"\nos.chdir: {command_dir!r}")
         os.chdir(command_dir)
     else:
         g.error(f"command directory not found: {command_dir!r}")
         return
     #
     # If a default command exists, just call it.
     # The user is responsible for making everything work.
     if self.sphinx_default_command:
         if trace:
             g.trace(f"\ncommand: {self.sphinx_default_command!r}\n")
         g.execute_shell_commands(self.sphinx_default_command)
         return
     # Compute the input directory.
     input_dir = g.os_path_finalize(self.sphinx_input_dir
                                    or os.path.dirname(i_path))
     if not os.path.exists(input_dir):
         g.error(f"input directory not found: {input_dir!r}")
         return
     # Compute the output directory.
     output_dir = g.os_path_finalize(self.sphinx_output_dir
                                     or os.path.dirname(o_path))
     if not os.path.exists(output_dir):
         g.error(f"output directory not found: {output_dir!r}")
         return
     #
     # Call sphinx-build to write the output file.
     # sphinx-build [OPTIONS] SOURCEDIR OUTPUTDIR [FILENAMES...]
     command = f"sphinx-build {input_dir} {output_dir} {i_path}"
     if trace:
         g.trace(f"\ncommand: {command!r}\n")
     g.execute_shell_commands(command)
Example #48
0
    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.frame.bodyWantsFocus()
Example #49
0
    def error(self, s):

        g.error('Error: %s' % (s))
Example #50
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()
Example #51
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)
Example #52
0
    def moveCurrentNodeToTarget(self, checked=False):
        '''Move the current position to the last child of self.target.'''

        c = self.c
        p = c.p

        vnodes = [i.v for i in c.getSelectedPositions()]

        needs_undo = self.type_ != "jump"

        if needs_undo:
            bunch = c.undoer.beforeMoveNode(p)

        for v in vnodes:

            p2 = c.vnode2position(self.target)
            p = c.vnode2position(v)

            if not c.positionExists(p2):
                g.error('Target no longer exists: %s' % self.targetHeadString)
                return

            if self.type_ in ('clone', 'move'):  # all others are always valid?
                if p.v == p2.v or not self.checkMove(p, p2):
                    g.error('Invalid move: %s' % (self.targetHeadString))
                    return
            if p2.isAncestorOf(p):  # not for sibling moves
                p2.expand()
            nxt = p.visNext(c) or p.visBack(c)
            nxt = nxt.v
            # store a VNode instead of position as positions are too easily lost

            if self.type_ != 'jump':
                p.setDirty()  # before move to dirty current parent
                p2.setDirty()
                c.setChanged()

            if self.type_ == 'clone':
                p = p.clone()

            if self.type_ in ('move', 'clone'):
                if self.which == 'first child':
                    p.moveToFirstChildOf(p2)
                elif self.which == 'last child':
                    p.moveToLastChildOf(p2)
                elif self.which in ('next sibling', 'prev sibling'):
                    if not p2.parent():
                        raise Exception(
                            "Not implemented for top-level nodes")  #FIXME
                    if self.which == 'next sibling':
                        p.moveToNthChildOf(p2.parent(), p2._childIndex)
                    elif self.which == 'prev sibling':
                        p.moveToNthChildOf(p2.parent(), p2._childIndex - 1)
                else:
                    raise Exception("Unknown move type " + self.which)

            elif self.type_ == 'bkmk':
                unl = self.computeUNL(p)  # before tree changes
                if self.which == 'first child':
                    nd = p2.insertAsNthChild(0)
                elif self.which == 'last child':
                    nd = p2.insertAsLastChild()
                elif self.which == 'next sibling':
                    nd = p2.insertAfter()
                elif self.which == 'prev sibling':
                    nd = p2.insertBefore()
                else:
                    raise Exception("Unknown move type " + self.which)
                h = p.anyAtFileNodeName() or p.h
                while h and h[0] == '@':
                    h = h[1:]
                nd.h = h
                nd.b = unl

            elif self.type_ == 'copy':

                if self.which == 'first child':
                    nd = p2.insertAsNthChild(0)
                    quickMove.copy_recursively(p, nd)
                    # unlike p.copyTreeFromSelfTo, deepcopys p.v.u
                elif self.which == 'last child':
                    nd = p2.insertAsLastChild()
                    quickMove.copy_recursively(p, nd)
                elif self.which == 'next sibling':
                    nd = p2.insertAfter()
                    quickMove.copy_recursively(p, nd)
                elif self.which == 'prev sibling':
                    nd = p2.insertBefore()
                    quickMove.copy_recursively(p, nd)
                else:
                    raise Exception("Unknown move type " + self.which)

            elif self.type_ in ('linkTo', 'linkFrom'):
                blc = getattr(c, 'backlinkController', None)
                if blc is None:
                    g.es("Linking requires backlink.py plugin")
                    return
                if self.type_ == 'linkTo':
                    blc.vlink(p.v, p2.v)
                else:
                    blc.vlink(p2.v, p.v)

            if self.type_ in ('bkmk', 'clone', 'copy', 'move'):
                nxt = c.vnode2position(nxt)
            elif self.type_ == 'jump':
                nxt = c.vnode2position(self.target)
            else:
                nxt = None  # linkTo / linkFrom don't move

            if nxt is not None and c.positionExists(nxt):
                c.selectPosition(nxt)

        if needs_undo:
            c.undoer.afterMoveNode(p, 'Quick Move', bunch)
            c.setChanged()

        c.redraw()
Example #53
0
 def error(self, s):
     g.error(f"Error: {s}")
Example #54
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
Example #55
0
def open_mimetype(tag, keywords, val=None):
    """Simulate double-clicking on the filename in a file manager.  Order of
    preference is:

        1) @string mime_open_cmd setting
        2) _mime_open_cmd, defined per sys.platform detection
        3) open_func(fpath), defined per sys.platform detection
        4) mailcap file for mimetype handling
    """

    global open_func

    c = keywords.get('c')
    p = keywords.get('p')
    if not c or not p:
        return None

    if p.h.startswith('@mime'):
        fname = p.h[6:]

        # honor @path
        d = c.scanAllDirectives(p)
        path = d.get('path')
        fpath = g.os_path_finalize_join(path, fname)

        # stop here if the file doesn't exist
        if not g.os_path_exists(fpath):
            g.error('@mime: file does not exist, %s' % fpath)
            return True

        # user-specified command string, or sys.platform-determined string
        mime_cmd = c.config.getString('mime-open-cmd') or _mime_open_cmd
        if mime_cmd:
            if '%s' not in mime_cmd:
                mime_cmd += ' %s'
            open_func = exec_string_cmd(mime_cmd)

        #no special handler function specified (unknown platform),
        #try mailcap/mimetype entries explicitly
        if open_func is None:
            (ftype, encoding) = mimetypes.guess_type(fname)
            if ftype:
                caps = mailcap.getcaps()
                (fullcmd, entry) = mailcap.findmatch(caps,
                                                     ftype,
                                                     filename=fpath,
                                                     key='view')
                if fullcmd:
                    # create a function which merely executes the fullcmd in
                    # a shell for e.g. PATH access
                    open_func = exec_full_cmd(fullcmd)
                else:
                    g.error('@mime: no mailcap entry for %s: %s' %
                            (ftype, fname))
                g.trace('mailcap command:', fullcmd)
            else:
                g.error('@mime: unknown file type: %s' % fname)

        # use the custom open_func to open external file viewer
        if open_func:
            open_func(fpath)
        else:
            g.error('@mime: no known way to open %s' % fname)

        # block execution of e.g. vim plugin
        return True

    # not an @mime node
    return val
Example #56
0
 def oops(message, i, j):
     # This can be called from c-to-python, in which case warnings should be suppressed.
     if giveWarnings:
         g.error('** changed ', p.h)
         g.es_print('%s after\n%s' % (message, repr(''.join(s[i:j]))))
Example #57
0
 def error(self, s):
     g.error('', s)
Example #58
0
    def moveCurrentNodeToTarget(self):
        '''Move the current position to the last child of self.target.'''

        c = self.c
        p = c.p
        p2 = c.vnode2position(self.target)

        needs_undo = self.type_ != "jump"

        if not c.positionExists(p2):
            g.error('Target no longer exists: %s' % self.targetHeadString)
            return

        if self.type_ in ('clone', 'move'):  # all others are always valid?
            if p.v == p2.v or not self.checkMove(p, p2):
                g.error('Invalid move: %s' % (self.targetHeadString))
                return

        if needs_undo:
            bunch = c.undoer.beforeMoveNode(p)

        p2.expand()
        nxt = p.visNext(c) or p.visBack(c)
        nxt = nxt.v
        # store a vnode instead of position as positions are too easily lost

        if self.type_ == 'clone':
            p = p.clone()

        if self.type_ in ('move', 'clone'):
            if self.first:
                p.moveToFirstChildOf(p2)
            else:
                p.moveToLastChildOf(p2)

        elif self.type_ == 'bkmk':
            unl = self.computeUNL(p)  # before tree changes
            if self.first:
                nd = p2.insertAsNthChild(0)
            else:
                nd = p2.insertAsLastChild()
            h = p.anyAtFileNodeName() or p.h
            while h and h[0] == '@':
                h = h[1:]
            nd.h = h
            nd.b = unl

        elif self.type_ == 'copy':
            if self.first:
                nd = p2.insertAsNthChild(0)
                quickMove.copy_recursively(p, nd)
                # unlike p.copyTreeFromSelfTo, deepcopys p.v.u
            else:
                nd = p2.insertAsLastChild()
                quickMove.copy_recursively(p, nd)

        elif self.type_ in ('linkTo', 'linkFrom'):
            blc = getattr(c, 'backlinkController', None)
            if blc is None:
                g.es("Linking requires backlink.py plugin")
                return
            if self.type_ == 'linkTo':
                blc.vlink(p.v, p2.v)
            else:
                blc.vlink(p2.v, p.v)

        if self.type_ in ('bkmk', 'clone', 'copy', 'move'):
            nxt = c.vnode2position(nxt)
        elif self.type_ == 'jump':
            nxt = c.vnode2position(self.target)
        else:
            nxt = None  # linkTo / linkFrom don't move

        if nxt is not None and c.positionExists(nxt):
            c.selectPosition(nxt)

        if needs_undo:
            c.undoer.afterMoveNode(p, 'Quick Move', bunch)
            c.setChanged(True)

        c.redraw()
Example #59
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
Example #60
0
#     outside the event loop.  It might be possible to do this in
#     an idle-time handler.
#
#     If it is possible several more settings would be possible.
#@-<< to do >>
#@+<< imports >>
#@+node:ekr.20080201143145.3: ** << imports >>
import leo.core.leoGlobals as g

import sys

try:
    import IPython.ipapi
    import_ok = True
except ImportError:
    g.error('ipython plugin: can not import IPython.ipapi')
    import_ok = False
except SyntaxError:
    g.error('ipython plugin: syntax error importing IPython.ipapi')
    import_ok = False

#@-<< imports >>

# Globals

# IPython IPApi instance. Global, because only one can exist through the whole leo session
gIP = None


#@+others
#@+node:ekr.20080201144219: ** Module-level functions