diff --git a/Jenkinsfile b/Jenkinsfile
index cb8e6a094..7992cda8b 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,6 +1,10 @@
pipeline {
agent {
- label 'migration'
+ label 'centos-latest'
+ }
+ tools {
+ maven 'apache-maven-latest'
+ jdk 'openjdk-jdk11-latest'
}
options {
buildDiscarder(logRotator(numToKeepStr:'10'))
diff --git a/README.md b/README.md
index 3ecd76cb9..e6398c330 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,22 @@
-# Eclipse tm4e - TextMate support in Eclipse IDE
+# Eclipse tm4e - TextMate and language-configuration support for Java and in Eclipse IDE
-[](https://github.com/eclipse/tm4e/blob/master/LICENSE)
-[](http://travis-ci.org/eclipse/tm4e)
+TM4E brings Java API to tokenize textual documents according to TextMate grammars with an Eclipse IDE client that can do syntax highlighting according to this tokenization; and Eclipse IDE client for VSCode [Language Configuration](https://code.visualstudio.com/docs/extensionAPI/extension-points#_contributeslanguages) to support matching bracket, auto close, on enter support.
-`tm4e` provides the capability to support :
+`tm4e` is an [official Eclipse.org project](https://projects.eclipse.org/projects/technology.tm4e) so it conforms to typical Eclipse.org requirements and guarantees.
- * `TextMate tokenizer` with Java and integrates it with Eclipse IDE.
- * VSCode [Language Configuration](https://code.visualstudio.com/docs/extensionAPI/extension-points#_contributeslanguages) to support matching bracket, auto close, on enter support.
+## 📥 Install
-`tm4e` is an [official Eclipse.org project](https://projects.eclipse.org/projects/technology.tm4e) so it conforms to typical Eclipse.org requirements and guarantees.
+### in Eclipse IDE or RCP applications
-## Install
+You can install `tm4e` with the update site [http://download.eclipse.org/tm4e/snapshots/](http://download.eclipse.org/tm4e/snapshots/). TM4E is usually installed together with its consumers, so end-user should usually not need to directly install it.
-You can install `tm4e` with the update site `http://download.eclipse.org/tm4e/snapshots/` which provides samples of syntax coloration with:
+### as a Java API with Maven
- * GenericEditor for Language Server (C#, CSS, JSON)
- * a TypeScript Editor.
+[more information coming soon]
-## Code
+## ⌨️ Code
-It provides:
+The following class and modules should be used as entry point provides:
* [org.eclipse.tm4e.core](https://github.com/eclipse/tm4e/tree/master/org.eclipse.tm4e.core) provides the Java TextMate tokenizer. This project is a Java port of [vscode-textmate](https://github.com/Microsoft/vscode-textmate) written in TypeScript. This Java API can be used with any Java UI Toolkit (Swing, Eclipse, etc). See [Core](https://github.com/eclipse/tm4e/wiki/Core) section for more information.
@@ -31,13 +28,14 @@ Here a sample with TypeScript:

-## Who is using tm4e?
+## 👪 Who is using tm4e?
Here are some projects that use tm4e:
* [Eclipse Corrosion](https://github.com/eclipse/corrosion) Rust development tools in Eclipse IDE.
* [Eclipse aCute](https://github.com/eclipse/aCute) C# edition in Eclipse IDE.
* [Eclipse Wild Web Developer](https://github.com/eclipse/wildwebdeveloper) a simple and productive Web Development Tools in the Eclipse IDE.
+ * [Eclipse ShellWax](https://github.com/eclipse/shellwax) is a rich Bash script editor in the Eclipse IDE.
* [LiClipseText](http://www.liclipse.com/text/) enables Eclipse to be used as a general-purpose text editor, providing support for several languages out of the box.
* [typescript.java](https://github.com/angelozerr/typescript.java) TypeScript IDE for Eclipse with JSDT & tsserver.
* [EditorConfig for Eclipse](https://github.com/angelozerr/ec4e) EditorConfig for Eclipse with GenericEditor.
@@ -45,11 +43,12 @@ Here are some projects that use tm4e:
* [Solargraph](https://github.com/PyvesB/eclipse-solargraph) Ruby edition in Eclipse IDE.
* [Dartboard](https://github.com/eclipse/dartboard) Dart language support in the Eclipse IDE.
-## Get support and contribute
+## 👷 Get support and contribute
* **License and community**: `tm4e` is a community open-source project licensed under the Eclipse Public License 1.0.
-* **Support:** You can ask questions, report bugs, and request features using [GitHub issues](http://github.com/eclipse/tm4e/issues).
+* **Support:** You can ask (and answer!) questions, report bugs, and request features using [GitHub issues](http://github.com/eclipse/tm4e/issues).
* **Git**: This `eclipse/tm4e` repository is the reference repository to contribute to `tm4e`
-* **Build and CI**: build can be performed with a simple `mvn clean verify`, continuous integration and deployment is performed by CI jobs at https://hudson.eclipse.org/tm4e
+* **Build**: build can be performed with a simple `mvn clean verify`, continuous integration and deployment is performed by CI jobs at https://hudson.eclipse.org/tm4e
+* **Continuous testing, integration and deployment** is performed by CI jobs at https://hudson.eclipse.org/tm4e
* **Developers mailing-list**: Contributors are also expected to subscribe the [tm4e-dev mailing-list](https://dev.eclipse.org/mailman/listinfo/tm4e-dev).
* **Becoming a committer**: as usual with Eclipse.org projects, anyone who's made significant contributions and who's upheld quality standards alongside good judgement and open-mindedness.
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
new file mode 100644
index 000000000..b891a35ab
--- /dev/null
+++ b/RELEASE_NOTES.md
@@ -0,0 +1,34 @@
+# Eclipse TM4E: Release notes
+
+This page describes the noteworthy improvements provided by each release of Eclipse TM4E.
+
+### Next release...
+
+## 0.4.2
+
+* 📅 Release Date (tentative): ?
+* All changes: https://github.com/eclipse/tm4e/compare/0.4.1...0.4.2
+
+## 0.4.1
+
+* 📅 Release Date: 27th August 2020
+* All changes: https://github.com/eclipse/tm4e/compare/0.4.0...0.4.1
+
+#### Users can add TextMate theme
+
+It's not possible for users to add extra TextMate theme to use in their IDE via the Textmate > Theme preference page.
+
+## 0.4.0
+
+* 📅 Release Date: 21st November 2019
+* All changes: https://github.com/eclipse/tm4e/compare/0.3.4...0.4.0
+
+#### Improve logging mechanism
+
+Most TM4E API entry-points can now be configured with a specific logger. That allows embedders (like the Eclipse UI plugin) to pass a specific logger so TM4E can log at the same location as other parts of the application that includes it, or enable some totally different logging is it fits better.
+
+In Eclipse IDE, the logger takes the "trace" settings into account and logs in the usual Eclipse logs.
+
+## Previous releases
+
+No release notes were maintained before that.
diff --git a/documentation/TROUBLESHOOTING.md b/documentation/TROUBLESHOOTING.md
new file mode 100644
index 000000000..b107904b3
--- /dev/null
+++ b/documentation/TROUBLESHOOTING.md
@@ -0,0 +1,11 @@
+## Troubleshooting TM4E
+
+This document list some typical options and workflows to actively analyze and fix issues happening in TM4E. Target users of those troubleshooting hints are TM4E users and contributors who want to add some more technical information about issues they face or investigate when reporting or discussing a specific bug on issue tickets.
+
+#### Get more debug traces from TM4E in Eclipse IDE
+
+Add a line `org.eclipse.tm4e.ui/trace=true` into a properties file (usually named `debug.options`). Then edit you `eclipse.ini` file so it adds the followng paramter `-debug /path/to/debug.options`). The file will be inspected and the option will trigger additional debug information in the Eclipse IDE log.
+
+#### Enable recording of text events to more easily reproduce bugs and write tests
+
+Add a line `org.eclipse.tm4e.ui/debug/log/GenerateTest=true` into a properties file (usually named `debug.options`). Then edit you `eclipse.ini` file so it adds the followng paramter `-debug /path/to/debug.options`). The file will be inspected and the option will trigger generation of a Java test skeleton on the error output stream when closing an editor which uses TM4E for syntax highlighting.
\ No newline at end of file
diff --git a/org.eclipse.tm4e.core/META-INF/MANIFEST.MF b/org.eclipse.tm4e.core/META-INF/MANIFEST.MF
index 78e5d0024..3daa6c456 100644
--- a/org.eclipse.tm4e.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.tm4e.core/META-INF/MANIFEST.MF
@@ -4,7 +4,7 @@ Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Bundle-SymbolicName: org.eclipse.tm4e.core
-Bundle-Version: 0.4.0.qualifier
+Bundle-Version: 0.4.1.qualifier
Require-Bundle: org.apache.batik.css;bundle-version="1.9.1";resolution:=optional,
org.apache.batik.util;bundle-version="1.9.1";resolution:=optional,
com.google.gson;resolution:=optional,
diff --git a/org.eclipse.tm4e.core/pom.xml b/org.eclipse.tm4e.core/pom.xml
index feca88254..aa6927b57 100644
--- a/org.eclipse.tm4e.core/pom.xml
+++ b/org.eclipse.tm4e.core/pom.xml
@@ -2,7 +2,7 @@
4.0.0
org.eclipse.tm4e.core
eclipse-plugin
- 0.4.0-SNAPSHOT
+ 0.4.1-SNAPSHOT
org.eclipse
org.eclipse.tm4e
diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/TMException.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/TMException.java
index 0ec1cebf3..e9ff82962 100644
--- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/TMException.java
+++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/TMException.java
@@ -22,4 +22,8 @@ public class TMException extends RuntimeException {
public TMException(String message) {
super(message);
}
+
+ public TMException(String message, Throwable cause) {
+ super(message, cause);
+ }
}
diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/model/Tokenizer.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/model/Tokenizer.java
index 3de8241e4..12d828b73 100644
--- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/model/Tokenizer.java
+++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/model/Tokenizer.java
@@ -62,7 +62,7 @@ public LineTokens tokenize(String line, TMState state, Integer offsetDelta, Inte
// state
// );
// }
- TMState freshState = state.clone();
+ TMState freshState = state != null ? state.clone() : getInitialState();
ITokenizeLineResult textMateResult = grammar.tokenizeLine(line, freshState.getRuleStack());
freshState.setRuleStack(textMateResult.getRuleStack());
diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/Registry.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/Registry.java
index d6aabc0ea..19a6e2e50 100644
--- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/Registry.java
+++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/Registry.java
@@ -115,7 +115,7 @@ private IGrammar _loadGrammar(String initialScopeName) {
// callback(new Error('Unknown location for grammar <' +
// initialScopeName + '>'), null);
// return;
- throw new TMException("Unknown location for grammar <" + initialScopeName + ">");
+ throw new TMException("Unknown location for grammar <" + initialScopeName + ">", e);
}
}
}
diff --git a/org.eclipse.tm4e.feature/feature.xml b/org.eclipse.tm4e.feature/feature.xml
index 7ac0d6a00..68a487f08 100644
--- a/org.eclipse.tm4e.feature/feature.xml
+++ b/org.eclipse.tm4e.feature/feature.xml
@@ -2,7 +2,7 @@
diff --git a/org.eclipse.tm4e.feature/pom.xml b/org.eclipse.tm4e.feature/pom.xml
index 83410ac8d..54a383d9a 100644
--- a/org.eclipse.tm4e.feature/pom.xml
+++ b/org.eclipse.tm4e.feature/pom.xml
@@ -7,5 +7,5 @@
org.eclipse.tm4e.feature
eclipse-feature
- 0.4.0-SNAPSHOT
+ 0.4.1-SNAPSHOT
diff --git a/org.eclipse.tm4e.languageconfiguration/META-INF/MANIFEST.MF b/org.eclipse.tm4e.languageconfiguration/META-INF/MANIFEST.MF
index f66c3818a..46de8d799 100644
--- a/org.eclipse.tm4e.languageconfiguration/META-INF/MANIFEST.MF
+++ b/org.eclipse.tm4e.languageconfiguration/META-INF/MANIFEST.MF
@@ -4,7 +4,7 @@ Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Bundle-SymbolicName: org.eclipse.tm4e.languageconfiguration;singleton:=true
-Bundle-Version: 0.3.4.qualifier
+Bundle-Version: 0.3.5.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: org.eclipse.jface.text,
org.eclipse.ui.genericeditor,
diff --git a/org.eclipse.tm4e.languageconfiguration/plugin.xml b/org.eclipse.tm4e.languageconfiguration/plugin.xml
index 8e6ea98ac..cd80e0723 100644
--- a/org.eclipse.tm4e.languageconfiguration/plugin.xml
+++ b/org.eclipse.tm4e.languageconfiguration/plugin.xml
@@ -69,7 +69,7 @@
contextId="org.eclipse.ui.textEditorScope"
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
platform="carbon"
- sequence="M1+/">
+ sequence="M1+M4+/">
+ sequence="M1+M4+\">
4.0.0
org.eclipse.tm4e.languageconfiguration
eclipse-plugin
- 0.3.4-SNAPSHOT
+ 0.3.5-SNAPSHOT
org.eclipse
org.eclipse.tm4e
diff --git a/org.eclipse.tm4e.languageconfiguration/src/main/java/org/eclipse/tm4e/languageconfiguration/LanguageConfigurationCharacterPairMatcher.java b/org.eclipse.tm4e.languageconfiguration/src/main/java/org/eclipse/tm4e/languageconfiguration/LanguageConfigurationCharacterPairMatcher.java
index 21eeabae9..0eab91090 100644
--- a/org.eclipse.tm4e.languageconfiguration/src/main/java/org/eclipse/tm4e/languageconfiguration/LanguageConfigurationCharacterPairMatcher.java
+++ b/org.eclipse.tm4e.languageconfiguration/src/main/java/org/eclipse/tm4e/languageconfiguration/LanguageConfigurationCharacterPairMatcher.java
@@ -109,6 +109,7 @@ private DefaultCharacterPairMatcher getMatcher(IDocument document) {
// initizalize a DefaultCharacterPairMatcher by using character pairs of the
// language configuration.
StringBuilder chars = new StringBuilder();
+ this.document = document;
IContentType[] contentTypes = findContentTypes(document);
if (contentTypes != null) {
LanguageConfigurationRegistryManager registry = LanguageConfigurationRegistryManager.getInstance();
@@ -131,8 +132,9 @@ private DefaultCharacterPairMatcher getMatcher(IDocument document) {
private IContentType[] findContentTypes(IDocument document) {
try {
ContentTypeInfo info = ContentTypeHelper.findContentTypes(document);
- this.document = document;
- return info.getContentTypes();
+ if(info != null) {
+ return info.getContentTypes();
+ }
} catch (CoreException e) {
e.printStackTrace();
}
diff --git a/org.eclipse.tm4e.ui/META-INF/MANIFEST.MF b/org.eclipse.tm4e.ui/META-INF/MANIFEST.MF
index 7aa714945..9c57e5c98 100644
--- a/org.eclipse.tm4e.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.tm4e.ui/META-INF/MANIFEST.MF
@@ -4,7 +4,7 @@ Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Bundle-SymbolicName: org.eclipse.tm4e.ui;singleton:=true
-Bundle-Version: 0.4.0.qualifier
+Bundle-Version: 0.4.1.qualifier
Require-Bundle: org.eclipse.tm4e.core,
org.eclipse.jface.text,
org.eclipse.core.runtime,
diff --git a/org.eclipse.tm4e.ui/pom.xml b/org.eclipse.tm4e.ui/pom.xml
index 50f2e06d6..3eb5ca5a8 100644
--- a/org.eclipse.tm4e.ui/pom.xml
+++ b/org.eclipse.tm4e.ui/pom.xml
@@ -2,7 +2,7 @@
4.0.0
org.eclipse.tm4e.ui
eclipse-plugin
- 0.4.0-SNAPSHOT
+ 0.4.1-SNAPSHOT
org.eclipse
org.eclipse.tm4e
diff --git a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/TMUIMessages.properties b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/TMUIMessages.properties
index 6ad0782ec..0066ccf12 100644
--- a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/TMUIMessages.properties
+++ b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/TMUIMessages.properties
@@ -10,10 +10,10 @@
###############################################################################
# Buttons
-Button_new=&New...
+Button_new=&Add...
Button_edit=&Edit...
-Button_remove=&Remove...
-Button_browse_FileSystem=Browse FileSystem...
+Button_remove=&Remove
+Button_browse_FileSystem=Browse Filesystem...
Button_browse_Workspace=Browse Workspace...
# preference page
diff --git a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/preferences/PreferenceHelper.java b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/preferences/PreferenceHelper.java
index 12770aab4..c7a4d4dee 100644
--- a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/preferences/PreferenceHelper.java
+++ b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/preferences/PreferenceHelper.java
@@ -32,12 +32,7 @@ public class PreferenceHelper {
private static final Gson DEFAULT_GSON;
static {
- DEFAULT_GSON = new GsonBuilder().registerTypeAdapter(ITheme.class, new InstanceCreator() {
- @Override
- public Theme createInstance(Type type) {
- return new Theme();
- }
- }).registerTypeAdapter(IThemeAssociation.class, new InstanceCreator() {
+ DEFAULT_GSON = new GsonBuilder().registerTypeAdapter(IThemeAssociation.class, new InstanceCreator() {
@Override
public ThemeAssociation createInstance(Type type) {
return new ThemeAssociation();
@@ -45,14 +40,6 @@ public ThemeAssociation createInstance(Type type) {
}).create();
}
- public static ITheme[] loadThemes(String json) {
- return DEFAULT_GSON.fromJson(json, Theme[].class);
- }
-
- public static String toJsonThemes(Collection themes) {
- return DEFAULT_GSON.toJson(themes);
- }
-
public static IThemeAssociation[] loadThemeAssociations(String json) {
return DEFAULT_GSON.fromJson(json, ThemeAssociation[].class);
}
diff --git a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/preferences/ThemePreferencePage.java b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/preferences/ThemePreferencePage.java
index 2c80cce31..e685ede86 100644
--- a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/preferences/ThemePreferencePage.java
+++ b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/preferences/ThemePreferencePage.java
@@ -12,6 +12,10 @@
*******************************************************************************/
package org.eclipse.tm4e.ui.internal.preferences;
+import java.io.File;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.preference.PreferencePage;
@@ -19,9 +23,8 @@
import org.eclipse.jface.util.BidiUtils;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ComboViewer;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
@@ -31,6 +34,7 @@
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
@@ -50,8 +54,10 @@
import org.eclipse.tm4e.ui.internal.widgets.ThemeLabelProvider;
import org.eclipse.tm4e.ui.themes.ITheme;
import org.eclipse.tm4e.ui.themes.IThemeManager;
+import org.eclipse.tm4e.ui.themes.Theme;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.osgi.service.prefs.BackingStoreException;
/**
* A theme preference page allows configuration of the TextMate themes It
@@ -64,61 +70,26 @@ public class ThemePreferencePage extends PreferencePage implements IWorkbenchPre
// Theme content
private TableViewer themeViewer;
- private Button themeNewButton;
private Button themeRemoveButton;
// Preview content
private ComboViewer grammarViewer;
private TMViewer previewViewer;
- private IGrammarRegistryManager grammarRegistryManager;
- private IThemeManager themeManager;
+ private final IGrammarRegistryManager grammarRegistryManager;
+ private final IThemeManager themeManager;
private Button darkThemeButton;
private Button defaultThemeButton;
+
+ private ITheme selectedTheme;
public ThemePreferencePage() {
super();
setDescription(TMUIMessages.ThemePreferencePage_description);
- setGrammarRegistryManager(TMEclipseRegistryPlugin.getGrammarRegistryManager());
- setThemeManager(TMUIPlugin.getThemeManager());
- }
-
- /**
- * Returns the grammar registry manager.
- *
- * @return the grammar registry manager.
- */
- public IGrammarRegistryManager getGrammarRegistryManager() {
- return grammarRegistryManager;
- }
-
- /**
- * Set the grammar registry manager.
- *
- * @param grammarRegistryManager
- */
- public void setGrammarRegistryManager(IGrammarRegistryManager grammarRegistryManager) {
- this.grammarRegistryManager = grammarRegistryManager;
- }
-
- /**
- * Returns the theme manager.
- *
- * @return the theme manager.
- */
- public IThemeManager getThemeManager() {
- return themeManager;
- }
-
- /**
- * Set the theme manager.
- *
- * @param themeManager
- */
- public void setThemeManager(IThemeManager themeManager) {
- this.themeManager = themeManager;
+ this.grammarRegistryManager = TMEclipseRegistryPlugin.getGrammarRegistryManager();
+ this.themeManager = TMUIPlugin.getThemeManager();
}
@Override
@@ -150,7 +121,6 @@ protected Control createContents(Composite ancestor) {
}
themeViewer.setInput(themeManager);
- updateButtons();
Dialog.applyDialogFont(parent);
innerParent.layout();
@@ -159,7 +129,7 @@ protected Control createContents(Composite ancestor) {
/**
* Create the theme list content.
- *
+ *
* @param parent
*/
private void createThemesContent(Composite parent) {
@@ -208,15 +178,15 @@ private void createThemesContent(Composite parent) {
themeViewer.setLabelProvider(new ThemeLabelProvider());
themeViewer.setContentProvider(new ThemeContentProvider());
themeViewer.setComparator(viewerComparator);
- themeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
- @Override
- public void selectionChanged(SelectionChangedEvent e) {
- // Fill Theme details
- ITheme theme = ((ITheme) ((IStructuredSelection) themeViewer.getSelection()).getFirstElement());
- darkThemeButton.setSelection(theme.isDark());
- defaultThemeButton.setSelection(theme.isDefault());
- preview();
+ themeViewer.addSelectionChangedListener(e -> {
+ // Fill Theme details
+ selectedTheme = ((ITheme) ((IStructuredSelection) themeViewer.getSelection()).getFirstElement());
+ if (selectedTheme != null) {
+ darkThemeButton.setSelection(selectedTheme.isDark());
+ defaultThemeButton.setSelection(selectedTheme.isDefault());
+ themeRemoveButton.setEnabled(selectedTheme.getPluginId() == null);
}
+ preview();
});
// Specify default sorting
@@ -232,30 +202,47 @@ public void selectionChanged(SelectionChangedEvent e) {
layout.marginWidth = 0;
buttons.setLayout(layout);
- themeNewButton = new Button(buttons, SWT.PUSH);
+ Button themeNewButton = new Button(buttons, SWT.PUSH);
themeNewButton.setText(TMUIMessages.Button_new);
themeNewButton.setLayoutData(getButtonGridData(themeNewButton));
themeNewButton.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event e) {
- // add();
+ ITheme newTheme = addTheme();
+ if (newTheme != null) {
+ themeManager.registerTheme(newTheme);
+ selectedTheme = newTheme;
+ themeViewer.refresh();
+ themeViewer.setSelection(new StructuredSelection(newTheme));
+ }
+ }
+
+ private ITheme addTheme() {
+ FileDialog dialog = new FileDialog(getShell());
+ dialog.setText("Select textmate theme file");
+ dialog.setFilterExtensions(new String[]{"*.css"});
+ String res = dialog.open();
+ if (res == null) {
+ return null;
+ }
+ File file = new File(res);
+ String name = file.getName().substring(0, file.getName().length() - ".css".length());
+ return new Theme(name, file.getAbsolutePath(), name, false, false);
}
});
themeRemoveButton = new Button(buttons, SWT.PUSH);
themeRemoveButton.setText(TMUIMessages.Button_remove);
themeRemoveButton.setLayoutData(getButtonGridData(themeRemoveButton));
- themeRemoveButton.addListener(SWT.Selection, new Listener() {
- @Override
- public void handleEvent(Event e) {
- // remove();
- }
+ themeRemoveButton.addListener(SWT.Selection, e -> {
+ themeManager.unregisterTheme(selectedTheme);
+ themeViewer.refresh();
});
}
/**
* Create theme detail content.
- *
+ *
* @param parent
*/
private void createThemeDetailContent(Composite ancestor) {
@@ -282,7 +269,7 @@ private void createThemeDetailContent(Composite ancestor) {
/**
* Create theme associations content.
- *
+ *
* @param parent
*/
private void createPreviewContent(Composite ancestor) {
@@ -320,11 +307,6 @@ private static GridData getButtonGridData(Button button) {
return data;
}
- private void updateButtons() {
- themeNewButton.setEnabled(false);
- themeRemoveButton.setEnabled(false);
- }
-
@Override
public void setVisible(boolean visible) {
super.setVisible(visible);
@@ -365,13 +347,7 @@ private TMViewer doCreateViewer(Composite parent) {
grammarViewer = new ComboViewer(parent);
grammarViewer.setContentProvider(new GrammarDefinitionContentProvider());
grammarViewer.setLabelProvider(new GrammarDefinitionLabelProvider());
- grammarViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-
- @Override
- public void selectionChanged(SelectionChangedEvent e) {
- preview();
- }
- });
+ grammarViewer.addSelectionChangedListener(e -> preview());
grammarViewer.getControl().setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
TMViewer viewer = createViewer(parent);
@@ -402,4 +378,16 @@ protected TMViewer createViewer(Composite parent) {
return new TMViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
}
+ @Override
+ public boolean performOk() {
+ try {
+ themeManager.save();
+ grammarRegistryManager.save();
+ return true;
+ } catch (BackingStoreException e) {
+ TMUIPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, TMUIPlugin.PLUGIN_ID, e.getMessage(), e));
+ return false;
+ }
+ }
+
}
diff --git a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/themes/ThemeManager.java b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/themes/ThemeManager.java
index 26f291ae9..f6f2cc732 100644
--- a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/themes/ThemeManager.java
+++ b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/internal/themes/ThemeManager.java
@@ -11,6 +11,7 @@
*/
package org.eclipse.tm4e.ui.internal.themes;
+
import java.util.Arrays;
import java.util.stream.Collectors;
@@ -22,13 +23,16 @@
import org.eclipse.tm4e.ui.TMUIPlugin;
import org.eclipse.tm4e.ui.internal.preferences.PreferenceConstants;
import org.eclipse.tm4e.ui.internal.preferences.PreferenceHelper;
-import org.eclipse.tm4e.ui.themes.ITheme;
import org.eclipse.tm4e.ui.themes.IThemeAssociation;
import org.eclipse.tm4e.ui.themes.Theme;
import org.eclipse.tm4e.ui.themes.ThemeAssociation;
import org.eclipse.tm4e.ui.utils.PreferenceUtils;
import org.osgi.service.prefs.BackingStoreException;
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+
/**
* Theme manager singleton.
*/
@@ -79,11 +83,8 @@ private void loadThemesFromExtensionPoints() {
for (IConfigurationElement ce : cf) {
String name = ce.getName();
if (THEME_ELT.equals(name)) {
- // theme
- Theme theme = new Theme(ce);
- super.registerTheme(theme);
+ super.registerTheme(new Theme(ce));
} else if (THEME_ASSOCIATION_ELT.equals(name)) {
- // themeAssociation
super.registerThemeAssociation(new ThemeAssociation(ce));
}
}
@@ -98,9 +99,9 @@ private void loadThemesFromPreferences() {
IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(TMUIPlugin.PLUGIN_ID);
String json = prefs.get(PreferenceConstants.THEMES, null);
if (json != null) {
- ITheme[] themes = PreferenceHelper.loadThemes(json);
- for (ITheme theme : themes) {
- super.registerTheme(theme);
+ for (JsonObject element : new Gson().fromJson(json, JsonObject[].class)) {
+ String name = element.get("id").getAsString();
+ super.registerTheme(new Theme(name, element.get("path").getAsString(), name, element.get("dark").getAsBoolean(), false));
}
}
@@ -115,16 +116,23 @@ private void loadThemesFromPreferences() {
@Override
public void save() throws BackingStoreException {
+ IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(TMUIPlugin.PLUGIN_ID);
// Save Themes in the
// "${workspace_loc}/metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.tm4e.ui.prefs"
- String json = PreferenceHelper.toJsonThemes(
- Arrays.stream(getThemes()).filter(t -> t.getPluginId() == null).collect(Collectors.toList()));
- IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(TMUIPlugin.PLUGIN_ID);
- prefs.put(PreferenceConstants.THEMES, json);
+ prefs.put(PreferenceConstants.THEMES, Arrays.stream(getThemes()) //
+ .filter(t -> t.getPluginId() == null) //
+ .map(theme -> {
+ JsonObject json = new JsonObject();
+ json.addProperty("id", theme.getId());
+ json.addProperty("path", theme.getPath());
+ json.addProperty("dark", theme.isDark());
+ return json;
+ }).collect(JsonArray::new, (JsonArray array, JsonObject object) -> array.add(object), (r,r1) -> {})
+ .toString());
// Save Theme associations in the
// "${workspace_loc}/metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.tm4e.ui.prefs"
- json = PreferenceHelper.toJsonThemeAssociations(Arrays.stream(getAllThemeAssociations())
+ String json = PreferenceHelper.toJsonThemeAssociations(Arrays.stream(getAllThemeAssociations())
.filter(t -> t.getPluginId() == null).collect(Collectors.toList()));
prefs.put(PreferenceConstants.THEME_ASSOCIATIONS, json);
diff --git a/pom.xml b/pom.xml
index 998646f95..3dcc2df86 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,11 +7,11 @@
pom
- 3.3.9
+ 3.6.2
UTF-8
- 1.5.1
+ 2.0.0
${tycho-version}
../target/jacoco.exec
scm:git:https://github.com/eclipse/tm4e.git
@@ -77,7 +77,7 @@
org.apache.maven.plugins
maven-surefire-plugin
- 2.22.0
+ 2.22.2
test
@@ -90,7 +90,7 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.7.0
+ 3.8.1
1.8
1.8
@@ -149,7 +149,7 @@
org.eclipse.cbi.maven.plugins
eclipse-jarsigner-plugin
- 1.1.5
+ 1.1.7
sign
@@ -251,7 +251,7 @@
org.apache.maven.plugins
maven-javadoc-plugin
- 3.0.0
+ 3.2.0
true
@@ -259,7 +259,7 @@
org.jacoco
jacoco-maven-plugin
- 0.8.2
+ 0.8.5
prepare-agent
diff --git a/target-platform/tm4e-target.target b/target-platform/tm4e-target.target
index b59d8b784..680a0e256 100644
--- a/target-platform/tm4e-target.target
+++ b/target-platform/tm4e-target.target
@@ -10,15 +10,15 @@
-
+
-
-
-
-
-
-
+
+
+
+
+
+