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,178 @@
1
+ package com.redcareditor.mate;
2
+
3
+ import java.util.ArrayList;
4
+ import java.util.Iterator;
5
+ import java.util.logging.Logger;
6
+ import java.util.logging.Handler;
7
+ import java.util.logging.ConsoleHandler;
8
+ import java.util.logging.Level;
9
+
10
+ import com.redcareditor.onig.Match;
11
+ import com.redcareditor.onig.Rx;
12
+
13
+ public class Scanner implements Iterable<Marker> {
14
+ public static int MAX_LINE_LENGTH = 500;
15
+ private Scope currentScope;
16
+ public int position;
17
+ public String line;
18
+ public int lineLength;
19
+ public int lineIx;
20
+ public Logger logger;
21
+
22
+ public void setCurrentScope(Scope scope) {
23
+ this.currentScope = scope;
24
+ }
25
+
26
+ public Scope getCurrentScope() {
27
+ return this.currentScope;
28
+ }
29
+
30
+ public Scanner(Scope startScope, String line, int lineIx) {
31
+ this.currentScope = startScope;
32
+ this.line = line;
33
+ this.lineIx = lineIx;
34
+ this.lineLength = line.getBytes().length;
35
+ this.position = 0;
36
+ logger = Logger.getLogger("JMV.Scanner");
37
+ logger.setUseParentHandlers(false);
38
+ for (Handler h : logger.getHandlers()) {
39
+ logger.removeHandler(h);
40
+ }
41
+ logger.addHandler(MateText.consoleHandler());
42
+ }
43
+
44
+ public Match scanForMatch(int from, Pattern p) {
45
+ int maxLength = Math.min(MAX_LINE_LENGTH, this.lineLength);
46
+ Match match = null;
47
+ if (p instanceof SinglePattern) {
48
+ SinglePattern sp = (SinglePattern) p;
49
+ if (sp.match.regex != null) {
50
+ match = sp.match.search(this.line, from, maxLength);
51
+ }
52
+ }
53
+ else if (p instanceof DoublePattern) {
54
+ if (((DoublePattern) p).begin.regex != null) {
55
+ match = ((DoublePattern) p).begin.search(this.line, from, maxLength);
56
+ }
57
+ }
58
+ return match;
59
+ }
60
+
61
+ public Marker findNextMarker() {
62
+ if (position >= this.lineLength)
63
+ return null;
64
+ //logger.info(String.format("scanning: '%s' from %d to %d [%d] (current_scope is %s)", this.line.replaceAll("\n", ""), this.position, this.lineLength, this.line.length(), currentScope.name));
65
+ if (position > MAX_LINE_LENGTH)
66
+ return null;
67
+ Marker bestMarker = null;
68
+ int newLength;
69
+ boolean isCloseMatch = false;
70
+ Rx closingRegex = currentScope.closingRegex;
71
+ if (closingRegex != null && closingRegex.usable()) {
72
+ //logger.info(String.format("closing regex: '%s'", closingRegex.pattern));
73
+ Match match = closingRegex.search(this.line, this.position, this.lineLength);
74
+ if (match != null &&
75
+ !(match.getCapture(0).start == currentScope.getStart().getLineOffset() &&
76
+ currentScope.getStart().getLine() == this.lineIx)
77
+ ) {
78
+ //logger.info(String.format("closing match: %s (%d-%d)", this.currentScope.name, match.getCapture(0).start, match.getCapture(0).end));
79
+ Marker newMarker = new Marker();
80
+ newMarker.pattern = this.currentScope.pattern;
81
+ newMarker.match = match;
82
+ newMarker.from = match.getCapture(0).start;
83
+ newMarker.isCloseScope = true;
84
+ bestMarker = newMarker;
85
+ isCloseMatch = true;
86
+ } else {
87
+ // logger.info(String.format("no close match"));
88
+ }
89
+ }
90
+
91
+ //logger.info(String.format(" scanning for %d patterns", ((DoublePattern) currentScope.pattern).patterns.size()));
92
+ if (currentScope.pattern instanceof SinglePattern)
93
+ return null;
94
+
95
+ DoublePattern dp = (DoublePattern) (currentScope.pattern);
96
+ dp.replaceGrammarIncludes();
97
+
98
+ Marker newMarker = scanLine(dp);
99
+ if (newMarker != null) {
100
+ bestMarker = newMarker.bestOf(bestMarker);
101
+ }
102
+ return bestMarker;
103
+ }
104
+
105
+ // public ArrayList<Marker> allDoublesOnLine(DoublePattern dp) {
106
+ // ArrayList<Marker> doubleMarkers = new ArrayList<Marker>();
107
+ // for (Pattern p : dp.patterns) {
108
+ // if (p.disabled) continue;
109
+ // Match match = scanForMatch(position, p);
110
+ // if (match != null) {
111
+ // Marker newMarker = markerFromMatch(p, match);
112
+ // if (newMarker != null) {
113
+ // doubleMarkers.add(newMarker);
114
+ // }
115
+ // }
116
+ // }
117
+ // return doubleMarkers;
118
+ // }
119
+
120
+ public Marker scanLine(DoublePattern dp) {
121
+ Marker bestMarker = null;
122
+ for (Pattern p : dp.patterns) {
123
+ // System.out.printf(" scanning for %s (%s)\n", p.name, p.disabled);
124
+ if (p.disabled) continue;
125
+ Match match = scanForMatch(position, p);
126
+ if (match != null) {
127
+ Marker newMarker = markerFromMatch(p, match);
128
+ if (newMarker != null) {
129
+ bestMarker = newMarker.bestOf(bestMarker);
130
+ }
131
+ }
132
+ }
133
+ return bestMarker;
134
+ }
135
+
136
+ public Marker markerFromMatch(Pattern p, Match match) {
137
+ Marker newMarker = new Marker();
138
+ newMarker.pattern = p;
139
+ newMarker.match = match;
140
+ try {
141
+ newMarker.from = match.getCapture(0).start;
142
+ }
143
+ catch (ArrayIndexOutOfBoundsException e) {
144
+ System.out.printf("*** Warning ArrayIndexOutOfBoundsException pattern: %s, line:'%s'\n", p.name, line);
145
+ e.printStackTrace();
146
+ return null;
147
+ }
148
+ newMarker.isCloseScope = false;
149
+ return newMarker;
150
+ }
151
+
152
+ public Iterator<Marker> iterator() {
153
+ return new ScannerIterator(this);
154
+ }
155
+
156
+ // TODO: implement this class for real
157
+ public class ScannerIterator implements Iterator<Marker> {
158
+ private Scanner scanner;
159
+ private Marker nextMarker;
160
+
161
+ public ScannerIterator(Scanner scanner) {
162
+ this.scanner = scanner;
163
+ }
164
+
165
+ public boolean hasNext() {
166
+ nextMarker = scanner.findNextMarker();
167
+ return (nextMarker != null);
168
+ }
169
+
170
+ public Marker next() {
171
+ return nextMarker;
172
+ }
173
+
174
+ public void remove() {
175
+ nextMarker = null;
176
+ }
177
+ }
178
+ }
@@ -0,0 +1,534 @@
1
+
2
+ package com.redcareditor.mate;
3
+
4
+ import java.util.List;
5
+ import java.util.ArrayList;
6
+
7
+ import com.redcareditor.mate.document.MateDocument;
8
+ import com.redcareditor.mate.document.MateTextLocation;
9
+ import com.redcareditor.mate.document.swt.SwtMateTextLocation;
10
+ import com.redcareditor.mate.document.MateTextRange;
11
+ import com.redcareditor.onig.Match;
12
+ import com.redcareditor.onig.Rx;
13
+ import com.redcareditor.theme.ThemeSetting;
14
+
15
+ public class Scope implements Comparable<Scope>{
16
+ private MateText mateText;
17
+
18
+ private MateDocument document;
19
+
20
+ private MateTextRange range;
21
+ private MateTextRange innerRange;
22
+
23
+ public String name;
24
+ public Pattern pattern;
25
+
26
+ public boolean isOpen;
27
+ public boolean isCapture;
28
+ public boolean isCloseCapture;
29
+
30
+ public Match openMatch;
31
+ public Match closeMatch;
32
+
33
+ public Rx closingRegex;
34
+ public String beginMatchString;
35
+ public String endMatchString;
36
+
37
+ public Scope parent;
38
+ public ArrayList<Scope> children;
39
+
40
+ public String bgColour;
41
+ public String fgColour;
42
+
43
+ StringBuilder prettyString;
44
+ int indent;
45
+
46
+ public ThemeSetting themeSetting;
47
+
48
+ public Scope(MateText mt, String name) {
49
+ this.mateText = mt;
50
+ this.name = name;
51
+ this.children = new ArrayList<Scope>();
52
+ this.document = mt.getMateDocument();
53
+
54
+ this.range = document.getTextRange();
55
+ this.innerRange = document.getTextRange();
56
+ }
57
+
58
+ public void setMateText(MateText mateText) {
59
+ this.mateText = mateText;
60
+ this.document = mateText.getMateDocument();
61
+ this.range.setDocument(this.document);
62
+ if (this.innerRange != null) {
63
+ this.innerRange.setDocument(this.document);
64
+ }
65
+
66
+ for (Scope child : children)
67
+ child.setMateText(mateText);
68
+ }
69
+
70
+ static public Scope findContainingScopeOld(ArrayList<Scope> scopes, MateTextLocation location) {
71
+ for (Scope child : scopes) {
72
+ if (child.contains(location)) {
73
+ return child;
74
+ }
75
+ }
76
+ return null;
77
+ }
78
+
79
+ static int indexOfEarliestAfter(ArrayList<Scope> scopes, int offset) {
80
+ if (offset == 0) {
81
+ if (scopes.size() > 0)
82
+ return 0;
83
+ else
84
+ return -1;
85
+ }
86
+ int ix = indexOfLatestBefore(scopes, offset - 1);
87
+ int c = ix + 1;
88
+ if (c == scopes.size())
89
+ return -1;
90
+ return c;
91
+ }
92
+
93
+ static int indexOfLatestBefore(ArrayList<Scope> scopes, int offset) {
94
+ int high = scopes.size(), low = -1, probe, probeStart;
95
+ if (high == 0)
96
+ return -1;
97
+ int bestProbe = 0;
98
+ int bestStart = ((SwtMateTextLocation) scopes.get(0).getStart()).offset;
99
+ if (bestStart > offset)
100
+ return -1;
101
+ Scope scope;
102
+ while (high - low > 1) {
103
+ probe = (low + high) >>> 1;
104
+ scope = scopes.get(probe);
105
+ probeStart = ((SwtMateTextLocation) scope.getStart()).offset;
106
+ //System.out.printf("low: %d high: %d diff: %d probe: %d value: %d\n", low, high, high - low, probe, probeStart);
107
+ if (probeStart <= offset) {
108
+ low = probe;
109
+ bestStart = probeStart;
110
+ bestProbe = probe;
111
+ }
112
+ else {
113
+ high = probe;
114
+ }
115
+ }
116
+ if (bestStart <= offset)
117
+ return bestProbe;
118
+ else
119
+ return -1;
120
+ }
121
+
122
+ static public Scope findContainingScopeNew(ArrayList<Scope> scopes, int offset) {
123
+ //System.out.printf("findContainingScopeNew(offset: %d)\n", offset);
124
+ int ix = indexOfLatestBefore(scopes, offset);
125
+ if (ix == -1)
126
+ return null;
127
+ Scope scope = scopes.get(ix);
128
+ int scopeStart = ((SwtMateTextLocation) scope.getStart()).offset;
129
+ if (scopeStart <= offset) {
130
+ int scopeEnd = ((SwtMateTextLocation) scope.getEnd()).offset;
131
+ if (scopeEnd > offset) {
132
+ return scope;
133
+ }
134
+ }
135
+ return null;
136
+ }
137
+
138
+ public Scope scopeAt(int line, int lineOffset) {
139
+ MateTextLocation location = document.getTextLocation(line, lineOffset);
140
+ Scope r = null;
141
+ if (getStart().compareTo(location) <= 0 || parent == null) {
142
+ if (isOpen || getEnd().compareTo(location) >= 0) {
143
+ Scope containingChildNew = Scope.findContainingScopeNew(children, ((SwtMateTextLocation) location).offset);
144
+ //Scope containingChildOld = Scope.findContainingScopeOld(children, location);
145
+ //if (containingChildNew != containingChildOld) {
146
+ // System.out.printf("scopeAt(%d, %d)\n", line, lineOffset);
147
+ // System.out.printf("containingChild differs %s -> %s\n",
148
+ // (containingChildOld == null ? "none" : containingChildOld.name),
149
+ // (containingChildNew == null ? "none" : containingChildNew.name)
150
+ // );
151
+ // System.out.printf(pretty(2));
152
+ //}
153
+ if (containingChildNew != null)
154
+ r = containingChildNew.scopeAt(line, lineOffset);
155
+ else
156
+ r = this;
157
+ }
158
+ }
159
+ return r;
160
+ }
161
+
162
+ public void clearFrom(int offset) {
163
+ //System.out.printf("clearFrom(%d) children: %d\n", offset, children.size());
164
+ int ix = indexOfLatestBefore(children, offset);
165
+ //System.out.printf(" ix: %d\n", ix);
166
+ if (ix == -1)
167
+ return;
168
+ Scope scope = children.get(ix);
169
+ int scopeStart = scope.getStart().getOffset();
170
+ //System.out.printf(" scopeStart: %d\n", scopeStart);
171
+ if (scopeStart < offset) {
172
+ ix = ix + 1;
173
+ int scopeEnd = scope.getEnd().getOffset();
174
+ if (scopeEnd > offset)
175
+ scope.clearFrom(offset);
176
+ }
177
+ if (ix <= children.size() - 1) {
178
+ //System.out.printf(" range: %d - %d\n", ix, children.size());
179
+ ((List<Scope>) children).subList(ix, children.size()).clear();
180
+ }
181
+ if (getEnd().getOffset() > offset) {
182
+ removeEnd();
183
+ isOpen = true;
184
+ }
185
+ }
186
+
187
+ public int compareTo(Scope o) {
188
+ if(getStart().compareTo(o.getStart()) == 0){
189
+ return getEnd().compareTo(o.getEnd());
190
+ }
191
+ return getStart().compareTo(o.getStart());
192
+ }
193
+
194
+ public Scope containingDoubleScope(int lineIx) {
195
+ Scope scope = this;
196
+ while ((scope.pattern instanceof SinglePattern ||
197
+ scope.isCapture ||
198
+ (scope.getStart().getLine() == lineIx && scope.getStart().getLineOffset() == 0)) &&
199
+ scope.parent != null) {
200
+ scope = scope.parent;
201
+ }
202
+ return scope;
203
+ }
204
+
205
+ public boolean surfaceIdenticalTo(Scope other) {
206
+ if (surfaceIdenticalToModuloEnding(other) &&
207
+ getEnd().equals(other.getEnd()) &&
208
+ getInnerEnd().equals(other.getInnerEnd()) &&
209
+ beginMatchString.equals(other.beginMatchString)) {
210
+ return true;
211
+ }
212
+ return false;
213
+ }
214
+
215
+ public boolean surfaceIdenticalToModuloEnding(Scope other) {
216
+ //System.out.printf("name: %s; other.name: %s\n", name, other.name);
217
+ //if (getStart() == null) {
218
+ // System.out.printf("getStart() is null");
219
+ //}
220
+ if (
221
+ ( (name == null && other.name == null) || (name != null && name.equals(other.name)) ) &&
222
+ pattern == other.pattern &&
223
+ getStart().equals(other.getStart()) &&
224
+ getInnerStart().equals(other.getInnerStart()) &&
225
+ beginMatchString.equals(other.beginMatchString)) {
226
+ return true;
227
+ }
228
+ return false;
229
+ }
230
+
231
+ public ArrayList<Scope> scopesOnLine(int lineIx) {
232
+ ArrayList<Scope> scopes = new ArrayList<Scope>();
233
+ if (getStart().getLine() <= lineIx && getEnd().getLine() >= lineIx)
234
+ scopes.add(this);
235
+ childScopesOnLine(lineIx, scopes);
236
+ return scopes;
237
+ }
238
+
239
+ public void childScopesOnLine(int lineIx, ArrayList<Scope> scopes) {
240
+ for (Scope child : children) {
241
+ if (child.getStart().getLine() <= lineIx && child.getEnd().getLine() >= lineIx) {
242
+ scopes.add(child);
243
+ child.childScopesOnLine(lineIx, scopes);
244
+ }
245
+ }
246
+ }
247
+
248
+ public ArrayList<Scope> scopesBetween(int startOffset, int endOffset) {
249
+ ArrayList<Scope> scopes = new ArrayList<Scope>();
250
+ if (getStart().getOffset() < endOffset && getEnd().getOffset() >= startOffset)
251
+ scopes.add(this);
252
+ childScopesBetween(startOffset, endOffset, scopes);
253
+ return scopes;
254
+ }
255
+
256
+ public void childScopesBetween(int startOffset, int endOffset, ArrayList<Scope> scopes) {
257
+ for (Scope child : children) {
258
+ if (child.getStart().getOffset() < endOffset && child.getEnd().getOffset() >= startOffset) {
259
+ scopes.add(child);
260
+ child.childScopesBetween(startOffset, endOffset, scopes);
261
+ }
262
+ }
263
+ }
264
+
265
+ public boolean overlapsWith(Scope other) {
266
+ // sd1 +---
267
+ // sd2 +---
268
+ if (getStart().compareTo(other.getStart()) >= 0) {
269
+ if (getStart().compareTo(other.getEnd()) < 0) {
270
+ return true;
271
+ }
272
+ return false;
273
+ }
274
+
275
+ // sd1 +---
276
+ // sd2 +---
277
+ if (getEnd().compareTo(other.getStart()) > 0) {
278
+ return true;
279
+ }
280
+ return false;
281
+ }
282
+
283
+ public void addChild(Scope newChild) {
284
+ if (children.size() == 0){
285
+ children.add(newChild);
286
+ return;
287
+ }
288
+
289
+ int newChildStartOffset = newChild.getStart().getOffset();
290
+
291
+ if (children.get(0).getStart().getOffset() > newChildStartOffset){
292
+ children.add(0, newChild);
293
+ return;
294
+ }
295
+
296
+ int insertIx = 0;
297
+ int ix = 1;
298
+ Scope lastChild = children.get(children.size() - 1);
299
+
300
+ if (lastChild.getStart().getOffset() <= newChildStartOffset) {
301
+ insertIx = children.size();
302
+ }
303
+ else {
304
+ for (Scope child : children) {
305
+ if (child.getStart().getOffset() <= newChildStartOffset) {
306
+ insertIx = ix;
307
+ }
308
+ ix++;
309
+ }
310
+ }
311
+ children.add(insertIx, newChild);
312
+ }
313
+
314
+ public void removeChild(Scope child) {
315
+ children.remove(child);
316
+ }
317
+
318
+ public Scope firstChildAfter(MateTextLocation location) {
319
+ if (children.size() == 0)
320
+ return null;
321
+
322
+ int offset = location.getOffset();
323
+ int ix = indexOfEarliestAfter(children, offset);
324
+ Scope r = null;
325
+ if (ix == -1) {
326
+ return null;
327
+ }
328
+ else {
329
+ return children.get(ix);
330
+ }
331
+ }
332
+
333
+ public void printScopeRanges(String title, ArrayList<Scope> scopes) {
334
+ System.out.printf("%s: ", title);
335
+ for (Scope s : scopes) {
336
+ System.out.printf("%d-%d, ", s.getStart().getOffset(), s.getEnd().getOffset());
337
+ }
338
+ System.out.printf("\n");
339
+ }
340
+
341
+ public ArrayList<Scope> deleteAnyBetweenNotIn(int startOffset, int endOffset, ArrayList<Scope> scopes) {
342
+ //System.out.printf("deleteAnyBetweenNotIn(%d, %d)\n", startOffset, endOffset);
343
+ //printScopeRanges(" children", children);
344
+ //printScopeRanges(" safe", scopes);
345
+ ArrayList<Scope> removedScopes = new ArrayList<Scope>();
346
+ int ix, childStart;
347
+
348
+ int ixEnd = indexOfLatestBefore(children, endOffset);
349
+ if (ixEnd == -1)
350
+ return removedScopes;
351
+ int ixStart = indexOfEarliestAfter(children, startOffset);
352
+ if (ixStart == -1)
353
+ ix = 0;
354
+ else
355
+ ix = ixStart;
356
+ //System.out.printf(" start: %d, end: %d\n", ixStart, ixEnd);
357
+ while (ix <= ixEnd) {
358
+ Scope child = children.get(ix);
359
+ childStart = child.getStart().getOffset();
360
+ //System.out.printf(" checking: %d-%d\n", child.getStart().getOffset(), child.getEnd().getOffset());
361
+ if (childStart >= startOffset && childStart < endOffset && !scopes.contains(child)) {
362
+ removedScopes.add(child);
363
+ }
364
+ ix++;
365
+ }
366
+ children.removeAll(removedScopes);
367
+ //printScopeRanges(" removedScopes", removedScopes);
368
+ return removedScopes;
369
+ }
370
+
371
+ public void setStartPos(int line, int lineOffset, boolean hasLeftGravity) {
372
+ MateTextLocation start = document.getTextLocation(line, lineOffset);
373
+ this.range.setStart(start);
374
+ document.addTextLocation("scopes", start);
375
+ }
376
+
377
+ public void setInnerStartPos(int line, int lineOffset, boolean hasLeftGravity) {
378
+ MateTextLocation innerStart = document.getTextLocation(line, lineOffset);
379
+ this.innerRange.setStart(innerStart);
380
+ document.addTextLocation("scopes", innerStart);
381
+ }
382
+
383
+ public void setInnerEndPos(int line, int lineOffset, boolean c) {
384
+ MateTextLocation innerEnd = document.getTextLocation(line, lineOffset);
385
+ this.innerRange.setEnd(innerEnd);
386
+ document.addTextLocation("scopes", innerEnd);
387
+ }
388
+
389
+ public void setEndPos(int line, int lineOffset, boolean c) {
390
+ MateTextLocation end = document.getTextLocation(line, lineOffset);
391
+ this.range.setEnd(end);
392
+ document.addTextLocation("scopes", end);
393
+ }
394
+
395
+ public void removeEnd() {
396
+ this.range.clearEnd();
397
+ this.innerRange.clearEnd();
398
+ }
399
+
400
+ public int getLength(){
401
+ return range.getLength();
402
+ }
403
+
404
+ public MateTextLocation getStart() {
405
+ return range.getStart();
406
+ }
407
+
408
+ public MateTextLocation getEnd(){
409
+ return range.getEnd();
410
+ }
411
+
412
+ public MateTextLocation getInnerStart(){
413
+ return innerRange.getStart();
414
+ }
415
+
416
+ public MateTextLocation getInnerEnd(){
417
+ return innerRange.getEnd();
418
+ }
419
+
420
+ public boolean contains(MateTextLocation location){
421
+ return range.conatains(location);
422
+ }
423
+
424
+ public String hierarchyNames(boolean inner) {
425
+ String selfName;
426
+ // stdout.printf("'%s'.hierarchy_names(%s)\n", name, inner ? "true" : "false");
427
+ if (pattern instanceof DoublePattern &&
428
+ ((DoublePattern) pattern).contentName != null &&
429
+ inner) {
430
+ selfName = name + " " + ((DoublePattern) pattern).contentName;
431
+ }
432
+ else {
433
+ selfName = name;
434
+ }
435
+ if (parent != null) {
436
+ boolean next_inner;
437
+ if (isCapture)
438
+ next_inner = false;
439
+ else
440
+ next_inner = true;
441
+ return parent.hierarchyNames(next_inner) + " " + selfName;
442
+ }
443
+ else {
444
+ return selfName;
445
+ }
446
+ }
447
+
448
+ public String pretty(int indent) {
449
+ prettyString = new StringBuilder("");
450
+ this.indent = indent;
451
+ for (int i = 0; i < indent; i++)
452
+ prettyString.append(" ");
453
+ if (this.isCapture)
454
+ prettyString.append("c");
455
+ else
456
+ prettyString.append("+");
457
+
458
+ if (this.name != null)
459
+ prettyString.append(" " + this.name);
460
+ else
461
+ prettyString.append(" " + "[noname]");
462
+
463
+ if (this.pattern instanceof DoublePattern &&
464
+ this.isCapture == false &&
465
+ ((DoublePattern) this.pattern).contentName != null)
466
+ prettyString.append(" " + ((DoublePattern) this.pattern).contentName);
467
+ prettyString.append(" (");
468
+ prettyString.append(String.format(
469
+ "%d,%d",
470
+ getStart().getLine(),
471
+ getStart().getLineOffset()));
472
+ // prettyString.append(getStart().getOffset());
473
+ prettyString.append(")-(");
474
+ prettyString.append(String.format(
475
+ "%d,%d",
476
+ getEnd().getLine(),
477
+ getEnd().getLineOffset()));
478
+ // prettyString.append(getEnd().getOffset());
479
+ prettyString.append(")");
480
+ prettyString.append((isOpen ? " open" : " closed"));
481
+ prettyString.append("\n");
482
+
483
+ this.indent += 1;
484
+ for (Scope child : this.children) {
485
+ prettyString.append(child.pretty(this.indent));
486
+ }
487
+
488
+ return prettyString.toString();
489
+ }
490
+
491
+
492
+ public String nearestBackgroundColour() {
493
+ if (parent != null) {
494
+ return parent.nearestBackgroundColour1();
495
+ }
496
+ return null;
497
+ }
498
+
499
+ public String nearestBackgroundColour1() {
500
+ if (bgColour != null)
501
+ return bgColour;
502
+ if (parent != null) {
503
+ return parent.nearestBackgroundColour1();
504
+ }
505
+ return null;
506
+ }
507
+
508
+ public String nearestForegroundColour() {
509
+ if (parent != null) {
510
+ return parent.nearestForegroundColour1();
511
+ }
512
+ return null;
513
+ }
514
+
515
+ public String nearestForegroundColour1() {
516
+ if (fgColour != null)
517
+ return fgColour;
518
+ if (parent != null) {
519
+ return parent.nearestForegroundColour1();
520
+ }
521
+ return null;
522
+ }
523
+
524
+ public int countDescendants() {
525
+ int i = children.size();
526
+ for (Scope child : children) {
527
+ i += child.countDescendants();
528
+ }
529
+ return i;
530
+ }
531
+ }
532
+
533
+
534
+