Exemplo n.º 1
0
 def _processCallTip_response(self, future):
     """ Process response of shell to show signature. 
     """
     
     # Process future
     if future.cancelled():
         #print('Introspect cancelled')  # No kernel
         return
     elif future.exception():
         print('Introspect-exception: ', future.exception())
         return
     else:
         response = future.result()
         cto = future.cto
     
     # First see if this is still the right editor (can also be a shell)
     editor1 = iep.editors.getCurrentEditor()
     editor2 = iep.shells.getCurrentShell()
     if cto.textCtrl not in [editor1, editor2]:
         # The editor or shell starting the autocomp is no longer active
         aco.textCtrl.autocompleteCancel()
         return
     
     # Invalid response
     if response is None:
         cto.textCtrl.autocompleteCancel()
         return
     
     # If still required, show tip, otherwise only store result
     if cto is self._currentCTO:
         cto.finish(response)
     else:
         cto.setBuffer(response)
Exemplo n.º 2
0
 def setInfo(self, info=None):
     """  Set the shell info struct, and use it to update the widgets.
     Not via init, because this function also sets the tab name.
     """ 
     
     # If info not given, use default as specified by the KernelInfo struct
     if info is None:
         info = KernelInfo()
         # Name
         n = self.parent().parent().count()
         if n > 1:
             info.name = "Shell config %i" % n
     
     # Store info
     self._info = info
     
     # Set widget values according to info
     try:            
        for key in info:
            widget = self._shellInfoWidgets.get(key, None)
            if widget is not None:
                widget.setTheText(info[key])
     
     except Exception as why:
         print("Error setting info in shell config:", why)
         print(info)
Exemplo n.º 3
0
    def _processCallTip_response(self, future):
        """ Process response of shell to show signature. 
        """

        # Process future
        if future.cancelled():
            #print('Introspect cancelled')  # No kernel
            return
        elif future.exception():
            print('Introspect-exception: ', future.exception())
            return
        else:
            response = future.result()
            cto = future.cto

        # First see if this is still the right editor (can also be a shell)
        editor1 = iep.editors.getCurrentEditor()
        editor2 = iep.shells.getCurrentShell()
        if cto.textCtrl not in [editor1, editor2]:
            # The editor or shell starting the autocomp is no longer active
            aco.textCtrl.autocompleteCancel()
            return

        # Invalid response
        if response is None:
            cto.textCtrl.autocompleteCancel()
            return

        # If still required, show tip, otherwise only store result
        if cto is self._currentCTO:
            cto.finish(response)
        else:
            cto.setBuffer(response)
Exemplo n.º 4
0
 def setInfo(self, info=None):
     """  Set the shell info struct, and use it to update the widgets.
     Not via init, because this function also sets the tab name.
     """ 
     
     # If info not given, use default as specified by the KernelInfo struct
     if info is None:
         info = KernelInfo()
         # Name
         n = self.parent().parent().count()
         if n > 1:
             info.name = "Shell config %i" % n
     
     # Store info
     self._info = info
     
     # Set widget values according to info
     try:            
        for key in info:
            widget = self._shellInfoWidgets.get(key, None)
            if widget is not None:
                widget.setTheText(info[key])
     
     except Exception as why:
         print("Error setting info in shell config:", why)
         print(info)
Exemplo n.º 5
0
    def _processAutoComp_response(self, future):
        """ Process the response of the shell for the auto completion. 
        """

        # Process future
        if future.cancelled():
            #print('Introspect cancelled') # No living kernel
            return
        elif future.exception():
            print('Introspect-exception: ', future.exception())
            return
        else:
            response = future.result()
            aco = future.aco

        # First see if this is still the right editor (can also be a shell)
        editor1 = iep.editors.getCurrentEditor()
        editor2 = iep.shells.getCurrentShell()
        if aco.textCtrl not in [editor1, editor2]:
            # The editor or shell starting the autocomp is no longer active
            aco.textCtrl.autocompleteCancel()
            return

        # Add result to the list
        foundNames = []
        if response is not None:
            foundNames = response
        aco.addNames(foundNames)

        # Process list
        if aco.name and not foundNames:
            # No names found for the requested name. This means
            # it does not exist, let's try to import it
            importNames, importLines = iep.parser.getFictiveImports(editor1)
            baseName = aco.nameInImportNames(importNames)
            if baseName:
                line = importLines[baseName].strip()
                if line not in self._importAttempts:
                    # Do import
                    self.processLine(line + ' # auto-import')
                    self._importAttempts.append(line)
                    # Wait a barely noticable time to increase the chances
                    # That the import is complete when we repost the request.
                    time.sleep(0.2)
                    # To be sure, decrease the experiration date on the buffer
                    aco.setBuffer(timeout=1)
                    # Repost request
                    future = self._request.signature(aco.name)
                    future.add_done_callback(self._processAutoComp_response)
                    future.aco = aco
        else:
            # If still required, show list, otherwise only store result
            if self._currentACO is aco:
                aco.finish()
            else:
                aco.setBuffer()
