redcar-javamateview 0.1-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,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
+ }