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,39 @@
1
+ package com.redcareditor.theme;
2
+
3
+ import java.util.ArrayList;
4
+ import java.util.List;
5
+
6
+ import com.redcareditor.onig.Rx;
7
+
8
+ public class ScopeSelector {
9
+ public Rx positiveRegex;
10
+ public List<Rx> negativeRegexes;
11
+
12
+ public static List<ScopeSelector> compile(String scopeSelector) {
13
+ List<ScopeSelector> result = new ArrayList<ScopeSelector>();
14
+ for (String selector : scopeSelector.split(",")) {
15
+ result.add(new ScopeSelector(selector));
16
+ }
17
+ return result;
18
+ }
19
+
20
+ private ScopeSelector(String selector) {
21
+ negativeRegexes = new ArrayList<Rx>();
22
+ String[] positivesAndNegatives = selector.split(" -");
23
+ for (String subSelector : positivesAndNegatives) {
24
+ if (positiveRegex == null) {
25
+ String s1 = backSlashDots(subSelector);
26
+ String s2 = s1.replace(" ", ").* .*(");
27
+ positiveRegex = Rx.createRx("(" + s2 + ")");
28
+ } else {
29
+ String s1 = backSlashDots(subSelector);
30
+ String s2 = s1.replace(" ", ".* .*");
31
+ negativeRegexes.add(Rx.createRx(s2));
32
+ }
33
+ }
34
+ }
35
+
36
+ private String backSlashDots(String subSelector) {
37
+ return subSelector.trim().replace(".", "\\.");
38
+ }
39
+ }
@@ -0,0 +1,122 @@
1
+ package com.redcareditor.theme;
2
+
3
+ import java.util.ArrayList;
4
+ import java.util.HashMap;
5
+ import java.util.List;
6
+ import java.util.Map;
7
+ import java.util.Collections;
8
+ import java.util.Comparator;
9
+
10
+ import com.redcareditor.mate.Scope;
11
+ import com.redcareditor.mate.ScopeMatcher;
12
+ import com.redcareditor.onig.Match;
13
+ import com.redcareditor.plist.Dict;
14
+ import com.redcareditor.plist.PlistNode;
15
+ import com.redcareditor.plist.PlistPropertyLoader;
16
+
17
+ public class Theme {
18
+ public String author;
19
+ public String name;
20
+ public Map<String, String> globalSettings = new HashMap<String, String>();
21
+ public List<ThemeSetting> settings = new ArrayList<ThemeSetting>();
22
+ public Map<String, ThemeSetting> cachedSettingsForScopes = new HashMap<String, ThemeSetting>();
23
+
24
+ private PlistPropertyLoader propertyLoader;
25
+ private boolean isInitialized = false;
26
+
27
+ public Theme(Dict dict) {
28
+ propertyLoader = new PlistPropertyLoader(dict, this);
29
+ propertyLoader.loadStringProperty("name");
30
+ propertyLoader.loadStringProperty("author");
31
+ loadSettings(dict);
32
+ }
33
+
34
+ private void loadSettings(Dict dict) {
35
+ List<PlistNode<?>> dictSettings = dict.getArray("settings");
36
+ for (PlistNode<?> node : dictSettings) {
37
+ Dict nodeDict = (Dict) node;
38
+ if (!nodeDict.containsElement("scope")) {
39
+ loadGlobalSetting(nodeDict);
40
+ } else {
41
+ settings.add(new ThemeSetting(nodeDict));
42
+ }
43
+ }
44
+ }
45
+
46
+ private void loadGlobalSetting(Dict nodeDict) {
47
+ Dict settingsDict = nodeDict.getDictionary("settings");
48
+ for (String key : settingsDict.value.keySet()) {
49
+ globalSettings.put(key, settingsDict.getString(key));
50
+ }
51
+ }
52
+
53
+ public void initForUse() {
54
+ if (isInitialized)
55
+ return;
56
+ isInitialized = true;
57
+ // System.out.printf("initializing theme for use: %s\n", name);
58
+ this.cachedSettingsForScopes = new HashMap<String, ThemeSetting>();
59
+ for (ThemeSetting setting : settings) {
60
+ setting.compileScopeMatchers();
61
+ }
62
+ }
63
+
64
+ public ThemeSetting settingsForScope(Scope scope, boolean inner, ThemeSetting excludeSetting) {
65
+ String hierarchyNames = scope.hierarchyNames(inner);
66
+ if (isSettingAlreadyCached(hierarchyNames)) {
67
+ return cachedSettingsForScopes.get(hierarchyNames);
68
+ } else {
69
+ ThemeSetting setting = findSetting(hierarchyNames, inner, excludeSetting);
70
+ cachedSettingsForScopes.put(hierarchyNames, setting);
71
+ return setting;
72
+ }
73
+ }
74
+
75
+ private boolean isSettingAlreadyCached(String scope) {
76
+ return cachedSettingsForScopes.containsKey(scope);
77
+ }
78
+
79
+ public class ThemeSettingComparator implements Comparator {
80
+ String scopeName;
81
+
82
+ public ThemeSettingComparator(String scopeName) {
83
+ this.scopeName = scopeName;
84
+ }
85
+
86
+ public int compare(Object o1, Object o2) {
87
+ return ScopeMatcher.compareMatch(scopeName, ((ThemeSetting) o1).thisMatch, ((ThemeSetting) o2).thisMatch);
88
+ }
89
+ }
90
+
91
+ public ThemeSetting findSetting(String hierarchyNames, boolean inner, ThemeSetting excludeSetting) {
92
+ // collect matching ThemeSettings
93
+ Match m;
94
+ ArrayList<ThemeSetting> matchingThemeSettings = new ArrayList<ThemeSetting>();
95
+ for (ThemeSetting setting : settings) {
96
+ if (setting == excludeSetting && excludeSetting != null) {
97
+ }
98
+ else {
99
+ if ((m = setting.match(hierarchyNames)) != null) {
100
+ setting.thisMatch = m;
101
+ matchingThemeSettings.add(setting);
102
+ }
103
+ }
104
+ }
105
+
106
+ Collections.sort(matchingThemeSettings, new ThemeSettingComparator(hierarchyNames));
107
+
108
+ // merge them together into a single ThemeSetting
109
+ ThemeSetting result = new ThemeSetting();
110
+ for (ThemeSetting ts : matchingThemeSettings) {
111
+ ts.thisMatch = null;
112
+ result.merge(ts);
113
+ }
114
+
115
+ return result;
116
+ }
117
+ }
118
+
119
+
120
+
121
+
122
+
@@ -0,0 +1,41 @@
1
+ package com.redcareditor.theme;
2
+
3
+ import java.io.File;
4
+ import java.util.ArrayList;
5
+ import java.util.List;
6
+
7
+ import com.redcareditor.plist.Dict;
8
+
9
+ public class ThemeManager {
10
+ public static List<Theme> themes;
11
+
12
+ public static List<String> themeNames(String textmateDir) {
13
+ List<String> names = new ArrayList<String>();
14
+ File dir = new File(textmateDir + "/Themes");
15
+ if (dir.exists()) {
16
+ for (String name : dir.list()) {
17
+ if (name.endsWith(".tmTheme")) {
18
+ names.add(name);
19
+ }
20
+ }
21
+ }
22
+ return names;
23
+ }
24
+
25
+ public static void loadThemes(String textmateDir) {
26
+ if (themes == null) {
27
+ themes = new ArrayList<Theme>();
28
+ }
29
+ for (String themeName : themeNames(textmateDir)) {
30
+ Dict dict = Dict.parseFile(textmateDir + "/Themes/" + themeName);
31
+ if (dict != null) {
32
+ Theme theme = new Theme(dict);
33
+ themes.add(theme);
34
+ }
35
+ }
36
+ }
37
+
38
+ private static boolean initialized() {
39
+ return themes != null;
40
+ }
41
+ }
@@ -0,0 +1,78 @@
1
+ package com.redcareditor.theme;
2
+
3
+ import java.util.HashMap;
4
+ import java.util.List;
5
+ import java.util.Map;
6
+
7
+ import com.redcareditor.mate.ScopeMatcher;
8
+ import com.redcareditor.onig.Match;
9
+ import com.redcareditor.plist.Dict;
10
+ import com.redcareditor.plist.PlistNode;
11
+ import com.redcareditor.plist.PlistPropertyLoader;
12
+
13
+ public class ThemeSetting {
14
+ public String name;
15
+ public String scopeSelector;
16
+ public String background;
17
+ public String foreground;
18
+ public String fontStyle;
19
+ public String marginBackground;
20
+ public String marginForeground;
21
+
22
+ public List<ScopeMatcher> matchers;
23
+
24
+ public Match thisMatch;
25
+
26
+ public ThemeSetting() {}
27
+
28
+ public ThemeSetting(Dict dict){
29
+ name = dict.getString("name");
30
+ scopeSelector = dict.getString("scope");
31
+
32
+ loadSettings(dict);
33
+ compileScopeMatchers();
34
+ }
35
+
36
+ private void loadSettings(Dict dict) {
37
+ Dict settingsDict = dict.getDictionary("settings");
38
+
39
+ background = getSetting(settingsDict, "background");
40
+ foreground = getSetting(settingsDict, "foreground");
41
+ fontStyle = getSetting(settingsDict, "fontStyle");
42
+ }
43
+
44
+ private String getSetting(Dict settingsDict, String settingName) {
45
+ PlistNode node = settingsDict.value.get(settingName);
46
+ return node == null ? null : (String) node.value;
47
+ }
48
+
49
+ public void compileScopeMatchers() {
50
+ this.matchers = ScopeMatcher.compile(scopeSelector);
51
+ }
52
+
53
+ public Match match(String scope) {
54
+ Match m;
55
+ if (this.matchers == null)
56
+ compileScopeMatchers();
57
+
58
+ for (ScopeMatcher matcher : this.matchers) {
59
+ if ((m = ScopeMatcher.testMatchRe(matcher.pos_rx, matcher.neg_rxs, scope)) != null)
60
+ return m;
61
+ }
62
+ return null;
63
+ }
64
+
65
+ // Merge this ThemeSetting with another, higher priority setting.
66
+ public void merge(ThemeSetting other) {
67
+ //System.out.printf("merging %s %s %s with %s %s %s\n",
68
+ // name, background, foreground,
69
+ // other.name, other.background, other.foreground);
70
+ if (other.background != null)
71
+ background = other.background;
72
+ if (other.foreground != null)
73
+ foreground = other.foreground;
74
+ if (other.fontStyle != null)
75
+ fontStyle = other.fontStyle;
76
+ }
77
+ }
78
+
@@ -0,0 +1,64 @@
1
+ package com.redcareditor.util;
2
+
3
+ import java.io.File;
4
+ import java.io.FileInputStream;
5
+ import java.io.FileNotFoundException;
6
+ import java.io.InputStream;
7
+
8
+ public class FileUtility {
9
+ private static final int INITIAL_BUFFER_SIZE = 2048;
10
+
11
+ /**
12
+ * read the file at the given path fully to a byte array.
13
+ */
14
+ public static byte[] readFully(String filepath)
15
+ throws FileNotFoundException {
16
+ return readFully(new File(filepath));
17
+ }
18
+
19
+ /**
20
+ * read the given file fully into a byte array.
21
+ *
22
+ * @return The files contents as a byte[].
23
+ * @throws FileNotFoundException
24
+ */
25
+ public static final byte[] readFully(File file)
26
+ throws FileNotFoundException {
27
+ return readFully(new FileInputStream(file));
28
+ }
29
+
30
+ /**
31
+ * read the given stream fully into a byte array.<br>
32
+ * This means that the stream has to end at some place, otherwise this
33
+ * method makes not sense.
34
+ */
35
+ public static final byte[] readFully(InputStream stream) {
36
+ try {
37
+ int readBytes = 0;
38
+ byte[] buffer = new byte[INITIAL_BUFFER_SIZE];
39
+ int b = 0;
40
+ while ((b = stream.read()) != -1) {
41
+ if (readBytes == buffer.length) {
42
+ buffer = doubleArraySize(buffer);
43
+ }
44
+
45
+ buffer[readBytes] = (byte) b;
46
+ readBytes++;
47
+ }
48
+
49
+ byte[] result = new byte[readBytes];
50
+ System.arraycopy(buffer, 0, result, 0, readBytes);
51
+ return result;
52
+
53
+ } catch (Exception e) {
54
+ e.printStackTrace();
55
+ }
56
+ return new byte[0];
57
+ }
58
+
59
+ private static final byte[] doubleArraySize(byte[] array) {
60
+ byte[] temp = new byte[array.length * 2];
61
+ System.arraycopy(array, 0, temp, 0, array.length);
62
+ return temp;
63
+ }
64
+ }
@@ -0,0 +1,11 @@
1
+
2
+ package com.redcareditor.util;
3
+
4
+ import java.util.logging.LogRecord;
5
+ import java.util.logging.SimpleFormatter;
6
+
7
+ public class SingleLineFormatter extends SimpleFormatter {
8
+ public String format(LogRecord record) {
9
+ return new java.util.Date().toGMTString() + " " + record.getLoggerName() + " " + record.getLevel() + " " + record.getMessage() + "\r\n";
10
+ }
11
+ }
@@ -0,0 +1,56 @@
1
+ package com.redcareditor.util.swt;
2
+
3
+ import org.eclipse.swt.graphics.Color;
4
+ import org.eclipse.swt.widgets.Display;
5
+
6
+
7
+ public class ColourUtil {
8
+
9
+ // Here parent_colour is like '#FFFFFF' and
10
+ // colour is like '#000000DD'.
11
+ static public String mergeColour(String parentColour, String colour) {
12
+ int pre_r, pre_g, pre_b;
13
+ int post_r, post_g, post_b;
14
+ int opacity;
15
+ int new_r, new_g, new_b;
16
+ String new_colour = null;
17
+ if (parentColour == null)
18
+ return null;
19
+ if (colour.length() == 7)
20
+ return colour;
21
+ if (colour.length() == 9) {
22
+ pre_r = ColourUtil.hex_to_int(parentColour.charAt(1), parentColour.charAt(2));
23
+ pre_g = ColourUtil.hex_to_int(parentColour.charAt(3), parentColour.charAt(4));
24
+ pre_b = ColourUtil.hex_to_int(parentColour.charAt(5), parentColour.charAt(6));
25
+
26
+ post_r = ColourUtil.hex_to_int(colour.charAt(1), colour.charAt(2));
27
+ post_g = ColourUtil.hex_to_int(colour.charAt(3), colour.charAt(4));
28
+ post_b = ColourUtil.hex_to_int(colour.charAt(5), colour.charAt(6));
29
+ opacity = ColourUtil.hex_to_int(colour.charAt(7), colour.charAt(8));
30
+
31
+ new_r = (pre_r*(255-opacity) + post_r*opacity)/255;
32
+ new_g = (pre_g*(255-opacity) + post_g*opacity)/255;
33
+ new_b = (pre_b*(255-opacity) + post_b*opacity)/255;
34
+ new_colour = String.format("#%02x%02x%02x", new_r, new_g, new_b);
35
+ // stdout.printf("%s/%s/%s - %d,%d,%d\n", parent_colour, colour, new_colour, new_r, new_g, new_b);
36
+ return new_colour;
37
+ }
38
+ return "#000000";
39
+ }
40
+
41
+ private static int char_to_hex(Character ch) {
42
+ return Character.digit(ch, 16);
43
+ }
44
+
45
+ private static int hex_to_int(char ch1, char ch2) {
46
+ return char_to_hex(ch1)*16 + char_to_hex(ch2);
47
+ }
48
+
49
+ public static Color getColour(String colour) {
50
+ return new Color(Display.getCurrent(),
51
+ Integer.parseInt(colour.substring(1, 3), 16),
52
+ Integer.parseInt(colour.substring(3, 5), 16),
53
+ Integer.parseInt(colour.substring(5, 7), 16));
54
+ }
55
+
56
+ }
@@ -0,0 +1,68 @@
1
+ require 'java'
2
+
3
+ $CLASSPATH << File.expand_path(File.join(File.dirname(__FILE__), *%w(.. .. bin)))
4
+ $:.push(File.expand_path(File.join(File.dirname(__FILE__), *%w(.. .. lib))))
5
+
6
+ require 'jdom'
7
+
8
+ require 'rbconfig'
9
+
10
+ swt_lib = case Config::CONFIG["host_os"]
11
+ when /darwin/i
12
+ if Config::CONFIG["host_cpu"] == "x86_64"
13
+ 'osx64/swt'
14
+ else
15
+ 'osx/swt'
16
+ end
17
+ when /linux/i
18
+ if %w(amd64 x84_64).include? Config::CONFIG["host_cpu"]
19
+ 'linux64/swt'
20
+ else
21
+ 'linux/swt'
22
+ end
23
+ when /windows/i
24
+ 'windows/swt'
25
+ end
26
+
27
+ require swt_lib
28
+ require 'org.eclipse.core.commands'
29
+ require 'org.eclipse.core.runtime_3.5.0.v20090525'
30
+ require 'org.eclipse.equinox.common'
31
+ require 'org.eclipse.jface.databinding_1.3.0.I20090525-2000'
32
+ require 'org.eclipse.jface'
33
+ require 'org.eclipse.jface.text_3.5.0'
34
+ require 'org.eclipse.osgi'
35
+ require 'org.eclipse.text_3.5.0.v20090513-2000'
36
+ require 'org.eclipse.core.jobs_3.4.100.v20090429-1800'
37
+ require 'org.eclipse.core.runtime_3.5.0.v20090525'
38
+ require 'org.eclipse.core.resources'
39
+
40
+ require 'swt_wrapper'
41
+
42
+ unless defined?(JavaMateView)
43
+
44
+ module JavaMateView
45
+ import com.redcareditor.mate.MateText
46
+ import com.redcareditor.mate.Grammar
47
+ import com.redcareditor.mate.Bundle
48
+ import com.redcareditor.mate.Parser
49
+ import com.redcareditor.mate.ParserScheduler
50
+ import com.redcareditor.theme.Theme
51
+ import com.redcareditor.theme.ThemeManager
52
+ end
53
+
54
+ module Plist
55
+ import com.redcareditor.plist.Dict
56
+ import com.redcareditor.plist.PlistNode
57
+ import com.redcareditor.plist.PlistPropertyLoader
58
+ end
59
+
60
+ module Onig
61
+ import com.redcareditor.onig.Rx
62
+ import com.redcareditor.onig.Match
63
+ end
64
+
65
+ module Util
66
+ import com.redcareditor.util.swt.ColourUtil
67
+ end
68
+ end