Exemplo n.º 6
0
 def _processAutoComp_response(self, future):
     """ Process the response of the shell for the auto completion. 
     """ 
     
     # Process future
     if future.cancelled():
         #print('Introspect cancelled') # No living kernel
         return
     elif future.exception():
         print('Introspect-exception: ', future.exception())
         return
     else:
         response = future.result()
         aco = future.aco
     
     # First see if this is still the right editor (can also be a shell)
     editor1 = iep.editors.getCurrentEditor()
     editor2 = iep.shells.getCurrentShell()
     if aco.textCtrl not in [editor1, editor2]:
         # The editor or shell starting the autocomp is no longer active
         aco.textCtrl.autocompleteCancel()
         return
     
     # Add result to the list
     foundNames = []
     if response is not None:
         foundNames = response
     aco.addNames(foundNames)
     
     # Process list
     if aco.name and not foundNames:
         # No names found for the requested name. This means
         # it does not exist, let's try to import it
         importNames, importLines = iep.parser.getFictiveImports(editor1)
         baseName = aco.nameInImportNames(importNames)
         if baseName:
             line = importLines[baseName].strip()
             if line not in self._importAttempts:
                 # Do import
                 self.processLine(line + ' # auto-import')
                 self._importAttempts.append(line)
                 # Wait a barely noticable time to increase the chances
                 # That the import is complete when we repost the request.
                 time.sleep(0.2)
                 # To be sure, decrease the experiration date on the buffer
                 aco.setBuffer(timeout=1)
                 # Repost request
                 future = self._request.signature(aco.name)
                 future.add_done_callback(self._processAutoComp_response)
                 future.aco = aco
     else:
         # If still required, show list, otherwise only store result
         if self._currentACO is aco:
             aco.finish()
         else:
             aco.setBuffer()
Exemplo n.º 7
0
    def saveFile(self, editor=None, filename=None):
        """ Save the file. 
        returns: True if succesfull, False if fails
        """
        
        # get editor
        if editor is None:
            editor = self.getCurrentEditor()
        elif isinstance(editor, int):
            index = editor
            editor = None
            if index>=0:
                item = self._tabs.items()[index]
                editor = item.editor
        if editor is None:
            return False
        
        # get filename
        if filename is None:
            filename = editor._filename
        if not filename:
            return self.saveFileAs(editor)

        
        # let the editor do the low level stuff...
        try:
            editor.save(filename)
        except Exception as err:
            # Notify in logger
            print("Error saving file:",err)
            # Make sure the user knows
            m = QtGui.QMessageBox(self)
            m.setWindowTitle("Error saving file")
            m.setText(str(err))
            m.setIcon(m.Warning)
            m.exec_()
            # Return now            
            return False
        
        # get actual normalized filename
        filename = editor._filename
        
        # notify
        # TODO: message concerining line endings
        print("saved file: {} ({})".format(filename, editor.lineEndingsHumanReadable))
        self._tabs.updateItems()
        
        # todo: this is where we once detected whether the file being saved was a style file.
        
        # Notify done
        return True
Exemplo n.º 8
0
    def saveFile(self, editor=None, filename=None):
        """ Save the file. 
        returns: True if succesfull, False if fails
        """
        
        # get editor
        if editor is None:
            editor = self.getCurrentEditor()
        elif isinstance(editor, int):
            index = editor
            editor = None
            if index>=0:
                item = self._tabs.items()[index]
                editor = item.editor
        if editor is None:
            return False
        
        # get filename
        if filename is None:
            filename = editor._filename
        if not filename:
            return self.saveFileAs(editor)

        
        # let the editor do the low level stuff...
        try:
            editor.save(filename)
        except Exception as err:
            # Notify in logger
            print("Error saving file:",err)
            # Make sure the user knows
            m = QtGui.QMessageBox(self)
            m.setWindowTitle("Error saving file")
            m.setText(str(err))
            m.setIcon(m.Warning)
            m.exec_()
            # Return now            
            return False
        
        # get actual normalized filename
        filename = editor._filename
        
        # notify
        # TODO: message concerining line endings
        print("saved file: {} ({})".format(filename, editor.lineEndingsHumanReadable))
        self._tabs.updateItems()
        
        # todo: this is where we once detected whether the file being saved was a style file.
        
        # Notify done
        return True
