eric6/QScintilla/Shell.py

branch
maintenance
changeset 8043
0acf98cd089a
parent 7924
8a96736d465e
parent 7990
3b865f4b7dff
child 8142
43248bafe9b2
diff -r 866adc8c315b -r 0acf98cd089a eric6/QScintilla/Shell.py
--- a/eric6/QScintilla/Shell.py	Sun Jan 17 13:53:08 2021 +0100
+++ b/eric6/QScintilla/Shell.py	Mon Feb 01 10:38:16 2021 +0100
@@ -12,7 +12,7 @@
 
 from enum import Enum
 
-from PyQt5.QtCore import pyqtSignal, QFileInfo, Qt, QEvent
+from PyQt5.QtCore import pyqtSignal, pyqtSlot, QFileInfo, Qt, QEvent
 from PyQt5.QtGui import QClipboard, QPalette, QFont
 from PyQt5.QtWidgets import (
     QDialog, QInputDialog, QApplication, QMenu, QWidget, QHBoxLayout,
@@ -240,6 +240,8 @@
         dbs.clientSignal.connect(self.__clientSignal)
         self.dbs = dbs
         
+        self.__debugUI = None
+        
         # Initialize instance variables.
         self.__initialise()
         self.prline = 0
@@ -603,6 +605,7 @@
         @param ui reference to the debugger UI object (DebugUI)
         """
         ui.exceptionInterrupt.connect(self.__writePrompt)
+        self.__debugUI = ui
         
     def __initialise(self):
         """
@@ -610,8 +613,10 @@
         """
         self.buff = ""
         self.inContinue = False
-        self.inRawMode = False
-        self.echoInput = True
+        self.__inRawMode = False
+        self.__echoInput = True
+        self.__rawModeDebuggerId = None
+        self.__rawModeQueue = []
         self.clientCapabilities = 0
         self.inCommandExecution = False
         self.interruptCommandExecution = False
@@ -817,7 +822,7 @@
         else:
             self.dbs.remoteBanner()
         
-    def __writeBanner(self, version, platform, dbgclient, venvName):
+    def __writeBanner(self, version, platform, venvName):
         """
         Private method to write a banner with info from the debug client.
         
@@ -825,8 +830,6 @@
         @type str
         @param platform platform of the remote interpreter
         @type str
-        @param dbgclient debug client variant used
-        @type str
         @param venvName name of the virtual environment
         @type str
         """
@@ -837,10 +840,8 @@
         else:
             self.__currentVenv = venvName
             version = version.replace("#", self.tr("No."))
-            if platform != "" and dbgclient != "":
-                self.__write(
-                    self.tr('{0} on {1}, {2}')
-                        .format(version, platform, dbgclient))
+            if platform != "":
+                self.__write(self.tr('{0} on {1}').format(version, platform))
             else:
                 self.__write(version)
             if venvName:
@@ -862,9 +863,10 @@
         """
         Private method to handle the response from the debugger client.
         
-        @param more flag indicating that more user input is required (boolean)
+        @param more flag indicating that more user input is required
+        @type bool
         """
-        if not self.inRawMode:
+        if not self.__inRawMode:
             self.inContinue = more
             self.__writePrompt()
         self.inCommandExecution = False
@@ -1037,38 +1039,48 @@
         """
         self.__write(self.tr("StdErr: {0}").format(s))
         
-    def __raw_input(self, prompt, echo):
+    def __raw_input(self, prompt, echo, debuggerId):
         """
         Private method to handle raw input.
         
-        @param prompt prompt to be displayed
+        @param prompt the input prompt
         @type str
-        @param echo Flag indicating echoing of the input
+        @param echo flag indicating an echoing of the input
         @type bool
+        @param debuggerId ID of the debugger backend
+        @type str
         """
-        self.setFocus()
-        self.inRawMode = True
-        self.echoInput = echo
-        
-        # Get all text which is still waiting for output
-        QApplication.processEvents()
-        self.__flushQueuedText()
+        if self.__inRawMode:
+            # we are processing another raw input event already
+            self.__rawModeQueue.append((debuggerId, prompt, echo))
+        else:
+            self.setFocus()
+            self.__inRawMode = True
+            self.__echoInput = echo
+            self.__rawModeDebuggerId = debuggerId
+            
+            # Get all text which is still waiting for output
+            QApplication.processEvents()
+            self.__flushQueuedText()
+            
+            self.__write(self.tr("<{0}> {1}").format(debuggerId, prompt))
+            line, col = self.__getEndPos()
+            self.setCursorPosition(line, col)
+            buf = self.text(line)
+            if buf.startswith(sys.ps1):
+                buf = buf.replace(sys.ps1, "")
+            if buf.startswith(sys.ps2):
+                buf = buf.replace(sys.ps2, "")
+            self.prompt = buf
+            # move cursor to end of line
+            self.moveCursorToEOL()
         
-        self.__write(prompt)
-        line, col = self.__getEndPos()
-        self.setCursorPosition(line, col)
-        buf = self.text(line)
-        if buf.startswith(sys.ps1):
-            buf = buf.replace(sys.ps1, "")
-        if buf.startswith(sys.ps2):
-            buf = buf.replace(sys.ps2, "")
-        self.prompt = buf
-        # move cursor to end of line
-        self.moveCursorToEOL()
-        
-    def paste(self):
+    def paste(self, lines=None):
         """
         Public slot to handle the paste action.
+        
+        @param lines list of lines to be inserted
+        @type list of str
         """
         if self.__isCursorOnLastLine():
             line, col = self.getCursorPosition()
@@ -1104,20 +1116,15 @@
             self.setCursorPosition(line, len(prompt))
             self.deleteLineRight()
             
-            lines = QApplication.clipboard().text()
+            if lines is None:
+                lines = QApplication.clipboard().text()
+            
             lines = lastLine[:col] + lines + lastLine[col:]
             self.executeLines(lines)
             line, _ = self.getCursorPosition()
             pos = len(self.text(line)) - (len(lastLine) - col)
             self.setCursorPosition(line, pos)
-        
-    def __middleMouseButton(self):
-        """
-        Private method to handle the middle mouse button press.
-        """
-        lines = QApplication.clipboard().text(QClipboard.Selection)
-        self.executeLines(lines)
-        
+    
     def executeLines(self, lines, historyIndex=None):
         """
         Public method to execute a set of lines as multiple commands.
@@ -1141,12 +1148,9 @@
             else:
                 line = line[indentLen:]
             
-            if line.endswith("\r\n"):
+            if line.endswith(("\r\n", "\r", "\n")):
                 fullline = True
-                cmd = line[:-2]
-            elif line.endswith("\r") or line.endswith("\n"):
-                fullline = True
-                cmd = line[:-1]
+                cmd = line.rstrip()
             else:
                 fullline = False
             
@@ -1228,7 +1232,8 @@
         """
         self.setFocus()
         if event.button() == Qt.MidButton:
-            self.__middleMouseButton()
+            lines = QApplication.clipboard().text(QClipboard.Selection)
+            self.paste(lines)
         else:
             super(Shell, self).mousePressEvent(event)
         
@@ -1320,12 +1325,15 @@
                 line, col = self.__getEndPos()
                 self.setCursorPosition(line, col)
                 self.prline, self.prcol = self.getCursorPosition()
-            if self.echoInput:
+            if self.__echoInput:
                 ac = self.isListActive()
                 super(Shell, self).keyPressEvent(ev)
                 self.incrementalSearchActive = True
                 if ac and self.racEnabled:
-                    self.dbs.remoteCompletion(self.completionText + txt)
+                    self.dbs.remoteCompletion(
+                        self.__debugUI.getSelectedDebuggerId(),
+                        self.completionText + txt
+                    )
             else:
                 self.__insertTextNoEcho(txt)
         else:
@@ -1357,7 +1365,10 @@
             if self.inContinue and not buf[:index - len(sys.ps2)].strip():
                 self.SendScintilla(cmd)
             elif self.racEnabled:
-                self.dbs.remoteCompletion(buf)
+                self.dbs.remoteCompletion(
+                    self.__debugUI.getSelectedDebuggerId(),
+                    buf
+                )
         
     def __QScintillaLeftDeleteCommand(self, method):
         """
@@ -1385,7 +1396,10 @@
                 db = 1
             if db and ac and self.racEnabled and self.completionText:
                 delta = len(self.text(line)) - oldLength
-                self.dbs.remoteCompletion(self.completionText[:delta])
+                self.dbs.remoteCompletion(
+                    self.__debugUI.getSelectedDebuggerId(),
+                    self.completionText[:delta]
+                )
         
     def __QScintillaDeleteBack(self):
         """
@@ -1762,7 +1776,7 @@
         @param historyIndex history index to be set
         @type int
         """
-        if not self.inRawMode:
+        if not self.__inRawMode:
             self.inCommandExecution = True
             self.interruptCommandExecution = False
             if not cmd:
@@ -1852,22 +1866,27 @@
                 self.vm.quit()
                 return
             
-            self.dbs.remoteStatement(cmd)
+            self.dbs.remoteStatement(self.__debugUI.getSelectedDebuggerId(),
+                                     cmd)
             while self.inCommandExecution:
                 try:
                     QApplication.processEvents()
                 except KeyboardInterrupt:
                     pass
         else:
-            if not self.echoInput:
+            if not self.__echoInput:
                 cmd = self.buff
                 self.buff = ""
             elif cmd:
                 cmd = cmd[len(self.prompt):]
-            self.inRawMode = False
-            self.echoInput = True
+            self.__inRawMode = False
+            self.__echoInput = True
             
-            self.dbs.remoteRawInput(cmd)
+            self.dbs.remoteRawInput(self.__rawModeDebuggerId, cmd)
+            
+            if self.__rawModeQueue:
+                debuggerId, prompt, echo = self.__rawModeQueue.pop(0)
+                self.__raw_input(prompt, echo, debuggerId)
     
     def __showVenvName(self):
         """
@@ -2064,7 +2083,8 @@
                 self.dbs.clientProcessStdout.disconnect(self.__writeStdOut)
                 self.dbs.clientProcessStderr.disconnect(self.__writeStdErr)
             self.__showStdOutErr = showStdOutErr
-        
+    
+    @pyqtSlot(list, str)
     def __showCompletions(self, completions, text):
         """
         Private method to display the possible completions.

eric ide

mercurial