src/eric7/QScintilla/Editor.py

branch
eric7
changeset 9482
a2bc06a54d9d
parent 9473
3f23dbf37dbe
child 9517
d73c3a1e432b
equal deleted inserted replaced
9481:0b936ff1bbb9 9482:a2bc06a54d9d
30 QTimer, 30 QTimer,
31 pyqtSignal, 31 pyqtSignal,
32 pyqtSlot, 32 pyqtSlot,
33 ) 33 )
34 from PyQt6.QtGui import QActionGroup, QFont, QPainter, QPalette, QPixmap 34 from PyQt6.QtGui import QActionGroup, QFont, QPainter, QPalette, QPixmap
35 from PyQt6.QtPrintSupport import QAbstractPrintDialog, QPrintDialog, QPrinter 35 from PyQt6.QtPrintSupport import (
36 QAbstractPrintDialog,
37 QPrintDialog,
38 QPrinter,
39 QPrintPreviewDialog,
40 )
36 from PyQt6.QtWidgets import QApplication, QDialog, QInputDialog, QLineEdit, QMenu 41 from PyQt6.QtWidgets import QApplication, QDialog, QInputDialog, QLineEdit, QMenu
37 42
38 from eric7 import Preferences, Utilities 43 from eric7 import Preferences, Utilities
39 from eric7.CodeFormatting.BlackFormattingAction import BlackFormattingAction 44 from eric7.CodeFormatting.BlackFormattingAction import BlackFormattingAction
40 from eric7.CodeFormatting.BlackUtilities import aboutBlack 45 from eric7.CodeFormatting.BlackUtilities import aboutBlack
47 from eric7.EricWidgets.EricApplication import ericApp 52 from eric7.EricWidgets.EricApplication import ericApp
48 from eric7.Globals import recentNameBreakpointConditions 53 from eric7.Globals import recentNameBreakpointConditions
49 from eric7.UI import PythonDisViewer 54 from eric7.UI import PythonDisViewer
50 from eric7.Utilities import MouseUtilities 55 from eric7.Utilities import MouseUtilities
51 56
57 from . import Exporters, Lexers, TypingCompleters
52 from .EditorMarkerMap import EditorMarkerMap 58 from .EditorMarkerMap import EditorMarkerMap
53 from .QsciScintillaCompat import QsciScintillaCompat 59 from .QsciScintillaCompat import QsciScintillaCompat
54 from .SpellChecker import SpellChecker 60 from .SpellChecker import SpellChecker
55 61
56 EditorAutoCompletionListID = 1 62 EditorAutoCompletionListID = 1
738 elif line0.startswith("\\documentclass"): 744 elif line0.startswith("\\documentclass"):
739 bindName = "dummy.tex" 745 bindName = "dummy.tex"
740 746
741 if not bindName and self.filetype: 747 if not bindName and self.filetype:
742 # check filetype 748 # check filetype
743 from . import Lexers
744
745 supportedLanguages = Lexers.getSupportedLanguages() 749 supportedLanguages = Lexers.getSupportedLanguages()
746 if self.filetype in supportedLanguages: 750 if self.filetype in supportedLanguages:
747 bindName = supportedLanguages[self.filetype][1] 751 bindName = supportedLanguages[self.filetype][1]
748 elif self.filetype in ["Python", "Python3", "MicroPython"]: 752 elif self.filetype in ["Python", "Python3", "MicroPython"]:
749 bindName = "dummy.py" 753 bindName = "dummy.py"
1167 self.noLanguageAct.setCheckable(True) 1171 self.noLanguageAct.setCheckable(True)
1168 self.noLanguageAct.setData("None") 1172 self.noLanguageAct.setData("None")
1169 self.languagesActGrp.addAction(self.noLanguageAct) 1173 self.languagesActGrp.addAction(self.noLanguageAct)
1170 menu.addSeparator() 1174 menu.addSeparator()
1171 1175
1172 from . import Lexers
1173
1174 self.supportedLanguages = {} 1176 self.supportedLanguages = {}
1175 supportedLanguages = Lexers.getSupportedLanguages() 1177 supportedLanguages = Lexers.getSupportedLanguages()
1176 languages = sorted(supportedLanguages.keys()) 1178 languages = sorted(supportedLanguages.keys())
1177 for language in languages: 1179 for language in languages:
1178 if language != "Guessed": 1180 if language != "Guessed":
1485 Public method to export the file. 1487 Public method to export the file.
1486 1488
1487 @param exporterFormat format the file should be exported into (string) 1489 @param exporterFormat format the file should be exported into (string)
1488 """ 1490 """
1489 if exporterFormat: 1491 if exporterFormat:
1490 from . import Exporters
1491
1492 exporter = Exporters.getExporter(exporterFormat, self) 1492 exporter = Exporters.getExporter(exporterFormat, self)
1493 if exporter: 1493 if exporter:
1494 exporter.exportSource() 1494 exporter.exportSource()
1495 else: 1495 else:
1496 EricMessageBox.critical( 1496 EricMessageBox.critical(
1525 """ 1525 """
1526 Private method to select a specific pygments lexer. 1526 Private method to select a specific pygments lexer.
1527 1527
1528 @return name of the selected pygments lexer (string) 1528 @return name of the selected pygments lexer (string)
1529 """ 1529 """
1530 from pygments.lexers import get_all_lexers 1530 from pygments.lexers import get_all_lexers # __IGNORE_WARNING_I102__
1531 1531
1532 lexerList = sorted(lex[0] for lex in get_all_lexers()) 1532 lexerList = sorted(lex[0] for lex in get_all_lexers())
1533 try: 1533 try:
1534 lexerSel = lexerList.index( 1534 lexerSel = lexerList.index(
1535 self.getLanguage(normalized=False, forPygments=True) 1535 self.getLanguage(normalized=False, forPygments=True)
1886 if language.startswith("Pygments|"): 1886 if language.startswith("Pygments|"):
1887 pyname = language 1887 pyname = language
1888 self.filetype = language.split("|")[-1] 1888 self.filetype = language.split("|")[-1]
1889 language = "" 1889 language = ""
1890 1890
1891 from . import Lexers
1892
1893 self.lexer_ = Lexers.getLexer(language, self, pyname=pyname) 1891 self.lexer_ = Lexers.getLexer(language, self, pyname=pyname)
1894 if self.lexer_ is None: 1892 if self.lexer_ is None:
1895 self.setLexer() 1893 self.setLexer()
1896 self.apiLanguage = "" 1894 self.apiLanguage = ""
1897 return 1895 return
2026 pyVer = self.__getPyVersion() 2024 pyVer = self.__getPyVersion()
2027 if pyVer: 2025 if pyVer:
2028 apiLanguage = "Python{0}".format(pyVer) 2026 apiLanguage = "Python{0}".format(pyVer)
2029 elif self.isRubyFile(): 2027 elif self.isRubyFile():
2030 apiLanguage = "Ruby" 2028 apiLanguage = "Ruby"
2031
2032 from . import TypingCompleters
2033 2029
2034 self.completer = TypingCompleters.getCompleter(apiLanguage, self) 2030 self.completer = TypingCompleters.getCompleter(apiLanguage, self)
2035 2031
2036 def getCompleter(self): 2032 def getCompleter(self):
2037 """ 2033 """
2617 """ 2613 """
2618 Public slot to handle the 'Edit breakpoint' context menu action. 2614 Public slot to handle the 'Edit breakpoint' context menu action.
2619 2615
2620 @param line linenumber of the breakpoint to edit 2616 @param line linenumber of the breakpoint to edit
2621 """ 2617 """
2618 from eric7.Debugger.EditBreakpointDialog import EditBreakpointDialog
2619
2622 if line is not None: 2620 if line is not None:
2623 self.line = line - 1 2621 self.line = line - 1
2624 if self.line < 0: 2622 if self.line < 0:
2625 self.line, index = self.getCursorPosition() 2623 self.line, index = self.getCursorPosition()
2626 2624
2636 condHistory = ( 2634 condHistory = (
2637 Preferences.toList(rs)[: Preferences.getDebugger("RecentNumber")] 2635 Preferences.toList(rs)[: Preferences.getDebugger("RecentNumber")]
2638 if rs is not None 2636 if rs is not None
2639 else [] 2637 else []
2640 ) 2638 )
2641
2642 from eric7.Debugger.EditBreakpointDialog import EditBreakpointDialog
2643 2639
2644 dlg = EditBreakpointDialog( 2640 dlg = EditBreakpointDialog(
2645 (self.fileName, ln), 2641 (self.fileName, ln),
2646 (cond, temp, enabled, ignorecount), 2642 (cond, temp, enabled, ignorecount),
2647 condHistory, 2643 condHistory,
2881 2877
2882 def printPreviewFile(self): 2878 def printPreviewFile(self):
2883 """ 2879 """
2884 Public slot to show a print preview of the text. 2880 Public slot to show a print preview of the text.
2885 """ 2881 """
2886 from PyQt6.QtPrintSupport import QPrintPreviewDialog
2887
2888 from .Printer import Printer 2882 from .Printer import Printer
2889 2883
2890 printer = Printer(mode=QPrinter.PrinterMode.HighResolution) 2884 printer = Printer(mode=QPrinter.PrinterMode.HighResolution)
2891 fn = self.getFileName() 2885 fn = self.getFileName()
2892 if fn is not None: 2886 if fn is not None:
3436 3430
3437 if not path and self.fileName: 3431 if not path and self.fileName:
3438 path = os.path.dirname(self.fileName) 3432 path = os.path.dirname(self.fileName)
3439 if not path: 3433 if not path:
3440 path = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir() 3434 path = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir()
3441
3442 from . import Lexers
3443 3435
3444 if self.fileName: 3436 if self.fileName:
3445 filterPattern = "(*{0})".format(os.path.splitext(self.fileName)[1]) 3437 filterPattern = "(*{0})".format(os.path.splitext(self.fileName)[1])
3446 for fileFilter in Lexers.getSaveFileFiltersList(True): 3438 for fileFilter in Lexers.getSaveFileFiltersList(True):
3447 if filterPattern in fileFilter: 3439 if filterPattern in fileFilter:
6121 6113
6122 def __showCodeMetrics(self): 6114 def __showCodeMetrics(self):
6123 """ 6115 """
6124 Private method to handle the code metrics context menu action. 6116 Private method to handle the code metrics context menu action.
6125 """ 6117 """
6118 from eric7.DataViews.CodeMetricsDialog import CodeMetricsDialog
6119
6126 if not self.checkDirty(): 6120 if not self.checkDirty():
6127 return 6121 return
6128
6129 from eric7.DataViews.CodeMetricsDialog import CodeMetricsDialog
6130 6122
6131 self.codemetrics = CodeMetricsDialog() 6123 self.codemetrics = CodeMetricsDialog()
6132 self.codemetrics.show() 6124 self.codemetrics.show()
6133 self.codemetrics.start(self.fileName) 6125 self.codemetrics.start(self.fileName)
6134 6126
6180 6172
6181 def __showCodeCoverage(self): 6173 def __showCodeCoverage(self):
6182 """ 6174 """
6183 Private method to handle the code coverage context menu action. 6175 Private method to handle the code coverage context menu action.
6184 """ 6176 """
6177 from eric7.DataViews.PyCoverageDialog import PyCoverageDialog
6178
6185 fn = self.__getCodeCoverageFile() 6179 fn = self.__getCodeCoverageFile()
6186 self.__coverageFile = fn 6180 self.__coverageFile = fn
6187 if fn: 6181 if fn:
6188 from eric7.DataViews.PyCoverageDialog import PyCoverageDialog
6189
6190 self.codecoverage = PyCoverageDialog() 6182 self.codecoverage = PyCoverageDialog()
6191 self.codecoverage.show() 6183 self.codecoverage.show()
6192 self.codecoverage.start(fn, self.fileName) 6184 self.codecoverage.start(fn, self.fileName)
6193 6185
6194 def refreshCoverageAnnotations(self): 6186 def refreshCoverageAnnotations(self):
6208 @type bool (optional) 6200 @type bool (optional)
6209 @param coverageFile path of the file containing the code coverage data 6201 @param coverageFile path of the file containing the code coverage data
6210 (defaults to None) 6202 (defaults to None)
6211 @type str (optional) 6203 @type str (optional)
6212 """ 6204 """
6205 from eric7.DebugClients.Python.coverage import ( # __IGNORE_WARNING_I102__
6206 Coverage,
6207 )
6208
6213 self.__codeCoverageHideAnnotations() 6209 self.__codeCoverageHideAnnotations()
6214 6210
6215 fn = coverageFile if bool(coverageFile) else self.__getCodeCoverageFile() 6211 fn = coverageFile if bool(coverageFile) else self.__getCodeCoverageFile()
6216 self.__coverageFile = fn 6212 self.__coverageFile = fn
6217 6213
6218 if fn: 6214 if fn:
6219 from coverage import Coverage
6220
6221 cover = Coverage(data_file=fn) 6215 cover = Coverage(data_file=fn)
6222 cover.load() 6216 cover.load()
6223 missing = cover.analysis2(self.fileName)[3] 6217 missing = cover.analysis2(self.fileName)[3]
6224 if missing: 6218 if missing:
6225 for line in missing: 6219 for line in missing:
6315 6309
6316 def __showProfileData(self): 6310 def __showProfileData(self):
6317 """ 6311 """
6318 Private method to handle the show profile data context menu action. 6312 Private method to handle the show profile data context menu action.
6319 """ 6313 """
6314 from eric7.DataViews.PyProfileDialog import PyProfileDialog
6315
6320 files = set() 6316 files = set()
6321 6317
6322 # first check if the file belongs to a project and there is 6318 # first check if the file belongs to a project and there is
6323 # a project profile file 6319 # a project profile file
6324 if self.project.isOpen() and self.project.isProjectSource(self.fileName): 6320 if self.project.isOpen() and self.project.isProjectSource(self.fileName):
6346 return 6342 return
6347 else: 6343 else:
6348 fn = files[0] 6344 fn = files[0]
6349 else: 6345 else:
6350 return 6346 return
6351
6352 from eric7.DataViews.PyProfileDialog import PyProfileDialog
6353 6347
6354 self.profiledata = PyProfileDialog() 6348 self.profiledata = PyProfileDialog()
6355 self.profiledata.show() 6349 self.profiledata.show()
6356 self.profiledata.start(fn, self.fileName) 6350 self.profiledata.start(fn, self.fileName)
6357 6351
8056 8050
8057 def checkSpelling(self): 8051 def checkSpelling(self):
8058 """ 8052 """
8059 Public slot to perform an interactive spell check of the document. 8053 Public slot to perform an interactive spell check of the document.
8060 """ 8054 """
8055 from .SpellCheckingDialog import SpellCheckingDialog
8056
8061 if self.spell: 8057 if self.spell:
8062 cline, cindex = self.getCursorPosition() 8058 cline, cindex = self.getCursorPosition()
8063 from .SpellCheckingDialog import SpellCheckingDialog
8064
8065 dlg = SpellCheckingDialog(self.spell, 0, self.length(), self) 8059 dlg = SpellCheckingDialog(self.spell, 0, self.length(), self)
8066 dlg.exec() 8060 dlg.exec()
8067 self.setCursorPosition(cline, cindex) 8061 self.setCursorPosition(cline, cindex)
8068 if Preferences.getEditor("AutoSpellCheckingEnabled"): 8062 if Preferences.getEditor("AutoSpellCheckingEnabled"):
8069 self.spell.checkDocumentIncrementally() 8063 self.spell.checkDocumentIncrementally()
8497 8491
8498 def sortLines(self): 8492 def sortLines(self):
8499 """ 8493 """
8500 Public slot to sort the lines spanned by a rectangular selection. 8494 Public slot to sort the lines spanned by a rectangular selection.
8501 """ 8495 """
8496 from .SortOptionsDialog import SortOptionsDialog
8497
8502 if not self.selectionIsRectangle(): 8498 if not self.selectionIsRectangle():
8503 return 8499 return
8504
8505 from .SortOptionsDialog import SortOptionsDialog
8506 8500
8507 dlg = SortOptionsDialog() 8501 dlg = SortOptionsDialog()
8508 if dlg.exec() == QDialog.DialogCode.Accepted: 8502 if dlg.exec() == QDialog.DialogCode.Accepted:
8509 ascending, alnum, caseSensitive = dlg.getData() 8503 ascending, alnum, caseSensitive = dlg.getData()
8510 ( 8504 (
8918 Public method to get a reference to the docstring generator. 8912 Public method to get a reference to the docstring generator.
8919 8913
8920 @return reference to the docstring generator 8914 @return reference to the docstring generator
8921 @rtype BaseDocstringGenerator 8915 @rtype BaseDocstringGenerator
8922 """ 8916 """
8917 from . import DocstringGenerator
8918
8923 if self.__docstringGenerator is None: 8919 if self.__docstringGenerator is None:
8924 from . import DocstringGenerator
8925
8926 self.__docstringGenerator = DocstringGenerator.getDocstringGenerator(self) 8920 self.__docstringGenerator = DocstringGenerator.getDocstringGenerator(self)
8927 8921
8928 return self.__docstringGenerator 8922 return self.__docstringGenerator
8929 8923
8930 def insertDocstring(self): 8924 def insertDocstring(self):
8981 if self.text(cursorPosition[0])[: cursorPosition[1]] != lastLineText: 8975 if self.text(cursorPosition[0])[: cursorPosition[1]] != lastLineText:
8982 return 8976 return
8983 8977
8984 generator = self.getDocstringGenerator() 8978 generator = self.getDocstringGenerator()
8985 if generator.hasFunctionDefinition(cursorPosition): 8979 if generator.hasFunctionDefinition(cursorPosition):
8986 from .DocstringGenerator.BaseDocstringGenerator import ( 8980 from .DocstringGenerator.BaseDocstringGenerator import ( # __IGNORE_WARNING__
8987 DocstringMenuForEnterOnly, 8981 DocstringMenuForEnterOnly,
8988 ) 8982 )
8989 8983
8990 docstringMenu = DocstringMenuForEnterOnly(self) 8984 docstringMenu = DocstringMenuForEnterOnly(self)
8991 act = docstringMenu.addAction( 8985 act = docstringMenu.addAction(

eric ide

mercurial