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,22 @@
1
+ package com.redcareditor.mate;
2
+
3
+ import com.redcareditor.onig.Match;
4
+
5
+ public class Marker {
6
+ public boolean isCloseScope;
7
+ public Pattern pattern;
8
+ public Match match;
9
+ public int from; // the line offset where it begins
10
+ public int hint; // ??
11
+
12
+ public int length() {
13
+ return match.getCapture(0).end - from;
14
+ }
15
+
16
+ // Return the most urgent Marker to process. The criteria
17
+ // is earliest, longest markers.
18
+ public Marker bestOf(Marker current) {
19
+ if (current == null) return this;
20
+ return current.from <= from ? current : this;
21
+ }
22
+ }
@@ -0,0 +1,697 @@
1
+ package com.redcareditor.mate;
2
+
3
+ import java.util.ArrayList;
4
+ import java.util.HashMap;
5
+ import java.util.Iterator;
6
+ import java.util.List;
7
+ import java.util.logging.Logger;
8
+ import java.util.logging.Handler;
9
+ import java.util.logging.ConsoleHandler;
10
+ import java.util.logging.Level;
11
+
12
+ import org.eclipse.jface.text.*;
13
+ import org.eclipse.jface.text.source.*;
14
+ import org.eclipse.swt.SWT;
15
+ import org.eclipse.swt.custom.StyledText;
16
+ import org.eclipse.swt.events.*;
17
+ import org.eclipse.swt.graphics.*;
18
+ import org.eclipse.swt.layout.*;
19
+ import org.eclipse.swt.widgets.Shell;
20
+ import org.eclipse.swt.widgets.Display;
21
+ import org.eclipse.swt.widgets.Composite;
22
+ import org.eclipse.swt.widgets.Canvas;
23
+ import org.eclipse.jface.text.presentation.IPresentationReconciler;
24
+ import org.eclipse.jface.text.presentation.PresentationReconciler;
25
+ import org.eclipse.core.resources.IMarker;
26
+ import org.eclipse.core.runtime.*;
27
+ import org.eclipse.core.runtime.jobs.*;
28
+
29
+ import com.redcareditor.mate.colouring.Colourer;
30
+ import com.redcareditor.mate.colouring.swt.SwtColourer;
31
+ import com.redcareditor.mate.document.MateDocument;
32
+ import com.redcareditor.mate.document.MateTextLocation;
33
+ import com.redcareditor.mate.document.swt.SwtMateTextLocation;
34
+ import com.redcareditor.mate.document.swt.SwtMateDocument;
35
+ import com.redcareditor.mate.undo.MateTextUndoManager;
36
+ import com.redcareditor.mate.undo.swt.SwtMateTextUndoManager;
37
+ import com.redcareditor.mate.WhitespaceCharacterPainter;
38
+ import com.redcareditor.mate.LineNumberRulerColumn;
39
+ import com.redcareditor.onig.NullRx;
40
+ import com.redcareditor.onig.Rx;
41
+ import com.redcareditor.theme.Theme;
42
+ import com.redcareditor.theme.ThemeManager;
43
+ import com.redcareditor.util.SingleLineFormatter;
44
+
45
+ public class MateText {
46
+ public static String VERSION = "0.11";
47
+ public Parser parser;
48
+ public Colourer colourer;
49
+ public Logger logger;
50
+
51
+ static private Handler _consoleHandler;
52
+ static public Handler consoleHandler() {
53
+ if (_consoleHandler == null) {
54
+ _consoleHandler = new ConsoleHandler();
55
+ _consoleHandler.setFormatter(new SingleLineFormatter());
56
+ }
57
+ return _consoleHandler;
58
+ }
59
+
60
+ /* components plugged together */
61
+ public SourceViewer viewer;
62
+ private IDocument document;
63
+ private CompositeRuler compositeRuler;
64
+ public AnnotationRulerColumn annotationRuler;
65
+ private LineNumberRulerColumn lineNumbers;
66
+ private SwtMateDocument mateDocument;
67
+
68
+ private MateTextUndoManager undoManager;
69
+ private List<IGrammarListener> grammarListeners;
70
+
71
+ private boolean singleLine;
72
+ private WhitespaceCharacterPainter whitespaceCharacterPainter;
73
+ private boolean showingInvisibles;
74
+
75
+ private static HashMap<String, Image> annotationImages = new HashMap<String, Image>();
76
+
77
+ // annotation model
78
+ private AnnotationModel fAnnotationModel = new AnnotationModel();
79
+ private IAnnotationAccess fAnnotationAccess;
80
+ private AnnotationPainter annotationPainter;
81
+ private MouseListener annotationMouseListener;
82
+ private ColorCache cc;
83
+
84
+ private int marginColumn = -1;
85
+
86
+ public MateText(Composite parent) {
87
+ this(parent, false);
88
+ }
89
+
90
+ public MateText(Composite parent, boolean thisSingleLine) {
91
+ singleLine = thisSingleLine;
92
+ document = new Document();
93
+ if (singleLine)
94
+ createSingleLineSourceViewer(parent);
95
+ else
96
+ createSourceViewer(parent);
97
+
98
+ whitespaceCharacterPainter = new WhitespaceCharacterPainter(viewer);
99
+ showingInvisibles = false;
100
+
101
+ colourer = new SwtColourer(this);
102
+ mateDocument = new SwtMateDocument(this);
103
+ grammarListeners = new ArrayList<IGrammarListener>();
104
+ getTextWidget().setLeftMargin(5);
105
+ logger = Logger.getLogger("JMV.MateText");
106
+ logger.setUseParentHandlers(false);
107
+ logger.setLevel(Level.SEVERE);
108
+ for (Handler h : logger.getHandlers()) {
109
+ logger.removeHandler(h);
110
+ }
111
+ logger.addHandler(MateText.consoleHandler());
112
+ logger.info("Created MateText");
113
+ }
114
+
115
+ private void createSingleLineSourceViewer(Composite parent) {
116
+ viewer = new SourceViewer(parent, null, SWT.FULL_SELECTION | SWT.HORIZONTAL | SWT.VERTICAL | SWT.SINGLE);
117
+ viewer.setDocument(document);
118
+ }
119
+
120
+ private void createSourceViewer(Composite parent) {
121
+ fAnnotationAccess = new AnnotationMarkerAccess();
122
+
123
+ cc = new ColorCache();
124
+
125
+ compositeRuler = new CompositeRuler();
126
+ annotationRuler = new AnnotationRulerColumn(fAnnotationModel, 16, fAnnotationAccess);
127
+ compositeRuler.setModel(fAnnotationModel);
128
+
129
+ // add what types are show on the different rulers
130
+
131
+ lineNumbers = new LineNumberRulerColumn();
132
+ compositeRuler.addDecorator(0, lineNumbers);
133
+ compositeRuler.addDecorator(0, annotationRuler);
134
+
135
+ viewer = new SourceViewer(parent, compositeRuler, SWT.FULL_SELECTION | SWT.HORIZONTAL | SWT.VERTICAL);
136
+ viewer.setDocument(document, fAnnotationModel);
137
+
138
+ // hover manager that shows text when we hover
139
+ AnnotationHover ah = new AnnotationHover();
140
+ AnnotationConfiguration ac = new AnnotationConfiguration();
141
+ AnnotationBarHoverManager fAnnotationHoverManager = new AnnotationBarHoverManager(compositeRuler, viewer, ah, ac);
142
+ fAnnotationHoverManager.install(annotationRuler.getControl());
143
+
144
+ // to paint the annotations
145
+ annotationPainter = new AnnotationPainter(viewer, fAnnotationAccess);
146
+
147
+ // this will draw the squigglies under the text
148
+ viewer.addPainter(annotationPainter);
149
+
150
+ createAnnotationMouseListener();
151
+ }
152
+
153
+ private void createAnnotationMouseListener() {
154
+ annotationMouseListener = new MouseListener() {
155
+ public void mouseUp(MouseEvent event) {
156
+ int lineNumber = annotationRuler.toDocumentLineNumber(event.y);
157
+ for (IAnnotationAreaListener l : annotationListeners) {
158
+ l.mouseClick(lineNumber);
159
+ }
160
+ }
161
+
162
+ public void mouseDown(MouseEvent event) {
163
+ int lineNumber = annotationRuler.toDocumentLineNumber(event.y);
164
+ System.out.printf("mouseDown line: %d\n", lineNumber);
165
+ }
166
+
167
+ public void mouseDoubleClick(MouseEvent event) {
168
+ int lineNumber = annotationRuler.toDocumentLineNumber(event.y);
169
+ System.out.printf("doubleClick line: %d\n", lineNumber);
170
+ for (IAnnotationAreaListener l : annotationListeners) {
171
+ l.mouseDoubleClick(lineNumber);
172
+ }
173
+ }
174
+ };
175
+ annotationRuler.getControl().addMouseListener(annotationMouseListener);
176
+
177
+ }
178
+
179
+ public int getMarginColumn() {
180
+ return marginColumn;
181
+ }
182
+
183
+ public void setMarginColumn(int val) {
184
+ this.marginColumn = val;
185
+ redraw();
186
+ }
187
+
188
+ public void addAnnotationType(String type, String imagePath, RGB rgb) {
189
+ if (singleLine) return;
190
+
191
+ annotationRuler.addAnnotationType(type);
192
+ annotationPainter.addAnnotationType(type);
193
+ annotationPainter.setAnnotationTypeColor(type, new Color(Display.getDefault(), rgb));
194
+ MateText.annotationImages.put(type, new Image(Display.getDefault(), imagePath));
195
+ }
196
+
197
+ public MateAnnotation addAnnotation(String type, int line, String text, int start, int length) {
198
+ if (singleLine) return null;
199
+
200
+ MateAnnotation mateAnnotation = new MateAnnotation(type, line, text);
201
+ fAnnotationModel.addAnnotation(mateAnnotation, new Position(start, length));
202
+ return mateAnnotation;
203
+ }
204
+
205
+ public ArrayList<MateAnnotation> annotations() {
206
+ ArrayList<MateAnnotation> result = new ArrayList<MateAnnotation>();
207
+
208
+ Iterator i = fAnnotationModel.getAnnotationIterator();
209
+ while (i.hasNext()) {
210
+ MateAnnotation next = (MateAnnotation) i.next();
211
+ result.add(next);
212
+ }
213
+ return result;
214
+ }
215
+
216
+ public ArrayList<MateAnnotation> annotationsOnLine(int line) {
217
+ ArrayList<MateAnnotation> result = new ArrayList<MateAnnotation>();
218
+
219
+ StyledText text = getTextWidget();
220
+ int startOffset = text.getOffsetAtLine(line);
221
+ int endOffset;
222
+ if (line == text.getLineCount() - 1)
223
+ endOffset = text.getCharCount();
224
+ else
225
+ endOffset = text.getOffsetAtLine(line + 1);
226
+
227
+ Iterator i = fAnnotationModel.getAnnotationIterator(startOffset, endOffset - startOffset, false, true);
228
+ while (i.hasNext()) {
229
+ MateAnnotation next = (MateAnnotation) i.next();
230
+ result.add(next);
231
+ }
232
+ return result;
233
+ }
234
+
235
+ public void removeAnnotation(MateAnnotation ann) {
236
+ fAnnotationModel.removeAnnotation(ann);
237
+ }
238
+
239
+ public void removeAllAnnotations() {
240
+ fAnnotationModel.removeAllAnnotations();
241
+ }
242
+
243
+ private ArrayList<IAnnotationAreaListener> annotationListeners =
244
+ new ArrayList<IAnnotationAreaListener>();
245
+
246
+ public void addAnnotationListener(IAnnotationAreaListener listener) {
247
+ annotationListeners.add(listener);
248
+ }
249
+
250
+ public ArrayList<IAnnotationAreaListener> getAnnotationListeners() {
251
+ return annotationListeners;
252
+ }
253
+
254
+ public void removeAnnotationListener(IAnnotationAreaListener listener) {
255
+ annotationListeners.remove(listener);
256
+ }
257
+
258
+ public void setLineNumbersVisible(boolean val) {
259
+ if (isSingleLine()) return;
260
+ redrawRuler(val, getAnnotationsVisible());
261
+ }
262
+
263
+ // the annotationRuler doesn't seem to like being added/removed
264
+ // (images don't draw), so it's always visible for now.
265
+ //public void setAnnotationsVisible(boolean val) {
266
+ // if (isSingleLine()) return;
267
+ // redrawRuler(getLineNumbersVisible(), val);
268
+ //}
269
+
270
+ public boolean getLineNumbersVisible() {
271
+ if (isSingleLine()) return false;
272
+ Iterator iterator = compositeRuler.getDecoratorIterator();
273
+ while (iterator.hasNext())
274
+ if (((IVerticalRulerColumn) iterator.next()) == lineNumbers)
275
+ return true;
276
+ return false;
277
+ }
278
+
279
+ public boolean getAnnotationsVisible() {
280
+ Iterator iterator = compositeRuler.getDecoratorIterator();
281
+ while (iterator.hasNext())
282
+ if (((IVerticalRulerColumn) iterator.next()) == annotationRuler)
283
+ return true;
284
+ return false;
285
+ }
286
+
287
+ private void redrawRuler(boolean showLineNumbers, boolean showAnnotations) {
288
+ compositeRuler.removeDecorator(lineNumbers);
289
+ if (showLineNumbers)
290
+ compositeRuler.addDecorator(1, (IVerticalRulerColumn) lineNumbers);
291
+ compositeRuler.relayout();
292
+ }
293
+
294
+ public boolean isSingleLine() {
295
+ return singleLine;
296
+ }
297
+
298
+ public void showInvisibles(boolean should) {
299
+ if (should) {
300
+ showingInvisibles = true;
301
+ viewer.addPainter(whitespaceCharacterPainter);
302
+ } else {
303
+ showingInvisibles = false;
304
+ viewer.removePainter(whitespaceCharacterPainter);
305
+ }
306
+ }
307
+
308
+ public boolean isShowingInvisibles() {
309
+ return showingInvisibles;
310
+ }
311
+
312
+ public void attachUpdater() {
313
+
314
+ }
315
+
316
+ public boolean getWordWrap() {
317
+ return getTextWidget().getWordWrap();
318
+ }
319
+
320
+ public void setWordWrap(boolean val) {
321
+ getTextWidget().setWordWrap(val);
322
+ }
323
+
324
+ public String grammarName() {
325
+ return parser.grammar.name;
326
+ }
327
+
328
+ public StyledText getTextWidget() {
329
+ return viewer.getTextWidget();
330
+ }
331
+
332
+ public IDocument getDocument() {
333
+ return document;
334
+ }
335
+
336
+ public MateDocument getMateDocument() {
337
+ return mateDocument;
338
+ }
339
+
340
+ public StyledText getControl() {
341
+ return viewer.getTextWidget();
342
+ }
343
+
344
+ public boolean shouldColour() {
345
+ return parser.shouldColour();
346
+ }
347
+
348
+ public String scopeAt(int line, int line_offset) {
349
+ return parser.root.scopeAt(line, line_offset).hierarchyNames(true);
350
+ }
351
+
352
+ // Sets the grammar explicitly by name.
353
+ // TODO: restore the uncolouring stuff
354
+ public boolean setGrammarByName(String name) {
355
+ // System.out.printf("setGrammarByName(%s)\n", name);
356
+ if (this.parser != null && this.parser.grammar.name.equals(name))
357
+ return true;
358
+
359
+ for (Bundle bundle : Bundle.getBundles()) {
360
+ for (Grammar grammar : bundle.getGrammars()) {
361
+ if (grammar.name.equals(name)) {
362
+ if (this.parser != null) {
363
+ this.parser.close();
364
+ }
365
+ this.parser = new Parser(grammar, this);
366
+ if (colourer != null) {
367
+ colourer.setGlobalColours();
368
+ }
369
+ getMateDocument().reparseAll();
370
+ for (IGrammarListener grammarListener : grammarListeners) {
371
+ grammarListener.grammarChanged(grammar.name);
372
+ }
373
+ return true;
374
+ }
375
+ }
376
+ }
377
+ return false;
378
+ }
379
+
380
+ // Sets the grammar by the file extension. If unable to find
381
+ // a grammar, sets the grammar to null. Returns the grammar
382
+ // name or null.
383
+ public String setGrammarByFilename(String fileName) {
384
+ String bestName = null;
385
+ long bestLength = 0;
386
+ for (Bundle bundle : Bundle.getBundles()) {
387
+ for (Grammar grammar : bundle.getGrammars()) {
388
+ if (grammar.fileTypes != null) {
389
+ for (String ext : grammar.fileTypes) {
390
+ if (fileName.endsWith(ext) && (bestName == null || ext.length() > bestLength)) {
391
+ bestName = grammar.name;
392
+ bestLength = ext.length();
393
+ }
394
+ }
395
+ }
396
+ }
397
+ }
398
+ if (bestName != null) {
399
+ if (this.parser == null || this.parser.grammar.name != bestName) {
400
+ setGrammarByName(bestName);
401
+ }
402
+ return bestName;
403
+ }
404
+ return null;
405
+ }
406
+
407
+ // Sets the grammar by examining the first line. If unable to find
408
+ // a grammar, sets the grammar to null. Returns the grammar
409
+ // name or null.
410
+ public String setGrammarByFirstLine(String firstLine) {
411
+ Rx re;
412
+ for (Bundle bundle : Bundle.getBundles()) {
413
+ for (Grammar grammar : bundle.getGrammars()) {
414
+ re = grammar.firstLineMatch;
415
+ if (re instanceof NullRx) {
416
+ } else {
417
+ if (re.search(firstLine, 0, (int) firstLine.length()) != null) {
418
+ setGrammarByName(grammar.name);
419
+ return grammar.name;
420
+ }
421
+ }
422
+ }
423
+ }
424
+ return null;
425
+ }
426
+
427
+ public boolean setThemeByName(String name) {
428
+ for (Theme theme : ThemeManager.themes) {
429
+ if (theme.name.equals(name)) {
430
+ this.colourer.setTheme(theme);
431
+ return true;
432
+ }
433
+ }
434
+ return false;
435
+ }
436
+
437
+ public void setFont(String name, int size) {
438
+ Font font = new Font(Display.getCurrent(), name, size, 0);
439
+ viewer.getTextWidget().setFont(font);
440
+ if (!singleLine)
441
+ lineNumbers.setFont(font);
442
+ if (getLineNumbersVisible()){
443
+ redrawRuler(true, getAnnotationsVisible());
444
+ }
445
+ }
446
+
447
+ @SuppressWarnings("unchecked")
448
+ public void setGutterBackground(Color color) {
449
+ if (singleLine) return;
450
+ lineNumbers.setBackground(color);
451
+ }
452
+
453
+ public void setGutterForeground(Color color) {
454
+ if (singleLine) return;
455
+ lineNumbers.setForeground(color);
456
+ }
457
+
458
+ public void addGrammarListener(IGrammarListener listener) {
459
+ grammarListeners.add(listener);
460
+ }
461
+
462
+ public void removeGrammarListener(IGrammarListener listener) {
463
+ grammarListeners.remove(listener);
464
+ }
465
+
466
+ public void redraw() {
467
+ // SwtMateTextLocation startLocation = new SwtMateTextLocation(0, getMateDocument());
468
+ // SwtMateTextLocation endLocation = new SwtMateTextLocation(0 + getTextWidget().getCharCount(), getMateDocument());
469
+ getTextWidget().redraw();
470
+ }
471
+
472
+ class AnnotationConfiguration implements IInformationControlCreator {
473
+ public IInformationControl createInformationControl(Shell shell) {
474
+ return new DefaultInformationControl(shell);
475
+ }
476
+ }
477
+
478
+ class ColorCache implements ISharedTextColors {
479
+ public Color getColor(RGB rgb) {
480
+ return new Color(Display.getDefault(), rgb);
481
+ }
482
+
483
+ public void dispose() {
484
+ }
485
+ }
486
+
487
+ class AnnotationMarkerAccess implements IAnnotationAccess, IAnnotationAccessExtension {
488
+ public Object getType(Annotation annotation) {
489
+ return annotation.getType();
490
+ }
491
+
492
+ public boolean isMultiLine(Annotation annotation) {
493
+ return true;
494
+ }
495
+
496
+ public boolean isTemporary(Annotation annotation) {
497
+ return !annotation.isPersistent();
498
+ }
499
+
500
+ public String getTypeLabel(Annotation annotation) {
501
+ if (annotation instanceof MateAnnotation)
502
+ return "Errors";
503
+
504
+ return null;
505
+ }
506
+
507
+ public int getLayer(Annotation annotation) {
508
+ if (annotation instanceof MateAnnotation)
509
+ return ((MateAnnotation)annotation).getLayer();
510
+
511
+ return 0;
512
+ }
513
+
514
+ public void paint(Annotation annotation, GC gc, Canvas canvas, Rectangle bounds) {
515
+ ImageUtilities.drawImage(((MateAnnotation)annotation).getImage(), gc, canvas, bounds, SWT.CENTER, SWT.TOP);
516
+ }
517
+
518
+ public boolean isPaintable(Annotation annotation) {
519
+ if (annotation instanceof MateAnnotation)
520
+ return ((MateAnnotation)annotation).getImage() != null;
521
+
522
+ return false;
523
+ }
524
+
525
+ public boolean isSubtype(Object annotationType, Object potentialSupertype) {
526
+ if (annotationType.equals(potentialSupertype))
527
+ return true;
528
+
529
+ return false;
530
+
531
+ }
532
+
533
+ public Object[] getSupertypes(Object annotationType) {
534
+ return new Object[0];
535
+ }
536
+ }
537
+
538
+ // annotation hover manager
539
+ class AnnotationHover implements IAnnotationHover, ITextHover {
540
+ public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
541
+ Iterator ite;
542
+ int startOffset;
543
+ int endOffset;
544
+ StyledText text = getTextWidget();
545
+ try {
546
+ if (lineNumber < 0 || lineNumber >= text.getLineCount()) return null;
547
+ startOffset = text.getOffsetAtLine(lineNumber);
548
+ if (lineNumber == text.getLineCount() - 1) {
549
+ endOffset = text.getCharCount();
550
+ } else {
551
+ endOffset = text.getOffsetAtLine(lineNumber + 1);
552
+ }
553
+ ite = fAnnotationModel.getAnnotationIterator(
554
+ startOffset, endOffset - startOffset, false, true);
555
+ } catch(java.lang.IllegalArgumentException e) {
556
+ System.out.printf("warning: got java.lang.IllegalArgumentException in AnnotationHover#getHoverInfo(%d). lineCount was %d\n", lineNumber, text.getLineCount());
557
+ return "";
558
+ }
559
+
560
+ ArrayList all = new ArrayList();
561
+
562
+ while (ite.hasNext()) {
563
+ Annotation a = (Annotation) ite.next();
564
+ if (a instanceof MateAnnotation) {
565
+ all.add(((MateAnnotation)a).getText());
566
+ }
567
+ }
568
+
569
+ StringBuffer total = new StringBuffer();
570
+ for (int x = 0; x < all.size(); x++) {
571
+ String str = (String) all.get(x);
572
+ total.append(" " + str + (x == (all.size()-1) ? "" : "\n"));
573
+ }
574
+
575
+ return total.toString();
576
+ }
577
+
578
+ public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
579
+ return null;
580
+ }
581
+
582
+ public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
583
+ return null;
584
+ }
585
+ }
586
+
587
+ class MateAnnotation extends Annotation {
588
+ private IMarker marker;
589
+ private String text;
590
+ private int line;
591
+ private Position position;
592
+ private String type;
593
+
594
+ public MateAnnotation(IMarker marker) {
595
+ this.marker = marker;
596
+ }
597
+
598
+ public MateAnnotation(String type, int line, String text) {
599
+ super(type, true, null);
600
+ this.marker = null;
601
+ this.line = line;
602
+ this.text = text;
603
+ this.type = type;
604
+ }
605
+
606
+ public IMarker getMarker() {
607
+ return marker;
608
+ }
609
+
610
+ public int getLine() {
611
+ return line;
612
+ }
613
+
614
+ public String getText() {
615
+ return text;
616
+ }
617
+
618
+ public Image getImage() {
619
+ return MateText.annotationImages.get(this.type);
620
+ }
621
+
622
+ public int getLayer() {
623
+ return 3;
624
+ }
625
+
626
+ public String getType() {
627
+ return type;
628
+ }
629
+
630
+ public Position getPosition() {
631
+ return position;
632
+ }
633
+
634
+ public void setPosition(Position position) {
635
+ this.position = position;
636
+ }
637
+ }
638
+
639
+ // See the table in the comment for columnOfLineOffset. This method translates from
640
+ // column to lineOffset in that table.
641
+ public static int lineOffsetOfColumn(String line, int targetColumn, int tabWidth) {
642
+ int offset = 0;
643
+ int newOffset = 0;
644
+ int column = 0;
645
+ int prevOffset = 0;
646
+ int prevColumn = 0;
647
+ while ((newOffset = line.indexOf("\t", offset)) != -1) {
648
+ newOffset++;
649
+ prevOffset = offset;
650
+ prevColumn = column;
651
+ column += newOffset - offset + tabWidth - 1;
652
+ offset = newOffset;
653
+ if (column > targetColumn)
654
+ return prevOffset + (targetColumn - prevColumn);
655
+ else if (column == targetColumn)
656
+ return offset;
657
+ }
658
+ return offset + targetColumn - column;
659
+ }
660
+
661
+ // if line is "\t\tasd", tab width is 4, then
662
+ //
663
+ // lineOffset, column
664
+ // 0 0
665
+ // 1 4
666
+ // 2 8
667
+ // 3 9
668
+ // 4 10
669
+ // 5 11
670
+ // 6 12 (note past the end of the string)
671
+ //
672
+ // This function translates from lineOffset to column
673
+ public static int columnOfLineOffset(String line, int lineOffset, int tabWidth) {
674
+ int stringOffset = Math.max(lineOffset, line.length());
675
+ String before = line.substring(0, stringOffset);
676
+ int length = before.length();
677
+ return (length + (tabWidth - 1)*countMatches(before, "\t"));
678
+ }
679
+
680
+ private static boolean isEmpty(String cs) {
681
+ return cs == null || cs.length() == 0;
682
+ }
683
+
684
+ private static int countMatches(String str, String sub) {
685
+ if (isEmpty(str) || isEmpty(sub)) {
686
+ return 0;
687
+ }
688
+ int count = 0;
689
+ int idx = 0;
690
+ while ((idx = str.indexOf(sub, idx)) != -1) {
691
+ count++;
692
+ idx += sub.length();
693
+ }
694
+ return count;
695
+ }
696
+ //
697
+ }