QScintilla/Shell.py

branch
5_3_x
changeset 2941
9bd47580bdbf
parent 2475
c74e1cff7f3f
child 3163
9f50365a0870
equal deleted inserted replaced
2932:1cf0eb73b52d 2941:9bd47580bdbf
9 9
10 import sys 10 import sys
11 import re 11 import re
12 12
13 from PyQt4.QtCore import pyqtSignal, QFileInfo, Qt, QEvent 13 from PyQt4.QtCore import pyqtSignal, QFileInfo, Qt, QEvent
14 from PyQt4.QtGui import QDialog, QInputDialog, QApplication, QClipboard, QMenu, \ 14 from PyQt4.QtGui import QDialog, QInputDialog, QApplication, QClipboard, \
15 QPalette, QFont, QWidget, QHBoxLayout, QVBoxLayout, QShortcut 15 QMenu, QPalette, QFont, QWidget, QHBoxLayout, QVBoxLayout, QShortcut
16 from PyQt4.Qsci import QsciScintilla 16 from PyQt4.Qsci import QsciScintilla
17 17
18 from E5Gui.E5Application import e5App 18 from E5Gui.E5Application import e5App
19 from E5Gui import E5MessageBox 19 from E5Gui import E5MessageBox
20 20
58 self.__layout.addWidget(self.__shell) 58 self.__layout.addWidget(self.__shell)
59 self.__layout.addWidget(self.__searchWidget) 59 self.__layout.addWidget(self.__searchWidget)
60 60
61 self.__searchWidget.searchNext.connect(self.__shell.searchNext) 61 self.__searchWidget.searchNext.connect(self.__shell.searchNext)
62 self.__searchWidget.searchPrevious.connect(self.__shell.searchPrev) 62 self.__searchWidget.searchPrevious.connect(self.__shell.searchPrev)
63 self.__shell.searchStringFound.connect(self.__searchWidget.searchStringFound) 63 self.__shell.searchStringFound.connect(
64 self.__searchWidget.searchStringFound)
64 65
65 def showFind(self, txt=""): 66 def showFind(self, txt=""):
66 """ 67 """
67 Public method to display the search widget. 68 Public method to display the search widget.
68 69
84 Class implementing a graphical Python shell. 85 Class implementing a graphical Python shell.
85 86
86 A user can enter commands that are executed in the remote 87 A user can enter commands that are executed in the remote
87 Python interpreter. 88 Python interpreter.
88 89
89 @signal searchStringFound(found) emitted to indicate the search result (boolean) 90 @signal searchStringFound(found) emitted to indicate the search
91 result (boolean)
90 """ 92 """
91 searchStringFound = pyqtSignal(bool) 93 searchStringFound = pyqtSignal(bool)
92 94
93 def __init__(self, dbs, vm, parent=None): 95 def __init__(self, dbs, vm, parent=None):
94 """ 96 """
114 self.setWindowTitle(self.trUtf8('Shell')) 116 self.setWindowTitle(self.trUtf8('Shell'))
115 117
116 self.setWhatsThis(self.trUtf8( 118 self.setWhatsThis(self.trUtf8(
117 """<b>The Shell Window</b>""" 119 """<b>The Shell Window</b>"""
118 """<p>This is simply an interpreter running in a window. The""" 120 """<p>This is simply an interpreter running in a window. The"""
119 """ interpreter is the one that is used to run the program being debugged.""" 121 """ interpreter is the one that is used to run the program"""
120 """ This means that you can execute any command while the program""" 122 """ being debugged. This means that you can execute any command"""
121 """ being debugged is running.</p>""" 123 """ while the program being debugged is running.</p>"""
122 """<p>You can use the cursor keys while entering commands. There is also a""" 124 """<p>You can use the cursor keys while entering commands. There"""
123 """ history of commands that can be recalled using the up and down cursor""" 125 """ is also a history of commands that can be recalled using the"""
124 """ keys. Pressing the up or down key after some text has been entered will""" 126 """ up and down cursor keys. Pressing the up or down key after"""
125 """ start an incremental search.</p>""" 127 """ some text has been entered will start an incremental search."""
126 """<p>The shell has some special commands. 'reset' kills the shell""" 128 """</p>"""
127 """ and starts a new one. 'clear' clears the display of the shell window.""" 129 """<p>The shell has some special commands. 'reset' kills the"""
128 """ 'start' is used to switch the shell language and must be followed by""" 130 """ shell and starts a new one. 'clear' clears the display of"""
129 """ a supported language. Supported languages are listed by the 'languages'""" 131 """ the shell window. 'start' is used to switch the shell"""
130 """ command. These commands (except 'languages') are available through the""" 132 """ language and must be followed by a supported language."""
131 """ context menu as well.</p>""" 133 """ Supported languages are listed by the 'languages' command."""
132 """<p>Pressing the Tab key after some text has been entered will show""" 134 """ These commands (except 'languages') are available through"""
133 """ a list of possible commandline completions. The relevant entry may""" 135 """ the context menu as well.</p>"""
134 """ be selected from this list. If only one entry is available, this will""" 136 """<p>Pressing the Tab key after some text has been entered will"""
135 """ inserted automatically.</p>""" 137 """ show a list of possible commandline completions. The"""
136 """<p>In passive debugging mode the shell is only available after the""" 138 """ relevant entry may be selected from this list. If only one"""
137 """ program to be debugged has connected to the IDE until it has finished.""" 139 """ entry is available, this will inserted automatically.</p>"""
138 """ This is indicated by a different prompt and by an indication in the""" 140 """<p>In passive debugging mode the shell is only available"""
139 """ window caption.</p>""" 141 """ after the program to be debugged has connected to the IDE"""
142 """ until it has finished. This is indicated by a different"""
143 """ prompt and by an indication in the window caption.</p>"""
140 )) 144 ))
141 145
142 self.userListActivated.connect(self.__completionListSelected) 146 self.userListActivated.connect(self.__completionListSelected)
143 147
144 self.__showStdOutErr = Preferences.getShell("ShowStdOutErr") 148 self.__showStdOutErr = Preferences.getShell("ShowStdOutErr")
323 """ 327 """
324 Private method to configure margin 0. 328 Private method to configure margin 0.
325 """ 329 """
326 # set the settings for all margins 330 # set the settings for all margins
327 self.setMarginsFont(Preferences.getShell("MarginsFont")) 331 self.setMarginsFont(Preferences.getShell("MarginsFont"))
328 self.setMarginsForegroundColor(Preferences.getEditorColour("MarginsForeground")) 332 self.setMarginsForegroundColor(
329 self.setMarginsBackgroundColor(Preferences.getEditorColour("MarginsBackground")) 333 Preferences.getEditorColour("MarginsForeground"))
334 self.setMarginsBackgroundColor(
335 Preferences.getEditorColour("MarginsBackground"))
330 336
331 # set margin 0 settings 337 # set margin 0 settings
332 linenoMargin = Preferences.getShell("LinenoMargin") 338 linenoMargin = Preferences.getShell("LinenoMargin")
333 self.setMarginLineNumbers(0, linenoMargin) 339 self.setMarginLineNumbers(0, linenoMargin)
334 if linenoMargin: 340 if linenoMargin:
447 Preferences.getEditorColour("CallTipsBackground")) 453 Preferences.getEditorColour("CallTipsBackground"))
448 self.setCallTipsVisible(Preferences.getEditor("CallTipsVisible")) 454 self.setCallTipsVisible(Preferences.getEditor("CallTipsVisible"))
449 calltipsStyle = Preferences.getEditor("CallTipsStyle") 455 calltipsStyle = Preferences.getEditor("CallTipsStyle")
450 if calltipsStyle == QsciScintilla.CallTipsNoContext: 456 if calltipsStyle == QsciScintilla.CallTipsNoContext:
451 self.setCallTipsStyle(QsciScintilla.CallTipsNoContext) 457 self.setCallTipsStyle(QsciScintilla.CallTipsNoContext)
452 elif calltipsStyle == QsciScintilla.CallTipsNoAutoCompletionContext: 458 elif calltipsStyle == \
453 self.setCallTipsStyle(QsciScintilla.CallTipsNoAutoCompletionContext) 459 QsciScintilla.CallTipsNoAutoCompletionContext:
460 self.setCallTipsStyle(
461 QsciScintilla.CallTipsNoAutoCompletionContext)
454 else: 462 else:
455 self.setCallTipsStyle(QsciScintilla.CallTipsContext) 463 self.setCallTipsStyle(QsciScintilla.CallTipsContext)
456 else: 464 else:
457 self.setCallTipsStyle(QsciScintilla.CallTipsNone) 465 self.setCallTipsStyle(QsciScintilla.CallTipsNone)
458 466
489 self.__bindLexer(clType) 497 self.__bindLexer(clType)
490 self.__setTextDisplay() 498 self.__setTextDisplay()
491 self.__setMargin0() 499 self.__setMargin0()
492 self.__setAutoCompletion(clType) 500 self.__setAutoCompletion(clType)
493 self.__setCallTips(clType) 501 self.__setCallTips(clType)
494 self.racEnabled = Preferences.getShell("AutoCompletionEnabled") and \ 502 self.racEnabled = \
495 (cap & HasCompleter) > 0 503 Preferences.getShell("AutoCompletionEnabled") and \
504 (cap & HasCompleter) > 0
496 505
497 if clType not in self.historyLists: 506 if clType not in self.historyLists:
498 # load history list 507 # load history list
499 self.loadHistory(clType) 508 self.loadHistory(clType)
500 self.history = self.historyLists[clType] 509 self.history = self.historyLists[clType]
512 else: 521 else:
513 self.historyLists[clientType] = [] 522 self.historyLists[clientType] = []
514 523
515 def reloadHistory(self): 524 def reloadHistory(self):
516 """ 525 """
517 Public method to reload the history of the currently selected client type. 526 Public method to reload the history of the currently selected client
527 type.
518 """ 528 """
519 self.loadHistory(self.clientType) 529 self.loadHistory(self.clientType)
520 self.history = self.historyLists[self.clientType] 530 self.history = self.historyLists[self.clientType]
521 self.histidx = -1 531 self.histidx = -1
522 532
556 Private slot to select a history entry to execute. 566 Private slot to select a history entry to execute.
557 """ 567 """
558 cmd, ok = QInputDialog.getItem( 568 cmd, ok = QInputDialog.getItem(
559 self, 569 self,
560 self.trUtf8("Select History"), 570 self.trUtf8("Select History"),
561 self.trUtf8("Select the history entry to execute (most recent shown last)."), 571 self.trUtf8("Select the history entry to execute"
572 " (most recent shown last)."),
562 self.history, 573 self.history,
563 0, False) 574 0, False)
564 if ok: 575 if ok:
565 self.__insertHistory(cmd) 576 self.__insertHistory(cmd)
566 577
691 self.inRawMode = True 702 self.inRawMode = True
692 self.echoInput = echo 703 self.echoInput = echo
693 self.__write(s) 704 self.__write(s)
694 line, col = self.__getEndPos() 705 line, col = self.__getEndPos()
695 self.setCursorPosition(line, col) 706 self.setCursorPosition(line, col)
696 self.prompt = self.text(line)\ 707 buf = self.text(line)
697 .replace(sys.ps1, "").replace(sys.ps2, "") 708 if buf.startswith(sys.ps1):
709 buf = buf.replace(sys.ps1, "")
710 if buf.startswith(sys.ps2):
711 buf = buf.replace(sys.ps2, "")
712 self.prompt = buf
698 # move cursor to end of line 713 # move cursor to end of line
699 self.moveCursorToEOL() 714 self.moveCursorToEOL()
700 715
701 def paste(self): 716 def paste(self):
702 """ 717 """
771 self.insert(s) 786 self.insert(s)
772 self.prline, self.prcol = self.getCursorPosition() 787 self.prline, self.prcol = self.getCursorPosition()
773 788
774 def __insertTextNoEcho(self, s): 789 def __insertTextNoEcho(self, s):
775 """ 790 """
776 Private method to insert some text at the end of the buffer without echoing it. 791 Private method to insert some text at the end of the buffer without
792 echoing it.
777 793
778 @param s text to be inserted (string) 794 @param s text to be inserted (string)
779 """ 795 """
780 self.buff += s 796 self.buff += s
781 self.prline, self.prcol = self.getCursorPosition() 797 self.prline, self.prcol = self.getCursorPosition()
897 """ 913 """
898 if self.isListActive(): 914 if self.isListActive():
899 self.SendScintilla(cmd) 915 self.SendScintilla(cmd)
900 elif self.__isCursorOnLastLine(): 916 elif self.__isCursorOnLastLine():
901 line, index = self.getCursorPosition() 917 line, index = self.getCursorPosition()
902 buf = self.text(line).replace(sys.ps1, "").replace(sys.ps2, "") 918 buf = self.text(line)
919 if buf.startswith(sys.ps1):
920 buf = buf.replace(sys.ps1, "")
921 if buf.startswith(sys.ps2):
922 buf = buf.replace(sys.ps2, "")
903 if self.inContinue and not buf[:index - len(sys.ps2)].strip(): 923 if self.inContinue and not buf[:index - len(sys.ps2)].strip():
904 self.SendScintilla(cmd) 924 self.SendScintilla(cmd)
905 elif self.racEnabled: 925 elif self.racEnabled:
906 self.dbs.remoteCompletion(buf) 926 self.dbs.remoteCompletion(buf)
907 927
908 def __QScintillaLeftDeleteCommand(self, method): 928 def __QScintillaLeftDeleteCommand(self, method):
909 """ 929 """
910 Private method to handle a QScintilla delete command working to the left. 930 Private method to handle a QScintilla delete command working to
931 the left.
911 932
912 @param method shell method to execute 933 @param method shell method to execute
913 """ 934 """
914 if self.__isCursorOnLastLine(): 935 if self.__isCursorOnLastLine():
915 line, col = self.getCursorPosition() 936 line, col = self.getCursorPosition()
994 else: 1015 else:
995 self.incrementalSearchString = "" 1016 self.incrementalSearchString = ""
996 self.incrementalSearchActive = False 1017 self.incrementalSearchActive = False
997 line, col = self.__getEndPos() 1018 line, col = self.__getEndPos()
998 self.setCursorPosition(line, col) 1019 self.setCursorPosition(line, col)
999 buf = self.text(line).replace(sys.ps1, "").replace(sys.ps2, "") 1020 buf = self.text(line)
1021 if buf.startswith(sys.ps1):
1022 buf = buf.replace(sys.ps1, "")
1023 if buf.startswith(sys.ps2):
1024 buf = buf.replace(sys.ps2, "")
1000 self.insert('\n') 1025 self.insert('\n')
1001 self.__executeCommand(buf) 1026 self.__executeCommand(buf)
1002 1027
1003 def __QScintillaLeftCommand(self, method, allLinesAllowed=False): 1028 def __QScintillaLeftCommand(self, method, allLinesAllowed=False):
1004 """ 1029 """
1101 """ 1126 """
1102 if self.isListActive(): 1127 if self.isListActive():
1103 self.SendScintilla(cmd) 1128 self.SendScintilla(cmd)
1104 else: 1129 else:
1105 line, col = self.__getEndPos() 1130 line, col = self.__getEndPos()
1106 buf = self.text(line).replace(sys.ps1, "").replace(sys.ps2, "") 1131 buf = self.text(line)
1132 if buf.startswith(sys.ps1):
1133 buf = buf.replace(sys.ps1, "")
1134 if buf.startswith(sys.ps2):
1135 buf = buf.replace(sys.ps2, "")
1107 if buf and self.incrementalSearchActive: 1136 if buf and self.incrementalSearchActive:
1108 if self.incrementalSearchString: 1137 if self.incrementalSearchString:
1109 idx = self.__rsearchHistory(self.incrementalSearchString, 1138 idx = self.__rsearchHistory(self.incrementalSearchString,
1110 self.histidx) 1139 self.histidx)
1111 if idx >= 0: 1140 if idx >= 0:
1132 """ 1161 """
1133 if self.isListActive(): 1162 if self.isListActive():
1134 self.SendScintilla(cmd) 1163 self.SendScintilla(cmd)
1135 else: 1164 else:
1136 line, col = self.__getEndPos() 1165 line, col = self.__getEndPos()
1137 buf = self.text(line).replace(sys.ps1, "").replace(sys.ps2, "") 1166 buf = self.text(line)
1167 if buf.startswith(sys.ps1):
1168 buf = buf.replace(sys.ps1, "")
1169 if buf.startswith(sys.ps2):
1170 buf = buf.replace(sys.ps2, "")
1138 if buf and self.incrementalSearchActive: 1171 if buf and self.incrementalSearchActive:
1139 if self.incrementalSearchString: 1172 if self.incrementalSearchString:
1140 idx = self.__searchHistory(self.incrementalSearchString, self.histidx) 1173 idx = self.__searchHistory(
1174 self.incrementalSearchString, self.histidx)
1141 if idx >= 0: 1175 if idx >= 0:
1142 self.histidx = idx 1176 self.histidx = idx
1143 self.__useHistory() 1177 self.__useHistory()
1144 else: 1178 else:
1145 idx = self.__searchHistory(buf) 1179 idx = self.__searchHistory(buf)
1220 if language: 1254 if language:
1221 self.dbs.startClient(False, language) 1255 self.dbs.startClient(False, language)
1222 else: 1256 else:
1223 # language not supported or typo 1257 # language not supported or typo
1224 self.__write( 1258 self.__write(
1225 self.trUtf8('Shell language "{0}" not supported.\n')\ 1259 self.trUtf8(
1260 'Shell language "{0}" not supported.\n')
1226 .format(cmdList[1])) 1261 .format(cmdList[1]))
1227 self.__clientStatement(False) 1262 self.__clientStatement(False)
1228 return 1263 return
1229 cmd = '' 1264 cmd = ''
1230 elif cmd == 'languages': 1265 elif cmd == 'languages':
1363 """ 1398 """
1364 self.dbs.startClient(False) 1399 self.dbs.startClient(False)
1365 1400
1366 def __startDebugClient(self, action): 1401 def __startDebugClient(self, action):
1367 """ 1402 """
1368 Private slot to start a debug client accoding to the action triggered[()]. 1403 Private slot to start a debug client according to the action
1404 triggered[()].
1369 1405
1370 @param action context menu action that was triggered (QAction) 1406 @param action context menu action that was triggered (QAction)
1371 """ 1407 """
1372 language = action.data() 1408 language = action.data()
1373 self.dbs.startClient(False, language) 1409 self.dbs.startClient(False, language)
1447 """ 1483 """
1448 Protected method to handle the drag enter event. 1484 Protected method to handle the drag enter event.
1449 1485
1450 @param event the drag enter event (QDragEnterEvent) 1486 @param event the drag enter event (QDragEnterEvent)
1451 """ 1487 """
1452 self.inDragDrop = event.mimeData().hasUrls() or event.mimeData().hasText() 1488 self.inDragDrop = event.mimeData().hasUrls() or \
1489 event.mimeData().hasText()
1453 if self.inDragDrop: 1490 if self.inDragDrop:
1454 event.acceptProposedAction() 1491 event.acceptProposedAction()
1455 else: 1492 else:
1456 super().dragEnterEvent(event) 1493 super().dragEnterEvent(event)
1457 1494
1515 """ 1552 """
1516 if not self.__actionsAdded: 1553 if not self.__actionsAdded:
1517 self.addActions(self.vm.editorActGrp.actions()) 1554 self.addActions(self.vm.editorActGrp.actions())
1518 self.addActions(self.vm.copyActGrp.actions()) 1555 self.addActions(self.vm.copyActGrp.actions())
1519 self.addActions(self.vm.viewActGrp.actions()) 1556 self.addActions(self.vm.viewActGrp.actions())
1520 self.__searchShortcut = QShortcut(self.vm.searchAct.shortcut(), self, 1557 self.__searchShortcut = QShortcut(
1558 self.vm.searchAct.shortcut(), self,
1521 self.__find, self.__find) 1559 self.__find, self.__find)
1522 self.__searchNextShortcut = QShortcut(self.vm.searchNextAct.shortcut(), self, 1560 self.__searchNextShortcut = QShortcut(
1561 self.vm.searchNextAct.shortcut(), self,
1523 self.__searchNext, self.__searchNext) 1562 self.__searchNext, self.__searchNext)
1524 self.__searchPrevShortcut = QShortcut(self.vm.searchPrevAct.shortcut(), self, 1563 self.__searchPrevShortcut = QShortcut(
1564 self.vm.searchPrevAct.shortcut(), self,
1525 self.__searchPrev, self.__searchPrev) 1565 self.__searchPrev, self.__searchPrev)
1526 1566
1527 try: 1567 try:
1528 self.vm.editActGrp.setEnabled(False) 1568 self.vm.editActGrp.setEnabled(False)
1529 self.vm.editorActGrp.setEnabled(True) 1569 self.vm.editorActGrp.setEnabled(True)
1600 search (boolean) 1640 search (boolean)
1601 @param wholeWord flag indicating to search for whole words 1641 @param wholeWord flag indicating to search for whole words
1602 only (boolean) 1642 only (boolean)
1603 """ 1643 """
1604 self.__lastSearch = (txt, caseSensitive, wholeWord) 1644 self.__lastSearch = (txt, caseSensitive, wholeWord)
1605 ok = self.findFirst(txt, False, caseSensitive, wholeWord, False, forward=True) 1645 ok = self.findFirst(txt, False, caseSensitive, wholeWord, False,
1646 forward=True)
1606 self.searchStringFound.emit(ok) 1647 self.searchStringFound.emit(ok)
1607 1648
1608 def __searchPrev(self): 1649 def __searchPrev(self):
1609 """ 1650 """
1610 Private method to search for the next occurrence. 1651 Private method to search for the next occurrence.
1625 self.__lastSearch = (txt, caseSensitive, wholeWord) 1666 self.__lastSearch = (txt, caseSensitive, wholeWord)
1626 if self.hasSelectedText(): 1667 if self.hasSelectedText():
1627 line, index = self.getSelection()[:2] 1668 line, index = self.getSelection()[:2]
1628 else: 1669 else:
1629 line, index = -1, -1 1670 line, index = -1, -1
1630 ok = self.findFirst(txt, False, caseSensitive, wholeWord, False, forward=False, 1671 ok = self.findFirst(txt, False, caseSensitive, wholeWord, False,
1672 forward=False,
1631 line=line, index=index) 1673 line=line, index=index)
1632 self.searchStringFound.emit(ok) 1674 self.searchStringFound.emit(ok)

eric ide

mercurial