diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/QScintilla/Lexers/LexerPygments.py --- a/src/eric7/QScintilla/Lexers/LexerPygments.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/QScintilla/Lexers/LexerPygments.py Wed Jul 13 14:55:47 2022 +0200 @@ -10,9 +10,7 @@ import contextlib from pygments.token import Token -from pygments.lexers import ( - guess_lexer_for_filename, guess_lexer, find_lexer_class -) +from pygments.lexers import guess_lexer_for_filename, guess_lexer, find_lexer_class from pygments.util import ClassNotFound from PyQt6.QtGui import QColor, QFont @@ -75,7 +73,7 @@ PYGMENTS_BACKTICKSTRING = 57 PYGMENTS_WHITESPACE = 58 -#-----------------------------------------------------------------------------# +# -----------------------------------------------------------------------------# TOKEN_MAP = { Token.Comment: PYGMENTS_COMMENT, @@ -85,11 +83,8 @@ Token.Comment.PreprocFile: PYGMENTS_PREPROCESSOR, Token.Comment.Single: PYGMENTS_COMMENT, Token.Comment.Special: PYGMENTS_COMMENT, - Token.Escape: PYGMENTS_ESCAPE, - Token.Error: PYGMENTS_ERROR, - Token.Generic: PYGMENTS_DEFAULT, Token.Generic.Deleted: PYGMENTS_DELETED, Token.Generic.Emph: PYGMENTS_EMPHASIZE, @@ -101,7 +96,6 @@ Token.Generic.Strong: PYGMENTS_STRONG, Token.Generic.Subheading: PYGMENTS_SUBHEADING, Token.Generic.Traceback: PYGMENTS_TRACEBACK, - Token.Keyword: PYGMENTS_KEYWORD, Token.Keyword.Constant: PYGMENTS_KEYWORD, Token.Keyword.Declaration: PYGMENTS_KEYWORD, @@ -109,10 +103,8 @@ Token.Keyword.Pseudo: PYGMENTS_PSEUDOKEYWORD, Token.Keyword.Reserved: PYGMENTS_RESERVEDKEYWORD, Token.Keyword.Type: PYGMENTS_TYPEKEYWORD, - Token.Literal: PYGMENTS_LITERAL, Token.Literal.Date: PYGMENTS_LITERAL, - Token.Name: PYGMENTS_DEFAULT, Token.Name.Attribute: PYGMENTS_ATTRIBUTE, Token.Name.Builtin: PYGMENTS_BUILTIN, @@ -134,7 +126,6 @@ Token.Name.Variable.Global: PYGMENTS_VARIABLE, Token.Name.Variable.Instance: PYGMENTS_VARIABLE, Token.Name.Variable.Magic: PYGMENTS_VARIABLE, - Token.Number: PYGMENTS_NUMBER, Token.Number.Bin: PYGMENTS_NUMBER, Token.Number.Float: PYGMENTS_NUMBER, @@ -142,14 +133,10 @@ Token.Number.Integer: PYGMENTS_NUMBER, Token.Number.Integer.Long: PYGMENTS_NUMBER, Token.Number.Oct: PYGMENTS_NUMBER, - Token.Operator: PYGMENTS_OPERATOR, Token.Operator.Word: PYGMENTS_WORD, - Token.Other: PYGMENTS_DEFAULT, - Token.Punctuation: PYGMENTS_PUNCTUATION, - Token.String: PYGMENTS_STRING, Token.String.Affix: PYGMENTS_STRING, Token.String.Backtick: PYGMENTS_BACKTICKSTRING, @@ -164,30 +151,29 @@ Token.String.Regex: PYGMENTS_REGEX, Token.String.Single: PYGMENTS_SINGLESTRING, Token.String.Symbol: PYGMENTS_SYMBOL, - Token.Whitespace: PYGMENTS_WHITESPACE, - Token.Text: PYGMENTS_DEFAULT, } -#-----------------------------------------------------------------------------# +# -----------------------------------------------------------------------------# class LexerPygments(LexerContainer): """ Class implementing a custom lexer using pygments. """ + def __init__(self, parent=None, name=""): """ Constructor - + @param parent parent widget of this lexer @param name name of the pygments lexer to use (string) """ super().__init__(parent) - + self.__inReadSettings = False - + if name.startswith("Pygments|"): self.__forcedPygmentsName = True self.__pygmentsName = name.replace("Pygments|", "") @@ -197,7 +183,7 @@ else: self.__pygmentsName = "" self.__forcedPygmentsName = False - + self.descriptions = { PYGMENTS_DEFAULT: self.tr("Default"), PYGMENTS_COMMENT: self.tr("Comment"), @@ -251,7 +237,7 @@ PYGMENTS_BACKTICKSTRING: self.tr("Backtick string"), PYGMENTS_WHITESPACE: self.tr("Whitespace"), } - + self.defaultColors = { PYGMENTS_DEFAULT: QColor("#000000"), PYGMENTS_COMMENT: QColor("#408080"), @@ -302,27 +288,27 @@ PYGMENTS_BACKTICKSTRING: QColor("#FFFF00"), PYGMENTS_WHITESPACE: QColor("#BBBBBB"), } - + self.defaultPapers = { PYGMENTS_ERROR: QColor("#FF0000"), PYGMENTS_MULTILINECOMMENT: QColor("#A8FFA8"), PYGMENTS_HEREDOC: QColor("#DDD0DD"), PYGMENTS_BACKTICKSTRING: QColor("#a08080"), } - + self.defaultEolFills = { PYGMENTS_ERROR: True, PYGMENTS_MULTILINECOMMENT: True, PYGMENTS_HEREDOC: True, PYGMENTS_BACKTICKSTRING: True, } - + def readSettings(self, qs, prefix="/Scintilla"): """ Public method to read the lexer settings. - + Note: Overridden to treat the Pygments lexer specially. - + @param qs reference to the settings object @type QSettings @param prefix prefix for the settings key (defaults to "/Scintilla") @@ -331,23 +317,23 @@ self.__inReadSettings = True super().readSettings(qs, prefix=prefix) self.__inReadSettings = False - + def language(self): """ Public method returning the language of the lexer. - + @return language of the lexer (string) """ if self.__pygmentsName and not self.__inReadSettings: return self.__pygmentsName else: return "Guessed" - + def description(self, style): """ Public method returning the descriptions of the styles supported by the lexer. - + @param style style number (integer) @return description for the style (string) """ @@ -355,11 +341,11 @@ return self.descriptions[style] except KeyError: return "" - + def defaultColor(self, style): """ Public method to get the default foreground color for a style. - + @param style style number (integer) @return foreground color (QColor) """ @@ -367,11 +353,11 @@ return self.defaultColors[style] except KeyError: return LexerContainer.defaultColor(self, style) - + def defaultPaper(self, style): """ Public method to get the default background color for a style. - + @param style style number (integer) @return background color (QColor) """ @@ -379,16 +365,19 @@ return self.defaultPapers[style] except KeyError: return LexerContainer.defaultPaper(self, style) - + def defaultFont(self, style): """ Public method to get the default font for a style. - + @param style style number (integer) @return font (QFont) """ - if style in [PYGMENTS_COMMENT, PYGMENTS_PREPROCESSOR, - PYGMENTS_MULTILINECOMMENT]: + if style in [ + PYGMENTS_COMMENT, + PYGMENTS_PREPROCESSOR, + PYGMENTS_MULTILINECOMMENT, + ]: if Utilities.isWindowsPlatform(): f = QFont(["Comic Sans MS"], 9) elif Utilities.isMacPlatform(): @@ -398,7 +387,7 @@ if style == PYGMENTS_PREPROCESSOR: f.setItalic(True) return f - + if style in [PYGMENTS_STRING, PYGMENTS_CHAR]: if Utilities.isWindowsPlatform(): return QFont(["Comic Sans MS"], 10) @@ -406,28 +395,41 @@ f = QFont(["Courier"], 11) else: return QFont(["Bitstream Vera Serif"], 10) - - if style in [PYGMENTS_KEYWORD, PYGMENTS_OPERATOR, PYGMENTS_WORD, - PYGMENTS_BUILTIN, PYGMENTS_ATTRIBUTE, PYGMENTS_FUNCTION, - PYGMENTS_CLASS, PYGMENTS_NAMESPACE, PYGMENTS_EXCEPTION, - PYGMENTS_ENTITY, PYGMENTS_TAG, PYGMENTS_SCALAR, - PYGMENTS_ESCAPE, PYGMENTS_HEADING, PYGMENTS_SUBHEADING, - PYGMENTS_STRONG, PYGMENTS_PROMPT]: + + if style in [ + PYGMENTS_KEYWORD, + PYGMENTS_OPERATOR, + PYGMENTS_WORD, + PYGMENTS_BUILTIN, + PYGMENTS_ATTRIBUTE, + PYGMENTS_FUNCTION, + PYGMENTS_CLASS, + PYGMENTS_NAMESPACE, + PYGMENTS_EXCEPTION, + PYGMENTS_ENTITY, + PYGMENTS_TAG, + PYGMENTS_SCALAR, + PYGMENTS_ESCAPE, + PYGMENTS_HEADING, + PYGMENTS_SUBHEADING, + PYGMENTS_STRONG, + PYGMENTS_PROMPT, + ]: f = LexerContainer.defaultFont(self, style) f.setBold(True) return f - + if style in [PYGMENTS_DOCSTRING, PYGMENTS_EMPHASIZE]: f = LexerContainer.defaultFont(self, style) f.setItalic(True) return f - + return LexerContainer.defaultFont(self, style) - + def defaultEolFill(self, style): """ Public method to get the default fill to eol flag. - + @param style style number (integer) @return fill to eol flag (boolean) """ @@ -435,21 +437,21 @@ return self.defaultEolFills[style] except KeyError: return LexerContainer.defaultEolFill(self, style) - + def __guessLexer(self, text): """ Private method to guess a pygments lexer. - + @param text text to base guessing on (string) @return reference to the guessed lexer (pygments.lexer) """ lexer = None - + if self.__pygmentsName: lexerClass = find_lexer_class(self.__pygmentsName) if lexerClass is not None: lexer = lexerClass() - + elif text: # step 1: guess based on filename and text if self.editor is not None: @@ -457,50 +459,50 @@ if fn: with contextlib.suppress(ClassNotFound, AttributeError): lexer = guess_lexer_for_filename(fn, text) - + # step 2: guess on text only if lexer is None: with contextlib.suppress(ClassNotFound, AttributeError): lexer = guess_lexer(text) - + return lexer - + def canStyle(self): """ Public method to check, if the lexer is able to style the text. - + @return flag indicating the lexer capability (boolean) """ if self.editor is None: return True - + text = self.editor.text() self.__lexer = self.__guessLexer(text) - + return self.__lexer is not None - + def name(self): """ Public method to get the name of the pygments lexer. - + @return name of the pygments lexer (string) """ if self.__lexer is None: return "" else: return self.__lexer.name - + def styleText(self, start, end): """ Public method to perform the styling. - + @param start position of first character to be styled (integer) @param end position of last character to be styled (integer) """ - text = self.editor.text()[:end + 1] + text = self.editor.text()[: end + 1] textLen = len(text.encode("utf-8")) self.__lexer = self.__guessLexer(text) - + cpos = 0 # adjust start position because pygments ignores empty line at # start of text @@ -509,50 +511,56 @@ cpos += 1 else: break - - self.editor.startStyling(cpos, 0x3f) + + self.editor.startStyling(cpos, 0x3F) if self.__lexer is None: self.editor.setStyling(len(text), PYGMENTS_DEFAULT) else: eolLen = len(self.editor.getLineSeparator()) for token, txt in self.__lexer.get_tokens(text): style = TOKEN_MAP.get(token, PYGMENTS_DEFAULT) - - tlen = len(txt.encode('utf-8')) + + tlen = len(txt.encode("utf-8")) if eolLen > 1: - tlen += txt.count('\n') + tlen += txt.count("\n") cpos += tlen if tlen and cpos < textLen: self.editor.setStyling(tlen, style) if cpos >= textLen: break - self.editor.startStyling(cpos, 0x3f) - + self.editor.startStyling(cpos, 0x3F) + def isCommentStyle(self, style): """ Public method to check, if a style is a comment style. - + @param style style to check (integer) @return flag indicating a comment style (boolean) """ return style in [PYGMENTS_COMMENT] - + def isStringStyle(self, style): """ Public method to check, if a style is a string style. - + @param style style to check (integer) @return flag indicating a string style (boolean) """ - return style in [PYGMENTS_STRING, PYGMENTS_DOCSTRING, PYGMENTS_OTHER, - PYGMENTS_HEADING, PYGMENTS_SUBHEADING, - PYGMENTS_EMPHASIZE, PYGMENTS_STRONG] - + return style in [ + PYGMENTS_STRING, + PYGMENTS_DOCSTRING, + PYGMENTS_OTHER, + PYGMENTS_HEADING, + PYGMENTS_SUBHEADING, + PYGMENTS_EMPHASIZE, + PYGMENTS_STRONG, + ] + def defaultKeywords(self, kwSet): """ Public method to get the default keywords. - + @param kwSet number of the keyword set (integer) @return string giving the keywords (string) or None """ - return None # __IGNORE_WARNING_M831__ + return None # __IGNORE_WARNING_M831__