redcar-javamateview 0.2

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 +134 -0
@@ -0,0 +1,237 @@
1
+ package com.redcareditor.mate;
2
+
3
+ import org.eclipse.swt.events.ModifyEvent;
4
+ import org.eclipse.swt.events.ModifyListener;
5
+ import org.eclipse.swt.events.SelectionEvent;
6
+ import org.eclipse.swt.events.SelectionListener;
7
+ import org.eclipse.swt.events.VerifyEvent;
8
+ import org.eclipse.swt.events.VerifyListener;
9
+
10
+ import org.eclipse.jface.text.IDocumentListener;
11
+ import org.eclipse.jface.text.IViewportListener;
12
+ import org.eclipse.jface.text.JFaceTextUtil;
13
+ import org.eclipse.jface.text.DocumentEvent;
14
+
15
+ import com.redcareditor.mate.document.swt.SwtMateTextLocation;
16
+ import com.redcareditor.onig.Range;
17
+
18
+ public class ParserScheduler {
19
+ public static int LOOK_AHEAD = 300;
20
+ public static boolean synchronousParsing = false;
21
+ public int lookAhead;
22
+ public int lastVisibleLine;
23
+ public boolean alwaysParseAll;
24
+ public boolean enabled;
25
+ public RangeSet changes;
26
+ public int deactivationLevel;
27
+
28
+ public int modifyStart, modifyEnd;
29
+ public String modifyText;
30
+ public ParseThunk thunk;
31
+ public Parser parser;
32
+
33
+ public int parsed_upto;
34
+ public SwtMateTextLocation parsedUpto;
35
+
36
+ public ParserScheduler(Parser parser) {
37
+ this.parser = parser;
38
+ lookAhead = LOOK_AHEAD;
39
+ lastVisibleLine = 0;
40
+ changes = new RangeSet();
41
+ deactivationLevel = 0;
42
+ alwaysParseAll = false;
43
+ modifyStart = -1;
44
+ enabled = true;
45
+ setParsedUpto(0);
46
+ attachListeners();
47
+ }
48
+
49
+ public void close() {
50
+ if (thunk != null) {
51
+ thunk.stop();
52
+ thunk = null;
53
+ }
54
+ removeListeners();
55
+ }
56
+
57
+ private VerifyListener verifyListener;
58
+ private ModifyListener modifyListener;
59
+ private IViewportListener viewportListener;
60
+ private IDocumentListener documentListener;
61
+
62
+ public void attachListeners() {
63
+ viewportListener = new IViewportListener() {
64
+ public void viewportChanged(int verticalOffset) {
65
+ viewportScrolledCallback();
66
+ }
67
+ };
68
+
69
+ parser.mateText.viewer.addViewportListener(viewportListener);
70
+
71
+ documentListener = new IDocumentListener() {
72
+ public void documentAboutToBeChanged(DocumentEvent e) {
73
+ verifyEventCallback(e.fOffset, e.fOffset + e.fLength, e.fText);
74
+ }
75
+
76
+ public void documentChanged(DocumentEvent e) {
77
+ modifyEventCallback();
78
+ }
79
+ };
80
+ parser.mateText.getDocument().addDocumentListener(documentListener);
81
+ }
82
+
83
+ public void removeListeners() {
84
+ parser.mateText.viewer.removeViewportListener(viewportListener);
85
+ parser.mateText.getDocument().removeDocumentListener(documentListener);
86
+ }
87
+
88
+ public void verifyEventCallback(int start, int end, String text) {
89
+ if (enabled) {
90
+ modifyStart = start;
91
+ modifyEnd = end;
92
+ modifyText = text;
93
+ }
94
+ }
95
+
96
+ public void modifyEventCallback() {
97
+ if (enabled) {
98
+ changes.add(
99
+ parser.getLineAtOffset(modifyStart),
100
+ parser.getLineAtOffset(modifyStart + modifyText.length())
101
+ );
102
+ modifyStart = -1;
103
+ modifyEnd = -1;
104
+ modifyText = null;
105
+ if (deactivationLevel == 0)
106
+ processChanges();
107
+ }
108
+ }
109
+
110
+ public void viewportScrolledCallback() {
111
+ if (enabled) {
112
+ lastVisibleLineChanged(JFaceTextUtil.getBottomIndex(parser.mateText.getTextWidget()));
113
+ }
114
+ }
115
+
116
+ public void deactivate() {
117
+ deactivationLevel++;
118
+ }
119
+
120
+ public void reactivate() {
121
+ deactivationLevel--;
122
+ if (deactivationLevel < 0)
123
+ deactivationLevel = 0;
124
+ if (deactivationLevel == 0)
125
+ processChanges();
126
+ }
127
+
128
+ // Process all change ranges.
129
+ public void processChanges() {
130
+ int thisParsedUpto = -1;
131
+ // System.out.printf("process_changes (lastVisibleLine: %d) (charCount = %d)\n", lastVisibleLine, document.getLength());
132
+ for (Range range : changes) {
133
+ if (range.end > thisParsedUpto && range.start <= lastVisibleLine + lookAhead) {
134
+ int rangeEnd;
135
+ if (alwaysParseAll) {
136
+ rangeEnd = parser.getLineCount() - 1;
137
+ } else {
138
+ rangeEnd = Math.min(lastVisibleLine + lookAhead, range.end);
139
+ }
140
+ //System.out.printf("parseRange from processChanges\n");
141
+ thisParsedUpto = parseRange(range.start, rangeEnd);
142
+ }
143
+ int startOffset = parser.getOffsetAtLine(range.start);
144
+ int endOffset = parser.getOffsetAtLine(range.end);
145
+ parser.styledText.redrawRange(startOffset, endOffset - startOffset, false);
146
+ }
147
+ // System.out.printf("%s\n", root.pretty(0));
148
+ changes.ranges.clear();
149
+ }
150
+
151
+ public void thunkFrom(int lineIx) {
152
+ if (thunk != null) {
153
+ thunk.delayAndUpdate(lineIx);
154
+ }
155
+ else {
156
+ if (lineIx <= parser.getLineCount() - 1) {
157
+ thunk = new ParseThunk(parser, lineIx);
158
+ if (ParserScheduler.synchronousParsing) {
159
+ thunk.execute();
160
+ }
161
+ }
162
+ }
163
+ }
164
+
165
+ // Parse from from_line to *at least* to_line. Will parse
166
+ // more if necessary. Returns the index of the last line
167
+ // parsed.
168
+ public int parseRange(int fromLine, int toLine) {
169
+ //System.out.printf("parse_range(%d, %d)\n", fromLine, toLine);
170
+
171
+ int lineIx = fromLine;
172
+ boolean scopeChanged = false;
173
+ boolean scopeEverChanged = false;
174
+ while (lineIx <= toLine) {
175
+ scopeChanged = parser.parseLine(lineIx);
176
+ if (scopeChanged) {
177
+ if (scopeEverChanged == false && getParsedUpto() > lineIx) {
178
+ //System.out.printf(parser.root.pretty(4));
179
+ //System.out.printf("-- clearFrom(%d) --\n", lineIx);
180
+ parser.clearFrom(parser.getOffsetAtLine(lineIx + 1));
181
+ //System.out.printf(parser.root.pretty(4));
182
+ }
183
+ setParsedUpto(lineIx);
184
+ scopeEverChanged = true;
185
+ }
186
+ lineIx++;
187
+ }
188
+ if (scopeEverChanged) {
189
+ thunkFrom(lineIx);
190
+ }
191
+
192
+ return toLine;
193
+ }
194
+
195
+ public int parseOnwards(int fromLine) {
196
+ // The widget can be disposed between the Thunk being created and being executed.
197
+ if (parser.styledText.isDisposed())
198
+ return -1;
199
+ int lineIx = fromLine;
200
+ int lineCount = parser.getLineCount();
201
+ int lastLine = Math.min(lastVisibleLine + LOOK_AHEAD, lineCount - 1);
202
+ int toLine = Math.min(fromLine + LOOK_AHEAD, lastLine);
203
+ while (lineIx <= toLine) {
204
+ parser.parseLine(lineIx);
205
+ setParsedUpto(lineIx);
206
+ parser.redrawLine(lineIx);
207
+ lineIx++;
208
+ }
209
+
210
+ return lineIx;
211
+ }
212
+
213
+ public void lastVisibleLineChanged(int newLastVisibleLine) {
214
+ int oldLastVisibleLine = lastVisibleLine;
215
+ //System.out.printf("lastVisibleLineChanged(%d)\n", newLastVisibleLine);
216
+ this.lastVisibleLine = newLastVisibleLine;
217
+ //System.out.printf("lastVisibleLine: %d, lookAhead: %d, getParsedUpto: %d\n", lastVisibleLine, lookAhead, getParsedUpto());
218
+ if (lastVisibleLine + lookAhead >= getParsedUpto() && getParsedUpto() < parser.getLineCount() - 1) {
219
+ int endRange = Math.min(parser.getLineCount() - 1, lastVisibleLine + lookAhead);
220
+ thunkFrom(getParsedUpto());
221
+ }
222
+ }
223
+
224
+ public void setParsedUpto(int line_ix) {
225
+ if (parsedUpto == null) {
226
+ parsedUpto = (SwtMateTextLocation) parser.mateDocument.getTextLocation(0, 0);
227
+ parser.mateDocument.addTextLocation("lefts", parsedUpto);
228
+ }
229
+ parsedUpto.offset = parser.getOffsetAtLine(line_ix);
230
+ }
231
+
232
+ public int getParsedUpto() {
233
+ // System.out.printf("parsedUpto %d,%d (/%d)\n", parsedUpto.getOffset(), parsedUpto.getLength(), parser.getCharCount());
234
+ return parser.getLineAtOffset(parsedUpto.getOffset());
235
+ }
236
+
237
+ }
@@ -0,0 +1,152 @@
1
+ package com.redcareditor.mate;
2
+
3
+ import java.util.ArrayList;
4
+ import java.util.HashMap;
5
+ import java.util.List;
6
+ import java.util.Map;
7
+
8
+ import com.redcareditor.plist.Dict;
9
+ import com.redcareditor.plist.PlistNode;
10
+
11
+ public class Pattern {
12
+ public Grammar grammar;
13
+ public String name;
14
+ public boolean disabled;
15
+
16
+ public static Pattern createPattern(List<Pattern> allPatterns, Dict dict) {
17
+ if (dict.containsElement("match")) {
18
+ return new SinglePattern(allPatterns, dict);
19
+ }
20
+
21
+ if (dict.containsElement("include")) {
22
+ return new IncludePattern(dict);
23
+ }
24
+
25
+ if (dict.containsElement("begin")) {
26
+ return new DoublePattern(allPatterns, dict);
27
+ }
28
+
29
+ return null;
30
+ }
31
+
32
+ public static Map<Integer, String> makeCapturesFromPlist(Dict pd) {
33
+ if (pd == null)
34
+ return new HashMap<Integer, String>();
35
+ Dict pcd;
36
+ String ns;
37
+ Map<Integer, String> captures = new HashMap<Integer, String>();
38
+ for (String sCapnum : pd.value.keySet()) {
39
+ int capnum = Integer.parseInt(sCapnum);
40
+ pcd = pd.getDictionary(sCapnum);
41
+ ns = pcd.getString("name");
42
+ // System.out.printf("capture: %d, %s\n", capnum, ns);
43
+ captures.put((Integer) capnum, ns);
44
+ }
45
+ return captures;
46
+ }
47
+
48
+ public static void replaceIncludePatterns(List<Pattern> patterns, Grammar grammar) {
49
+ replaceRepositoryIncludes(patterns, grammar);
50
+ replaceBaseAndSelfIncludes(patterns, grammar);
51
+ }
52
+
53
+ public static void replaceRepositoryIncludes(List<Pattern> patterns, Grammar grammar) {
54
+ int i = 0;
55
+ while (i < patterns.size()) {
56
+ Pattern p = patterns.get(i);
57
+ if (p instanceof IncludePattern && p.name.startsWith("#")) {
58
+ // System.out.printf("repo include: %s\n", p.name);
59
+ String reponame = p.name.substring(1, p.name.length());
60
+ List<Pattern> repositoryEntryPatterns = grammar.repository.get(reponame);
61
+ if (repositoryEntryPatterns != null) {
62
+ // System.out.printf(" got %d patterns\n", repositoryEntryPatterns.size());
63
+ patterns.remove(i);
64
+ patterns.addAll(i, repositoryEntryPatterns);
65
+ i--;
66
+ } else {
67
+ System.out.printf("warning: couldn't find repository key '%s' in grammar '%s'\n", reponame,
68
+ grammar.name);
69
+ }
70
+ }
71
+ i++;
72
+ }
73
+ }
74
+
75
+ public static void replaceBaseAndSelfIncludes(List<Pattern> patterns, Grammar grammar) {
76
+ boolean alreadySelf = false; // some patterns have $self twice
77
+ Grammar ng;
78
+ int i = 0;
79
+ while (i < patterns.size()) {
80
+ Pattern p = patterns.get(i);
81
+ if (p instanceof IncludePattern) {
82
+ if (p.name.startsWith("$")) {
83
+ if ((p.name.equals("$self") || p.name.equals("$base")) && !alreadySelf) {
84
+ alreadySelf = true;
85
+ patterns.remove(i);
86
+ patterns.addAll(i, grammar.patterns);
87
+ i--;
88
+ }
89
+ //} else if ((ng = Grammar.findByScopeName(p.name)) != null) {
90
+ // ng.initForUse();
91
+ // patterns.remove(i);
92
+ // patterns.addAll(i, ng.patterns);
93
+ // i--;
94
+ }
95
+ }
96
+ i++;
97
+ }
98
+ }
99
+
100
+ private static void removePatterns(List<Pattern> patlist, List<Pattern> ps) {
101
+ for (Pattern p : ps) {
102
+ patlist.remove(p);
103
+ }
104
+ }
105
+
106
+ private static void addPatterns(List<Pattern> patlist, List<Pattern> ps) {
107
+ for (Pattern p : ps) {
108
+ patlist.add(p);
109
+ }
110
+ }
111
+
112
+ public void setDisabled(Dict dict) {
113
+ PlistNode<?> plistNode = dict.value.get("disabled");
114
+ int intn;
115
+ if (plistNode != null) {
116
+ if (plistNode.value instanceof String) {
117
+ String strn = dict.getString("disabled");
118
+ intn = Integer.parseInt(strn);
119
+ }
120
+ else {
121
+ intn = dict.getInt("disabled");
122
+ }
123
+ switch (intn) {
124
+ case 1:
125
+ disabled = true;
126
+ break;
127
+ default:
128
+ disabled = false;
129
+ break;
130
+ }
131
+ } else {
132
+ disabled = false;
133
+ }
134
+ }
135
+
136
+ public String prettyName() {
137
+ if (name == null) {
138
+ if (this instanceof SinglePattern) {
139
+ return ((SinglePattern) this).match.pattern;
140
+ }
141
+ else if (this instanceof DoublePattern) {
142
+ return ((DoublePattern) this).begin.pattern;
143
+ }
144
+ else {
145
+ return "unknown";
146
+ }
147
+ }
148
+ else {
149
+ return name;
150
+ }
151
+ }
152
+ }
@@ -0,0 +1,91 @@
1
+ package com.redcareditor.mate;
2
+
3
+ import java.util.ArrayList;
4
+ import java.util.Iterator;
5
+ import java.util.List;
6
+
7
+ import com.redcareditor.onig.Range;
8
+
9
+ public class RangeSet implements Iterable<Range> {
10
+ List<Range> ranges = new ArrayList<Range>();
11
+
12
+ public void add(int a, int b) {
13
+ int insertAt = 0;
14
+ Range range = new Range(a, b);
15
+
16
+ while (insertAt < length() && ranges.get(insertAt).start < range.start) {
17
+ insertAt++;
18
+ }
19
+
20
+ merge(insertAt, range);
21
+ }
22
+
23
+ public Range get(int i) {
24
+ return ranges.get(i);
25
+ }
26
+
27
+ public int length() {
28
+ return size();
29
+ }
30
+
31
+ public int size() {
32
+ return ranges.size();
33
+ }
34
+
35
+ public int rangeSize() {
36
+ int sizec = 0;
37
+ for (int i = 0; i < length(); i++) {
38
+ sizec += ranges.get(i).end - ranges.get(i).start + 1;
39
+ }
40
+ return sizec;
41
+ }
42
+
43
+ public String present() {
44
+ return toString();
45
+ }
46
+
47
+ public String toString() {
48
+ StringBuilder sb = new StringBuilder("");
49
+ for (int i = 0; i < length(); i++) {
50
+ sb.append(get(i).toString());
51
+ if (i != length() - 1) {
52
+ sb.append(", ");
53
+ }
54
+ }
55
+ return sb.toString();
56
+ }
57
+
58
+ public boolean isEmpty() {
59
+ return ranges.isEmpty();
60
+ }
61
+
62
+ public Iterator<Range> iterator() {
63
+ return ranges.iterator();
64
+ }
65
+
66
+ private void merge(int mergeAt, Range range) {
67
+ ranges.add(mergeAt, range);
68
+
69
+ if (mergeAt > 0) {
70
+ Range beforeMerge = ranges.get(mergeAt - 1);
71
+ if (range.isTouching(beforeMerge)) {
72
+ ranges.remove(mergeAt);
73
+ beforeMerge.end = Math.max(beforeMerge.end, range.end);
74
+ mergeAt--;
75
+ range = ranges.get(mergeAt);
76
+ }
77
+ }
78
+
79
+ if (mergeAt + 1 < length()) {
80
+ Range afterMerge = ranges.get(mergeAt + 1);
81
+ while (mergeAt < length() - 1 && range.isTouching(afterMerge)) {
82
+ range.start = Math.min(range.start, afterMerge.start);
83
+ range.end = Math.max(range.end, afterMerge.end);
84
+ ranges.remove(mergeAt + 1);
85
+ if (mergeAt + 1 < length())
86
+ afterMerge = ranges.get(mergeAt + 1);
87
+ }
88
+ }
89
+ }
90
+
91
+ }