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,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
+ }