Exemplo n.º 9
0
 def loadFile(self, filename, updateTabs=True):
     """ Load the specified file. 
     On success returns the item of the file, also if it was
     already open."""
     
     # Note that by giving the name of a tempfile, we can select that
     # temp file.
     
     # normalize path
     if filename[0] != '<':
         filename = normalizePath(filename)
     if not filename:
         return None
     
     # if the file is already open...
     for item in self._tabs.items():
         if item.id == filename:
             # id gets _filename or _name for temp files
             break
     else:
         item = None
     if item:
         self._tabs.setCurrentItem(item)
         print("File already open: '{}'".format(filename))
         return item
     
     # create editor
     try:
         editor = createEditor(self, filename)
     except Exception as err:
         # Notify in logger
         print("Error loading file: ", err)
         # Make sure the user knows
         m = QtGui.QMessageBox(self)
         m.setWindowTitle("Error loading file")
         m.setText(str(err))
         m.setIcon(m.Warning)
         m.exec_()
         return None
     
     # create list item
     item = FileItem(editor)
     self._tabs.addItem(item, updateTabs)        
     if updateTabs:
         self._tabs.setCurrentItem(item)
     
     # store the path
     self._lastpath = os.path.dirname(item.filename)
     
     return item
Exemplo n.º 10
0
 def loadFile(self, filename, updateTabs=True):
     """ Load the specified file. 
     On success returns the item of the file, also if it was
     already open."""
     
     # Note that by giving the name of a tempfile, we can select that
     # temp file.
     
     # normalize path
     if filename[0] != '<':
         filename = normalizePath(filename)
     if not filename:
         return None
     
     # if the file is already open...
     for item in self._tabs.items():
         if item.id == filename:
             # id gets _filename or _name for temp files
             break
     else:
         item = None
     if item:
         self._tabs.setCurrentItem(item)
         print("File already open: '{}'".format(filename))
         return item
     
     # create editor
     try:
         editor = createEditor(self, filename)
     except Exception as err:
         # Notify in logger
         print("Error loading file: ", err)
         # Make sure the user knows
         m = QtGui.QMessageBox(self)
         m.setWindowTitle("Error loading file")
         m.setText(str(err))
         m.setIcon(m.Warning)
         m.exec_()
         return None
     
     # create list item
     item = FileItem(editor)
     self._tabs.addItem(item, updateTabs)        
     if updateTabs:
         self._tabs.setCurrentItem(item)
     
     # store the path
     self._lastpath = os.path.dirname(item.filename)
     
     return item
Exemplo n.º 11
0
 def getInfo(self):
     
     info = self._info
     
     # Set struct values according to widgets
     try:   
         for key, widget in self._shellInfoWidgets.items():
             info[key] = widget.getTheText()
     
     except Exception as why:
         print("Error getting info in shell config:", why)
         print(info)
     
     # Return the original (but modified) ssdf struct object
     return info
Exemplo n.º 12
0
 def getInfo(self):
     
     info = self._info
     
     # Set struct values according to widgets
     try:            
        for key in info:
            widget = self._shellInfoWidgets.get(key, None)
            if widget is not None:
                info[key] = widget.getTheText()
     
     except Exception as why:
         print("Error getting info in shell config:", why)
         print(info)
     
     # Return the original (but modified) ssdf struct object
     return info
Exemplo n.º 13
0
def normalizePath(path):
    """ Normalize the path given. 
    All slashes will be made the same (and doubles removed)
    The real case as stored on the file system is recovered.
    Returns None on error.
    """
    
    # normalize
    path = os.path.abspath(path)  # make sure it is defined from the drive up
    path = os.path.normpath(path)
    
    # If does not exist, return as is.
    # This also happens if the path's case is incorrect and the
    # file system is case sensitive. That's ok, because the stuff we 
    # do below is intended to get the path right on case insensitive
    # file systems.
    if not os.path.isfile(path):
        return path
    
    # split drive name from the rest
    drive, rest = os.path.splitdrive(path)
    fullpath = drive.upper() + os.sep
    
    # make lowercase and split in parts    
    parts = rest.lower().split(os.sep)
    parts = [part for part in parts if part]
    
    for part in parts:
        options = [x for x in os.listdir(fullpath) if x.lower()==part]
        if len(options) > 1:
            print("Error normalizing path: Ambiguous path names!")
            return path
        elif not options:
            print("Invalid path (part %s) in %s" % (part, fullpath))
            return path
        fullpath = os.path.join(fullpath, options[0])
    
    # remove last sep
    return fullpath
