Getting Started
Requirements
Before including sora-editor library into your project, please ensure your environment and build configuration satisfy the requirements below:
- Running Gradle on JDK 17 or above
- The minimum Android SDK version of your module is at least Android L (API 21)
- If you are to use Language Server Protocol, the requirement will be at least Android O (API 26)
- Project Java source compatibility and target compatibility is
JavaVersion.VERSION_17
Set Java Source and Target Compatibilities
android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}
// If Kotlin used in your app
// kotlin {
// jvmToolchain(17)
// }
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
}
For Non-Gradle Build Systems
The editor uses resources and is distributed in AAR files. Your build system must support processing AAR files.
If you are not using Gradle as your build system, we won't provide information related to your build issues.
Add Dependencies
Add sora-editor library to your app's dependencies:
dependencies {
implementation(platform("io.github.Rosemoe.sora-editor:bom:<versionName>"))
implementation("io.github.Rosemoe.sora-editor:<moduleName>")
}
dependencies {
implementation(platform("io.github.Rosemoe.sora-editor:bom:<versionName>"))
implementation 'io.github.Rosemoe.sora-editor:<moduleName>'
}
Replace the placeholder <versionName>
and <moduleName>
with correct version name and module name. You may add multiple modules to your project.
Here's an example for those who want to use TextMate grammars for syntax-highlighting in editor:
dependencies {
implementation(platform("io.github.Rosemoe.sora-editor:bom:0.23.2"))
implementation("io.github.Rosemoe.sora-editor:editor")
implementation("io.github.Rosemoe.sora-editor:language-textmate")
}
dependencies {
implementation(platform("io.github.Rosemoe.sora-editor:bom:0.23.2"))
implementation 'io.github.Rosemoe.sora-editor:editor'
implementation 'io.github.Rosemoe.sora-editor:language-textmate'
}
dependencies {
val editorVersion = "0.23.2"
implementation("io.github.Rosemoe.sora-editor:editor:$editorVersion")
implementation("io.github.Rosemoe.sora-editor:language-textmate:$editorVersion")
}
dependencies {
def editorVersion = '0.23.2'
implementation 'io.github.Rosemoe.sora-editor:editor:$editorVersion'
implementation 'io.github.Rosemoe.sora-editor:language-textmate:$editorVersion'
}
NOTE
You can find the newest version name from the badge above, or turn to our GitHub Releases page for full version list.
Currently, available modules names are: editor
, editor-lsp
, language-java
, language-textmate
and language-treesitter
. Check the table below to get more information about the modules.
🛠️Available modules
Module | Summary |
---|---|
editor | Widget library containing all basic things of the framework |
editor-lsp | A convenient library for creating languages by Language Server Protocol (aka LSP) |
language-java | A simple implementation for Java lexer-based highlighting and identifier auto-completion |
language-textmate | An advanced highlighter for the editor. It can be used to load TextMate language bundles and themes. The internal implementation of TextMate is from tm4e |
language-treesitter | Offer tree-sitter support for editor. This can be used to parse the code to an AST fast and incrementally, which is helpful for accurate highlighting and providing completions. Note that this module only provides incremental parsing and highlighting. Thanks to Java bindings android-tree-sitter |
🚧Snapshot Builds
Generally, it is recommended to use released versions. But sometimes you may still want to use nightly builds for latest bug fixes and enhancements.
How to Use Snapshot Builds
Snapshot versions are automatically published on repository push. You may combine current released version name and short commit hash to make a snapshot version name.
For example, if the latest released version name is '0.21.1' and short commit hash is '97c4963', you may use version name '0.21.1-97c4963-SNAPSHOT' to import the snapshot version to your project.
Note that adding extra maven repository is required:
repositories {
// ...
maven("https://s01.oss.sonatype.org/content/repositories/snapshots")
}
Configure Desugaring for TextMate
If you use language-textmate
module in your project, and want to run the application on devices under Android 13 (API 33), you must enable Core Library Desugaring to avoid compatibility issues. Otherwise, you can go on to next section.
To enable the desugaring, follow the instructions below to setup your application module. Note that the following instructions are for AGP 7.4.0 or above.
- Add Desugaring Dependency
dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4")
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
}
- Add Compile Option
android {
compileOptions {
isCoreLibraryDesugaringEnabled = true
}
}
android {
compileOptions {
coreLibraryDesugaringEnabled true
}
}
BE CAUTIOUS
When desugaring is enabled, you should build the production APK in Android Studio by:
- Build from menu
Build
|Build Bundle(s) / APK(s)
|Build APK(s)
- Or, run Gradle task
assemble<Variant>
. For example, executeassembleDebug
for yourdebug
variant.
Android Studio tries to speed up the desugaring process when you run the application on a specific device from clicking the Run
button (or shortcuts Shift+F10
). It will generate a device API specific APK, and as a result the APK may not work properly on other devices.
Alternatively, you can disable this feature in Android Studio by disabling Experimental > Optimize build for target device API level only
in preferences to avoid this issue.
Create the Widget
Please ensure you have included editor
module in your project, and then sync your project with Gradle files successfully.
The main widget class is io.github.rosemoe.sora.widget.CodeEditor
. You can create the code editor either by XML or Java/Kotlin code(recommended). Only limited editor attributes can be set in XML.
Use in XML
Declare editor in your layout XML files:
<io.github.rosemoe.sora.widget.CodeEditor
android:id="@+id/editor"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:text="Hello, world!"
app:textSize="18sp" />
It's not necessary to set text
or textSize
in XML declaration.
Refer to XML Attributes for more information about its usage in XML.
NOTE
It is not recommended to use wrap_content
for editor width or height. In that case, when the text is editted, the editor has to request re-layout which probably causes lags.
Use in Java/Kotlin code
Just create a editor and add it to any view group. Supposing we are in any Activity
context, and vg
is a ViewGroup
instance.
val editor = CodeEditor(this)
editor.setText("Hello, world!") // Set text
editor.typefaceText = Typeface.MONOSPACE // Use Monospace Typeface
editor.nonPrintablePaintingFlags =
CodeEditor.FLAG_DRAW_WHITESPACE_LEADING or CodeEditor.FLAG_DRAW_LINE_SEPARATOR or CodeEditor.FLAG_DRAW_WHITESPACE_IN_SELECTION // Show Non-Printable Characters
vg.add(editor, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
var editor = new CodeEditor(this);
editor.setText("Hello, world!"); // Set Text
editor.setTypefaceText(Typeface.MONOSPACE); // Use Monospace Typeface
editor.setNonPrintablePaintingFlags(
CodeEditor.FLAG_DRAW_WHITESPACE_LEADING | CodeEditor.FLAG_DRAW_LINE_SEPARATOR | CodeEditor.FLAG_DRAW_WHITESPACE_IN_SELECTION); // Show Non-Printable Characters
vg.add(editor, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
Please view methods of CodeEditor
and fields of DirectAccessProps
for more attributes you can configure.
BE CAUTIOUS
Not all fields of DirectAccessProps
can take effect without invalidation. Call invalidate()
on editor after changing those fields marked with @InvalidateRequired
.
Methods and fields that marked with @UnsupportedUserUsage
should not be used. They are visible for internal access.
Release the Widget
When a CodeEditor
instance is no longer used, its release()
method must be invoked to release resources and any background thread serving for the editor. After releasing the editor, you should not use the editor, to avoid errors.
override fun onDestroy() {
super.onDestroy()
editor?.release()
}
@Override
protected void onDestroy() {
super.onDestroy();
if (editor != null) {
editor.release();
}
}
Continue
Go to Language and Color Scheme to equip the editor with programming language support and your custom color scheme.