eric6/Plugins/VcsPlugins/vcsGit/GitDiffHighlighter.py

branch
without_py2_and_pyqt4
changeset 7192
a22eee00b052
parent 6942
2602857055c5
child 7229
53054eb5b15a
equal deleted inserted replaced
7191:960850ec284c 7192:a22eee00b052
7 Module implementing a syntax highlighter for diff outputs. 7 Module implementing a syntax highlighter for diff outputs.
8 """ 8 """
9 9
10 from __future__ import unicode_literals 10 from __future__ import unicode_literals
11 11
12 import re 12 from PyQt5.QtGui import QColor
13 13
14 from PyQt5.QtGui import QSyntaxHighlighter, QColor, QTextCharFormat, QFont 14 from E5Gui.E5GenericDiffHighlighter import TERMINAL, E5GenericDiffHighlighter
15
16 import Preferences
17
18 try:
19 from E5Gui.E5GenericDiffHighlighter import TERMINAL, \
20 E5GenericDiffHighlighter
21 except ImportError:
22 def TERMINAL(pattern):
23 """
24 Function to mark a pattern as the final one to search for.
25
26 @param pattern pattern to be marked (string)
27 @return marked pattern (string)
28 """
29 return "__TERMINAL__:{0}".format(pattern)
30
31 # Cache the results of re.compile for performance reasons
32 _REGEX_CACHE = {}
33
34 class E5GenericDiffHighlighter(QSyntaxHighlighter):
35 """
36 Class implementing a generic diff highlighter.
37 """
38 def __init__(self, doc):
39 """
40 Constructor
41
42 @param doc reference to the text document (QTextDocument)
43 """
44 super(E5GenericDiffHighlighter, self).__init__(doc)
45
46 self.textColor = QColor(0, 0, 0)
47 self.addedColor = QColor(190, 237, 190)
48 self.removedColor = QColor(237, 190, 190)
49 self.replacedColor = QColor(190, 190, 237)
50 self.contextColor = QColor(255, 220, 168)
51 self.headerColor = QColor(237, 237, 190)
52
53 self.normalFormat = self.makeFormat()
54
55 self._rules = []
56 self.generateRules()
57
58 def generateRules(self):
59 """
60 Public method to generate the rule set.
61
62 Note: This method must me implemented by derived syntax
63 highlighters.
64 """
65 pass
66
67 def createRules(self, *rules):
68 """
69 Public method to create the highlighting rules.
70
71 @param rules set of highlighting rules (list of tuples of rule
72 pattern (string) and highlighting format (QTextCharFormat))
73 """
74 for ruleFormat in rules:
75 rule, formats = ruleFormat
76 terminal = rule.startswith(TERMINAL(''))
77 if terminal:
78 rule = rule[len(TERMINAL('')):]
79 try:
80 regex = _REGEX_CACHE[rule]
81 except KeyError:
82 regex = _REGEX_CACHE[rule] = re.compile(rule)
83 self._rules.append((regex, formats, terminal))
84
85 def formats(self, line):
86 """
87 Public method to determine the highlighting formats for a line of
88 text.
89
90 @param line text line to be highlighted (string)
91 @return list of matched highlighting rules (list of tuples of match
92 object and format (QTextCharFormat))
93 """
94 matched = []
95 for rx, formats, terminal in self._rules:
96 match = rx.match(line)
97 if not match:
98 continue
99 matched.append([match, formats])
100 if terminal:
101 return matched
102
103 return matched
104
105 def makeFormat(self, fg=None, bg=None, bold=False):
106 """
107 Public method to generate a format definition.
108
109 @param fg foreground color (QColor)
110 @param bg background color (QColor)
111 @param bold flag indicating bold text (boolean)
112 @return format definiton (QTextCharFormat)
113 """
114 font = Preferences.getEditorOtherFonts("MonospacedFont")
115 charFormat = QTextCharFormat()
116 charFormat.setFontFamily(font.family())
117 charFormat.setFontPointSize(font.pointSize())
118
119 if fg:
120 charFormat.setForeground(fg)
121
122 if bg:
123 charFormat.setBackground(bg)
124
125 if bold:
126 charFormat.setFontWeight(QFont.Bold)
127
128 return charFormat
129
130 def highlightBlock(self, text):
131 """
132 Public method to highlight a block of text.
133
134 @param text text to be highlighted (string)
135 """
136 formats = self.formats(text)
137 if not formats:
138 # nothing matched
139 self.setFormat(0, len(text), self.normalFormat)
140 return
141
142 for match, charFormat in formats:
143 start = match.start()
144 groups = match.groups()
145
146 # No groups in the regex, assume this is a single rule
147 # that spans the entire line
148 if not groups:
149 self.setFormat(0, len(text), charFormat)
150 continue
151
152 # Groups exist, rule is a tuple corresponding to group
153 for groupIndex, group in enumerate(groups):
154 if not group:
155 # empty match
156 continue
157
158 # allow None as a no-op format
159 length = len(group)
160 if charFormat[groupIndex]:
161 self.setFormat(start, start + length,
162 charFormat[groupIndex])
163 start += length
164 15
165 16
166 class GitDiffHighlighter(E5GenericDiffHighlighter): 17 class GitDiffHighlighter(E5GenericDiffHighlighter):
167 """ 18 """
168 Class implementing a diff highlighter for Git. 19 Class implementing a diff highlighter for Git.

eric ide

mercurial