Exemplo n.º 14
0
 def _setCurrentOpenFilesAsSsdfList(self, state):
     """ Set the state of the editor in terms of opened files.
     The input should be a list object as returned by 
     ._getCurrentOpenFilesAsSsdfList().
     """
     
     # Init dict
     fileItems = {}
     
     # Process items
     for item in state:
         fname = item[0]
         if item[1] == 'hist':
             # select item (to make the history right)
             if fname in fileItems:
                 self._tabs.setCurrentItem( fileItems[fname] )
         elif fname:
             # a file item, create editor-item and store
             itm = self.loadFile(fname)
             fileItems[fname] = itm
             # set position
             if itm:
                 try:
                     ed = itm.editor
                     cursor = ed.textCursor()
                     cursor.setPosition(int(item[1]))
                     ed.setTextCursor(cursor)
                     # set scrolling
                     ed.verticalScrollBar().setValue(int(item[2]))
                     #ed.centerCursor() #TODO: this does not work properly yet
                     # set main and/or pinned?
                     if 'main' in item:
                         self._tabs._mainFile = itm.id
                     if 'pinned' in item:
                         itm._pinned = True
                 except Exception as err:
                     print('Could not set position for %s' % fname, err)
Exemplo n.º 15
0
 def _setCurrentOpenFilesAsSsdfList(self, state):
     """ Set the state of the editor in terms of opened files.
     The input should be a list object as returned by 
     ._getCurrentOpenFilesAsSsdfList().
     """
     
     # Init dict
     fileItems = {}
     
     # Process items
     for item in state:
         fname = item[0]
         if item[1] == 'hist':
             # select item (to make the history right)
             if fname in fileItems:
                 self._tabs.setCurrentItem( fileItems[fname] )
         elif fname:
             # a file item, create editor-item and store
             itm = self.loadFile(fname)
             fileItems[fname] = itm
             # set position
             if itm:
                 try:
                     ed = itm.editor
                     cursor = ed.textCursor()
                     cursor.setPosition(int(item[1]))
                     ed.setTextCursor(cursor)
                     # set scrolling
                     ed.verticalScrollBar().setValue(int(item[2]))
                     #ed.centerCursor() #TODO: this does not work properly yet
                     # set main and/or pinned?
                     if 'main' in item:
                         self._tabs._mainFile = itm.id
                     if 'pinned' in item:
                         itm._pinned = True
                 except Exception as err:
                     print('Could not set position for %s' % fname, err)
Exemplo n.º 16
0
 def loadDir(self, path):
     """ Create a project with the dir's name and add all files
     contained in the directory to it.
     extensions is a komma separated list of extenstions of files
     to accept...        
     """
     
     # if the path does not exist, stop     
     path = os.path.abspath(path)   
     if not os.path.isdir(path):
         print("ERROR loading dir: the specified directory does not exist!")
         return
     
     # get extensions
     extensions = iep.config.advanced.fileExtensionsToLoadFromDir
     extensions = extensions.replace(',',' ').replace(';',' ')
     extensions = ["."+a.lstrip(".").strip() for a in extensions.split(" ")]
     
     # init item
     item = None
     
     # open all qualified files...
     self._tabs.setUpdatesEnabled(False)
     try:
         filelist = os.listdir(path)
         for filename in filelist:
             filename = os.path.join(path, filename)
             ext = os.path.splitext(filename)[1]            
             if str(ext) in extensions:
                 item = self.loadFile(filename, False)
     finally:
         self._tabs.setUpdatesEnabled(True)
         self._tabs.updateItems()
     
     # return lastopened item
     return item
Exemplo n.º 17
0
 def loadDir(self, path):
     """ Create a project with the dir's name and add all files
     contained in the directory to it.
     extensions is a komma separated list of extenstions of files
     to accept...        
     """
     
     # if the path does not exist, stop     
     path = os.path.abspath(path)   
     if not os.path.isdir(path):
         print("ERROR loading dir: the specified directory does not exist!")
         return
     
     # get extensions
     extensions = iep.config.advanced.fileExtensionsToLoadFromDir
     extensions = extensions.replace(',',' ').replace(';',' ')
     extensions = ["."+a.lstrip(".").strip() for a in extensions.split(" ")]
     
     # init item
     item = None
     
     # open all qualified files...
     self._tabs.setUpdatesEnabled(False)
     try:
         filelist = os.listdir(path)
         for filename in filelist:
             filename = os.path.join(path, filename)
             ext = os.path.splitext(filename)[1]            
             if str(ext) in extensions:
                 item = self.loadFile(filename, False)
     finally:
         self._tabs.setUpdatesEnabled(True)
         self._tabs.updateItems()
     
     # return lastopened item
     return item
