redcar-javamateview 0.1-java
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +34 -0
- data/README +58 -0
- data/Rakefile +94 -0
- data/lib/javamateview.rb +41 -0
- data/lib/javamateview/example.rb +334 -0
- data/lib/javamateview/jar/java-mateview.jar +0 -0
- data/lib/javamateview/jcodings.jar +0 -0
- data/lib/javamateview/jdom.jar +0 -0
- data/lib/javamateview/joni.jar +0 -0
- data/spec/onig/match_spec.rb +50 -0
- data/spec/parsing/dynamic_parsing_spec.rb +172 -0
- data/spec/parsing/static_parsing_spec.rb +476 -0
- data/spec/spec_helper.rb +33 -0
- data/src/com/redcareditor/mate/Bundle.java +81 -0
- data/src/com/redcareditor/mate/DoublePattern.java +89 -0
- data/src/com/redcareditor/mate/Grammar.java +129 -0
- data/src/com/redcareditor/mate/IAnnotationAreaListener.java +7 -0
- data/src/com/redcareditor/mate/IGrammarListener.java +5 -0
- data/src/com/redcareditor/mate/IncludePattern.java +10 -0
- data/src/com/redcareditor/mate/LineNumberRulerColumn.java +922 -0
- data/src/com/redcareditor/mate/Marker.java +22 -0
- data/src/com/redcareditor/mate/MateText.java +697 -0
- data/src/com/redcareditor/mate/ParseThunk.java +71 -0
- data/src/com/redcareditor/mate/Parser.java +627 -0
- data/src/com/redcareditor/mate/ParserScheduler.java +237 -0
- data/src/com/redcareditor/mate/Pattern.java +152 -0
- data/src/com/redcareditor/mate/RangeSet.java +91 -0
- data/src/com/redcareditor/mate/Scanner.java +178 -0
- data/src/com/redcareditor/mate/Scope.java +534 -0
- data/src/com/redcareditor/mate/ScopeMatcher.java +162 -0
- data/src/com/redcareditor/mate/SharedTextColors.java +110 -0
- data/src/com/redcareditor/mate/SinglePattern.java +20 -0
- data/src/com/redcareditor/mate/WhitespaceCharacterPainter.java +395 -0
- data/src/com/redcareditor/mate/colouring/Colourer.java +16 -0
- data/src/com/redcareditor/mate/colouring/swt/MarginPaintListener.java +62 -0
- data/src/com/redcareditor/mate/colouring/swt/SwtColourer.java +501 -0
- data/src/com/redcareditor/mate/document/MateDocument.java +15 -0
- data/src/com/redcareditor/mate/document/MateTextFactory.java +9 -0
- data/src/com/redcareditor/mate/document/MateTextLocation.java +8 -0
- data/src/com/redcareditor/mate/document/MateTextLocationComparator.java +17 -0
- data/src/com/redcareditor/mate/document/MateTextRange.java +18 -0
- data/src/com/redcareditor/mate/document/swt/SwtMateDocument.java +143 -0
- data/src/com/redcareditor/mate/document/swt/SwtMateTextLocation.java +88 -0
- data/src/com/redcareditor/mate/document/swt/SwtMateTextRange.java +92 -0
- data/src/com/redcareditor/mate/document/swt/SwtScopePositionUpdater.java +90 -0
- data/src/com/redcareditor/mate/undo/MateTextUndoManager.java +11 -0
- data/src/com/redcareditor/mate/undo/swt/SwtMateTextUndoManager.java +166 -0
- data/src/com/redcareditor/onig/Match.java +212 -0
- data/src/com/redcareditor/onig/NullMatch.java +57 -0
- data/src/com/redcareditor/onig/NullRx.java +29 -0
- data/src/com/redcareditor/onig/Range.java +45 -0
- data/src/com/redcareditor/onig/Rx.java +167 -0
- data/src/com/redcareditor/plist/Dict.java +119 -0
- data/src/com/redcareditor/plist/PlistNode.java +52 -0
- data/src/com/redcareditor/plist/PlistPropertyLoader.java +44 -0
- data/src/com/redcareditor/theme/ScopeSelector.java +39 -0
- data/src/com/redcareditor/theme/Theme.java +122 -0
- data/src/com/redcareditor/theme/ThemeManager.java +41 -0
- data/src/com/redcareditor/theme/ThemeSetting.java +78 -0
- data/src/com/redcareditor/util/FileUtility.java +64 -0
- data/src/com/redcareditor/util/SingleLineFormatter.java +11 -0
- data/src/com/redcareditor/util/swt/ColourUtil.java +56 -0
- data/src/ruby/java-mateview.rb +68 -0
- data/test/com/redcareditor/mate/BundleTest.java +33 -0
- data/test/com/redcareditor/mate/EmptyRangeSetTest.java +27 -0
- data/test/com/redcareditor/mate/FilledRangeSetTest.java +82 -0
- data/test/com/redcareditor/mate/GrammarTest.java +158 -0
- data/test/com/redcareditor/mate/MateTextTest.java +35 -0
- data/test/com/redcareditor/mate/ScopeMatcherMatchingTest.java +55 -0
- data/test/com/redcareditor/mate/ScopeMatcherRankingTest.java +40 -0
- data/test/com/redcareditor/onig/RxTest.java +54 -0
- data/test/com/redcareditor/plist/DictTest.java +33 -0
- data/test/com/redcareditor/theme/RailsCastThemeTest.java +37 -0
- data/test/com/redcareditor/theme/ScopeSelectorTest.java +38 -0
- data/test/com/redcareditor/theme/ThemeManagerTest.java +29 -0
- data/test/com/redcareditor/util/swt/ColourUtilTest.java +17 -0
- metadata +142 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
package com.redcareditor.mate.colouring;
|
2
|
+
|
3
|
+
import java.util.List;
|
4
|
+
|
5
|
+
import com.redcareditor.mate.Scope;
|
6
|
+
import com.redcareditor.theme.Theme;
|
7
|
+
|
8
|
+
public interface Colourer {
|
9
|
+
|
10
|
+
public abstract void setTheme(Theme theme);
|
11
|
+
|
12
|
+
public abstract Theme getTheme();
|
13
|
+
|
14
|
+
public abstract void setGlobalColours();
|
15
|
+
|
16
|
+
}
|
@@ -0,0 +1,62 @@
|
|
1
|
+
package com.redcareditor.mate.colouring.swt;
|
2
|
+
|
3
|
+
import org.eclipse.swt.SWT;
|
4
|
+
import org.eclipse.swt.custom.StyledText;
|
5
|
+
import org.eclipse.swt.events.PaintEvent;
|
6
|
+
import org.eclipse.swt.events.PaintListener;
|
7
|
+
import org.eclipse.swt.graphics.Color;
|
8
|
+
import org.eclipse.swt.graphics.GC;
|
9
|
+
import org.eclipse.swt.graphics.Rectangle;
|
10
|
+
import org.eclipse.swt.widgets.Display;
|
11
|
+
|
12
|
+
import com.redcareditor.mate.MateText;
|
13
|
+
|
14
|
+
public class MarginPaintListener implements PaintListener {
|
15
|
+
static Color marginColor = Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
|
16
|
+
|
17
|
+
private MateText mateText;
|
18
|
+
private StyledText control;
|
19
|
+
|
20
|
+
|
21
|
+
public MarginPaintListener(MateText mateText) {
|
22
|
+
this.mateText = mateText;
|
23
|
+
this.control = mateText.getControl();
|
24
|
+
}
|
25
|
+
|
26
|
+
public void paintControl(PaintEvent e) {
|
27
|
+
int marginColumn = mateText.getMarginColumn();
|
28
|
+
if (marginColumn == -1) return;
|
29
|
+
drawMargin(e.gc, marginColumn);
|
30
|
+
}
|
31
|
+
|
32
|
+
private void drawMargin(GC gc, int marginColumn) {
|
33
|
+
int width = gc.getFontMetrics().getAverageCharWidth() * marginColumn + control.getLeftMargin();
|
34
|
+
Rectangle controlBounds = control.getBounds();
|
35
|
+
if (gc.getAdvanced()) {
|
36
|
+
drawMarginOverlay(gc, width, controlBounds);
|
37
|
+
} else {
|
38
|
+
drawMarginLine(gc, width, controlBounds);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
private void drawMarginLine(GC gc, int width, Rectangle controlBounds) {
|
43
|
+
Color fgColor = gc.getForeground();
|
44
|
+
gc.setForeground(getMarginColor());
|
45
|
+
gc.drawLine(width, 0, width, controlBounds.height);
|
46
|
+
gc.setForeground(fgColor);
|
47
|
+
}
|
48
|
+
|
49
|
+
private void drawMarginOverlay(GC gc, int width, Rectangle controlBounds) {
|
50
|
+
Color bgColor = gc.getBackground();
|
51
|
+
int alpha = gc.getAlpha();
|
52
|
+
gc.setBackground(getMarginColor());
|
53
|
+
gc.setAlpha(64); // Draw transparently over widget. We cannot draw under the text (!)
|
54
|
+
gc.fillRectangle(width, 0, controlBounds.width, controlBounds.height);
|
55
|
+
gc.setAlpha(alpha);
|
56
|
+
gc.setForeground(bgColor);
|
57
|
+
}
|
58
|
+
|
59
|
+
static private Color getMarginColor() {
|
60
|
+
return marginColor;
|
61
|
+
}
|
62
|
+
}
|
@@ -0,0 +1,501 @@
|
|
1
|
+
package com.redcareditor.mate.colouring.swt;
|
2
|
+
|
3
|
+
import java.util.ArrayList;
|
4
|
+
import java.util.Comparator;
|
5
|
+
|
6
|
+
import org.eclipse.swt.SWT;
|
7
|
+
import org.eclipse.swt.custom.CaretEvent;
|
8
|
+
import org.eclipse.swt.custom.CaretListener;
|
9
|
+
import org.eclipse.swt.custom.LineStyleEvent;
|
10
|
+
import org.eclipse.swt.custom.LineStyleListener;
|
11
|
+
import org.eclipse.swt.custom.StyleRange;
|
12
|
+
import org.eclipse.swt.custom.StyledText;
|
13
|
+
import org.eclipse.swt.events.ModifyEvent;
|
14
|
+
import org.eclipse.swt.events.ModifyListener;
|
15
|
+
import org.eclipse.swt.events.VerifyEvent;
|
16
|
+
import org.eclipse.swt.events.VerifyListener;
|
17
|
+
import org.eclipse.swt.graphics.Color;
|
18
|
+
import org.eclipse.swt.graphics.Image;
|
19
|
+
import org.eclipse.swt.graphics.ImageData;
|
20
|
+
import org.eclipse.swt.graphics.PaletteData;
|
21
|
+
import org.eclipse.swt.graphics.RGB;
|
22
|
+
import org.eclipse.swt.graphics.Rectangle;
|
23
|
+
import org.eclipse.swt.widgets.Caret;
|
24
|
+
import org.eclipse.swt.widgets.Display;
|
25
|
+
|
26
|
+
import com.redcareditor.mate.DoublePattern;
|
27
|
+
import com.redcareditor.mate.MateText;
|
28
|
+
import com.redcareditor.mate.Scope;
|
29
|
+
import com.redcareditor.mate.SinglePattern;
|
30
|
+
import com.redcareditor.mate.colouring.Colourer;
|
31
|
+
import com.redcareditor.theme.Theme;
|
32
|
+
import com.redcareditor.theme.ThemeSetting;
|
33
|
+
import com.redcareditor.util.swt.ColourUtil;
|
34
|
+
|
35
|
+
public class SwtColourer implements Colourer {
|
36
|
+
private Theme theme;
|
37
|
+
private MateText mateText;
|
38
|
+
|
39
|
+
private int highlightedLine = 0;
|
40
|
+
private StyledText control;
|
41
|
+
|
42
|
+
public SwtColourer(MateText mt) {
|
43
|
+
mateText = mt;
|
44
|
+
|
45
|
+
control = mateText.getControl();
|
46
|
+
|
47
|
+
this.control.addPaintListener(new MarginPaintListener(mateText));
|
48
|
+
this.control.addLineStyleListener(new LineStyleListener() {
|
49
|
+
public void lineGetStyle(LineStyleEvent event) {
|
50
|
+
colourLine(event);
|
51
|
+
}
|
52
|
+
});
|
53
|
+
|
54
|
+
addCaretMovedListeners();
|
55
|
+
}
|
56
|
+
|
57
|
+
private boolean inModification = false;
|
58
|
+
private int lineToUpdate = -1;
|
59
|
+
|
60
|
+
// This little dance with these three listeners and two attributes is necessary because
|
61
|
+
// the caretMoved event is fired before the text is modified in the buffer, so
|
62
|
+
// control.getLineCount() is not uptodate when it is called in updateHighlightedLine.
|
63
|
+
private void addCaretMovedListeners() {
|
64
|
+
control.addCaretListener(new CaretListener() {
|
65
|
+
public void caretMoved(CaretEvent e) {
|
66
|
+
lineToUpdate = control.getLineAtOffset(e.caretOffset);
|
67
|
+
if (!inModification) {
|
68
|
+
updateHighlightedLine(lineToUpdate);
|
69
|
+
lineToUpdate = -1;
|
70
|
+
}
|
71
|
+
}
|
72
|
+
});
|
73
|
+
|
74
|
+
control.addModifyListener(new ModifyListener() {
|
75
|
+
public void modifyText(ModifyEvent e) {
|
76
|
+
if (inModification && lineToUpdate != -1) {
|
77
|
+
updateHighlightedLine(lineToUpdate);
|
78
|
+
}
|
79
|
+
inModification = false;
|
80
|
+
lineToUpdate = -1;
|
81
|
+
}
|
82
|
+
});
|
83
|
+
|
84
|
+
control.addVerifyListener(new VerifyListener() {
|
85
|
+
public void verifyText(VerifyEvent e) {
|
86
|
+
inModification = true;
|
87
|
+
}
|
88
|
+
});
|
89
|
+
}
|
90
|
+
|
91
|
+
private void updateHighlightedLine(int line) {
|
92
|
+
if (caretLineHasChanged(line)) {
|
93
|
+
try {
|
94
|
+
int maxLineIx = control.getLineCount() - 1;
|
95
|
+
if (line <= maxLineIx)
|
96
|
+
control.setLineBackground(line, 1, ColourUtil.getColour(globalLineBackground()));
|
97
|
+
if (highlightedLine <= maxLineIx)
|
98
|
+
control.setLineBackground(highlightedLine, 1, ColourUtil.getColour(globalBackground()));
|
99
|
+
highlightedLine = line;
|
100
|
+
}
|
101
|
+
catch(java.lang.ArrayIndexOutOfBoundsException e) {
|
102
|
+
|
103
|
+
}
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
private boolean caretLineHasChanged(int line) {
|
108
|
+
return line != highlightedLine;
|
109
|
+
}
|
110
|
+
|
111
|
+
public void setTheme(Theme theme) {
|
112
|
+
this.theme = theme;
|
113
|
+
theme.initForUse();
|
114
|
+
setGlobalColours();
|
115
|
+
}
|
116
|
+
|
117
|
+
public void setGlobalColours() {
|
118
|
+
if (theme != null) {
|
119
|
+
setMateTextColours();
|
120
|
+
setCaretColour();
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
private void setCaretColour() {
|
125
|
+
Caret caret = control.getCaret();
|
126
|
+
Rectangle bounds = caret.getBounds();
|
127
|
+
int width = bounds.width;
|
128
|
+
int height = bounds.height;
|
129
|
+
caret = new Caret(control, SWT.NONE);
|
130
|
+
Display display = Display.getCurrent();
|
131
|
+
// System.out.printf("caret colour: %s %d %d\n", globalColour("caret"), width, height);
|
132
|
+
String caretColourString = bareGlobalColour("caret");
|
133
|
+
Color caretColour = ColourUtil.getColour(caretColourString);
|
134
|
+
Color white = display.getSystemColor(SWT.COLOR_WHITE);
|
135
|
+
Color black = display.getSystemColor(SWT.COLOR_BLACK);
|
136
|
+
String backgroundColourString = globalBackground();
|
137
|
+
int red = Integer.parseInt(backgroundColourString.substring(1, 3), 16) ^
|
138
|
+
Integer.parseInt(caretColourString.substring(1, 3), 16);
|
139
|
+
int green = Integer.parseInt(backgroundColourString.substring(3, 5), 16) ^
|
140
|
+
Integer.parseInt(caretColourString.substring(3, 5), 16);
|
141
|
+
int blue = Integer.parseInt(backgroundColourString.substring(5, 7), 16) ^
|
142
|
+
Integer.parseInt(caretColourString.substring(5, 7), 16);
|
143
|
+
PaletteData palette = new PaletteData (
|
144
|
+
new RGB [] {
|
145
|
+
new RGB (0, 0, 0),
|
146
|
+
new RGB (red, green, blue),
|
147
|
+
new RGB (0xFF, 0xFF, 0xFF),
|
148
|
+
});
|
149
|
+
ImageData maskData = new ImageData (1, height, 2, palette);
|
150
|
+
for (int y=0; y < height; y++)
|
151
|
+
maskData.setPixel(0, y, 1);
|
152
|
+
Image image = new Image (display, maskData);
|
153
|
+
caret.setImage(image);
|
154
|
+
control.setCaret(caret);
|
155
|
+
}
|
156
|
+
|
157
|
+
private void setMateTextColours() {
|
158
|
+
control.setBackground(ColourUtil.getColour(globalBackground()));
|
159
|
+
control.setForeground(ColourUtil.getColour(globalForeground()));
|
160
|
+
int currentLine = control.getLineAtOffset(control.getCaretOffset());
|
161
|
+
// int startLine = JFaceTextUtil.getPartialTopIndex(control);
|
162
|
+
// int endLine = JFaceTextUtil.getPartialBottomIndex(control);
|
163
|
+
for (int i = 0; i < control.getLineCount(); i ++)
|
164
|
+
control.setLineBackground(i, 1, ColourUtil.getColour(globalBackground()));
|
165
|
+
control.setLineBackground(currentLine, 1, ColourUtil.getColour(globalLineBackground()));
|
166
|
+
mateText.setGutterBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
|
167
|
+
mateText.setGutterForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY));
|
168
|
+
}
|
169
|
+
|
170
|
+
public Theme getTheme() {
|
171
|
+
return theme;
|
172
|
+
}
|
173
|
+
|
174
|
+
private ThemeSetting globalThemeSetting() {
|
175
|
+
if (mateText.parser != null && mateText.parser.grammar != null && theme != null) {
|
176
|
+
return theme.findSetting(mateText.parser.grammar.scopeName, false, null);
|
177
|
+
}
|
178
|
+
else {
|
179
|
+
return new ThemeSetting();
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
private String globalBackground() {
|
184
|
+
ThemeSetting globalSetting = globalThemeSetting();
|
185
|
+
if (globalSetting.background == null) {
|
186
|
+
return bareGlobalColour("background");
|
187
|
+
}
|
188
|
+
else {
|
189
|
+
return globalSetting.background;
|
190
|
+
}
|
191
|
+
}
|
192
|
+
|
193
|
+
private String globalForeground() {
|
194
|
+
ThemeSetting globalSetting = globalThemeSetting();
|
195
|
+
if (globalSetting.foreground == null) {
|
196
|
+
return bareGlobalColour("foreground");
|
197
|
+
}
|
198
|
+
else {
|
199
|
+
return globalSetting.foreground;
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
private String globalLineBackground() {
|
204
|
+
return ColourUtil.mergeColour(globalBackground(), bareGlobalColour("lineHighlight"));
|
205
|
+
}
|
206
|
+
|
207
|
+
private String bareGlobalColour(String name) {
|
208
|
+
if (theme == null)
|
209
|
+
return "#FFFFFF";
|
210
|
+
String colour = theme.globalSettings.get(name);
|
211
|
+
if (isColorDefined(colour)) {
|
212
|
+
return colour;
|
213
|
+
} else {
|
214
|
+
return "#FFFFFF";
|
215
|
+
}
|
216
|
+
}
|
217
|
+
|
218
|
+
private boolean themeHasMarginColours() {
|
219
|
+
return (theme.globalSettings.get("marginForeground") != null &&
|
220
|
+
theme.globalSettings.get("marginBackground") != null);
|
221
|
+
}
|
222
|
+
|
223
|
+
private Color globalMarginForeground() {
|
224
|
+
return ColourUtil.getColour(theme.globalSettings.get("marginForeground"));
|
225
|
+
}
|
226
|
+
|
227
|
+
private Color globalMarginBackground() {
|
228
|
+
return ColourUtil.getColour(theme.globalSettings.get("marginBackground"));
|
229
|
+
}
|
230
|
+
|
231
|
+
private boolean isColorDefined(String colour) {
|
232
|
+
return colour != null && !(colour.length() == 0);
|
233
|
+
}
|
234
|
+
|
235
|
+
public class StyleRangeComparator implements Comparator {
|
236
|
+
|
237
|
+
public int compare(Object o1, Object o2) {
|
238
|
+
StyleRange s1 = (StyleRange) o1;
|
239
|
+
StyleRange s2 = (StyleRange) o2;
|
240
|
+
if (s1.start < s2.start) {
|
241
|
+
return -1;
|
242
|
+
} else {
|
243
|
+
if (s1.start > s2.start) {
|
244
|
+
return 1;
|
245
|
+
}
|
246
|
+
else {
|
247
|
+
if (s1.length < s2.length) {
|
248
|
+
return -1;
|
249
|
+
}
|
250
|
+
else {
|
251
|
+
if (s1.length > s2.length) {
|
252
|
+
return 1;
|
253
|
+
}
|
254
|
+
else {
|
255
|
+
return 0;
|
256
|
+
}
|
257
|
+
}
|
258
|
+
}
|
259
|
+
}
|
260
|
+
}
|
261
|
+
|
262
|
+
public boolean equals(Object obj) {
|
263
|
+
return false;
|
264
|
+
}
|
265
|
+
}
|
266
|
+
|
267
|
+
private void colourLine(LineStyleEvent event) {
|
268
|
+
if (theme == null)
|
269
|
+
return;
|
270
|
+
if (!mateText.shouldColour())
|
271
|
+
return;
|
272
|
+
int eventLine = mateText.getControl().getLineAtOffset(event.lineOffset);
|
273
|
+
// System.out.printf("c%d, ", eventLine);
|
274
|
+
|
275
|
+
// ArrayList<Scope> scopes = mateText.parser.root.scopesOnLine(eventLine);
|
276
|
+
int startLineOffset = event.lineOffset;
|
277
|
+
int endLineOffset;
|
278
|
+
|
279
|
+
if (eventLine >= mateText.getControl().getLineCount() - 1)
|
280
|
+
endLineOffset = mateText.getControl().getCharCount();
|
281
|
+
else
|
282
|
+
endLineOffset = mateText.getControl().getOffsetAtLine(eventLine + 1);
|
283
|
+
|
284
|
+
ArrayList<Scope> scopes = mateText.parser.root.scopesBetween(startLineOffset, endLineOffset);
|
285
|
+
//System.out.printf("[Color] colouring %d (%d-%d) n%d\n", eventLine, startLineOffset, endLineOffset, scopes.size());
|
286
|
+
|
287
|
+
// System.out.printf("[Color] got to colour %d scopes\n", scopes.size());
|
288
|
+
ArrayList<StyleRange> styleRanges = new ArrayList<StyleRange>();
|
289
|
+
for (Scope scope : scopes) {
|
290
|
+
// System.out.printf("[Color] scope: %s\n", scope.name);
|
291
|
+
if (scope.parent == null) {
|
292
|
+
continue;
|
293
|
+
}
|
294
|
+
if (scope.name == null && scope.pattern != null
|
295
|
+
&& (scope.pattern instanceof SinglePattern || ((DoublePattern) scope.pattern).contentName == null)) {
|
296
|
+
continue;
|
297
|
+
}
|
298
|
+
addStyleRangeForScope(styleRanges, scope, false, event);
|
299
|
+
if (scope.pattern instanceof DoublePattern && ((DoublePattern) scope.pattern).contentName != null && scope.isCapture == false)
|
300
|
+
addStyleRangeForScope(styleRanges, scope, true, event);
|
301
|
+
// printStyleRanges(styleRanges);
|
302
|
+
}
|
303
|
+
int tabWidth = mateText.getControl().getTabs();
|
304
|
+
addMarginColumnStyleRange(styleRanges, event, tabWidth);
|
305
|
+
|
306
|
+
event.styles = (StyleRange[]) styleRanges.toArray(new StyleRange[0]);
|
307
|
+
}
|
308
|
+
|
309
|
+
private void printStyleRanges(ArrayList<StyleRange> styleRanges) {
|
310
|
+
System.out.printf("[");
|
311
|
+
for (StyleRange r : styleRanges) {
|
312
|
+
System.out.printf("%s, ", r);
|
313
|
+
}
|
314
|
+
System.out.printf("]\n");
|
315
|
+
}
|
316
|
+
|
317
|
+
private void addStyleRangeForScope(ArrayList<StyleRange> styleRanges, Scope scope, boolean inner, LineStyleEvent event) {
|
318
|
+
StyleRange styleRange = new StyleRange();
|
319
|
+
|
320
|
+
ThemeSetting setting = null;
|
321
|
+
ThemeSetting excludeSetting = null;
|
322
|
+
if (scope.parent != null)
|
323
|
+
excludeSetting = scope.parent.themeSetting;
|
324
|
+
setting = theme.settingsForScope(scope, inner, null);
|
325
|
+
|
326
|
+
int startLineOffset = event.lineOffset;
|
327
|
+
int endLineOffset = startLineOffset + event.lineText.length();
|
328
|
+
|
329
|
+
if (inner) {
|
330
|
+
styleRange.start = Math.max(scope.getInnerStart().getOffset(), startLineOffset);
|
331
|
+
styleRange.length = Math.min(scope.getInnerEnd().getOffset() - styleRange.start,
|
332
|
+
event.lineText.length() - styleRange.start + startLineOffset);
|
333
|
+
} else {
|
334
|
+
styleRange.start = Math.max(scope.getStart().getOffset(), startLineOffset);
|
335
|
+
styleRange.length = Math.min(scope.getEnd().getOffset() - styleRange.start,
|
336
|
+
event.lineText.length() - styleRange.start + startLineOffset);
|
337
|
+
}
|
338
|
+
if (styleRange.length == 0)
|
339
|
+
return;
|
340
|
+
if (setting != null) {
|
341
|
+
setStyleRangeProperties(scope, setting, styleRange);
|
342
|
+
addStyleRangeWithoutOverlaps(styleRanges, styleRange);
|
343
|
+
//System.out.printf("[Color] style range (%d, %d) %s\n", styleRange.start, styleRange.length, styleRange.toString());
|
344
|
+
}
|
345
|
+
}
|
346
|
+
|
347
|
+
private void addMarginColumnStyleRange(ArrayList<StyleRange> styleRanges, LineStyleEvent event, int tabWidth) {
|
348
|
+
int marginColumn = mateText.getMarginColumn();
|
349
|
+
|
350
|
+
if (marginColumn == -1 || !themeHasMarginColours())
|
351
|
+
return;
|
352
|
+
|
353
|
+
int startLineOffset = event.lineOffset;
|
354
|
+
int endLineOffset = startLineOffset + event.lineText.length();
|
355
|
+
int maxColumn = MateText.columnOfLineOffset(event.lineText, endLineOffset - startLineOffset, tabWidth);
|
356
|
+
|
357
|
+
if (maxColumn <= marginColumn)
|
358
|
+
return;
|
359
|
+
|
360
|
+
StyleRange styleRange = new StyleRange();
|
361
|
+
|
362
|
+
int offsetOfColumn = MateText.lineOffsetOfColumn(event.lineText, marginColumn, tabWidth);
|
363
|
+
styleRange.start = startLineOffset + offsetOfColumn;
|
364
|
+
styleRange.length = endLineOffset - styleRange.start;
|
365
|
+
|
366
|
+
styleRange.background = globalMarginBackground();
|
367
|
+
styleRange.foreground = globalMarginForeground();
|
368
|
+
|
369
|
+
addStyleRangeWithoutOverlaps(styleRanges, styleRange);
|
370
|
+
}
|
371
|
+
|
372
|
+
private void addStyleRangeWithoutOverlaps(ArrayList<StyleRange> styleRanges, StyleRange styleRange) {
|
373
|
+
if (styleRanges.size() == 0) {
|
374
|
+
styleRanges.add(styleRange);
|
375
|
+
return;
|
376
|
+
}
|
377
|
+
|
378
|
+
// there is always an overlapping StyleRange because the document root scope is always in here
|
379
|
+
int indexOfParent = indexOfOverlappingStyleRange(styleRanges, styleRange);
|
380
|
+
if (indexOfParent == -1) {
|
381
|
+
styleRanges.add(styleRange);
|
382
|
+
return;
|
383
|
+
}
|
384
|
+
|
385
|
+
StyleRange parentStyleRange = styleRanges.get(indexOfParent);
|
386
|
+
|
387
|
+
int parentStart = parentStyleRange.start;
|
388
|
+
int parentEnd = parentStyleRange.start + parentStyleRange.length;
|
389
|
+
int childStart = styleRange.start;
|
390
|
+
int childEnd = styleRange.start + styleRange.length;
|
391
|
+
|
392
|
+
//System.out.printf("parent %d-%d, child: %d-%d\n", parentStart, parentEnd, childStart, childEnd);
|
393
|
+
|
394
|
+
// *-----*
|
395
|
+
// *-----*
|
396
|
+
if (parentStart == childStart && parentEnd == childEnd) {
|
397
|
+
styleRangeCopyValues(parentStyleRange, styleRange);
|
398
|
+
return;
|
399
|
+
}
|
400
|
+
|
401
|
+
// *------*
|
402
|
+
// *--*
|
403
|
+
if (childStart == parentStart) {
|
404
|
+
parentStyleRange.start = childEnd;
|
405
|
+
parentStyleRange.length -= styleRange.length;
|
406
|
+
styleRanges.add(indexOfParent, styleRange);
|
407
|
+
return;
|
408
|
+
}
|
409
|
+
|
410
|
+
// *------*
|
411
|
+
// *---*
|
412
|
+
if (childEnd == parentEnd) {
|
413
|
+
parentStyleRange.length = childStart - parentStart;
|
414
|
+
styleRanges.add(indexOfParent + 1, styleRange);
|
415
|
+
return;
|
416
|
+
}
|
417
|
+
|
418
|
+
// *----------*
|
419
|
+
// *---*
|
420
|
+
parentStyleRange.length = childStart - parentStart;
|
421
|
+
styleRanges.add(indexOfParent + 1, styleRange);
|
422
|
+
StyleRange newStyleRange = new StyleRange();
|
423
|
+
newStyleRange.start = childEnd;
|
424
|
+
newStyleRange.length = parentEnd - childEnd;
|
425
|
+
styleRangeCopyValues(newStyleRange, parentStyleRange);
|
426
|
+
styleRanges.add(indexOfParent + 2, newStyleRange);
|
427
|
+
}
|
428
|
+
|
429
|
+
private void styleRangeCopyValues(StyleRange target, StyleRange source) {
|
430
|
+
target.fontStyle = source.fontStyle;
|
431
|
+
target.foreground = source.foreground;
|
432
|
+
target.background = source.background;
|
433
|
+
target.underline = source.underline;
|
434
|
+
}
|
435
|
+
|
436
|
+
private int indexOfOverlappingStyleRange(ArrayList<StyleRange> styleRanges, StyleRange styleRange) {
|
437
|
+
int i = 0;
|
438
|
+
for (StyleRange possibleParent : styleRanges) {
|
439
|
+
if (possibleParent.start < styleRange.start + styleRange.length &&
|
440
|
+
possibleParent.start + possibleParent.length > styleRange.start)
|
441
|
+
return i;
|
442
|
+
i++;
|
443
|
+
}
|
444
|
+
return -1;
|
445
|
+
}
|
446
|
+
|
447
|
+
private void setStyleRangeProperties(Scope scope, ThemeSetting setting, StyleRange styleRange) {
|
448
|
+
String fontStyle = setting.fontStyle;
|
449
|
+
if (fontStyle != null) {
|
450
|
+
// TODO: make this support "bold italic" etc.
|
451
|
+
if (fontStyle.equals("italic")) {
|
452
|
+
styleRange.fontStyle = SWT.ITALIC;
|
453
|
+
}
|
454
|
+
if (fontStyle.equals("bold")) {
|
455
|
+
styleRange.fontStyle = SWT.BOLD;
|
456
|
+
}
|
457
|
+
if (fontStyle.equals("underline")) {
|
458
|
+
styleRange.underline = true;
|
459
|
+
}
|
460
|
+
}
|
461
|
+
|
462
|
+
String background = setting.background;
|
463
|
+
// System.out.printf("[Color] scope background: %s\n", background);
|
464
|
+
String mergedBgColour;
|
465
|
+
String parentBg = globalBackground();
|
466
|
+
//System.out.printf(" global background: %s\n", parentBg);
|
467
|
+
if (background != null && background != "") {
|
468
|
+
mergedBgColour = ColourUtil.mergeColour(parentBg, background);
|
469
|
+
if (mergedBgColour != null) {
|
470
|
+
scope.bgColour = mergedBgColour;
|
471
|
+
styleRange.background = ColourUtil.getColour(mergedBgColour);
|
472
|
+
// System.out.printf("[Color] background = %s\n", mergedBgColour);
|
473
|
+
}
|
474
|
+
} else {
|
475
|
+
mergedBgColour = parentBg;
|
476
|
+
}
|
477
|
+
// stdout.printf(" merged_bg_colour: %s\n", merged_bg_colour);
|
478
|
+
String foreground = setting.foreground;
|
479
|
+
// System.out.printf("[Color] scope foreground: %s\n", foreground);
|
480
|
+
String parentFg = scope.nearestForegroundColour();
|
481
|
+
if (parentFg == null) {
|
482
|
+
parentFg = globalForeground();
|
483
|
+
// stdout.printf(" global foreground: %s\n",
|
484
|
+
// parent_fg);
|
485
|
+
}
|
486
|
+
if (foreground != null && foreground != "") {
|
487
|
+
String mergedFgColour;
|
488
|
+
if (parentFg != null && !scope.isCapture)
|
489
|
+
mergedFgColour = ColourUtil.mergeColour(parentFg, foreground);
|
490
|
+
else
|
491
|
+
mergedFgColour = foreground;
|
492
|
+
if (mergedFgColour != null) {
|
493
|
+
scope.fgColour = mergedFgColour;
|
494
|
+
styleRange.foreground = ColourUtil.getColour(mergedFgColour);
|
495
|
+
}
|
496
|
+
// stdout.printf(" merged_fg_colour: %s\n", merged_fg_colour);
|
497
|
+
}
|
498
|
+
// stdout.printf("\n");
|
499
|
+
}
|
500
|
+
|
501
|
+
}
|