Efxclipse/SmartCode
e(fx)clipse provides a SmartCode-Editing Framework who can be embedded in fairly any application (not only OSGi)
Contents
Integration into OSGi
Setup
Before adding the source you need to configure your application to support
Basic Control with Syntax Highlighting
Basics
To make it easier to define syntax highlighting for any language the smart-code framework uses unlike the Eclipse IDE a declarative language named ldef.
The first step when integrating a syntax highlighting editor into your application is to create a file ending with .ldef (eg java.ldef, ...).
package my.plugin js { partitioning { partition __dftl_partition_content_type partition __js_single_line_comment partition __js_multi_line_comment partition __js_string partition __js_regex rule { single_line __js_single_line_comment "//" => '' multi_line __js_multi_line_comment "/*" => "*/" single_line __js_string "'" => "'" escaped by "\\" single_line __js_string '"' => '"' escaped by "\\" single_line __js_regex '/' => '/' escaped by "\\" } } lexical_highlighting { rule __dftl_partition_content_type whitespace javawhitespace { default js_default js_operator { character [ ';', '.', '=', '/', '\\', '+', '-', '*', '<', '>', ':', '?', '!', ',', '|', '&', '^', '%', '~' ] } js_bracket { character [ '(', ')', '{', '}', '[', ']' ] } js_keyword { keywords [ "break", "case", "catch", "continue", "debugger","default", "delete", "do", "else", "finally", "for", "function", "if", "in", "instanceof", "new", "return", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with" ] } js_constant { keywords [ "true", "false", "undefined" ] } js_number { pattern "\\d" containing "[\\d|\\.]" } } rule __js_single_line_comment { default js_doc_default } rule __js_multi_line_comment { default js_doc_default } rule __js_string { default js_string } rule __js_regex { default js_string } token_def { js_default "-source-editor-code"; js_operator "-source-editor-operator"; js_bracket "-source-editor-bracket"; js_keyword "-source-editor-keyword" bold; js_doc_default "-source-editor-doc"; js_string "-source-editor-string"; js_constant "-source-editor-keyword" bold; js_number "-source-editor-number"; } } }
As the smart code editor framework is built on top of the EclipseText-Framework you notice that the DSL aligns heavily to the concepts you find there:
- Documents are first split in partitions (eg source-code, documentation, strings, ...)
- Single Partitions are then split in tokens like constants, reserved words, ...
- Tokens are then associated with styling information (color, font-weight,...)
Once you created an ldef-File for your favorite language the Eclipse-Tooling will generate a total of 3 files in the src-gen folder:
-
$language$.json
: Configuration data loaded at runtime and used to configure Eclipse Text -
$language$.css
: Styleing information when using JavaFX as the renderer -
$language$-swt-style.json
: Styleing information when using SWT as the renderer (we are not looking into this feature in this document)
Dependencies
To integrate a smart editor into your application you need to add dependencies to the following bundles your MANIFEST.MF:
-
org.eclipse.fx.code.editor
-
org.eclipse.fx.code.editor.configuration
-
org.eclipse.fx.code.editor.configuration.text
-
org.eclipse.fx.ui.services
Or if you prefer the following packages:
-
org.eclipse.fx.code.editor
-
org.eclipse.fx.code.editor.configuration
-
org.eclipse.fx.code.editor.configuration.text
-
org.eclipse.fx.code.editor.services
-
org.eclipse.fx.ui.services.theme
Editor Registration
From the DSL we generated various artifacts are generated and we need to register them in the framework:
-
$language$.json
file is registered through aorg.eclipse.fx.code.editor.configuration.text.ConfigurationModelProvider
OSGi-Service-Component -
$language$.css
file is registered through aorg.eclipse.fx.ui.services.theme.Stylesheet
OSGi-Service-Component
Samples for JavaScript could look like this:
ConfigurationModelProvider-Component
@Component public class JavaScriptConfigurationProvider implements ConfigurationModelProvider { @Override public boolean applies(Input<?> input) { return ((URIProvider)input).getURI().endsWith(".js"); } @Override public LanguageDef getModel(Input<?> input) { try(InputStream in = getClass().getResourceAsStream("js.json"); Reader r = new InputStreamReader(in)) { return EditorGModel.create().createObject(r); } catch (IOException e) { throw new RuntimeException(e); } } }
Stylesheet-Component
@Component public class JavaScriptStylesheet implements Stylesheet { @Override public boolean appliesToTheme(Theme t) { return true; } @Override public URL getURL(Theme t) { try { return new URL("platform:/plugin/my.plugin/my/plugin/js.json"); } catch (MalformedURLException e) { throw new RuntimeException(e); } } }