Exemplo n.º 18
0
    def poll(self, channel=None):
        """ poll()
        To keep the shell up-to-date.
        Call this periodically. 
        """

        if self._write_buffer:
            # There is still data in the buffer
            sub, M = self._write_buffer
        else:
            # Check what subchannel has the latest message pending
            sub = yoton.select_sub_channel(self._strm_out, self._strm_err,
                                           self._strm_echo, self._strm_raw,
                                           self._strm_broker,
                                           self._strm_prompt)
            # Read messages from it
            if sub:
                M = sub.recv_selected()
                #M = [sub.recv()] # Slow version (for testing)
                # Optimization: handle backspaces on stack of messages
                if sub is self._strm_out:
                    M = self._handleBackspacesOnList(M)
            # New prompt?
            if sub is self._strm_prompt:
                self.stateChanged.emit(self)

        # Write all pending messages that are later than any other message
        if sub:
            # Select messages to process
            N = 256
            M, buffer = M[:N], M[N:]
            # Buffer the rest
            if buffer:
                self._write_buffer = sub, buffer
            else:
                self._write_buffer = None
            # Get how to deal with prompt
            prompt = 0
            if sub is self._strm_echo:
                prompt = 1
            elif sub is self._strm_prompt:
                prompt = 2
            # Get color
            color = None
            if sub is self._strm_broker:
                color = '#000'
            elif sub is self._strm_raw:
                color = '#888888'  # Halfway
            elif sub is self._strm_err:
                color = '#F00'
            # Write
            self.write(''.join(M), prompt, color)

        # Do any actions?
        action = self._strm_action.recv(False)
        if action:
            if action.startswith('open '):
                fname = action.split(' ', 1)[1]
                iep.editors.loadFile(fname)
            else:
                print('Unkown action: %s' % action)

        # Update status
        state = self._stat_interpreter.recv()
        if state != self._state:
            self._state = state
            self.stateChanged.emit(self)

        # Update debug status
        state = self._stat_debug.recv()
        if state != self._debugState:
            self._debugState = state
            self.debugStateChanged.emit(self)
Exemplo n.º 19
0
 def poll(self, channel=None):
     """ poll()
     To keep the shell up-to-date.
     Call this periodically. 
     """
     
     if self._write_buffer:
         # There is still data in the buffer
         sub, M = self._write_buffer
     else:
         # Check what subchannel has the latest message pending
         sub = yoton.select_sub_channel(self._strm_out, self._strm_err, 
                             self._strm_echo, self._strm_raw,
                             self._strm_broker, self._strm_prompt )
         # Read messages from it
         if sub:
             M = sub.recv_selected()
             #M = [sub.recv()] # Slow version (for testing)
             # Optimization: handle backspaces on stack of messages
             if sub is self._strm_out:
                 M = self._handleBackspacesOnList(M)
         # New prompt?
         if sub is self._strm_prompt:
             self.stateChanged.emit(self)
     
     # Write all pending messages that are later than any other message
     if sub:
         # Select messages to process
         N = 256
         M, buffer = M[:N], M[N:]
         # Buffer the rest
         if buffer:
             self._write_buffer = sub, buffer
         else:
             self._write_buffer = None
         # Get how to deal with prompt
         prompt = 0
         if sub is self._strm_echo:
             prompt = 1 
         elif sub is  self._strm_prompt:
             prompt = 2
         # Get color
         color = None
         if sub is self._strm_broker:
             color = '#000'
         elif sub is self._strm_raw:
             color = '#888888' # Halfway
         elif sub is self._strm_err:
             color = '#F00'
         # Write
         self.write(''.join(M), prompt, color)
     
     
     # Do any actions?
     action = self._strm_action.recv(False)
     if action:
         if action.startswith('open '):
             fname = action.split(' ',1)[1]
             iep.editors.loadFile(fname)
         else:
             print('Unkown action: %s' % action)
     
     # Update status
     state = self._stat_interpreter.recv()
     if state != self._state:
         self._state = state
         self.stateChanged.emit(self)
     
     # Update debug status
     state = self._stat_debug.recv()        
     if state != self._debugState:
         self._debugState = state
         self.debugStateChanged.emit(self)