src/eric7/QScintilla/Shell.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9332
2e0a16d95083
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
14 import pathlib 14 import pathlib
15 15
16 from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QEvent 16 from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QEvent
17 from PyQt6.QtGui import QClipboard, QPalette, QFont, QShortcut 17 from PyQt6.QtGui import QClipboard, QPalette, QFont, QShortcut
18 from PyQt6.QtWidgets import ( 18 from PyQt6.QtWidgets import (
19 QDialog, QInputDialog, QApplication, QMenu, QWidget, QHBoxLayout, 19 QDialog,
20 QVBoxLayout, QSizePolicy 20 QInputDialog,
21 QApplication,
22 QMenu,
23 QWidget,
24 QHBoxLayout,
25 QVBoxLayout,
26 QSizePolicy,
21 ) 27 )
22 from PyQt6.Qsci import QsciScintilla 28 from PyQt6.Qsci import QsciScintilla
23 29
24 from EricWidgets.EricApplication import ericApp 30 from EricWidgets.EricApplication import ericApp
25 from EricWidgets import EricMessageBox, EricFileDialog 31 from EricWidgets import EricMessageBox, EricFileDialog
36 42
37 class ShellAssembly(QWidget): 43 class ShellAssembly(QWidget):
38 """ 44 """
39 Class implementing the containing widget for the shell. 45 Class implementing the containing widget for the shell.
40 """ 46 """
47
41 def __init__(self, dbs, vm, project, horizontal=True, parent=None): 48 def __init__(self, dbs, vm, project, horizontal=True, parent=None):
42 """ 49 """
43 Constructor 50 Constructor
44 51
45 @param dbs reference to the debug server object 52 @param dbs reference to the debug server object
46 @type DebugServer 53 @type DebugServer
47 @param vm reference to the viewmanager object 54 @param vm reference to the viewmanager object
48 @type ViewManager 55 @type ViewManager
49 @param project reference to the project object 56 @param project reference to the project object
52 @type bool 59 @type bool
53 @param parent parent widget 60 @param parent parent widget
54 @type QWidget 61 @type QWidget
55 """ 62 """
56 super().__init__(parent) 63 super().__init__(parent)
57 64
58 self.__shell = Shell(dbs, vm, project, False, self) 65 self.__shell = Shell(dbs, vm, project, False, self)
59 66
60 from UI.SearchWidget import SearchWidget 67 from UI.SearchWidget import SearchWidget
68
61 self.__searchWidget = SearchWidget(self.__shell, self, horizontal) 69 self.__searchWidget = SearchWidget(self.__shell, self, horizontal)
62 self.__searchWidget.setSizePolicy(QSizePolicy.Policy.Fixed, 70 self.__searchWidget.setSizePolicy(
63 QSizePolicy.Policy.Preferred) 71 QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred
72 )
64 self.__searchWidget.hide() 73 self.__searchWidget.hide()
65 74
66 if horizontal: 75 if horizontal:
67 self.__layout = QHBoxLayout(self) 76 self.__layout = QHBoxLayout(self)
68 else: 77 else:
69 self.__layout = QVBoxLayout(self) 78 self.__layout = QVBoxLayout(self)
70 self.__layout.setContentsMargins(1, 1, 1, 1) 79 self.__layout.setContentsMargins(1, 1, 1, 1)
71 self.__layout.addWidget(self.__shell) 80 self.__layout.addWidget(self.__shell)
72 self.__layout.addWidget(self.__searchWidget) 81 self.__layout.addWidget(self.__searchWidget)
73 82
74 self.__searchWidget.searchNext.connect(self.__shell.searchNext) 83 self.__searchWidget.searchNext.connect(self.__shell.searchNext)
75 self.__searchWidget.searchPrevious.connect(self.__shell.searchPrev) 84 self.__searchWidget.searchPrevious.connect(self.__shell.searchPrev)
76 self.__shell.searchStringFound.connect( 85 self.__shell.searchStringFound.connect(self.__searchWidget.searchStringFound)
77 self.__searchWidget.searchStringFound) 86
78
79 def showFind(self, txt=""): 87 def showFind(self, txt=""):
80 """ 88 """
81 Public method to display the search widget. 89 Public method to display the search widget.
82 90
83 @param txt text to be shown in the combo (string) 91 @param txt text to be shown in the combo (string)
84 """ 92 """
85 self.__searchWidget.showFind(txt) 93 self.__searchWidget.showFind(txt)
86 94
87 def shell(self): 95 def shell(self):
88 """ 96 """
89 Public method to get a reference to the shell widget. 97 Public method to get a reference to the shell widget.
90 98
91 @return reference to the shell widget (Shell) 99 @return reference to the shell widget (Shell)
92 """ 100 """
93 return self.__shell 101 return self.__shell
94 102
95 103
96 class ShellHistoryStyle(enum.Enum): 104 class ShellHistoryStyle(enum.Enum):
97 """ 105 """
98 Class defining the shell history styles. 106 Class defining the shell history styles.
99 """ 107 """
108
100 DISABLED = 0 109 DISABLED = 0
101 LINUXSTYLE = 1 110 LINUXSTYLE = 1
102 WINDOWSSTYLE = 2 111 WINDOWSSTYLE = 2
103 112
104 113
105 class Shell(QsciScintillaCompat): 114 class Shell(QsciScintillaCompat):
106 """ 115 """
107 Class implementing a graphical Python shell. 116 Class implementing a graphical Python shell.
108 117
109 A user can enter commands that are executed in the remote 118 A user can enter commands that are executed in the remote
110 Python interpreter. 119 Python interpreter.
111 120
112 @signal searchStringFound(bool) emitted to indicate the search 121 @signal searchStringFound(bool) emitted to indicate the search
113 result 122 result
114 @signal historyStyleChanged(ShellHistoryStyle) emitted to indicate a 123 @signal historyStyleChanged(ShellHistoryStyle) emitted to indicate a
115 change of the history style 124 change of the history style
116 @signal queueText(str) emitted to queue some text for processing 125 @signal queueText(str) emitted to queue some text for processing
117 @signal virtualEnvironmentChanged(str) emitted to signal the new virtual 126 @signal virtualEnvironmentChanged(str) emitted to signal the new virtual
118 environment of the shell 127 environment of the shell
119 """ 128 """
129
120 searchStringFound = pyqtSignal(bool) 130 searchStringFound = pyqtSignal(bool)
121 historyStyleChanged = pyqtSignal(ShellHistoryStyle) 131 historyStyleChanged = pyqtSignal(ShellHistoryStyle)
122 queueText = pyqtSignal(str) 132 queueText = pyqtSignal(str)
123 virtualEnvironmentChanged = pyqtSignal(str) 133 virtualEnvironmentChanged = pyqtSignal(str)
124 134
125 def __init__(self, dbs, vm, project, windowedVariant, parent=None): 135 def __init__(self, dbs, vm, project, windowedVariant, parent=None):
126 """ 136 """
127 Constructor 137 Constructor
128 138
129 @param dbs reference to the debug server object 139 @param dbs reference to the debug server object
130 @type DebugServer 140 @type DebugServer
131 @param vm reference to the viewmanager object 141 @param vm reference to the viewmanager object
132 @type ViewManager 142 @type ViewManager
133 @param project reference to the project object 143 @param project reference to the project object
137 @param parent parent widget 147 @param parent parent widget
138 @type QWidget 148 @type QWidget
139 """ 149 """
140 super().__init__(parent) 150 super().__init__(parent)
141 self.setUtf8(True) 151 self.setUtf8(True)
142 152
143 self.vm = vm 153 self.vm = vm
144 self.__mainWindow = parent 154 self.__mainWindow = parent
145 self.__lastSearch = () 155 self.__lastSearch = ()
146 self.__windowed = windowedVariant 156 self.__windowed = windowedVariant
147 self.__currentVenv = "" 157 self.__currentVenv = ""
148 self.__currentWorkingDirectory = "" 158 self.__currentWorkingDirectory = ""
149 159
150 self.linesepRegExp = r"\r\n|\n|\r" 160 self.linesepRegExp = r"\r\n|\n|\r"
151 161
152 self.passive = ((not self.__windowed) and 162 self.passive = (not self.__windowed) and Preferences.getDebugger(
153 Preferences.getDebugger("PassiveDbgEnabled")) 163 "PassiveDbgEnabled"
164 )
154 if self.passive: 165 if self.passive:
155 self.setWindowTitle(self.tr('Shell - Passive')) 166 self.setWindowTitle(self.tr("Shell - Passive"))
156 else: 167 else:
157 self.setWindowTitle(self.tr('Shell')) 168 self.setWindowTitle(self.tr("Shell"))
158 169
159 if self.__windowed: 170 if self.__windowed:
160 self.setWhatsThis(self.tr( 171 self.setWhatsThis(
161 """<b>The Shell Window</b>""" 172 self.tr(
162 """<p>You can use the cursor keys while entering commands.""" 173 """<b>The Shell Window</b>"""
163 """ There is also a history of commands that can be recalled""" 174 """<p>You can use the cursor keys while entering commands."""
164 """ using the up and down cursor keys while holding down the""" 175 """ There is also a history of commands that can be recalled"""
165 """ Ctrl-key. This can be switched to just the up and down""" 176 """ using the up and down cursor keys while holding down the"""
166 """ cursor keys on the Shell page of the configuration""" 177 """ Ctrl-key. This can be switched to just the up and down"""
167 """ dialog. Pressing these keys after some text has been""" 178 """ cursor keys on the Shell page of the configuration"""
168 """ entered will start an incremental search.</p>""" 179 """ dialog. Pressing these keys after some text has been"""
169 """<p>The shell has some special commands. '%restart' kills""" 180 """ entered will start an incremental search.</p>"""
170 """ the shell and starts a new one. '%clear' clears the""" 181 """<p>The shell has some special commands. '%restart' kills"""
171 """ display of the shell window. '%start' is used to start a""" 182 """ the shell and starts a new one. '%clear' clears the"""
172 """ shell for a virtual environment and should be followed""" 183 """ display of the shell window. '%start' is used to start a"""
173 """ by a virtual environment name. '%start' without a""" 184 """ shell for a virtual environment and should be followed"""
174 """ virtual environment name starts the default shell.""" 185 """ by a virtual environment name. '%start' without a"""
175 """ Available virtual environments may be listed with the""" 186 """ virtual environment name starts the default shell."""
176 """ '%envs' or '%environments' commands. The active virtual""" 187 """ Available virtual environments may be listed with the"""
177 """ environment can be questioned by the '%which' command.""" 188 """ '%envs' or '%environments' commands. The active virtual"""
178 """ '%quit' or '%exit' is used to exit the application.""" 189 """ environment can be questioned by the '%which' command."""
179 """ These commands (except '%environments', '%envs' and""" 190 """ '%quit' or '%exit' is used to exit the application."""
180 """ '%which') are available through the window menus as""" 191 """ These commands (except '%environments', '%envs' and"""
181 """ well.</p>""" 192 """ '%which') are available through the window menus as"""
182 """<p>Pressing the Tab key after some text has been entered""" 193 """ well.</p>"""
183 """ will show a list of possible completions. The relevant""" 194 """<p>Pressing the Tab key after some text has been entered"""
184 """ entry may be selected from this list. If only one entry""" 195 """ will show a list of possible completions. The relevant"""
185 """ is available, this will be inserted automatically.</p>""" 196 """ entry may be selected from this list. If only one entry"""
186 )) 197 """ is available, this will be inserted automatically.</p>"""
187 else: 198 )
188 self.setWhatsThis(self.tr( 199 )
189 """<b>The Shell Window</b>""" 200 else:
190 """<p>This is simply an interpreter running in a window. The""" 201 self.setWhatsThis(
191 """ interpreter is the one that is used to run the program""" 202 self.tr(
192 """ being debugged. This means that you can execute any""" 203 """<b>The Shell Window</b>"""
193 """ command while the program being debugged is running.</p>""" 204 """<p>This is simply an interpreter running in a window. The"""
194 """<p>You can use the cursor keys while entering commands.""" 205 """ interpreter is the one that is used to run the program"""
195 """ There is also a history of commands that can be recalled""" 206 """ being debugged. This means that you can execute any"""
196 """ using the up and down cursor keys while holding down the""" 207 """ command while the program being debugged is running.</p>"""
197 """ Ctrl-key. This can be switched to just the up and down""" 208 """<p>You can use the cursor keys while entering commands."""
198 """ cursor keys on the Shell page of the configuration""" 209 """ There is also a history of commands that can be recalled"""
199 """ dialog. Pressing these keys after some text has been""" 210 """ using the up and down cursor keys while holding down the"""
200 """ entered will start an incremental search.</p>""" 211 """ Ctrl-key. This can be switched to just the up and down"""
201 """<p>The shell has some special commands. '%restart' kills""" 212 """ cursor keys on the Shell page of the configuration"""
202 """ the shell and starts a new one. '%clear' clears the""" 213 """ dialog. Pressing these keys after some text has been"""
203 """ display of the shell window. '%start' is used to start a""" 214 """ entered will start an incremental search.</p>"""
204 """ shell for a virtual environment and should be followed""" 215 """<p>The shell has some special commands. '%restart' kills"""
205 """ by a virtual environment name. '%start' without a""" 216 """ the shell and starts a new one. '%clear' clears the"""
206 """ virtual environment name starts the default shell.""" 217 """ display of the shell window. '%start' is used to start a"""
207 """ Available virtual environments may be listed with the""" 218 """ shell for a virtual environment and should be followed"""
208 """ '%envs' or '%environments' commands. The active virtual""" 219 """ by a virtual environment name. '%start' without a"""
209 """ environment can be questioned by the '%which' command.""" 220 """ virtual environment name starts the default shell."""
210 """ These commands (except '%environments' and '%envs') are""" 221 """ Available virtual environments may be listed with the"""
211 """ available through the context menu as well.</p>""" 222 """ '%envs' or '%environments' commands. The active virtual"""
212 """<p>Pressing the Tab key after some text has been entered""" 223 """ environment can be questioned by the '%which' command."""
213 """ will show a list of possible completions. The relevant""" 224 """ These commands (except '%environments' and '%envs') are"""
214 """ entry may be selected from this list. If only one entry""" 225 """ available through the context menu as well.</p>"""
215 """ is available, this will be inserted automatically.</p>""" 226 """<p>Pressing the Tab key after some text has been entered"""
216 """<p>In passive debugging mode the shell is only available""" 227 """ will show a list of possible completions. The relevant"""
217 """ after the program to be debugged has connected to the""" 228 """ entry may be selected from this list. If only one entry"""
218 """ IDE until it has finished. This is indicated by a""" 229 """ is available, this will be inserted automatically.</p>"""
219 """ different prompt and by an indication in the window""" 230 """<p>In passive debugging mode the shell is only available"""
220 """ caption.</p>""" 231 """ after the program to be debugged has connected to the"""
221 )) 232 """ IDE until it has finished. This is indicated by a"""
222 233 """ different prompt and by an indication in the window"""
234 """ caption.</p>"""
235 )
236 )
237
223 self.userListActivated.connect(self.__completionListSelected) 238 self.userListActivated.connect(self.__completionListSelected)
224 self.linesChanged.connect(self.__resizeLinenoMargin) 239 self.linesChanged.connect(self.__resizeLinenoMargin)
225 240
226 if self.__windowed: 241 if self.__windowed:
227 self.__showStdOutErr = True 242 self.__showStdOutErr = True
228 else: 243 else:
229 self.__showStdOutErr = Preferences.getShell("ShowStdOutErr") 244 self.__showStdOutErr = Preferences.getShell("ShowStdOutErr")
230 if self.__showStdOutErr: 245 if self.__showStdOutErr:
240 dbs.clientException.connect(self.__clientException) 255 dbs.clientException.connect(self.__clientException)
241 dbs.clientSyntaxError.connect(self.__clientSyntaxError) 256 dbs.clientSyntaxError.connect(self.__clientSyntaxError)
242 dbs.clientSignal.connect(self.__clientSignal) 257 dbs.clientSignal.connect(self.__clientSignal)
243 dbs.mainClientExit.connect(self.__writePrompt) 258 dbs.mainClientExit.connect(self.__writePrompt)
244 self.dbs = dbs 259 self.dbs = dbs
245 260
246 # will register a method to get the debugger ID to work with 261 # will register a method to get the debugger ID to work with
247 self.__getSelectedDebuggerId = None 262 self.__getSelectedDebuggerId = None
248 263
249 # Make sure we have prompts. 264 # Make sure we have prompts.
250 if self.passive: 265 if self.passive:
251 sys.ps1 = self.tr("Passive >>> ") 266 sys.ps1 = self.tr("Passive >>> ")
252 else: 267 else:
253 try: 268 try:
256 sys.ps1 = ">>> " 271 sys.ps1 = ">>> "
257 try: 272 try:
258 sys.ps2 273 sys.ps2
259 except AttributeError: 274 except AttributeError:
260 sys.ps2 = "... " 275 sys.ps2 = "... "
261 276
262 # Initialize instance variables. 277 # Initialize instance variables.
263 self.__initialise() 278 self.__initialise()
264 self.prline = 0 279 self.prline = 0
265 self.prcol = 0 280 self.prcol = 0
266 self.inDragDrop = False 281 self.inDragDrop = False
267 self.lexer_ = None 282 self.lexer_ = None
268 self.completionText = "" 283 self.completionText = ""
269 284
270 self.clientType = '' 285 self.clientType = ""
271 286
272 # Initialize history 287 # Initialize history
273 self.__historyLists = {} 288 self.__historyLists = {}
274 self.__maxHistoryEntries = Preferences.getShell("MaxHistoryEntries") 289 self.__maxHistoryEntries = Preferences.getShell("MaxHistoryEntries")
275 self.__historyStyle = Preferences.getShell("HistoryStyle") 290 self.__historyStyle = Preferences.getShell("HistoryStyle")
276 self.__historyWrap = Preferences.getShell("HistoryWrap") 291 self.__historyWrap = Preferences.getShell("HistoryWrap")
277 self.__history = [] 292 self.__history = []
278 self.__setHistoryIndex() 293 self.__setHistoryIndex()
279 # remove obsolete shell histories (Python and Ruby) 294 # remove obsolete shell histories (Python and Ruby)
280 for clientType in ["Python", "Ruby"]: 295 for clientType in ["Python", "Ruby"]:
281 Preferences.getSettings().remove("Shell/Histories/" + clientType) 296 Preferences.getSettings().remove("Shell/Histories/" + clientType)
282 297
283 # clear QScintilla defined keyboard commands 298 # clear QScintilla defined keyboard commands
284 # we do our own handling through the view manager 299 # we do our own handling through the view manager
285 self.clearAlternateKeys() 300 self.clearAlternateKeys()
286 self.clearKeys() 301 self.clearKeys()
287 self.__actionsAdded = False 302 self.__actionsAdded = False
288 303
289 if self.passive: 304 if self.passive:
290 self.__getBanner() 305 self.__getBanner()
291 306
292 if not self.__windowed: 307 if not self.__windowed:
293 # Create a little language context menu 308 # Create a little language context menu
294 self.lmenu = QMenu(self.tr('Start')) 309 self.lmenu = QMenu(self.tr("Start"))
295 self.lmenu.aboutToShow.connect(self.__showStartMenu) 310 self.lmenu.aboutToShow.connect(self.__showStartMenu)
296 self.lmenu.triggered.connect(self.__startDebugClient) 311 self.lmenu.triggered.connect(self.__startDebugClient)
297 312
298 # Create the history context menu 313 # Create the history context menu
299 self.hmenu = QMenu(self.tr('History')) 314 self.hmenu = QMenu(self.tr("History"))
300 self.hmenu.addAction(self.tr('Select entry'), self.selectHistory) 315 self.hmenu.addAction(self.tr("Select entry"), self.selectHistory)
301 self.hmenu.addAction(self.tr('Show'), self.showHistory) 316 self.hmenu.addAction(self.tr("Show"), self.showHistory)
302 self.hmenu.addAction(self.tr('Clear'), self.clearHistory) 317 self.hmenu.addAction(self.tr("Clear"), self.clearHistory)
303 318
304 # Create a little context menu 319 # Create a little context menu
305 self.menu = QMenu(self) 320 self.menu = QMenu(self)
306 self.menu.addAction(self.tr('Cut'), self.cut) 321 self.menu.addAction(self.tr("Cut"), self.cut)
307 self.menu.addAction(self.tr('Copy'), self.copy) 322 self.menu.addAction(self.tr("Copy"), self.copy)
308 self.menu.addAction(self.tr('Paste'), self.paste) 323 self.menu.addAction(self.tr("Paste"), self.paste)
309 self.menu.addMenu(self.hmenu).setEnabled(self.isHistoryEnabled()) 324 self.menu.addMenu(self.hmenu).setEnabled(self.isHistoryEnabled())
310 325
311 self.menu.addSeparator() 326 self.menu.addSeparator()
312 self.menu.addAction(self.tr('Find'), self.__find) 327 self.menu.addAction(self.tr("Find"), self.__find)
313 self.menu.addSeparator() 328 self.menu.addSeparator()
314 self.menu.addAction(self.tr('Clear'), self.clear) 329 self.menu.addAction(self.tr("Clear"), self.clear)
315 self.menu.addAction(self.tr('Restart'), self.doRestart) 330 self.menu.addAction(self.tr("Restart"), self.doRestart)
316 self.menu.addAction( 331 self.menu.addAction(self.tr("Restart and Clear"), self.doClearRestart)
317 self.tr('Restart and Clear'), self.doClearRestart)
318 self.menu.addSeparator() 332 self.menu.addSeparator()
319 self.menu.addMenu(self.lmenu) 333 self.menu.addMenu(self.lmenu)
320 self.menu.addAction(self.tr('Active Name'), self.__showVenvName) 334 self.menu.addAction(self.tr("Active Name"), self.__showVenvName)
321 self.menu.addSeparator() 335 self.menu.addSeparator()
322 self.menu.addAction(self.tr("Save Contents..."), self.saveContents) 336 self.menu.addAction(self.tr("Save Contents..."), self.saveContents)
323 self.menu.addSeparator() 337 self.menu.addSeparator()
324 self.menu.addAction(self.tr("Configure..."), self.__configure) 338 self.menu.addAction(self.tr("Configure..."), self.__configure)
325 339
326 self.__bindLexer() 340 self.__bindLexer()
327 self.__setTextDisplay() 341 self.__setTextDisplay()
328 self.__setMargin0() 342 self.__setMargin0()
329 343
330 # set the autocompletion and calltips function 344 # set the autocompletion and calltips function
331 self.__setAutoCompletion() 345 self.__setAutoCompletion()
332 self.__setCallTips() 346 self.__setCallTips()
333 347
334 self.setWindowIcon(UI.PixmapCache.getIcon("eric")) 348 self.setWindowIcon(UI.PixmapCache.getIcon("eric"))
335 349
336 self.incrementalSearchString = "" 350 self.incrementalSearchString = ""
337 self.incrementalSearchActive = False 351 self.incrementalSearchActive = False
338 352
339 self.supportedEditorCommands = { 353 self.supportedEditorCommands = {
340 QsciScintilla.SCI_LINEDELETE: self.__clearCurrentLine, 354 QsciScintilla.SCI_LINEDELETE: self.__clearCurrentLine,
341 QsciScintilla.SCI_TAB: self.__QScintillaTab, 355 QsciScintilla.SCI_TAB: self.__QScintillaTab,
342 QsciScintilla.SCI_NEWLINE: self.__QScintillaNewline, 356 QsciScintilla.SCI_NEWLINE: self.__QScintillaNewline,
343
344 QsciScintilla.SCI_DELETEBACK: self.__QScintillaDeleteBack, 357 QsciScintilla.SCI_DELETEBACK: self.__QScintillaDeleteBack,
345 QsciScintilla.SCI_CLEAR: self.__QScintillaDelete, 358 QsciScintilla.SCI_CLEAR: self.__QScintillaDelete,
346 QsciScintilla.SCI_DELWORDLEFT: self.__QScintillaDeleteWordLeft, 359 QsciScintilla.SCI_DELWORDLEFT: self.__QScintillaDeleteWordLeft,
347 QsciScintilla.SCI_DELWORDRIGHT: self.__QScintillaDeleteWordRight, 360 QsciScintilla.SCI_DELWORDRIGHT: self.__QScintillaDeleteWordRight,
348 QsciScintilla.SCI_DELLINELEFT: self.__QScintillaDeleteLineLeft, 361 QsciScintilla.SCI_DELLINELEFT: self.__QScintillaDeleteLineLeft,
349 QsciScintilla.SCI_DELLINERIGHT: self.__QScintillaDeleteLineRight, 362 QsciScintilla.SCI_DELLINERIGHT: self.__QScintillaDeleteLineRight,
350
351 QsciScintilla.SCI_CHARLEFT: self.__QScintillaCharLeft, 363 QsciScintilla.SCI_CHARLEFT: self.__QScintillaCharLeft,
352 QsciScintilla.SCI_CHARRIGHT: self.__QScintillaCharRight, 364 QsciScintilla.SCI_CHARRIGHT: self.__QScintillaCharRight,
353 QsciScintilla.SCI_WORDLEFT: self.__QScintillaWordLeft, 365 QsciScintilla.SCI_WORDLEFT: self.__QScintillaWordLeft,
354 QsciScintilla.SCI_WORDRIGHT: self.__QScintillaWordRight, 366 QsciScintilla.SCI_WORDRIGHT: self.__QScintillaWordRight,
355 QsciScintilla.SCI_VCHOME: self.__QScintillaVCHome, 367 QsciScintilla.SCI_VCHOME: self.__QScintillaVCHome,
356 QsciScintilla.SCI_LINEEND: self.__QScintillaLineEnd, 368 QsciScintilla.SCI_LINEEND: self.__QScintillaLineEnd,
357
358 QsciScintilla.SCI_LINEUP: self.__QScintillaCursorCommand, 369 QsciScintilla.SCI_LINEUP: self.__QScintillaCursorCommand,
359 QsciScintilla.SCI_LINEDOWN: self.__QScintillaCursorCommand, 370 QsciScintilla.SCI_LINEDOWN: self.__QScintillaCursorCommand,
360 QsciScintilla.SCI_LINESCROLLUP: self.__QScintillaCursorCommand, 371 QsciScintilla.SCI_LINESCROLLUP: self.__QScintillaCursorCommand,
361 QsciScintilla.SCI_LINESCROLLDOWN: self.__QScintillaCursorCommand, 372 QsciScintilla.SCI_LINESCROLLDOWN: self.__QScintillaCursorCommand,
362
363 QsciScintilla.SCI_PAGEUP: self.__QScintillaAutoCompletionCommand, 373 QsciScintilla.SCI_PAGEUP: self.__QScintillaAutoCompletionCommand,
364 QsciScintilla.SCI_PAGEDOWN: self.__QScintillaAutoCompletionCommand, 374 QsciScintilla.SCI_PAGEDOWN: self.__QScintillaAutoCompletionCommand,
365
366 QsciScintilla.SCI_CHARLEFTEXTEND: self.__QScintillaCharLeftExtend, 375 QsciScintilla.SCI_CHARLEFTEXTEND: self.__QScintillaCharLeftExtend,
367 QsciScintilla.SCI_CHARRIGHTEXTEND: self.extendSelectionRight, 376 QsciScintilla.SCI_CHARRIGHTEXTEND: self.extendSelectionRight,
368 QsciScintilla.SCI_WORDLEFTEXTEND: self.__QScintillaWordLeftExtend, 377 QsciScintilla.SCI_WORDLEFTEXTEND: self.__QScintillaWordLeftExtend,
369 QsciScintilla.SCI_WORDRIGHTEXTEND: self.extendSelectionWordRight, 378 QsciScintilla.SCI_WORDRIGHTEXTEND: self.extendSelectionWordRight,
370 QsciScintilla.SCI_VCHOMEEXTEND: self.__QScintillaVCHomeExtend, 379 QsciScintilla.SCI_VCHOMEEXTEND: self.__QScintillaVCHomeExtend,
371 QsciScintilla.SCI_LINEENDEXTEND: self.extendSelectionToEOL, 380 QsciScintilla.SCI_LINEENDEXTEND: self.extendSelectionToEOL,
372
373 QsciScintilla.SCI_CANCEL: self.__QScintillaCancel, 381 QsciScintilla.SCI_CANCEL: self.__QScintillaCancel,
374 } 382 }
375 383
376 self.__historyNavigateByCursor = ( 384 self.__historyNavigateByCursor = Preferences.getShell("HistoryNavigateByCursor")
377 Preferences.getShell("HistoryNavigateByCursor") 385
386 self.__queuedText = ""
387 self.__blockTextProcessing = False
388 self.queueText.connect(
389 self.__concatenateText, Qt.ConnectionType.QueuedConnection
378 ) 390 )
379 391
380 self.__queuedText = ''
381 self.__blockTextProcessing = False
382 self.queueText.connect(self.__concatenateText,
383 Qt.ConnectionType.QueuedConnection)
384
385 self.__project = project 392 self.__project = project
386 if self.__project: 393 if self.__project:
387 self.__project.projectOpened.connect(self.__projectOpened) 394 self.__project.projectOpened.connect(self.__projectOpened)
388 self.__project.projectClosed.connect(self.__projectClosed) 395 self.__project.projectClosed.connect(self.__projectClosed)
389 396
390 self.grabGesture(Qt.GestureType.PinchGesture) 397 self.grabGesture(Qt.GestureType.PinchGesture)
391 398
392 def __showStartMenu(self): 399 def __showStartMenu(self):
393 """ 400 """
394 Private slot to prepare the start submenu. 401 Private slot to prepare the start submenu.
395 """ 402 """
396 self.lmenu.clear() 403 self.lmenu.clear()
398 for venvName in sorted(venvManager.getVirtualenvNames()): 405 for venvName in sorted(venvManager.getVirtualenvNames()):
399 self.lmenu.addAction(venvName) 406 self.lmenu.addAction(venvName)
400 if self.__project.isOpen(): 407 if self.__project.isOpen():
401 self.lmenu.addSeparator() 408 self.lmenu.addSeparator()
402 self.lmenu.addAction(self.tr("Project")) 409 self.lmenu.addAction(self.tr("Project"))
403 410
404 def __resizeLinenoMargin(self): 411 def __resizeLinenoMargin(self):
405 """ 412 """
406 Private slot to resize the line numbers margin. 413 Private slot to resize the line numbers margin.
407 """ 414 """
408 linenoMargin = Preferences.getShell("LinenoMargin") 415 linenoMargin = Preferences.getShell("LinenoMargin")
409 if linenoMargin: 416 if linenoMargin:
410 self.setMarginWidth(0, '8' * (len(str(self.lines())) + 1)) 417 self.setMarginWidth(0, "8" * (len(str(self.lines())) + 1))
411 418
412 def closeShell(self): 419 def closeShell(self):
413 """ 420 """
414 Public method to shutdown the shell. 421 Public method to shutdown the shell.
415 """ 422 """
416 for clientType in self.__historyLists: 423 for clientType in self.__historyLists:
417 self.saveHistory(clientType) 424 self.saveHistory(clientType)
418 425
419 def __bindLexer(self, language='Python3'): 426 def __bindLexer(self, language="Python3"):
420 """ 427 """
421 Private slot to set the lexer. 428 Private slot to set the lexer.
422 429
423 @param language lexer language to set (string) 430 @param language lexer language to set (string)
424 """ 431 """
425 self.language = language 432 self.language = language
426 if Preferences.getShell("SyntaxHighlightingEnabled"): 433 if Preferences.getShell("SyntaxHighlightingEnabled"):
427 from . import Lexers 434 from . import Lexers
435
428 self.lexer_ = Lexers.getLexer(self.language, self) 436 self.lexer_ = Lexers.getLexer(self.language, self)
429 else: 437 else:
430 self.lexer_ = None 438 self.lexer_ = None
431 439
432 if self.lexer_ is None: 440 if self.lexer_ is None:
433 self.setLexer(None) 441 self.setLexer(None)
434 font = Preferences.getShell("MonospacedFont") 442 font = Preferences.getShell("MonospacedFont")
435 self.monospacedStyles(font) 443 self.monospacedStyles(font)
436 return 444 return
437 445
438 # get the font for style 0 and set it as the default font 446 # get the font for style 0 and set it as the default font
439 key = 'Scintilla/{0}/style0/font'.format(self.lexer_.language()) 447 key = "Scintilla/{0}/style0/font".format(self.lexer_.language())
440 fdesc = Preferences.getSettings().value(key) 448 fdesc = Preferences.getSettings().value(key)
441 if fdesc is not None: 449 if fdesc is not None:
442 font = QFont([fdesc[0]], int(fdesc[1])) 450 font = QFont([fdesc[0]], int(fdesc[1]))
443 self.lexer_.setDefaultFont(font) 451 self.lexer_.setDefaultFont(font)
444 self.setLexer(self.lexer_) 452 self.setLexer(self.lexer_)
445 self.lexer_.readSettings(Preferences.getSettings(), "Scintilla") 453 self.lexer_.readSettings(Preferences.getSettings(), "Scintilla")
446 if self.lexer_.hasSubstyles(): 454 if self.lexer_.hasSubstyles():
447 self.lexer_.readSubstyles(self) 455 self.lexer_.readSubstyles(self)
448 456
449 # initialize the lexer APIs settings 457 # initialize the lexer APIs settings
450 api = self.vm.getAPIsManager().getAPIs(self.language) 458 api = self.vm.getAPIsManager().getAPIs(self.language)
451 if api is not None: 459 if api is not None:
452 api = api.getQsciAPIs() 460 api = api.getQsciAPIs()
453 if api is not None: 461 if api is not None:
454 self.lexer_.setAPIs(api) 462 self.lexer_.setAPIs(api)
455 463
456 self.lexer_.setDefaultColor(self.lexer_.color(0)) 464 self.lexer_.setDefaultColor(self.lexer_.color(0))
457 self.lexer_.setDefaultPaper(self.lexer_.paper(0)) 465 self.lexer_.setDefaultPaper(self.lexer_.paper(0))
458 466
459 def __setMargin0(self): 467 def __setMargin0(self):
460 """ 468 """
461 Private method to configure margin 0. 469 Private method to configure margin 0.
462 """ 470 """
463 # set the settings for all margins 471 # set the settings for all margins
464 self.setMarginsFont(Preferences.getShell("MarginsFont")) 472 self.setMarginsFont(Preferences.getShell("MarginsFont"))
465 self.setMarginsForegroundColor( 473 self.setMarginsForegroundColor(Preferences.getEditorColour("MarginsForeground"))
466 Preferences.getEditorColour("MarginsForeground")) 474 self.setMarginsBackgroundColor(Preferences.getEditorColour("MarginsBackground"))
467 self.setMarginsBackgroundColor( 475
468 Preferences.getEditorColour("MarginsBackground"))
469
470 # set margin 0 settings 476 # set margin 0 settings
471 linenoMargin = Preferences.getShell("LinenoMargin") 477 linenoMargin = Preferences.getShell("LinenoMargin")
472 self.setMarginLineNumbers(0, linenoMargin) 478 self.setMarginLineNumbers(0, linenoMargin)
473 if linenoMargin: 479 if linenoMargin:
474 self.__resizeLinenoMargin() 480 self.__resizeLinenoMargin()
475 else: 481 else:
476 self.setMarginWidth(0, 0) 482 self.setMarginWidth(0, 0)
477 483
478 # disable margins 1 and 2 484 # disable margins 1 and 2
479 self.setMarginWidth(1, 0) 485 self.setMarginWidth(1, 0)
480 self.setMarginWidth(2, 0) 486 self.setMarginWidth(2, 0)
481 487
482 def __setTextDisplay(self): 488 def __setTextDisplay(self):
483 """ 489 """
484 Private method to configure the text display. 490 Private method to configure the text display.
485 """ 491 """
486 self.setTabWidth(Preferences.getEditor("TabWidth")) 492 self.setTabWidth(Preferences.getEditor("TabWidth"))
487 if Preferences.getEditor("ShowWhitespace"): 493 if Preferences.getEditor("ShowWhitespace"):
488 self.setWhitespaceVisibility( 494 self.setWhitespaceVisibility(QsciScintilla.WhitespaceVisibility.WsVisible)
489 QsciScintilla.WhitespaceVisibility.WsVisible)
490 with contextlib.suppress(AttributeError): 495 with contextlib.suppress(AttributeError):
491 self.setWhitespaceForegroundColor( 496 self.setWhitespaceForegroundColor(
492 Preferences.getEditorColour("WhitespaceForeground")) 497 Preferences.getEditorColour("WhitespaceForeground")
498 )
493 self.setWhitespaceBackgroundColor( 499 self.setWhitespaceBackgroundColor(
494 Preferences.getEditorColour("WhitespaceBackground")) 500 Preferences.getEditorColour("WhitespaceBackground")
495 self.setWhitespaceSize( 501 )
496 Preferences.getEditor("WhitespaceSize")) 502 self.setWhitespaceSize(Preferences.getEditor("WhitespaceSize"))
497 else: 503 else:
498 self.setWhitespaceVisibility( 504 self.setWhitespaceVisibility(QsciScintilla.WhitespaceVisibility.WsInvisible)
499 QsciScintilla.WhitespaceVisibility.WsInvisible)
500 self.setEolVisibility(Preferences.getEditor("ShowEOL")) 505 self.setEolVisibility(Preferences.getEditor("ShowEOL"))
501 if Preferences.getEditor("BraceHighlighting"): 506 if Preferences.getEditor("BraceHighlighting"):
502 self.setBraceMatching(QsciScintilla.BraceMatch.SloppyBraceMatch) 507 self.setBraceMatching(QsciScintilla.BraceMatch.SloppyBraceMatch)
503 else: 508 else:
504 self.setBraceMatching(QsciScintilla.BraceMatch.NoBraceMatch) 509 self.setBraceMatching(QsciScintilla.BraceMatch.NoBraceMatch)
505 self.setMatchedBraceForegroundColor( 510 self.setMatchedBraceForegroundColor(
506 Preferences.getEditorColour("MatchingBrace")) 511 Preferences.getEditorColour("MatchingBrace")
512 )
507 self.setMatchedBraceBackgroundColor( 513 self.setMatchedBraceBackgroundColor(
508 Preferences.getEditorColour("MatchingBraceBack")) 514 Preferences.getEditorColour("MatchingBraceBack")
515 )
509 self.setUnmatchedBraceForegroundColor( 516 self.setUnmatchedBraceForegroundColor(
510 Preferences.getEditorColour("NonmatchingBrace")) 517 Preferences.getEditorColour("NonmatchingBrace")
518 )
511 self.setUnmatchedBraceBackgroundColor( 519 self.setUnmatchedBraceBackgroundColor(
512 Preferences.getEditorColour("NonmatchingBraceBack")) 520 Preferences.getEditorColour("NonmatchingBraceBack")
521 )
513 if Preferences.getEditor("CustomSelectionColours"): 522 if Preferences.getEditor("CustomSelectionColours"):
514 self.setSelectionBackgroundColor( 523 self.setSelectionBackgroundColor(
515 Preferences.getEditorColour("SelectionBackground")) 524 Preferences.getEditorColour("SelectionBackground")
525 )
516 else: 526 else:
517 self.setSelectionBackgroundColor( 527 self.setSelectionBackgroundColor(
518 QApplication.palette().color(QPalette.ColorRole.Highlight)) 528 QApplication.palette().color(QPalette.ColorRole.Highlight)
529 )
519 if Preferences.getEditor("ColourizeSelText"): 530 if Preferences.getEditor("ColourizeSelText"):
520 self.resetSelectionForegroundColor() 531 self.resetSelectionForegroundColor()
521 elif Preferences.getEditor("CustomSelectionColours"): 532 elif Preferences.getEditor("CustomSelectionColours"):
522 self.setSelectionForegroundColor( 533 self.setSelectionForegroundColor(
523 Preferences.getEditorColour("SelectionForeground")) 534 Preferences.getEditorColour("SelectionForeground")
535 )
524 else: 536 else:
525 self.setSelectionForegroundColor( 537 self.setSelectionForegroundColor(
526 QApplication.palette().color( 538 QApplication.palette().color(QPalette.ColorRole.HighlightedText)
527 QPalette.ColorRole.HighlightedText)) 539 )
528 self.setSelectionToEol(Preferences.getEditor("ExtendSelectionToEol")) 540 self.setSelectionToEol(Preferences.getEditor("ExtendSelectionToEol"))
529 self.setCaretForegroundColor( 541 self.setCaretForegroundColor(Preferences.getEditorColour("CaretForeground"))
530 Preferences.getEditorColour("CaretForeground"))
531 self.setCaretLineVisible(False) 542 self.setCaretLineVisible(False)
532 self.caretWidth = Preferences.getEditor("CaretWidth") 543 self.caretWidth = Preferences.getEditor("CaretWidth")
533 self.setCaretWidth(self.caretWidth) 544 self.setCaretWidth(self.caretWidth)
534 if Preferences.getShell("WrapEnabled"): 545 if Preferences.getShell("WrapEnabled"):
535 self.setWrapMode(QsciScintilla.WrapMode.WrapWord) 546 self.setWrapMode(QsciScintilla.WrapMode.WrapWord)
536 else: 547 else:
537 self.setWrapMode(QsciScintilla.WrapMode.WrapNone) 548 self.setWrapMode(QsciScintilla.WrapMode.WrapNone)
538 self.useMonospaced = Preferences.getShell("UseMonospacedFont") 549 self.useMonospaced = Preferences.getShell("UseMonospacedFont")
539 self.__setMonospaced(self.useMonospaced) 550 self.__setMonospaced(self.useMonospaced)
540 551
541 self.setCursorFlashTime(QApplication.cursorFlashTime()) 552 self.setCursorFlashTime(QApplication.cursorFlashTime())
542 553
543 if Preferences.getEditor("OverrideEditAreaColours"): 554 if Preferences.getEditor("OverrideEditAreaColours"):
544 self.setColor(Preferences.getEditorColour("EditAreaForeground")) 555 self.setColor(Preferences.getEditorColour("EditAreaForeground"))
545 self.setPaper(Preferences.getEditorColour("EditAreaBackground")) 556 self.setPaper(Preferences.getEditorColour("EditAreaBackground"))
546 557
547 def __setMonospaced(self, on): 558 def __setMonospaced(self, on):
548 """ 559 """
549 Private method to set/reset a monospaced font. 560 Private method to set/reset a monospaced font.
550 561
551 @param on flag to indicate usage of a monospace font (boolean) 562 @param on flag to indicate usage of a monospace font (boolean)
552 """ 563 """
553 if on: 564 if on:
554 if not self.lexer_: 565 if not self.lexer_:
555 f = Preferences.getShell("MonospacedFont") 566 f = Preferences.getShell("MonospacedFont")
557 else: 568 else:
558 if not self.lexer_: 569 if not self.lexer_:
559 self.clearStyles() 570 self.clearStyles()
560 self.__setMargin0() 571 self.__setMargin0()
561 self.setFont(Preferences.getShell("MonospacedFont")) 572 self.setFont(Preferences.getShell("MonospacedFont"))
562 573
563 self.useMonospaced = on 574 self.useMonospaced = on
564 575
565 def __setAutoCompletion(self, language='Python'): 576 def __setAutoCompletion(self, language="Python"):
566 """ 577 """
567 Private method to configure the autocompletion function. 578 Private method to configure the autocompletion function.
568 579
569 @param language of the autocompletion set to set (string) 580 @param language of the autocompletion set to set (string)
570 """ 581 """
571 self.setAutoCompletionCaseSensitivity( 582 self.setAutoCompletionCaseSensitivity(
572 Preferences.getEditor("AutoCompletionCaseSensitivity")) 583 Preferences.getEditor("AutoCompletionCaseSensitivity")
584 )
573 self.setAutoCompletionThreshold(-1) 585 self.setAutoCompletionThreshold(-1)
574 586
575 self.racEnabled = Preferences.getShell("AutoCompletionEnabled") 587 self.racEnabled = Preferences.getShell("AutoCompletionEnabled")
576 588
577 self.setAutoCompletionWidgetSize( 589 self.setAutoCompletionWidgetSize(
578 Preferences.getEditor("AutoCompletionMaxChars"), 590 Preferences.getEditor("AutoCompletionMaxChars"),
579 Preferences.getEditor("AutoCompletionMaxLines") 591 Preferences.getEditor("AutoCompletionMaxLines"),
580 ) 592 )
581 593
582 def __setCallTips(self, language='Python'): 594 def __setCallTips(self, language="Python"):
583 """ 595 """
584 Private method to configure the calltips function. 596 Private method to configure the calltips function.
585 597
586 @param language of the calltips set to set (string) 598 @param language of the calltips set to set (string)
587 """ 599 """
588 if Preferences.getShell("CallTipsEnabled"): 600 if Preferences.getShell("CallTipsEnabled"):
589 self.setCallTipsBackgroundColor( 601 self.setCallTipsBackgroundColor(
590 Preferences.getEditorColour("CallTipsBackground")) 602 Preferences.getEditorColour("CallTipsBackground")
603 )
591 self.setCallTipsForegroundColor( 604 self.setCallTipsForegroundColor(
592 Preferences.getEditorColour("CallTipsForeground")) 605 Preferences.getEditorColour("CallTipsForeground")
606 )
593 self.setCallTipsHighlightColor( 607 self.setCallTipsHighlightColor(
594 Preferences.getEditorColour("CallTipsHighlight")) 608 Preferences.getEditorColour("CallTipsHighlight")
609 )
595 self.setCallTipsVisible(Preferences.getEditor("CallTipsVisible")) 610 self.setCallTipsVisible(Preferences.getEditor("CallTipsVisible"))
596 calltipsStyle = Preferences.getEditor("CallTipsStyle") 611 calltipsStyle = Preferences.getEditor("CallTipsStyle")
597 if calltipsStyle == QsciScintilla.CallTipsStyle.CallTipsNoContext: 612 if calltipsStyle == QsciScintilla.CallTipsStyle.CallTipsNoContext:
598 self.setCallTipsStyle( 613 self.setCallTipsStyle(QsciScintilla.CallTipsStyle.CallTipsNoContext)
599 QsciScintilla.CallTipsStyle.CallTipsNoContext)
600 elif ( 614 elif (
601 calltipsStyle == 615 calltipsStyle
602 QsciScintilla.CallTipsStyle.CallTipsNoAutoCompletionContext 616 == QsciScintilla.CallTipsStyle.CallTipsNoAutoCompletionContext
603 ): 617 ):
604 self.setCallTipsStyle( 618 self.setCallTipsStyle(
605 QsciScintilla.CallTipsStyle 619 QsciScintilla.CallTipsStyle.CallTipsNoAutoCompletionContext
606 .CallTipsNoAutoCompletionContext) 620 )
607 else: 621 else:
608 self.setCallTipsStyle( 622 self.setCallTipsStyle(QsciScintilla.CallTipsStyle.CallTipsContext)
609 QsciScintilla.CallTipsStyle.CallTipsContext)
610 else: 623 else:
611 self.setCallTipsStyle(QsciScintilla.CallTipsStyle.CallTipsNone) 624 self.setCallTipsStyle(QsciScintilla.CallTipsStyle.CallTipsNone)
612 625
613 def setDebuggerUI(self, ui): 626 def setDebuggerUI(self, ui):
614 """ 627 """
615 Public method to set the debugger UI. 628 Public method to set the debugger UI.
616 629
617 @param ui reference to the debugger UI object (DebugUI) 630 @param ui reference to the debugger UI object (DebugUI)
618 """ 631 """
619 ui.exceptionInterrupt.connect(self.__writePrompt) 632 ui.exceptionInterrupt.connect(self.__writePrompt)
620 self.registerDebuggerIdMethod(ui.getSelectedDebuggerId) 633 self.registerDebuggerIdMethod(ui.getSelectedDebuggerId)
621 634
622 def registerDebuggerIdMethod(self, method): 635 def registerDebuggerIdMethod(self, method):
623 """ 636 """
624 Public method to register a method to get the debugger ID to send data 637 Public method to register a method to get the debugger ID to send data
625 to. 638 to.
626 639
627 @param method reference to the method 640 @param method reference to the method
628 @type function 641 @type function
629 """ 642 """
630 self.__getSelectedDebuggerId = method 643 self.__getSelectedDebuggerId = method
631 644
632 def __initialise(self): 645 def __initialise(self):
633 """ 646 """
634 Private method to get ready for a new remote interpreter. 647 Private method to get ready for a new remote interpreter.
635 """ 648 """
636 self.buff = "" 649 self.buff = ""
640 self.__rawModeDebuggerId = None 653 self.__rawModeDebuggerId = None
641 self.__rawModeQueue = [] 654 self.__rawModeQueue = []
642 self.clientCapabilities = 0 655 self.clientCapabilities = 0
643 self.inCommandExecution = False 656 self.inCommandExecution = False
644 self.interruptCommandExecution = False 657 self.interruptCommandExecution = False
645 658
646 def __clientCapabilities(self, cap, clType, venvName): 659 def __clientCapabilities(self, cap, clType, venvName):
647 """ 660 """
648 Private slot to handle the reporting of the clients capabilities. 661 Private slot to handle the reporting of the clients capabilities.
649 662
650 @param cap client capabilities 663 @param cap client capabilities
651 @type int 664 @type int
652 @param clType type of the debug client 665 @param clType type of the debug client
653 @type str 666 @type str
654 @param venvName name of the virtual environment 667 @param venvName name of the virtual environment
662 self.__setTextDisplay() 675 self.__setTextDisplay()
663 self.__setMargin0() 676 self.__setMargin0()
664 self.__setAutoCompletion(self.clientType) 677 self.__setAutoCompletion(self.clientType)
665 self.__setCallTips(self.clientType) 678 self.__setCallTips(self.clientType)
666 self.racEnabled = ( 679 self.racEnabled = (
667 Preferences.getShell("AutoCompletionEnabled") and 680 Preferences.getShell("AutoCompletionEnabled")
668 (cap & HasCompleter) > 0 681 and (cap & HasCompleter) > 0
669 ) 682 )
670 683
671 if self.clientType not in self.__historyLists: 684 if self.clientType not in self.__historyLists:
672 # load history list 685 # load history list
673 self.loadHistory(self.clientType) 686 self.loadHistory(self.clientType)
674 self.__history = self.__historyLists[self.clientType] 687 self.__history = self.__historyLists[self.clientType]
675 self.__setHistoryIndex() 688 self.__setHistoryIndex()
676 689
677 self.virtualEnvironmentChanged.emit(venvName) 690 self.virtualEnvironmentChanged.emit(venvName)
678 Preferences.setShell("LastVirtualEnvironment", venvName) 691 Preferences.setShell("LastVirtualEnvironment", venvName)
679 692
680 def __setHistoryIndex(self, index=None): 693 def __setHistoryIndex(self, index=None):
681 """ 694 """
682 Private method to set the initial history index. 695 Private method to set the initial history index.
683 696
684 @param index index value to be set 697 @param index index value to be set
685 @type int or None 698 @type int or None
686 """ 699 """
687 if index is None: 700 if index is None:
688 # determine based on history style 701 # determine based on history style
689 if ( 702 if (
690 self.clientType and 703 self.clientType
691 self.__historyStyle == ShellHistoryStyle.WINDOWSSTYLE 704 and self.__historyStyle == ShellHistoryStyle.WINDOWSSTYLE
692 ): 705 ):
693 idx = int(Preferences.getSettings().value( 706 idx = int(
694 "Shell/HistoryIndexes/" + self.clientType, -1)) 707 Preferences.getSettings().value(
708 "Shell/HistoryIndexes/" + self.clientType, -1
709 )
710 )
695 if idx >= len(self.__history): 711 if idx >= len(self.__history):
696 idx = -1 712 idx = -1
697 self.__histidx = idx 713 self.__histidx = idx
698 else: 714 else:
699 self.__histidx = -1 715 self.__histidx = -1
700 else: 716 else:
701 self.__histidx = index 717 self.__histidx = index
702 if self.__histidx >= len(self.__history): 718 if self.__histidx >= len(self.__history):
703 self.__histidx = -1 719 self.__histidx = -1
704 if ( 720 if (
705 self.clientType and 721 self.clientType
706 self.__historyStyle == ShellHistoryStyle.WINDOWSSTYLE 722 and self.__historyStyle == ShellHistoryStyle.WINDOWSSTYLE
707 ): 723 ):
708 Preferences.getSettings().setValue( 724 Preferences.getSettings().setValue(
709 "Shell/HistoryIndexes/" + self.clientType, self.__histidx) 725 "Shell/HistoryIndexes/" + self.clientType, self.__histidx
710 726 )
727
711 def __isHistoryIndexValid(self): 728 def __isHistoryIndexValid(self):
712 """ 729 """
713 Private method to test, if the history index is valid. 730 Private method to test, if the history index is valid.
714 731
715 @return flag indicating validity 732 @return flag indicating validity
716 @rtype bool 733 @rtype bool
717 """ 734 """
718 return (0 <= self.__histidx < len(self.__history)) 735 return 0 <= self.__histidx < len(self.__history)
719 736
720 def getHistoryIndex(self): 737 def getHistoryIndex(self):
721 """ 738 """
722 Public method to get the current value of the history index. 739 Public method to get the current value of the history index.
723 740
724 @return history index 741 @return history index
725 @rtype int 742 @rtype int
726 """ 743 """
727 return self.__histidx 744 return self.__histidx
728 745
729 def loadHistory(self, clientType): 746 def loadHistory(self, clientType):
730 """ 747 """
731 Public method to load the history for the given client type. 748 Public method to load the history for the given client type.
732 749
733 @param clientType type of the debug client (string) 750 @param clientType type of the debug client (string)
734 """ 751 """
735 hl = Preferences.getSettings().value("Shell/Histories/" + clientType) 752 hl = Preferences.getSettings().value("Shell/Histories/" + clientType)
736 if hl is not None: 753 if hl is not None:
737 self.__historyLists[clientType] = hl[-self.__maxHistoryEntries:] 754 self.__historyLists[clientType] = hl[-self.__maxHistoryEntries :]
738 else: 755 else:
739 self.__historyLists[clientType] = [] 756 self.__historyLists[clientType] = []
740 757
741 def reloadHistory(self): 758 def reloadHistory(self):
742 """ 759 """
743 Public method to reload the history of the currently selected client 760 Public method to reload the history of the currently selected client
744 type. 761 type.
745 """ 762 """
746 self.loadHistory(self.clientType) 763 self.loadHistory(self.clientType)
747 self.__history = self.__historyLists[self.clientType] 764 self.__history = self.__historyLists[self.clientType]
748 self.__setHistoryIndex() 765 self.__setHistoryIndex()
749 766
750 def saveHistory(self, clientType): 767 def saveHistory(self, clientType):
751 """ 768 """
752 Public method to save the history for the given client type. 769 Public method to save the history for the given client type.
753 770
754 @param clientType type of the debug client (string) 771 @param clientType type of the debug client (string)
755 """ 772 """
756 if clientType in self.__historyLists: 773 if clientType in self.__historyLists:
757 Preferences.getSettings().setValue( 774 Preferences.getSettings().setValue(
758 "Shell/Histories/" + clientType, 775 "Shell/Histories/" + clientType, self.__historyLists[clientType]
759 self.__historyLists[clientType]) 776 )
760 777
761 def getHistory(self, clientType): 778 def getHistory(self, clientType):
762 """ 779 """
763 Public method to get the history for the given client type. 780 Public method to get the history for the given client type.
764 781
765 @param clientType type of the debug client (string). 782 @param clientType type of the debug client (string).
766 If it is None, the current history is returned. 783 If it is None, the current history is returned.
767 @return reference to the history list (list of strings) 784 @return reference to the history list (list of strings)
768 """ 785 """
769 if clientType is None: 786 if clientType is None:
770 return self.__history 787 return self.__history
771 elif clientType in self.__historyLists: 788 elif clientType in self.__historyLists:
772 return self.__historyLists[clientType] 789 return self.__historyLists[clientType]
773 else: 790 else:
774 return [] 791 return []
775 792
776 def clearHistory(self): 793 def clearHistory(self):
777 """ 794 """
778 Public slot to clear the current history. 795 Public slot to clear the current history.
779 """ 796 """
780 if self.clientType: 797 if self.clientType:
781 self.__historyLists[self.clientType] = [] 798 self.__historyLists[self.clientType] = []
782 self.__history = self.__historyLists[self.clientType] 799 self.__history = self.__historyLists[self.clientType]
783 else: 800 else:
784 self.__history = [] 801 self.__history = []
785 self.__setHistoryIndex(index=-1) 802 self.__setHistoryIndex(index=-1)
786 803
787 def selectHistory(self): 804 def selectHistory(self):
788 """ 805 """
789 Public slot to select a history entry to execute. 806 Public slot to select a history entry to execute.
790 """ 807 """
791 current = self.__histidx 808 current = self.__histidx
792 if current == -1: 809 if current == -1:
793 current = len(self.__history) - 1 810 current = len(self.__history) - 1
794 cmd, ok = QInputDialog.getItem( 811 cmd, ok = QInputDialog.getItem(
795 self, 812 self,
796 self.tr("Select History"), 813 self.tr("Select History"),
797 self.tr("Select the history entry to execute" 814 self.tr("Select the history entry to execute" " (most recent shown last)."),
798 " (most recent shown last)."),
799 self.__history, 815 self.__history,
800 current, False) 816 current,
817 False,
818 )
801 if ok: 819 if ok:
802 self.__insertHistory(cmd) 820 self.__insertHistory(cmd)
803 821
804 def showHistory(self): 822 def showHistory(self):
805 """ 823 """
806 Public slot to show the shell history dialog. 824 Public slot to show the shell history dialog.
807 """ 825 """
808 from .ShellHistoryDialog import ShellHistoryDialog 826 from .ShellHistoryDialog import ShellHistoryDialog
827
809 dlg = ShellHistoryDialog(self.__history, self.vm, self) 828 dlg = ShellHistoryDialog(self.__history, self.vm, self)
810 if dlg.exec() == QDialog.DialogCode.Accepted: 829 if dlg.exec() == QDialog.DialogCode.Accepted:
811 self.__historyLists[self.clientType], idx = dlg.getHistory() 830 self.__historyLists[self.clientType], idx = dlg.getHistory()
812 self.__history = self.__historyLists[self.clientType] 831 self.__history = self.__historyLists[self.clientType]
813 self.__setHistoryIndex(index=idx) 832 self.__setHistoryIndex(index=idx)
814 833
815 def clearAllHistories(self): 834 def clearAllHistories(self):
816 """ 835 """
817 Public method to clear all available histories and sync them. 836 Public method to clear all available histories and sync them.
818 """ 837 """
819 Preferences.getSettings().beginGroup("Shell/Histories") 838 Preferences.getSettings().beginGroup("Shell/Histories")
820 for clientType in Preferences.getSettings().childKeys(): 839 for clientType in Preferences.getSettings().childKeys():
821 self.__historyLists[clientType] = [] 840 self.__historyLists[clientType] = []
822 self.saveHistory(clientType) 841 self.saveHistory(clientType)
823 Preferences.getSettings().endGroup() 842 Preferences.getSettings().endGroup()
824 843
825 self.clearHistory() 844 self.clearHistory()
826 845
827 def getClientType(self): 846 def getClientType(self):
828 """ 847 """
829 Public slot to get the clients type. 848 Public slot to get the clients type.
830 849
831 @return client type (string) 850 @return client type (string)
832 """ 851 """
833 return self.clientType 852 return self.clientType
834 853
835 def __getBanner(self): 854 def __getBanner(self):
836 """ 855 """
837 Private method to get the banner for the remote interpreter. 856 Private method to get the banner for the remote interpreter.
838 857
839 It requests the interpreter version and platform running on the 858 It requests the interpreter version and platform running on the
840 debug client side. 859 debug client side.
841 """ 860 """
842 if self.passive: 861 if self.passive:
843 self.__writeBanner('', '', '', '') 862 self.__writeBanner("", "", "", "")
844 else: 863 else:
845 self.dbs.remoteBanner() 864 self.dbs.remoteBanner()
846 865
847 def __writeBanner(self, version, platform, venvName): 866 def __writeBanner(self, version, platform, venvName):
848 """ 867 """
849 Private method to write a banner with info from the debug client. 868 Private method to write a banner with info from the debug client.
850 869
851 @param version interpreter version string 870 @param version interpreter version string
852 @type str 871 @type str
853 @param platform platform of the remote interpreter 872 @param platform platform of the remote interpreter
854 @type str 873 @type str
855 @param venvName name of the virtual environment 874 @param venvName name of the virtual environment
856 @type str 875 @type str
857 """ 876 """
858 super().clear() 877 super().clear()
859 if self.passive and not self.dbs.isConnected(): 878 if self.passive and not self.dbs.isConnected():
860 self.__write(self.tr('Passive Debug Mode')) 879 self.__write(self.tr("Passive Debug Mode"))
861 self.__write(self.tr('\nNot connected')) 880 self.__write(self.tr("\nNot connected"))
862 else: 881 else:
863 self.__currentVenv = venvName 882 self.__currentVenv = venvName
864 version = version.replace("#", self.tr("No.")) 883 version = version.replace("#", self.tr("No."))
865 if platform != "": 884 if platform != "":
866 self.__write(self.tr('{0} on {1}').format(version, platform)) 885 self.__write(self.tr("{0} on {1}").format(version, platform))
867 else: 886 else:
868 self.__write(version) 887 self.__write(version)
869 if venvName: 888 if venvName:
870 self.__write("\n[{0}]".format(venvName)) 889 self.__write("\n[{0}]".format(venvName))
871 890
872 self.virtualEnvironmentChanged.emit(venvName) 891 self.virtualEnvironmentChanged.emit(venvName)
873 Preferences.setShell("LastVirtualEnvironment", venvName) 892 Preferences.setShell("LastVirtualEnvironment", venvName)
874 self.__write('\n') 893 self.__write("\n")
875 894
876 self.__write(sys.ps1) 895 self.__write(sys.ps1)
877 896
878 def __writePrompt(self): 897 def __writePrompt(self):
879 """ 898 """
880 Private method to write the prompt using a write queue. 899 Private method to write the prompt using a write queue.
881 """ 900 """
882 self.queueText.emit(self.inContinue and sys.ps2 or sys.ps1) 901 self.queueText.emit(self.inContinue and sys.ps2 or sys.ps1)
883 902
884 def __clientStatement(self, more): 903 def __clientStatement(self, more):
885 """ 904 """
886 Private method to handle the response from the debugger client. 905 Private method to handle the response from the debugger client.
887 906
888 @param more flag indicating that more user input is required 907 @param more flag indicating that more user input is required
889 @type bool 908 @type bool
890 """ 909 """
891 if not self.__inRawMode: 910 if not self.__inRawMode:
892 self.inContinue = more 911 self.inContinue = more
893 self.__writePrompt() 912 self.__writePrompt()
894 self.inCommandExecution = False 913 self.inCommandExecution = False
895 914
896 def __clientException(self, exceptionType, exceptionMessage, stackTrace): 915 def __clientException(self, exceptionType, exceptionMessage, stackTrace):
897 """ 916 """
898 Private method to handle an exception of the client. 917 Private method to handle an exception of the client.
899 918
900 @param exceptionType type of exception raised (string) 919 @param exceptionType type of exception raised (string)
901 @param exceptionMessage message given by the exception (string) 920 @param exceptionMessage message given by the exception (string)
902 @param stackTrace list of stack entries (list of string) 921 @param stackTrace list of stack entries (list of string)
903 """ 922 """
904 self .__clientError() 923 self.__clientError()
905 924
906 if ( 925 if (
907 not self.__windowed and 926 not self.__windowed
908 Preferences.getDebugger("ShowExceptionInShell") and 927 and Preferences.getDebugger("ShowExceptionInShell")
909 exceptionType 928 and exceptionType
910 ): 929 ):
911 if stackTrace: 930 if stackTrace:
912 self.__write( 931 self.__write(
913 self.tr('Exception "{0}"\n{1}\nFile: {2}, Line: {3}\n') 932 self.tr('Exception "{0}"\n{1}\nFile: {2}, Line: {3}\n').format(
914 .format(
915 exceptionType, 933 exceptionType,
916 exceptionMessage, 934 exceptionMessage,
917 stackTrace[0][0], 935 stackTrace[0][0],
918 stackTrace[0][1] 936 stackTrace[0][1],
919 ) 937 )
920 ) 938 )
921 else: 939 else:
922 self.__write( 940 self.__write(
923 self.tr('Exception "{0}"\n{1}\n') 941 self.tr('Exception "{0}"\n{1}\n').format(
924 .format( 942 exceptionType, exceptionMessage
925 exceptionType, 943 )
926 exceptionMessage)
927 ) 944 )
928 945
929 def __clientSyntaxError(self, message, filename, lineNo, characterNo): 946 def __clientSyntaxError(self, message, filename, lineNo, characterNo):
930 """ 947 """
931 Private method to handle a syntax error in the debugged program. 948 Private method to handle a syntax error in the debugged program.
932 949
933 @param message message of the syntax error (string) 950 @param message message of the syntax error (string)
934 @param filename translated filename of the syntax error position 951 @param filename translated filename of the syntax error position
935 (string) 952 (string)
936 @param lineNo line number of the syntax error position (integer) 953 @param lineNo line number of the syntax error position (integer)
937 @param characterNo character number of the syntax error position 954 @param characterNo character number of the syntax error position
938 (integer) 955 (integer)
939 """ 956 """
940 self .__clientError() 957 self.__clientError()
941 958
942 if ( 959 if not self.__windowed and Preferences.getDebugger("ShowExceptionInShell"):
943 not self.__windowed and
944 Preferences.getDebugger("ShowExceptionInShell")
945 ):
946 if message is None: 960 if message is None:
947 self.__write(self.tr("Unspecified syntax error.\n")) 961 self.__write(self.tr("Unspecified syntax error.\n"))
948 else: 962 else:
949 self.__write( 963 self.__write(
950 self.tr('Syntax error "{1}" in file {0} at line {2},' 964 self.tr(
951 ' character {3}.\n') 965 'Syntax error "{1}" in file {0} at line {2},'
952 .format(filename, message, lineNo, characterNo) 966 " character {3}.\n"
967 ).format(filename, message, lineNo, characterNo)
953 ) 968 )
954 969
955 def __clientSignal(self, message, filename, lineNo, funcName, funcArgs): 970 def __clientSignal(self, message, filename, lineNo, funcName, funcArgs):
956 """ 971 """
957 Private method to handle a signal generated on the client side. 972 Private method to handle a signal generated on the client side.
958 973
959 @param message message of the syntax error 974 @param message message of the syntax error
960 @type str 975 @type str
961 @param filename translated filename of the syntax error position 976 @param filename translated filename of the syntax error position
962 @type str 977 @type str
963 @param lineNo line number of the syntax error position 978 @param lineNo line number of the syntax error position
966 @type str 981 @type str
967 @param funcArgs function arguments 982 @param funcArgs function arguments
968 @type str 983 @type str
969 """ 984 """
970 self.__clientError() 985 self.__clientError()
971 986
972 self.__write( 987 self.__write(
973 self.tr("""Signal "{0}" generated in file {1} at line {2}.\n""" 988 self.tr(
974 """Function: {3}({4})""") 989 """Signal "{0}" generated in file {1} at line {2}.\n"""
975 .format(message, filename, lineNo, funcName, funcArgs) 990 """Function: {3}({4})"""
991 ).format(message, filename, lineNo, funcName, funcArgs)
976 ) 992 )
977 993
978 def __clientError(self): 994 def __clientError(self):
979 """ 995 """
980 Private method to handle an error in the client. 996 Private method to handle an error in the client.
981 """ 997 """
982 self.inCommandExecution = False 998 self.inCommandExecution = False
983 self.interruptCommandExecution = True 999 self.interruptCommandExecution = True
984 self.inContinue = False 1000 self.inContinue = False
985 1001
986 def __getEndPos(self): 1002 def __getEndPos(self):
987 """ 1003 """
988 Private method to return the line and column of the last character. 1004 Private method to return the line and column of the last character.
989 1005
990 @return tuple of two values (int, int) giving the line and column 1006 @return tuple of two values (int, int) giving the line and column
991 """ 1007 """
992 line = self.lines() - 1 1008 line = self.lines() - 1
993 return (line, len(self.text(line))) 1009 return (line, len(self.text(line)))
994 1010
995 def __writeQueued(self, s): 1011 def __writeQueued(self, s):
996 """ 1012 """
997 Private method to display some text using a write queue. 1013 Private method to display some text using a write queue.
998 1014
999 @param s text to be displayed (string) 1015 @param s text to be displayed (string)
1000 """ 1016 """
1001 self.queueText.emit(s) 1017 self.queueText.emit(s)
1002 1018
1003 def __concatenateText(self, text): 1019 def __concatenateText(self, text):
1004 """ 1020 """
1005 Private slot to queue text and process it in one step. 1021 Private slot to queue text and process it in one step.
1006 1022
1007 @param text text to be appended 1023 @param text text to be appended
1008 @type str 1024 @type str
1009 """ 1025 """
1010 self.__queuedText += text 1026 self.__queuedText += text
1011 if self.__blockTextProcessing: 1027 if self.__blockTextProcessing:
1012 return 1028 return
1013 1029
1014 self.__blockTextProcessing = True 1030 self.__blockTextProcessing = True
1015 # Get all text which is still waiting for output 1031 # Get all text which is still waiting for output
1016 QApplication.processEvents() 1032 QApplication.processEvents()
1017 1033
1018 # Finally process the accumulated text 1034 # Finally process the accumulated text
1019 self.__flushQueuedText() 1035 self.__flushQueuedText()
1020 1036
1021 def __flushQueuedText(self): 1037 def __flushQueuedText(self):
1022 """ 1038 """
1023 Private slot to flush the accumulated text output. 1039 Private slot to flush the accumulated text output.
1024 """ 1040 """
1025 self.__write(self.__queuedText) 1041 self.__write(self.__queuedText)
1026 1042
1027 self.__queuedText = '' 1043 self.__queuedText = ""
1028 self.__blockTextProcessing = False 1044 self.__blockTextProcessing = False
1029 1045
1030 # little trick to get the cursor position registered within QScintilla 1046 # little trick to get the cursor position registered within QScintilla
1031 self.SendScintilla(QsciScintilla.SCI_CHARLEFT) 1047 self.SendScintilla(QsciScintilla.SCI_CHARLEFT)
1032 self.SendScintilla(QsciScintilla.SCI_CHARRIGHT) 1048 self.SendScintilla(QsciScintilla.SCI_CHARRIGHT)
1033 1049
1034 def __write(self, s): 1050 def __write(self, s):
1035 """ 1051 """
1036 Private method to display some text without queuing. 1052 Private method to display some text without queuing.
1037 1053
1038 @param s text to be displayed 1054 @param s text to be displayed
1039 @type str 1055 @type str
1040 """ 1056 """
1041 line, col = self.__getEndPos() 1057 line, col = self.__getEndPos()
1042 self.setCursorPosition(line, col) 1058 self.setCursorPosition(line, col)
1043 self.insert(Utilities.filterAnsiSequences(s)) 1059 self.insert(Utilities.filterAnsiSequences(s))
1044 self.prline, self.prcol = self.getCursorPosition() 1060 self.prline, self.prcol = self.getCursorPosition()
1045 self.ensureCursorVisible() 1061 self.ensureCursorVisible()
1046 self.ensureLineVisible(self.prline) 1062 self.ensureLineVisible(self.prline)
1047 1063
1048 def __writeStdOut(self, s): 1064 def __writeStdOut(self, s):
1049 """ 1065 """
1050 Private method to display some text with StdOut label. 1066 Private method to display some text with StdOut label.
1051 1067
1052 @param s text to be displayed (string) 1068 @param s text to be displayed (string)
1053 """ 1069 """
1054 self.__write(self.tr("StdOut: {0}").format(s)) 1070 self.__write(self.tr("StdOut: {0}").format(s))
1055 1071
1056 def __writeStdErr(self, s): 1072 def __writeStdErr(self, s):
1057 """ 1073 """
1058 Private method to display some text with StdErr label. 1074 Private method to display some text with StdErr label.
1059 1075
1060 @param s text to be displayed (string) 1076 @param s text to be displayed (string)
1061 """ 1077 """
1062 self.__write(self.tr("StdErr: {0}").format(s)) 1078 self.__write(self.tr("StdErr: {0}").format(s))
1063 1079
1064 def __raw_input(self, prompt, echo, debuggerId): 1080 def __raw_input(self, prompt, echo, debuggerId):
1065 """ 1081 """
1066 Private method to handle raw input. 1082 Private method to handle raw input.
1067 1083
1068 @param prompt the input prompt 1084 @param prompt the input prompt
1069 @type str 1085 @type str
1070 @param echo flag indicating an echoing of the input 1086 @param echo flag indicating an echoing of the input
1071 @type bool 1087 @type bool
1072 @param debuggerId ID of the debugger backend 1088 @param debuggerId ID of the debugger backend
1078 else: 1094 else:
1079 self.setFocus() 1095 self.setFocus()
1080 self.__inRawMode = True 1096 self.__inRawMode = True
1081 self.__echoInput = echo 1097 self.__echoInput = echo
1082 self.__rawModeDebuggerId = debuggerId 1098 self.__rawModeDebuggerId = debuggerId
1083 1099
1084 # Get all text which is still waiting for output 1100 # Get all text which is still waiting for output
1085 QApplication.processEvents() 1101 QApplication.processEvents()
1086 self.__flushQueuedText() 1102 self.__flushQueuedText()
1087 1103
1088 self.__write(self.tr("<{0}> {1}").format(debuggerId, prompt)) 1104 self.__write(self.tr("<{0}> {1}").format(debuggerId, prompt))
1089 line, col = self.__getEndPos() 1105 line, col = self.__getEndPos()
1090 self.setCursorPosition(line, col) 1106 self.setCursorPosition(line, col)
1091 buf = self.text(line) 1107 buf = self.text(line)
1092 if buf.startswith(sys.ps1): 1108 if buf.startswith(sys.ps1):
1094 if buf.startswith(sys.ps2): 1110 if buf.startswith(sys.ps2):
1095 buf = buf.replace(sys.ps2, "") 1111 buf = buf.replace(sys.ps2, "")
1096 self.prompt = buf 1112 self.prompt = buf
1097 # move cursor to end of line 1113 # move cursor to end of line
1098 self.moveCursorToEOL() 1114 self.moveCursorToEOL()
1099 1115
1100 def paste(self, lines=None): 1116 def paste(self, lines=None):
1101 """ 1117 """
1102 Public slot to handle the paste action. 1118 Public slot to handle the paste action.
1103 1119
1104 @param lines list of lines to be inserted 1120 @param lines list of lines to be inserted
1105 @type list of str 1121 @type list of str
1106 """ 1122 """
1107 if self.__isCursorOnLastLine(): 1123 if self.__isCursorOnLastLine():
1108 line, col = self.getCursorPosition() 1124 line, col = self.getCursorPosition()
1109 lastLine = self.text(line) 1125 lastLine = self.text(line)
1110 if lastLine.startswith(sys.ps1): 1126 if lastLine.startswith(sys.ps1):
1111 lastLine = lastLine[len(sys.ps1):] 1127 lastLine = lastLine[len(sys.ps1) :]
1112 col -= len(sys.ps1) 1128 col -= len(sys.ps1)
1113 prompt = sys.ps1 1129 prompt = sys.ps1
1114 elif lastLine.startswith(sys.ps2): 1130 elif lastLine.startswith(sys.ps2):
1115 lastLine = lastLine[len(sys.ps2):] 1131 lastLine = lastLine[len(sys.ps2) :]
1116 col -= len(sys.ps2) 1132 col -= len(sys.ps2)
1117 prompt = sys.ps2 1133 prompt = sys.ps2
1118 else: 1134 else:
1119 prompt = "" 1135 prompt = ""
1120 if col < 0: 1136 if col < 0:
1121 col = 0 1137 col = 0
1122 prompt = "" 1138 prompt = ""
1123 1139
1124 # Remove if text is selected 1140 # Remove if text is selected
1125 if self.hasSelectedText(): 1141 if self.hasSelectedText():
1126 lineFrom, indexFrom, lineTo, indexTo = self.getSelection() 1142 lineFrom, indexFrom, lineTo, indexTo = self.getSelection()
1127 if self.text(lineFrom).startswith(sys.ps1): 1143 if self.text(lineFrom).startswith(sys.ps1):
1128 indexFrom -= len(sys.ps1) 1144 indexFrom -= len(sys.ps1)
1135 lastLine = lastLine[:indexFrom] + lastLine[indexTo:] 1151 lastLine = lastLine[:indexFrom] + lastLine[indexTo:]
1136 col = indexFrom 1152 col = indexFrom
1137 1153
1138 self.setCursorPosition(line, len(prompt)) 1154 self.setCursorPosition(line, len(prompt))
1139 self.deleteLineRight() 1155 self.deleteLineRight()
1140 1156
1141 if lines is None: 1157 if lines is None:
1142 lines = QApplication.clipboard().text() 1158 lines = QApplication.clipboard().text()
1143 1159
1144 lines = lastLine[:col] + lines + lastLine[col:] 1160 lines = lastLine[:col] + lines + lastLine[col:]
1145 self.executeLines(lines) 1161 self.executeLines(lines)
1146 line, _ = self.getCursorPosition() 1162 line, _ = self.getCursorPosition()
1147 pos = len(self.text(line)) - (len(lastLine) - col) 1163 pos = len(self.text(line)) - (len(lastLine) - col)
1148 self.setCursorPosition(line, pos) 1164 self.setCursorPosition(line, pos)
1149 1165
1150 def executeLines(self, lines, historyIndex=None): 1166 def executeLines(self, lines, historyIndex=None):
1151 """ 1167 """
1152 Public method to execute a set of lines as multiple commands. 1168 Public method to execute a set of lines as multiple commands.
1153 1169
1154 @param lines multiple lines of text to be executed as 1170 @param lines multiple lines of text to be executed as
1155 single commands 1171 single commands
1156 @type str 1172 @type str
1157 @param historyIndex history index to be set 1173 @param historyIndex history index to be set
1158 @type int 1174 @type int
1159 """ 1175 """
1160 lines = lines.splitlines(True) 1176 lines = lines.splitlines(True)
1161 if not lines: 1177 if not lines:
1162 return 1178 return
1163 1179
1164 indentLen = self.__indentLength(lines[0]) 1180 indentLen = self.__indentLength(lines[0])
1165 for line in lines: 1181 for line in lines:
1166 if line.startswith(sys.ps1): 1182 if line.startswith(sys.ps1):
1167 line = line[len(sys.ps1) + indentLen:] 1183 line = line[len(sys.ps1) + indentLen :]
1168 elif line.startswith(sys.ps2): 1184 elif line.startswith(sys.ps2):
1169 line = line[len(sys.ps2) + indentLen:] 1185 line = line[len(sys.ps2) + indentLen :]
1170 else: 1186 else:
1171 line = line[indentLen:] 1187 line = line[indentLen:]
1172 1188
1173 if line.endswith(("\r\n", "\r", "\n")): 1189 if line.endswith(("\r\n", "\r", "\n")):
1174 fullline = True 1190 fullline = True
1175 cmd = line.rstrip() 1191 cmd = line.rstrip()
1176 else: 1192 else:
1177 fullline = False 1193 fullline = False
1178 1194
1179 self.incrementalSearchActive = True 1195 self.incrementalSearchActive = True
1180 self.__insertTextAtEnd(line) 1196 self.__insertTextAtEnd(line)
1181 if fullline: 1197 if fullline:
1182 self.incrementalSearchActive = False 1198 self.incrementalSearchActive = False
1183 1199
1184 self.__executeCommand(cmd, historyIndex=historyIndex) 1200 self.__executeCommand(cmd, historyIndex=historyIndex)
1185 if self.interruptCommandExecution: 1201 if self.interruptCommandExecution:
1186 self.__executeCommand("") 1202 self.__executeCommand("")
1187 break 1203 break
1188 1204
1189 def __indentLength(self, line): 1205 def __indentLength(self, line):
1190 """ 1206 """
1191 Private method to determine the indentation length of the given line. 1207 Private method to determine the indentation length of the given line.
1192 1208
1193 @param line line to determine the indentation length for 1209 @param line line to determine the indentation length for
1194 @type str 1210 @type str
1195 @return indentation length 1211 @return indentation length
1196 @rtype int 1212 @rtype int
1197 """ 1213 """
1198 if line.startswith(sys.ps1): 1214 if line.startswith(sys.ps1):
1199 line = line[len(sys.ps1):] 1215 line = line[len(sys.ps1) :]
1200 # If line starts with sys.ps2 or neither don't manipulate the line. 1216 # If line starts with sys.ps2 or neither don't manipulate the line.
1201 indentLen = len(line) - len(line.lstrip()) 1217 indentLen = len(line) - len(line.lstrip())
1202 return indentLen 1218 return indentLen
1203 1219
1204 def __clearCurrentLine(self): 1220 def __clearCurrentLine(self):
1205 """ 1221 """
1206 Private method to clear the line containing the cursor. 1222 Private method to clear the line containing the cursor.
1207 """ 1223 """
1208 line, col = self.getCursorPosition() 1224 line, col = self.getCursorPosition()
1212 col = len(sys.ps2) 1228 col = len(sys.ps2)
1213 else: 1229 else:
1214 col = 0 1230 col = 0
1215 self.setCursorPosition(line, col) 1231 self.setCursorPosition(line, col)
1216 self.deleteLineRight() 1232 self.deleteLineRight()
1217 1233
1218 def __insertText(self, s): 1234 def __insertText(self, s):
1219 """ 1235 """
1220 Private method to insert some text at the current cursor position. 1236 Private method to insert some text at the current cursor position.
1221 1237
1222 @param s text to be inserted (string) 1238 @param s text to be inserted (string)
1223 """ 1239 """
1224 line, col = self.getCursorPosition() 1240 line, col = self.getCursorPosition()
1225 self.insertAt(Utilities.filterAnsiSequences(s), line, col) 1241 self.insertAt(Utilities.filterAnsiSequences(s), line, col)
1226 self.setCursorPosition(line, col + len(s)) 1242 self.setCursorPosition(line, col + len(s))
1227 1243
1228 def __insertTextAtEnd(self, s): 1244 def __insertTextAtEnd(self, s):
1229 """ 1245 """
1230 Private method to insert some text at the end of the command line. 1246 Private method to insert some text at the end of the command line.
1231 1247
1232 @param s text to be inserted (string) 1248 @param s text to be inserted (string)
1233 """ 1249 """
1234 line, col = self.__getEndPos() 1250 line, col = self.__getEndPos()
1235 self.setCursorPosition(line, col) 1251 self.setCursorPosition(line, col)
1236 self.insert(Utilities.filterAnsiSequences(s)) 1252 self.insert(Utilities.filterAnsiSequences(s))
1237 self.prline, _ = self.getCursorPosition() 1253 self.prline, _ = self.getCursorPosition()
1238 1254
1239 def __insertTextNoEcho(self, s): 1255 def __insertTextNoEcho(self, s):
1240 """ 1256 """
1241 Private method to insert some text at the end of the buffer without 1257 Private method to insert some text at the end of the buffer without
1242 echoing it. 1258 echoing it.
1243 1259
1244 @param s text to be inserted (string) 1260 @param s text to be inserted (string)
1245 """ 1261 """
1246 self.buff += s 1262 self.buff += s
1247 self.prline, self.prcol = self.getCursorPosition() 1263 self.prline, self.prcol = self.getCursorPosition()
1248 1264
1249 def mousePressEvent(self, event): 1265 def mousePressEvent(self, event):
1250 """ 1266 """
1251 Protected method to handle the mouse press event. 1267 Protected method to handle the mouse press event.
1252 1268
1253 @param event the mouse press event (QMouseEvent) 1269 @param event the mouse press event (QMouseEvent)
1254 """ 1270 """
1255 self.setFocus() 1271 self.setFocus()
1256 if event.button() == Qt.MouseButton.MiddleButton: 1272 if event.button() == Qt.MouseButton.MiddleButton:
1257 lines = QApplication.clipboard().text(QClipboard.Mode.Selection) 1273 lines = QApplication.clipboard().text(QClipboard.Mode.Selection)
1258 self.paste(lines) 1274 self.paste(lines)
1259 else: 1275 else:
1260 super().mousePressEvent(event) 1276 super().mousePressEvent(event)
1261 1277
1262 def wheelEvent(self, evt): 1278 def wheelEvent(self, evt):
1263 """ 1279 """
1264 Protected method to handle wheel events. 1280 Protected method to handle wheel events.
1265 1281
1266 @param evt reference to the wheel event (QWheelEvent) 1282 @param evt reference to the wheel event (QWheelEvent)
1267 """ 1283 """
1268 if evt.modifiers() & Qt.KeyboardModifier.ControlModifier: 1284 if evt.modifiers() & Qt.KeyboardModifier.ControlModifier:
1269 delta = evt.angleDelta().y() 1285 delta = evt.angleDelta().y()
1270 if delta < 0: 1286 if delta < 0:
1271 self.zoomOut() 1287 self.zoomOut()
1272 elif delta > 0: 1288 elif delta > 0:
1273 self.zoomIn() 1289 self.zoomIn()
1274 evt.accept() 1290 evt.accept()
1275 return 1291 return
1276 1292
1277 super().wheelEvent(evt) 1293 super().wheelEvent(evt)
1278 1294
1279 def event(self, evt): 1295 def event(self, evt):
1280 """ 1296 """
1281 Public method handling events. 1297 Public method handling events.
1282 1298
1283 @param evt reference to the event (QEvent) 1299 @param evt reference to the event (QEvent)
1284 @return flag indicating, if the event was handled (boolean) 1300 @return flag indicating, if the event was handled (boolean)
1285 """ 1301 """
1286 if evt.type() == QEvent.Type.Gesture: 1302 if evt.type() == QEvent.Type.Gesture:
1287 self.gestureEvent(evt) 1303 self.gestureEvent(evt)
1288 return True 1304 return True
1289 1305
1290 return super().event(evt) 1306 return super().event(evt)
1291 1307
1292 def gestureEvent(self, evt): 1308 def gestureEvent(self, evt):
1293 """ 1309 """
1294 Protected method handling gesture events. 1310 Protected method handling gesture events.
1295 1311
1296 @param evt reference to the gesture event (QGestureEvent 1312 @param evt reference to the gesture event (QGestureEvent
1297 """ 1313 """
1298 pinch = evt.gesture(Qt.GestureType.PinchGesture) 1314 pinch = evt.gesture(Qt.GestureType.PinchGesture)
1299 if pinch: 1315 if pinch:
1300 if pinch.state() == Qt.GestureState.GestureStarted: 1316 if pinch.state() == Qt.GestureState.GestureStarted:
1308 elif zoom >= 20: 1324 elif zoom >= 20:
1309 zoom = 20 1325 zoom = 20
1310 pinch.setTotalScaleFactor(3.0) 1326 pinch.setTotalScaleFactor(3.0)
1311 self.zoomTo(zoom) 1327 self.zoomTo(zoom)
1312 evt.accept() 1328 evt.accept()
1313 1329
1314 def editorCommand(self, cmd): 1330 def editorCommand(self, cmd):
1315 """ 1331 """
1316 Public method to perform an editor command. 1332 Public method to perform an editor command.
1317 1333
1318 @param cmd the scintilla command to be performed 1334 @param cmd the scintilla command to be performed
1319 """ 1335 """
1320 try: 1336 try:
1321 self.supportedEditorCommands[cmd]() 1337 self.supportedEditorCommands[cmd]()
1322 except TypeError: 1338 except TypeError:
1323 self.supportedEditorCommands[cmd](cmd) 1339 self.supportedEditorCommands[cmd](cmd)
1324 except KeyError: 1340 except KeyError:
1325 pass 1341 pass
1326 1342
1327 def __isCursorOnLastLine(self): 1343 def __isCursorOnLastLine(self):
1328 """ 1344 """
1329 Private method to check, if the cursor is on the last line. 1345 Private method to check, if the cursor is on the last line.
1330 1346
1331 @return flag indicating that the cursor is on the last line (boolean) 1347 @return flag indicating that the cursor is on the last line (boolean)
1332 """ 1348 """
1333 cline, ccol = self.getCursorPosition() 1349 cline, ccol = self.getCursorPosition()
1334 return cline == self.lines() - 1 1350 return cline == self.lines() - 1
1335 1351
1336 def keyPressEvent(self, ev): 1352 def keyPressEvent(self, ev):
1337 """ 1353 """
1338 Protected method to handle the user input a key at a time. 1354 Protected method to handle the user input a key at a time.
1339 1355
1340 @param ev key event (QKeyEvent) 1356 @param ev key event (QKeyEvent)
1341 """ 1357 """
1342 txt = ev.text() 1358 txt = ev.text()
1343 1359
1344 # See it is text to insert. 1360 # See it is text to insert.
1345 if len(txt) and txt >= " ": 1361 if len(txt) and txt >= " ":
1346 if not self.__isCursorOnLastLine(): 1362 if not self.__isCursorOnLastLine():
1347 line, col = self.__getEndPos() 1363 line, col = self.__getEndPos()
1348 self.setCursorPosition(line, col) 1364 self.setCursorPosition(line, col)
1351 ac = self.isListActive() 1367 ac = self.isListActive()
1352 super().keyPressEvent(ev) 1368 super().keyPressEvent(ev)
1353 self.incrementalSearchActive = True 1369 self.incrementalSearchActive = True
1354 if ac and self.racEnabled: 1370 if ac and self.racEnabled:
1355 self.dbs.remoteCompletion( 1371 self.dbs.remoteCompletion(
1356 self.__getSelectedDebuggerId(), 1372 self.__getSelectedDebuggerId(), self.completionText + txt
1357 self.completionText + txt
1358 ) 1373 )
1359 else: 1374 else:
1360 self.__insertTextNoEcho(txt) 1375 self.__insertTextNoEcho(txt)
1361 else: 1376 else:
1362 ev.ignore() 1377 ev.ignore()
1363 1378
1364 def __QScintillaCommand(self, cmd): 1379 def __QScintillaCommand(self, cmd):
1365 """ 1380 """
1366 Private method to send the command to QScintilla. 1381 Private method to send the command to QScintilla.
1367 1382
1368 @param cmd QScintilla command 1383 @param cmd QScintilla command
1369 """ 1384 """
1370 self.SendScintilla(cmd) 1385 self.SendScintilla(cmd)
1371 1386
1372 def __QScintillaTab(self, cmd): 1387 def __QScintillaTab(self, cmd):
1373 """ 1388 """
1374 Private method to handle the Tab key. 1389 Private method to handle the Tab key.
1375 1390
1376 @param cmd QScintilla command 1391 @param cmd QScintilla command
1377 """ 1392 """
1378 if self.isListActive(): 1393 if self.isListActive():
1379 self.SendScintilla(cmd) 1394 self.SendScintilla(cmd)
1380 elif self.__isCursorOnLastLine(): 1395 elif self.__isCursorOnLastLine():
1382 buf = self.text(line) 1397 buf = self.text(line)
1383 if buf.startswith(sys.ps1): 1398 if buf.startswith(sys.ps1):
1384 buf = buf.replace(sys.ps1, "") 1399 buf = buf.replace(sys.ps1, "")
1385 if buf.startswith(sys.ps2): 1400 if buf.startswith(sys.ps2):
1386 buf = buf.replace(sys.ps2, "") 1401 buf = buf.replace(sys.ps2, "")
1387 if self.inContinue and not buf[:index - len(sys.ps2)].strip(): 1402 if self.inContinue and not buf[: index - len(sys.ps2)].strip():
1388 self.SendScintilla(cmd) 1403 self.SendScintilla(cmd)
1389 elif self.racEnabled: 1404 elif self.racEnabled:
1390 self.dbs.remoteCompletion( 1405 self.dbs.remoteCompletion(self.__getSelectedDebuggerId(), buf)
1391 self.__getSelectedDebuggerId(), 1406
1392 buf
1393 )
1394
1395 def __QScintillaLeftDeleteCommand(self, method): 1407 def __QScintillaLeftDeleteCommand(self, method):
1396 """ 1408 """
1397 Private method to handle a QScintilla delete command working to 1409 Private method to handle a QScintilla delete command working to
1398 the left. 1410 the left.
1399 1411
1400 @param method shell method to execute 1412 @param method shell method to execute
1401 """ 1413 """
1402 if self.__isCursorOnLastLine(): 1414 if self.__isCursorOnLastLine():
1403 line, col = self.getCursorPosition() 1415 line, col = self.getCursorPosition()
1404 db = 0 1416 db = 0
1405 ac = self.isListActive() 1417 ac = self.isListActive()
1406 oldLength = len(self.text(line)) 1418 oldLength = len(self.text(line))
1407 1419
1408 if self.text(line).startswith(sys.ps1): 1420 if self.text(line).startswith(sys.ps1):
1409 if col > len(sys.ps1): 1421 if col > len(sys.ps1):
1410 method() 1422 method()
1411 db = 1 1423 db = 1
1412 elif self.text(line).startswith(sys.ps2): 1424 elif self.text(line).startswith(sys.ps2):
1417 method() 1429 method()
1418 db = 1 1430 db = 1
1419 if db and ac and self.racEnabled and self.completionText: 1431 if db and ac and self.racEnabled and self.completionText:
1420 delta = len(self.text(line)) - oldLength 1432 delta = len(self.text(line)) - oldLength
1421 self.dbs.remoteCompletion( 1433 self.dbs.remoteCompletion(
1422 self.__getSelectedDebuggerId(), 1434 self.__getSelectedDebuggerId(), self.completionText[:delta]
1423 self.completionText[:delta]
1424 ) 1435 )
1425 1436
1426 def __QScintillaDeleteBack(self): 1437 def __QScintillaDeleteBack(self):
1427 """ 1438 """
1428 Private method to handle the Backspace key. 1439 Private method to handle the Backspace key.
1429 """ 1440 """
1430 self.__QScintillaLeftDeleteCommand(self.deleteBack) 1441 self.__QScintillaLeftDeleteCommand(self.deleteBack)
1431 1442
1432 def __QScintillaDeleteWordLeft(self): 1443 def __QScintillaDeleteWordLeft(self):
1433 """ 1444 """
1434 Private method to handle the Delete Word Left command. 1445 Private method to handle the Delete Word Left command.
1435 """ 1446 """
1436 self.__QScintillaLeftDeleteCommand(self.deleteWordLeft) 1447 self.__QScintillaLeftDeleteCommand(self.deleteWordLeft)
1437 1448
1438 def __QScintillaDelete(self): 1449 def __QScintillaDelete(self):
1439 """ 1450 """
1440 Private method to handle the delete command. 1451 Private method to handle the delete command.
1441 """ 1452 """
1442 if self.__isCursorOnLastLine(): 1453 if self.__isCursorOnLastLine():
1450 self.delete() 1461 self.delete()
1451 elif indexFrom >= 0: 1462 elif indexFrom >= 0:
1452 self.delete() 1463 self.delete()
1453 else: 1464 else:
1454 self.delete() 1465 self.delete()
1455 1466
1456 def __QScintillaDeleteLineLeft(self): 1467 def __QScintillaDeleteLineLeft(self):
1457 """ 1468 """
1458 Private method to handle the Delete Line Left command. 1469 Private method to handle the Delete Line Left command.
1459 """ 1470 """
1460 if self.__isCursorOnLastLine(): 1471 if self.__isCursorOnLastLine():
1461 if self.isListActive(): 1472 if self.isListActive():
1462 self.cancelList() 1473 self.cancelList()
1463 1474
1464 line, col = self.getCursorPosition() 1475 line, col = self.getCursorPosition()
1465 if self.text(line).startswith(sys.ps1): 1476 if self.text(line).startswith(sys.ps1):
1466 prompt = sys.ps1 1477 prompt = sys.ps1
1467 elif self.text(line).startswith(sys.ps2): 1478 elif self.text(line).startswith(sys.ps2):
1468 prompt = sys.ps2 1479 prompt = sys.ps2
1469 else: 1480 else:
1470 prompt = "" 1481 prompt = ""
1471 1482
1472 self.deleteLineLeft() 1483 self.deleteLineLeft()
1473 self.insertAt(prompt, line, 0) 1484 self.insertAt(prompt, line, 0)
1474 self.setCursorPosition(line, len(prompt)) 1485 self.setCursorPosition(line, len(prompt))
1475 1486
1476 def __QScintillaNewline(self, cmd): 1487 def __QScintillaNewline(self, cmd):
1477 """ 1488 """
1478 Private method to handle the Return key. 1489 Private method to handle the Return key.
1479 1490
1480 @param cmd QScintilla command 1491 @param cmd QScintilla command
1481 """ 1492 """
1482 if self.__isCursorOnLastLine(): 1493 if self.__isCursorOnLastLine():
1483 if self.isListActive(): 1494 if self.isListActive():
1484 self.SendScintilla(cmd) 1495 self.SendScintilla(cmd)
1490 buf = self.text(line) 1501 buf = self.text(line)
1491 if buf.startswith(sys.ps1): 1502 if buf.startswith(sys.ps1):
1492 buf = buf.replace(sys.ps1, "") 1503 buf = buf.replace(sys.ps1, "")
1493 if buf.startswith(sys.ps2): 1504 if buf.startswith(sys.ps2):
1494 buf = buf.replace(sys.ps2, "") 1505 buf = buf.replace(sys.ps2, "")
1495 self.insert('\n') 1506 self.insert("\n")
1496 self.__executeCommand(buf) 1507 self.__executeCommand(buf)
1497 else: 1508 else:
1498 txt = "" 1509 txt = ""
1499 line, col = self.getCursorPosition() 1510 line, col = self.getCursorPosition()
1500 if self.hasSelectedText(): 1511 if self.hasSelectedText():
1503 txt = self.text(line)[indexFrom:].rstrip() 1514 txt = self.text(line)[indexFrom:].rstrip()
1504 elif line == lineTo: 1515 elif line == lineTo:
1505 txt = self.text(line)[:indexTo] 1516 txt = self.text(line)[:indexTo]
1506 else: 1517 else:
1507 txt = self.text(line)[col:].rstrip() 1518 txt = self.text(line)[col:].rstrip()
1508 1519
1509 if txt: 1520 if txt:
1510 line, col = self.__getEndPos() 1521 line, col = self.__getEndPos()
1511 self.setCursorPosition(line, col) 1522 self.setCursorPosition(line, col)
1512 self.insert(txt) 1523 self.insert(txt)
1513 1524
1514 def __QScintillaLeftCommand(self, method, allLinesAllowed=False): 1525 def __QScintillaLeftCommand(self, method, allLinesAllowed=False):
1515 """ 1526 """
1516 Private method to handle a QScintilla command working to the left. 1527 Private method to handle a QScintilla command working to the left.
1517 1528
1518 @param method shell method to execute 1529 @param method shell method to execute
1519 @param allLinesAllowed flag indicating that the command may be executed 1530 @param allLinesAllowed flag indicating that the command may be executed
1520 on any line (boolean) 1531 on any line (boolean)
1521 """ 1532 """
1522 if self.__isCursorOnLastLine() or allLinesAllowed: 1533 if self.__isCursorOnLastLine() or allLinesAllowed:
1529 method() 1540 method()
1530 elif col > 0: 1541 elif col > 0:
1531 method() 1542 method()
1532 else: 1543 else:
1533 method() 1544 method()
1534 1545
1535 def __QScintillaCharLeft(self): 1546 def __QScintillaCharLeft(self):
1536 """ 1547 """
1537 Private method to handle the Cursor Left command. 1548 Private method to handle the Cursor Left command.
1538 """ 1549 """
1539 self.__QScintillaLeftCommand(self.moveCursorLeft) 1550 self.__QScintillaLeftCommand(self.moveCursorLeft)
1540 1551
1541 def __QScintillaWordLeft(self): 1552 def __QScintillaWordLeft(self):
1542 """ 1553 """
1543 Private method to handle the Cursor Word Left command. 1554 Private method to handle the Cursor Word Left command.
1544 """ 1555 """
1545 self.__QScintillaLeftCommand(self.moveCursorWordLeft) 1556 self.__QScintillaLeftCommand(self.moveCursorWordLeft)
1546 1557
1547 def __QScintillaRightCommand(self, method): 1558 def __QScintillaRightCommand(self, method):
1548 """ 1559 """
1549 Private method to handle a QScintilla command working to the right. 1560 Private method to handle a QScintilla command working to the right.
1550 1561
1551 @param method shell method to execute 1562 @param method shell method to execute
1552 """ 1563 """
1553 if self.__isCursorOnLastLine(): 1564 if self.__isCursorOnLastLine():
1554 method() 1565 method()
1555 else: 1566 else:
1556 method() 1567 method()
1557 1568
1558 def __QScintillaCharRight(self): 1569 def __QScintillaCharRight(self):
1559 """ 1570 """
1560 Private method to handle the Cursor Right command. 1571 Private method to handle the Cursor Right command.
1561 """ 1572 """
1562 self.__QScintillaRightCommand(self.moveCursorRight) 1573 self.__QScintillaRightCommand(self.moveCursorRight)
1563 1574
1564 def __QScintillaWordRight(self): 1575 def __QScintillaWordRight(self):
1565 """ 1576 """
1566 Private method to handle the Cursor Word Right command. 1577 Private method to handle the Cursor Word Right command.
1567 """ 1578 """
1568 self.__QScintillaRightCommand(self.moveCursorWordRight) 1579 self.__QScintillaRightCommand(self.moveCursorWordRight)
1569 1580
1570 def __QScintillaDeleteWordRight(self): 1581 def __QScintillaDeleteWordRight(self):
1571 """ 1582 """
1572 Private method to handle the Delete Word Right command. 1583 Private method to handle the Delete Word Right command.
1573 """ 1584 """
1574 self.__QScintillaRightCommand(self.deleteWordRight) 1585 self.__QScintillaRightCommand(self.deleteWordRight)
1575 1586
1576 def __QScintillaDeleteLineRight(self): 1587 def __QScintillaDeleteLineRight(self):
1577 """ 1588 """
1578 Private method to handle the Delete Line Right command. 1589 Private method to handle the Delete Line Right command.
1579 """ 1590 """
1580 self.__QScintillaRightCommand(self.deleteLineRight) 1591 self.__QScintillaRightCommand(self.deleteLineRight)
1581 1592
1582 def __QScintillaVCHome(self, cmd): 1593 def __QScintillaVCHome(self, cmd):
1583 """ 1594 """
1584 Private method to handle the Home key. 1595 Private method to handle the Home key.
1585 1596
1586 @param cmd QScintilla command 1597 @param cmd QScintilla command
1587 """ 1598 """
1588 if self.isListActive(): 1599 if self.isListActive():
1589 self.SendScintilla(cmd) 1600 self.SendScintilla(cmd)
1590 elif self.__isCursorOnLastLine(): 1601 elif self.__isCursorOnLastLine():
1594 elif self.text(line).startswith(sys.ps2): 1605 elif self.text(line).startswith(sys.ps2):
1595 col = len(sys.ps2) 1606 col = len(sys.ps2)
1596 else: 1607 else:
1597 col = 0 1608 col = 0
1598 self.setCursorPosition(line, col) 1609 self.setCursorPosition(line, col)
1599 1610
1600 def __QScintillaLineEnd(self, cmd): 1611 def __QScintillaLineEnd(self, cmd):
1601 """ 1612 """
1602 Private method to handle the End key. 1613 Private method to handle the End key.
1603 1614
1604 @param cmd QScintilla command 1615 @param cmd QScintilla command
1605 """ 1616 """
1606 if self.isListActive(): 1617 if self.isListActive():
1607 self.SendScintilla(cmd) 1618 self.SendScintilla(cmd)
1608 elif self.__isCursorOnLastLine(): 1619 elif self.__isCursorOnLastLine():
1609 self.moveCursorToEOL() 1620 self.moveCursorToEOL()
1610 1621
1611 def __QScintillaCursorCommand(self, cmd): 1622 def __QScintillaCursorCommand(self, cmd):
1612 """ 1623 """
1613 Private method to handle the cursor commands. 1624 Private method to handle the cursor commands.
1614 1625
1615 @param cmd QScintilla command 1626 @param cmd QScintilla command
1616 """ 1627 """
1617 if self.isListActive() or self.isCallTipActive(): 1628 if self.isListActive() or self.isCallTipActive():
1618 if cmd in (QsciScintilla.SCI_LINEUP, QsciScintilla.SCI_LINEDOWN): 1629 if cmd in (QsciScintilla.SCI_LINEUP, QsciScintilla.SCI_LINEDOWN):
1619 self.SendScintilla(cmd) 1630 self.SendScintilla(cmd)
1634 self.__QScintillaLineDown(cmd) 1645 self.__QScintillaLineDown(cmd)
1635 elif cmd == QsciScintilla.SCI_LINESCROLLUP: 1646 elif cmd == QsciScintilla.SCI_LINESCROLLUP:
1636 self.__QScintillaHistoryUp(cmd) 1647 self.__QScintillaHistoryUp(cmd)
1637 elif cmd == QsciScintilla.SCI_LINESCROLLDOWN: 1648 elif cmd == QsciScintilla.SCI_LINESCROLLDOWN:
1638 self.__QScintillaHistoryDown(cmd) 1649 self.__QScintillaHistoryDown(cmd)
1639 1650
1640 def __QScintillaLineUp(self, cmd): 1651 def __QScintillaLineUp(self, cmd):
1641 """ 1652 """
1642 Private method to handle the cursor up command. 1653 Private method to handle the cursor up command.
1643 1654
1644 @param cmd QScintilla command 1655 @param cmd QScintilla command
1645 """ 1656 """
1646 self.SendScintilla(QsciScintilla.SCI_LINEUP) 1657 self.SendScintilla(QsciScintilla.SCI_LINEUP)
1647 1658
1648 def __QScintillaLineDown(self, cmd): 1659 def __QScintillaLineDown(self, cmd):
1649 """ 1660 """
1650 Private method to handle the cursor down command. 1661 Private method to handle the cursor down command.
1651 1662
1652 @param cmd QScintilla command 1663 @param cmd QScintilla command
1653 """ 1664 """
1654 self.SendScintilla(QsciScintilla.SCI_LINEDOWN) 1665 self.SendScintilla(QsciScintilla.SCI_LINEDOWN)
1655 1666
1656 def __QScintillaHistoryUp(self, cmd): 1667 def __QScintillaHistoryUp(self, cmd):
1657 """ 1668 """
1658 Private method to handle the history up command. 1669 Private method to handle the history up command.
1659 1670
1660 @param cmd QScintilla command 1671 @param cmd QScintilla command
1661 """ 1672 """
1662 if self.isHistoryEnabled(): 1673 if self.isHistoryEnabled():
1663 line, col = self.__getEndPos() 1674 line, col = self.__getEndPos()
1664 buf = self.text(line) 1675 buf = self.text(line)
1665 if buf.startswith(sys.ps1): 1676 if buf.startswith(sys.ps1):
1666 buf = buf.replace(sys.ps1, "") 1677 buf = buf.replace(sys.ps1, "")
1667 if buf.startswith(sys.ps2): 1678 if buf.startswith(sys.ps2):
1668 buf = buf.replace(sys.ps2, "") 1679 buf = buf.replace(sys.ps2, "")
1669 if buf and self.incrementalSearchActive: 1680 if buf and self.incrementalSearchActive:
1670 if ( 1681 if self.incrementalSearchString and buf.startswith(
1671 self.incrementalSearchString and 1682 self.incrementalSearchString
1672 buf.startswith(self.incrementalSearchString)
1673 ): 1683 ):
1674 idx, found = self.__rsearchHistory( 1684 idx, found = self.__rsearchHistory(
1675 self.incrementalSearchString, self.__histidx) 1685 self.incrementalSearchString, self.__histidx
1686 )
1676 if found and idx >= 0: 1687 if found and idx >= 0:
1677 self.__setHistoryIndex(index=idx) 1688 self.__setHistoryIndex(index=idx)
1678 self.__useHistory() 1689 self.__useHistory()
1679 else: 1690 else:
1680 idx, found = self.__rsearchHistory(buf) 1691 idx, found = self.__rsearchHistory(buf)
1695 self.__setHistoryIndex(index=len(self.__history) - 1) 1706 self.__setHistoryIndex(index=len(self.__history) - 1)
1696 self.__useHistory() 1707 self.__useHistory()
1697 elif self.__histidx > 0: 1708 elif self.__histidx > 0:
1698 self.__setHistoryIndex(index=self.__histidx - 1) 1709 self.__setHistoryIndex(index=self.__histidx - 1)
1699 self.__useHistory() 1710 self.__useHistory()
1700 1711
1701 def __QScintillaHistoryDown(self, cmd): 1712 def __QScintillaHistoryDown(self, cmd):
1702 """ 1713 """
1703 Private method to handle the history down command. 1714 Private method to handle the history down command.
1704 1715
1705 @param cmd QScintilla command 1716 @param cmd QScintilla command
1706 """ 1717 """
1707 if self.isHistoryEnabled(): 1718 if self.isHistoryEnabled():
1708 line, col = self.__getEndPos() 1719 line, col = self.__getEndPos()
1709 buf = self.text(line) 1720 buf = self.text(line)
1710 if buf.startswith(sys.ps1): 1721 if buf.startswith(sys.ps1):
1711 buf = buf.replace(sys.ps1, "") 1722 buf = buf.replace(sys.ps1, "")
1712 if buf.startswith(sys.ps2): 1723 if buf.startswith(sys.ps2):
1713 buf = buf.replace(sys.ps2, "") 1724 buf = buf.replace(sys.ps2, "")
1714 if buf and self.incrementalSearchActive: 1725 if buf and self.incrementalSearchActive:
1715 if ( 1726 if self.incrementalSearchString and buf.startswith(
1716 self.incrementalSearchString and 1727 self.incrementalSearchString
1717 buf.startswith(self.incrementalSearchString)
1718 ): 1728 ):
1719 idx, found = self.__searchHistory( 1729 idx, found = self.__searchHistory(
1720 self.incrementalSearchString, self.__histidx) 1730 self.incrementalSearchString, self.__histidx
1731 )
1721 if found and idx >= 0: 1732 if found and idx >= 0:
1722 self.__setHistoryIndex(index=idx) 1733 self.__setHistoryIndex(index=idx)
1723 self.__useHistory() 1734 self.__useHistory()
1724 else: 1735 else:
1725 idx, found = self.__searchHistory(buf) 1736 idx, found = self.__searchHistory(buf)
1737 self.__useHistory() 1748 self.__useHistory()
1738 else: 1749 else:
1739 if self.__isHistoryIndexValid(): 1750 if self.__isHistoryIndexValid():
1740 self.__setHistoryIndex(index=self.__histidx + 1) 1751 self.__setHistoryIndex(index=self.__histidx + 1)
1741 self.__useHistory() 1752 self.__useHistory()
1742 1753
1743 def __QScintillaCancel(self): 1754 def __QScintillaCancel(self):
1744 """ 1755 """
1745 Private method to handle the ESC command. 1756 Private method to handle the ESC command.
1746 """ 1757 """
1747 if self.isListActive() or self.isCallTipActive(): 1758 if self.isListActive() or self.isCallTipActive():
1748 self.SendScintilla(QsciScintilla.SCI_CANCEL) 1759 self.SendScintilla(QsciScintilla.SCI_CANCEL)
1749 else: 1760 else:
1750 if self.incrementalSearchActive: 1761 if self.incrementalSearchActive:
1751 self.__resetIncrementalHistorySearch() 1762 self.__resetIncrementalHistorySearch()
1752 self.__insertHistory("") 1763 self.__insertHistory("")
1753 1764
1754 def __QScintillaCharLeftExtend(self): 1765 def __QScintillaCharLeftExtend(self):
1755 """ 1766 """
1756 Private method to handle the Extend Selection Left command. 1767 Private method to handle the Extend Selection Left command.
1757 """ 1768 """
1758 self.__QScintillaLeftCommand(self.extendSelectionLeft, True) 1769 self.__QScintillaLeftCommand(self.extendSelectionLeft, True)
1759 1770
1760 def __QScintillaWordLeftExtend(self): 1771 def __QScintillaWordLeftExtend(self):
1761 """ 1772 """
1762 Private method to handle the Extend Selection Left one word command. 1773 Private method to handle the Extend Selection Left one word command.
1763 """ 1774 """
1764 self.__QScintillaLeftCommand(self.extendSelectionWordLeft, True) 1775 self.__QScintillaLeftCommand(self.extendSelectionWordLeft, True)
1765 1776
1766 def __QScintillaVCHomeExtend(self): 1777 def __QScintillaVCHomeExtend(self):
1767 """ 1778 """
1768 Private method to handle the Extend Selection to start of line command. 1779 Private method to handle the Extend Selection to start of line command.
1769 """ 1780 """
1770 line, col = self.getCursorPosition() 1781 line, col = self.getCursorPosition()
1772 col = len(sys.ps1) 1783 col = len(sys.ps1)
1773 elif self.text(line).startswith(sys.ps2): 1784 elif self.text(line).startswith(sys.ps2):
1774 col = len(sys.ps2) 1785 col = len(sys.ps2)
1775 else: 1786 else:
1776 col = 0 1787 col = 0
1777 1788
1778 self.extendSelectionToBOL() 1789 self.extendSelectionToBOL()
1779 while col > 0: 1790 while col > 0:
1780 self.extendSelectionRight() 1791 self.extendSelectionRight()
1781 col -= 1 1792 col -= 1
1782 1793
1783 def __QScintillaAutoCompletionCommand(self, cmd): 1794 def __QScintillaAutoCompletionCommand(self, cmd):
1784 """ 1795 """
1785 Private method to handle a command for autocompletion only. 1796 Private method to handle a command for autocompletion only.
1786 1797
1787 @param cmd QScintilla command 1798 @param cmd QScintilla command
1788 """ 1799 """
1789 if self.isListActive() or self.isCallTipActive(): 1800 if self.isListActive() or self.isCallTipActive():
1790 self.SendScintilla(cmd) 1801 self.SendScintilla(cmd)
1791 1802
1792 def __executeCommand(self, cmd, historyIndex=None): 1803 def __executeCommand(self, cmd, historyIndex=None):
1793 """ 1804 """
1794 Private slot to execute a command. 1805 Private slot to execute a command.
1795 1806
1796 @param cmd command to be executed by debug client 1807 @param cmd command to be executed by debug client
1797 @type str 1808 @type str
1798 @param historyIndex history index to be set 1809 @param historyIndex history index to be set
1799 @type int 1810 @type int
1800 """ 1811 """
1801 if not self.__inRawMode: 1812 if not self.__inRawMode:
1802 self.inCommandExecution = True 1813 self.inCommandExecution = True
1803 self.interruptCommandExecution = False 1814 self.interruptCommandExecution = False
1804 if not cmd: 1815 if not cmd:
1805 # make sure cmd is a string 1816 # make sure cmd is a string
1806 cmd = '' 1817 cmd = ""
1807 1818
1808 # History Handling 1819 # History Handling
1809 if self.isHistoryEnabled(): 1820 if self.isHistoryEnabled():
1810 if cmd != "" and ( 1821 if cmd != "" and (
1811 len(self.__history) == 0 or self.__history[-1] != cmd): 1822 len(self.__history) == 0 or self.__history[-1] != cmd
1823 ):
1812 if len(self.__history) == self.__maxHistoryEntries: 1824 if len(self.__history) == self.__maxHistoryEntries:
1813 del self.__history[0] 1825 del self.__history[0]
1814 self.__history.append(cmd) 1826 self.__history.append(cmd)
1815 if self.__historyStyle == ShellHistoryStyle.LINUXSTYLE: 1827 if self.__historyStyle == ShellHistoryStyle.LINUXSTYLE:
1816 self.__setHistoryIndex(index=-1) 1828 self.__setHistoryIndex(index=-1)
1817 elif self.__historyStyle == ShellHistoryStyle.WINDOWSSTYLE: 1829 elif self.__historyStyle == ShellHistoryStyle.WINDOWSSTYLE:
1818 if historyIndex is None: 1830 if historyIndex is None:
1819 if ( 1831 if (
1820 self.__histidx - 1 > 0 and 1832 self.__histidx - 1 > 0
1821 cmd != self.__history[self.__histidx - 1] 1833 and cmd != self.__history[self.__histidx - 1]
1822 ): 1834 ):
1823 self.__setHistoryIndex(index=-1) 1835 self.__setHistoryIndex(index=-1)
1824 else: 1836 else:
1825 self.__setHistoryIndex(historyIndex) 1837 self.__setHistoryIndex(historyIndex)
1826 1838
1827 if cmd.startswith("%"): 1839 if cmd.startswith("%"):
1828 if cmd == '%start' or cmd.startswith('%start '): 1840 if cmd == "%start" or cmd.startswith("%start "):
1829 if not self.passive: 1841 if not self.passive:
1830 cmdList = cmd.split(None, 1) 1842 cmdList = cmd.split(None, 1)
1831 if len(cmdList) < 2: 1843 if len(cmdList) < 2:
1832 self.dbs.startClient(False) 1844 self.dbs.startClient(False)
1833 # start default backend 1845 # start default backend
1836 if venvName == self.tr("Project"): 1848 if venvName == self.tr("Project"):
1837 if self.__project.isOpen(): 1849 if self.__project.isOpen():
1838 self.dbs.startClient( 1850 self.dbs.startClient(
1839 False, 1851 False,
1840 forProject=True, 1852 forProject=True,
1841 workingDir=self.__project 1853 workingDir=self.__project.getProjectPath(),
1842 .getProjectPath()
1843 ) 1854 )
1844 self.__currentWorkingDirectory = ( 1855 self.__currentWorkingDirectory = (
1845 self.__project.getProjectPath() 1856 self.__project.getProjectPath()
1846 ) 1857 )
1847 else: 1858 else:
1848 self.dbs.startClient( 1859 self.dbs.startClient(
1849 False, 1860 False,
1850 venvName=self.__currentVenv, 1861 venvName=self.__currentVenv,
1851 workingDir=self 1862 workingDir=self.__currentWorkingDirectory,
1852 .__currentWorkingDirectory
1853 ) 1863 )
1854 # same as reset 1864 # same as reset
1855 else: 1865 else:
1856 self.dbs.startClient(False, venvName=venvName) 1866 self.dbs.startClient(False, venvName=venvName)
1857 self.__currentWorkingDirectory = "" 1867 self.__currentWorkingDirectory = ""
1858 self.__getBanner() 1868 self.__getBanner()
1859 return 1869 return
1860 elif cmd == '%clear': 1870 elif cmd == "%clear":
1861 # Display the banner. 1871 # Display the banner.
1862 self.__getBanner() 1872 self.__getBanner()
1863 if not self.passive: 1873 if not self.passive:
1864 return 1874 return
1865 else: 1875 else:
1866 cmd = '' 1876 cmd = ""
1867 elif cmd in ['%reset', '%restart']: 1877 elif cmd in ["%reset", "%restart"]:
1868 self.dbs.startClient( 1878 self.dbs.startClient(
1869 False, venvName=self.__currentVenv, 1879 False,
1870 workingDir=self.__currentWorkingDirectory) 1880 venvName=self.__currentVenv,
1881 workingDir=self.__currentWorkingDirectory,
1882 )
1871 if self.passive: 1883 if self.passive:
1872 return 1884 return
1873 else: 1885 else:
1874 cmd = '' 1886 cmd = ""
1875 elif cmd in ['%envs', '%environments']: 1887 elif cmd in ["%envs", "%environments"]:
1876 venvs = ( 1888 venvs = (
1877 ericApp().getObject("VirtualEnvManager") 1889 ericApp().getObject("VirtualEnvManager").getVirtualenvNames()
1878 .getVirtualenvNames()
1879 ) 1890 )
1880 s = ( 1891 s = self.tr("Available Virtual Environments:\n{0}\n").format(
1881 self.tr('Available Virtual Environments:\n{0}\n') 1892 "\n".join("- {0}".format(venv) for venv in sorted(venvs))
1882 .format('\n'.join(
1883 "- {0}".format(venv)
1884 for venv in sorted(venvs)
1885 ))
1886 ) 1893 )
1887 self.__write(s) 1894 self.__write(s)
1888 self.__clientStatement(False) 1895 self.__clientStatement(False)
1889 return 1896 return
1890 elif cmd == '%which': 1897 elif cmd == "%which":
1891 s = self.tr("Current Virtual Environment: '{0}'\n").format( 1898 s = self.tr("Current Virtual Environment: '{0}'\n").format(
1892 self.__currentVenv) 1899 self.__currentVenv
1900 )
1893 self.__write(s) 1901 self.__write(s)
1894 self.__clientStatement(False) 1902 self.__clientStatement(False)
1895 return 1903 return
1896 elif ( 1904 elif (
1897 cmd in ["%quit", "%quit()", "%exit", "%exit()"] and 1905 cmd in ["%quit", "%quit()", "%exit", "%exit()"] and self.__windowed
1898 self.__windowed
1899 ): 1906 ):
1900 # call main window quit() 1907 # call main window quit()
1901 self.vm.quit() 1908 self.vm.quit()
1902 return 1909 return
1903 else: 1910 else:
1904 self.dbs.remoteStatement( 1911 self.dbs.remoteStatement(self.__getSelectedDebuggerId(), cmd)
1905 self.__getSelectedDebuggerId(), cmd)
1906 while self.inCommandExecution: 1912 while self.inCommandExecution:
1907 with contextlib.suppress(KeyboardInterrupt): 1913 with contextlib.suppress(KeyboardInterrupt):
1908 QApplication.processEvents() 1914 QApplication.processEvents()
1909 else: 1915 else:
1910 if not self.__echoInput: 1916 if not self.__echoInput:
1911 cmd = self.buff 1917 cmd = self.buff
1912 self.buff = "" 1918 self.buff = ""
1913 elif cmd: 1919 elif cmd:
1914 cmd = cmd[len(self.prompt):] 1920 cmd = cmd[len(self.prompt) :]
1915 self.__inRawMode = False 1921 self.__inRawMode = False
1916 self.__echoInput = True 1922 self.__echoInput = True
1917 1923
1918 self.dbs.remoteRawInput(self.__rawModeDebuggerId, cmd) 1924 self.dbs.remoteRawInput(self.__rawModeDebuggerId, cmd)
1919 1925
1920 if self.__rawModeQueue: 1926 if self.__rawModeQueue:
1921 debuggerId, prompt, echo = self.__rawModeQueue.pop(0) 1927 debuggerId, prompt, echo = self.__rawModeQueue.pop(0)
1922 self.__raw_input(prompt, echo, debuggerId) 1928 self.__raw_input(prompt, echo, debuggerId)
1923 1929
1924 def __showVenvName(self): 1930 def __showVenvName(self):
1925 """ 1931 """
1926 Private method to show the name of the active virtual environment. 1932 Private method to show the name of the active virtual environment.
1927 """ 1933 """
1928 s = "\n" + self.tr("Current Virtual Environment: '{0}'\n").format( 1934 s = "\n" + self.tr("Current Virtual Environment: '{0}'\n").format(
1929 self.__currentVenv) 1935 self.__currentVenv
1936 )
1930 self.__write(s) 1937 self.__write(s)
1931 self.__clientStatement(False) 1938 self.__clientStatement(False)
1932 1939
1933 def __useHistory(self): 1940 def __useHistory(self):
1934 """ 1941 """
1935 Private method to display a command from the history. 1942 Private method to display a command from the history.
1936 """ 1943 """
1937 if self.__isHistoryIndexValid(): 1944 if self.__isHistoryIndexValid():
1938 cmd = self.__history[self.__histidx] 1945 cmd = self.__history[self.__histidx]
1939 else: 1946 else:
1940 cmd = "" 1947 cmd = ""
1941 self.__resetIncrementalHistorySearch() 1948 self.__resetIncrementalHistorySearch()
1942 1949
1943 self.__insertHistory(cmd) 1950 self.__insertHistory(cmd)
1944 1951
1945 def __insertHistory(self, cmd): 1952 def __insertHistory(self, cmd):
1946 """ 1953 """
1947 Private method to insert a command selected from the history. 1954 Private method to insert a command selected from the history.
1948 1955
1949 @param cmd history entry to be inserted (string) 1956 @param cmd history entry to be inserted (string)
1950 """ 1957 """
1951 self.setCursorPosition(self.prline, self.prcol) 1958 self.setCursorPosition(self.prline, self.prcol)
1952 self.setSelection(self.prline, self.prcol, 1959 self.setSelection(
1953 self.prline, self.lineLength(self.prline)) 1960 self.prline, self.prcol, self.prline, self.lineLength(self.prline)
1961 )
1954 self.removeSelectedText() 1962 self.removeSelectedText()
1955 self.__insertText(cmd) 1963 self.__insertText(cmd)
1956 1964
1957 def __resetIncrementalHistorySearch(self): 1965 def __resetIncrementalHistorySearch(self):
1958 """ 1966 """
1959 Private method to reset the incremental history search. 1967 Private method to reset the incremental history search.
1960 """ 1968 """
1961 self.incrementalSearchString = "" 1969 self.incrementalSearchString = ""
1962 self.incrementalSearchActive = False 1970 self.incrementalSearchActive = False
1963 1971
1964 def __searchHistory(self, txt, startIdx=-1): 1972 def __searchHistory(self, txt, startIdx=-1):
1965 """ 1973 """
1966 Private method used to search the history. 1974 Private method used to search the history.
1967 1975
1968 @param txt text to match at the beginning 1976 @param txt text to match at the beginning
1969 @type str 1977 @type str
1970 @param startIdx index to start search from 1978 @param startIdx index to start search from
1971 @type int 1979 @type int
1972 @return tuple containing the index of found entry and a flag indicating 1980 @return tuple containing the index of found entry and a flag indicating
1973 that something was found 1981 that something was found
1974 @rtype tuple of (int, bool) 1982 @rtype tuple of (int, bool)
1975 """ 1983 """
1976 idx = 0 if startIdx == -1 else startIdx + 1 1984 idx = 0 if startIdx == -1 else startIdx + 1
1977 while ( 1985 while idx < len(self.__history) and not self.__history[idx].startswith(txt):
1978 idx < len(self.__history) and
1979 not self.__history[idx].startswith(txt)
1980 ):
1981 idx += 1 1986 idx += 1
1982 found = (idx < len(self.__history) and 1987 found = idx < len(self.__history) and self.__history[idx].startswith(txt)
1983 self.__history[idx].startswith(txt))
1984 return idx, found 1988 return idx, found
1985 1989
1986 def __rsearchHistory(self, txt, startIdx=-1): 1990 def __rsearchHistory(self, txt, startIdx=-1):
1987 """ 1991 """
1988 Private method used to reverse search the history. 1992 Private method used to reverse search the history.
1989 1993
1990 @param txt text to match at the beginning 1994 @param txt text to match at the beginning
1991 @type str 1995 @type str
1992 @param startIdx index to start search from 1996 @param startIdx index to start search from
1993 @type int 1997 @type int
1994 @return tuple containing the index of found entry and a flag indicating 1998 @return tuple containing the index of found entry and a flag indicating
1995 that something was found 1999 that something was found
1996 @rtype tuple of (int, bool) 2000 @rtype tuple of (int, bool)
1997 """ 2001 """
1998 idx = len(self.__history) - 1 if startIdx == -1 else startIdx - 1 2002 idx = len(self.__history) - 1 if startIdx == -1 else startIdx - 1
1999 while ( 2003 while idx >= 0 and not self.__history[idx].startswith(txt):
2000 idx >= 0 and
2001 not self.__history[idx].startswith(txt)
2002 ):
2003 idx -= 1 2004 idx -= 1
2004 found = idx >= 0 and self.__history[idx].startswith(txt) 2005 found = idx >= 0 and self.__history[idx].startswith(txt)
2005 return idx, found 2006 return idx, found
2006 2007
2007 def focusNextPrevChild(self, nextChild): 2008 def focusNextPrevChild(self, nextChild):
2008 """ 2009 """
2009 Public method to stop Tab moving to the next window. 2010 Public method to stop Tab moving to the next window.
2010 2011
2011 While the user is entering a multi-line command, the movement to 2012 While the user is entering a multi-line command, the movement to
2012 the next window by the Tab key being pressed is suppressed. 2013 the next window by the Tab key being pressed is suppressed.
2013 2014
2014 @param nextChild next window 2015 @param nextChild next window
2015 @return flag indicating the movement 2016 @return flag indicating the movement
2016 """ 2017 """
2017 if nextChild and self.inContinue: 2018 if nextChild and self.inContinue:
2018 return False 2019 return False
2019 2020
2020 return QsciScintillaCompat.focusNextPrevChild(self, nextChild) 2021 return QsciScintillaCompat.focusNextPrevChild(self, nextChild)
2021 2022
2022 def contextMenuEvent(self, ev): 2023 def contextMenuEvent(self, ev):
2023 """ 2024 """
2024 Protected method to show our own context menu. 2025 Protected method to show our own context menu.
2025 2026
2026 @param ev context menu event (QContextMenuEvent) 2027 @param ev context menu event (QContextMenuEvent)
2027 """ 2028 """
2028 if not self.__windowed: 2029 if not self.__windowed:
2029 self.menu.popup(ev.globalPos()) 2030 self.menu.popup(ev.globalPos())
2030 ev.accept() 2031 ev.accept()
2031 2032
2032 def clear(self): 2033 def clear(self):
2033 """ 2034 """
2034 Public slot to clear the display. 2035 Public slot to clear the display.
2035 """ 2036 """
2036 # Display the banner. 2037 # Display the banner.
2037 self.__getBanner() 2038 self.__getBanner()
2038 2039
2039 def doClearRestart(self): 2040 def doClearRestart(self):
2040 """ 2041 """
2041 Public slot to handle the 'restart and clear' context menu entry. 2042 Public slot to handle the 'restart and clear' context menu entry.
2042 """ 2043 """
2043 self.doRestart() 2044 self.doRestart()
2044 self.clear() 2045 self.clear()
2045 2046
2046 def doRestart(self): 2047 def doRestart(self):
2047 """ 2048 """
2048 Public slot to handle the 'restart' context menu entry. 2049 Public slot to handle the 'restart' context menu entry.
2049 """ 2050 """
2050 self.dbs.startClient(False, venvName=self.__currentVenv, 2051 self.dbs.startClient(
2051 workingDir=self.__currentWorkingDirectory) 2052 False,
2052 2053 venvName=self.__currentVenv,
2054 workingDir=self.__currentWorkingDirectory,
2055 )
2056
2053 def __startDebugClient(self, action): 2057 def __startDebugClient(self, action):
2054 """ 2058 """
2055 Private slot to start a debug client according to the action 2059 Private slot to start a debug client according to the action
2056 triggered. 2060 triggered.
2057 2061
2058 @param action context menu action that was triggered (QAction) 2062 @param action context menu action that was triggered (QAction)
2059 """ 2063 """
2060 venvName = action.text() 2064 venvName = action.text()
2061 if venvName == self.tr("Project"): 2065 if venvName == self.tr("Project"):
2062 if self.__project.isOpen(): 2066 if self.__project.isOpen():
2063 self.__currentWorkingDirectory = ( 2067 self.__currentWorkingDirectory = self.__project.getProjectPath()
2064 self.__project.getProjectPath() 2068 self.dbs.startClient(
2065 ) 2069 False, forProject=True, workingDir=self.__currentWorkingDirectory
2066 self.dbs.startClient(False, forProject=True, 2070 )
2067 workingDir=self.__currentWorkingDirectory)
2068 else: 2071 else:
2069 self.dbs.startClient(False, venvName=venvName) 2072 self.dbs.startClient(False, venvName=venvName)
2070 self.__getBanner() 2073 self.__getBanner()
2071 2074
2072 def handlePreferencesChanged(self): 2075 def handlePreferencesChanged(self):
2073 """ 2076 """
2074 Public slot to handle the preferencesChanged signal. 2077 Public slot to handle the preferencesChanged signal.
2075 """ 2078 """
2076 # rebind the lexer 2079 # rebind the lexer
2077 self.__bindLexer(self.language) 2080 self.__bindLexer(self.language)
2078 self.recolor() 2081 self.recolor()
2079 2082
2080 # set margin 0 configuration 2083 # set margin 0 configuration
2081 self.__setTextDisplay() 2084 self.__setTextDisplay()
2082 self.__setMargin0() 2085 self.__setMargin0()
2083 2086
2084 # set the autocompletion and calltips function 2087 # set the autocompletion and calltips function
2085 self.__setAutoCompletion() 2088 self.__setAutoCompletion()
2086 self.__setCallTips() 2089 self.__setCallTips()
2087 2090
2088 # do the history related stuff 2091 # do the history related stuff
2089 self.__maxHistoryEntries = Preferences.getShell("MaxHistoryEntries") 2092 self.__maxHistoryEntries = Preferences.getShell("MaxHistoryEntries")
2090 for key in list(self.__historyLists.keys()): 2093 for key in list(self.__historyLists.keys()):
2091 self.__historyLists[key] = ( 2094 self.__historyLists[key] = self.__historyLists[key][
2092 self.__historyLists[key][-self.__maxHistoryEntries:] 2095 -self.__maxHistoryEntries :
2093 ) 2096 ]
2094 self.__historyStyle = Preferences.getShell("HistoryStyle") 2097 self.__historyStyle = Preferences.getShell("HistoryStyle")
2095 self.__historyWrap = Preferences.getShell("HistoryWrap") 2098 self.__historyWrap = Preferences.getShell("HistoryWrap")
2096 self.__setHistoryIndex() 2099 self.__setHistoryIndex()
2097 if not self.__windowed: 2100 if not self.__windowed:
2098 self.hmenu.menuAction().setEnabled(self.isHistoryEnabled()) 2101 self.hmenu.menuAction().setEnabled(self.isHistoryEnabled())
2099 self.__historyNavigateByCursor = Preferences.getShell( 2102 self.__historyNavigateByCursor = Preferences.getShell("HistoryNavigateByCursor")
2100 "HistoryNavigateByCursor")
2101 self.historyStyleChanged.emit(self.__historyStyle) 2103 self.historyStyleChanged.emit(self.__historyStyle)
2102 2104
2103 # do stdout /stderr stuff 2105 # do stdout /stderr stuff
2104 showStdOutErr = Preferences.getShell("ShowStdOutErr") 2106 showStdOutErr = Preferences.getShell("ShowStdOutErr")
2105 if self.__showStdOutErr != showStdOutErr: 2107 if self.__showStdOutErr != showStdOutErr:
2106 if showStdOutErr: 2108 if showStdOutErr:
2107 self.dbs.clientProcessStdout.connect(self.__writeStdOut) 2109 self.dbs.clientProcessStdout.connect(self.__writeStdOut)
2108 self.dbs.clientProcessStderr.connect(self.__writeStdErr) 2110 self.dbs.clientProcessStderr.connect(self.__writeStdErr)
2109 else: 2111 else:
2110 self.dbs.clientProcessStdout.disconnect(self.__writeStdOut) 2112 self.dbs.clientProcessStdout.disconnect(self.__writeStdOut)
2111 self.dbs.clientProcessStderr.disconnect(self.__writeStdErr) 2113 self.dbs.clientProcessStderr.disconnect(self.__writeStdErr)
2112 self.__showStdOutErr = showStdOutErr 2114 self.__showStdOutErr = showStdOutErr
2113 2115
2114 @pyqtSlot(list, str) 2116 @pyqtSlot(list, str)
2115 def __showCompletions(self, completions, text): 2117 def __showCompletions(self, completions, text):
2116 """ 2118 """
2117 Private method to display the possible completions. 2119 Private method to display the possible completions.
2118 2120
2119 @param completions list of possible completions (list of strings) 2121 @param completions list of possible completions (list of strings)
2120 @param text text that is about to be completed (string) 2122 @param text text that is about to be completed (string)
2121 """ 2123 """
2122 if len(completions) == 0: 2124 if len(completions) == 0:
2123 return 2125 return
2124 2126
2125 if len(completions) > 1: 2127 if len(completions) > 1:
2126 completions.sort() 2128 completions.sort()
2127 self.showUserList(1, completions) 2129 self.showUserList(1, completions)
2128 self.completionText = text 2130 self.completionText = text
2129 else: 2131 else:
2130 txt = completions[0] 2132 txt = completions[0]
2131 if text != "": 2133 if text != "":
2132 txt = txt.replace(text, "") 2134 txt = txt.replace(text, "")
2133 self.__insertText(txt) 2135 self.__insertText(txt)
2134 self.completionText = "" 2136 self.completionText = ""
2135 2137
2136 def __completionListSelected(self, listId, txt): 2138 def __completionListSelected(self, listId, txt):
2137 """ 2139 """
2138 Private slot to handle the selection from the completion list. 2140 Private slot to handle the selection from the completion list.
2139 2141
2140 @param listId the ID of the user list (should be 1) (integer) 2142 @param listId the ID of the user list (should be 1) (integer)
2141 @param txt the selected text (string) 2143 @param txt the selected text (string)
2142 """ 2144 """
2143 if listId == 1: 2145 if listId == 1:
2144 if self.completionText != "": 2146 if self.completionText != "":
2145 txt = txt.replace(self.completionText, "") 2147 txt = txt.replace(self.completionText, "")
2146 self.__insertText(txt) 2148 self.__insertText(txt)
2147 self.completionText = "" 2149 self.completionText = ""
2148 2150
2149 ################################################################# 2151 #################################################################
2150 ## Drag and Drop Support 2152 ## Drag and Drop Support
2151 ################################################################# 2153 #################################################################
2152 2154
2153 def dragEnterEvent(self, event): 2155 def dragEnterEvent(self, event):
2154 """ 2156 """
2155 Protected method to handle the drag enter event. 2157 Protected method to handle the drag enter event.
2156 2158
2157 @param event the drag enter event (QDragEnterEvent) 2159 @param event the drag enter event (QDragEnterEvent)
2158 """ 2160 """
2159 self.inDragDrop = ( 2161 self.inDragDrop = event.mimeData().hasUrls() or event.mimeData().hasText()
2160 event.mimeData().hasUrls() or
2161 event.mimeData().hasText()
2162 )
2163 if self.inDragDrop: 2162 if self.inDragDrop:
2164 event.acceptProposedAction() 2163 event.acceptProposedAction()
2165 else: 2164 else:
2166 super().dragEnterEvent(event) 2165 super().dragEnterEvent(event)
2167 2166
2168 def dragMoveEvent(self, event): 2167 def dragMoveEvent(self, event):
2169 """ 2168 """
2170 Protected method to handle the drag move event. 2169 Protected method to handle the drag move event.
2171 2170
2172 @param event the drag move event (QDragMoveEvent) 2171 @param event the drag move event (QDragMoveEvent)
2173 """ 2172 """
2174 if self.inDragDrop: 2173 if self.inDragDrop:
2175 event.accept() 2174 event.accept()
2176 else: 2175 else:
2177 super().dragMoveEvent(event) 2176 super().dragMoveEvent(event)
2178 2177
2179 def dragLeaveEvent(self, event): 2178 def dragLeaveEvent(self, event):
2180 """ 2179 """
2181 Protected method to handle the drag leave event. 2180 Protected method to handle the drag leave event.
2182 2181
2183 @param event the drag leave event (QDragLeaveEvent) 2182 @param event the drag leave event (QDragLeaveEvent)
2184 """ 2183 """
2185 if self.inDragDrop: 2184 if self.inDragDrop:
2186 self.inDragDrop = False 2185 self.inDragDrop = False
2187 event.accept() 2186 event.accept()
2188 else: 2187 else:
2189 super().dragLeaveEvent(event) 2188 super().dragLeaveEvent(event)
2190 2189
2191 def dropEvent(self, event): 2190 def dropEvent(self, event):
2192 """ 2191 """
2193 Protected method to handle the drop event. 2192 Protected method to handle the drop event.
2194 2193
2195 @param event the drop event (QDropEvent) 2194 @param event the drop event (QDropEvent)
2196 """ 2195 """
2197 if event.mimeData().hasUrls() and not self.__windowed: 2196 if event.mimeData().hasUrls() and not self.__windowed:
2198 for url in event.mimeData().urls(): 2197 for url in event.mimeData().urls():
2199 fname = url.toLocalFile() 2198 fname = url.toLocalFile()
2202 self.vm.openSourceFile(fname) 2201 self.vm.openSourceFile(fname)
2203 else: 2202 else:
2204 EricMessageBox.information( 2203 EricMessageBox.information(
2205 self, 2204 self,
2206 self.tr("Drop Error"), 2205 self.tr("Drop Error"),
2207 self.tr("""<p><b>{0}</b> is not a file.</p>""") 2206 self.tr("""<p><b>{0}</b> is not a file.</p>""").format(
2208 .format(fname)) 2207 fname
2208 ),
2209 )
2209 event.acceptProposedAction() 2210 event.acceptProposedAction()
2210 elif event.mimeData().hasText(): 2211 elif event.mimeData().hasText():
2211 s = event.mimeData().text() 2212 s = event.mimeData().text()
2212 if s: 2213 if s:
2213 event.acceptProposedAction() 2214 event.acceptProposedAction()
2214 self.executeLines(s) 2215 self.executeLines(s)
2215 del s 2216 del s
2216 else: 2217 else:
2217 super().dropEvent(event) 2218 super().dropEvent(event)
2218 2219
2219 self.inDragDrop = False 2220 self.inDragDrop = False
2220 2221
2221 def focusInEvent(self, event): 2222 def focusInEvent(self, event):
2222 """ 2223 """
2223 Protected method called when the shell receives focus. 2224 Protected method called when the shell receives focus.
2224 2225
2225 @param event the event object (QFocusEvent) 2226 @param event the event object (QFocusEvent)
2226 """ 2227 """
2227 if not self.__actionsAdded: 2228 if not self.__actionsAdded:
2228 self.addActions(self.vm.editorActGrp.actions()) 2229 self.addActions(self.vm.editorActGrp.actions())
2229 self.addActions(self.vm.copyActGrp.actions()) 2230 self.addActions(self.vm.copyActGrp.actions())
2230 self.addActions(self.vm.viewActGrp.actions()) 2231 self.addActions(self.vm.viewActGrp.actions())
2231 if not self.__windowed: 2232 if not self.__windowed:
2232 self.__searchShortcut = QShortcut( 2233 self.__searchShortcut = QShortcut(
2233 self.vm.searchAct.shortcut(), self, 2234 self.vm.searchAct.shortcut(), self, self.__find, self.__find
2234 self.__find, self.__find) 2235 )
2235 self.__searchNextShortcut = QShortcut( 2236 self.__searchNextShortcut = QShortcut(
2236 self.vm.searchNextAct.shortcut(), self, 2237 self.vm.searchNextAct.shortcut(),
2237 self.__searchNext, self.__searchNext) 2238 self,
2239 self.__searchNext,
2240 self.__searchNext,
2241 )
2238 self.__searchPrevShortcut = QShortcut( 2242 self.__searchPrevShortcut = QShortcut(
2239 self.vm.searchPrevAct.shortcut(), self, 2243 self.vm.searchPrevAct.shortcut(),
2240 self.__searchPrev, self.__searchPrev) 2244 self,
2241 2245 self.__searchPrev,
2246 self.__searchPrev,
2247 )
2248
2242 with contextlib.suppress(AttributeError): 2249 with contextlib.suppress(AttributeError):
2243 self.vm.editActGrp.setEnabled(False) 2250 self.vm.editActGrp.setEnabled(False)
2244 self.vm.editorActGrp.setEnabled(True) 2251 self.vm.editorActGrp.setEnabled(True)
2245 self.vm.copyActGrp.setEnabled(True) 2252 self.vm.copyActGrp.setEnabled(True)
2246 self.vm.viewActGrp.setEnabled(True) 2253 self.vm.viewActGrp.setEnabled(True)
2249 self.__searchShortcut.setEnabled(True) 2256 self.__searchShortcut.setEnabled(True)
2250 self.__searchNextShortcut.setEnabled(True) 2257 self.__searchNextShortcut.setEnabled(True)
2251 self.__searchPrevShortcut.setEnabled(True) 2258 self.__searchPrevShortcut.setEnabled(True)
2252 self.setCaretWidth(self.caretWidth) 2259 self.setCaretWidth(self.caretWidth)
2253 self.setCursorFlashTime(QApplication.cursorFlashTime()) 2260 self.setCursorFlashTime(QApplication.cursorFlashTime())
2254 2261
2255 super().focusInEvent(event) 2262 super().focusInEvent(event)
2256 2263
2257 def focusOutEvent(self, event): 2264 def focusOutEvent(self, event):
2258 """ 2265 """
2259 Protected method called when the shell loses focus. 2266 Protected method called when the shell loses focus.
2260 2267
2261 @param event the event object (QFocusEvent) 2268 @param event the event object (QFocusEvent)
2262 """ 2269 """
2263 with contextlib.suppress(AttributeError): 2270 with contextlib.suppress(AttributeError):
2264 self.vm.editorActGrp.setEnabled(False) 2271 self.vm.editorActGrp.setEnabled(False)
2265 if not self.__windowed: 2272 if not self.__windowed:
2266 self.__searchShortcut.setEnabled(False) 2273 self.__searchShortcut.setEnabled(False)
2267 self.__searchNextShortcut.setEnabled(False) 2274 self.__searchNextShortcut.setEnabled(False)
2268 self.__searchPrevShortcut.setEnabled(False) 2275 self.__searchPrevShortcut.setEnabled(False)
2269 self.setCaretWidth(0) 2276 self.setCaretWidth(0)
2270 super().focusOutEvent(event) 2277 super().focusOutEvent(event)
2271 2278
2272 def insert(self, txt): 2279 def insert(self, txt):
2273 """ 2280 """
2274 Public slot to insert text at the current cursor position. 2281 Public slot to insert text at the current cursor position.
2275 2282
2276 The cursor is advanced to the end of the inserted text. 2283 The cursor is advanced to the end of the inserted text.
2277 2284
2278 @param txt text to be inserted (string) 2285 @param txt text to be inserted (string)
2279 """ 2286 """
2280 txt = Utilities.filterAnsiSequences(txt) 2287 txt = Utilities.filterAnsiSequences(txt)
2281 length = len(txt) 2288 length = len(txt)
2282 line, col = self.getCursorPosition() 2289 line, col = self.getCursorPosition()
2283 self.insertAt(txt, line, col) 2290 self.insertAt(txt, line, col)
2284 if re.search(self.linesepRegExp, txt) is not None: 2291 if re.search(self.linesepRegExp, txt) is not None:
2285 line += 1 2292 line += 1
2286 self.setCursorPosition(line, col + length) 2293 self.setCursorPosition(line, col + length)
2287 2294
2288 def __configure(self): 2295 def __configure(self):
2289 """ 2296 """
2290 Private method to open the configuration dialog. 2297 Private method to open the configuration dialog.
2291 """ 2298 """
2292 ericApp().getObject("UserInterface").showPreferences("shellPage") 2299 ericApp().getObject("UserInterface").showPreferences("shellPage")
2293 2300
2294 def __find(self): 2301 def __find(self):
2295 """ 2302 """
2296 Private slot to show the find widget. 2303 Private slot to show the find widget.
2297 """ 2304 """
2298 txt = self.selectedText() 2305 txt = self.selectedText()
2299 self.__mainWindow.showFind(txt) 2306 self.__mainWindow.showFind(txt)
2300 2307
2301 def __searchNext(self): 2308 def __searchNext(self):
2302 """ 2309 """
2303 Private method to search for the next occurrence. 2310 Private method to search for the next occurrence.
2304 """ 2311 """
2305 if self.__lastSearch: 2312 if self.__lastSearch:
2306 self.searchNext(*self.__lastSearch) 2313 self.searchNext(*self.__lastSearch)
2307 2314
2308 def searchNext(self, txt, caseSensitive, wholeWord, regexp): 2315 def searchNext(self, txt, caseSensitive, wholeWord, regexp):
2309 """ 2316 """
2310 Public method to search the next occurrence of the given text. 2317 Public method to search the next occurrence of the given text.
2311 2318
2312 @param txt text to search for 2319 @param txt text to search for
2313 @type str 2320 @type str
2314 @param caseSensitive flag indicating to perform a case sensitive 2321 @param caseSensitive flag indicating to perform a case sensitive
2315 search 2322 search
2316 @type bool 2323 @type bool
2322 """ 2329 """
2323 self.__lastSearch = (txt, caseSensitive, wholeWord, regexp) 2330 self.__lastSearch = (txt, caseSensitive, wholeWord, regexp)
2324 posixMode = Preferences.getEditor("SearchRegexpMode") == 0 and regexp 2331 posixMode = Preferences.getEditor("SearchRegexpMode") == 0 and regexp
2325 cxx11Mode = Preferences.getEditor("SearchRegexpMode") == 1 and regexp 2332 cxx11Mode = Preferences.getEditor("SearchRegexpMode") == 1 and regexp
2326 ok = self.findFirst( 2333 ok = self.findFirst(
2327 txt, regexp, caseSensitive, wholeWord, True, forward=True, 2334 txt,
2328 posix=posixMode, cxx11=cxx11Mode) 2335 regexp,
2336 caseSensitive,
2337 wholeWord,
2338 True,
2339 forward=True,
2340 posix=posixMode,
2341 cxx11=cxx11Mode,
2342 )
2329 self.searchStringFound.emit(ok) 2343 self.searchStringFound.emit(ok)
2330 2344
2331 def __searchPrev(self): 2345 def __searchPrev(self):
2332 """ 2346 """
2333 Private method to search for the next occurrence. 2347 Private method to search for the next occurrence.
2334 """ 2348 """
2335 if self.__lastSearch: 2349 if self.__lastSearch:
2336 self.searchPrev(*self.__lastSearch) 2350 self.searchPrev(*self.__lastSearch)
2337 2351
2338 def searchPrev(self, txt, caseSensitive, wholeWord, regexp): 2352 def searchPrev(self, txt, caseSensitive, wholeWord, regexp):
2339 """ 2353 """
2340 Public method to search the previous occurrence of the given text. 2354 Public method to search the previous occurrence of the given text.
2341 2355
2342 @param txt text to search for 2356 @param txt text to search for
2343 @type str 2357 @type str
2344 @param caseSensitive flag indicating to perform a case sensitive 2358 @param caseSensitive flag indicating to perform a case sensitive
2345 search 2359 search
2346 @type bool 2360 @type bool
2356 else: 2370 else:
2357 line, index = -1, -1 2371 line, index = -1, -1
2358 posixMode = Preferences.getEditor("SearchRegexpMode") == 0 and regexp 2372 posixMode = Preferences.getEditor("SearchRegexpMode") == 0 and regexp
2359 cxx11Mode = Preferences.getEditor("SearchRegexpMode") == 1 and regexp 2373 cxx11Mode = Preferences.getEditor("SearchRegexpMode") == 1 and regexp
2360 ok = self.findFirst( 2374 ok = self.findFirst(
2361 txt, regexp, caseSensitive, wholeWord, True, 2375 txt,
2362 forward=False, line=line, index=index, posix=posixMode, 2376 regexp,
2363 cxx11=cxx11Mode) 2377 caseSensitive,
2378 wholeWord,
2379 True,
2380 forward=False,
2381 line=line,
2382 index=index,
2383 posix=posixMode,
2384 cxx11=cxx11Mode,
2385 )
2364 self.searchStringFound.emit(ok) 2386 self.searchStringFound.emit(ok)
2365 2387
2366 def historyStyle(self): 2388 def historyStyle(self):
2367 """ 2389 """
2368 Public method to get the shell history style. 2390 Public method to get the shell history style.
2369 2391
2370 @return shell history style 2392 @return shell history style
2371 @rtype ShellHistoryStyle 2393 @rtype ShellHistoryStyle
2372 """ 2394 """
2373 return self.__historyStyle 2395 return self.__historyStyle
2374 2396
2375 def isHistoryEnabled(self): 2397 def isHistoryEnabled(self):
2376 """ 2398 """
2377 Public method to check, if the history is enabled. 2399 Public method to check, if the history is enabled.
2378 2400
2379 @return flag indicating if history is enabled 2401 @return flag indicating if history is enabled
2380 @rtype bool 2402 @rtype bool
2381 """ 2403 """
2382 return self.__historyStyle != ShellHistoryStyle.DISABLED 2404 return self.__historyStyle != ShellHistoryStyle.DISABLED
2383 2405
2384 def saveContents(self): 2406 def saveContents(self):
2385 """ 2407 """
2386 Public method to save the current contents to a file. 2408 Public method to save the current contents to a file.
2387 """ 2409 """
2388 txt = self.text() 2410 txt = self.text()
2391 self, 2413 self,
2392 self.tr("Save Shell Contents"), 2414 self.tr("Save Shell Contents"),
2393 Preferences.getMultiProject("Workspace"), 2415 Preferences.getMultiProject("Workspace"),
2394 self.tr("Text Files (*.txt);;All Files (*)"), 2416 self.tr("Text Files (*.txt);;All Files (*)"),
2395 None, 2417 None,
2396 EricFileDialog.DontConfirmOverwrite 2418 EricFileDialog.DontConfirmOverwrite,
2397 ) 2419 )
2398 2420
2399 if fn: 2421 if fn:
2400 if fn.endswith("."): 2422 if fn.endswith("."):
2401 fn = fn[:-1] 2423 fn = fn[:-1]
2402 2424
2403 fpath = pathlib.Path(fn) 2425 fpath = pathlib.Path(fn)
2404 if not fpath.suffix: 2426 if not fpath.suffix:
2405 ex = selectedFilter.split("(*")[1].split(")")[0] 2427 ex = selectedFilter.split("(*")[1].split(")")[0]
2406 if ex: 2428 if ex:
2407 fpath = fpath.with_suffix(ex) 2429 fpath = fpath.with_suffix(ex)
2408 if fpath.exists(): 2430 if fpath.exists():
2409 res = EricMessageBox.yesNo( 2431 res = EricMessageBox.yesNo(
2410 self, 2432 self,
2411 self.tr("Save Shell Contents"), 2433 self.tr("Save Shell Contents"),
2412 self.tr("<p>The file <b>{0}</b> already exists." 2434 self.tr(
2413 " Overwrite it?</p>").format(fpath), 2435 "<p>The file <b>{0}</b> already exists."
2414 icon=EricMessageBox.Warning) 2436 " Overwrite it?</p>"
2437 ).format(fpath),
2438 icon=EricMessageBox.Warning,
2439 )
2415 if not res: 2440 if not res:
2416 return 2441 return
2417 try: 2442 try:
2418 with fpath.open("w", encoding="utf-8") as f: 2443 with fpath.open("w", encoding="utf-8") as f:
2419 f.write(txt) 2444 f.write(txt)
2420 except (OSError, UnicodeError) as why: 2445 except (OSError, UnicodeError) as why:
2421 EricMessageBox.critical( 2446 EricMessageBox.critical(
2422 self, 2447 self,
2423 self.tr("Save Shell Contents"), 2448 self.tr("Save Shell Contents"),
2424 self.tr('<p>The file <b>{0}</b> could not be saved.<br/>' 2449 self.tr(
2425 'Reason: {1}</p>') 2450 "<p>The file <b>{0}</b> could not be saved.<br/>"
2426 .format(fpath, str(why))) 2451 "Reason: {1}</p>"
2427 2452 ).format(fpath, str(why)),
2453 )
2454
2428 ################################################################# 2455 #################################################################
2429 ## Project Support 2456 ## Project Support
2430 ################################################################# 2457 #################################################################
2431 2458
2432 def __projectOpened(self): 2459 def __projectOpened(self):
2433 """ 2460 """
2434 Private slot to start the shell for the opened project. 2461 Private slot to start the shell for the opened project.
2435 """ 2462 """
2436 if Preferences.getProject("RestartShellForProject"): 2463 if Preferences.getProject("RestartShellForProject"):
2437 self.dbs.startClient(False, forProject=True, 2464 self.dbs.startClient(
2438 workingDir=self.__project.getProjectPath()) 2465 False, forProject=True, workingDir=self.__project.getProjectPath()
2466 )
2439 self.__currentWorkingDirectory = self.__project.getProjectPath() 2467 self.__currentWorkingDirectory = self.__project.getProjectPath()
2440 self.__getBanner() 2468 self.__getBanner()
2441 2469
2442 def __projectClosed(self): 2470 def __projectClosed(self):
2443 """ 2471 """
2444 Private slot to restart the default shell when the project is closed. 2472 Private slot to restart the default shell when the project is closed.
2445 """ 2473 """
2446 if Preferences.getProject("RestartShellForProject"): 2474 if Preferences.getProject("RestartShellForProject"):
2447 self.dbs.startClient(False) 2475 self.dbs.startClient(False)
2448 self.__getBanner() 2476 self.__getBanner()
2449 2477
2478
2450 # 2479 #
2451 # eflag: noqa = M601 2480 # eflag: noqa = M601

eric ide

mercurial