redcar-javamateview 0.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/LICENSE +34 -0
  2. data/README +58 -0
  3. data/Rakefile +94 -0
  4. data/lib/javamateview.rb +41 -0
  5. data/lib/javamateview/example.rb +334 -0
  6. data/lib/javamateview/jar/java-mateview.jar +0 -0
  7. data/lib/javamateview/jcodings.jar +0 -0
  8. data/lib/javamateview/jdom.jar +0 -0
  9. data/lib/javamateview/joni.jar +0 -0
  10. data/spec/onig/match_spec.rb +50 -0
  11. data/spec/parsing/dynamic_parsing_spec.rb +172 -0
  12. data/spec/parsing/static_parsing_spec.rb +476 -0
  13. data/spec/spec_helper.rb +33 -0
  14. data/src/com/redcareditor/mate/Bundle.java +81 -0
  15. data/src/com/redcareditor/mate/DoublePattern.java +89 -0
  16. data/src/com/redcareditor/mate/Grammar.java +129 -0
  17. data/src/com/redcareditor/mate/IAnnotationAreaListener.java +7 -0
  18. data/src/com/redcareditor/mate/IGrammarListener.java +5 -0
  19. data/src/com/redcareditor/mate/IncludePattern.java +10 -0
  20. data/src/com/redcareditor/mate/LineNumberRulerColumn.java +922 -0
  21. data/src/com/redcareditor/mate/Marker.java +22 -0
  22. data/src/com/redcareditor/mate/MateText.java +697 -0
  23. data/src/com/redcareditor/mate/ParseThunk.java +71 -0
  24. data/src/com/redcareditor/mate/Parser.java +627 -0
  25. data/src/com/redcareditor/mate/ParserScheduler.java +237 -0
  26. data/src/com/redcareditor/mate/Pattern.java +152 -0
  27. data/src/com/redcareditor/mate/RangeSet.java +91 -0
  28. data/src/com/redcareditor/mate/Scanner.java +178 -0
  29. data/src/com/redcareditor/mate/Scope.java +534 -0
  30. data/src/com/redcareditor/mate/ScopeMatcher.java +162 -0
  31. data/src/com/redcareditor/mate/SharedTextColors.java +110 -0
  32. data/src/com/redcareditor/mate/SinglePattern.java +20 -0
  33. data/src/com/redcareditor/mate/WhitespaceCharacterPainter.java +395 -0
  34. data/src/com/redcareditor/mate/colouring/Colourer.java +16 -0
  35. data/src/com/redcareditor/mate/colouring/swt/MarginPaintListener.java +62 -0
  36. data/src/com/redcareditor/mate/colouring/swt/SwtColourer.java +501 -0
  37. data/src/com/redcareditor/mate/document/MateDocument.java +15 -0
  38. data/src/com/redcareditor/mate/document/MateTextFactory.java +9 -0
  39. data/src/com/redcareditor/mate/document/MateTextLocation.java +8 -0
  40. data/src/com/redcareditor/mate/document/MateTextLocationComparator.java +17 -0
  41. data/src/com/redcareditor/mate/document/MateTextRange.java +18 -0
  42. data/src/com/redcareditor/mate/document/swt/SwtMateDocument.java +143 -0
  43. data/src/com/redcareditor/mate/document/swt/SwtMateTextLocation.java +88 -0
  44. data/src/com/redcareditor/mate/document/swt/SwtMateTextRange.java +92 -0
  45. data/src/com/redcareditor/mate/document/swt/SwtScopePositionUpdater.java +90 -0
  46. data/src/com/redcareditor/mate/undo/MateTextUndoManager.java +11 -0
  47. data/src/com/redcareditor/mate/undo/swt/SwtMateTextUndoManager.java +166 -0
  48. data/src/com/redcareditor/onig/Match.java +212 -0
  49. data/src/com/redcareditor/onig/NullMatch.java +57 -0
  50. data/src/com/redcareditor/onig/NullRx.java +29 -0
  51. data/src/com/redcareditor/onig/Range.java +45 -0
  52. data/src/com/redcareditor/onig/Rx.java +167 -0
  53. data/src/com/redcareditor/plist/Dict.java +119 -0
  54. data/src/com/redcareditor/plist/PlistNode.java +52 -0
  55. data/src/com/redcareditor/plist/PlistPropertyLoader.java +44 -0
  56. data/src/com/redcareditor/theme/ScopeSelector.java +39 -0
  57. data/src/com/redcareditor/theme/Theme.java +122 -0
  58. data/src/com/redcareditor/theme/ThemeManager.java +41 -0
  59. data/src/com/redcareditor/theme/ThemeSetting.java +78 -0
  60. data/src/com/redcareditor/util/FileUtility.java +64 -0
  61. data/src/com/redcareditor/util/SingleLineFormatter.java +11 -0
  62. data/src/com/redcareditor/util/swt/ColourUtil.java +56 -0
  63. data/src/ruby/java-mateview.rb +68 -0
  64. data/test/com/redcareditor/mate/BundleTest.java +33 -0
  65. data/test/com/redcareditor/mate/EmptyRangeSetTest.java +27 -0
  66. data/test/com/redcareditor/mate/FilledRangeSetTest.java +82 -0
  67. data/test/com/redcareditor/mate/GrammarTest.java +158 -0
  68. data/test/com/redcareditor/mate/MateTextTest.java +35 -0
  69. data/test/com/redcareditor/mate/ScopeMatcherMatchingTest.java +55 -0
  70. data/test/com/redcareditor/mate/ScopeMatcherRankingTest.java +40 -0
  71. data/test/com/redcareditor/onig/RxTest.java +54 -0
  72. data/test/com/redcareditor/plist/DictTest.java +33 -0
  73. data/test/com/redcareditor/theme/RailsCastThemeTest.java +37 -0
  74. data/test/com/redcareditor/theme/ScopeSelectorTest.java +38 -0
  75. data/test/com/redcareditor/theme/ThemeManagerTest.java +29 -0
  76. data/test/com/redcareditor/util/swt/ColourUtilTest.java +17 -0
  77. 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
+ }