Guide: Syntax Highlighting
This guide explains how to add support for syntax highlighting for a new language to Xed-Editor.
Xed-Editor uses TextMate grammars for syntax highlighting. To add support for a new language, you need to:
- Register a
FileResolverfor your grammar files. - Load your grammar.
- Register a
FileType.
Step 1: Register a FileResolver
Grammar files should usually be bundled within your extension's assets. Before they can be loaded, Xed-Editor needs to know where to find them.
override fun onLoad() {
val fileResolver = AssetsFileResolver(context.assets)
FileProviderRegistry.getInstance().addFileProvider(fileResolver)
// ...
}Step 2: Load the Grammar
After registering the file provider, load your grammar definition:
override fun onLoad() {
// ...
GrammarRegistry.getInstance().loadGrammars("languages.json")
}A grammar definition file is a JSON file with the following structure:
{
"languages": [
{
"grammar": "Dart.tmLanguage.json", // (1)
"name": "Dart",
"scopeName": "source.dart", // (2)
"languageConfiguration": "Dart.config.json" // (3)
}
]
}// See example file at:
// https://github.com/microsoft/vscode/blob/4f2ff19ecacffa0aa4874db4d63ed4e899d98431/extensions/dart/language-configuration.json// See example file at:
// https://github.com/microsoft/vscode/blob/4f2ff19ecacffa0aa4874db4d63ed4e899d98431/extensions/dart/syntaxes/dart.tmLanguage.json- (1) The
grammarproperty defines the path to the TextMate rule file (akasyntax) used for later tokenizing the source code, so that the editor can apply colors based on the chosen theme. Xed-Editor supports*.tmLanguagePLIST files or*.tmLanguage.jsonJSON files. - (2) The grammar definition's
scopeNameshould match thescopeNameof yourtmLanguagefile. - (3) The
languageConfigurationproperty (optional) references an additional JSON config file that defines indentation rules, comment toggling and bracket matching.
If you don't want to write these TextMate files yourself, you can find already written grammars in:
Step 3: Register a FileType
A FileType tells Xed-Editor how to recognize a language and which metadata belongs to it. Read more about it in the File Types guide.
class MyLanguage(resources: Resources) : FileType {
override val extensions = listOf("ml", "mylang")
override val textmateScope = "source.mylang"
override val icon = Icon.ExternalResourceIcon(R.drawable.ic_language, resources)
override val name = "mylang"
override val title = "My language"
}Then register it during initialization:
override fun onLoad() {
FileTypeManager.register(MyLanguage)
}Complete Example
class MyLanguage(resources: Resources) : FileType {
override val extensions = listOf("ml", "mylang")
override val textmateScope = "source.mylang"
override val icon = Icon.ExternalResourceIcon(R.drawable.ic_language, resources)
override val name = "mylang"
override val title = "My Language"
}
class Main(context: ExtensionContext) : ExtensionAPI(context) {
private var fileResolver: AssetsFileResolver? = null
private var myLanguage: MyLanguage? = null
override fun onLoad() {
// Register the asset provider
fileResolver = AssetsFileResolver(context.assets)
FileProviderRegistry.getInstance().addFileProvider(fileResolver)
// Load the grammar
GrammarRegistry.getInstance().loadGrammars("languages.json")
// Register the language
myLanguage = MyLanguage(context.resources)
FileTypeManager.register(myLanguage)
}
override fun onDispose() {
fileResolver?.let {
FileProviderRegistry.getInstance().removeFileProvider(it)
}
myLanguage?.let {
FileTypeManager.unregister(it)
}
}
}