From 3d5fd892fee27fdacc941599cbea7d1aa5c3b923 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Sun, 31 Mar 2024 03:45:25 +0800 Subject: [PATCH 01/40] feat(language-monarch): add monarch module --- gradle/libs.versions.toml | 3 + language-monarch/.gitignore | 1 + language-monarch/README.md | 15 +++++ language-monarch/build.gradle.kts | 67 +++++++++++++++++++ language-monarch/consumer-rules.pro | 0 language-monarch/gradle.properties | 28 ++++++++ language-monarch/proguard-rules.pro | 21 ++++++ language-monarch/src/main/AndroidManifest.xml | 27 ++++++++ settings.gradle.kts | 1 + 9 files changed, 163 insertions(+) create mode 100644 language-monarch/.gitignore create mode 100644 language-monarch/README.md create mode 100644 language-monarch/build.gradle.kts create mode 100644 language-monarch/consumer-rules.pro create mode 100644 language-monarch/gradle.properties create mode 100644 language-monarch/proguard-rules.pro create mode 100644 language-monarch/src/main/AndroidManifest.xml diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 194de485c..8ccb07cc9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,6 +29,9 @@ jcodings = { module = "org.jruby.jcodings:jcodings", version = "1.0.58" } joni = { module = "org.jruby.joni:joni", version = "2.2.1" } snakeyaml-engine = { module = "org.snakeyaml:snakeyaml-engine", version = "2.7" } jdt-annotation = { module = "org.eclipse.jdt:org.eclipse.jdt.annotation", version = "2.3.0" } +monarch-code = { module = "io.github.dingyi222666.monarch:monarch", version = "1.0.0" } +monarch-json = { module = "io.github.dingyi222666.monarch:monarch-json-loader", version = "1.0.0" } +regex-onig = { module = "io.github.dingyi222666.regex-lib:regex-lib-oniguruma", version = "1.0.0" } tests-google-truth = { module = "com.google.truth:truth", version = "1.4.2" } tests-robolectric = { module = "org.robolectric:robolectric", version = "4.11.1" } diff --git a/language-monarch/.gitignore b/language-monarch/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/language-monarch/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/language-monarch/README.md b/language-monarch/README.md new file mode 100644 index 000000000..c76edbe4e --- /dev/null +++ b/language-monarch/README.md @@ -0,0 +1,15 @@ +## About + +**Work In Progress** `language-textmate` module is a module that performs syntax highlighting and other functions dynamically. To use it, you need to introduce several other `textmate-*` modules.Our goal is to achieve the effect of VSCode. However, for many reasons, this may be difficult to achieve in the short term. + +## Features(already available) + +1. Highlighting of files based on syntax rules +2. Load color theme from file +3. Code block line based on indent and rule + +## How to get syntax and theme files +If many people use this module, they may collect the available configuration files into a repository later. +- You can obtain relevant documents from [Textmate](https://github.com/textmate). +- Eclipse also uses Textmate, and you can also get files from its related repository。 +- Textmate is also used in [vscode](https://github.com/microsoft/vscode/tree/main/extensions), but its version is ahead of the version used in this module. You can get the configuration file from its source code, but not all of them can be used normally \ No newline at end of file diff --git a/language-monarch/build.gradle.kts b/language-monarch/build.gradle.kts new file mode 100644 index 000000000..f69a36285 --- /dev/null +++ b/language-monarch/build.gradle.kts @@ -0,0 +1,67 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +plugins { + id("com.android.library") + id("com.vanniktech.maven.publish.base") + kotlin("android") +} + +group = "io.github.Rosemoe.sora-editor" +version = Versions.versionName + +android { + namespace = "io.github.rosemoe.sora.langs.monarch" + + defaultConfig { + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildFeatures { + buildConfig = true + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } +} + +dependencies { + + compileOnly(projects.editor) + implementation(libs.monarch.code) + implementation(libs.monarch.json) + implementation(libs.regex.onig) + + implementation(libs.snakeyaml.engine) + implementation(libs.jdt.annotation) + + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.test.junit) + androidTestImplementation(libs.androidx.test.espresso) +} diff --git a/language-monarch/consumer-rules.pro b/language-monarch/consumer-rules.pro new file mode 100644 index 000000000..e69de29bb diff --git a/language-monarch/gradle.properties b/language-monarch/gradle.properties new file mode 100644 index 000000000..f5755b62e --- /dev/null +++ b/language-monarch/gradle.properties @@ -0,0 +1,28 @@ +################################################################################ +# sora-editor - the awesome code editor for Android +# https://github.com/Rosemoe/sora-editor +# Copyright (C) 2020-2024 Rosemoe +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 +# USA +# +# Please contact Rosemoe by email 2073412493@qq.com if you need +# additional information or have any questions +################################################################################ + +POM_ARTIFACT_ID=language-textmate +POM_NAME=language-textmate +POM_DESCRIPTION=An awesome code editor library on Android +POM_PACKAGING=aar diff --git a/language-monarch/proguard-rules.pro b/language-monarch/proguard-rules.pro new file mode 100644 index 000000000..481bb4348 --- /dev/null +++ b/language-monarch/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/language-monarch/src/main/AndroidManifest.xml b/language-monarch/src/main/AndroidManifest.xml new file mode 100644 index 000000000..b73f5efae --- /dev/null +++ b/language-monarch/src/main/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index b8e3d4f51..71c8fd713 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -49,6 +49,7 @@ include( ":bom", ":editor", ":app", + ":language-monarch", ":language-java", ":language-textmate", ":editor-lsp", From 413f14a2070fa993ec0bf6fca9bad93bc4f3e737 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Sun, 31 Mar 2024 04:29:58 +0800 Subject: [PATCH 02/40] feat(language-monarch): migrate the vscode's token theme code --- .../sora/langs/monarch/theme/ColorMap.kt | 50 +++++++++ .../monarch/theme/ExternalThemeTrieElement.kt | 32 ++++++ .../langs/monarch/theme/ThemeTrieElement.kt | 67 +++++++++++ .../monarch/theme/ThemeTrieElementRule.kt | 56 +++++++++ .../sora/langs/monarch/theme/TokenTheme.kt | 83 ++++++++++++++ .../rosemoe/sora/langs/monarch/theme/parse.kt | 106 ++++++++++++++++++ .../rosemoe/sora/langs/monarch/theme/types.kt | 43 +++++++ 7 files changed, 437 insertions(+) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ExternalThemeTrieElement.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElementRule.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/types.kt diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt new file mode 100644 index 000000000..803642102 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt @@ -0,0 +1,50 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.theme + +class ColorMap { + + private var lastColorId: Int = 0 + private val id2color = mutableListOf() + private val color2id = mutableMapOf() + + fun getId(color: String): Int { + + return color2id.getOrPut(color) { + lastColorId++ + id2color.add(lastColorId, color) + lastColorId + } + } + + fun getColor(id: Int): String { + return id2color[id] + } + + fun getColorMap(): List { + return id2color.toList() + } + +} diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ExternalThemeTrieElement.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ExternalThemeTrieElement.kt new file mode 100644 index 000000000..99cf86608 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ExternalThemeTrieElement.kt @@ -0,0 +1,32 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.theme + +class ExternalThemeTrieElement( + val mainRule: ThemeTrieElementRule, + children: Map = mapOf() +) { + val children: MutableMap = children.toMutableMap() +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt new file mode 100644 index 000000000..da5ad38a9 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt @@ -0,0 +1,67 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.theme + +class ThemeTrieElement(private val mainRule: ThemeTrieElementRule) { + private val children: MutableMap = mutableMapOf() + + fun toExternalThemeTrieElement(): ExternalThemeTrieElement { + val children = children.mapValues { it.value.toExternalThemeTrieElement() }.toMutableMap() + return ExternalThemeTrieElement(mainRule, children) + } + + fun match(token: String): ThemeTrieElementRule { + if (token.isEmpty()) { + return mainRule + } + + val dotIndex = token.indexOf('.') + val (head, tail) = if (dotIndex == -1) { + token to "" + } else { + token.substring(0, dotIndex) to token.substring(dotIndex + 1) + } + + val child = children[head] + return child?.match(tail) ?: mainRule + } + + fun insert(token: String, fontStyle: Int, foreground: Int, background: Int) { + if (token.isEmpty()) { + mainRule.acceptOverwrite(fontStyle, foreground, background) + return + } + + val dotIndex = token.indexOf('.') + val (head, tail) = if (dotIndex == -1) { + token to "" + } else { + token.substring(0, dotIndex) to token.substring(dotIndex + 1) + } + + val child = children.getOrPut(head) { ThemeTrieElement(mainRule.clone()) } + child.insert(tail, fontStyle, foreground, background) + } +} diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElementRule.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElementRule.kt new file mode 100644 index 000000000..f6b84f2bd --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElementRule.kt @@ -0,0 +1,56 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.theme + +import io.github.dingyi222666.monarch.types.ColorId +import io.github.dingyi222666.monarch.types.FontStyle +import io.github.dingyi222666.monarch.types.MetadataConsts + +class ThemeTrieElementRule( + private var fontStyle: Int, + private var foreground: Int, + private var background: Int +) { + var metadata: Int = (fontStyle shl MetadataConsts.FONT_STYLE_OFFSET) or + (foreground shl MetadataConsts.FOREGROUND_OFFSET) or + (background shl MetadataConsts.BACKGROUND_OFFSET) + + fun clone(): ThemeTrieElementRule = ThemeTrieElementRule(fontStyle, foreground, background) + + fun acceptOverwrite(fontStyle: Int, foreground: Int, background: Int) { + if (fontStyle != FontStyle.NotSet) { + this.fontStyle = fontStyle + } + if (foreground != ColorId.None) { + this.foreground = foreground + } + if (background != ColorId.None) { + this.background = background + } + metadata = (this.fontStyle shl MetadataConsts.FONT_STYLE_OFFSET) or + (this.foreground shl MetadataConsts.FOREGROUND_OFFSET) or + (this.background shl MetadataConsts.BACKGROUND_OFFSET) + } +} diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt new file mode 100644 index 000000000..e078f6cf9 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt @@ -0,0 +1,83 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.theme + +import io.github.dingyi222666.monarch.types.MetadataConsts +import io.github.dingyi222666.monarch.types.StandardTokenType + +class TokenTheme internal constructor( + private val colorMap: ColorMap, + private val root: ThemeTrieElement +) { + private val cache: MutableMap = mutableMapOf() + + fun getColorMap(): List { + return colorMap.getColorMap() + } + + fun getThemeTrieElement(): ExternalThemeTrieElement { + return root.toExternalThemeTrieElement() + } + + private fun _match(token: String): ThemeTrieElementRule { + return root.match(token) + } + + fun match(token: String): Int { + val result = cache.getOrPut(token) { + val rule = _match(token) + val standardToken = token.toStandardTokenType() + (rule.metadata or (standardToken shl MetadataConsts.TOKEN_TYPE_OFFSET)).toInt() + } + return result + } + + fun match(languageId: Int, token: String): Int { + return (match(token) or (languageId shl MetadataConsts.LANGUAGEID_OFFSET)).toInt() + } + + companion object { + fun createFromRawTokenTheme(source: List, customTokenColors: Array): TokenTheme { + return createFromParsedTokenTheme(source.parseTokenTheme(), customTokenColors) + } + + fun createFromParsedTokenTheme(source: List, customTokenColors: Array): TokenTheme { + return source.resolveParsedTokenThemeRules( customTokenColors) + } + } +} + +val STANDARD_TOKEN_TYPE_REGEXP = Regex("\\b(comment|string|regex|regexp)\\b") + +fun String.toStandardTokenType(): Int { + val match = STANDARD_TOKEN_TYPE_REGEXP.find(this) + val token = match?.groups?.get(1)?.value + return when (token) { + "comment" -> StandardTokenType.Comment + "string" -> StandardTokenType.String + "regex", "regexp" -> StandardTokenType.RegEx + else -> StandardTokenType.Other + } +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt new file mode 100644 index 000000000..dc05ce77a --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt @@ -0,0 +1,106 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.theme + +import io.github.dingyi222666.monarch.types.FontStyle + +fun List.parseTokenTheme(): List { + val result = mutableListOf() + + forEachIndexed { index, it -> + + var fontStyle = FontStyle.NotSet + + val segments = it.fontStyle?.split(' ') + + segments?.forEach { segment -> + fontStyle = fontStyle or when (segment) { + "italic" -> FontStyle.Italic; + "bold" -> FontStyle.Bold; + "underline" -> FontStyle.Underline + "strikethrough" -> FontStyle.Strikethrough; + else -> 0 + } + } + + result.add( + ParsedTokenThemeRule( + token = it.token, + index = index, + background = it.background, + foreground = it.foreground, + fontStyle = fontStyle + ) + ) + } + + return result +} + +fun List.resolveParsedTokenThemeRules(customTokenColors: Array): TokenTheme { + // Sort rules lexicographically, and then by index if necessary + // this.sortWith(compareBy({ it.token }, { it.index })) + val parsedThemeRules = sortedWith(compareBy({ it.token }, { it.index })).toMutableList() + + // Determine defaults + var defaultFontStyle = FontStyle.None + var defaultForeground = "#000000" + var defaultBackground = "#ffffff" + while (parsedThemeRules.isNotEmpty() && parsedThemeRules[0].token == "") { + val incomingDefaults = parsedThemeRules[0] + parsedThemeRules.removeFirst() + if (incomingDefaults.fontStyle != FontStyle.NotSet) { + defaultFontStyle = incomingDefaults.fontStyle + } + if (incomingDefaults.foreground != null) { + defaultForeground = incomingDefaults.foreground + } + if (incomingDefaults.background != null) { + defaultBackground = incomingDefaults.background + } + } + val colorMap = ColorMap() + + // Start with token colors from custom token themes + for (color in customTokenColors) { + colorMap.getId(color) + } + + val foregroundColorId = colorMap.getId(defaultForeground) + val backgroundColorId = colorMap.getId(defaultBackground) + + val defaults = ThemeTrieElementRule(defaultFontStyle, foregroundColorId, backgroundColorId) + val root = ThemeTrieElement(defaults) + for (rule in parsedThemeRules) { + root.insert( + rule.token, rule.fontStyle, colorMap.getId( + requireNotNull(rule.foreground) + ), + colorMap.getId(requireNotNull(rule.background)) + ) + } + + return TokenTheme(colorMap, root) +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/types.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/types.kt new file mode 100644 index 000000000..5d7540adb --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/types.kt @@ -0,0 +1,43 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.theme + +import io.github.dingyi222666.monarch.types.FontStyle + + +interface ITokenThemeRule { + var token: String + var foreground: String? + var background: String? + var fontStyle: String? +} + +class ParsedTokenThemeRule( + val token: String, + val index: Int, + val fontStyle: Int, + val foreground: String?, + val background: String? +) \ No newline at end of file From d84d046ce94620913370dafc866aa66604aab1ce Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Thu, 4 Apr 2024 02:06:09 +0800 Subject: [PATCH 03/40] feat(language-monarch): support load vscode theme --- gradle/libs.versions.toml | 7 +- language-monarch/build.gradle.kts | 2 +- .../sora/langs/monarch/theme/ColorMap.kt | 14 +- .../langs/monarch/theme/ThemeDefaultColors.kt | 54 + .../langs/monarch/theme/ThemeTrieElement.kt | 6 + .../monarch/theme/ThemeTrieElementRule.kt | 6 + .../sora/langs/monarch/theme/TokenTheme.kt | 39 +- .../sora/langs/monarch/theme/loader.kt | 170 ++ .../rosemoe/sora/langs/monarch/theme/parse.kt | 12 +- .../src/test/kotlin/ThemeParse.kt | 39 + .../test/resources/sakura-color-theme.json | 2105 +++++++++++++++++ 11 files changed, 2438 insertions(+), 16 deletions(-) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt create mode 100644 language-monarch/src/test/kotlin/ThemeParse.kt create mode 100644 language-monarch/src/test/resources/sakura-color-theme.json diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8ccb07cc9..2002e7bc5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,9 +16,9 @@ androidx-test-espresso = { module = "androidx.test.espresso:espresso-core", vers desugar = { module = "com.android.tools:desugar_jdk_libs", version = "2.0.4" } kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version = "1.8.0" } kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } -lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version = "2.7.0"} -material = { module = "com.google.android.material:material", version = "1.11.0"} -gms-instantapps = { module = "com.google.android.gms:play-services-instantapps", version = "18.0.1"} +lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version = "2.7.0" } +material = { module = "com.google.android.material:material", version = "1.11.0" } +gms-instantapps = { module = "com.google.android.gms:play-services-instantapps", version = "18.0.1" } tree-sitter-java = { module = "com.itsaky.androidide.treesitter:tree-sitter-java", version.ref = "tsBinding" } tree-sitter = { module = "com.itsaky.androidide.treesitter:android-tree-sitter", version.ref = "tsBinding" } lsp4j = { module = "org.eclipse.lsp4j:org.eclipse.lsp4j", version.ref = "lsp4j" } @@ -28,6 +28,7 @@ gson = { module = "com.google.code.gson:gson", version = "2.10.1" } jcodings = { module = "org.jruby.jcodings:jcodings", version = "1.0.58" } joni = { module = "org.jruby.joni:joni", version = "2.2.1" } snakeyaml-engine = { module = "org.snakeyaml:snakeyaml-engine", version = "2.7" } +moshi = { module = "com.squareup.moshi:moshi", version = "1.15.0" } jdt-annotation = { module = "org.eclipse.jdt:org.eclipse.jdt.annotation", version = "2.3.0" } monarch-code = { module = "io.github.dingyi222666.monarch:monarch", version = "1.0.0" } monarch-json = { module = "io.github.dingyi222666.monarch:monarch-json-loader", version = "1.0.0" } diff --git a/language-monarch/build.gradle.kts b/language-monarch/build.gradle.kts index f69a36285..4eb9b3e0c 100644 --- a/language-monarch/build.gradle.kts +++ b/language-monarch/build.gradle.kts @@ -59,7 +59,7 @@ dependencies { implementation(libs.regex.onig) implementation(libs.snakeyaml.engine) - implementation(libs.jdt.annotation) + implementation(libs.moshi) testImplementation(libs.junit) androidTestImplementation(libs.androidx.test.junit) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt index 803642102..92369fe13 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt @@ -26,12 +26,15 @@ package io.github.rosemoe.sora.langs.monarch.theme class ColorMap { - private var lastColorId: Int = 0 + private var lastColorId: Int = -1 private val id2color = mutableListOf() - private val color2id = mutableMapOf() + private val color2id = mutableMapOf() - fun getId(color: String): Int { + fun getId(color: String?): Int { + if (color == null) { + return 0 + } return color2id.getOrPut(color) { lastColorId++ id2color.add(lastColorId, color) @@ -47,4 +50,9 @@ class ColorMap { return id2color.toList() } + override fun toString(): String { + return "ColorMap(lastColorId=$lastColorId, id2color=$id2color, color2id=$color2id)" + } + + } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt new file mode 100644 index 000000000..e17361b1b --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt @@ -0,0 +1,54 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.theme + +class ThemeDefaultColors(defaultColors: Map) { + private val colors = mutableMapOf() + + init { + colors.putAll(defaultColors) + } + + constructor() : this(emptyMap()) + + + fun putColors(map: Map) { + colors.putAll(map) + } + + fun getColor(key: String): String? { + return colors[key] + } + + fun getColors(): Map { + return colors + } + + override fun toString(): String { + return "ThemeDefaultColors(colors=$colors)" + } + + +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt index da5ad38a9..7eedc9c20 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt @@ -64,4 +64,10 @@ class ThemeTrieElement(private val mainRule: ThemeTrieElementRule) { val child = children.getOrPut(head) { ThemeTrieElement(mainRule.clone()) } child.insert(tail, fontStyle, foreground, background) } + + override fun toString(): String { + return "ThemeTrieElement(mainRule=$mainRule, children=$children)" + } + + } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElementRule.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElementRule.kt index f6b84f2bd..fc7091633 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElementRule.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElementRule.kt @@ -53,4 +53,10 @@ class ThemeTrieElementRule( (this.foreground shl MetadataConsts.FOREGROUND_OFFSET) or (this.background shl MetadataConsts.BACKGROUND_OFFSET) } + + override fun toString(): String { + return "ThemeTrieElementRule(fontStyle=$fontStyle, foreground=$foreground, background=$background, metadata=$metadata)" + } + + } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt index e078f6cf9..26b09229f 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt @@ -29,7 +29,9 @@ import io.github.dingyi222666.monarch.types.StandardTokenType class TokenTheme internal constructor( private val colorMap: ColorMap, - private val root: ThemeTrieElement + private val root: ThemeTrieElement, + private val themeDefaultColors: ThemeDefaultColors = ThemeDefaultColors(), + val themeType: String = "light" ) { private val cache: MutableMap = mutableMapOf() @@ -58,14 +60,41 @@ class TokenTheme internal constructor( return (match(token) or (languageId shl MetadataConsts.LANGUAGEID_OFFSET)).toInt() } + fun getDefaults(): ThemeDefaultColors = themeDefaultColors + + override fun toString(): String { + return "TokenTheme(colorMap=$colorMap, root=$root, themeDefaultColors=$themeDefaultColors, themeType='$themeType', cache=$cache)" + } + + companion object { - fun createFromRawTokenTheme(source: List, customTokenColors: Array): TokenTheme { - return createFromParsedTokenTheme(source.parseTokenTheme(), customTokenColors) + fun createFromRawTokenTheme( + source: List, + customTokenColors: List = emptyList(), + themeDefaultColors: ThemeDefaultColors = ThemeDefaultColors(), + themeType: String = "light" + ): TokenTheme { + return createFromParsedTokenTheme( + source.parseTokenTheme(), + customTokenColors, + themeDefaultColors, + themeType + ) } - fun createFromParsedTokenTheme(source: List, customTokenColors: Array): TokenTheme { - return source.resolveParsedTokenThemeRules( customTokenColors) + fun createFromParsedTokenTheme( + source: List, + customTokenColors: List = emptyList(), + themeDefaultColors: ThemeDefaultColors = ThemeDefaultColors(), + themeType: String = "light" + ): TokenTheme { + return source.resolveParsedTokenThemeRules( + customTokenColors, + themeDefaultColors, + themeType + ) } + } } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt new file mode 100644 index 000000000..b60490508 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt @@ -0,0 +1,170 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.theme + +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import com.squareup.moshi.Moshi +import io.github.dingyi222666.monarch.loader.json.addLast + +class TokenThemeAdapter : JsonAdapter() { + override fun fromJson(reader: JsonReader): TokenTheme { + reader.isLenient = true + val tokenThemeRuleList = mutableListOf() + val themeColorsMap = mutableMapOf() + var themeType = "light" + + // ignore name + + reader.beginObject() + + while (reader.hasNext()) { + when (val name = reader.nextName()) { + "type" -> { + themeType = reader.nextString() + } + + "tokenColors" -> { + readTokenColors(reader, tokenThemeRuleList) + } + + "colors" -> { + reader.beginObject() + while (reader.hasNext()) { + themeColorsMap[reader.nextName()] = reader.nextString() + } + reader.endObject() + } + else -> { + reader.skipValue() + } + } + } + + reader.endObject() + + return TokenTheme.createFromRawTokenTheme( + tokenThemeRuleList, + emptyList(), + ThemeDefaultColors(themeColorsMap), + themeType, + ) + + } + + private fun readTokenColors( + reader: JsonReader, + tokenThemeRuleList: MutableList + ) { + reader.beginArray() + + while (reader.hasNext()) { + reader.beginObject() + val tokenList = mutableListOf() + var foreground: String? = null + var background: String? = null + var fontStyle: String? = null + + while (reader.hasNext()) { + when (reader.nextName()) { + "scope" -> { + if (reader.peek() == JsonReader.Token.BEGIN_ARRAY) { + reader.beginArray() + while (reader.hasNext()) { + tokenList.add(reader.nextString()) + } + reader.endArray() + } else { + tokenList.add(reader.nextString()) + } + } + + "settings" -> { + reader.beginObject() + while (reader.hasNext()) { + when (reader.nextName()) { + "foreground" -> { + foreground = reader.nextString() + } + + "background" -> { + background = reader.nextString() + } + + "fontStyle" -> { + fontStyle = reader.nextString() + } + } + } + reader.endObject() + } + + else -> { + reader.skipValue() + } + } + + } + + if (tokenList.isNotEmpty()) { + for (token in tokenList) { + tokenThemeRuleList.add( + TokenThemeRule( + token, + foreground, + background, + fontStyle + ) + ) + } + } + + reader.endObject() + } + + reader.endArray() + } + + override fun toJson(p0: JsonWriter, p1: TokenTheme?) { + TODO("Not yet implemented") + } + +} + +internal val MoshiRoot: Moshi = Moshi.Builder() + .addLast(TokenThemeAdapter()) + .build() + +fun String.toTokenTheme(): TokenTheme { + return MoshiRoot.adapter(TokenTheme::class.java).fromJson(this)!! +} + +internal data class TokenThemeRule( + override var token: String, + override var foreground: String?, + override var background: String?, + override var fontStyle: String? +) : ITokenThemeRule \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt index dc05ce77a..a20ef788e 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt @@ -59,7 +59,11 @@ fun List.parseTokenTheme(): List { return result } -fun List.resolveParsedTokenThemeRules(customTokenColors: Array): TokenTheme { +fun List.resolveParsedTokenThemeRules( + customTokenColors: List = emptyList(), + themeDefaultColors: ThemeDefaultColors = ThemeDefaultColors(), + themeType: String = "light" +): TokenTheme { // Sort rules lexicographically, and then by index if necessary // this.sortWith(compareBy({ it.token }, { it.index })) val parsedThemeRules = sortedWith(compareBy({ it.token }, { it.index })).toMutableList() @@ -96,11 +100,11 @@ fun List.resolveParsedTokenThemeRules(customTokenColors: A for (rule in parsedThemeRules) { root.insert( rule.token, rule.fontStyle, colorMap.getId( - requireNotNull(rule.foreground) + rule.foreground ), - colorMap.getId(requireNotNull(rule.background)) + colorMap.getId(rule.background) ) } - return TokenTheme(colorMap, root) + return TokenTheme(colorMap, root, themeDefaultColors, themeType) } \ No newline at end of file diff --git a/language-monarch/src/test/kotlin/ThemeParse.kt b/language-monarch/src/test/kotlin/ThemeParse.kt new file mode 100644 index 000000000..f55fc9d7b --- /dev/null +++ b/language-monarch/src/test/kotlin/ThemeParse.kt @@ -0,0 +1,39 @@ +import io.github.rosemoe.sora.langs.monarch.theme.toTokenTheme +import org.junit.Test +import java.io.File + +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +class ThemeParse { + + @Test + fun parse() { + val themeJson = File("src/test/resources/sakura-color-theme.json") + + val tokenTheme = themeJson.readText().toTokenTheme() + + println(tokenTheme) + } +} \ No newline at end of file diff --git a/language-monarch/src/test/resources/sakura-color-theme.json b/language-monarch/src/test/resources/sakura-color-theme.json new file mode 100644 index 000000000..654e45613 --- /dev/null +++ b/language-monarch/src/test/resources/sakura-color-theme.json @@ -0,0 +1,2105 @@ +{ + "name": "Sakura", + "type": "light", + "semanticHighlighting": true, + "semanticTokenColors": { + "enumMember": { + "foreground": "#e75e80" + }, + "variable.constant": { + "foreground": "#b3454e" + }, + "variable.defaultLibrary": { + "foreground": "#900024" + } + }, + "tokenColors": [ + { + "name": "unison punctuation", + "scope": "punctuation.definition.delayed.unison,punctuation.definition.list.begin.unison,punctuation.definition.list.end.unison,punctuation.definition.ability.begin.unison,punctuation.definition.ability.end.unison,punctuation.operator.assignment.as.unison,punctuation.separator.pipe.unison,punctuation.separator.delimiter.unison,punctuation.definition.hash.unison", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "haskell variable generic-type", + "scope": "variable.other.generic-type.haskell", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "haskell storage type", + "scope": "storage.type.haskell", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "support.variable.magic.python", + "scope": "support.variable.magic.python", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "punctuation.separator.parameters.python", + "scope": "punctuation.separator.period.python,punctuation.separator.element.python,punctuation.parenthesis.begin.python,punctuation.parenthesis.end.python", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "variable.parameter.function.language.special.self.python", + "scope": "variable.parameter.function.language.special.self.python", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "storage.modifier.lifetime.rust", + "scope": "storage.modifier.lifetime.rust", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "support.function.std.rust", + "scope": "support.function.std.rust", + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "entity.name.lifetime.rust", + "scope": "entity.name.lifetime.rust", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "variable.language.rust", + "scope": "variable.language.rust", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "support.constant.edge", + "scope": "support.constant.edge", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "regexp constant character-class", + "scope": "constant.other.character-class.regexp", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "regexp operator.quantifier", + "scope": "keyword.operator.quantifier.regexp", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "punctuation.definition", + "scope": "punctuation.definition.string.begin,punctuation.definition.string.end", + "settings": { + "foreground": "#c91858" + } + }, + { + "name": "Text", + "scope": "variable.parameter.function", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "Comment Markup Link", + "scope": "comment markup.link", + "settings": { + "foreground": "#474b54" + } + }, + { + "name": "markup diff", + "scope": "markup.changed.diff", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "diff", + "scope": "meta.diff.header.from-file,meta.diff.header.to-file,punctuation.definition.from-file.diff,punctuation.definition.to-file.diff", + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "inserted.diff", + "scope": "markup.inserted.diff", + "settings": { + "foreground": "#c91858" + } + }, + { + "name": "deleted.diff", + "scope": "markup.deleted.diff", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "c++ function", + "scope": "meta.function.c,meta.function.cpp", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "c++ block", + "scope": "punctuation.section.block.begin.bracket.curly.cpp,punctuation.section.block.end.bracket.curly.cpp,punctuation.terminator.statement.c,punctuation.section.block.begin.bracket.curly.c,punctuation.section.block.end.bracket.curly.c,punctuation.section.parens.begin.bracket.round.c,punctuation.section.parens.end.bracket.round.c,punctuation.section.parameters.begin.bracket.round.c,punctuation.section.parameters.end.bracket.round.c", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "js/ts punctuation separator key-value", + "scope": "punctuation.separator.key-value", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "js/ts import keyword", + "scope": "keyword.operator.expression.import", + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "math js/ts", + "scope": "support.constant.math", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "math property js/ts", + "scope": "support.constant.property.math", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "js/ts variable.other.constant", + "scope": "variable.other.constant", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "java type", + "scope": [ + "storage.type.annotation.java", + "storage.type.object.array.java" + ], + "settings": { + "foreground": "#900024" + } + }, + { + "name": "java source", + "scope": "source.java", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "java modifier.import", + "scope": "punctuation.section.block.begin.java,punctuation.section.block.end.java,punctuation.definition.method-parameters.begin.java,punctuation.definition.method-parameters.end.java,meta.method.identifier.java,punctuation.section.method.begin.java,punctuation.section.method.end.java,punctuation.terminator.java,punctuation.section.class.begin.java,punctuation.section.class.end.java,punctuation.section.inner-class.begin.java,punctuation.section.inner-class.end.java,meta.method-call.java,punctuation.section.class.begin.bracket.curly.java,punctuation.section.class.end.bracket.curly.java,punctuation.section.method.begin.bracket.curly.java,punctuation.section.method.end.bracket.curly.java,punctuation.separator.period.java,punctuation.bracket.angle.java,punctuation.definition.annotation.java,meta.method.body.java", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "java modifier.import", + "scope": "meta.method.java", + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "java modifier.import", + "scope": "storage.modifier.import.java,storage.type.java,storage.type.generic.java", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "java instanceof", + "scope": "keyword.operator.instanceof.java", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "java variable.name", + "scope": "meta.definition.variable.name.java", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "operator logical", + "scope": "keyword.operator.logical", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "operator bitwise", + "scope": "keyword.operator.bitwise", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "operator channel", + "scope": "keyword.operator.channel", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "support.constant.property-value.scss", + "scope": "support.constant.property-value.scss,support.constant.property-value.css", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "CSS/SCSS/LESS Operators", + "scope": "keyword.operator.css,keyword.operator.scss,keyword.operator.less", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "css color standard name", + "scope": "support.constant.color.w3c-standard-color-name.css,support.constant.color.w3c-standard-color-name.scss", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "css comma", + "scope": "punctuation.separator.list.comma.css", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "css attribute-name.id", + "scope": "support.constant.color.w3c-standard-color-name.css", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "css property-name", + "scope": "support.type.vendored.property-name.css", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "js/ts module", + "scope": "support.module.node,support.type.object.module,support.module.node", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "entity.name.type.module", + "scope": "entity.name.type.module", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "js variable readwrite", + "scope": "variable.other.readwrite,meta.object-literal.key,support.variable.property,support.variable.object.process,support.variable.object.node", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "js/ts json", + "scope": "support.constant.json", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "js/ts Keyword", + "scope": [ + "keyword.operator.expression.instanceof", + "keyword.operator.new", + "keyword.operator.ternary", + "keyword.operator.optional", + "keyword.operator.expression.keyof" + ], + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "js/ts console", + "scope": "support.type.object.console", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "js/ts support.variable.property.process", + "scope": "support.variable.property.process", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "js console function", + "scope": "entity.name.function,support.function.console", + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "keyword.operator.misc.rust", + "scope": "keyword.operator.misc.rust", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "keyword.operator.sigil.rust", + "scope": "keyword.operator.sigil.rust", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "operator", + "scope": "keyword.operator.delete", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "js dom", + "scope": "support.type.object.dom", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "js dom variable", + "scope": "support.variable.dom,support.variable.property.dom", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "keyword.operator", + "scope": "keyword.operator.arithmetic,keyword.operator.comparison,keyword.operator.decrement,keyword.operator.increment,keyword.operator.relational", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "C operator assignment", + "scope": "keyword.operator.assignment.c,keyword.operator.comparison.c,keyword.operator.c,keyword.operator.increment.c,keyword.operator.decrement.c,keyword.operator.bitwise.shift.c,keyword.operator.assignment.cpp,keyword.operator.comparison.cpp,keyword.operator.cpp,keyword.operator.increment.cpp,keyword.operator.decrement.cpp,keyword.operator.bitwise.shift.cpp", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "Punctuation", + "scope": "punctuation.separator.delimiter", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "Other punctuation .c", + "scope": "punctuation.separator.c,punctuation.separator.cpp", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "C type posix-reserved", + "scope": "support.type.posix-reserved.c,support.type.posix-reserved.cpp", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "keyword.operator.sizeof.c", + "scope": "keyword.operator.sizeof.c,keyword.operator.sizeof.cpp", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "python parameter", + "scope": "variable.parameter.function.language.python", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "python type", + "scope": "support.type.python", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "python logical", + "scope": "keyword.operator.logical.python", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "pyCs", + "scope": "variable.parameter.function.python", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "python block", + "scope": "punctuation.definition.arguments.begin.python,punctuation.definition.arguments.end.python,punctuation.separator.arguments.python,punctuation.definition.list.begin.python,punctuation.definition.list.end.python", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "python function-call.generic", + "scope": "meta.function-call.generic.python", + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "python placeholder reset to normal string", + "scope": "constant.character.format.placeholder.other.python", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "Operators", + "scope": "keyword.operator", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "Compound Assignment Operators", + "scope": "keyword.operator.assignment.compound", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "Compound Assignment Operators js/ts", + "scope": "keyword.operator.assignment.compound.js,keyword.operator.assignment.compound.ts", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "Keywords", + "scope": "keyword", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "Namespaces", + "scope": "entity.name.namespace", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "Variables", + "scope": "variable", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "Variables", + "scope": "variable.c", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "Language variables", + "scope": "variable.language", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "Java Variables", + "scope": "token.variable.parameter.java", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "Java Imports", + "scope": "import.storage.java", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "Packages", + "scope": "token.package.keyword", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "Packages", + "scope": "token.package", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "Functions", + "scope": [ + "entity.name.function", + "meta.require", + "support.function.any-method", + "variable.function" + ], + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "Classes", + "scope": "entity.name.type.namespace", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "Classes", + "scope": "support.class, entity.name.type.class", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "Class name", + "scope": "entity.name.class.identifier.namespace.type", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "Class name", + "scope": [ + "entity.name.class", + "variable.other.class.js", + "variable.other.class.ts" + ], + "settings": { + "foreground": "#900024" + } + }, + { + "name": "Class name php", + "scope": "variable.other.class.php", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "Type Name", + "scope": "entity.name.type", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "Keyword Control", + "scope": "keyword.control", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "Control Elements", + "scope": "control.elements, keyword.operator.less", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "Methods", + "scope": "keyword.other.special-method", + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "Storage", + "scope": "storage", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "Storage JS TS", + "scope": "token.storage", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "Source Js Keyword Operator Delete,source Js Keyword Operator In,source Js Keyword Operator Of,source Js Keyword Operator Instanceof,source Js Keyword Operator New,source Js Keyword Operator Typeof,source Js Keyword Operator Void", + "scope": "keyword.operator.expression.delete,keyword.operator.expression.in,keyword.operator.expression.of,keyword.operator.expression.instanceof,keyword.operator.new,keyword.operator.expression.typeof,keyword.operator.expression.void", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "Java Storage", + "scope": "token.storage.type.java", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "Support", + "scope": "support.function", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "Support type", + "scope": "support.type.property-name", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "Support type", + "scope": "support.constant.property-value", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "Support type", + "scope": "support.constant.font-name", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "Meta tag", + "scope": "meta.tag", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "Strings", + "scope": "string", + "settings": { + "foreground": "#c91858" + } + }, + { + "name": "Inherited Class", + "scope": "entity.other.inherited-class", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "Constant other symbol", + "scope": "constant.other.symbol", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "Integers", + "scope": "constant.numeric", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "Constants", + "scope": "constant", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "Constants", + "scope": "punctuation.definition.constant", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "Tags", + "scope": "entity.name.tag", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "Attributes", + "scope": "entity.other.attribute-name", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "Attribute IDs", + "scope": "entity.other.attribute-name.id", + "settings": { + "fontStyle": "normal", + "foreground": "#bc0c62" + } + }, + { + "name": "Attribute class", + "scope": "entity.other.attribute-name.class.css", + "settings": { + "fontStyle": "normal", + "foreground": "#b3454e" + } + }, + { + "name": "Selector", + "scope": "meta.selector", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "Headings", + "scope": "markup.heading", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "Headings", + "scope": "markup.heading punctuation.definition.heading, entity.name.section", + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "Units", + "scope": "keyword.other.unit", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "Bold", + "scope": "markup.bold,todo.bold", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "Bold", + "scope": "punctuation.definition.bold", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "markup Italic", + "scope": "markup.italic, punctuation.definition.italic,todo.emphasis", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "emphasis md", + "scope": "emphasis md", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "[VSCODE-CUSTOM] Markdown headings", + "scope": "entity.name.section.markdown", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "[VSCODE-CUSTOM] Markdown heading Punctuation Definition", + "scope": "punctuation.definition.heading.markdown", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "punctuation.definition.list.begin.markdown", + "scope": "punctuation.definition.list.begin.markdown", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "[VSCODE-CUSTOM] Markdown heading setext", + "scope": "markup.heading.setext", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "[VSCODE-CUSTOM] Markdown Punctuation Definition Bold", + "scope": "punctuation.definition.bold.markdown", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "[VSCODE-CUSTOM] Markdown Inline Raw", + "scope": "markup.inline.raw.markdown", + "settings": { + "foreground": "#c91858" + } + }, + { + "name": "[VSCODE-CUSTOM] Markdown Inline Raw", + "scope": "markup.inline.raw.string.markdown", + "settings": { + "foreground": "#c91858" + } + }, + { + "name": "[VSCODE-CUSTOM] Markdown List Punctuation Definition", + "scope": "punctuation.definition.list.markdown", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "[VSCODE-CUSTOM] Markdown Punctuation Definition String", + "scope": [ + "punctuation.definition.string.begin.markdown", + "punctuation.definition.string.end.markdown", + "punctuation.definition.metadata.markdown" + ], + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "beginning.punctuation.definition.list.markdown", + "scope": [ + "beginning.punctuation.definition.list.markdown" + ], + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "[VSCODE-CUSTOM] Markdown Punctuation Definition Link", + "scope": "punctuation.definition.metadata.markdown", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "[VSCODE-CUSTOM] Markdown Underline Link/Image", + "scope": "markup.underline.link.markdown,markup.underline.link.image.markdown", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "[VSCODE-CUSTOM] Markdown Link Title/Description", + "scope": "string.other.link.title.markdown,string.other.link.description.markdown", + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "Regular Expressions", + "scope": "string.regexp", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "Escape Characters", + "scope": "constant.character.escape", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "Embedded", + "scope": "punctuation.section.embedded, variable.interpolation", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "Embedded", + "scope": "punctuation.section.embedded.begin,punctuation.section.embedded.end", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "illegal", + "scope": "invalid.illegal", + "settings": { + "foreground": "#ffffff" + } + }, + { + "name": "illegal", + "scope": "invalid.illegal.bad-ampersand.html", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "Broken", + "scope": "invalid.broken", + "settings": { + "foreground": "#ffffff" + } + }, + { + "name": "Deprecated", + "scope": "invalid.deprecated", + "settings": { + "foreground": "#ffffff" + } + }, + { + "name": "Unimplemented", + "scope": "invalid.unimplemented", + "settings": { + "foreground": "#ffffff" + } + }, + { + "name": "Source Json Meta Structure Dictionary Json > String Quoted Json", + "scope": "source.json meta.structure.dictionary.json > string.quoted.json", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "Source Json Meta Structure Dictionary Json > String Quoted Json > Punctuation String", + "scope": "source.json meta.structure.dictionary.json > string.quoted.json > punctuation.string", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "Source Json Meta Structure Dictionary Json > Value Json > String Quoted Json,source Json Meta Structure Array Json > Value Json > String Quoted Json,source Json Meta Structure Dictionary Json > Value Json > String Quoted Json > Punctuation,source Json Meta Structure Array Json > Value Json > String Quoted Json > Punctuation", + "scope": "source.json meta.structure.dictionary.json > value.json > string.quoted.json,source.json meta.structure.array.json > value.json > string.quoted.json,source.json meta.structure.dictionary.json > value.json > string.quoted.json > punctuation,source.json meta.structure.array.json > value.json > string.quoted.json > punctuation", + "settings": { + "foreground": "#c91858" + } + }, + { + "name": "Source Json Meta Structure Dictionary Json > Constant Language Json,source Json Meta Structure Array Json > Constant Language Json", + "scope": "source.json meta.structure.dictionary.json > constant.language.json,source.json meta.structure.array.json > constant.language.json", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "[VSCODE-CUSTOM] JSON Property Name", + "scope": "support.type.property-name.json", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "[VSCODE-CUSTOM] JSON Punctuation for Property Name", + "scope": "support.type.property-name.json punctuation", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "laravel blade tag", + "scope": "text.html.laravel-blade source.php.embedded.line.html entity.name.tag.laravel-blade", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "laravel blade @", + "scope": "text.html.laravel-blade source.php.embedded.line.html support.constant.laravel-blade", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "use statement for other classes", + "scope": "support.other.namespace.use.php,support.other.namespace.use-as.php,support.other.namespace.php,entity.other.alias.php,meta.interface.php", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "error suppression", + "scope": "keyword.operator.error-control.php", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "php instanceof", + "scope": "keyword.operator.type.php", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "style double quoted array index normal begin", + "scope": "punctuation.section.array.begin.php", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "style double quoted array index normal end", + "scope": "punctuation.section.array.end.php", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "php illegal.non-null-typehinted", + "scope": "invalid.illegal.non-null-typehinted.php", + "settings": { + "foreground": "#f44747" + } + }, + { + "name": "php types", + "scope": "storage.type.php,meta.other.type.phpdoc.php,keyword.other.type.php,keyword.other.array.phpdoc.php", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "php call-function", + "scope": "meta.function-call.php,meta.function-call.object.php,meta.function-call.static.php", + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "php function-resets", + "scope": "punctuation.definition.parameters.begin.bracket.round.php,punctuation.definition.parameters.end.bracket.round.php,punctuation.separator.delimiter.php,punctuation.section.scope.begin.php,punctuation.section.scope.end.php,punctuation.terminator.expression.php,punctuation.definition.arguments.begin.bracket.round.php,punctuation.definition.arguments.end.bracket.round.php,punctuation.definition.storage-type.begin.bracket.round.php,punctuation.definition.storage-type.end.bracket.round.php,punctuation.definition.array.begin.bracket.round.php,punctuation.definition.array.end.bracket.round.php,punctuation.definition.begin.bracket.round.php,punctuation.definition.end.bracket.round.php,punctuation.definition.begin.bracket.curly.php,punctuation.definition.end.bracket.curly.php,punctuation.definition.section.switch-block.end.bracket.curly.php,punctuation.definition.section.switch-block.start.bracket.curly.php,punctuation.definition.section.switch-block.begin.bracket.curly.php,punctuation.definition.section.switch-block.end.bracket.curly.php", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "support php constants", + "scope": "support.constant.core.rust", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "support php constants", + "scope": "support.constant.ext.php,support.constant.std.php,support.constant.core.php,support.constant.parser-token.php", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "php goto", + "scope": "entity.name.goto-label.php,support.other.php", + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "php logical/bitwise operator", + "scope": "keyword.operator.logical.php,keyword.operator.bitwise.php,keyword.operator.arithmetic.php", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "php regexp operator", + "scope": "keyword.operator.regexp.php", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "php comparison", + "scope": "keyword.operator.comparison.php", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "php heredoc/nowdoc", + "scope": "keyword.operator.heredoc.php,keyword.operator.nowdoc.php", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "python function decorator @", + "scope": "meta.function.decorator.python", + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "python function support", + "scope": "support.token.decorator.python,meta.function.decorator.identifier.python", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "parameter function js/ts", + "scope": "function.parameter", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "brace function", + "scope": "function.brace", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "parameter function ruby cs", + "scope": "function.parameter.ruby, function.parameter.cs", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "constant.language.symbol.ruby", + "scope": "constant.language.symbol.ruby", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "rgb-value", + "scope": "rgb-value", + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "rgb value", + "scope": "inline-color-decoration rgb-value", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "rgb value less", + "scope": "less rgb-value", + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "sass selector", + "scope": "selector.sass", + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "ts primitive/builtin types", + "scope": "support.type.primitive.ts,support.type.builtin.ts,support.type.primitive.tsx,support.type.builtin.tsx", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "block scope", + "scope": "block.scope.end,block.scope.begin", + "settings": { + "foreground": "#000000" + } + }, + { + "name": "cs storage type", + "scope": "storage.type.cs", + "settings": { + "foreground": "#900024" + } + }, + { + "name": "cs local variable", + "scope": "entity.name.variable.local.cs", + "settings": { + "foreground": "#c7004a" + } + }, + { + "scope": "token.info-token", + "settings": { + "foreground": "#bc0c62" + } + }, + { + "scope": "token.warn-token", + "settings": { + "foreground": "#b3454e" + } + }, + { + "scope": "token.error-token", + "settings": { + "foreground": "#f44747" + } + }, + { + "scope": "token.debug-token", + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "String interpolation", + "scope": [ + "punctuation.definition.template-expression.begin", + "punctuation.definition.template-expression.end", + "punctuation.section.embedded" + ], + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "Reset JavaScript string interpolation expression", + "scope": [ + "meta.template.expression" + ], + "settings": { + "foreground": "#000000" + } + }, + { + "name": "Import module JS", + "scope": [ + "keyword.operator.module" + ], + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "js Flowtype", + "scope": [ + "support.type.type.flowtype" + ], + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "js Flow", + "scope": [ + "support.type.primitive" + ], + "settings": { + "foreground": "#900024" + } + }, + { + "name": "js class prop", + "scope": [ + "meta.property.object" + ], + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "js func parameter", + "scope": [ + "variable.parameter.function.js" + ], + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "js template literals begin", + "scope": [ + "keyword.other.template.begin" + ], + "settings": { + "foreground": "#c91858" + } + }, + { + "name": "js template literals end", + "scope": [ + "keyword.other.template.end" + ], + "settings": { + "foreground": "#c91858" + } + }, + { + "name": "js template literals variable braces begin", + "scope": [ + "keyword.other.substitution.begin" + ], + "settings": { + "foreground": "#c91858" + } + }, + { + "name": "js template literals variable braces end", + "scope": [ + "keyword.other.substitution.end" + ], + "settings": { + "foreground": "#c91858" + } + }, + { + "name": "js operator.assignment", + "scope": [ + "keyword.operator.assignment" + ], + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "go operator", + "scope": [ + "keyword.operator.assignment.go" + ], + "settings": { + "foreground": "#900024" + } + }, + { + "name": "go operator", + "scope": [ + "keyword.operator.arithmetic.go", + "keyword.operator.address.go" + ], + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "Go package name", + "scope": [ + "entity.name.package.go" + ], + "settings": { + "foreground": "#900024" + } + }, + { + "name": "elm prelude", + "scope": [ + "support.type.prelude.elm" + ], + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "elm constant", + "scope": [ + "support.constant.elm" + ], + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "template literal", + "scope": [ + "punctuation.quasi.element" + ], + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "html/pug (jade) escaped characters and entities", + "scope": [ + "constant.character.entity" + ], + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "styling css pseudo-elements/classes to be able to differentiate from classes which are the same colour", + "scope": [ + "entity.other.attribute-name.pseudo-element", + "entity.other.attribute-name.pseudo-class" + ], + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "Clojure globals", + "scope": [ + "entity.global.clojure" + ], + "settings": { + "foreground": "#900024" + } + }, + { + "name": "Clojure symbols", + "scope": [ + "meta.symbol.clojure" + ], + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "Clojure constants", + "scope": [ + "constant.keyword.clojure" + ], + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "CoffeeScript Function Argument", + "scope": [ + "meta.arguments.coffee", + "variable.parameter.function.coffee" + ], + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "Ini Default Text", + "scope": [ + "source.ini" + ], + "settings": { + "foreground": "#c91858" + } + }, + { + "name": "Makefile prerequisities", + "scope": [ + "meta.scope.prerequisites.makefile" + ], + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "Makefile text colour", + "scope": [ + "source.makefile" + ], + "settings": { + "foreground": "#900024" + } + }, + { + "name": "Groovy import names", + "scope": [ + "storage.modifier.import.groovy" + ], + "settings": { + "foreground": "#900024" + } + }, + { + "name": "Groovy Methods", + "scope": [ + "meta.method.groovy" + ], + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "Groovy Variables", + "scope": [ + "meta.definition.variable.name.groovy" + ], + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "Groovy Inheritance", + "scope": [ + "meta.definition.class.inherited.classes.groovy" + ], + "settings": { + "foreground": "#c91858" + } + }, + { + "name": "HLSL Semantic", + "scope": [ + "support.variable.semantic.hlsl" + ], + "settings": { + "foreground": "#900024" + } + }, + { + "name": "HLSL Types", + "scope": [ + "support.type.texture.hlsl", + "support.type.sampler.hlsl", + "support.type.object.hlsl", + "support.type.object.rw.hlsl", + "support.type.fx.hlsl", + "support.type.object.hlsl" + ], + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "SQL Variables", + "scope": [ + "text.variable", + "text.bracketed" + ], + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "types", + "scope": [ + "support.type.swift", + "support.type.vb.asp" + ], + "settings": { + "foreground": "#900024" + } + }, + { + "name": "heading 1, keyword", + "scope": [ + "entity.name.function.xi" + ], + "settings": { + "foreground": "#900024" + } + }, + { + "name": "heading 2, callable", + "scope": [ + "entity.name.class.xi" + ], + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "heading 3, property", + "scope": [ + "constant.character.character-class.regexp.xi" + ], + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "heading 4, type, class, interface", + "scope": [ + "constant.regexp.xi" + ], + "settings": { + "foreground": "#fb2ba0" + } + }, + { + "name": "heading 5, enums, preprocessor, constant, decorator", + "scope": [ + "keyword.control.xi" + ], + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "heading 6, number", + "scope": [ + "invalid.xi" + ], + "settings": { + "foreground": "#000000" + } + }, + { + "name": "string", + "scope": [ + "beginning.punctuation.definition.quote.markdown.xi" + ], + "settings": { + "foreground": "#c91858" + } + }, + { + "name": "comments", + "scope": [ + "beginning.punctuation.definition.list.markdown.xi" + ], + "settings": { + "foreground": "#474b54" + } + }, + { + "name": "link", + "scope": [ + "constant.character.xi" + ], + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "accent", + "scope": [ + "accent.xi" + ], + "settings": { + "foreground": "#bc0c62" + } + }, + { + "name": "wikiword", + "scope": [ + "wikiword.xi" + ], + "settings": { + "foreground": "#b3454e" + } + }, + { + "name": "language operators like '+', '-' etc", + "scope": [ + "constant.other.color.rgb-value.xi" + ], + "settings": { + "foreground": "#ffffff" + } + }, + { + "name": "elements to dim", + "scope": [ + "punctuation.definition.tag.xi" + ], + "settings": { + "foreground": "#474b54" + } + }, + { + "name": "C++/C#", + "scope": [ + "entity.name.label.cs", + "entity.name.scope-resolution.function.call", + "entity.name.scope-resolution.function.definition" + ], + "settings": { + "foreground": "#900024" + } + }, + { + "name": "Markdown underscore-style headers", + "scope": [ + "entity.name.label.cs", + "markup.heading.setext.1.markdown", + "markup.heading.setext.2.markdown" + ], + "settings": { + "foreground": "#c7004a" + } + }, + { + "name": "meta.brace.square", + "scope": [ + " meta.brace.square" + ], + "settings": { + "foreground": "#000000" + } + }, + { + "name": "Comments", + "scope": "comment, punctuation.definition.comment", + "settings": { + "fontStyle": "italic", + "foreground": "#474b54" + } + }, + { + "name": "[VSCODE-CUSTOM] Markdown Quote", + "scope": "markup.quote.markdown", + "settings": { + "foreground": "#474b54" + } + }, + { + "name": "punctuation.definition.block.sequence.item.yaml", + "scope": "punctuation.definition.block.sequence.item.yaml", + "settings": { + "foreground": "#000000" + } + }, + { + "scope": [ + "constant.language.symbol.elixir" + ], + "settings": { + "foreground": "#e75e80" + } + }, + { + "name": "js/ts italic", + "scope": "entity.other.attribute-name.js,entity.other.attribute-name.ts,entity.other.attribute-name.jsx,entity.other.attribute-name.tsx,variable.parameter,variable.language.super", + "settings": { + "fontStyle": "italic" + } + }, + { + "name": "comment", + "scope": "comment.line.double-slash,comment.block.documentation", + "settings": { + "fontStyle": "italic" + } + }, + { + "name": "Python Keyword Control", + "scope": "keyword.control.import.python,keyword.control.flow.python", + "settings": { + "fontStyle": "italic" + } + }, + { + "name": "markup.italic.markdown", + "scope": "markup.italic.markdown", + "settings": { + "fontStyle": "italic" + } + } + ], + "colors": { + "foreground": "#a34d60", + "focusBorder": "#b8516700", + "selection.background": "#f48fa4", + "scrollbar.shadow": "#dddddd", + "activityBar.foreground": "#ffffff", + "activityBar.background": "#ffbcc8", + "activityBar.inactiveForeground": "#d0607a", + "activityBarBadge.foreground": "#ffffff", + "activityBarBadge.background": "#f86d92", + "activityBar.border": "#f48fa4", + "activityBar.activeBackground": "#f48fa4", + "sideBar.background": "#ffbcc8", + "sideBar.foreground": "#a34d60", + "sideBarSectionHeader.background": "#ff89a87e", + "sideBarSectionHeader.foreground": "#1b1b1b", + "sideBarSectionHeader.border": "#61616100", + "sideBarTitle.foreground": "#000000", + "sideBar.border": "#ffffff00", + "list.inactiveSelectionBackground": "#ff89a8", + "list.inactiveSelectionForeground": "#ffffff", + "list.hoverBackground": "#ff739478", + "list.hoverForeground": "#ffffff", + "list.activeSelectionBackground": "#ff8da5", + "list.activeSelectionForeground": "#ffffff", + "tree.indentGuidesStroke": "#f48fa4", + "list.dropBackground": "#f48fa49d", + "list.highlightForeground": "#6f061c", + "list.focusBackground": "#ffa5b6", + "list.focusForeground": "#000000", + "listFilterWidget.background": "#f48fa4", + "listFilterWidget.outline": "#2a2a2a00", + "listFilterWidget.noMatchesOutline": "#be1100", + "statusBar.foreground": "#ffffff", + "statusBar.background": "#e75e80", + "statusBarItem.hoverBackground": "#ffffff1f", + "statusBar.debuggingBackground": "#cc6633", + "statusBar.debuggingForeground": "#ffffff", + "statusBar.noFolderBackground": "#68217a", + "statusBar.noFolderForeground": "#ffffff", + "statusBarItem.remoteBackground": "#a34d60", + "statusBarItem.remoteForeground": "#ffffff", + "titleBar.activeBackground": "#ff7394", + "titleBar.activeForeground": "#ffffff", + "titleBar.inactiveBackground": "#ffb3c5", + "titleBar.inactiveForeground": "#000000", + "titleBar.border": "#00000000", + "menubar.selectionForeground": "#333333", + "menubar.selectionBackground": "#ff8da5", + "menubar.selectionBorder": "#b62b2b", + "menu.foreground": "#a34d60", + "menu.background": "#ffd2da", + "menu.selectionForeground": "#ffffff", + "menu.selectionBackground": "#ff8da5", + "menu.selectionBorder": "#00000000", + "menu.separatorBackground": "#f48fa4", + "menu.border": "#00000038", + "button.background": "#f48fa4", + "button.foreground": "#ffffff", + "button.hoverBackground": "#d0607a", + "button.secondaryForeground": "#ffffff", + "button.secondaryBackground": "#d0607a", + "button.secondaryHoverBackground": "#f48fa4", + "input.background": "#ffffff", + "input.border": "#00000000", + "input.foreground": "#616161", + "inputOption.activeBackground": "#ffbcc8", + "inputOption.activeBorder": "#007acc00", + "inputOption.activeForeground": "#000000", + "input.placeholderForeground": "#767676", + "textLink.foreground": "#783b48", + "editor.background": "#ffd2da", + "editor.foreground": "#000000", + "editorLineNumber.foreground": "#a34d60", + "editorCursor.foreground": "#ff4a70", + "editorCursor.background": "#ff5c7e", + "editor.selectionBackground": "#ffb7ca", + "editor.inactiveSelectionBackground": "#ffb7ca", + "editorWhitespace.foreground": "#f48fa4", + "editor.selectionHighlightBackground": "#ffa5b7", + "editor.selectionHighlightBorder": "#502a31", + "editor.findMatchBackground": "#a8ac94", + "editor.findMatchBorder": "#979b83", + "editor.findMatchHighlightBackground": "#ea5c0055", + "editor.findMatchHighlightBorder": "#ffffff00", + "editor.findRangeHighlightBackground": "#ff8da558", + "editor.findRangeHighlightBorder": "#ffe7e700", + "editor.rangeHighlightBackground": "#fdff0033", + "editor.rangeHighlightBorder": "#ffffff00", + "editor.hoverHighlightBackground": "#ff8da57a", + "editor.wordHighlightStrongBackground": "#eab0b0", + "editor.wordHighlightStrongBorder": "#ff000000", + "editor.wordHighlightBackground": "#a34d6048", + "editor.lineHighlightBackground": "#f48fa48d", + "editor.lineHighlightBorder": "#f48fa4", + "editorLineNumber.activeForeground": "#000000", + "editorLink.activeForeground": "#ff8300", + "editorIndentGuide.background": "#a34d60", + "editorIndentGuide.activeBackground": "#d0607a", + "editorRuler.foreground": "#ffffff00", + "editorBracketMatch.background": "#ffbcc8", + "editorBracketMatch.border": "#f48fa4", + "editor.foldBackground": "#ffbcc8", + "editorOverviewRuler.background": "#fd97b0a5", + "editorOverviewRuler.border": "#f48fa4", + "editorError.foreground": "#e51400", + "editorError.background": "#B73A3400", + "editorError.border": "#ffffff00", + "editorWarning.foreground": "#e9a700", + "editorWarning.background": "#A9904000", + "editorWarning.border": "#ffffff00", + "editorInfo.foreground": "#75beff", + "editorInfo.background": "#4dbbff00", + "editorInfo.border": "#4490BF00", + "editorGutter.background": "#ffd2da", + "editorGutter.modifiedBackground": "#66afe0", + "editorGutter.addedBackground": "#81b88b", + "editorGutter.deletedBackground": "#ca4b51", + "editorGutter.foldingControlForeground": "#000000", + "editorCodeLens.foreground": "#000000", + "editorGroup.border": "#f48fa4", + "diffEditor.insertedTextBackground": "#fd97b0a5", + "diffEditor.insertedTextBorder": "#ffffff00", + "diffEditor.removedTextBackground": "#ff000033", + "diffEditor.removedTextBorder": "#d1cece00", + "diffEditor.border": "#f48fa4", + "panel.background": "#ffd2da", + "panel.border": "#ff7394c7", + "panelTitle.activeBorder": "#f48fa4", + "panelTitle.activeForeground": "#b84f68", + "panelTitle.inactiveForeground": "#000000bf", + "badge.background": "#f48fa4", + "badge.foreground": "#000000", + "terminal.foreground": "#333333", + "terminal.selectionBackground": "#ff8da35e", + "terminalCursor.background": "#d0607a", + "terminalCursor.foreground": "#f48fa4", + "terminal.border": "#f48fa4", + "terminal.ansiBlack": "#000000", + "terminal.ansiBlue": "#0451a5", + "terminal.ansiBrightBlack": "#666666", + "terminal.ansiBrightBlue": "#0451a5", + "terminal.ansiBrightCyan": "#0598bc", + "terminal.ansiBrightGreen": "#14ce14", + "terminal.ansiBrightMagenta": "#bc05bc", + "terminal.ansiBrightRed": "#cd3131", + "terminal.ansiBrightWhite": "#a5a5a5", + "terminal.ansiBrightYellow": "#b5ba00", + "terminal.ansiCyan": "#0598bc", + "terminal.ansiGreen": "#00bc00", + "terminal.ansiMagenta": "#bc05bc", + "terminal.ansiRed": "#cd3131", + "terminal.ansiWhite": "#ff6d6d", + "terminal.ansiYellow": "#949800", + "breadcrumb.background": "#ffd2da", + "breadcrumb.foreground": "#502a31", + "breadcrumb.focusForeground": "#ffffff", + "editorGroupHeader.border": "#f48fa4", + "editorGroupHeader.tabsBackground": "#ffbcc8", + "tab.activeForeground": "#000000", + "tab.border": "#f3f3f300", + "tab.activeBackground": "#ffd2da", + "tab.activeBorder": "#00000000", + "tab.activeBorderTop": "#00000000", + "tab.inactiveBackground": "#ffbcc8", + "tab.inactiveForeground": "#000000b7", + "tab.hoverBackground": "#ff7394", + "tab.hoverForeground": "#ffffff", + "scrollbarSlider.background": "#ff91c69f", + "scrollbarSlider.hoverBackground": "#ff73b790", + "scrollbarSlider.activeBackground": "#ff007b90", + "progressBar.background": "#ff8da5", + "widget.shadow": "#00000058", + "editorWidget.foreground": "#502a31", + "editorWidget.background": "#ffd2da", + "editorWidget.resizeBorder": "#c7c7c7", + "pickerGroup.border": "#cccedb", + "pickerGroup.foreground": "#000000", + "debugToolBar.background": "#ea6987", + "debugToolBar.border": "#d0607a", + "notifications.foreground": "#000000", + "notifications.background": "#ffd2da", + "notificationToast.border": "#f48fa4a1", + "notificationsErrorIcon.foreground": "#e51400", + "notificationsWarningIcon.foreground": "#e9a700", + "notificationsInfoIcon.foreground": "#75beff", + "notificationCenter.border": "#f48fa4", + "notificationCenterHeader.foreground": "#000000", + "notificationCenterHeader.background": "#f48fa4", + "notifications.border": "#f48fa4", + "gitDecoration.addedResourceForeground": "#587c0c", + "gitDecoration.conflictingResourceForeground": "#6c6cc4", + "gitDecoration.deletedResourceForeground": "#ad0707", + "gitDecoration.ignoredResourceForeground": "#8e8e90", + "gitDecoration.modifiedResourceForeground": "#895503", + "gitDecoration.stageDeletedResourceForeground": "#ad0707", + "gitDecoration.stageModifiedResourceForeground": "#895503", + "gitDecoration.submoduleResourceForeground": "#1258a7", + "gitDecoration.untrackedResourceForeground": "#007100", + "editorMarkerNavigation.background": "#ffbcc8", + "editorMarkerNavigationError.background": "#e51400", + "editorMarkerNavigationWarning.background": "#e9a700", + "editorMarkerNavigationInfo.background": "#75beff", + "merge.currentHeaderBackground": "#A4E3D6", + "merge.currentContentBackground": "#DBF4EF", + "merge.incomingHeaderBackground": "#A6CFFF", + "merge.incomingContentBackground": "#DBECFF", + "merge.commonHeaderBackground": "#BFBFBF", + "merge.commonContentBackground": "#E5E5E5", + "editorSuggestWidget.background": "#ffbcc8", + "editorSuggestWidget.border": "#f48fa4", + "editorSuggestWidget.foreground": "#000000", + "editorSuggestWidget.highlightForeground": "#d0607a", + "editorSuggestWidget.selectedBackground": "#f48fa4", + "editorHoverWidget.foreground": "#000000", + "editorHoverWidget.background": "#ffbcc8", + "editorHoverWidget.border": "#f48fa4", + "peekView.border": "#f48fa4", + "peekViewEditor.background": "#ffd2da", + "peekViewEditorGutter.background": "#fd97b0a5", + "peekViewEditor.matchHighlightBackground": "#f5d802de", + "peekViewEditor.matchHighlightBorder": "#dbc417", + "peekViewResult.background": "#fd97b0a5", + "peekViewResult.fileForeground": "#1e1e1e", + "peekViewResult.lineForeground": "#0a0a0a", + "peekViewResult.matchHighlightBackground": "#ea5c004d", + "peekViewResult.selectionBackground": "#ffa5b6", + "peekViewResult.selectionForeground": "#000000", + "peekViewTitle.background": "#ff7394", + "peekViewTitleDescription.foreground": "#ffffffe6", + "peekViewTitleLabel.foreground": "#000000", + "icon.foreground": "#a34d60", + "checkbox.background": "#ffffff", + "checkbox.foreground": "#616161", + "checkbox.border": "#00000000", + "dropdown.background": "#ffffff", + "dropdown.foreground": "#616161", + "dropdown.border": "#00000000", + "minimapGutter.addedBackground": "#81b88b", + "minimapGutter.modifiedBackground": "#66afe0", + "minimapGutter.deletedBackground": "#ca4b51", + "minimap.findMatchHighlight": "#a8ac94", + "minimap.selectionHighlight": "#ffb7ca", + "minimap.errorHighlight": "#e51400", + "minimap.warningHighlight": "#e9a700", + "minimap.background": "#ffd2da", + "sideBar.dropBackground": "#f48fa49d", + "editorGroup.emptyBackground": "#ffd2da", + "panelSection.border": "#f48fa4", + "statusBarItem.activeBackground": "#FFFFFF25", + "settings.headerForeground": "#a34d60", + "settings.focusedRowBackground": "#ffffff07", + "walkThrough.embeddedEditorBackground": "#00000050", + "breadcrumb.activeSelectionForeground": "#ffffff", + "editorGutter.commentRangeForeground": "#000000", + "debugExceptionWidget.background": "#ea6987", + "debugExceptionWidget.border": "#d0607a" + } +} \ No newline at end of file From 8debf99d063b2c4e38e28dcd06c2ff9c7b60efa3 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Sun, 7 Apr 2024 20:00:02 +0800 Subject: [PATCH 04/40] feat(language-monarch): add language configuration model --- .../model/AutoClosingPair.kt | 36 ++++++++ .../model/CommentRule.kt | 30 +++++++ .../model/CompleteEnterAction.kt | 44 ++++++++++ .../model/EnterAction.kt | 31 +++++++ .../model/FoldingMarkers.kt | 30 +++++++ .../model/FoldingRules.kt | 30 +++++++ .../model/IndentAction.kt | 32 +++++++ .../model/IndentationRule.kt | 34 ++++++++ .../model/LanguageConfiguration.kt | 84 +++++++++++++++++++ .../model/OnEnterRule.kt | 33 ++++++++ 10 files changed, 384 insertions(+) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CommentRule.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CompleteEnterAction.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/EnterAction.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingMarkers.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingRules.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentAction.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentationRule.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/OnEnterRule.kt diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt new file mode 100644 index 000000000..2475def4a --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt @@ -0,0 +1,36 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model + +data class AutoClosingPair( + val open: String, + val close: String +) + +data class AutoClosingPairConditional( + val open: String, + val close: String, + val notIn: List +) \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CommentRule.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CommentRule.kt new file mode 100644 index 000000000..f7fad4285 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CommentRule.kt @@ -0,0 +1,30 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model + +data class CommentRule ( + val lineComment: String? = null, + val blockComment: CharacterPair? = null +) \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CompleteEnterAction.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CompleteEnterAction.kt new file mode 100644 index 000000000..3d1de5ae3 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CompleteEnterAction.kt @@ -0,0 +1,44 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model + +data class CompleteEnterAction( + /** + * Describe what to do with the indentation. + */ + val indentAction: IndentAction, + /** + * Describes text to be appended after the new line and after the indentation. + */ + val appendText: String, + /** + * Describes the number of characters to remove from the new line's indentation. + */ + val removeText: Int, + /** + * The line's indentation minus removeText + */ + val indentation: String +) \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/EnterAction.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/EnterAction.kt new file mode 100644 index 000000000..0144b89dd --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/EnterAction.kt @@ -0,0 +1,31 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model + +data class EnterAction( + val indentAction: Int, + val appendText: String? = null, + val removeText: Int? = null +) \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingMarkers.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingMarkers.kt new file mode 100644 index 000000000..68f6331fb --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingMarkers.kt @@ -0,0 +1,30 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model + +data class FoldingMarkers( + val start: Regex, + val end: Regex +) \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingRules.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingRules.kt new file mode 100644 index 000000000..12f8e2207 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingRules.kt @@ -0,0 +1,30 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model + +data class FoldingRules( + val offSide: Boolean? = null, + val markers: FoldingMarkers? = null +) \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentAction.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentAction.kt new file mode 100644 index 000000000..fc548b781 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentAction.kt @@ -0,0 +1,32 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model + +object IndentAction { + const val None = 0 + const val Indent = 1 + const val IndentOutdent = 2 + const val Outdent = 3 +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentationRule.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentationRule.kt new file mode 100644 index 000000000..f92395a3b --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentationRule.kt @@ -0,0 +1,34 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model + +import io.github.dingyi222666.regex.Regex + +data class IndentationRule( + val decreaseIndentPattern: Regex, + val increaseIndentPattern: Regex, + val indentNextLinePattern: Regex? = null, + val unIndentedLinePattern: Regex? = null +) \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt new file mode 100644 index 000000000..2b6dced7a --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt @@ -0,0 +1,84 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model + +import io.github.dingyi222666.regex.Regex + +data class LanguageConfiguration( + /** + * The language's comment settings. + */ + val comments: CommentRule? = null, + /** + * The language's brackets. + * This configuration implicitly affects pressing Enter around these brackets. + */ + val brackets: List? = null, + /** + * The language's word definition. + * If the language supports Unicode identifiers (e.g. JavaScript), it is preferable + * to provide a word definition that uses exclusion of known separators. + * e.g.: A regex that matches anything except known separators (and dot is allowed to occur in a floating point number): + * /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g + */ + val wordPattern: Regex? = null, + /** + * The language's indentation settings. + */ + val indentationRules: IndentationRule? = null, + /** + * The language's rules to be evaluated when pressing Enter. + */ + val onEnterRules: List? = null, + /** + * The language's auto closing pairs. The 'close' character is automatically inserted with the + * 'open' character is typed. If not set, the configured brackets will be used. + */ + val autoClosingPairs: List? = null, + /** + * The language's surrounding pairs. When the 'open' character is typed on a selection, the + * selected string is surrounded by the open and close characters. If not set, the autoclosing pairs + * settings will be used. + */ + val surroundingPairs: List? = null, + /** + * Defines a list of bracket pairs that are colorized depending on their nesting level. + * If not set, the configured brackets will be used. + */ + val colorizedBracketPairs: List, + /** + * Defines what characters must be after the cursor for bracket or quote autoclosing to occur when using the \'languageDefined\' autoclosing setting. + * + * This is typically the set of characters which can not start an expression, such as whitespace, closing brackets, non-unary operators, etc. + */ + val autoCloseBefore: String, + + /** + * The language's folding rules. + */ + val folding: FoldingRules +) + +typealias CharacterPair = Pair diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/OnEnterRule.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/OnEnterRule.kt new file mode 100644 index 000000000..af5f6be83 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/OnEnterRule.kt @@ -0,0 +1,33 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model + +import io.github.dingyi222666.regex.Regex + +data class OnEnterRule( + val beforeText: Regex, + val afterText: Regex? = null, + val action: EnterAction +) \ No newline at end of file From 93e454261e4d9d4b2696444c69a7aaa0b56d5e24 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Sat, 13 Apr 2024 03:50:53 +0800 Subject: [PATCH 05/40] feat(language-monarch): support parse language configuration --- .../monarch/languageconfiguration/loader.kt | 470 ++++++++++++++++++ .../model/AutoClosingPair.kt | 17 +- .../model/FoldingMarkers.kt | 2 + .../model/LanguageConfiguration.kt | 8 +- .../model/OnEnterRule.kt | 1 + .../sora/langs/monarch/theme/loader.kt | 13 +- .../{ThemeParse.kt => JsonParseTests.kt} | 14 +- .../javascript-language-configuration.json | 1 + 8 files changed, 512 insertions(+), 14 deletions(-) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt rename language-monarch/src/test/kotlin/{ThemeParse.kt => JsonParseTests.kt} (79%) create mode 100644 language-monarch/src/test/resources/javascript-language-configuration.json diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt new file mode 100644 index 000000000..4c2c896e7 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt @@ -0,0 +1,470 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.languageconfiguration + +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import io.github.dingyi222666.regex.GlobalRegexLib +import io.github.dingyi222666.regex.Regex +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.AutoClosingPair +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.AutoClosingPairConditional +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.BaseAutoClosingPair +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.CharacterPair +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.CommentRule +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.EnterAction +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.FoldingMarkers +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.FoldingRules +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.IndentAction +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.IndentationRule +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.OnEnterRule +import java.util.Locale +import kotlin.properties.Delegates + +class LanguageConfigurationAdapter : JsonAdapter() { + override fun fromJson(reader: JsonReader): LanguageConfiguration { + reader.isLenient = true + + var comments: CommentRule? = null + + var brackets: List? = null + + var surroundingPairs: List? = null + + var wordPattern: Regex? = null + + var indentationRules: IndentationRule? = null + + var onEnterRules: List? = null + + var autoCloseBefore: String? = null + + var foldingRules: FoldingRules? = null + + var colorizedBracketPairs: List? = null + + var autoClosingPairs: List? = null + + reader.beginObject() + + while (reader.hasNext()) { + when (reader.nextName()) { + "comments" -> { + comments = readCommentRule(reader) + } + + "brackets" -> { + brackets = readBrackets(reader) + } + + "colorizedBracketPairs" -> { + colorizedBracketPairs = readBrackets(reader) + } + + "surroundingPairs" -> { + surroundingPairs = readSurroundingPairs(reader) + } + + "autoClosingPairs" -> { + autoClosingPairs = readAutoClosingPairs(reader) + } + + "wordPattern" -> { + wordPattern = readRegex(reader) + } + + "indentationRules" -> { + indentationRules = readIndentationRules(reader) + } + + "onEnterRules" -> { + onEnterRules = readOnEnterRules(reader) + } + + "autoCloseBefore" -> { + autoCloseBefore = reader.nextString() + } + + "folding" -> { + foldingRules = readFoldingRules(reader) + } + + else -> { + reader.skipValue() + } + } + } + + reader.endObject() + + return LanguageConfiguration( + comments = comments, + brackets = brackets, + surroundingPairs = surroundingPairs, + wordPattern = wordPattern, + indentationRules = indentationRules, + onEnterRules = onEnterRules, + autoCloseBefore = autoCloseBefore, + colorizedBracketPairs = colorizedBracketPairs, + folding = foldingRules, + autoClosingPairs = autoClosingPairs + ) + + } + + private fun readAutoClosingPairs(reader: JsonReader): List { + reader.beginArray() + + val list = mutableListOf() + + while (reader.hasNext()) { + val pair = readAutoClosingPairConditional(reader) + + list.add(pair) + } + + reader.endArray() + + return list + } + + private fun readFoldingRules(reader: JsonReader): FoldingRules { + reader.beginObject() + + var offSide: Boolean? = null + + var markers: FoldingMarkers? = null + + while (reader.hasNext()) { + when (reader.nextName()) { + "offSide" -> { + offSide = reader.nextBoolean() + } + + "markers" -> { + markers = readFoldingMarkers(reader) + } + } + } + + reader.endObject() + + return FoldingRules( + offSide = offSide, + markers = markers + ) + } + + private fun readFoldingMarkers(reader: JsonReader): FoldingMarkers { + reader.beginObject() + + var start by Delegates.notNull() + var end by Delegates.notNull() + + while (reader.hasNext()) { + when (reader.nextName()) { + "start" -> { + start = readRegex(reader) + } + + "end" -> { + end = readRegex(reader) + } + } + } + + reader.endObject() + + return FoldingMarkers( + start = start, + end = end + ) + } + + + private fun readOnEnterRules(reader: JsonReader): List { + reader.beginArray() + + val onEnterRules = mutableListOf() + + while (reader.hasNext()) { + reader.beginObject() + + var beforeText by Delegates.notNull() + var afterText: Regex? = null + var action by Delegates.notNull() + var previousLineText: Regex? = null + + while (reader.hasNext()) { + when (reader.nextName()) { + "beforeText" -> { + beforeText = readRegex(reader) + } + + "afterText" -> { + afterText = readRegex(reader) + } + + "action" -> { + action = readEnterAction(reader) + } + + "previousLineText" -> { + previousLineText = readRegex(reader) + } + } + } + + onEnterRules.add(OnEnterRule(beforeText, afterText, previousLineText, action)) + reader.endObject() + } + + reader.endArray() + + return onEnterRules + } + + private fun readEnterAction(reader: JsonReader): EnterAction { + reader.beginObject() + var indentAction by Delegates.notNull() + var appendText: String? = null + var removeText: Int? = null + + while (reader.hasNext()) { + when (reader.nextName()) { + "indent" -> { + + indentAction = when (reader.nextString()) { + "none" -> IndentAction.None + "indent" -> IndentAction.Indent + "indentOutdent" -> IndentAction.IndentOutdent + "outdent" -> IndentAction.Outdent + else -> throw IllegalArgumentException("Invalid indentAction") + } + } + + "appendText" -> { + appendText = reader.nextString() + } + + "removeText" -> { + removeText = reader.nextInt() + } + } + } + reader.endObject() + return EnterAction(indentAction, appendText, removeText) + } + + private fun readIndentationRules(reader: JsonReader): IndentationRule { + reader.beginObject() + var decreaseIndentPattern by Delegates.notNull() + var increaseIndentPattern by Delegates.notNull() + var indentNextLinePattern: Regex? = null + var unIndentedLinePattern: Regex? = null + + while (reader.hasNext()) { + when (reader.nextName()) { + "decreaseIndentPattern" -> { + decreaseIndentPattern = readRegex(reader) + } + + "increaseIndentPattern" -> { + increaseIndentPattern = readRegex(reader) + } + + "indentNextLinePattern" -> { + indentNextLinePattern = readRegex(reader) + } + + "unIndentedLinePattern" -> { + unIndentedLinePattern = readRegex(reader) + } + } + } + + reader.endObject() + + return IndentationRule( + decreaseIndentPattern = decreaseIndentPattern, + increaseIndentPattern = increaseIndentPattern, + indentNextLinePattern = indentNextLinePattern, + unIndentedLinePattern = unIndentedLinePattern + ) + } + + + private fun readRegex(reader: JsonReader): Regex { + if (reader.peek() == JsonReader.Token.STRING) { + return GlobalRegexLib.compile(reader.nextString()) + } + + reader.beginObject() + + var pattern by Delegates.notNull() + + while (reader.hasNext()) { + when (reader.nextName()) { + "pattern" -> { + pattern = reader.nextString() + } + } + } + + reader.endObject() + + return GlobalRegexLib.compile(pattern) + } + + private fun readSurroundingPairs(reader: JsonReader): List { + reader.beginArray() + + val list = mutableListOf() + + while (reader.hasNext()) { + list.add(readAutoClosingPair(reader)) + } + + reader.endArray() + + return list + } + + private fun readAutoClosingPair(reader: JsonReader): BaseAutoClosingPair { + if (reader.peek() == JsonReader.Token.BEGIN_OBJECT) { + return readAutoClosingPairConditional(reader) + } + + reader.beginArray() + + val open = reader.nextString() + val close = reader.nextString() + + if (reader.hasNext()) { + val notIn = readStringArray(reader) + return AutoClosingPairConditional(open, close, notIn) + } + + reader.endArray() + + return AutoClosingPair(open, close) + } + + private fun readAutoClosingPairConditional(reader: JsonReader): AutoClosingPairConditional { + reader.beginObject() + + var open by Delegates.notNull() + var close by Delegates.notNull() + var notIn: List? = null + + while (reader.hasNext()) { + when (reader.nextName()) { + "open" -> { + open = reader.nextString() + } + + "close" -> { + close = reader.nextString() + } + + "notIn" -> { + notIn = readStringArray(reader) + } + } + } + + reader.endObject() + + return AutoClosingPairConditional(open, close, notIn ?: emptyList()) + } + + private fun readStringArray(reader: JsonReader): List { + reader.beginArray() + + val list = mutableListOf() + + while (reader.hasNext()) { + list.add(reader.nextString()) + } + + reader.endArray() + + return list + } + + private fun readBrackets(reader: JsonReader): List { + reader.beginArray() + + val list = mutableListOf() + + while (reader.hasNext()) { + list.add(readCharacterPair(reader)) + } + + reader.endArray() + + return list + } + + private fun readCommentRule(reader: JsonReader): CommentRule { + reader.beginObject() + + var lineComment: String? = null + var blockComment: CharacterPair? = null + + while (reader.hasNext()) { + when (reader.nextName()) { + "lineComment" -> { + lineComment = reader.nextString() + } + + "blockComment" -> { + blockComment = readCharacterPair(reader) + } + } + } + + reader.endObject() + + return CommentRule(lineComment, blockComment) + } + + private fun readCharacterPair(reader: JsonReader): CharacterPair { + reader.beginArray() + + val first = reader.nextString() + val second = reader.nextString() + + reader.endArray() + + return CharacterPair(first, second) + } + + override fun toJson(p0: JsonWriter, p1: LanguageConfiguration?) { + TODO("Not yet implemented") + } + +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt index 2475def4a..be7682334 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt @@ -24,13 +24,18 @@ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model -data class AutoClosingPair( - val open: String, +interface BaseAutoClosingPair { + val open: String val close: String -) +} + +data class AutoClosingPair( + override val open: String, + override val close: String +): BaseAutoClosingPair data class AutoClosingPairConditional( - val open: String, - val close: String, + override val open: String, + override val close: String, val notIn: List -) \ No newline at end of file +): BaseAutoClosingPair \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingMarkers.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingMarkers.kt index 68f6331fb..c22029d5d 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingMarkers.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingMarkers.kt @@ -24,6 +24,8 @@ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model +import io.github.dingyi222666.regex.Regex + data class FoldingMarkers( val start: Regex, val end: Regex diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt index 2b6dced7a..e8c2f2f8d 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt @@ -62,23 +62,23 @@ data class LanguageConfiguration( * selected string is surrounded by the open and close characters. If not set, the autoclosing pairs * settings will be used. */ - val surroundingPairs: List? = null, + val surroundingPairs: List? = null, /** * Defines a list of bracket pairs that are colorized depending on their nesting level. * If not set, the configured brackets will be used. */ - val colorizedBracketPairs: List, + val colorizedBracketPairs: List? = null, /** * Defines what characters must be after the cursor for bracket or quote autoclosing to occur when using the \'languageDefined\' autoclosing setting. * * This is typically the set of characters which can not start an expression, such as whitespace, closing brackets, non-unary operators, etc. */ - val autoCloseBefore: String, + val autoCloseBefore: String? = null, /** * The language's folding rules. */ - val folding: FoldingRules + val folding: FoldingRules? = null ) typealias CharacterPair = Pair diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/OnEnterRule.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/OnEnterRule.kt index af5f6be83..1ead70b73 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/OnEnterRule.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/OnEnterRule.kt @@ -29,5 +29,6 @@ import io.github.dingyi222666.regex.Regex data class OnEnterRule( val beforeText: Regex, val afterText: Regex? = null, + val previousLineText: Regex? = null, val action: EnterAction ) \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt index b60490508..4e61b2a20 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt @@ -29,6 +29,8 @@ import com.squareup.moshi.JsonReader import com.squareup.moshi.JsonWriter import com.squareup.moshi.Moshi import io.github.dingyi222666.monarch.loader.json.addLast +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.LanguageConfigurationAdapter +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration class TokenThemeAdapter : JsonAdapter() { override fun fromJson(reader: JsonReader): TokenTheme { @@ -42,7 +44,7 @@ class TokenThemeAdapter : JsonAdapter() { reader.beginObject() while (reader.hasNext()) { - when (val name = reader.nextName()) { + when (reader.nextName()) { "type" -> { themeType = reader.nextString() } @@ -155,13 +157,20 @@ class TokenThemeAdapter : JsonAdapter() { } internal val MoshiRoot: Moshi = Moshi.Builder() - .addLast(TokenThemeAdapter()) + .apply { + addLast(TokenThemeAdapter()) + addLast(LanguageConfigurationAdapter()) + } .build() fun String.toTokenTheme(): TokenTheme { return MoshiRoot.adapter(TokenTheme::class.java).fromJson(this)!! } +fun String.toLanguageConfiguration(): LanguageConfiguration { + return MoshiRoot.adapter(LanguageConfiguration::class.java).fromJson(this)!! +} + internal data class TokenThemeRule( override var token: String, override var foreground: String?, diff --git a/language-monarch/src/test/kotlin/ThemeParse.kt b/language-monarch/src/test/kotlin/JsonParseTests.kt similarity index 79% rename from language-monarch/src/test/kotlin/ThemeParse.kt rename to language-monarch/src/test/kotlin/JsonParseTests.kt index f55fc9d7b..a8f65127f 100644 --- a/language-monarch/src/test/kotlin/ThemeParse.kt +++ b/language-monarch/src/test/kotlin/JsonParseTests.kt @@ -1,3 +1,4 @@ +import io.github.rosemoe.sora.langs.monarch.theme.toLanguageConfiguration import io.github.rosemoe.sora.langs.monarch.theme.toTokenTheme import org.junit.Test import java.io.File @@ -26,10 +27,19 @@ import java.io.File * additional information or have any questions ******************************************************************************/ -class ThemeParse { +class JsonParseTests { @Test - fun parse() { + fun parseLanguageConfiguration() { + val languageJson = File("src/test/resources/javascript-language-configuration.json") + + val languageConfiguration = languageJson.readText().toLanguageConfiguration() + + println(languageConfiguration) + } + + @Test + fun parseTheme() { val themeJson = File("src/test/resources/sakura-color-theme.json") val tokenTheme = themeJson.readText().toTokenTheme() diff --git a/language-monarch/src/test/resources/javascript-language-configuration.json b/language-monarch/src/test/resources/javascript-language-configuration.json new file mode 100644 index 000000000..516dbd1d3 --- /dev/null +++ b/language-monarch/src/test/resources/javascript-language-configuration.json @@ -0,0 +1 @@ +{"comments":{"lineComment":"//","blockComment":["/*","*/"]},"brackets":[["${","}"],["{","}"],["[","]"],["(",")"]],"autoClosingPairs":[{"open":"{","close":"}"},{"open":"[","close":"]"},{"open":"(","close":")"},{"open":"'","close":"'","notIn":["string","comment"]},{"open":"\"","close":"\"","notIn":["string"]},{"open":"`","close":"`","notIn":["string","comment"]},{"open":"/**","close":" */","notIn":["string"]}],"surroundingPairs":[["{","}"],["[","]"],["(",")"],["'","'"],["\"","\""],["`","`"],["<",">"]],"autoCloseBefore":";:.,=}])>` \n\t","folding":{"markers":{"start":"^\\s*//\\s*#?region\\b","end":"^\\s*//\\s*#?endregion\\b"}},"wordPattern":{"pattern":"(-?\\d*\\.\\d\\w*)|([^\\`\\~\\@\\!\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>/\\?\\s]+)"},"indentationRules":{"decreaseIndentPattern":{"pattern":"^((?!.*?/\\*).*\\*/)?\\s*[\\}\\]\\)].*$"},"increaseIndentPattern":{"pattern":"^((?!//).)*(\\{([^}\"'`/]*|(\\t|[ ])*//.*)|\\([^)\"'`/]*|\\[[^\\]\"'`/]*)$"},"unIndentedLinePattern":{"pattern":"^(\\t|[ ])*[ ]\\*[^/]*\\*/\\s*$|^(\\t|[ ])*[ ]\\*/\\s*$|^(\\t|[ ])*[ ]\\*([ ]([^\\*]|\\*(?!/))*)?$"}},"onEnterRules":[{"beforeText":{"pattern":"^\\s*/\\*\\*(?!/)([^\\*]|\\*(?!/))*$"},"afterText":{"pattern":"^\\s*\\*/$"},"action":{"indent":"indentOutdent","appendText":" * "}},{"beforeText":{"pattern":"^\\s*/\\*\\*(?!/)([^\\*]|\\*(?!/))*$"},"action":{"indent":"none","appendText":" * "}},{"beforeText":{"pattern":"^(\\t|[ ])*[ ]\\*([ ]([^\\*]|\\*(?!/))*)?$"},"previousLineText":{"pattern":"(?=^(\\s*(/\\*\\*|\\*)).*)(?=(?!(\\s*\\*/)))"},"action":{"indent":"none","appendText":"* "}},{"beforeText":{"pattern":"^(\\t|[ ])*[ ]\\*/\\s*$"},"action":{"indent":"none","removeText":1}},{"beforeText":{"pattern":"^(\\t|[ ])*[ ]\\*[^/]*\\*/\\s*$"},"action":{"indent":"none","removeText":1}},{"beforeText":{"pattern":"^\\s*(\\bcase\\s.+:|\\bdefault:)$"},"afterText":{"pattern":"^(?!\\s*(\\bcase\\b|\\bdefault\\b))"},"action":{"indent":"indent"}},{"previousLineText":"^\\s*(((else ?)?if|for|while)\\s*\\(.*\\)\\s*|else\\s*)$","beforeText":"^\\s+([^{i\\s]|i(?!f\\b))","action":{"indent":"outdent"}}]} \ No newline at end of file From dd14b51bd260410e8a6d4294ec1203179a5e786c Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Sat, 13 Apr 2024 03:58:07 +0800 Subject: [PATCH 06/40] docs(language-monarch): update readme --- language-monarch/README.md | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/language-monarch/README.md b/language-monarch/README.md index c76edbe4e..c3e33b18d 100644 --- a/language-monarch/README.md +++ b/language-monarch/README.md @@ -1,15 +1,3 @@ ## About -**Work In Progress** `language-textmate` module is a module that performs syntax highlighting and other functions dynamically. To use it, you need to introduce several other `textmate-*` modules.Our goal is to achieve the effect of VSCode. However, for many reasons, this may be difficult to achieve in the short term. - -## Features(already available) - -1. Highlighting of files based on syntax rules -2. Load color theme from file -3. Code block line based on indent and rule - -## How to get syntax and theme files -If many people use this module, they may collect the available configuration files into a repository later. -- You can obtain relevant documents from [Textmate](https://github.com/textmate). -- Eclipse also uses Textmate, and you can also get files from its related repository。 -- Textmate is also used in [vscode](https://github.com/microsoft/vscode/tree/main/extensions), but its version is ahead of the version used in this module. You can get the configuration file from its source code, but not all of them can be used normally \ No newline at end of file +**Work In Progress** \ No newline at end of file From 3c2f97b44c03c109a3d0731f9c53dd4f49deb192 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Mon, 15 Apr 2024 09:54:37 +0800 Subject: [PATCH 07/40] feat(language-monarch): add folding package --- language-monarch/build.gradle.kts | 2 - language-monarch/gradle.properties | 4 +- .../langs/monarch/folding/FoldingHelper.kt | 33 ++++ .../langs/monarch/folding/FoldingRegion.kt | 36 ++++ .../langs/monarch/folding/FoldingRegions.kt | 105 +++++++++++ .../sora/langs/monarch/folding/IndentRange.kt | 174 ++++++++++++++++++ .../langs/monarch/folding/PreviousRegion.kt | 30 +++ .../langs/monarch/folding/RangesCollector.kt | 68 +++++++ .../model/LanguageConfiguration.kt | 2 + .../sora/langs/monarch/theme/TokenTheme.kt | 2 + 10 files changed, 452 insertions(+), 4 deletions(-) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingHelper.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingRegion.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingRegions.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/IndentRange.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/PreviousRegion.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/RangesCollector.kt diff --git a/language-monarch/build.gradle.kts b/language-monarch/build.gradle.kts index 4eb9b3e0c..9110b8004 100644 --- a/language-monarch/build.gradle.kts +++ b/language-monarch/build.gradle.kts @@ -52,13 +52,11 @@ android { } dependencies { - compileOnly(projects.editor) implementation(libs.monarch.code) implementation(libs.monarch.json) implementation(libs.regex.onig) - implementation(libs.snakeyaml.engine) implementation(libs.moshi) testImplementation(libs.junit) diff --git a/language-monarch/gradle.properties b/language-monarch/gradle.properties index f5755b62e..9ddb97b4e 100644 --- a/language-monarch/gradle.properties +++ b/language-monarch/gradle.properties @@ -22,7 +22,7 @@ # additional information or have any questions ################################################################################ -POM_ARTIFACT_ID=language-textmate -POM_NAME=language-textmate +POM_ARTIFACT_ID=language-monarch +POM_NAME=language-monarch POM_DESCRIPTION=An awesome code editor library on Android POM_PACKAGING=aar diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingHelper.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingHelper.kt new file mode 100644 index 000000000..69b8884e2 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingHelper.kt @@ -0,0 +1,33 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.folding + +import io.github.dingyi222666.regex.MatchResult + +interface FoldingHelper { + fun getResultFor(line: Int): MatchResult + + fun getIndentFor(line: Int): Int +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingRegion.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingRegion.kt new file mode 100644 index 000000000..68c9e6f71 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingRegion.kt @@ -0,0 +1,36 @@ +/* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + */ +package io.github.rosemoe.sora.langs.monarch.folding + +class FoldingRegion(private val ranges: FoldingRegions, private val regionIndex: Int) { + val startLineNumber: Int + get() = ranges.getStartLineNumber(this.regionIndex) + + val endLineNumber: Int + get() = ranges.getEndLineNumber(this.regionIndex) + + @get:Throws(Exception::class) + val parentIndex: Int + get() = ranges.getParentIndex(this.regionIndex) +} diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingRegions.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingRegions.kt new file mode 100644 index 000000000..ddbbec96a --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingRegions.kt @@ -0,0 +1,105 @@ +/* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + */ +package io.github.rosemoe.sora.langs.monarch.folding + +import android.util.SparseIntArray + +class FoldingRegions( + private val _startIndexes: SparseIntArray, + private val _endIndexes: SparseIntArray +) { + + companion object { + const val MAX_FOLDING_REGIONS = 8192 + const val MAX_LINE_NUMBER = 0x00FFFFFF + const val MASK_INDENT = 0xFF000000.toInt() + } + + private var _parentsComputed = false + + init { + require(_startIndexes.size() == _endIndexes.size()) { + "Invalid startIndexes or endIndexes size" + } + require(_startIndexes.size() <= MAX_FOLDING_REGIONS) { + "startIndexes or endIndexes size exceeds $MAX_FOLDING_REGIONS" + } + } + + val length: Int + get() = _startIndexes.size() + + fun getStartLineNumber(index: Int): Int { + return _startIndexes[index] and MAX_LINE_NUMBER + } + + fun getEndLineNumber(index: Int): Int { + return _endIndexes[index] and MAX_LINE_NUMBER + } + + fun toRegion(index: Int): FoldingRegion = FoldingRegion(this, index) + + private fun isInsideLast( + parentIndexes: ArrayDeque, + startLineNumber: Int, + endLineNumber: Int + ): Boolean { + val index = parentIndexes[parentIndexes.size - 1] + return getStartLineNumber(index) <= startLineNumber && getEndLineNumber(index) >= endLineNumber + } + + private fun ensureParentIndices() { + if (!_parentsComputed) { + _parentsComputed = true + val parentIndexes = ArrayDeque() + for (i in 0 until _startIndexes.size()) { + val startLineNumber = _startIndexes[i] + val endLineNumber = _endIndexes[i] + require(startLineNumber <= MAX_LINE_NUMBER && endLineNumber <= MAX_LINE_NUMBER) { + "startLineNumber or endLineNumber must not exceed $MAX_LINE_NUMBER" + } + while (parentIndexes.isNotEmpty() && !isInsideLast( + parentIndexes, + startLineNumber, + endLineNumber + ) + ) { + parentIndexes.removeFirst() + } + val parentIndex = + if (parentIndexes.isNotEmpty()) parentIndexes[parentIndexes.size - 1] else -1 + parentIndexes.addFirst(i) + _startIndexes.put(i, startLineNumber + ((parentIndex and 0xFF) shl 24)) + _endIndexes.put(i, endLineNumber + ((parentIndex and 0xFF00) shl 16)) + } + } + } + + fun getParentIndex(index: Int): Int { + ensureParentIndices() + val parent = + ((_startIndexes[index] and MASK_INDENT) ushr 24) + ((_endIndexes[index] and MASK_INDENT) ushr 16) + return if (parent == MAX_FOLDING_REGIONS) -1 else parent + } +} diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/IndentRange.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/IndentRange.kt new file mode 100644 index 000000000..c939753a3 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/IndentRange.kt @@ -0,0 +1,174 @@ +/* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + */ +package io.github.rosemoe.sora.langs.monarch.folding + +import io.github.dingyi222666.regex.Regex +import io.github.rosemoe.sora.lang.analysis.AsyncIncrementalAnalyzeManager +import io.github.rosemoe.sora.text.Content + +object IndentRange { + const val MAX_LINE_NUMBER: Int = 0xFFFFFF + const val MAX_FOLDING_REGIONS: Int = 0xFFFF + const val MASK_INDENT: Int = -0x1000000 + + // START sora-editor note + // Change String to char[] and int + // END sora-editor note + fun computeStartColumn(line: CharArray, len: Int, tabSize: Int): Int { + var column = 0 + var i = 0 + + while (i < len) { + val chCode = line[i] + if (chCode == ' ') { + column++ + } else if (chCode == '\t') { + column += tabSize + } else { + break + } + i++ + } + + if (i == len) { + // line only consists of whitespace + return -1 + } + + return column + } + + /** + * @return : + * - -1 => the line consists of whitespace + * - otherwise => the indent level is returned value + */ + fun computeIndentLevel(line: CharArray, len: Int, tabSize: Int): Int { + var indent = 0 + var i = 0 + + while (i < len) { + val chCode = line[i] + if (chCode == ' ') { + indent++ + } else if (chCode == '\t') { + indent = indent - indent % tabSize + tabSize + } else { + break + } + i++ + } + + if (i == len) { + // line only consists of whitespace + return -1 + } + + return indent + } + + fun computeRanges( + model: Content, + tabSize: Int, + offSide: Boolean, + helper: FoldingHelper, + pattern: Regex?, + delegate: AsyncIncrementalAnalyzeManager<*, *>.CodeBlockAnalyzeDelegate + ): FoldingRegions { + val result = RangesCollector(/*tabSize*/) + val previousRegions = mutableListOf().apply { + add(PreviousRegion(-1, model.getLineCount() + 1, model.getLineCount() + 1)) + } + + for (line in model.lineCount - 1 downTo 0) { + if (delegate.isCancelled) break + val indent = helper.getIndentFor(line) // computeIndentLevel(model.getLine(line).getBackingCharArray(), model.getColumnCount(line), tabSize) + var previous = previousRegions.last() + + if (indent == -1) { + if (offSide) { + // for offSide languages, empty lines are associated to the previous block + // note: the next block is already written to the results, so this only + // impacts the end position of the block before + previous.endAbove = line + } + continue // only whitespace + } + val m = pattern?.let { helper.getResultFor(line) } + + if (m != null) { + // folding pattern match + when { + m.count >= 2 -> { // start pattern match + // discard all regions until the folding pattern + var i = previousRegions.lastIndex + while (i > 0 && previousRegions[i].indent != -2) { + i-- + } + if (i > 0) { + // previousRegions.length = i + 1 + previous = previousRegions[i] + + // new folding range from pattern, includes the end line + result.insertFirst(line, previous.line, indent) + previous.line = line + previous.indent = indent + previous.endAbove = line + continue + } else { + // no end marker found, treat line as a regular line + } + } + else -> { // end pattern match + previousRegions.add(PreviousRegion(-2, line, line)) + continue + } + } + } + + if (previous.indent > indent) { + // discard all regions with larger indent + while (previousRegions.last().indent > indent) { + previousRegions.removeLast() + previous = previousRegions.last() + } + + // new folding range + val endLineNumber = previous.endAbove - 1 + if (endLineNumber - line >= 1) { // needs at least size 1 + result.insertFirst(line, endLineNumber, indent) + } + } + + when { + previous.indent == indent -> previous.endAbove = line + else -> { // previous.indent < indent + // new region with a bigger indent + previousRegions.add(PreviousRegion(indent, line, line)) + } + } + } + return result.toIndentRanges(model) + } +} diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/PreviousRegion.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/PreviousRegion.kt new file mode 100644 index 000000000..f19b3bffe --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/PreviousRegion.kt @@ -0,0 +1,30 @@ +/* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + */ +package io.github.rosemoe.sora.langs.monarch.folding + +data class PreviousRegion(// indent or -2 if a marker + var indent: Int, // end line number for the region above + var endAbove: Int, // start line of the region. Only used for marker regions. + var line: Int +) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/RangesCollector.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/RangesCollector.kt new file mode 100644 index 000000000..a5ead80c4 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/RangesCollector.kt @@ -0,0 +1,68 @@ +/* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + */ +package io.github.rosemoe.sora.langs.monarch.folding + +import android.util.SparseIntArray +import io.github.rosemoe.sora.text.Content + +class RangesCollector { + //this.tabSize = tabSize; + private val _startIndexes = SparseIntArray() + private val _endIndexes = SparseIntArray() + + //private final SparseIntArray _indentOccurrences; + private var _length = 0 + + //private final int tabSize; + init { + //this._indentOccurrences = new SparseIntArray(); + } + + fun insertFirst(startLineNumber: Int, endLineNumber: Int, indent: Int) { + if (startLineNumber > IndentRange.MAX_LINE_NUMBER || endLineNumber > IndentRange.MAX_LINE_NUMBER) { + return + } + val index = this._length + _startIndexes.put(index, startLineNumber) + _endIndexes.put(index, endLineNumber) + _length++ + /*if (indent < 1000) { + this._indentOccurrences.put(indent, (this._indentOccurrences.get(indent)) + 1); + }*/ + } + + @Throws(Exception::class) + fun toIndentRanges(model: Content): FoldingRegions { + return FoldingRegions(_startIndexes, _endIndexes) + /* + // reverse and create arrays of the exact length + SparseIntArray startIndexes = new SparseIntArray(this._length); + SparseIntArray endIndexes = new SparseIntArray(this._length); + for (int i = this._length - 1, k = 0; i >= 0; i--, k++) { + startIndexes.put(k, this._startIndexes.get(i)); + endIndexes.put(k, this._endIndexes.get(i)); + } + return new FoldingRegions(startIndexes, endIndexes);*/ + } +} diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt index e8c2f2f8d..608b89471 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt @@ -24,8 +24,10 @@ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model +import com.squareup.moshi.JsonClass import io.github.dingyi222666.regex.Regex +@JsonClass(generateAdapter = false) data class LanguageConfiguration( /** * The language's comment settings. diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt index 26b09229f..a41ef4c01 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt @@ -24,9 +24,11 @@ package io.github.rosemoe.sora.langs.monarch.theme +import com.squareup.moshi.JsonClass import io.github.dingyi222666.monarch.types.MetadataConsts import io.github.dingyi222666.monarch.types.StandardTokenType +@JsonClass(generateAdapter = false) class TokenTheme internal constructor( private val colorMap: ColorMap, private val root: ThemeTrieElement, From 10fa0903af23a044ef79c2d8bd61b26e94ad5515 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Mon, 15 Apr 2024 11:34:35 +0800 Subject: [PATCH 08/40] feat(language-monarch): add file registry, grammar dsl --- .../sora/langs/monarch/MonarchState.kt | 35 ++++++ .../monarch/registery/FileProviderRegistry.kt | 62 ++++++++++ .../langs/monarch/registery/ThemeRegistry.kt | 114 ++++++++++++++++++ .../registery/dsl/GrammarDefinitionDSL.kt | 71 +++++++++++ .../registery/model/GrammarDefinition.kt | 35 ++++++ .../monarch/registery/model/ThemeModel.kt | 84 +++++++++++++ .../registery/provider/AssetsFileResolver.kt | 38 ++++++ .../registery/provider/FileResolver.kt | 47 ++++++++ .../sora/langs/monarch/theme/TokenTheme.kt | 13 +- .../sora/langs/monarch/theme/loader.kt | 6 + .../rosemoe/sora/langs/monarch/theme/parse.kt | 5 +- 11 files changed, 504 insertions(+), 6 deletions(-) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchState.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/FileProviderRegistry.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/GrammarDefinition.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/provider/AssetsFileResolver.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/provider/FileResolver.kt diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchState.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchState.kt new file mode 100644 index 000000000..0bc3c4729 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchState.kt @@ -0,0 +1,35 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch + +import io.github.dingyi222666.monarch.types.TokenizeState +import io.github.dingyi222666.regex.MatchResult + +data class MonarchState( + val tokenizeState: TokenizeState, + val foldingCache: MatchResult, + val indent: Int, + val identifiers: List +) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/FileProviderRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/FileProviderRegistry.kt new file mode 100644 index 000000000..876e4fcb4 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/FileProviderRegistry.kt @@ -0,0 +1,62 @@ +/* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + */ +package io.github.rosemoe.sora.langs.monarch.registery + +import io.github.rosemoe.sora.langs.monarch.registery.provider.FileResolver +import java.io.InputStream + +object FileProviderRegistry : FileResolver { + private val fileResolvers = mutableListOf() + + init { + fileResolvers.add(FileResolver.DEFAULT) + } + + @Synchronized + fun addFileProvider(fileResolver: FileResolver) { + if (fileResolver !== FileResolver.DEFAULT) { + fileResolvers.add(fileResolver) + } + } + + @Synchronized + fun removeFileProvider(fileResolver: FileResolver) { + if (fileResolver !== FileResolver.DEFAULT) { + fileResolvers.remove(fileResolver) + } + } + + override fun resolve(path: String): InputStream? { + return fileResolvers.firstNotNullOfOrNull { it.resolve(path) } + } + + override fun dispose() { + fileResolvers.forEach { + it.dispose() + } + fileResolvers.clear() + } + + +} diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt new file mode 100644 index 000000000..ece64e298 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt @@ -0,0 +1,114 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.registery + + +import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel +import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeSource + +object ThemeRegistry { + + private val themeChangeListeners = mutableListOf() + + private val themes = mutableListOf() + + private var currentTheme: ThemeModel = ThemeModel.EMPTY + + @Throws(Exception::class) + fun loadTheme(themeSource: ThemeSource) { + loadTheme(themeSource, true) + } + + @Throws(Exception::class) + fun loadTheme(themeSource: ThemeSource, isCurrentTheme: Boolean) { + loadTheme( + ThemeModel(themeSource), + isCurrentTheme + ) + } + + @Throws(Exception::class) + fun loadTheme(themeModel: ThemeModel) { + loadTheme(themeModel, true) + } + + @Synchronized + @Throws(Exception::class) + fun loadTheme( + themeModel: ThemeModel, + isCurrentTheme: Boolean + ) { + if (!themeModel.isLoaded) { + themeModel.load() + } + val theme: ThemeModel = + findThemeByThemeName(themeModel.getName()) + if (theme != null) { + setTheme(theme) + return + } + allThemeModel.add(themeModel) + if (isCurrentTheme) { + setTheme(themeModel) + } + } + + @Synchronized + fun setTheme(name: String): Boolean { + var targetModel: ThemeModel? = + findThemeByFileName(name) + + if (targetModel != null) { + setTheme(targetModel) + return true + } + + // need? + targetModel = findThemeByThemeName(name) + + if (targetModel != null) { + setTheme(targetModel) + return true + } + + return false + } + + fun findThemeByFileName(name: String): ThemeModel? { + return themes.firstOrNull { + it.name == name + } + } + + fun findTheme(name: String): ThemeModel? { + return themes.firstOrNull { + it.theme.name == name + } + } +} + +fun interface ThemeChangeListener { + fun onChangeTheme(newTheme: ThemeModel) +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt new file mode 100644 index 000000000..01c2a6f96 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt @@ -0,0 +1,71 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.registery.dsl + +import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition + + +abstract class LanguageDefinitionListBuilder { + + private val allBuilder = mutableListOf() + + fun language(name: String, block: LanguageDefinitionBuilder.() -> Unit) { + allBuilder.add(LanguageDefinitionBuilder(name).also(block)) + } + + abstract fun build(): List> +} + +class LanguageDefinitionBuilder(var name: String) { + lateinit var grammar: String + var scopeName: String? = null + var languageConfiguration: String? = null + + var embeddedLanguages: MutableMap? = null + + fun defaultScopeName(prefix: String = "source") { + scopeName = "$prefix.$name" + } + + fun embeddedLanguages(block: LanguageEmbeddedLanguagesDefinitionBuilder.() -> Unit) { + embeddedLanguages = embeddedLanguages ?: mutableMapOf() + LanguageEmbeddedLanguagesDefinitionBuilder(checkNotNull(embeddedLanguages)).also(block) + } + + fun embeddedLanguage(scopeName: String, languageName: String) { + embeddedLanguages = embeddedLanguages ?: mutableMapOf() + embeddedLanguages?.put(scopeName, languageName) + } +} + +class LanguageEmbeddedLanguagesDefinitionBuilder(private val map: MutableMap) { + + + infix fun String.to(languageName: String) { + map[this] = languageName + } + +} + diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/GrammarDefinition.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/GrammarDefinition.kt new file mode 100644 index 000000000..4bd3dac4e --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/GrammarDefinition.kt @@ -0,0 +1,35 @@ +/* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + */ +package io.github.rosemoe.sora.langs.monarch.registery.model; + +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration + + +data class GrammarDefinition( + val name: String, + val languageConfiguration: LanguageConfiguration?, + val scopeName: String, + val embeddedLanguages: Map, + val grammar: T +) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt new file mode 100644 index 000000000..728510430 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt @@ -0,0 +1,84 @@ +/* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + */ +package io.github.rosemoe.sora.langs.monarch.registery.model + +import io.github.rosemoe.sora.langs.monarch.registery.FileProviderRegistry +import io.github.rosemoe.sora.langs.monarch.theme.TokenTheme +import io.github.rosemoe.sora.langs.monarch.theme.toTokenTheme + + +class ThemeModel { + private var themeSource: ThemeSource? = null + lateinit var theme: TokenTheme + private set + + var name: String + private set + + var isDark: Boolean = false + private set + + constructor(themeSource: ThemeSource) { + this.themeSource = themeSource + this.name = themeSource.name + } + + internal constructor(name: String) { + this.name = name + theme = TokenTheme.createFromParsedTokenTheme(emptyList()) + } + + + @Throws(Exception::class) + fun load() { + val rawThemeString = themeSource?.let { source -> + source.rawSource ?: FileProviderRegistry.resolve(source.path)?.use { + it.bufferedReader().readText() + } + } + + if (rawThemeString != null) { + theme = rawThemeString.toTokenTheme() + } + + isDark = theme.themeType == "dark" + } + + val isLoaded: Boolean + get() = ::theme.isInitialized + + + companion object { + val EMPTY = ThemeModel("EMPTY") + } + +} + + +data class ThemeSource( + val path: String, + val name: String, + val rawSource: String? = null +) + diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/provider/AssetsFileResolver.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/provider/AssetsFileResolver.kt new file mode 100644 index 000000000..e3b531ab5 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/provider/AssetsFileResolver.kt @@ -0,0 +1,38 @@ +/* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + */ +package io.github.rosemoe.sora.langs.monarch.registery.provider + +import android.content.res.AssetManager +import java.io.InputStream + +class AssetsFileResolver(private var assetManager: AssetManager?) : FileResolver { + override fun resolve(path: String): InputStream? { + return assetManager?.open(path) + } + + override fun dispose() { + // assetManager?.close() + assetManager = null + } +} diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/provider/FileResolver.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/provider/FileResolver.kt new file mode 100644 index 000000000..6ce50ba48 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/provider/FileResolver.kt @@ -0,0 +1,47 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.registery.provider + +import java.io.File +import java.io.FileInputStream +import java.io.InputStream + +fun interface FileResolver { + fun resolve(path: String): InputStream? + + fun dispose() { + // no-op + } + + companion object DEFAULT : FileResolver { + override fun resolve(path: String): InputStream? { + val file = File(path) + + return runCatching { + FileInputStream(file) + }.getOrNull() + } + } +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt index a41ef4c01..d60294505 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt @@ -33,6 +33,7 @@ class TokenTheme internal constructor( private val colorMap: ColorMap, private val root: ThemeTrieElement, private val themeDefaultColors: ThemeDefaultColors = ThemeDefaultColors(), + val name: String = "default", val themeType: String = "light" ) { private val cache: MutableMap = mutableMapOf() @@ -74,13 +75,15 @@ class TokenTheme internal constructor( source: List, customTokenColors: List = emptyList(), themeDefaultColors: ThemeDefaultColors = ThemeDefaultColors(), - themeType: String = "light" + themeType: String = "light", + name: String = "default" ): TokenTheme { return createFromParsedTokenTheme( source.parseTokenTheme(), customTokenColors, themeDefaultColors, - themeType + themeType, + name ) } @@ -88,12 +91,14 @@ class TokenTheme internal constructor( source: List, customTokenColors: List = emptyList(), themeDefaultColors: ThemeDefaultColors = ThemeDefaultColors(), - themeType: String = "light" + themeType: String = "light", + name: String = "default" ): TokenTheme { return source.resolveParsedTokenThemeRules( customTokenColors, themeDefaultColors, - themeType + themeType, + name ) } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt index 4e61b2a20..f0c9582c8 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt @@ -38,6 +38,7 @@ class TokenThemeAdapter : JsonAdapter() { val tokenThemeRuleList = mutableListOf() val themeColorsMap = mutableMapOf() var themeType = "light" + var themeName = "" // ignore name @@ -60,6 +61,9 @@ class TokenThemeAdapter : JsonAdapter() { } reader.endObject() } + "name" -> { + themeName = reader.nextString() + } else -> { reader.skipValue() } @@ -73,10 +77,12 @@ class TokenThemeAdapter : JsonAdapter() { emptyList(), ThemeDefaultColors(themeColorsMap), themeType, + themeName ) } + private fun readTokenColors( reader: JsonReader, tokenThemeRuleList: MutableList diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt index a20ef788e..1d75dd5a4 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt @@ -62,7 +62,8 @@ fun List.parseTokenTheme(): List { fun List.resolveParsedTokenThemeRules( customTokenColors: List = emptyList(), themeDefaultColors: ThemeDefaultColors = ThemeDefaultColors(), - themeType: String = "light" + themeType: String = "light", + name: String ): TokenTheme { // Sort rules lexicographically, and then by index if necessary // this.sortWith(compareBy({ it.token }, { it.index })) @@ -106,5 +107,5 @@ fun List.resolveParsedTokenThemeRules( ) } - return TokenTheme(colorMap, root, themeDefaultColors, themeType) + return TokenTheme(colorMap, root, themeDefaultColors, themeType, name) } \ No newline at end of file From 3af0f2b585825587cbf9dcef2967ff7aacf990fc Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Mon, 22 Apr 2024 09:01:00 +0800 Subject: [PATCH 09/40] feat(language-monarch): add grammar registry --- .../monarch/registery/FileProviderRegistry.kt | 4 +- .../monarch/registery/GrammarRegistry.kt | 252 ++++++++++++++++++ .../langs/monarch/registery/ThemeRegistry.kt | 45 +++- .../registery/model/GrammarDefinition.kt | 6 +- 4 files changed, 298 insertions(+), 9 deletions(-) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/FileProviderRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/FileProviderRegistry.kt index 876e4fcb4..3e719236b 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/FileProviderRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/FileProviderRegistry.kt @@ -34,14 +34,14 @@ object FileProviderRegistry : FileResolver { } @Synchronized - fun addFileProvider(fileResolver: FileResolver) { + fun addProvider(fileResolver: FileResolver) { if (fileResolver !== FileResolver.DEFAULT) { fileResolvers.add(fileResolver) } } @Synchronized - fun removeFileProvider(fileResolver: FileResolver) { + fun removeProvider(fileResolver: FileResolver) { if (fileResolver !== FileResolver.DEFAULT) { fileResolvers.remove(fileResolver) } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt new file mode 100644 index 000000000..384e420b6 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt @@ -0,0 +1,252 @@ +/* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + */ +package io.github.rosemoe.sora.langs.monarch.registery + + +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration +import io.github.rosemoe.sora.langs.monarch.registery.dsl.LanguageDefinitionListBuilder +import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition +import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel + + +abstract class GrammarRegistry { + private var parent: GrammarRegistry? = null + + private val languageConfigurationMap = + mutableMapOf() + + private val scopeName2GrammarId = mutableMapOf() + + private val grammarFileName2ScopeName = mutableMapOf() + + private val scopeName2GrammarDefinition = + mutableMapOf>() + + private val themeChangeListener: ThemeChangeListener = + ThemeChangeListener { newTheme -> + try { + setTheme(newTheme) + } catch (e: Exception) { + throw RuntimeException(e) + } + } + + init { + initThemeListener() + } + + constructor(parent: GrammarRegistry?) { + this.parent = parent + } + + private fun initThemeListener() { + if (!ThemeRegistry.hasListener(themeChangeListener)) { + ThemeRegistry.addListener(themeChangeListener) + } + } + + + fun findGrammar(scopeName: String): T? { + return findGrammar(scopeName, true) + } + + fun findGrammar(scopeName: String, findInParent: Boolean): T? { + val grammar = doSearchGrammar(scopeName) + + if (grammar != null) { + return grammar + } + + if (!findInParent) { + return null + } + + + return parent?.findGrammar(scopeName, true) + } + + + /** + * Adapted to use streams to read and load language configuration files by yourself [TextMateLanguage.create]. + * + * @param languageConfiguration loaded language configuration + * @param grammar Binding to grammar + */ + @Deprecated("The grammar file and language configuration file should in most cases be on local file, use {@link GrammarDefinition#getLanguageConfiguration()} and {@link FileResolver} to read the language configuration file") + @Synchronized + fun languageConfigurationToGrammar( + languageConfiguration: LanguageConfiguration, + grammar: T + ) { + languageConfigurationMap[doTransformGrammar(grammar).scopeName] = languageConfiguration + } + + + fun findLanguageConfiguration(scopeName: String): LanguageConfiguration? { + return findLanguageConfiguration(scopeName, true) + } + + + fun findLanguageConfiguration( + scopeName: String, + findInParent: Boolean + ): LanguageConfiguration? { + val languageConfiguration: LanguageConfiguration? = languageConfigurationMap[scopeName] + + if (languageConfiguration != null) { + return languageConfiguration + } + + if (!findInParent) { + return null + } + + + return parent?.findLanguageConfiguration(scopeName, true) + } + + + fun loadLanguageAndLanguageConfiguration(grammarDefinition: GrammarDefinition): Pair { + val grammar = loadGrammar(grammarDefinition) + + val languageConfiguration: LanguageConfiguration? = + findLanguageConfiguration(grammarDefinition.scopeName, false) + + return grammar to languageConfiguration + } + + fun loadGrammars(builder: LanguageDefinitionListBuilder): List { + return loadGrammars(builder.build()) + } + + fun loadGrammars(list: List>): List { + prepareLoadGrammars(list) + return list.map { loadGrammar(it) } + } + + // TODO: load grammars by json path + /* fun loadGrammars(jsonPath: String?): List { + return loadGrammars(LanguageDefinitionReader.read(jsonPath)) + }*/ + + @Synchronized + fun loadGrammar(grammarDefinition: GrammarDefinition): T { + val languageName = grammarDefinition.name + + if (grammarFileName2ScopeName.containsKey(languageName) && grammarDefinition.scopeName.isNotEmpty()) { + //loaded + return doSearchGrammar(grammarDefinition.scopeName) + } + + + val grammar = doLoadGrammar(grammarDefinition) + + if (grammarDefinition.scopeName.isNotEmpty()) { + grammarFileName2ScopeName[languageName] = grammarDefinition.scopeName + scopeName2GrammarDefinition[grammarDefinition.scopeName] = grammarDefinition + } + + return grammar + } + + + private fun prepareLoadGrammars(grammarDefinitions: List>) { + for (grammar in grammarDefinitions) { + getOrPullGrammarId(grammar.scopeName) + } + } + + @Synchronized + @Throws(Exception::class) + fun setTheme(themeModel: ThemeModel) { + if (!themeModel.isLoaded) { + themeModel.load() + } + doSetGrammarRegistryTheme(themeModel) + } + + + @Synchronized + private fun getOrPullGrammarId(scopeName: String): Int { + var id = scopeName2GrammarId[scopeName] + + if (id == null) { + id = scopeName2GrammarId.size + 2 + } + + scopeName2GrammarId[scopeName] = id + + return id + } + + + @Synchronized + private fun findGrammarIds(scopeName2LanguageName: Map): Map { + val result = mutableMapOf() + for ((key, value) in scopeName2LanguageName) { + // scopeName (entry#getKey) + result[key] = getOrPullGrammarId( + getGrammarScopeName(value) + ) + } + return result + } + + private fun getGrammarScopeName(name: String): String { + if (scopeName2GrammarDefinition.containsKey(name)) { + return name + } + val grammarName = grammarFileName2ScopeName[name] + return grammarName ?: name + } + + @Synchronized + fun dispose(closeParent: Boolean) { + grammarFileName2ScopeName.clear() + languageConfigurationMap.clear() + scopeName2GrammarId.clear() + scopeName2GrammarDefinition.clear() + + // if (parent == null) { + // ? need? + //FileProviderRegistry.getInstance().dispose(); + // } + if (parent != null && closeParent) { + parent?.dispose(true) + } + } + + fun dispose() { + dispose(false) + } + + + abstract fun doLoadGrammar(grammarDefinition: GrammarDefinition): T + + abstract fun doSetGrammarRegistryTheme(themeModel: ThemeModel) + + abstract fun doTransformGrammar(grammar: T): GrammarDefinition + + abstract fun doSearchGrammar(scopeName: String): T +} diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt index ece64e298..823f19e68 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt @@ -63,13 +63,13 @@ object ThemeRegistry { if (!themeModel.isLoaded) { themeModel.load() } - val theme: ThemeModel = - findThemeByThemeName(themeModel.getName()) + val theme = + findTheme(themeModel.name) if (theme != null) { setTheme(theme) return } - allThemeModel.add(themeModel) + if (isCurrentTheme) { setTheme(themeModel) } @@ -86,7 +86,7 @@ object ThemeRegistry { } // need? - targetModel = findThemeByThemeName(name) + targetModel = findTheme(name) if (targetModel != null) { setTheme(targetModel) @@ -96,6 +96,43 @@ object ThemeRegistry { return false } + @Synchronized + fun setTheme(themeModel: ThemeModel) { + currentTheme = themeModel + themeChangeListeners.forEach { + it.onChangeTheme(themeModel) + } + if (!themes.contains(themeModel)) { + themes.add(themeModel) + } + dispatchThemeChange(themeModel) + } + + private fun dispatchThemeChange(targetThemeModel: ThemeModel) { + for (listener in themeChangeListeners) { + listener.onChangeTheme(targetThemeModel) + } + } + + fun hasListener(themeChangeListener: ThemeChangeListener): Boolean { + return themeChangeListeners.contains(themeChangeListener) + } + + @Synchronized + fun addListener(themeChangeListener: ThemeChangeListener) { + themeChangeListeners.add(themeChangeListener) + } + + @Synchronized + fun removeListener(themeChangeListener: ThemeChangeListener) { + themeChangeListeners.remove(themeChangeListener) + } + + + fun dispose() { + themeChangeListeners.clear() + } + fun findThemeByFileName(name: String): ThemeModel? { return themes.firstOrNull { it.name == name diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/GrammarDefinition.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/GrammarDefinition.kt index 4bd3dac4e..0454e0be2 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/GrammarDefinition.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/GrammarDefinition.kt @@ -28,8 +28,8 @@ import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.Language data class GrammarDefinition( val name: String, - val languageConfiguration: LanguageConfiguration?, - val scopeName: String, + val grammar: T, val embeddedLanguages: Map, - val grammar: T + val languageConfiguration: LanguageConfiguration? = null, + var scopeName: String, ) From 7a82b36dd7cf26f81e14257c5bc6d79c984252c6 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Sat, 11 May 2024 03:23:40 +0800 Subject: [PATCH 10/40] feat(language-monarch): add color scheme support --- .../sora/langs/monarch/MonarchColorScheme.kt | 229 ++++++++++++++++++ .../monarch/registery/GrammarRegistry.kt | 2 +- .../registery/dsl/GrammarDefinitionDSL.kt | 1 - .../monarch/registery/model/ThemeModel.kt | 2 +- .../sora/langs/monarch/theme/ColorMap.kt | 7 +- .../langs/monarch/theme/ThemeDefaultColors.kt | 6 + .../sora/langs/monarch/theme/TokenTheme.kt | 18 +- 7 files changed, 249 insertions(+), 16 deletions(-) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt new file mode 100644 index 000000000..14f209357 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt @@ -0,0 +1,229 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch + +import android.graphics.Color +import io.github.rosemoe.sora.langs.monarch.registery.ThemeChangeListener +import io.github.rosemoe.sora.langs.monarch.registery.ThemeRegistry +import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel +import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeSource +import io.github.rosemoe.sora.langs.monarch.theme.ThemeDefaultColors +import io.github.rosemoe.sora.widget.CodeEditor +import io.github.rosemoe.sora.widget.schemes.EditorColorScheme + +class MonarchColorScheme( + themeModel: ThemeModel +) : EditorColorScheme(), ThemeChangeListener { + + var currentThemeModel = themeModel + set(value) { + field = value + onChangeTheme(value) + } + + override fun onChangeTheme(newTheme: ThemeModel) { + super.colors.clear(); + applyDefault(); + } + + override fun applyDefault() { + super.applyDefault() + + if (!ThemeRegistry.hasListener(this)) { + ThemeRegistry.addListener(this) + } + + if (!currentThemeModel.isLoaded) { + currentThemeModel.load() + } + + applyThemeSettings(currentThemeModel.theme.defaults) + } + + private fun applyThemeSettings(defaultColors: ThemeDefaultColors) { + setColor(LINE_DIVIDER, Color.TRANSPARENT) + + + defaultColors["editor.foreground"]?.let { + setColor(SELECTION_INSERT, Color.parseColor(it)) + } + + defaultColors["editor.selectionBackground"]?.let { + setColor(SELECTED_TEXT_BACKGROUND, Color.parseColor(it)) + } + + + defaultColors["editorWhitespace.foreground"]?.let { + setColor(NON_PRINTABLE_CHAR, Color.parseColor(it)) + } + + + defaultColors["editor.lineHighlightBackground"]?.let { + setColor(CURRENT_LINE, Color.parseColor(it)) + } + + + defaultColors["editor.background"]?.let { + setColor(WHOLE_BACKGROUND, Color.parseColor(it)) + setColor(LINE_NUMBER_BACKGROUND, Color.parseColor(it)) + } + + + defaultColors["editorLineNumber.foreground"]?.let { + setColor(LINE_NUMBER, Color.parseColor(it)) + } + + + defaultColors["editorLineNumber.activeForeground"]?.let { + setColor(LINE_NUMBER_CURRENT, Color.parseColor(it)) + } + + defaultColors["editor.foreground"]?.let { + setColor(TEXT_NORMAL, Color.parseColor(it)) + } + + + defaultColors["completionWindowBackground"]?.let { + setColor(COMPLETION_WND_BACKGROUND, Color.parseColor(it)) + } + + defaultColors["completionWindowBackgroundCurrent"]?.let { + setColor( + COMPLETION_WND_ITEM_CURRENT, + Color.parseColor(it) + ) + } + + + defaultColors["highlightedDelimetersForeground"]?.let { + setColor( + HIGHLIGHTED_DELIMITERS_FOREGROUND, + Color.parseColor(it) + ) + } + + defaultColors["tooltipBackground"]?.let { + setColor(DIAGNOSTIC_TOOLTIP_BACKGROUND, Color.parseColor(it)) + } + + + defaultColors["tooltipBriefMessageColor"]?.let { + setColor(DIAGNOSTIC_TOOLTIP_BRIEF_MSG, Color.parseColor(it)) + } + + + defaultColors["tooltipDetailedMessageColor"]?.let { + setColor(DIAGNOSTIC_TOOLTIP_DETAILED_MSG, Color.parseColor(it)) + } + + + defaultColors["tooltipActionColor"]?.let { + setColor(DIAGNOSTIC_TOOLTIP_ACTION, Color.parseColor(it)) + } + + + val editorIndentGuideBackground = defaultColors["editorIndentGuide.background"] + val blockLineColor = + (getColor(WHOLE_BACKGROUND) + getColor(TEXT_NORMAL)) / 2 and 0x00FFFFFF or -0x78000000 + val blockLineColorCur = (blockLineColor) or -0x1000000 + + + if (editorIndentGuideBackground != null) { + setColor(BLOCK_LINE, Color.parseColor(editorIndentGuideBackground)) + } else { + setColor(BLOCK_LINE, blockLineColor) + } + + val editorIndentGuideActiveBackground = defaultColors["editorIndentGuide.activeBackground"] + + if (editorIndentGuideActiveBackground != null) { + setColor(BLOCK_LINE_CURRENT, Color.parseColor(editorIndentGuideActiveBackground)) + } else { + setColor(BLOCK_LINE_CURRENT, blockLineColorCur) + } + } + + override fun getColor(type: Int): Int { + if (type < 255) { + return super.getColor(type) + } + + // Cache colors in super class + val superColor = super.getColor(type) + + if (superColor != 0) { + return superColor + } + + val theme = currentThemeModel.theme + val color = theme.colorMap.getOrNull(type - 255) + val newColor = if (color != null) Color.parseColor(color) else super.getColor( + TEXT_NORMAL + ) + + super.colors.put(type, newColor) + + return newColor + + } + + override fun isDark(): Boolean { + val superIsDark = super.isDark() + if (superIsDark) { + return true + } + return currentThemeModel.isDark + } + + override fun detachEditor(editor: CodeEditor) { + super.detachEditor(editor) + ThemeRegistry.removeListener(this) + } + + override fun attachEditor(editor: CodeEditor) { + super.attachEditor(editor) + try { + ThemeRegistry.loadTheme(currentThemeModel) + } catch (e: Exception) { + //throw new RuntimeException(e); + } + onChangeTheme(currentThemeModel) + } + + companion object { + fun create(themeSource: ThemeSource): MonarchColorScheme { + return create( + ThemeModel(themeSource) + ) + } + + + fun create(themeModel: ThemeModel): MonarchColorScheme { + return MonarchColorScheme(themeModel) + } + + + } +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt index 384e420b6..b362fd628 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt @@ -24,12 +24,12 @@ package io.github.rosemoe.sora.langs.monarch.registery +import io.github.dingyi222666.monarch.types.MonarchLanguage import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration import io.github.rosemoe.sora.langs.monarch.registery.dsl.LanguageDefinitionListBuilder import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel - abstract class GrammarRegistry { private var parent: GrammarRegistry? = null diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt index 01c2a6f96..b11f496ca 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt @@ -28,7 +28,6 @@ import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition abstract class LanguageDefinitionListBuilder { - private val allBuilder = mutableListOf() fun language(name: String, block: LanguageDefinitionBuilder.() -> Unit) { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt index 728510430..65160fb6d 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt @@ -36,7 +36,7 @@ class ThemeModel { var name: String private set - var isDark: Boolean = false + var isDark = false private set constructor(themeSource: ThemeSource) { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt index 92369fe13..b09ff0ed8 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt @@ -30,7 +30,6 @@ class ColorMap { private val id2color = mutableListOf() private val color2id = mutableMapOf() - fun getId(color: String?): Int { if (color == null) { return 0 @@ -46,9 +45,9 @@ class ColorMap { return id2color[id] } - fun getColorMap(): List { - return id2color.toList() - } + + val colorMap: List + get() = id2color.toList() override fun toString(): String { return "ColorMap(lastColorId=$lastColorId, id2color=$id2color, color2id=$color2id)" diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt index e17361b1b..c1db1b448 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt @@ -33,6 +33,9 @@ class ThemeDefaultColors(defaultColors: Map) { constructor() : this(emptyMap()) + operator fun get(key: String): String? { + return colors[key] + } fun putColors(map: Map) { colors.putAll(map) @@ -50,5 +53,8 @@ class ThemeDefaultColors(defaultColors: Map) { return "ThemeDefaultColors(colors=$colors)" } + companion object { + val EMPTY = ThemeDefaultColors() + } } \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt index d60294505..933982480 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt @@ -30,21 +30,22 @@ import io.github.dingyi222666.monarch.types.StandardTokenType @JsonClass(generateAdapter = false) class TokenTheme internal constructor( - private val colorMap: ColorMap, + private val privateColorMap: ColorMap, private val root: ThemeTrieElement, - private val themeDefaultColors: ThemeDefaultColors = ThemeDefaultColors(), + private val themeDefaultColors: ThemeDefaultColors = ThemeDefaultColors.EMPTY, val name: String = "default", val themeType: String = "light" ) { private val cache: MutableMap = mutableMapOf() - fun getColorMap(): List { - return colorMap.getColorMap() - } + val colorMap: List + get() = privateColorMap.colorMap - fun getThemeTrieElement(): ExternalThemeTrieElement { - return root.toExternalThemeTrieElement() - } + val themeTrieElement: ExternalThemeTrieElement + get() = root.toExternalThemeTrieElement() + + val defaults: ThemeDefaultColors + get() = themeDefaultColors private fun _match(token: String): ThemeTrieElementRule { return root.match(token) @@ -63,7 +64,6 @@ class TokenTheme internal constructor( return (match(token) or (languageId shl MetadataConsts.LANGUAGEID_OFFSET)).toInt() } - fun getDefaults(): ThemeDefaultColors = themeDefaultColors override fun toString(): String { return "TokenTheme(colorMap=$colorMap, root=$root, themeDefaultColors=$themeDefaultColors, themeType='$themeType', cache=$cache)" From a470bbb41b71ad777063f1263dcd291a50444cd5 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Sat, 11 May 2024 03:43:29 +0800 Subject: [PATCH 11/40] feat(language-monarch): add monarch grammar registry --- .../monarch/registery/GrammarRegistry.kt | 32 +++------ .../registery/MonarchGrammarRegistry.kt | 66 +++++++++++++++++++ .../sora/langs/monarch/theme/TokenTheme.kt | 5 +- 3 files changed, 79 insertions(+), 24 deletions(-) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt index b362fd628..f26eda9d2 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt @@ -24,7 +24,6 @@ package io.github.rosemoe.sora.langs.monarch.registery -import io.github.dingyi222666.monarch.types.MonarchLanguage import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration import io.github.rosemoe.sora.langs.monarch.registery.dsl.LanguageDefinitionListBuilder import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition @@ -86,23 +85,6 @@ abstract class GrammarRegistry { return parent?.findGrammar(scopeName, true) } - - /** - * Adapted to use streams to read and load language configuration files by yourself [TextMateLanguage.create]. - * - * @param languageConfiguration loaded language configuration - * @param grammar Binding to grammar - */ - @Deprecated("The grammar file and language configuration file should in most cases be on local file, use {@link GrammarDefinition#getLanguageConfiguration()} and {@link FileResolver} to read the language configuration file") - @Synchronized - fun languageConfigurationToGrammar( - languageConfiguration: LanguageConfiguration, - grammar: T - ) { - languageConfigurationMap[doTransformGrammar(grammar).scopeName] = languageConfiguration - } - - fun findLanguageConfiguration(scopeName: String): LanguageConfiguration? { return findLanguageConfiguration(scopeName, true) } @@ -145,6 +127,10 @@ abstract class GrammarRegistry { return list.map { loadGrammar(it) } } + fun loadGrammars(jsonPath: String): List { + return loadGrammars(doLoadGrammarsFromJsonPath(jsonPath)) + } + // TODO: load grammars by json path /* fun loadGrammars(jsonPath: String?): List { return loadGrammars(LanguageDefinitionReader.read(jsonPath)) @@ -157,6 +143,7 @@ abstract class GrammarRegistry { if (grammarFileName2ScopeName.containsKey(languageName) && grammarDefinition.scopeName.isNotEmpty()) { //loaded return doSearchGrammar(grammarDefinition.scopeName) + ?: throw RuntimeException("Grammar cannot be find by scope name: $languageName") } @@ -242,11 +229,12 @@ abstract class GrammarRegistry { } - abstract fun doLoadGrammar(grammarDefinition: GrammarDefinition): T + protected abstract fun doLoadGrammar(grammarDefinition: GrammarDefinition): T - abstract fun doSetGrammarRegistryTheme(themeModel: ThemeModel) + protected abstract fun doSetGrammarRegistryTheme(themeModel: ThemeModel) - abstract fun doTransformGrammar(grammar: T): GrammarDefinition + protected abstract fun doLoadGrammarsFromJsonPath(jsonPath: String): List> - abstract fun doSearchGrammar(scopeName: String): T + protected abstract fun doSearchGrammar(scopeName: String): T? } + diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt new file mode 100644 index 000000000..99d8a6416 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt @@ -0,0 +1,66 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.registery + +import io.github.dingyi222666.monarch.language.Language +import io.github.dingyi222666.monarch.language.LanguageRegistry +import io.github.dingyi222666.monarch.types.IThemeService +import io.github.dingyi222666.monarch.types.ITokenTheme +import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition +import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel + +class MonarchGrammarRegistry( + private val languageRegistry: LanguageRegistry = LanguageRegistry(), + parent: GrammarRegistry? = null +) : GrammarRegistry(parent), IThemeService { + + private var currentTheme: ThemeModel = ThemeModel.EMPTY + + override fun doLoadGrammar(grammarDefinition: GrammarDefinition): Language { + return grammarDefinition.grammar.also { + languageRegistry.registerLanguage(it, true, this) + } + } + + override fun doSetGrammarRegistryTheme(themeModel: ThemeModel) { + currentTheme = themeModel + } + + override fun doLoadGrammarsFromJsonPath(jsonPath: String): List> { + TODO("Not yet implemented") + } + + override fun doSearchGrammar(scopeName: String): Language? { + // fast search? + return languageRegistry.getRegisteredLanguages().find { + it.monarchLanguage.tokenPostfix == scopeName + } + } + + + override fun currentColorTheme(): ITokenTheme { + return currentTheme.theme + } +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt index 933982480..0d99a2dad 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt @@ -25,6 +25,7 @@ package io.github.rosemoe.sora.langs.monarch.theme import com.squareup.moshi.JsonClass +import io.github.dingyi222666.monarch.types.ITokenTheme import io.github.dingyi222666.monarch.types.MetadataConsts import io.github.dingyi222666.monarch.types.StandardTokenType @@ -35,7 +36,7 @@ class TokenTheme internal constructor( private val themeDefaultColors: ThemeDefaultColors = ThemeDefaultColors.EMPTY, val name: String = "default", val themeType: String = "light" -) { +): ITokenTheme { private val cache: MutableMap = mutableMapOf() val colorMap: List @@ -60,7 +61,7 @@ class TokenTheme internal constructor( return result } - fun match(languageId: Int, token: String): Int { + override fun match(languageId: Int, token: String): Int { return (match(token) or (languageId shl MetadataConsts.LANGUAGEID_OFFSET)).toInt() } From ed1343f037de6f5d627e4fccfc2e92fd1876e1e7 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Sun, 12 May 2024 20:14:14 +0800 Subject: [PATCH 12/40] feat(language-monarch): add monarch language --- .../sora/langs/monarch/MonarchColorScheme.kt | 1 - .../sora/langs/monarch/MonarchLanguage.kt | 82 +++++++++++++++++++ .../registery/MonarchGrammarRegistry.kt | 2 +- .../monarch/theme/ExternalThemeTrieElement.kt | 2 +- .../langs/monarch/theme/ThemeTrieElement.kt | 2 +- .../sora/langs/monarch/theme/TokenTheme.kt | 2 +- .../rosemoe/sora/langs/monarch/theme/types.kt | 2 - 7 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt index 14f209357..788ab422b 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt @@ -186,7 +186,6 @@ class MonarchColorScheme( super.colors.put(type, newColor) return newColor - } override fun isDark(): Boolean { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt new file mode 100644 index 000000000..d7a9ab661 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt @@ -0,0 +1,82 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch + +import android.os.Bundle +import io.github.rosemoe.sora.lang.EmptyLanguage +import io.github.rosemoe.sora.lang.completion.CompletionHelper +import io.github.rosemoe.sora.lang.completion.CompletionPublisher +import io.github.rosemoe.sora.lang.completion.IdentifierAutoComplete +import io.github.rosemoe.sora.lang.completion.IdentifierAutoComplete.SyncIdentifiers +import io.github.rosemoe.sora.langs.monarch.registery.MonarchGrammarRegistry +import io.github.rosemoe.sora.text.CharPosition +import io.github.rosemoe.sora.text.ContentReference +import io.github.rosemoe.sora.util.MyCharacter + +class MonarchLanguage : EmptyLanguage() { + var tabSize = 4 + + var useTab = false + + val autoCompleter = IdentifierAutoComplete() + + var autoCompleteEnabled = false + + private var createIdentifiers = false + + // var monarchAnalyzer: MonarchAnalyzer? = null + + private lateinit var grammarRegistry: MonarchGrammarRegistry + /* + var newlineHandlers: Array + + var symbolPairMatch: TextMateSymbolPairMatch? = null*/ + + override fun useTab() = useTab + + override fun destroy() { + super.destroy() + } + + override fun requireAutoComplete( + content: ContentReference, + position: CharPosition, + publisher: CompletionPublisher, + extraArguments: Bundle + ) { + if (!autoCompleteEnabled) { + return + } + val prefix = CompletionHelper.computePrefix( + content, position + ) { key: Char -> MyCharacter.isJavaIdentifierPart(key) } + /*val idt: SyncIdentifiers = textMateAnalyzer.syncIdentifiers + autoComplete.requireAutoComplete(content, position, prefix, publisher, idt)*/ + } + + fun setCompleterKeywords(keywords: Array?) { + autoCompleter.setKeywords(keywords, false) + } +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt index 99d8a6416..ebc014c37 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt @@ -36,7 +36,7 @@ class MonarchGrammarRegistry( parent: GrammarRegistry? = null ) : GrammarRegistry(parent), IThemeService { - private var currentTheme: ThemeModel = ThemeModel.EMPTY + private var currentTheme = ThemeModel.EMPTY override fun doLoadGrammar(grammarDefinition: GrammarDefinition): Language { return grammarDefinition.grammar.also { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ExternalThemeTrieElement.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ExternalThemeTrieElement.kt index 99cf86608..b9074d78d 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ExternalThemeTrieElement.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ExternalThemeTrieElement.kt @@ -28,5 +28,5 @@ class ExternalThemeTrieElement( val mainRule: ThemeTrieElementRule, children: Map = mapOf() ) { - val children: MutableMap = children.toMutableMap() + val children = children.toMutableMap() } \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt index 7eedc9c20..1f8b622c9 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt @@ -25,7 +25,7 @@ package io.github.rosemoe.sora.langs.monarch.theme class ThemeTrieElement(private val mainRule: ThemeTrieElementRule) { - private val children: MutableMap = mutableMapOf() + private val children = mutableMapOf() fun toExternalThemeTrieElement(): ExternalThemeTrieElement { val children = children.mapValues { it.value.toExternalThemeTrieElement() }.toMutableMap() diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt index 0d99a2dad..91931a2dc 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt @@ -37,7 +37,7 @@ class TokenTheme internal constructor( val name: String = "default", val themeType: String = "light" ): ITokenTheme { - private val cache: MutableMap = mutableMapOf() + private val cache = mutableMapOf() val colorMap: List get() = privateColorMap.colorMap diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/types.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/types.kt index 5d7540adb..0651de72b 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/types.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/types.kt @@ -24,8 +24,6 @@ package io.github.rosemoe.sora.langs.monarch.theme -import io.github.dingyi222666.monarch.types.FontStyle - interface ITokenThemeRule { var token: String From 9f1bfa52e24e390e2d968b0de3dbf62bae656126 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Mon, 13 May 2024 16:11:49 +0800 Subject: [PATCH 13/40] feat(language-monarch): support analyze code blocks --- .../sora/langs/monarch/MonarchAnalyzer.kt | 242 ++++++++++++++++++ .../sora/langs/monarch/MonarchLanguage.kt | 2 +- .../langs/monarch/folding/FoldingRegions.kt | 3 + .../langs/monarch/registery/ThemeRegistry.kt | 3 +- 4 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt new file mode 100644 index 000000000..6fdffdc4e --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt @@ -0,0 +1,242 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch + +import android.os.Bundle +import io.github.dingyi222666.monarch.types.ITokenizationSupport +import io.github.dingyi222666.regex.GlobalRegexLib +import io.github.dingyi222666.regex.MatchResult +import io.github.dingyi222666.regex.Regex +import io.github.rosemoe.sora.lang.analysis.AsyncIncrementalAnalyzeManager +import io.github.rosemoe.sora.lang.analysis.IncrementalAnalyzeManager.LineTokenizeResult +import io.github.rosemoe.sora.lang.analysis.StyleReceiver +import io.github.rosemoe.sora.lang.brackets.BracketsProvider +import io.github.rosemoe.sora.lang.brackets.OnlineBracketsMatcher +import io.github.rosemoe.sora.lang.completion.IdentifierAutoComplete.SyncIdentifiers +import io.github.rosemoe.sora.lang.styling.CodeBlock +import io.github.rosemoe.sora.lang.styling.Span +import io.github.rosemoe.sora.langs.monarch.folding.FoldingHelper +import io.github.rosemoe.sora.langs.monarch.folding.IndentRange +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration +import io.github.rosemoe.sora.langs.monarch.registery.ThemeChangeListener +import io.github.rosemoe.sora.langs.monarch.registery.ThemeRegistry +import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel +import io.github.rosemoe.sora.text.Content +import io.github.rosemoe.sora.text.ContentReference +import io.github.rosemoe.sora.util.ArrayList + +class MonarchAnalyzer( + private val language: MonarchLanguage, + private val tokenization: ITokenizationSupport, + private val languageConfiguration: LanguageConfiguration? = null, +) : AsyncIncrementalAnalyzeManager(), FoldingHelper, + ThemeChangeListener { + + private var cachedFoldingRegExp: Regex? = null + private var foldingOffside = false + private var bracketsProvider: BracketsProvider? = null + private val syncIdentifiers = SyncIdentifiers() + private var theme = ThemeRegistry.currentTheme + + + init { + if (!ThemeRegistry.hasListener(this)) { + ThemeRegistry.addListener(this) + } + + if (languageConfiguration != null) { + val pairs = languageConfiguration.brackets + if (!pairs.isNullOrEmpty()) { + val filteredPairs = pairs.filter { it.first.length == 1 && it.second.length == 1 } + val pairArr = CharArray(filteredPairs.size * 2) { index -> + val pairIndex = index / 2 + when (index % 2) { + 0 -> filteredPairs[pairIndex].first[0] + else -> filteredPairs[pairIndex].second[0] + } + } + bracketsProvider = OnlineBracketsMatcher(pairArr, 100000) + } + + createFoldingExp() + } + + } + + private fun createFoldingExp() { + if (languageConfiguration == null) { + return + } + val markers = languageConfiguration.folding ?: return + foldingOffside = markers.offSide == true + cachedFoldingRegExp = + GlobalRegexLib.compile("(" + markers.markers?.start + ")|(?:" + markers.markers?.end + ")") + } + + + override fun getInitialState(): MonarchState { + return MonarchState( + tokenizeState = tokenization.getInitialState(), + foldingCache = MatchResult("", IntRange.EMPTY, emptyArray()), + indent = 0, + identifiers = emptyList() + ) + } + + override fun stateEquals(state: MonarchState?, another: MonarchState?): Boolean { + if (state == null && another == null) { + return true + } + if (state != null && another != null) { + return state.tokenizeState == another.tokenizeState + } + return false + } + + override fun getIndentFor(line: Int): Int { + return getState(line).state.indent + } + + override fun getResultFor(line: Int): MatchResult { + return getState(line).state.foldingCache + } + + + override fun computeBlocks( + text: Content, + delegate: CodeBlockAnalyzeDelegate + ): MutableList { + val list = ArrayList() + analyzeCodeBlocks(text, list, delegate) + if (delegate.isNotCancelled) { + withReceiver { + it.updateBracketProvider( + this, + bracketsProvider + ) + } + } + return list + } + + private fun analyzeCodeBlocks( + model: Content, + blocks: ArrayList, + delegate: CodeBlockAnalyzeDelegate + ) { + val cachedFoldingRegExp = cachedFoldingRegExp ?: return + + runCatching { + val foldingRegions = IndentRange.computeRanges( + model, language.tabSize, foldingOffside, + this, cachedFoldingRegExp, delegate + ) + blocks.ensureCapacity(foldingRegions.length) + + for (i in foldingRegions.indices) { + if (delegate.isCancelled) { + break + } + + val foldingStartLine = foldingRegions.getStartLineNumber(i) + val foldingEndLine = foldingRegions.getEndLineNumber(i) + + if (foldingStartLine == foldingEndLine) { + continue + } + + val codeBlock = CodeBlock().apply { + toBottomOfEndLine = true + startLine = foldingStartLine + endLine = foldingEndLine + } + + // It's safe here to use raw data because the Content is only held by this thread + val length = model.getColumnCount(foldingStartLine) + val chars = model.getLine(foldingStartLine).backingCharArray + + codeBlock.startColumn = + IndentRange.computeStartColumn( + chars, + length, + language.tabSize + ) + codeBlock.endColumn = codeBlock.startColumn + blocks.add(codeBlock) + + } + + }.onFailure { + it.printStackTrace() + } + managedStyles.isIndentCountMode = true + } + + + override fun tokenizeLine( + line: CharSequence?, + state: MonarchState?, + lineIndex: Int + ): LineTokenizeResult { + TODO("Not yet implemented") + } + + override fun onAddState(state: MonarchState) { + super.onAddState(state) + if (language.createIdentifiers) { + for (identifier in state.identifiers) { + syncIdentifiers.identifierIncrease(identifier) + } + } + } + + override fun onAbandonState(state: MonarchState) { + super.onAbandonState(state) + if (language.createIdentifiers) { + for (identifier in state.identifiers) { + syncIdentifiers.identifierDecrease(identifier) + } + } + } + + override fun reset(content: ContentReference, extraArguments: Bundle) { + super.reset(content, extraArguments) + syncIdentifiers.clear() + } + + override fun destroy() { + super.destroy() + ThemeRegistry.removeListener(this) + } + + override fun generateSpansForLine(tokens: LineTokenizeResult): List? { + return null + } + + override fun onChangeTheme(newTheme: ThemeModel) { + this.theme = newTheme + } + +} diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt index d7a9ab661..653b1d7a0 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt @@ -44,7 +44,7 @@ class MonarchLanguage : EmptyLanguage() { var autoCompleteEnabled = false - private var createIdentifiers = false + var createIdentifiers = false // var monarchAnalyzer: MonarchAnalyzer? = null diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingRegions.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingRegions.kt index ddbbec96a..060b49fba 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingRegions.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingRegions.kt @@ -47,6 +47,9 @@ class FoldingRegions( } } + val indices: IntRange + get() = IntRange(0, length) + val length: Int get() = _startIndexes.size() diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt index 823f19e68..210f65d15 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt @@ -34,7 +34,8 @@ object ThemeRegistry { private val themes = mutableListOf() - private var currentTheme: ThemeModel = ThemeModel.EMPTY + var currentTheme: ThemeModel = ThemeModel.EMPTY + private set @Throws(Exception::class) fun loadTheme(themeSource: ThemeSource) { From 4fca6b3aa045b2cb3067323c7ecb8383b205e86b Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Mon, 13 May 2024 20:33:50 +0800 Subject: [PATCH 14/40] feat(language-monarch): add tokenize line support for monarch analyzer --- .../sora/langs/monarch/MonarchAnalyzer.kt | 107 ++++++++++++++++-- .../sora/langs/monarch/MonarchColorScheme.kt | 2 +- .../sora/langs/monarch/MonarchState.kt | 4 +- .../langs/monarch/folding/FoldingHelper.kt | 2 +- .../sora/langs/monarch/theme/ColorMap.kt | 4 +- .../sora/langs/monarch/theme/TokenTheme.kt | 4 +- .../sora/langs/monarch/utils/string.kt | 63 +++++++++++ 7 files changed, 170 insertions(+), 16 deletions(-) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt index 6fdffdc4e..aa368804f 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt @@ -24,28 +24,37 @@ package io.github.rosemoe.sora.langs.monarch +import android.graphics.Color import android.os.Bundle +import io.github.dingyi222666.monarch.tokenization.TokenMetadata +import io.github.dingyi222666.monarch.types.FontStyle import io.github.dingyi222666.monarch.types.ITokenizationSupport +import io.github.dingyi222666.monarch.types.StandardTokenType import io.github.dingyi222666.regex.GlobalRegexLib import io.github.dingyi222666.regex.MatchResult import io.github.dingyi222666.regex.Regex import io.github.rosemoe.sora.lang.analysis.AsyncIncrementalAnalyzeManager import io.github.rosemoe.sora.lang.analysis.IncrementalAnalyzeManager.LineTokenizeResult -import io.github.rosemoe.sora.lang.analysis.StyleReceiver import io.github.rosemoe.sora.lang.brackets.BracketsProvider import io.github.rosemoe.sora.lang.brackets.OnlineBracketsMatcher import io.github.rosemoe.sora.lang.completion.IdentifierAutoComplete.SyncIdentifiers import io.github.rosemoe.sora.lang.styling.CodeBlock import io.github.rosemoe.sora.lang.styling.Span +import io.github.rosemoe.sora.lang.styling.SpanFactory +import io.github.rosemoe.sora.lang.styling.TextStyle import io.github.rosemoe.sora.langs.monarch.folding.FoldingHelper import io.github.rosemoe.sora.langs.monarch.folding.IndentRange import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration import io.github.rosemoe.sora.langs.monarch.registery.ThemeChangeListener import io.github.rosemoe.sora.langs.monarch.registery.ThemeRegistry import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel +import io.github.rosemoe.sora.langs.monarch.utils.checkSurrogate +import io.github.rosemoe.sora.langs.monarch.utils.convertUnicodeOffsetToUtf16 import io.github.rosemoe.sora.text.Content +import io.github.rosemoe.sora.text.ContentLine import io.github.rosemoe.sora.text.ContentReference -import io.github.rosemoe.sora.util.ArrayList +import io.github.rosemoe.sora.util.MyCharacter +import io.github.rosemoe.sora.widget.schemes.EditorColorScheme class MonarchAnalyzer( private val language: MonarchLanguage, @@ -119,7 +128,7 @@ class MonarchAnalyzer( return getState(line).state.indent } - override fun getResultFor(line: Int): MatchResult { + override fun getResultFor(line: Int): MatchResult? { return getState(line).state.foldingCache } @@ -196,17 +205,99 @@ class MonarchAnalyzer( override fun tokenizeLine( - line: CharSequence?, + lineC: CharSequence, state: MonarchState?, lineIndex: Int ): LineTokenizeResult { - TODO("Not yet implemented") + val line = + if ((lineC is ContentLine)) lineC.toStringWithNewline() else lineC.toString() + + val tokens = ArrayList() + val surrogate = line.checkSurrogate() + val lineTokens = tokenization.tokenizeEncoded( + line, false, state?.tokenizeState ?: initialState.tokenizeState + ) + + val tokensLength = lineTokens.tokens.size / 2 + val identifiers = if (language.createIdentifiers) mutableListOf() else null + + for (index in 0 until tokensLength) { + val startIndex = + line.convertUnicodeOffsetToUtf16( + lineTokens.tokens[2 * index], surrogate + ) + if (index == 0 && startIndex != 0) { + tokens.add(SpanFactory.obtain(0, EditorColorScheme.TEXT_NORMAL.toLong())) + } + val metadata = lineTokens.tokens[2 * index + 1] + val foreground = TokenMetadata.getForeground(metadata) + val fontStyle = TokenMetadata.getFontStyle(metadata) + val tokenType = TokenMetadata.getTokenType(metadata) + + if (language.createIdentifiers && + tokenType == StandardTokenType.Other + ) { + val end = if (index + 1 == tokensLength) + lineC.length + else + line.convertUnicodeOffsetToUtf16( + lineTokens.tokens[2 * (index + 1)], + surrogate + ) + if (end > startIndex && MyCharacter.isJavaIdentifierStart(line[startIndex])) { + var isValidIdentifier = true + for (j in startIndex + 1 until end) { + if (!MyCharacter.isJavaIdentifierPart(line[j])) { + isValidIdentifier = false + break + } + } + if (isValidIdentifier) { + identifiers?.add(line.substring(startIndex, end)) + } + } + } + + val span = SpanFactory.obtain( + startIndex, TextStyle.makeStyle( + foreground + 255, + 0, + (fontStyle and FontStyle.Bold) != 0, + (fontStyle and FontStyle.Italic) != 0, + false + ) + ) + + span.extra = tokenType + + if ((fontStyle and FontStyle.Underline) != 0) { + val color = theme.theme.colorMap.getColor(foreground) + if (color != null) { + span.setUnderlineColor(Color.parseColor(color)) + } + } + + tokens.add(span) + } + + return LineTokenizeResult( + MonarchState( + lineTokens.endState, + cachedFoldingRegExp?.search( + line, 0 + ), + IndentRange.computeIndentLevel( + (lineC as ContentLine).backingCharArray, line.length - 1, language.tabSize + ), + identifiers + ), null, tokens + ) } override fun onAddState(state: MonarchState) { super.onAddState(state) if (language.createIdentifiers) { - for (identifier in state.identifiers) { + state.identifiers?.forEach { identifier -> syncIdentifiers.identifierIncrease(identifier) } } @@ -215,8 +306,8 @@ class MonarchAnalyzer( override fun onAbandonState(state: MonarchState) { super.onAbandonState(state) if (language.createIdentifiers) { - for (identifier in state.identifiers) { - syncIdentifiers.identifierDecrease(identifier) + state.identifiers?.forEach { identifier -> + syncIdentifiers.identifierIncrease(identifier) } } } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt index 788ab422b..430f177d3 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt @@ -178,7 +178,7 @@ class MonarchColorScheme( } val theme = currentThemeModel.theme - val color = theme.colorMap.getOrNull(type - 255) + val color = theme.colorMap.getColor(type - 255) val newColor = if (color != null) Color.parseColor(color) else super.getColor( TEXT_NORMAL ) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchState.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchState.kt index 0bc3c4729..ec61aa85b 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchState.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchState.kt @@ -29,7 +29,7 @@ import io.github.dingyi222666.regex.MatchResult data class MonarchState( val tokenizeState: TokenizeState, - val foldingCache: MatchResult, + val foldingCache: MatchResult?, val indent: Int, - val identifiers: List + val identifiers: List? ) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingHelper.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingHelper.kt index 69b8884e2..437bee5b1 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingHelper.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/folding/FoldingHelper.kt @@ -27,7 +27,7 @@ package io.github.rosemoe.sora.langs.monarch.folding import io.github.dingyi222666.regex.MatchResult interface FoldingHelper { - fun getResultFor(line: Int): MatchResult + fun getResultFor(line: Int): MatchResult? fun getIndentFor(line: Int): Int } \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt index b09ff0ed8..8e162b9f5 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt @@ -41,8 +41,8 @@ class ColorMap { } } - fun getColor(id: Int): String { - return id2color[id] + fun getColor(id: Int): String? { + return id2color.getOrNull(id) } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt index 91931a2dc..c775b6a2d 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt @@ -39,8 +39,8 @@ class TokenTheme internal constructor( ): ITokenTheme { private val cache = mutableMapOf() - val colorMap: List - get() = privateColorMap.colorMap + val colorMap: ColorMap + get() = privateColorMap val themeTrieElement: ExternalThemeTrieElement get() = root.toExternalThemeTrieElement() diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt new file mode 100644 index 000000000..c8951700f --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt @@ -0,0 +1,63 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.utils + +fun String.checkSurrogate(): Boolean { + for (element in this) { + if (Character.isSurrogate(element)) { + return true + } + } + return false +} + + +fun String.convertUnicodeOffsetToUtf16(offset: Int, isSurrogatePairConsidered: Boolean): Int { + if (offset < 0) { + throw IllegalArgumentException("Offset cannot be negative.") + } + + if (!isSurrogatePairConsidered) { + return offset + } + + var i = 0 + while (i < length) { + if (i == offset) { + return i + } + + val ch = this[i] + + if (Character.isHighSurrogate(ch) && i + 1 < length && Character.isLowSurrogate(this[i + 1])) { + i += 2 + continue + } + + i++ + } + + return offset +} From 9ccb1ba896268fd15d4bd6942e718398985187c8 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Sun, 19 May 2024 04:27:33 +0800 Subject: [PATCH 15/40] feat(lang-monarch): add create analyze manager logic to language class --- .../sora/langs/monarch/MonarchAnalyzer.kt | 4 +- .../sora/langs/monarch/MonarchColorScheme.kt | 4 +- .../sora/langs/monarch/MonarchLanguage.kt | 147 ++++++++++++++++-- .../monarch/registery/FileProviderRegistry.kt | 2 + .../monarch/registery/GrammarRegistry.kt | 16 ++ .../registery/MonarchGrammarRegistry.kt | 14 +- .../langs/monarch/registery/ThemeRegistry.kt | 2 +- .../monarch/registery/model/ThemeModel.kt | 10 +- .../sora/langs/monarch/theme/TokenTheme.kt | 4 +- 9 files changed, 175 insertions(+), 28 deletions(-) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt index aa368804f..8dcbf488e 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt @@ -66,8 +66,8 @@ class MonarchAnalyzer( private var cachedFoldingRegExp: Regex? = null private var foldingOffside = false private var bracketsProvider: BracketsProvider? = null - private val syncIdentifiers = SyncIdentifiers() private var theme = ThemeRegistry.currentTheme + internal val syncIdentifiers = SyncIdentifiers() init { @@ -271,7 +271,7 @@ class MonarchAnalyzer( span.extra = tokenType if ((fontStyle and FontStyle.Underline) != 0) { - val color = theme.theme.colorMap.getColor(foreground) + val color = theme.value.colorMap.getColor(foreground) if (color != null) { span.setUnderlineColor(Color.parseColor(color)) } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt index 430f177d3..9e30c5def 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt @@ -59,7 +59,7 @@ class MonarchColorScheme( currentThemeModel.load() } - applyThemeSettings(currentThemeModel.theme.defaults) + applyThemeSettings(currentThemeModel.value.defaults) } private fun applyThemeSettings(defaultColors: ThemeDefaultColors) { @@ -177,7 +177,7 @@ class MonarchColorScheme( return superColor } - val theme = currentThemeModel.theme + val theme = currentThemeModel.value val color = theme.colorMap.getColor(type - 255) val newColor = if (color != null) Color.parseColor(color) else super.getColor( TEXT_NORMAL diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt index 653b1d7a0..b3b83374d 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt @@ -25,34 +25,50 @@ package io.github.rosemoe.sora.langs.monarch import android.os.Bundle +import io.github.dingyi222666.monarch.language.Language import io.github.rosemoe.sora.lang.EmptyLanguage +import io.github.rosemoe.sora.lang.analysis.AnalyzeManager import io.github.rosemoe.sora.lang.completion.CompletionHelper import io.github.rosemoe.sora.lang.completion.CompletionPublisher import io.github.rosemoe.sora.lang.completion.IdentifierAutoComplete -import io.github.rosemoe.sora.lang.completion.IdentifierAutoComplete.SyncIdentifiers +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration import io.github.rosemoe.sora.langs.monarch.registery.MonarchGrammarRegistry +import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition import io.github.rosemoe.sora.text.CharPosition import io.github.rosemoe.sora.text.ContentReference import io.github.rosemoe.sora.util.MyCharacter -class MonarchLanguage : EmptyLanguage() { +class MonarchLanguage( + private var grammar: Language, + private var languageConfiguration: LanguageConfiguration?, + private var grammarRegistry: MonarchGrammarRegistry, + private var autoCompleteEnabled: Boolean +) : EmptyLanguage() { var tabSize = 4 var useTab = false - val autoCompleter = IdentifierAutoComplete() + private val autoCompleter by lazy(LazyThreadSafetyMode.NONE) { + IdentifierAutoComplete() + } + + internal var createIdentifiers = false - var autoCompleteEnabled = false + private var monarchAnalyzer: MonarchAnalyzer? = null - var createIdentifiers = false + init { + createAnalyzerAndNewlineHandler(grammar, languageConfiguration) + } - // var monarchAnalyzer: MonarchAnalyzer? = null - private lateinit var grammarRegistry: MonarchGrammarRegistry - /* - var newlineHandlers: Array + /* + var newlineHandlers: Array - var symbolPairMatch: TextMateSymbolPairMatch? = null*/ + var symbolPairMatch: TextMateSymbolPairMatch? = null*/ + + override fun getAnalyzeManager(): AnalyzeManager { + return monarchAnalyzer ?: EmptyAnalyzeManager.INSTANCE + } override fun useTab() = useTab @@ -66,17 +82,122 @@ class MonarchLanguage : EmptyLanguage() { publisher: CompletionPublisher, extraArguments: Bundle ) { - if (!autoCompleteEnabled) { + val monarchAnalyzer = monarchAnalyzer + if (!autoCompleteEnabled || monarchAnalyzer == null) { return } val prefix = CompletionHelper.computePrefix( content, position ) { key: Char -> MyCharacter.isJavaIdentifierPart(key) } - /*val idt: SyncIdentifiers = textMateAnalyzer.syncIdentifiers - autoComplete.requireAutoComplete(content, position, prefix, publisher, idt)*/ + val idt = monarchAnalyzer.syncIdentifiers + autoCompleter.requireAutoComplete(content, position, prefix, publisher, idt) } fun setCompleterKeywords(keywords: Array?) { autoCompleter.setKeywords(keywords, false) } + + private fun createAnalyzerAndNewlineHandler( + grammar: Language, + languageConfiguration: LanguageConfiguration? + ) { + val old = monarchAnalyzer + if (old != null) { + old.setReceiver(null) + old.destroy() + } + try { + monarchAnalyzer = MonarchAnalyzer( + this, + grammarRegistry.languageRegistry.getTokenizer(grammar.languageId) + ?: throw Exception("No tokenizer found for language ${grammar.languageId}"), + languageConfiguration + ) + } catch (e: Exception) { + e.printStackTrace() + } + this.languageConfiguration = languageConfiguration + /*newlineHandler = TextMateNewlineHandler(this) + newlineHandlers = arrayOf(newlineHandler) + if (languageConfiguration != null) { + // because the editor will only get the symbol pair matcher once + // (caching object to stop repeated new object created), + // the symbol pair needs to be updated inside the symbol pair matcher. + symbolPairMatch.updatePair() + }*/ + } + + companion object { + + @JvmStatic + fun create(languageScopeName: String, autoCompleteEnabled: Boolean): MonarchLanguage { + return create( + languageScopeName, + MonarchGrammarRegistry.INSTANCE, + autoCompleteEnabled + ) + } + + @JvmStatic + fun create( + languageScopeName: String, + grammarRegistry: MonarchGrammarRegistry, + autoCompleteEnabled: Boolean + ): MonarchLanguage { + val grammar = grammarRegistry.findGrammar(languageScopeName) + ?: throw IllegalArgumentException( + String.format( + "Language with %s scope name not found", + grammarRegistry + ) + ) + + val languageConfiguration = + grammarRegistry.findLanguageConfiguration( + grammar.monarchLanguage.tokenPostfix ?: grammar.languageName + ) + + return MonarchLanguage( + grammar, + languageConfiguration, + grammarRegistry, + autoCompleteEnabled + ) + } + + + @JvmStatic + fun create( + grammarDefinition: GrammarDefinition, + autoCompleteEnabled: Boolean + ): MonarchLanguage { + return create( + grammarDefinition, + MonarchGrammarRegistry.INSTANCE, + autoCompleteEnabled + ) + } + + @JvmStatic + fun create( + grammarDefinition: GrammarDefinition, + grammarRegistry: MonarchGrammarRegistry, + autoCompleteEnabled: Boolean + ): MonarchLanguage { + val grammar = grammarRegistry.loadGrammar(grammarDefinition) + + val languageConfiguration = + grammarRegistry.findLanguageConfiguration( + grammar.monarchLanguage.tokenPostfix ?: grammar.languageName + ) + + return MonarchLanguage( + grammar, + languageConfiguration, + grammarRegistry, + autoCompleteEnabled + ) + } + + } } \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/FileProviderRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/FileProviderRegistry.kt index 3e719236b..7b08fada2 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/FileProviderRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/FileProviderRegistry.kt @@ -26,6 +26,7 @@ package io.github.rosemoe.sora.langs.monarch.registery import io.github.rosemoe.sora.langs.monarch.registery.provider.FileResolver import java.io.InputStream + object FileProviderRegistry : FileResolver { private val fileResolvers = mutableListOf() @@ -47,6 +48,7 @@ object FileProviderRegistry : FileResolver { } } + override fun resolve(path: String): InputStream? { return fileResolvers.firstNotNullOfOrNull { it.resolve(path) } } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt index f26eda9d2..c2781e0cb 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt @@ -131,6 +131,19 @@ abstract class GrammarRegistry { return loadGrammars(doLoadGrammarsFromJsonPath(jsonPath)) } + /** + * Adapted to use streams to read and load language configuration files by yourself [TextMateLanguage.create]. + * + * @param languageConfiguration loaded language configuration + * @param grammar Binding to grammar + */ + fun languageConfigurationToGrammar( + languageConfiguration: LanguageConfiguration, + scopeName: String + ) { + languageConfigurationMap[scopeName] = languageConfiguration + } + // TODO: load grammars by json path /* fun loadGrammars(jsonPath: String?): List { return loadGrammars(LanguageDefinitionReader.read(jsonPath)) @@ -152,6 +165,9 @@ abstract class GrammarRegistry { if (grammarDefinition.scopeName.isNotEmpty()) { grammarFileName2ScopeName[languageName] = grammarDefinition.scopeName scopeName2GrammarDefinition[grammarDefinition.scopeName] = grammarDefinition + grammarDefinition.languageConfiguration?.also { + languageConfigurationMap[grammarDefinition.scopeName] = it + } } return grammar diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt index ebc014c37..b505fa918 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt @@ -32,7 +32,7 @@ import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel class MonarchGrammarRegistry( - private val languageRegistry: LanguageRegistry = LanguageRegistry(), + internal val languageRegistry: LanguageRegistry = LanguageRegistry(), parent: GrammarRegistry? = null ) : GrammarRegistry(parent), IThemeService { @@ -41,6 +41,7 @@ class MonarchGrammarRegistry( override fun doLoadGrammar(grammarDefinition: GrammarDefinition): Language { return grammarDefinition.grammar.also { languageRegistry.registerLanguage(it, true, this) + grammarDefinition.scopeName = it.monarchLanguage.tokenPostfix ?: it.languageName } } @@ -61,6 +62,13 @@ class MonarchGrammarRegistry( override fun currentColorTheme(): ITokenTheme { - return currentTheme.theme + return currentTheme.value } -} \ No newline at end of file + + companion object { + val INSTANCE by lazy { + MonarchGrammarRegistry() + } + } +} + diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt index 210f65d15..f09254a77 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt @@ -142,7 +142,7 @@ object ThemeRegistry { fun findTheme(name: String): ThemeModel? { return themes.firstOrNull { - it.theme.name == name + it.value.name == name } } } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt index 65160fb6d..aed987f66 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt @@ -30,7 +30,7 @@ import io.github.rosemoe.sora.langs.monarch.theme.toTokenTheme class ThemeModel { private var themeSource: ThemeSource? = null - lateinit var theme: TokenTheme + lateinit var value: TokenTheme private set var name: String @@ -46,7 +46,7 @@ class ThemeModel { internal constructor(name: String) { this.name = name - theme = TokenTheme.createFromParsedTokenTheme(emptyList()) + value = TokenTheme.createFromParsedTokenTheme(emptyList()) } @@ -59,14 +59,14 @@ class ThemeModel { } if (rawThemeString != null) { - theme = rawThemeString.toTokenTheme() + value = rawThemeString.toTokenTheme() } - isDark = theme.themeType == "dark" + isDark = value.themeType == "dark" } val isLoaded: Boolean - get() = ::theme.isInitialized + get() = ::value.isInitialized companion object { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt index c775b6a2d..9046b2c59 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt @@ -56,13 +56,13 @@ class TokenTheme internal constructor( val result = cache.getOrPut(token) { val rule = _match(token) val standardToken = token.toStandardTokenType() - (rule.metadata or (standardToken shl MetadataConsts.TOKEN_TYPE_OFFSET)).toInt() + (rule.metadata or (standardToken shl MetadataConsts.TOKEN_TYPE_OFFSET)) } return result } override fun match(languageId: Int, token: String): Int { - return (match(token) or (languageId shl MetadataConsts.LANGUAGEID_OFFSET)).toInt() + return (match(token) or (languageId shl MetadataConsts.LANGUAGEID_OFFSET)) } From 79833ae02d6e619bb7544cc4357ad4cdb96e2546 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Sun, 19 May 2024 05:14:27 +0800 Subject: [PATCH 16/40] feat(lang-monarch): add symbol pair match --- .../sora/langs/monarch/MonarchLanguage.kt | 30 ++- .../langs/monarch/MonarchSymbolPairMatch.kt | 251 ++++++++++++++++++ .../monarch/languageconfiguration/loader.kt | 23 +- .../model/AutoClosingPair.kt | 7 +- 4 files changed, 287 insertions(+), 24 deletions(-) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt index b3b83374d..28de014bc 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt @@ -37,34 +37,41 @@ import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition import io.github.rosemoe.sora.text.CharPosition import io.github.rosemoe.sora.text.ContentReference import io.github.rosemoe.sora.util.MyCharacter +import io.github.rosemoe.sora.widget.SymbolPairMatch class MonarchLanguage( private var grammar: Language, - private var languageConfiguration: LanguageConfiguration?, + internal var languageConfiguration: LanguageConfiguration?, private var grammarRegistry: MonarchGrammarRegistry, private var autoCompleteEnabled: Boolean ) : EmptyLanguage() { - var tabSize = 4 - - var useTab = false private val autoCompleter by lazy(LazyThreadSafetyMode.NONE) { IdentifierAutoComplete() } + private var monarchAnalyzer: MonarchAnalyzer? = null + + private val symbolPairMatch by lazy(LazyThreadSafetyMode.NONE) { + MonarchSymbolPairMatch(this) + } + internal var createIdentifiers = false - private var monarchAnalyzer: MonarchAnalyzer? = null + var tabSize = 4 + + var useTab = false + + // var newlineHandlers: Array + init { createAnalyzerAndNewlineHandler(grammar, languageConfiguration) } - - /* - var newlineHandlers: Array - - var symbolPairMatch: TextMateSymbolPairMatch? = null*/ + override fun getSymbolPairs(): SymbolPairMatch { + return symbolPairMatch + } override fun getAnalyzeManager(): AnalyzeManager { return monarchAnalyzer ?: EmptyAnalyzeManager.INSTANCE @@ -72,9 +79,6 @@ class MonarchLanguage( override fun useTab() = useTab - override fun destroy() { - super.destroy() - } override fun requireAutoComplete( content: ContentReference, diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt new file mode 100644 index 000000000..02169de7f --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt @@ -0,0 +1,251 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch + +import io.github.dingyi222666.monarch.types.StandardTokenType +import io.github.rosemoe.sora.lang.styling.Span +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.AutoClosingPairConditional +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration +import io.github.rosemoe.sora.text.Content +import io.github.rosemoe.sora.text.ContentLine +import io.github.rosemoe.sora.widget.CodeEditor +import io.github.rosemoe.sora.widget.SymbolPairMatch +import java.util.Arrays +import java.util.Locale + +class MonarchSymbolPairMatch( + private val language: MonarchLanguage, +) : SymbolPairMatch(DefaultSymbolPairs()) { + + + var enabled = true + set(value) { + if (!value) { + removeAllPairs() + } else { + updatePair() + } + field = value + } + + init { + updatePair() + } + + + fun updatePair() { + if (!enabled) { + return + } + + val languageConfiguration: LanguageConfiguration = + language.languageConfiguration + ?: return + + removeAllPairs() + + val surroundingPairs = + languageConfiguration.surroundingPairs ?: emptyList() + + val autoClosingPairs: List = + languageConfiguration.autoClosingPairs ?: emptyList() + + val mergePairs = + mutableListOf() + + mergePairs.addAll(autoClosingPairs) + + + + for (surroundingPair in surroundingPairs) { + + val originAutoClosingPair = mergePairs.find { + it.open == surroundingPair.open && it.close == surroundingPair.close + } + + val surroundingPairNotInList = if (surroundingPair is AutoClosingPairConditional) { + surroundingPair.notIn + } else emptyList() + + + if (originAutoClosingPair == null) { + mergePairs.add( + AutoClosingPairConditional( + surroundingPair.open, + surroundingPair.close, + surroundingPairNotInList, + true + ) + ) + continue + } + + + mergePairs.remove(originAutoClosingPair) + mergePairs.add( + AutoClosingPairConditional( + surroundingPair.open, + surroundingPair.close, + (surroundingPairNotInList + originAutoClosingPair.notIn).distinct(), + true + ) + ) + + + mergePairs.forEach { + putPair( + it.open, + SymbolPair( + it.open, + it.close, + SymbolPairEx(it) + ) + ) + } + + + } + } + + class SymbolPairEx( + autoClosingPairConditional: AutoClosingPairConditional + ) : + SymbolPair.SymbolPairEx { + + private var excludeTokenTypesArray: IntArray? = null + + private var isSurroundingPair = autoClosingPairConditional.isSurroundingPair + + init { + run { + val excludeTokenTypeList = autoClosingPairConditional.notIn.toMutableList() + + if (excludeTokenTypeList.isEmpty()) { + excludeTokenTypesArray = null + } + + val excludeTokenTypesArray = IntArray(excludeTokenTypeList.size) + + for (i in excludeTokenTypesArray.indices) { + val excludeTokenName = + excludeTokenTypeList[i].lowercase(Locale.getDefault()) + + var excludeTokenType = StandardTokenType.String + + when (excludeTokenName) { + "comment" -> excludeTokenType = StandardTokenType.Comment + "regex" -> excludeTokenType = StandardTokenType.RegEx + } + excludeTokenTypesArray[i] = excludeTokenType + } + + Arrays.sort(excludeTokenTypesArray) + + this.excludeTokenTypesArray = excludeTokenTypesArray + } + } + + override fun shouldReplace( + editor: CodeEditor, + contentLine: ContentLine?, + leftColumn: Int + ): Boolean { + if (editor.cursor.isSelected) { + return isSurroundingPair + } + + val excludedTokenTypes = excludeTokenTypesArray ?: return true + + val cursor = editor.cursor + + val currentLine = cursor.leftLine + val currentColumn = cursor.leftColumn + + val spansOnCurrentLine = editor.getSpansForLine(currentLine) + + val currentSpan = binarySearchSpan(spansOnCurrentLine, currentColumn) + val extra = currentSpan?.extra + + + if (extra is Int) { + val index = Arrays.binarySearch( + excludedTokenTypes, + extra + ) + return index < 0 + } + + return true + } + + private fun checkIndex(index: Int, max: Int): Int { + return index.coerceIn(0, max) + } + + private fun binarySearchSpan(spanList: List, column: Int): Span? { + var left = 0 + var right = spanList.size - 1 + val size = spanList.size - 1 + + while (left <= right) { + val middle = (left + right) / 2 + + val currentSpan = spanList[middle] + + if (currentSpan.column == column) { + return currentSpan + } + + val nextIndex = checkIndex(middle + 1, right) + val nextSpan = if (nextIndex <= right) spanList[nextIndex] else null + if (nextSpan != null && nextSpan.column > column) { + return currentSpan + } + + // if (currentSpan.column > column) + val lastSpan = spanList[checkIndex(middle - 1, size)] + + if (lastSpan.column < column) { + return currentSpan + } + + if (currentSpan.column < column) { + left = middle + 1 + } else { + right = middle - 1 + } + } + + return null + } + + + override fun shouldDoAutoSurround(content: Content): Boolean { + return isSurroundingPair && content.cursor.isSelected + } + } + + +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt index 4c2c896e7..bdc76f2bf 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt @@ -41,7 +41,6 @@ import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.IndentAc import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.IndentationRule import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.OnEnterRule -import java.util.Locale import kotlin.properties.Delegates class LanguageConfigurationAdapter : JsonAdapter() { @@ -141,7 +140,7 @@ class LanguageConfigurationAdapter : JsonAdapter() { val list = mutableListOf() while (reader.hasNext()) { - val pair = readAutoClosingPairConditional(reader) + val pair = readAutoClosingPairConditional(reader, false) list.add(pair) } @@ -345,7 +344,7 @@ class LanguageConfigurationAdapter : JsonAdapter() { val list = mutableListOf() while (reader.hasNext()) { - list.add(readAutoClosingPair(reader)) + list.add(readAutoClosingPair(reader, true)) } reader.endArray() @@ -353,9 +352,12 @@ class LanguageConfigurationAdapter : JsonAdapter() { return list } - private fun readAutoClosingPair(reader: JsonReader): BaseAutoClosingPair { + private fun readAutoClosingPair( + reader: JsonReader, + isSurroundingPair: Boolean + ): BaseAutoClosingPair { if (reader.peek() == JsonReader.Token.BEGIN_OBJECT) { - return readAutoClosingPairConditional(reader) + return readAutoClosingPairConditional(reader, isSurroundingPair) } reader.beginArray() @@ -365,15 +367,18 @@ class LanguageConfigurationAdapter : JsonAdapter() { if (reader.hasNext()) { val notIn = readStringArray(reader) - return AutoClosingPairConditional(open, close, notIn) + return AutoClosingPairConditional(open, close, notIn, isSurroundingPair) } reader.endArray() - return AutoClosingPair(open, close) + return AutoClosingPair(open, close, isSurroundingPair) } - private fun readAutoClosingPairConditional(reader: JsonReader): AutoClosingPairConditional { + private fun readAutoClosingPairConditional( + reader: JsonReader, + isSurroundingPair: Boolean + ): AutoClosingPairConditional { reader.beginObject() var open by Delegates.notNull() @@ -398,7 +403,7 @@ class LanguageConfigurationAdapter : JsonAdapter() { reader.endObject() - return AutoClosingPairConditional(open, close, notIn ?: emptyList()) + return AutoClosingPairConditional(open, close, notIn ?: emptyList(), isSurroundingPair) } private fun readStringArray(reader: JsonReader): List { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt index be7682334..436e1eee8 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt @@ -27,15 +27,18 @@ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model interface BaseAutoClosingPair { val open: String val close: String + val isSurroundingPair: Boolean } data class AutoClosingPair( override val open: String, - override val close: String + override val close: String, + override val isSurroundingPair: Boolean = false ): BaseAutoClosingPair data class AutoClosingPairConditional( override val open: String, override val close: String, - val notIn: List + val notIn: List, + override val isSurroundingPair: Boolean = false ): BaseAutoClosingPair \ No newline at end of file From b24fc1a00989162a13c1cec5f5c885bf1efed703 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Mon, 20 May 2024 20:26:06 +0800 Subject: [PATCH 17/40] feat(lang-monarch): base on enter support --- .../sora/langs/monarch/MonarchLanguage.kt | 4 +- .../langs/monarch/MonarchSymbolPairMatch.kt | 1 - .../support/OnEnterSupport.kt | 90 +++++++++++++++++++ .../sora/langs/monarch/utils/string.kt | 20 +++++ 4 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt index 28de014bc..edbf3a58c 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt @@ -122,13 +122,13 @@ class MonarchLanguage( } this.languageConfiguration = languageConfiguration /*newlineHandler = TextMateNewlineHandler(this) - newlineHandlers = arrayOf(newlineHandler) + newlineHandlers = arrayOf(newlineHandler) */ if (languageConfiguration != null) { // because the editor will only get the symbol pair matcher once // (caching object to stop repeated new object created), // the symbol pair needs to be updated inside the symbol pair matcher. symbolPairMatch.updatePair() - }*/ + } } companion object { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt index 02169de7f..49bf18bf8 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt @@ -78,7 +78,6 @@ class MonarchSymbolPairMatch( mergePairs.addAll(autoClosingPairs) - for (surroundingPair in surroundingPairs) { val originAutoClosingPair = mergePairs.find { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt new file mode 100644 index 000000000..d10aa90d5 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt @@ -0,0 +1,90 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.languageconfiguration.support + +import io.github.dingyi222666.regex.Regex +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.CharacterPair +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.OnEnterRule + +// See https://github.com/microsoft/vscode/blob/aa31bfc9fd1746626b3efe86f41b9c172d5f4d23/src/vs/editor/common/languages/supports/onEnter.ts# + +data class OnEnterSupportOptions( + val brackets: List?, + val onEnterRules: List? +) + +data class ProcessedBracketPair( + val open: String, + val close: String, + val openRegExp: Regex, + val closeRegExp: Regex +) + +class OnEnterSupport( + options: OnEnterSupportOptions +) { + + private val brackets: List + private val regExpRules: List + + init { + val brackets = options.brackets ?: listOf( + CharacterPair("(", ")"), + CharacterPair("[", "]"), + CharacterPair("{", "}") + ) + + val processedBracketPairs = mutableListOf() + + brackets.forEach { + val openRegExp = createOpenBracketRegExp(it.first) + val closeRegExp = createCloseBracketRegExp(it.second) + if (openRegExp != null && closeRegExp != null) { + processedBracketPairs.add( + ProcessedBracketPair( + it.first, + it.second, + openRegExp, + closeRegExp + ) + ) + } + } + + + this.brackets = processedBracketPairs + this.regExpRules = options.onEnterRules ?: emptyList() + } + + companion object { + private fun createOpenBracketRegExp(bracket: String): Regex? { + TODO("") + } + + private fun createCloseBracketRegExp(bracket: String): Regex? { + TODO("") + } + } +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt index c8951700f..226ab6cd3 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt @@ -24,6 +24,8 @@ package io.github.rosemoe.sora.langs.monarch.utils +import io.github.dingyi222666.regex.Regex + fun String.checkSurrogate(): Boolean { for (element in this) { if (Character.isSurrogate(element)) { @@ -61,3 +63,21 @@ fun String.convertUnicodeOffsetToUtf16(offset: Int, isSurrogatePairConsidered: B return offset } + +fun Regex.matchesFully(text: String): Boolean { + val result = search(text, 0) ?: return false + return result.count == 1 && result.value.length == text.length +} + +fun Regex.matchesPartially(text: String): Boolean { + return search(text, 0) != null +} + +inline fun String.matchesFully(regex:Regex): Boolean { + return regex.matchesFully(this) +} + +inline fun String.matchesPartially(regex: Regex): Boolean { + return regex.matchesPartially(this) +} + From a7646310d4a4343dd8aa6803a378f47d68c892e9 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Wed, 22 May 2024 19:48:44 +0800 Subject: [PATCH 18/40] feat(lang-monarch): finish onEnterSupport --- .../support/OnEnterSupport.kt | 81 ++++++++++++++++++- .../sora/langs/monarch/utils/string.kt | 12 ++- 2 files changed, 90 insertions(+), 3 deletions(-) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt index d10aa90d5..76250a685 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt @@ -24,9 +24,15 @@ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.support +import io.github.dingyi222666.regex.GlobalRegexLib import io.github.dingyi222666.regex.Regex import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.CharacterPair +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.EnterAction +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.IndentAction import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.OnEnterRule +import io.github.rosemoe.sora.langs.monarch.utils.escapeRegExpCharacters +import io.github.rosemoe.sora.langs.monarch.utils.matchesPartially +import java.util.regex.Pattern // See https://github.com/microsoft/vscode/blob/aa31bfc9fd1746626b3efe86f41b9c172d5f4d23/src/vs/editor/common/languages/supports/onEnter.ts# @@ -78,13 +84,84 @@ class OnEnterSupport( this.regExpRules = options.onEnterRules ?: emptyList() } + fun onEnter( + // TODO autoIndent: EditorAutoIndentStrategy, + previousLineText: String?, + beforeEnterText: String, + afterEnterText: String + ): EnterAction? { + // (1): `regExpRules` + // if (autoIndent >= EditorAutoIndentStrategy.Advanced) { + for ((beforeText, afterTextPattern, previousLinePattern, action) in regExpRules) { + if (!beforeText.matchesPartially(beforeEnterText)) continue + + if (afterTextPattern != null && !afterTextPattern.matchesPartially(afterEnterText)) continue + + if (previousLinePattern != null && !previousLinePattern.matchesPartially( + previousLineText ?: "" + ) + ) continue + + return action + } + + // (2): Special indent-outdent + // if (autoIndent >= EditorAutoIndentStrategy.Brackets) { + if (beforeEnterText.isNotEmpty() && afterEnterText.isNotEmpty()) { + for (bracket in brackets) { + if (bracket.openRegExp.matches(beforeEnterText) && bracket.closeRegExp.matches( + afterEnterText + ) + ) { + return EnterAction(indentAction = IndentAction.IndentOutdent) + } + } + } + + // (3): Open bracket based logic + // if (autoIndent >= EditorAutoIndentStrategy.Brackets) { + if (beforeEnterText.isNotEmpty()) { + for (bracket in brackets) { + if (bracket.openRegExp.matches(beforeEnterText)) { + return EnterAction(IndentAction.Indent) + } + } + } + + return null + } + companion object { + + // native pattern is faster that the regexp pattern + val B_REGEXP = Pattern.compile("\\B") //$NON-NLS-1$ + private fun createOpenBracketRegExp(bracket: String): Regex? { - TODO("") + val string = StringBuilder(bracket.escapeRegExpCharacters()) + val firstChar = string.first().toString() + if (!B_REGEXP.matcher( + firstChar + ).find() + ) { + string.insert(0, "\\b") //$NON-NLS-1$ + } + string.append("\\s*$") //$NON-NLS-1$ + return GlobalRegexLib.compile(string) } private fun createCloseBracketRegExp(bracket: String): Regex? { - TODO("") + val string = StringBuilder(bracket.escapeRegExpCharacters()) + val firstChar = string.last().toString() + if (!B_REGEXP.matcher( + firstChar + ).find() + ) { + string.insert(0, "\\b") //$NON-NLS-1$ + } + string.append("\\s*$") //$NON-NLS-1$ + return GlobalRegexLib.compile(string) } + + } } \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt index 226ab6cd3..eb792ceeb 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt @@ -73,7 +73,7 @@ fun Regex.matchesPartially(text: String): Boolean { return search(text, 0) != null } -inline fun String.matchesFully(regex:Regex): Boolean { +inline fun String.matchesFully(regex: Regex): Boolean { return regex.matchesFully(this) } @@ -81,3 +81,13 @@ inline fun String.matchesPartially(regex: Regex): Boolean { return regex.matchesPartially(this) } +/** + * Escapes regular expression characters in a given string + */ +fun String.escapeRegExpCharacters(): String { + return replace( + "[\\-\\\\\\{\\}\\*\\+\\?\\|\\^\\$\\.\\[\\]\\(\\)\\#]".toRegex(), + "\\\\$0" + ) //$NON-NLS-1$ //$NON-NLS-2$ +} + From 651d3a2060872e273d5b97eba65b978c4a392f7f Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Wed, 22 May 2024 19:57:22 +0800 Subject: [PATCH 19/40] feat(lang-monarch): finish indentRulesSupport --- .../support/IndentRulesSupport.kt | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/IndentRulesSupport.kt diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/IndentRulesSupport.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/IndentRulesSupport.kt new file mode 100644 index 000000000..ea174351d --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/IndentRulesSupport.kt @@ -0,0 +1,77 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.languageconfiguration.support + +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.IndentationRule +import io.github.rosemoe.sora.langs.monarch.utils.matchesFully + +class IndentRulesSupport( + private val indentationRules: IndentationRule +) { + + fun shouldIncrease(text: String): Boolean { + return indentationRules.increaseIndentPattern.matchesFully(text) + } + + fun shouldDecrease(text: String): Boolean { + return indentationRules.decreaseIndentPattern.matchesFully(text) + } + + fun shouldIndentNextLine(text: String): Boolean { + return indentationRules.indentNextLinePattern?.matchesFully(text) ?: false + } + + + fun shouldIgnore(text: String): Boolean { + return indentationRules.unIndentedLinePattern?.matchesFully(text) ?: false + } + + fun getIndentMetadata(text: String): Int { + var ret = 0 + if (shouldIncrease(text)) { + ret = ret or IndentConsts.INCREASE_MASK + } + if (shouldDecrease(text)) { + ret = ret or IndentConsts.DECREASE_MASK + } + if (shouldIndentNextLine(text)) { + ret = ret or IndentConsts.INDENT_NEXTLINE_MASK + } + if (shouldIgnore(text)) { + ret = ret or IndentConsts.UNINDENT_MASK + } + return ret + } + + object IndentConsts { + const val INCREASE_MASK = 1 + const val DECREASE_MASK = 2 + const val INDENT_NEXTLINE_MASK = 4 + const val UNINDENT_MASK = 8 + + } + + +} \ No newline at end of file From 437be693d51730011886af0429e65138fccb2467 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Fri, 7 Jun 2024 11:43:59 +0800 Subject: [PATCH 20/40] feat(lang-monarch): finish `MonarchNewlineHandler` support --- .../sora/langs/monarch/MonarchLanguage.kt | 18 +- .../langs/monarch/MonarchNewlineHandler.kt | 520 ++++++++++++++++++ .../model/CompleteEnterAction.kt | 4 +- .../support/OnEnterSupport.kt | 11 +- .../sora/langs/monarch/utils/string.kt | 129 +++++ .../textmate/TextMateNewlineHandler.java | 4 +- 6 files changed, 670 insertions(+), 16 deletions(-) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt index edbf3a58c..e83a6f78e 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt @@ -31,6 +31,7 @@ import io.github.rosemoe.sora.lang.analysis.AnalyzeManager import io.github.rosemoe.sora.lang.completion.CompletionHelper import io.github.rosemoe.sora.lang.completion.CompletionPublisher import io.github.rosemoe.sora.lang.completion.IdentifierAutoComplete +import io.github.rosemoe.sora.lang.smartEnter.NewlineHandler import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration import io.github.rosemoe.sora.langs.monarch.registery.MonarchGrammarRegistry import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition @@ -46,7 +47,7 @@ class MonarchLanguage( private var autoCompleteEnabled: Boolean ) : EmptyLanguage() { - private val autoCompleter by lazy(LazyThreadSafetyMode.NONE) { + val autoCompleter by lazy(LazyThreadSafetyMode.NONE) { IdentifierAutoComplete() } @@ -62,7 +63,8 @@ class MonarchLanguage( var useTab = false - // var newlineHandlers: Array + internal var newlineHandlers: Array? = emptyArray() + internal lateinit var newlineHandler: MonarchNewlineHandler init { @@ -92,12 +94,16 @@ class MonarchLanguage( } val prefix = CompletionHelper.computePrefix( content, position - ) { key: Char -> MyCharacter.isJavaIdentifierPart(key) } + ) { key -> MyCharacter.isJavaIdentifierPart(key) } val idt = monarchAnalyzer.syncIdentifiers autoCompleter.requireAutoComplete(content, position, prefix, publisher, idt) } - fun setCompleterKeywords(keywords: Array?) { + override fun getNewlineHandlers(): Array? = + newlineHandlers ?: super.getNewlineHandlers() + + + fun setCompleterKeywords(keywords: Array) { autoCompleter.setKeywords(keywords, false) } @@ -121,8 +127,8 @@ class MonarchLanguage( e.printStackTrace() } this.languageConfiguration = languageConfiguration - /*newlineHandler = TextMateNewlineHandler(this) - newlineHandlers = arrayOf(newlineHandler) */ + newlineHandler = MonarchNewlineHandler(this) + newlineHandlers = arrayOf(newlineHandler) if (languageConfiguration != null) { // because the editor will only get the symbol pair matcher once // (caching object to stop repeated new object created), diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt new file mode 100644 index 000000000..fffecc90b --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt @@ -0,0 +1,520 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch + +import io.github.rosemoe.sora.lang.smartEnter.NewlineHandleResult +import io.github.rosemoe.sora.lang.smartEnter.NewlineHandler +import io.github.rosemoe.sora.lang.styling.Styles +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.CompleteEnterAction +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.EnterAction +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.IndentAction +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.IndentAction.Indent +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.IndentAction.IndentOutdent +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.IndentAction.None +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.IndentAction.Outdent +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.support.IndentRulesSupport +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.support.OnEnterSupport +import io.github.rosemoe.sora.langs.monarch.utils.getIndentationFromWhitespace +import io.github.rosemoe.sora.langs.monarch.utils.getLeadingWhitespace +import io.github.rosemoe.sora.langs.monarch.utils.getLinePrefixingWhitespaceAtPosition +import io.github.rosemoe.sora.langs.monarch.utils.normalizeIndentation +import io.github.rosemoe.sora.langs.monarch.utils.outdentString +import io.github.rosemoe.sora.text.CharPosition +import io.github.rosemoe.sora.text.Content +import kotlin.math.max + + +class MonarchNewlineHandler( + private val language: MonarchLanguage +) : NewlineHandler { + + private lateinit var enterSupport: OnEnterSupport + private lateinit var indentRulesSupport: IndentRulesSupport + + private var enterAction: CompleteEnterAction? = null + private var indentForEnter: Pair? = null + + private var isEnabled = true + + init { + val languageConfiguration = language.languageConfiguration + + run { + if (languageConfiguration == null) { + return@run + } + + val enterRules = + languageConfiguration.onEnterRules + val brackets = languageConfiguration.brackets + + val indentationsRules = languageConfiguration.indentationRules + if (enterRules != null) { + enterSupport = + OnEnterSupport( + brackets, + enterRules + ) + } + + if (indentationsRules != null) { + indentRulesSupport = IndentRulesSupport( + indentationsRules + ) + } + + } + } + + override fun matchesRequirement( + text: Content, + position: CharPosition, + style: Styles? + ): Boolean { + if (!isEnabled) { + return false + } + + enterAction = getEnterAction(text, position) + + indentForEnter = null + + if (enterAction == null) { + indentForEnter = getIndentForEnter(text, position) + } + + return enterAction != null || indentForEnter != null + } + + fun getIndentForEnter(text: Content, position: CharPosition): Pair? { + // https://github.com/microsoft/vscode/blob/bf63ea1932dd253745f38a4cbe26bb9be01801b1/src/vs/editor/common/languages/autoIndent.ts#L278 + + val currentLineText = text.getLineString(position.line) + + val beforeEnterText = currentLineText.substring(0, position.column) + + val afterEnterText = currentLineText.substring(position.column) + + + val beforeEnterIndent = + beforeEnterText.getLeadingWhitespace(0, beforeEnterText.length) + + val afterEnterAction = + getInheritIndentForLine( + WrapperContent(text, position.line, beforeEnterText), + true, + position.line + 1 + ) ?: return beforeEnterIndent to beforeEnterIndent + + + var afterEnterIndent = afterEnterAction.indentation + var indent = "" + + indent = if (language.useTab()) { + " ".repeat(language.tabSize) + } else { + "\t" + } + + + //var firstNonScapeIndex = TextUtils.firstNonWhitespaceIndex(beforeEnterIndent); + if (afterEnterAction.action == IndentAction.Indent) { + // afterEnterIndent = indentConverter.shiftIndent(afterEnterIndent) + + //var invisibleColumn = TextUtils.invisibleColumnFromColumn(text, position.line, position.column, tabSpaces); + + afterEnterIndent = beforeEnterIndent.toString() + indent + } + + if (indentRulesSupport.shouldDecrease(afterEnterText)) { + // afterEnterIndent = indentConverter.unshiftIndent(afterEnterIndent); + + afterEnterIndent = beforeEnterIndent.substring( + 0, + max( + 0.coerceAtLeast(beforeEnterIndent.length - 1), + beforeEnterIndent.length - indent.length /*- 1*/ + ) + ) + } + + return beforeEnterIndent to afterEnterIndent + } + + + override fun handleNewline( + text: Content, + position: CharPosition, + style: Styles?, + tabSize: Int + ): NewlineHandleResult { + + // https://github.com/microsoft/vscode/blob/bf63ea1932dd253745f38a4cbe26bb9be01801b1/src/vs/editor/common/cursor/cursorTypeOperations.ts#L309 + val delim = "\n" /*command.text;*/ + + + indentForEnter?.let { + val normalIndent = it.second.normalizeIndentation() + val typeText = delim + normalIndent + + //var caretOffset = normalIndent.length() ; + return NewlineHandleResult(typeText, 0) + } + + val enterAction = enterAction ?: return NewlineHandleResult("", 0) + + + when (enterAction.indentAction) { + None, Indent -> { + // Nothing special + val increasedIndent = + (enterAction.indentation + enterAction.appendText).normalizeIndentation() + val typeText = delim + increasedIndent + + // var caretOffset = typeText.length(); + // offset value is not needed because the editor ignores the position of invisible characters when moving the cursor + return NewlineHandleResult(typeText, 0) + } // Indent once + IndentOutdent -> { + // Ultra special + val normalIndent = enterAction.indentation.normalizeIndentation() + val increasedIndent = + (enterAction.indentation + enterAction.appendText).normalizeIndentation() + val typeText = delim + increasedIndent + delim + normalIndent + + val caretOffset = normalIndent.length + 1 + return NewlineHandleResult(typeText, caretOffset) + } + + Outdent -> { + val indentation = enterAction.indentation.getIndentationFromWhitespace( + language.tabSize, + language.useTab() + ) + val outdentedText = (indentation + enterAction.appendText).normalizeIndentation() + .outdentString(language.useTab(), language.tabSize) + + val caretOffset = outdentedText.length + 1 + return NewlineHandleResult(outdentedText, caretOffset) + } + } + + return NewlineHandleResult("", 0) + } + + + /** + * @see [ + * https://github.com/microsoft/vscode/blob/main/src/vs/editor/common/languages/enterAction.ts](https://github.com/microsoft/vscode/blob/main/src/vs/editor/common/languages/enterAction.ts) + */ + fun getEnterAction(content: Content, position: CharPosition): CompleteEnterAction? { + var indentation = content.getLinePrefixingWhitespaceAtPosition(position) + // let scopedLineTokens = this.getScopedLineTokens(model, range.startLineNumber, range.startColumn); + val onEnterSupport = this.enterSupport + ?: return null + + + val scopedLineText = content.getLineString(position.line) + + + val beforeEnterText = scopedLineText.substring( + 0, + position.column /*- 0*/ /*scopedLineTokens.firstCharOffset*/ + ) + + + // String afterEnterText = null; + + // selection support + // if (range.isEmpty()) { + val afterEnterText = + scopedLineText.substring(position.column /*- scopedLineTokens.firstCharOffset*/) + + // afterEnterText = scopedLineText.substr(range.startColumn - 1 - scopedLineTokens.firstCharOffset); + // } else { + // const endScopedLineTokens = this.getScopedLineTokens(model, + // range.endLineNumber, range.endColumn); + // afterEnterText = endScopedLineTokens.getLineContent().substr(range.endColumn - 1 - + // scopedLineTokens.firstCharOffset); + // } + + /* + * let lineNumber = range.startLineNumber; let oneLineAboveText = ''; + * + * if (lineNumber > 1 && scopedLineTokens.firstCharOffset === 0) { // This is + * not the first line and the entire line belongs to this mode let + * oneLineAboveScopedLineTokens = this.getScopedLineTokens(model, lineNumber - + * 1); if (oneLineAboveScopedLineTokens.languageId === + * scopedLineTokens.languageId) { // The line above ends with text belonging to + * the same mode oneLineAboveText = + * oneLineAboveScopedLineTokens.getLineContent(); } } + */ + + /* + let previousLineText = ''; + if (range.startLineNumber > 1 && scopedLineTokens.firstCharOffset === 0) { + // This is not the first line and the entire line belongs to this mode + const oneLineAboveScopedLineTokens = getScopedLineTokens(model, range.startLineNumber - 1); + if (oneLineAboveScopedLineTokens.languageId === scopedLineTokens.languageId) { + // The line above ends with text belonging to the same mode + previousLineText = oneLineAboveScopedLineTokens.getLineContent(); + } + } */ + var previousLineText: String? = "" + + if (position.line > 1 /*|| position.column == 0*/) { + // This is not the first line and the entire line belongs to this mode + // The line above ends with text belonging to the same mode + previousLineText = content.getLineString(position.line - 1) + } + + var enterResult: EnterAction? = null + try { + enterResult = onEnterSupport.onEnter(previousLineText, beforeEnterText, afterEnterText) + } catch (e: Exception) { + e.printStackTrace() + // onUnexpectedError(e); + } + + if (enterResult == null) { + return null + } + + val indentAction = enterResult.indentAction + var appendText = enterResult.appendText + val removeText = enterResult.removeText + // Here we add `\t` to appendText first because enterAction is leveraging + // appendText and removeText to change indentation. + + if (appendText == null) { + appendText = if (indentAction == IndentAction.Indent + || indentAction == IndentOutdent + ) { + "\t" + } else { + "" + } + } else if (indentAction == IndentAction.Indent) { + appendText = "\t" + appendText + } + + if (removeText != null) { + indentation = indentation.substring(0, indentation.length - removeText) + } + + return CompleteEnterAction( + indentAction, appendText, + removeText, indentation + ) + } + + /** + * Get nearest preceding line which doesn't match unIndentPattern or contains all whitespace. + * Result: + * -1: run into the boundary of embedded languages + * 0: every line above are invalid + * else: nearest preceding line of the same language + */ + fun getPrecedingValidLine(content: WrapperContent, lineNumber: Int): Int { + // remove embeddedLanguages support + // const languageId = model.tokenization.getLanguageIdAtPosition(lineNumber, 0); + if (lineNumber > 0) { + for (lastLineNumber in lineNumber - 1 downTo 0) { + val lineContent = content.getLineContent(lastLineNumber); + if (indentRulesSupport.shouldIgnore(lineContent) || precedingValidPattern.matches( + lineContent + ) || lineContent.isEmpty() + ) { + continue; + } + return lastLineNumber + } + + } + + return -1 + } + + /** + * Get inherited indentation from above lines. + * 1. Find the nearest preceding line which doesn't match unIndentedLinePattern. + * 2. If this line matches indentNextLinePattern or increaseIndentPattern, it means that the indent level of `lineNumber` should be 1 greater than this line. + * 3. If this line doesn't match any indent rules + * a. check whether the line above it matches indentNextLinePattern + * b. If not, the indent level of this line is the result + * c. If so, it means the indent of this line is *temporary*, go upward utill we find a line whose indent is not temporary (the same workflow a -> b -> c). + * 4. Otherwise, we fail to get an inherited indent from aboves. Return null and we should not touch the indent of `lineNumber` + *

+ * This function only return the inherited indent based on above lines, it doesn't check whether current line should decrease or not. + */ + + private fun getInheritIndentForLine( + model: WrapperContent, + honorIntentialIndent: Boolean, line: Int + ): InheritIndentResult? { + // https://github.com/microsoft/vscode/blob/bf63ea1932dd253745f38a4cbe26bb9be01801b1/src/vs/editor/common/languages/autoIndent.ts#L73 + + if (line < 1) { + return InheritIndentResult("", 0) + } + + val precedingUnIgnoredLine = getPrecedingValidLine(model, line) + + if (precedingUnIgnoredLine < 0) { + return null + } else if (precedingUnIgnoredLine < 1) { + return InheritIndentResult("", 0) + } + + val precedingUnIgnoredLineContent = model.getLineContent(precedingUnIgnoredLine) + + if (indentRulesSupport.shouldIncrease(precedingUnIgnoredLineContent) || indentRulesSupport.shouldIndentNextLine( + precedingUnIgnoredLineContent + ) + ) { + return InheritIndentResult( + precedingUnIgnoredLineContent.getLeadingWhitespace(), + IndentAction.Indent, + precedingUnIgnoredLine + ) + } else if (indentRulesSupport.shouldDecrease(precedingUnIgnoredLineContent)) { + return InheritIndentResult( + precedingUnIgnoredLineContent.getLeadingWhitespace(), + IndentAction.None, + precedingUnIgnoredLine + ) + } else { + // precedingUnIgnoredLine can not be ignored. + // it doesn't increase indent of following lines + // it doesn't increase just next line + // so current line is not affect by precedingUnIgnoredLine + // and then we should get a correct inheritted indentation from above lines + if (precedingUnIgnoredLine == 0) { + return InheritIndentResult( + precedingUnIgnoredLineContent.getLeadingWhitespace(), + IndentAction.None, + precedingUnIgnoredLine + ) + } + + + val previousLine = precedingUnIgnoredLine - 1; + + val previousLineIndentMetadata = + indentRulesSupport.getIndentMetadata(model.getLineContent(previousLine)); + + if (((previousLineIndentMetadata and (IndentRulesSupport.IndentConsts.INCREASE_MASK or IndentRulesSupport.IndentConsts.DECREASE_MASK)) === 0) && ((previousLineIndentMetadata and IndentRulesSupport.IndentConsts.INDENT_NEXTLINE_MASK) === 0) && (previousLineIndentMetadata > 0)) { + + var stopLine = 0 + for (i in previousLine - 1 downTo 1) { + if (indentRulesSupport.shouldIndentNextLine(model.getLineContent((i)))) { + continue + } + stopLine = i + break + } + + return InheritIndentResult( + model.getLineContent( + stopLine + 1 + ).getLeadingWhitespace(), IndentAction.None, stopLine + 1 + ) + + } + + + // search from precedingUnIgnoredLine until we find one whose indent is not temporary + for (i in precedingUnIgnoredLine downTo 1) { + val lineContent = model.getLineContent(i) + if (indentRulesSupport.shouldIncrease(lineContent)) { + return InheritIndentResult( + lineContent.getLeadingWhitespace(), + IndentAction.Indent, + i + ) + } else if (indentRulesSupport.shouldIndentNextLine(lineContent)) { + var stopLine = 0 + for (j in i - 1 downTo 1) { + if (indentRulesSupport.shouldIndentNextLine(model.getLineContent(i))) { + continue + } + stopLine = j + break + } + + + return InheritIndentResult( + + model.getLineContent( + stopLine + 1 + ).getLeadingWhitespace(), IndentAction.None, stopLine + 1 + ) + } else if (indentRulesSupport.shouldDecrease(lineContent)) { + return InheritIndentResult( + lineContent.getLeadingWhitespace(), + IndentAction.None, + i + ) + } + } + + return InheritIndentResult( + model.getLineContent( + 1 + ).getLeadingWhitespace(), IndentAction.None, 1 + ) + + } + } + + + private fun String.normalizeIndentation(): String { + return this.normalizeIndentation(language.tabSize, !language.useTab()) + } + + data class InheritIndentResult( + var indentation: String, + var action: Int = IndentAction.None, + var line: Int = 0 + ) + + class WrapperContent( + private val origin: Content, + private val line: Int, + private val currentLineContent: String + ) { + fun getLineContent(line: Int): String { + return if (line == this.line) { + currentLineContent + } else { + origin.getLineString(line) + } + } + } + + companion object { + private val precedingValidPattern = Regex("^\\s+$") + } +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CompleteEnterAction.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CompleteEnterAction.kt index 3d1de5ae3..79ecb8681 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CompleteEnterAction.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CompleteEnterAction.kt @@ -28,7 +28,7 @@ data class CompleteEnterAction( /** * Describe what to do with the indentation. */ - val indentAction: IndentAction, + val indentAction: Int, /** * Describes text to be appended after the new line and after the indentation. */ @@ -36,7 +36,7 @@ data class CompleteEnterAction( /** * Describes the number of characters to remove from the new line's indentation. */ - val removeText: Int, + val removeText: Int?, /** * The line's indentation minus removeText */ diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt index 76250a685..20d9d7ec8 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt @@ -36,10 +36,6 @@ import java.util.regex.Pattern // See https://github.com/microsoft/vscode/blob/aa31bfc9fd1746626b3efe86f41b9c172d5f4d23/src/vs/editor/common/languages/supports/onEnter.ts# -data class OnEnterSupportOptions( - val brackets: List?, - val onEnterRules: List? -) data class ProcessedBracketPair( val open: String, @@ -49,14 +45,15 @@ data class ProcessedBracketPair( ) class OnEnterSupport( - options: OnEnterSupportOptions + brackets: List?, + onEnterRules: List? ) { private val brackets: List private val regExpRules: List init { - val brackets = options.brackets ?: listOf( + val brackets = brackets ?: listOf( CharacterPair("(", ")"), CharacterPair("[", "]"), CharacterPair("{", "}") @@ -81,7 +78,7 @@ class OnEnterSupport( this.brackets = processedBracketPairs - this.regExpRules = options.onEnterRules ?: emptyList() + this.regExpRules = onEnterRules ?: emptyList() } fun onEnter( diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt index eb792ceeb..c1fe96e37 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt @@ -25,6 +25,12 @@ package io.github.rosemoe.sora.langs.monarch.utils import io.github.dingyi222666.regex.Regex +import io.github.rosemoe.sora.text.CharPosition +import io.github.rosemoe.sora.text.Content +import io.github.rosemoe.sora.text.TextUtils +import io.github.rosemoe.sora.util.CharCode +import io.github.rosemoe.sora.util.IntPair + fun String.checkSurrogate(): Boolean { for (element in this) { @@ -36,6 +42,129 @@ fun String.checkSurrogate(): Boolean { } +/** + * Returns the leading whitespace of the string. + * If the string contains only whitespaces, returns entire string + */ +fun String.getLeadingWhitespace(start: Int = 0, end: Int = length): String { + for (index in start..end) { + val chCode = this[index].code + if (chCode != CharCode.Space && chCode != CharCode.Tab) { + return substring(start, index) + } + } + return substring(start, end); +} + +/** + * Returns first index of the string that is not whitespace. If string is empty + * or contains only whitespaces, returns -1 + */ +fun String.firstNonWhitespaceIndex(): Int { + var i = 0 + while (i < length) { + val c = this[i] + if (c != ' ' && c != '\t') { + return i + } + i++ + } + return -1 +} + +fun String.normalizeIndentation(tabSize: Int, insertSpaces: Boolean): String { + var firstNonWhitespaceIndex = this.firstNonWhitespaceIndex() + if (firstNonWhitespaceIndex == -1) { + firstNonWhitespaceIndex = length + } + + return substring(0, firstNonWhitespaceIndex).normalizeIndentationFromWhitespace( + tabSize, + insertSpaces + ) + substring(firstNonWhitespaceIndex); +} + +fun String.getIndentationFromWhitespace(tabSize: Int, insertSpaces: Boolean): String { + val tab = "\t" //$NON-NLS-1$ + var indentOffset = 0 + var startsWithTab = true + var startsWithSpaces = true + val spaces = if (insertSpaces + ) " ".repeat(tabSize) + else "" + while (startsWithTab || startsWithSpaces) { + startsWithTab = this.startsWith(tab, indentOffset) + startsWithSpaces = insertSpaces && this.startsWith(spaces, indentOffset) + if (startsWithTab) { + indentOffset += tab.length + } + if (startsWithSpaces) { + indentOffset += spaces.length + } + } + return this.substring(0, indentOffset) +} + +fun String.normalizeIndentationFromWhitespace( + tabSize: Int, + insertSpaces: Boolean +): String { + var spacesCnt = 0 + + for (element in this) { + if (element == '\t') { + spacesCnt += tabSize + } else { + spacesCnt++ + } + } + + val result = StringBuilder() + if (!insertSpaces) { + val tabsCnt = (spacesCnt / tabSize).toLong() + spacesCnt %= tabSize + for (i in 0 until tabsCnt) { + result.append('\t') + } + } + + for (i in 0 until spacesCnt) { + result.append(' ') + } + + return result.toString() +} + +fun Content.getLinePrefixingWhitespaceAtPosition(position: CharPosition): String { + val line = getLine(position.line) + + val startIndex = IntPair.getFirst( + TextUtils.findLeadingAndTrailingWhitespacePos( + line + ) + ) + + return line.subSequence(0, startIndex).toString() +} + + +fun String.outdentString(useTab: Boolean = false, tabSize: Int = 4): String { + if (startsWith("\t")) { // $NON-NLS-1$ + return substring(1) + } + + if (useTab) { + val chars = CharArray(tabSize) { + ' ' + } + val spaces = String(chars) + if (startsWith(spaces)) { + return substring(spaces.length) + } + } + return this +} + fun String.convertUnicodeOffsetToUtf16(offset: Int, isSurrogatePairConsidered: Boolean): Int { if (offset < 0) { throw IllegalArgumentException("Offset cannot be negative.") diff --git a/language-textmate/src/main/java/io/github/rosemoe/sora/langs/textmate/TextMateNewlineHandler.java b/language-textmate/src/main/java/io/github/rosemoe/sora/langs/textmate/TextMateNewlineHandler.java index ce6763511..5909f63c1 100644 --- a/language-textmate/src/main/java/io/github/rosemoe/sora/langs/textmate/TextMateNewlineHandler.java +++ b/language-textmate/src/main/java/io/github/rosemoe/sora/langs/textmate/TextMateNewlineHandler.java @@ -56,11 +56,13 @@ public class TextMateNewlineHandler implements NewlineHandler { private CompleteEnterAction enterAction; + private Pair indentForEnter; + private boolean isEnabled = true; //private static final Pattern precedingValidPattern = Pattern.compile("^\\s+$"); - private Pair indentForEnter; + private LanguageConfiguration languageConfiguration; From 351f257d407ddcd4356c09729fcf4a74d5c00e59 Mon Sep 17 00:00:00 2001 From: dingyi222666 Date: Thu, 13 Jun 2024 12:00:28 +0800 Subject: [PATCH 21/40] feat(lang-monarch): finish `GrammarDefinitionReader` --- .../registery/dsl/GrammarDefinitionDSL.kt | 2 +- .../dsl/MonarchGrammarDefinitionDSL.kt | 77 ++++++++++++ .../GrammarDefinitionReader.kt | 110 ++++++++++++++++++ .../MonarchGrammarDefinitionReader.kt | 55 +++++++++ 4 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/GrammarDefinitionReader.kt create mode 100644 language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/MonarchGrammarDefinitionReader.kt diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt index b11f496ca..77a7ff570 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt @@ -28,7 +28,7 @@ import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition abstract class LanguageDefinitionListBuilder { - private val allBuilder = mutableListOf() + protected val allBuilder = mutableListOf() fun language(name: String, block: LanguageDefinitionBuilder.() -> Unit) { allBuilder.add(LanguageDefinitionBuilder(name).also(block)) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt new file mode 100644 index 000000000..3d93b04a4 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt @@ -0,0 +1,77 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.registery.dsl + +import io.github.dingyi222666.monarch.language.Language +import io.github.dingyi222666.monarch.loader.json.loadMonarchJson +import io.github.rosemoe.sora.langs.monarch.registery.FileProviderRegistry +import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition +import io.github.rosemoe.sora.langs.monarch.theme.toLanguageConfiguration +import java.io.File +import java.nio.charset.Charset + + +class MonarchLanguageDefinitionListBuilder : LanguageDefinitionListBuilder() { + override fun build(): List> = allBuilder.map { languageDefinition -> + val monarchSource = runCatching { + FileProviderRegistry.resolve(languageDefinition.grammar ?: "")?.use { + it.bufferedReader().readText() + } + }.getOrNull()?.runCatching { + val monarchLanguage = + loadMonarchJson(this) ?: throw Exception("Failed to load monarch source") + + Language( + monarchLanguage = monarchLanguage, + languageName = languageDefinition.name, + languageId = monarchLanguage.tokenPostfix ?: languageDefinition.name, + fileExtensions = emptyList(), + embeddedLanguages = languageDefinition.embeddedLanguages, + ) + }?.getOrNull() ?: throw Exception("Failed to load monarch source") + + val languageConfiguration = languageDefinition.languageConfiguration?.let { configuration -> + kotlin.runCatching { + configuration.toLanguageConfiguration() + }.getOrNull() ?: runCatching { + FileProviderRegistry.resolve(languageDefinition.languageConfiguration ?: "")?.use { + it.bufferedReader().readText() + }?.toLanguageConfiguration() + }.getOrNull() + } + + + GrammarDefinition( + name = languageDefinition.name, + grammar = monarchSource, + embeddedLanguages = languageDefinition.embeddedLanguages ?: emptyMap(), + languageConfiguration = languageConfiguration, + scopeName = languageDefinition.scopeName ?: monarchSource.languageId + ) + + + } +} + diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/GrammarDefinitionReader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/GrammarDefinitionReader.kt new file mode 100644 index 000000000..b552d3157 --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/GrammarDefinitionReader.kt @@ -0,0 +1,110 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.registery.grammardefinition + +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration +import io.github.rosemoe.sora.langs.monarch.registery.FileProviderRegistry +import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition +import io.github.rosemoe.sora.langs.monarch.theme.toLanguageConfiguration + +abstract class GrammarDefinitionReader : JsonAdapter>() { + override fun fromJson(reader: JsonReader): GrammarDefinition { + reader.isLenient = true + + var name = "" + val grammar: T? + val embeddedLanguages = mutableMapOf() + var grammarPath = "" + var languageConfiguration: LanguageConfiguration? = null + var scopeName = "" + + reader.beginObject() + + while (reader.hasNext()) { + when (reader.nextName()) { + "name" -> { + name = reader.nextString() + } + + "embeddedLanguages" -> { + reader.beginObject() + while (reader.hasNext()) { + embeddedLanguages[reader.nextName()] = reader.nextString() + } + reader.endObject() + } + + "languageConfiguration" -> { + + languageConfiguration = kotlin.runCatching { + val path = reader.nextString() + + val rawText = + FileProviderRegistry.resolve(path)?.bufferedReader()?.readText() + + rawText?.toLanguageConfiguration() + }.getOrNull() + } + + "scopeName" -> { + scopeName = reader.nextString() + } + + "grammar" -> { + grammarPath = reader.nextString() + } + } + } + + reader.endObject() + + grammar = readGrammar( + GrammarDefinition( + name, + Unit, + embeddedLanguages, + languageConfiguration, + scopeName + ), grammarPath + ) + + + return GrammarDefinition( + name, + grammar ?: throw IllegalStateException("Grammar is null"), + embeddedLanguages, + languageConfiguration, + scopeName + ) + } + + abstract fun readGrammar(grammarDefinition: GrammarDefinition, path: String): T? + override fun toJson(p0: JsonWriter, p1: GrammarDefinition?) { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/MonarchGrammarDefinitionReader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/MonarchGrammarDefinitionReader.kt new file mode 100644 index 000000000..5f0a923ff --- /dev/null +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/MonarchGrammarDefinitionReader.kt @@ -0,0 +1,55 @@ +/******************************************************************************* + * sora-editor - the awesome code editor for Android + * https://github.com/Rosemoe/sora-editor + * Copyright (C) 2020-2024 Rosemoe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Please contact Rosemoe by email 2073412493@qq.com if you need + * additional information or have any questions + ******************************************************************************/ + +package io.github.rosemoe.sora.langs.monarch.registery.grammardefinition + +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import io.github.dingyi222666.monarch.language.Language +import io.github.dingyi222666.monarch.loader.json.loadMonarchJson +import io.github.rosemoe.sora.langs.monarch.registery.FileProviderRegistry +import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition + +class MonarchGrammarDefinitionReader : GrammarDefinitionReader() { + + override fun readGrammar(grammarDefinition: GrammarDefinition, path: String): Language? = + runCatching { + FileProviderRegistry.resolve(path)?.use { + it.bufferedReader().readText() + } + }.getOrNull()?.runCatching { + val monarchLanguage = + loadMonarchJson(this) ?: throw Exception("Failed to load monarch source") + + Language( + monarchLanguage = monarchLanguage, + languageName = grammarDefinition.name, + languageId = monarchLanguage.tokenPostfix ?: grammarDefinition.name, + fileExtensions = emptyList(), + embeddedLanguages = grammarDefinition.embeddedLanguages, + ) + }?.getOrNull() + + +} \ No newline at end of file From bdf9c765a7b89b5e7b8745d50c74c96c8d433351 Mon Sep 17 00:00:00 2001 From: dingyi Date: Tue, 2 Jul 2024 22:08:08 +0800 Subject: [PATCH 22/40] feat(lang-monarch): support load grammar for json --- .../monarch/languageconfiguration/loader.kt | 4 +- .../monarch/registery/GrammarRegistry.kt | 4 -- .../registery/MonarchGrammarRegistry.kt | 22 +++++++- .../GrammarDefinitionReader.kt | 50 +++++++++++++++++-- .../sora/langs/monarch/theme/loader.kt | 19 +++++-- 5 files changed, 82 insertions(+), 17 deletions(-) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt index bdc76f2bf..6871fc18c 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt @@ -468,8 +468,6 @@ class LanguageConfigurationAdapter : JsonAdapter() { return CharacterPair(first, second) } - override fun toJson(p0: JsonWriter, p1: LanguageConfiguration?) { - TODO("Not yet implemented") - } + override fun toJson(p0: JsonWriter, p1: LanguageConfiguration?) {} } \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt index c2781e0cb..60ce5b871 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt @@ -144,10 +144,6 @@ abstract class GrammarRegistry { languageConfigurationMap[scopeName] = languageConfiguration } - // TODO: load grammars by json path - /* fun loadGrammars(jsonPath: String?): List { - return loadGrammars(LanguageDefinitionReader.read(jsonPath)) - }*/ @Synchronized fun loadGrammar(grammarDefinition: GrammarDefinition): T { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt index b505fa918..d39b4150e 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt @@ -24,18 +24,36 @@ package io.github.rosemoe.sora.langs.monarch.registery +import com.squareup.moshi.Moshi import io.github.dingyi222666.monarch.language.Language import io.github.dingyi222666.monarch.language.LanguageRegistry +import io.github.dingyi222666.monarch.loader.json.addLast import io.github.dingyi222666.monarch.types.IThemeService import io.github.dingyi222666.monarch.types.ITokenTheme +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.LanguageConfigurationAdapter +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration +import io.github.rosemoe.sora.langs.monarch.registery.grammardefinition.MonarchGrammarDefinitionReader +import io.github.rosemoe.sora.langs.monarch.registery.grammardefinition.ParsedGrammarDefinitionList import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel +import io.github.rosemoe.sora.langs.monarch.theme.MoshiRoot +import io.github.rosemoe.sora.langs.monarch.theme.TokenTheme +import io.github.rosemoe.sora.langs.monarch.theme.TokenThemeAdapter +import io.github.rosemoe.sora.langs.monarch.theme.adapter +import java.io.File class MonarchGrammarRegistry( internal val languageRegistry: LanguageRegistry = LanguageRegistry(), parent: GrammarRegistry? = null ) : GrammarRegistry(parent), IThemeService { + val moshi: Moshi = Moshi.Builder() + .apply { + addLast>(MonarchGrammarDefinitionReader()) + } + .build() + + private var currentTheme = ThemeModel.EMPTY override fun doLoadGrammar(grammarDefinition: GrammarDefinition): Language { @@ -50,7 +68,9 @@ class MonarchGrammarRegistry( } override fun doLoadGrammarsFromJsonPath(jsonPath: String): List> { - TODO("Not yet implemented") + val adapter = moshi.adapter>() + return (adapter.fromJson(File(jsonPath).readText()) + ?: ParsedGrammarDefinitionList.empty()).grammarDefinition } override fun doSearchGrammar(scopeName: String): Language? { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/GrammarDefinitionReader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/GrammarDefinitionReader.kt index b552d3157..07ce10c98 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/GrammarDefinitionReader.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/GrammarDefinitionReader.kt @@ -32,10 +32,40 @@ import io.github.rosemoe.sora.langs.monarch.registery.FileProviderRegistry import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition import io.github.rosemoe.sora.langs.monarch.theme.toLanguageConfiguration -abstract class GrammarDefinitionReader : JsonAdapter>() { - override fun fromJson(reader: JsonReader): GrammarDefinition { +abstract class GrammarDefinitionReader : JsonAdapter>() { + override fun fromJson(reader: JsonReader): ParsedGrammarDefinitionList { reader.isLenient = true + val result = mutableListOf>() + + + reader.beginObject() + + while (reader.hasNext()) { + when (reader.nextName()) { + "languages" -> { + reader.beginArray() + while (reader.hasNext()) { + val grammarDefinition = readGrammarDefinition(reader) + result.add(grammarDefinition) + } + reader.endArray() + } + + else -> { + reader.skipValue() + } + } + } + + reader.endObject() + + return ParsedGrammarDefinitionList(result) + } + + private fun readGrammarDefinition( + reader: JsonReader + ): GrammarDefinition { var name = "" val grammar: T? val embeddedLanguages = mutableMapOf() @@ -83,6 +113,7 @@ abstract class GrammarDefinitionReader : JsonAdapter>() reader.endObject() + grammar = readGrammar( GrammarDefinition( name, @@ -103,8 +134,19 @@ abstract class GrammarDefinitionReader : JsonAdapter>() ) } + override fun toJson(p0: JsonWriter, p1: ParsedGrammarDefinitionList?) {} + abstract fun readGrammar(grammarDefinition: GrammarDefinition, path: String): T? - override fun toJson(p0: JsonWriter, p1: GrammarDefinition?) { - TODO("Not yet implemented") +} + +data class ParsedGrammarDefinitionList( + val grammarDefinition: List>, +) { + companion object { + private val EMPTY = ParsedGrammarDefinitionList(emptyList()) + + fun empty(): ParsedGrammarDefinitionList { + return EMPTY as ParsedGrammarDefinitionList + } } } \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt index f0c9582c8..4b66580d7 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt @@ -28,9 +28,12 @@ import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonReader import com.squareup.moshi.JsonWriter import com.squareup.moshi.Moshi +import io.github.dingyi222666.monarch.language.Language import io.github.dingyi222666.monarch.loader.json.addLast import io.github.rosemoe.sora.langs.monarch.languageconfiguration.LanguageConfigurationAdapter import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration +import io.github.rosemoe.sora.langs.monarch.registery.grammardefinition.MonarchGrammarDefinitionReader +import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition class TokenThemeAdapter : JsonAdapter() { override fun fromJson(reader: JsonReader): TokenTheme { @@ -61,9 +64,11 @@ class TokenThemeAdapter : JsonAdapter() { } reader.endObject() } + "name" -> { themeName = reader.nextString() } + else -> { reader.skipValue() } @@ -156,9 +161,7 @@ class TokenThemeAdapter : JsonAdapter() { reader.endArray() } - override fun toJson(p0: JsonWriter, p1: TokenTheme?) { - TODO("Not yet implemented") - } + override fun toJson(p0: JsonWriter, p1: TokenTheme?) {} } @@ -166,15 +169,21 @@ internal val MoshiRoot: Moshi = Moshi.Builder() .apply { addLast(TokenThemeAdapter()) addLast(LanguageConfigurationAdapter()) + } .build() +internal inline fun Moshi.adapter(): JsonAdapter { + return this.adapter(T::class.java) +} + + fun String.toTokenTheme(): TokenTheme { - return MoshiRoot.adapter(TokenTheme::class.java).fromJson(this)!! + return MoshiRoot.adapter().fromJson(this)!! } fun String.toLanguageConfiguration(): LanguageConfiguration { - return MoshiRoot.adapter(LanguageConfiguration::class.java).fromJson(this)!! + return MoshiRoot.adapter().fromJson(this)!! } internal data class TokenThemeRule( From 1e8ac99092108f47de44549de5bdd300388137e4 Mon Sep 17 00:00:00 2001 From: dingyi Date: Wed, 3 Jul 2024 02:54:27 +0800 Subject: [PATCH 23/40] feat(language-monarch): integrate monarch language support This commit adds support for the Monarch language system, including the implementation of MonarchGrammarDefinitionDSL for grammar definition, and updates to the language-monarch module to handle language loading and configuration. Theme support for Monarch is also introduced, allowing for dark and light mode theming consistency with TextMate. --- app/build.gradle.kts | 4 + .../github/rosemoe/sora/app/MainActivity.kt | 193 ++++++++++++++---- .../java/io/github/rosemoe/sora/app/Utils.kt | 5 + gradle/libs.versions.toml | 7 +- language-monarch/build.gradle.kts | 6 +- .../sora/langs/monarch/MonarchColorScheme.kt | 23 ++- .../sora/langs/monarch/MonarchLanguage.kt | 23 ++- .../monarch/registery/GrammarRegistry.kt | 8 +- .../registery/MonarchGrammarRegistry.kt | 7 +- .../registery/dsl/GrammarDefinitionDSL.kt | 10 +- .../dsl/MonarchGrammarDefinitionDSL.kt | 41 ++-- .../MonarchGrammarDefinitionReader.kt | 2 +- .../monarch/registery/model/ThemeModel.kt | 6 +- 13 files changed, 259 insertions(+), 76 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9a9febb4a..eeb2f4ce7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -96,12 +96,16 @@ dependencies { implementation(projects.editor) implementation(projects.languageJava) implementation(projects.languageTextmate) + implementation(projects.languageMonarch) implementation(projects.editorLsp) implementation(projects.languageTreesitter) // Tree-sitter languages implementation(libs.tree.sitter.java) + // Monarch Languages + implementation(libs.monarch.language.pack) + // Kotlin coroutines implementation(libs.kotlinx.coroutines) diff --git a/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt b/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt index 45c56907a..9327b89c4 100644 --- a/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt +++ b/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt @@ -42,6 +42,9 @@ import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts.GetContent import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope +import io.github.dingyi222666.monarch.languages.JavaLanguage +import io.github.dingyi222666.monarch.languages.KotlinLanguage +import io.github.dingyi222666.monarch.languages.PythonLanguage import io.github.rosemoe.sora.app.databinding.ActivityMainBinding import io.github.rosemoe.sora.app.tests.TestActivity import io.github.rosemoe.sora.event.ContentChangeEvent @@ -57,6 +60,11 @@ import io.github.rosemoe.sora.lang.TsLanguageJava import io.github.rosemoe.sora.lang.diagnostic.DiagnosticRegion import io.github.rosemoe.sora.lang.diagnostic.DiagnosticsContainer import io.github.rosemoe.sora.langs.java.JavaLanguage +import io.github.rosemoe.sora.langs.monarch.MonarchColorScheme +import io.github.rosemoe.sora.langs.monarch.MonarchLanguage +import io.github.rosemoe.sora.langs.monarch.registery.MonarchGrammarRegistry +import io.github.rosemoe.sora.langs.monarch.registery.dsl.monarchLanguages +import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeSource import io.github.rosemoe.sora.langs.textmate.TextMateColorScheme import io.github.rosemoe.sora.langs.textmate.TextMateLanguage import io.github.rosemoe.sora.langs.textmate.registry.FileProviderRegistry @@ -238,6 +246,10 @@ class MainActivity : AppCompatActivity() { // Load textmate themes and grammars setupTextmate() + + // Load monarch themes and grammars + setupMonarch() + // Before using Textmate Language, TextmateColorScheme should be applied ensureTextmateTheme() @@ -303,15 +315,15 @@ class MainActivity : AppCompatActivity() { applicationContext.assets // use application context ) ) - loadDefaultThemes() - loadDefaultLanguages() + loadDefaultTextMateThemes() + loadDefaultTextMateLanguages() } /** * Load default textmate themes */ - private /*suspend*/ fun loadDefaultThemes() /*= withContext(Dispatchers.IO)*/ { + private /*suspend*/ fun loadDefaultTextMateThemes() /*= withContext(Dispatchers.IO)*/ { val themes = arrayOf("darcula", "abyss", "quietlight", "solarized_drak") val themeRegistry = ThemeRegistry.getInstance() themes.forEach { name -> @@ -337,10 +349,73 @@ class MainActivity : AppCompatActivity() { * * @see loadDefaultLanguagesWithDSL Load by Kotlin DSL */ - private /*suspend*/ fun loadDefaultLanguages() /*= withContext(Dispatchers.Main)*/ { + private /*suspend*/ fun loadDefaultTextMateLanguages() /*= withContext(Dispatchers.Main)*/ { GrammarRegistry.getInstance().loadGrammars("textmate/languages.json") } + /** + * Setup monarch. Load our grammars and themes from assets + */ + private fun setupMonarch() { + // Add assets file provider so that files in assets can be loaded + io.github.rosemoe.sora.langs.monarch.registery.FileProviderRegistry.addProvider( + io.github.rosemoe.sora.langs.monarch.registery.provider.AssetsFileResolver( + applicationContext.assets // use application context + ) + ) + loadDefaultMonarchThemes() + loadDefaultMonarchLanguages() + } + + + /** + * Load default monarch themes + * + */ + private /*suspend*/ fun loadDefaultMonarchThemes() /*= withContext(Dispatchers.IO)*/ { + val themes = arrayOf("darcula", "abyss", "quietlight", "solarized_drak") + + themes.forEach { name -> + val path = "textmate/$name.json" + io.github.rosemoe.sora.langs.monarch.registery.ThemeRegistry.loadTheme( + io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel( + ThemeSource(path, name) + ).apply { + if (name != "quietlight") { + isDark = true + } + }, false + ) + } + + io.github.rosemoe.sora.langs.monarch.registery.ThemeRegistry.setTheme("quietlight") + } + + /** + * Load default languages from Monarch + */ + private fun loadDefaultMonarchLanguages() { + MonarchGrammarRegistry.INSTANCE.loadGrammars( + monarchLanguages { + language("java") { + monarchLanguage = JavaLanguage + defaultScopeName() + languageConfiguration = "textmate/java/language-configuration.json" + } + language("kotlin") { + monarchLanguage = KotlinLanguage + defaultScopeName() + languageConfiguration = "textmate/kotlin/language-configuration.json" + } + language("python") { + monarchLanguage = PythonLanguage + defaultScopeName() + languageConfiguration = "textmate/python/language-configuration.json" + } + } + ) + } + private fun loadDefaultLanguagesWithDSL() { GrammarRegistry.getInstance().loadGrammars( languages { @@ -405,6 +480,19 @@ class MainActivity : AppCompatActivity() { } } + /** + * Ensure the editor uses a [MonarchColorScheme] + */ + private fun ensureMonarchTheme() { + val editor = binding.editor + var editorColorScheme = editor.colorScheme + if (editorColorScheme !is MonarchColorScheme) { + editorColorScheme = TextMateColorScheme.create(ThemeRegistry.getInstance()) + editor.colorScheme = editorColorScheme + switchThemeIfRequired(this, editor) + } + } + private fun generateKeybindingString(event: KeyBindingEvent): String { val sb = StringBuilder() if (event.isCtrlPressed) { @@ -729,6 +817,9 @@ class MainActivity : AppCompatActivity() { "TextMate MarkDown", "TM Language from file", "Tree-sitter Java", + "Monarch Java", + "Monarch Kotlin", + "Monarch Python", "Text" ) val tmLanguages = mapOf( @@ -739,45 +830,75 @@ class MainActivity : AppCompatActivity() { "TextMate JavaScript" to Pair("source.js", "source.js"), "TextMate MarkDown" to Pair("text.html.markdown", "text.html.markdown") ) + + val monarchLanguages = mapOf( + "Monarch Java" to "source.java", + "Monarch Kotlin" to "source.kotlin", + "Monarch Python" to "source.python", + ) + AlertDialog.Builder(this) .setTitle(R.string.switch_language) .setSingleChoiceItems(languageOptions, -1) { dialog: DialogInterface, which: Int -> - val selected = languageOptions[which] - if (selected in tmLanguages) { - val info = tmLanguages[selected]!! - try { - ensureTextmateTheme() - val editorLanguage = editor.editorLanguage - val language = if (editorLanguage is TextMateLanguage) { - editorLanguage.updateLanguage(info.first) - editorLanguage - } else { - TextMateLanguage.create(info.second, true) + when (val selected = languageOptions[which]) { + in tmLanguages -> { + val info = tmLanguages[selected]!! + try { + ensureTextmateTheme() + val editorLanguage = editor.editorLanguage + val language = if (editorLanguage is TextMateLanguage) { + editorLanguage.updateLanguage(info.first) + editorLanguage + } else { + TextMateLanguage.create(info.second, true) + } + editor.setEditorLanguage(language) + } catch (e: Exception) { + e.printStackTrace() } - editor.setEditorLanguage(language) - } catch (e: Exception) { - e.printStackTrace() } - } else { - when (selected) { - "Java" -> editor.setEditorLanguage(JavaLanguage()) - "Text" -> editor.setEditorLanguage(EmptyLanguage()) - "TM Language from file" -> loadTMLLauncher.launch("*/*") - "Tree-sitter Java" -> { - editor.setEditorLanguage( - TsLanguageJava( - JavaLanguageSpec( - highlightScmSource = assets.open("tree-sitter-queries/java/highlights.scm") - .reader().readText(), - codeBlocksScmSource = assets.open("tree-sitter-queries/java/blocks.scm") - .reader().readText(), - bracketsScmSource = assets.open("tree-sitter-queries/java/brackets.scm") - .reader().readText(), - localsScmSource = assets.open("tree-sitter-queries/java/locals.scm") - .reader().readText() + + in monarchLanguages -> { + val info = monarchLanguages[selected]!! + + try { + ensureMonarchTheme() + + val editorLanguage = editor.editorLanguage + + val language = if (editorLanguage is MonarchLanguage) { + editorLanguage.updateLanguage(info) + editorLanguage + } else { + MonarchLanguage.create(info, true) + } + editor.setEditorLanguage(language) + } catch (e: Exception) { + e.printStackTrace() + } + } + + else -> { + when (selected) { + "Java" -> editor.setEditorLanguage(JavaLanguage()) + "Text" -> editor.setEditorLanguage(EmptyLanguage()) + "TM Language from file" -> loadTMLLauncher.launch("*/*") + "Tree-sitter Java" -> { + editor.setEditorLanguage( + TsLanguageJava( + JavaLanguageSpec( + highlightScmSource = assets.open("tree-sitter-queries/java/highlights.scm") + .reader().readText(), + codeBlocksScmSource = assets.open("tree-sitter-queries/java/blocks.scm") + .reader().readText(), + bracketsScmSource = assets.open("tree-sitter-queries/java/brackets.scm") + .reader().readText(), + localsScmSource = assets.open("tree-sitter-queries/java/locals.scm") + .reader().readText() + ) ) ) - ) + } } } } diff --git a/app/src/main/java/io/github/rosemoe/sora/app/Utils.kt b/app/src/main/java/io/github/rosemoe/sora/app/Utils.kt index e3c7112be..b2e8c6c3d 100644 --- a/app/src/main/java/io/github/rosemoe/sora/app/Utils.kt +++ b/app/src/main/java/io/github/rosemoe/sora/app/Utils.kt @@ -28,6 +28,7 @@ import android.app.Activity import android.content.Context import android.content.Intent import android.content.res.Configuration +import io.github.rosemoe.sora.langs.monarch.MonarchColorScheme import io.github.rosemoe.sora.langs.textmate.TextMateColorScheme import io.github.rosemoe.sora.langs.textmate.registry.ThemeRegistry import io.github.rosemoe.sora.widget.CodeEditor @@ -38,12 +39,16 @@ fun switchThemeIfRequired(context: Context, editor: CodeEditor) { if ((context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES) { if (editor.colorScheme is TextMateColorScheme) { ThemeRegistry.getInstance().setTheme("darcula") + } else if (editor.colorScheme is MonarchColorScheme) { + io.github.rosemoe.sora.langs.monarch.registery.ThemeRegistry.setTheme("darcula") } else { editor.colorScheme = SchemeDarcula() } } else { if (editor.colorScheme is TextMateColorScheme) { ThemeRegistry.getInstance().setTheme("quietlight") + } else if (editor.colorScheme is MonarchColorScheme) { + io.github.rosemoe.sora.langs.monarch.registery.ThemeRegistry.setTheme("quietlight") } else { editor.colorScheme = EditorColorScheme() } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2002e7bc5..0db4c8cc1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -30,9 +30,10 @@ joni = { module = "org.jruby.joni:joni", version = "2.2.1" } snakeyaml-engine = { module = "org.snakeyaml:snakeyaml-engine", version = "2.7" } moshi = { module = "com.squareup.moshi:moshi", version = "1.15.0" } jdt-annotation = { module = "org.eclipse.jdt:org.eclipse.jdt.annotation", version = "2.3.0" } -monarch-code = { module = "io.github.dingyi222666.monarch:monarch", version = "1.0.0" } -monarch-json = { module = "io.github.dingyi222666.monarch:monarch-json-loader", version = "1.0.0" } -regex-onig = { module = "io.github.dingyi222666.regex-lib:regex-lib-oniguruma", version = "1.0.0" } +monarch-code = { module = "io.github.dingyi222666.monarch:monarch", version = "1.0.1" } +monarch-language-pack = { module = "io.github.dingyi222666.monarch:monarch-language-pack", version = "1.0.1" } +monarch-json = { module = "io.github.dingyi222666.monarch:monarch-json-loader", version = "1.0.1" } +regex-onig = { module = "io.github.dingyi222666.regex-lib:regex-lib-oniguruma", version = "1.0.1" } tests-google-truth = { module = "com.google.truth:truth", version = "1.4.2" } tests-robolectric = { module = "org.robolectric:robolectric", version = "4.11.1" } diff --git a/language-monarch/build.gradle.kts b/language-monarch/build.gradle.kts index 9110b8004..5caf22ad6 100644 --- a/language-monarch/build.gradle.kts +++ b/language-monarch/build.gradle.kts @@ -53,9 +53,9 @@ android { dependencies { compileOnly(projects.editor) - implementation(libs.monarch.code) - implementation(libs.monarch.json) - implementation(libs.regex.onig) + api(libs.monarch.code) + api(libs.monarch.json) + api(libs.regex.onig) implementation(libs.moshi) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt index 9e30c5def..dbf16ae9a 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt @@ -33,21 +33,28 @@ import io.github.rosemoe.sora.langs.monarch.theme.ThemeDefaultColors import io.github.rosemoe.sora.widget.CodeEditor import io.github.rosemoe.sora.widget.schemes.EditorColorScheme + class MonarchColorScheme( themeModel: ThemeModel ) : EditorColorScheme(), ThemeChangeListener { - var currentThemeModel = themeModel + + var currentThemeModel: ThemeModel = themeModel set(value) { field = value onChangeTheme(value) } + init { + applyDefault() + } + override fun onChangeTheme(newTheme: ThemeModel) { - super.colors.clear(); + super.colors.clear() applyDefault(); } + override fun applyDefault() { super.applyDefault() @@ -55,6 +62,13 @@ class MonarchColorScheme( ThemeRegistry.addListener(this) } + val themeModel: ThemeModel? = currentThemeModel + + // no initialized + if (themeModel == null) { + return + } + if (!currentThemeModel.isLoaded) { currentThemeModel.load() } @@ -193,7 +207,8 @@ class MonarchColorScheme( if (superIsDark) { return true } - return currentThemeModel.isDark + val themeModel: ThemeModel? = currentThemeModel + return themeModel?.isDark ?: false } override fun detachEditor(editor: CodeEditor) { @@ -220,9 +235,11 @@ class MonarchColorScheme( fun create(themeModel: ThemeModel): MonarchColorScheme { + println(themeModel) return MonarchColorScheme(themeModel) } + fun create() = create(ThemeRegistry.currentTheme) } } \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt index e83a6f78e..dd82b36fd 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt @@ -137,6 +137,25 @@ class MonarchLanguage( } } + fun updateLanguage( + languageScopeName: String, + ) { + val grammar = grammarRegistry.findGrammar(languageScopeName) + ?: throw IllegalArgumentException( + String.format( + "Language with %s scope name not found", + grammarRegistry + ) + ) + + val languageConfiguration = + grammarRegistry.findLanguageConfiguration( + languageScopeName + ) + + createAnalyzerAndNewlineHandler(grammar, languageConfiguration) + } + companion object { @JvmStatic @@ -164,7 +183,7 @@ class MonarchLanguage( val languageConfiguration = grammarRegistry.findLanguageConfiguration( - grammar.monarchLanguage.tokenPostfix ?: grammar.languageName + languageScopeName ) return MonarchLanguage( @@ -198,7 +217,7 @@ class MonarchLanguage( val languageConfiguration = grammarRegistry.findLanguageConfiguration( - grammar.monarchLanguage.tokenPostfix ?: grammar.languageName + grammarDefinition.scopeName ) return MonarchLanguage( diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt index 60ce5b871..20f56f6b5 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt @@ -25,6 +25,7 @@ package io.github.rosemoe.sora.langs.monarch.registery import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration +import io.github.rosemoe.sora.langs.monarch.registery.dsl.LanguageDefinitionBuilder import io.github.rosemoe.sora.langs.monarch.registery.dsl.LanguageDefinitionListBuilder import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel @@ -118,16 +119,17 @@ abstract class GrammarRegistry { return grammar to languageConfiguration } - fun loadGrammars(builder: LanguageDefinitionListBuilder): List { + fun loadGrammars(builder: LanguageDefinitionListBuilder): List { return loadGrammars(builder.build()) } + fun loadGrammars(list: List>): List { prepareLoadGrammars(list) return list.map { loadGrammar(it) } } - fun loadGrammars(jsonPath: String): List { + open fun loadGrammars(jsonPath: String): List { return loadGrammars(doLoadGrammarsFromJsonPath(jsonPath)) } @@ -147,7 +149,7 @@ abstract class GrammarRegistry { @Synchronized fun loadGrammar(grammarDefinition: GrammarDefinition): T { - val languageName = grammarDefinition.name + val languageName = grammarDefinition.scopeName if (grammarFileName2ScopeName.containsKey(languageName) && grammarDefinition.scopeName.isNotEmpty()) { //loaded diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt index d39b4150e..97ca3bf1d 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt @@ -32,6 +32,10 @@ import io.github.dingyi222666.monarch.types.IThemeService import io.github.dingyi222666.monarch.types.ITokenTheme import io.github.rosemoe.sora.langs.monarch.languageconfiguration.LanguageConfigurationAdapter import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration +import io.github.rosemoe.sora.langs.monarch.registery.dsl.LanguageDefinitionBuilder +import io.github.rosemoe.sora.langs.monarch.registery.dsl.LanguageDefinitionListBuilder +import io.github.rosemoe.sora.langs.monarch.registery.dsl.MonarchLanguageDefinitionBuilder +import io.github.rosemoe.sora.langs.monarch.registery.dsl.MonarchLanguageDefinitionListBuilder import io.github.rosemoe.sora.langs.monarch.registery.grammardefinition.MonarchGrammarDefinitionReader import io.github.rosemoe.sora.langs.monarch.registery.grammardefinition.ParsedGrammarDefinitionList import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition @@ -59,7 +63,6 @@ class MonarchGrammarRegistry( override fun doLoadGrammar(grammarDefinition: GrammarDefinition): Language { return grammarDefinition.grammar.also { languageRegistry.registerLanguage(it, true, this) - grammarDefinition.scopeName = it.monarchLanguage.tokenPostfix ?: it.languageName } } @@ -76,7 +79,7 @@ class MonarchGrammarRegistry( override fun doSearchGrammar(scopeName: String): Language? { // fast search? return languageRegistry.getRegisteredLanguages().find { - it.monarchLanguage.tokenPostfix == scopeName + "source${it.monarchLanguage.tokenPostfix}" == scopeName } } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt index 77a7ff570..85d39d940 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt @@ -27,17 +27,15 @@ package io.github.rosemoe.sora.langs.monarch.registery.dsl import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition -abstract class LanguageDefinitionListBuilder { - protected val allBuilder = mutableListOf() +abstract class LanguageDefinitionListBuilder { + protected val allBuilder = mutableListOf() - fun language(name: String, block: LanguageDefinitionBuilder.() -> Unit) { - allBuilder.add(LanguageDefinitionBuilder(name).also(block)) - } + abstract fun language(name: String, block: R.() -> Unit) abstract fun build(): List> } -class LanguageDefinitionBuilder(var name: String) { +open class LanguageDefinitionBuilder(var name: String) { lateinit var grammar: String var scopeName: String? = null var languageConfiguration: String? = null diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt index 3d93b04a4..05619d936 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt @@ -26,6 +26,7 @@ package io.github.rosemoe.sora.langs.monarch.registery.dsl import io.github.dingyi222666.monarch.language.Language import io.github.dingyi222666.monarch.loader.json.loadMonarchJson +import io.github.dingyi222666.monarch.types.IMonarchLanguage import io.github.rosemoe.sora.langs.monarch.registery.FileProviderRegistry import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition import io.github.rosemoe.sora.langs.monarch.theme.toLanguageConfiguration @@ -33,25 +34,29 @@ import java.io.File import java.nio.charset.Charset -class MonarchLanguageDefinitionListBuilder : LanguageDefinitionListBuilder() { +class MonarchLanguageDefinitionListBuilder : + LanguageDefinitionListBuilder() { + override fun language(name: String, block: MonarchLanguageDefinitionBuilder.() -> Unit) { + allBuilder.add(MonarchLanguageDefinitionBuilder(name).also(block)) + } + override fun build(): List> = allBuilder.map { languageDefinition -> - val monarchSource = runCatching { - FileProviderRegistry.resolve(languageDefinition.grammar ?: "")?.use { + val monarchLanguage = languageDefinition.monarchLanguage ?: languageDefinition.runCatching { + FileProviderRegistry.resolve(languageDefinition.grammar)?.use { it.bufferedReader().readText() } }.getOrNull()?.runCatching { - val monarchLanguage = - loadMonarchJson(this) ?: throw Exception("Failed to load monarch source") - - Language( - monarchLanguage = monarchLanguage, - languageName = languageDefinition.name, - languageId = monarchLanguage.tokenPostfix ?: languageDefinition.name, - fileExtensions = emptyList(), - embeddedLanguages = languageDefinition.embeddedLanguages, - ) + loadMonarchJson(this) ?: throw Exception("Failed to load monarch source") }?.getOrNull() ?: throw Exception("Failed to load monarch source") + val language = Language( + monarchLanguage = monarchLanguage, + languageName = languageDefinition.name, + languageId = languageDefinition.scopeName ?: "source.${monarchLanguage.tokenPostfix ?: languageDefinition.name}", + fileExtensions = emptyList(), + embeddedLanguages = languageDefinition.embeddedLanguages, + ) + val languageConfiguration = languageDefinition.languageConfiguration?.let { configuration -> kotlin.runCatching { configuration.toLanguageConfiguration() @@ -65,13 +70,19 @@ class MonarchLanguageDefinitionListBuilder : LanguageDefinitionListBuilder Unit) = + MonarchLanguageDefinitionListBuilder().apply(block) \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/MonarchGrammarDefinitionReader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/MonarchGrammarDefinitionReader.kt index 5f0a923ff..761c42420 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/MonarchGrammarDefinitionReader.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/MonarchGrammarDefinitionReader.kt @@ -45,7 +45,7 @@ class MonarchGrammarDefinitionReader : GrammarDefinitionReader() { Language( monarchLanguage = monarchLanguage, languageName = grammarDefinition.name, - languageId = monarchLanguage.tokenPostfix ?: grammarDefinition.name, + languageId = grammarDefinition.scopeName ?: "source${monarchLanguage.tokenPostfix}", fileExtensions = emptyList(), embeddedLanguages = grammarDefinition.embeddedLanguages, ) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt index aed987f66..6dbc374e4 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt @@ -37,7 +37,6 @@ class ThemeModel { private set var isDark = false - private set constructor(themeSource: ThemeSource) { this.themeSource = themeSource @@ -60,9 +59,12 @@ class ThemeModel { if (rawThemeString != null) { value = rawThemeString.toTokenTheme() + if (value.themeType == "dark") { + isDark = true + } } - isDark = value.themeType == "dark" + } val isLoaded: Boolean From 7cefd27bea78082480e7d04ebf54548842382715 Mon Sep 17 00:00:00 2001 From: dingyi Date: Wed, 25 Sep 2024 05:31:38 +0800 Subject: [PATCH 24/40] refactor(language-monarch): load theme colors asynchronously Themes now load colors asynchronously, which prevents blocking the main thread when parsing and applying theme settings. This optimization enhances the overall performance andresponsiveness of the application when switching or initializing themes. The TokenTheme adapter was updated to handle the asynchronous loading of theme colors. MonarchColorScheme was modified to apply themes more efficiently, especially when dealing with legacy TextMate themes. Additionally, the theme registration and management logic was refactored to ensure themes are loaded only when necessary. --- .../github/rosemoe/sora/app/MainActivity.kt | 2 +- .../AsyncIncrementalAnalyzeManager.java | 6 +- .../sora/langs/monarch/MonarchColorScheme.kt | 94 ++++++--- .../sora/langs/monarch/MonarchLanguage.kt | 2 +- .../langs/monarch/MonarchNewlineHandler.kt | 9 +- .../registery/MonarchGrammarRegistry.kt | 7 +- .../langs/monarch/registery/ThemeRegistry.kt | 14 +- .../dsl/MonarchGrammarDefinitionDSL.kt | 4 +- .../monarch/registery/model/ThemeModel.kt | 12 +- .../sora/langs/monarch/theme/ColorMap.kt | 1 - .../langs/monarch/theme/ThemeDefaultColors.kt | 5 +- .../sora/langs/monarch/theme/TokenTheme.kt | 5 +- .../sora/langs/monarch/theme/loader.kt | 199 ++++++++++++------ .../rosemoe/sora/langs/monarch/theme/parse.kt | 4 +- 14 files changed, 239 insertions(+), 125 deletions(-) diff --git a/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt b/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt index 9327b89c4..3d135baa1 100644 --- a/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt +++ b/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt @@ -487,7 +487,7 @@ class MainActivity : AppCompatActivity() { val editor = binding.editor var editorColorScheme = editor.colorScheme if (editorColorScheme !is MonarchColorScheme) { - editorColorScheme = TextMateColorScheme.create(ThemeRegistry.getInstance()) + editorColorScheme = MonarchColorScheme.create(io.github.rosemoe.sora.langs.monarch.registery.ThemeRegistry.currentTheme) editor.colorScheme = editorColorScheme switchThemeIfRequired(this, editor) } diff --git a/editor/src/main/java/io/github/rosemoe/sora/lang/analysis/AsyncIncrementalAnalyzeManager.java b/editor/src/main/java/io/github/rosemoe/sora/lang/analysis/AsyncIncrementalAnalyzeManager.java index 420a33776..550a22287 100644 --- a/editor/src/main/java/io/github/rosemoe/sora/lang/analysis/AsyncIncrementalAnalyzeManager.java +++ b/editor/src/main/java/io/github/rosemoe/sora/lang/analysis/AsyncIncrementalAnalyzeManager.java @@ -445,6 +445,7 @@ public void offerMessage(@NonNull Message msg) { } private void initialize() { + var time = System.currentTimeMillis(); styles = new Styles(spans = new LockedSpans()); S state = getInitialState(); var mdf = spans.modify(); @@ -460,8 +461,11 @@ private void initialize() { styles.blocks = computeBlocks(shadowed, delegate); styles.setSuppressSwitch(delegate.suppressSwitch); styles.finishBuilding(); - if (!abort) + if (!abort) { sendNewStyles(styles); + } + + Log.e("AsyncAnalysis", "Analyze finished in " + (System.currentTimeMillis() - time) + "ms"); } public boolean handleMessage(@NonNull Message msg) { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt index dbf16ae9a..3a2f4d2e7 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt @@ -38,18 +38,15 @@ class MonarchColorScheme( themeModel: ThemeModel ) : EditorColorScheme(), ThemeChangeListener { - var currentThemeModel: ThemeModel = themeModel - set(value) { - field = value - onChangeTheme(value) - } + private set init { applyDefault() } override fun onChangeTheme(newTheme: ThemeModel) { + this.currentThemeModel = newTheme super.colors.clear() applyDefault(); } @@ -69,18 +66,24 @@ class MonarchColorScheme( return } - if (!currentThemeModel.isLoaded) { - currentThemeModel.load() + if (!themeModel.isLoaded) { + themeModel.load() } - applyThemeSettings(currentThemeModel.value.defaults) - } - private fun applyThemeSettings(defaultColors: ThemeDefaultColors) { - setColor(LINE_DIVIDER, Color.TRANSPARENT) + val value = themeModel.value + println("current theme: ${value.defaults.oldTextMateStyle}, name: ${value.name}, loaded: ${themeModel.isLoaded}") - defaultColors["editor.foreground"]?.let { + if (value.defaults.oldTextMateStyle) { + applyTMTheme(value.defaults) + } else { + applyThemeSettings(value.defaults) + } + } + + private fun applyThemeSettings(defaultColors: ThemeDefaultColors) { + defaultColors["editorCursor.foreground"]?.let { setColor(SELECTION_INSERT, Color.parseColor(it)) } @@ -88,28 +91,23 @@ class MonarchColorScheme( setColor(SELECTED_TEXT_BACKGROUND, Color.parseColor(it)) } - defaultColors["editorWhitespace.foreground"]?.let { setColor(NON_PRINTABLE_CHAR, Color.parseColor(it)) } - defaultColors["editor.lineHighlightBackground"]?.let { setColor(CURRENT_LINE, Color.parseColor(it)) } - defaultColors["editor.background"]?.let { setColor(WHOLE_BACKGROUND, Color.parseColor(it)) setColor(LINE_NUMBER_BACKGROUND, Color.parseColor(it)) } - defaultColors["editorLineNumber.foreground"]?.let { setColor(LINE_NUMBER, Color.parseColor(it)) } - defaultColors["editorLineNumber.activeForeground"]?.let { setColor(LINE_NUMBER_CURRENT, Color.parseColor(it)) } @@ -118,51 +116,38 @@ class MonarchColorScheme( setColor(TEXT_NORMAL, Color.parseColor(it)) } - defaultColors["completionWindowBackground"]?.let { setColor(COMPLETION_WND_BACKGROUND, Color.parseColor(it)) } defaultColors["completionWindowBackgroundCurrent"]?.let { - setColor( - COMPLETION_WND_ITEM_CURRENT, - Color.parseColor(it) - ) + setColor(COMPLETION_WND_ITEM_CURRENT, Color.parseColor(it)) } - defaultColors["highlightedDelimetersForeground"]?.let { - setColor( - HIGHLIGHTED_DELIMITERS_FOREGROUND, - Color.parseColor(it) - ) + setColor(HIGHLIGHTED_DELIMITERS_FOREGROUND, Color.parseColor(it)) } defaultColors["tooltipBackground"]?.let { setColor(DIAGNOSTIC_TOOLTIP_BACKGROUND, Color.parseColor(it)) } - defaultColors["tooltipBriefMessageColor"]?.let { setColor(DIAGNOSTIC_TOOLTIP_BRIEF_MSG, Color.parseColor(it)) } - defaultColors["tooltipDetailedMessageColor"]?.let { setColor(DIAGNOSTIC_TOOLTIP_DETAILED_MSG, Color.parseColor(it)) } - defaultColors["tooltipActionColor"]?.let { setColor(DIAGNOSTIC_TOOLTIP_ACTION, Color.parseColor(it)) } - val editorIndentGuideBackground = defaultColors["editorIndentGuide.background"] val blockLineColor = - (getColor(WHOLE_BACKGROUND) + getColor(TEXT_NORMAL)) / 2 and 0x00FFFFFF or -0x78000000 - val blockLineColorCur = (blockLineColor) or -0x1000000 - + (getColor(WHOLE_BACKGROUND) + getColor(TEXT_NORMAL)) / 2 and 0x00FFFFFF or 0x88000000.toInt() + val blockLineColorCur = blockLineColor or 0xFF000000.toInt() if (editorIndentGuideBackground != null) { setColor(BLOCK_LINE, Color.parseColor(editorIndentGuideBackground)) @@ -179,6 +164,46 @@ class MonarchColorScheme( } } + private fun applyTMTheme(defaultColors: ThemeDefaultColors) { + setColor(LINE_DIVIDER, Color.TRANSPARENT) + + defaultColors["caret"]?.let { + setColor(SELECTION_INSERT, Color.parseColor(it)) + } + + defaultColors["selection"]?.let { + setColor(SELECTED_TEXT_BACKGROUND, Color.parseColor(it)) + } + + defaultColors["invisibles"]?.let { + setColor(NON_PRINTABLE_CHAR, Color.parseColor(it)) + } + + defaultColors["lineHighlight"]?.let { + setColor(CURRENT_LINE, Color.parseColor(it)) + } + + defaultColors["background"]?.let { + setColor(WHOLE_BACKGROUND, Color.parseColor(it)) + setColor(LINE_NUMBER_BACKGROUND, Color.parseColor(it)) + } + + defaultColors["foreground"]?.let { + setColor(TEXT_NORMAL, Color.parseColor(it)) + } + + defaultColors["highlightedDelimetersForeground"]?.let { + setColor(HIGHLIGHTED_DELIMITERS_FOREGROUND, Color.parseColor(it)) + } + + // TMTheme seems to have no fields to control BLOCK_LINE colors + val blockLineColor = + (getColor(WHOLE_BACKGROUND) + getColor(TEXT_NORMAL)) / 2 and 0x00FFFFFF or 0x88000000.toInt() + setColor(BLOCK_LINE, blockLineColor) + val blockLineColorCur = blockLineColor or 0xFF000000.toInt() + setColor(BLOCK_LINE_CURRENT, blockLineColorCur) + } + override fun getColor(type: Int): Int { if (type < 255) { return super.getColor(type) @@ -235,7 +260,6 @@ class MonarchColorScheme( fun create(themeModel: ThemeModel): MonarchColorScheme { - println(themeModel) return MonarchColorScheme(themeModel) } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt index dd82b36fd..242fb38a0 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt @@ -177,7 +177,7 @@ class MonarchLanguage( ?: throw IllegalArgumentException( String.format( "Language with %s scope name not found", - grammarRegistry + languageScopeName ) ) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt index fffecc90b..7d5e2086a 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt @@ -50,8 +50,8 @@ class MonarchNewlineHandler( private val language: MonarchLanguage ) : NewlineHandler { - private lateinit var enterSupport: OnEnterSupport - private lateinit var indentRulesSupport: IndentRulesSupport + private var enterSupport: OnEnterSupport? = null + private var indentRulesSupport: IndentRulesSupport? = null private var enterAction: CompleteEnterAction? = null private var indentForEnter: Pair? = null @@ -148,7 +148,7 @@ class MonarchNewlineHandler( afterEnterIndent = beforeEnterIndent.toString() + indent } - if (indentRulesSupport.shouldDecrease(afterEnterText)) { + if (indentRulesSupport?.shouldDecrease(afterEnterText) == true) { // afterEnterIndent = indentConverter.unshiftIndent(afterEnterIndent); afterEnterIndent = beforeEnterIndent.substring( @@ -343,7 +343,7 @@ class MonarchNewlineHandler( if (lineNumber > 0) { for (lastLineNumber in lineNumber - 1 downTo 0) { val lineContent = content.getLineContent(lastLineNumber); - if (indentRulesSupport.shouldIgnore(lineContent) || precedingValidPattern.matches( + if (indentRulesSupport?.shouldIgnore(lineContent) == true || precedingValidPattern.matches( lineContent ) || lineContent.isEmpty() ) { @@ -376,6 +376,7 @@ class MonarchNewlineHandler( ): InheritIndentResult? { // https://github.com/microsoft/vscode/blob/bf63ea1932dd253745f38a4cbe26bb9be01801b1/src/vs/editor/common/languages/autoIndent.ts#L73 + val indentRulesSupport = requireNotNull(indentRulesSupport) if (line < 1) { return InheritIndentResult("", 0) } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt index 97ca3bf1d..1e003699d 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt @@ -27,6 +27,7 @@ package io.github.rosemoe.sora.langs.monarch.registery import com.squareup.moshi.Moshi import io.github.dingyi222666.monarch.language.Language import io.github.dingyi222666.monarch.language.LanguageRegistry +import io.github.dingyi222666.monarch.loader.dsl.splitToRegex import io.github.dingyi222666.monarch.loader.json.addLast import io.github.dingyi222666.monarch.types.IThemeService import io.github.dingyi222666.monarch.types.ITokenTheme @@ -79,7 +80,11 @@ class MonarchGrammarRegistry( override fun doSearchGrammar(scopeName: String): Language? { // fast search? return languageRegistry.getRegisteredLanguages().find { - "source${it.monarchLanguage.tokenPostfix}" == scopeName + "source${it.monarchLanguage.tokenPostfix}" == scopeName || + "source.${it.monarchLanguage.tokenPostfix}" == scopeName || + "source.${it.languageId}" == scopeName || + it.languageId == scopeName + } } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt index f09254a77..5fcec856f 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt @@ -64,12 +64,8 @@ object ThemeRegistry { if (!themeModel.isLoaded) { themeModel.load() } - val theme = - findTheme(themeModel.name) - if (theme != null) { - setTheme(theme) - return - } + + themes.add(themeModel) if (isCurrentTheme) { setTheme(themeModel) @@ -100,12 +96,6 @@ object ThemeRegistry { @Synchronized fun setTheme(themeModel: ThemeModel) { currentTheme = themeModel - themeChangeListeners.forEach { - it.onChangeTheme(themeModel) - } - if (!themes.contains(themeModel)) { - themes.add(themeModel) - } dispatchThemeChange(themeModel) } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt index 05619d936..5f7b87b1b 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt @@ -24,6 +24,7 @@ package io.github.rosemoe.sora.langs.monarch.registery.dsl +import android.util.Log import io.github.dingyi222666.monarch.language.Language import io.github.dingyi222666.monarch.loader.json.loadMonarchJson import io.github.dingyi222666.monarch.types.IMonarchLanguage @@ -52,7 +53,8 @@ class MonarchLanguageDefinitionListBuilder : val language = Language( monarchLanguage = monarchLanguage, languageName = languageDefinition.name, - languageId = languageDefinition.scopeName ?: "source.${monarchLanguage.tokenPostfix ?: languageDefinition.name}", + languageId = languageDefinition.scopeName + ?: "source.${monarchLanguage.tokenPostfix ?: languageDefinition.name}", fileExtensions = emptyList(), embeddedLanguages = languageDefinition.embeddedLanguages, ) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt index 6dbc374e4..2cbb2b725 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt @@ -57,13 +57,15 @@ class ThemeModel { } } - if (rawThemeString != null) { - value = rawThemeString.toTokenTheme() - if (value.themeType == "dark") { - isDark = true - } + if (rawThemeString == null) { + throw Exception("Theme source is null") } + value = rawThemeString.toTokenTheme() + + if (value.themeType == "dark") { + isDark = true + } } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt index 8e162b9f5..fd028b05c 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt @@ -45,7 +45,6 @@ class ColorMap { return id2color.getOrNull(id) } - val colorMap: List get() = id2color.toList() diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt index c1db1b448..e079d4039 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt @@ -24,7 +24,10 @@ package io.github.rosemoe.sora.langs.monarch.theme -class ThemeDefaultColors(defaultColors: Map) { +class ThemeDefaultColors( + defaultColors: Map, + val oldTextMateStyle: Boolean = false +) { private val colors = mutableMapOf() init { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt index 9046b2c59..83afbf154 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt @@ -58,6 +58,9 @@ class TokenTheme internal constructor( val standardToken = token.toStandardTokenType() (rule.metadata or (standardToken shl MetadataConsts.TOKEN_TYPE_OFFSET)) } + if (token.isNotEmpty()) { + println("token: $token, result: $result") + } return result } @@ -67,7 +70,7 @@ class TokenTheme internal constructor( override fun toString(): String { - return "TokenTheme(colorMap=$colorMap, root=$root, themeDefaultColors=$themeDefaultColors, themeType='$themeType', cache=$cache)" + return "TokenTheme(name=$name, colorMap=$colorMap, root=$root, themeDefaultColors=$themeDefaultColors, themeType='$themeType', cache=$cache)" } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt index 4b66580d7..e0e3d311c 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt @@ -28,12 +28,9 @@ import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonReader import com.squareup.moshi.JsonWriter import com.squareup.moshi.Moshi -import io.github.dingyi222666.monarch.language.Language import io.github.dingyi222666.monarch.loader.json.addLast import io.github.rosemoe.sora.langs.monarch.languageconfiguration.LanguageConfigurationAdapter import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration -import io.github.rosemoe.sora.langs.monarch.registery.grammardefinition.MonarchGrammarDefinitionReader -import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition class TokenThemeAdapter : JsonAdapter() { override fun fromJson(reader: JsonReader): TokenTheme { @@ -42,6 +39,7 @@ class TokenThemeAdapter : JsonAdapter() { val themeColorsMap = mutableMapOf() var themeType = "light" var themeName = "" + var isOldTextMateTheme = false // ignore name @@ -58,11 +56,12 @@ class TokenThemeAdapter : JsonAdapter() { } "colors" -> { - reader.beginObject() - while (reader.hasNext()) { - themeColorsMap[reader.nextName()] = reader.nextString() - } - reader.endObject() + readThemeColors(reader, themeColorsMap) + } + + "settings" -> { + isOldTextMateTheme = true + readTextMateTokenColors(reader, tokenThemeRuleList, themeColorsMap) } "name" -> { @@ -77,16 +76,31 @@ class TokenThemeAdapter : JsonAdapter() { reader.endObject() + println("$themeName $tokenThemeRuleList") + return TokenTheme.createFromRawTokenTheme( tokenThemeRuleList, emptyList(), - ThemeDefaultColors(themeColorsMap), + ThemeDefaultColors(themeColorsMap, isOldTextMateTheme), themeType, themeName ) } + private fun readThemeColors( + reader: JsonReader, + themeColorsMap: MutableMap + ) { + reader.beginObject() + + while (reader.hasNext()) { + val key = reader.nextName() + themeColorsMap[key] = reader.nextString() + } + + reader.endObject() + } private fun readTokenColors( reader: JsonReader, @@ -95,67 +109,135 @@ class TokenThemeAdapter : JsonAdapter() { reader.beginArray() while (reader.hasNext()) { - reader.beginObject() - val tokenList = mutableListOf() - var foreground: String? = null - var background: String? = null - var fontStyle: String? = null - - while (reader.hasNext()) { - when (reader.nextName()) { - "scope" -> { - if (reader.peek() == JsonReader.Token.BEGIN_ARRAY) { - reader.beginArray() - while (reader.hasNext()) { - tokenList.add(reader.nextString()) - } - reader.endArray() - } else { - tokenList.add(reader.nextString()) - } - } + readTokenColor(reader, tokenThemeRuleList) + } + + reader.endArray() + } + + private fun readTokenColor( + reader: JsonReader, + tokenThemeRuleList: MutableList + ) { + reader.beginObject() + val tokenList = mutableListOf() + var foreground: String? = null + var background: String? = null + var fontStyle: String? = null + + val processToken = { token: String -> + if (token.contains(",")) { + tokenList.addAll(token.split(",").map { + it.trim() + }) + } else { + tokenList.add(token) + } + } - "settings" -> { - reader.beginObject() + while (reader.hasNext()) { + when (reader.nextName()) { + "scope" -> { + if (reader.peek() == JsonReader.Token.BEGIN_ARRAY) { + reader.beginArray() while (reader.hasNext()) { - when (reader.nextName()) { - "foreground" -> { - foreground = reader.nextString() - } - - "background" -> { - background = reader.nextString() - } - - "fontStyle" -> { - fontStyle = reader.nextString() - } - } + processToken(reader.nextString()) } - reader.endObject() + reader.endArray() + } else { + val token = reader.nextString() + + processToken(token) } + } - else -> { - reader.skipValue() + "settings" -> { + reader.beginObject() + while (reader.hasNext()) { + when (reader.nextName()) { + "foreground" -> { + foreground = reader.nextString() + } + + "background" -> { + background = reader.nextString() + } + + "fontStyle" -> { + fontStyle = reader.nextString() + } + } } + reader.endObject() } + else -> { + reader.skipValue() + } } - if (tokenList.isNotEmpty()) { - for (token in tokenList) { - tokenThemeRuleList.add( - TokenThemeRule( - token, - foreground, - background, - fontStyle - ) - ) - } + } + + reader.endObject() + + if (tokenList.isEmpty()) { + return + } + + for (token in tokenList) { + tokenThemeRuleList.add( + TokenThemeRule( + token, + foreground, + background, + fontStyle + ) + ) + } + + + } + + private fun readTextMateTokenColors( + reader: JsonReader, + tokenThemeRuleList: MutableList, + themeColorsMap: MutableMap + ) { + reader.beginArray() + + // "settings": [{ + // "settings": { + // "background": "#242424", + // "foreground": "#cccccc", + // "lineHighlight": "#2B2B2B", + // "selection": "#214283", + // "highlightedDelimetersForeground": "#57f6c0" + // } + // }, + // { + // "name": "Comment", + // "scope": "comment", + // "settings": { + // "foreground": "#707070" + // } + // }, + + // object 0: settings object + + reader.beginObject() + + while (reader.hasNext()) { + if (reader.nextName() == "settings") { + readThemeColors(reader, themeColorsMap) } + } - reader.endObject() + reader.endObject() + + // other: object + + while (reader.hasNext()) { + readTokenColor(reader, tokenThemeRuleList) } reader.endArray() @@ -169,7 +251,6 @@ internal val MoshiRoot: Moshi = Moshi.Builder() .apply { addLast(TokenThemeAdapter()) addLast(LanguageConfigurationAdapter()) - } .build() diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt index 1d75dd5a4..31b5fa03f 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt @@ -75,7 +75,7 @@ fun List.resolveParsedTokenThemeRules( var defaultBackground = "#ffffff" while (parsedThemeRules.isNotEmpty() && parsedThemeRules[0].token == "") { val incomingDefaults = parsedThemeRules[0] - parsedThemeRules.removeFirst() + parsedThemeRules.removeAt(0) if (incomingDefaults.fontStyle != FontStyle.NotSet) { defaultFontStyle = incomingDefaults.fontStyle } @@ -107,5 +107,5 @@ fun List.resolveParsedTokenThemeRules( ) } - return TokenTheme(colorMap, root, themeDefaultColors, themeType, name) + return TokenTheme(colorMap, root, themeDefaultColors, name, themeType) } \ No newline at end of file From 4838ea85a403832203991ec251ce82f8d8d48642 Mon Sep 17 00:00:00 2001 From: dingyi Date: Wed, 25 Sep 2024 07:04:45 +0800 Subject: [PATCH 25/40] refactor(language-monarch): enhance theme loading and handle empty tokens Adjust the theme loading function to collect colors into a map when provided with a nullthemeColorsMap. This change simplifies theme loading logic and avoids unnecessary skipping of values. Additionally, modify the token color reading function to add a default empty token, ensuring that at least one token is always present. This prevents potential runtime issues due to empty token lists. --- .../github/rosemoe/sora/app/MainActivity.kt | 10 ++++ language-monarch/README.md | 58 ++++++++++++++++++- .../langs/monarch/MonarchNewlineHandler.kt | 5 +- .../langs/monarch/theme/ThemeTrieElement.kt | 2 +- .../sora/langs/monarch/theme/TokenTheme.kt | 46 +++++++++++++-- .../sora/langs/monarch/theme/loader.kt | 38 ++++++++---- .../sora/langs/monarch/utils/string.kt | 2 +- 7 files changed, 141 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt b/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt index 3d135baa1..4d3a7cc0b 100644 --- a/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt +++ b/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt @@ -45,6 +45,7 @@ import androidx.lifecycle.lifecycleScope import io.github.dingyi222666.monarch.languages.JavaLanguage import io.github.dingyi222666.monarch.languages.KotlinLanguage import io.github.dingyi222666.monarch.languages.PythonLanguage +import io.github.dingyi222666.monarch.languages.TypescriptLanguage import io.github.rosemoe.sora.app.databinding.ActivityMainBinding import io.github.rosemoe.sora.app.tests.TestActivity import io.github.rosemoe.sora.event.ContentChangeEvent @@ -395,9 +396,11 @@ class MainActivity : AppCompatActivity() { * Load default languages from Monarch */ private fun loadDefaultMonarchLanguages() { + MonarchGrammarRegistry.INSTANCE.loadGrammar(Lan) MonarchGrammarRegistry.INSTANCE.loadGrammars( monarchLanguages { language("java") { + monarchLanguage = JavaLanguage defaultScopeName() languageConfiguration = "textmate/java/language-configuration.json" @@ -412,6 +415,11 @@ class MainActivity : AppCompatActivity() { defaultScopeName() languageConfiguration = "textmate/python/language-configuration.json" } + language("typescript") { + monarchLanguage = TypescriptLanguage + defaultScopeName() + languageConfiguration = "textmate/javascript/language-configuration.json" + } } ) } @@ -820,6 +828,7 @@ class MainActivity : AppCompatActivity() { "Monarch Java", "Monarch Kotlin", "Monarch Python", + "Monarch TypeScript", "Text" ) val tmLanguages = mapOf( @@ -835,6 +844,7 @@ class MainActivity : AppCompatActivity() { "Monarch Java" to "source.java", "Monarch Kotlin" to "source.kotlin", "Monarch Python" to "source.python", + "Monarch TypeScript" to "source.typescript" ) AlertDialog.Builder(this) diff --git a/language-monarch/README.md b/language-monarch/README.md index c3e33b18d..c3229f46d 100644 --- a/language-monarch/README.md +++ b/language-monarch/README.md @@ -1,3 +1,59 @@ +# language-monarch + +**Work In Progress** + ## About -**Work In Progress** \ No newline at end of file +The `language-monarch` module is a dynamic syntax highlighting and functionality module based on the [Monarch syntax definition](https://microsoft.github.io/monaco-editor/monarch.html) of the Monaco editor. + +## Comparison with the Textmate Module + +1. Monarch uses simpler regular expression syntax, suitable for general cases where complex information is not required for code highlighting. +2. Compared to the Textmate module, Monarch may offer a 10% to 40% speed improvement in rendering for the same language (due to simpler syntax definitions and fewer regular expressions). +3. You can use Kotlin to [write syntax definitions](https://github.com/dingyi222666/monarch-kt/blob/main/monarch-language-pack/src/main/kotlin/io/github/dingyi222666/monarch/languages/LanguageKotlin.kt) instead of dynamically loading grammar files. + +## Features (Already Available) + +1. File highlighting based on syntax rules +2. Load color themes from files +3. Code block lines based on indentation and rules + +## How to Get Syntax and Theme Files + +### Syntax Packs + +You can obtain syntax packs from [monarch-kt](https://github.com/dingyi222666/monarch-kt/tree/main/monarch-language-pack/src/main/resources/language_packs). Syntax packs are available in both Kotlin and JSON versions. + +#### Kotlin Version Example: + +```kotlin +import io.github.dingyi222666.monarch.languages.KotlinLanguage + +MonarchGrammarRegistry.INSTANCE.loadGrammars( + monarchLanguages { + language("kotlin") { + monarchLanguage = KotlinLanguage + defaultScopeName() + languageConfiguration = "textmate/kotlin/language-configuration.json" + } + } +) +``` + +#### JSON Version Example: +```kotlin +MonarchGrammarRegistry.INSTANCE.loadGrammars( + monarchLanguages { + language("kotlin") { + grammar = "xxx/kotlin.json" + defaultScopeName() + languageConfiguration = "textmate/kotlin/language-configuration.json" + } + } +) +``` + + +### Theme Files + +We have attempted to make theme files compatible with Textmate themes. Therefore, by default, you can directly use Textmate theme files. \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt index 7d5e2086a..7f51aba48 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt @@ -376,11 +376,12 @@ class MonarchNewlineHandler( ): InheritIndentResult? { // https://github.com/microsoft/vscode/blob/bf63ea1932dd253745f38a4cbe26bb9be01801b1/src/vs/editor/common/languages/autoIndent.ts#L73 - val indentRulesSupport = requireNotNull(indentRulesSupport) - if (line < 1) { + if (line < 1 || indentRulesSupport == null) { return InheritIndentResult("", 0) } + val indentRulesSupport = requireNotNull(indentRulesSupport) + val precedingUnIgnoredLine = getPrecedingValidLine(model, line) if (precedingUnIgnoredLine < 0) { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt index 1f8b622c9..e2f1260c7 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt @@ -24,7 +24,7 @@ package io.github.rosemoe.sora.langs.monarch.theme -class ThemeTrieElement(private val mainRule: ThemeTrieElementRule) { +open class ThemeTrieElement(val mainRule: ThemeTrieElementRule) { private val children = mutableMapOf() fun toExternalThemeTrieElement(): ExternalThemeTrieElement { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt index 83afbf154..80f1f3aed 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt @@ -36,7 +36,7 @@ class TokenTheme internal constructor( private val themeDefaultColors: ThemeDefaultColors = ThemeDefaultColors.EMPTY, val name: String = "default", val themeType: String = "light" -): ITokenTheme { +) : ITokenTheme { private val cache = mutableMapOf() val colorMap: ColorMap @@ -54,13 +54,49 @@ class TokenTheme internal constructor( fun match(token: String): Int { val result = cache.getOrPut(token) { - val rule = _match(token) + var rule = _match(token) + + if (rule === root.mainRule) { + when { + // monarch -> textmate + token.startsWith("identifier") -> { + // ? + rule = _match(token.replace("identifier", "source")) + } + + token.startsWith("attribute") -> { + rule = _match(token.replace("attribute", "entity.other.attribute-name")) + } + + token.startsWith("regexp") -> { + rule = _match(token.replace("regexp", "string.regexp")) + } + + token.startsWith("type") -> { + rule = _match(token.replace("type", "entity.name.type")) + } + + token.startsWith("delimiter") -> { + rule = _match(token.replace("delimiter", "punctuation")) + } + + token.startsWith("annotation") -> { + rule = _match(token.replace("annotation", "storage.type.annotation")) + } + + token.startsWith("tag") -> { + rule = _match(token.replace("tag", "entity.name.tag")) + } + + token.startsWith("number") -> { + rule = _match(token.replace("number", "constant.numeric")) + } + } + } + val standardToken = token.toStandardTokenType() (rule.metadata or (standardToken shl MetadataConsts.TOKEN_TYPE_OFFSET)) } - if (token.isNotEmpty()) { - println("token: $token, result: $result") - } return result } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt index e0e3d311c..ce2c6d86d 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt @@ -117,7 +117,8 @@ class TokenThemeAdapter : JsonAdapter() { private fun readTokenColor( reader: JsonReader, - tokenThemeRuleList: MutableList + tokenThemeRuleList: MutableList, + themeColorsMap: MutableMap? = null ) { reader.beginObject() val tokenList = mutableListOf() @@ -154,7 +155,7 @@ class TokenThemeAdapter : JsonAdapter() { "settings" -> { reader.beginObject() while (reader.hasNext()) { - when (reader.nextName()) { + when (val key = reader.nextName()) { "foreground" -> { foreground = reader.nextString() } @@ -166,6 +167,14 @@ class TokenThemeAdapter : JsonAdapter() { "fontStyle" -> { fontStyle = reader.nextString() } + + else -> { + if (themeColorsMap != null) { + themeColorsMap[key] = reader.nextString() + } else { + reader.skipValue() + } + } } } reader.endObject() @@ -181,7 +190,7 @@ class TokenThemeAdapter : JsonAdapter() { reader.endObject() if (tokenList.isEmpty()) { - return + tokenList.add("") } for (token in tokenList) { @@ -195,6 +204,21 @@ class TokenThemeAdapter : JsonAdapter() { ) } + val updates = mapOf( + "foreground" to foreground, + "background" to background, + "fontStyle" to fontStyle + ) + + if (themeColorsMap == null) return + + updates + .filterValues { it != null } + .mapValues { requireNotNull(it.value) } + .let { + themeColorsMap.putAll(it) + } + } @@ -224,15 +248,9 @@ class TokenThemeAdapter : JsonAdapter() { // object 0: settings object - reader.beginObject() - while (reader.hasNext()) { - if (reader.nextName() == "settings") { - readThemeColors(reader, themeColorsMap) - } - } + readTokenColor(reader, tokenThemeRuleList, themeColorsMap) - reader.endObject() // other: object diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt index c1fe96e37..2ada136bd 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/utils/string.kt @@ -47,7 +47,7 @@ fun String.checkSurrogate(): Boolean { * If the string contains only whitespaces, returns entire string */ fun String.getLeadingWhitespace(start: Int = 0, end: Int = length): String { - for (index in start..end) { + for (index in start until end) { val chCode = this[index].code if (chCode != CharCode.Space && chCode != CharCode.Tab) { return substring(start, index) From 159ae98f27ca2b55270176e85ed0c74d0bc1037a Mon Sep 17 00:00:00 2001 From: dingyi Date: Wed, 25 Sep 2024 07:12:33 +0800 Subject: [PATCH 26/40] refactor(versions): remove whitespace from libs.versions consistency and adhere to coding standards. --- gradle/libs.versions.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0db4c8cc1..7a9d07234 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,9 +16,9 @@ androidx-test-espresso = { module = "androidx.test.espresso:espresso-core", vers desugar = { module = "com.android.tools:desugar_jdk_libs", version = "2.0.4" } kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version = "1.8.0" } kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } -lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version = "2.7.0" } -material = { module = "com.google.android.material:material", version = "1.11.0" } -gms-instantapps = { module = "com.google.android.gms:play-services-instantapps", version = "18.0.1" } +lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version = "2.7.0"} +material = { module = "com.google.android.material:material", version = "1.11.0"} +gms-instantapps = { module = "com.google.android.gms:play-services-instantapps", version = "18.0.1"} tree-sitter-java = { module = "com.itsaky.androidide.treesitter:tree-sitter-java", version.ref = "tsBinding" } tree-sitter = { module = "com.itsaky.androidide.treesitter:android-tree-sitter", version.ref = "tsBinding" } lsp4j = { module = "org.eclipse.lsp4j:org.eclipse.lsp4j", version.ref = "lsp4j" } From 8cc5c2a405cd65d578a0435b63863d00957699f2 Mon Sep 17 00:00:00 2001 From: dingyi Date: Wed, 25 Sep 2024 10:52:49 +0800 Subject: [PATCH 27/40] feat(language-monarch): update regex library versions and adjust regex implementation Update the regex libraries to the latest versions and modify the implementation in the MonarchLanguage class to support the additional regex features. Additionally, refactor the JSON parsing logic in the AutoClosingPairConditional loading process for better clarity. --- .../java/io/github/rosemoe/sora/app/MainActivity.kt | 2 -- gradle/libs.versions.toml | 9 +++++---- language-monarch/build.gradle.kts | 1 + .../rosemoe/sora/langs/monarch/MonarchLanguage.kt | 6 ++++++ .../sora/langs/monarch/languageconfiguration/loader.kt | 10 ++++++++-- .../registery/dsl/MonarchGrammarDefinitionDSL.kt | 6 ++++-- 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt b/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt index 4d3a7cc0b..f034713af 100644 --- a/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt +++ b/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt @@ -396,11 +396,9 @@ class MainActivity : AppCompatActivity() { * Load default languages from Monarch */ private fun loadDefaultMonarchLanguages() { - MonarchGrammarRegistry.INSTANCE.loadGrammar(Lan) MonarchGrammarRegistry.INSTANCE.loadGrammars( monarchLanguages { language("java") { - monarchLanguage = JavaLanguage defaultScopeName() languageConfiguration = "textmate/java/language-configuration.json" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7a9d07234..5915dc8fd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -30,10 +30,11 @@ joni = { module = "org.jruby.joni:joni", version = "2.2.1" } snakeyaml-engine = { module = "org.snakeyaml:snakeyaml-engine", version = "2.7" } moshi = { module = "com.squareup.moshi:moshi", version = "1.15.0" } jdt-annotation = { module = "org.eclipse.jdt:org.eclipse.jdt.annotation", version = "2.3.0" } -monarch-code = { module = "io.github.dingyi222666.monarch:monarch", version = "1.0.1" } -monarch-language-pack = { module = "io.github.dingyi222666.monarch:monarch-language-pack", version = "1.0.1" } -monarch-json = { module = "io.github.dingyi222666.monarch:monarch-json-loader", version = "1.0.1" } -regex-onig = { module = "io.github.dingyi222666.regex-lib:regex-lib-oniguruma", version = "1.0.1" } +monarch-code = { module = "io.github.dingyi222666.monarch:monarch", version = "1.0.3" } +monarch-language-pack = { module = "io.github.dingyi222666.monarch:monarch-language-pack", version = "1.0.2" } +monarch-json = { module = "io.github.dingyi222666.monarch:monarch-json-loader", version = "1.0.2" } +regex-onig = { module = "io.github.dingyi222666.regex-lib:regex-lib-oniguruma", version = "1.0.2" } +regex-re2j = { module = "io.github.dingyi222666.regex-lib:regex-lib-re2j", version = "1.0.2" } tests-google-truth = { module = "com.google.truth:truth", version = "1.4.2" } tests-robolectric = { module = "org.robolectric:robolectric", version = "4.11.1" } diff --git a/language-monarch/build.gradle.kts b/language-monarch/build.gradle.kts index 5caf22ad6..18b4997a6 100644 --- a/language-monarch/build.gradle.kts +++ b/language-monarch/build.gradle.kts @@ -56,6 +56,7 @@ dependencies { api(libs.monarch.code) api(libs.monarch.json) api(libs.regex.onig) + api(libs.regex.re2j) implementation(libs.moshi) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt index 242fb38a0..affe77e57 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt @@ -26,6 +26,9 @@ package io.github.rosemoe.sora.langs.monarch import android.os.Bundle import io.github.dingyi222666.monarch.language.Language +import io.github.dingyi222666.regex.GlobalRegexLib +import io.github.dingyi222666.regex.oniguruma.OnigRegexLib +import io.github.dingyi222666.regex.regex.re2j.Re2JRegexLib import io.github.rosemoe.sora.lang.EmptyLanguage import io.github.rosemoe.sora.lang.analysis.AnalyzeManager import io.github.rosemoe.sora.lang.completion.CompletionHelper @@ -228,5 +231,8 @@ class MonarchLanguage( ) } + init { + //GlobalRegexLib.defaultRegexLib = Re2JRegexLib() + } } } \ No newline at end of file diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt index 6871fc18c..cf08dead4 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt @@ -140,9 +140,15 @@ class LanguageConfigurationAdapter : JsonAdapter() { val list = mutableListOf() while (reader.hasNext()) { - val pair = readAutoClosingPairConditional(reader, false) + if (reader.peek() == JsonReader.Token.BEGIN_OBJECT) { + val pair = readAutoClosingPairConditional(reader, false) - list.add(pair) + list.add(pair) + } else { + val pair = readAutoClosingPair(reader, false) + + list.add(AutoClosingPairConditional(pair.open, pair.close, emptyList())) + } } reader.endArray() diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt index 5f7b87b1b..a08f46acd 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt @@ -62,11 +62,13 @@ class MonarchLanguageDefinitionListBuilder : val languageConfiguration = languageDefinition.languageConfiguration?.let { configuration -> kotlin.runCatching { configuration.toLanguageConfiguration() - }.getOrNull() ?: runCatching { + } + .getOrNull() ?: runCatching { FileProviderRegistry.resolve(languageDefinition.languageConfiguration ?: "")?.use { it.bufferedReader().readText() }?.toLanguageConfiguration() - }.getOrNull() + } + .getOrNull() } From 09b2f5ba858a0e521444be4541eb1c3732e7d9a0 Mon Sep 17 00:00:00 2001 From: dingyi Date: Wed, 25 Sep 2024 11:00:26 +0800 Subject: [PATCH 28/40] chore: cleanup code in `AsyncIncrementalAnalyzeManager` - Remove unnecessary logging statements in AsyncIncrementalAnalyzeManager to clean up the code. - Adjust if-statement formatting for consistency and better readability. - Eliminate unused code segments in JsonParseTests and adjust import statements. - Ensure consistent code formatting across the specified files for enhanced maintainability. --- .../lang/analysis/AsyncIncrementalAnalyzeManager.java | 6 ++---- .../rosemoe/sora/langs/monarch/MonarchColorScheme.kt | 3 --- .../github/rosemoe/sora/langs/monarch/theme/loader.kt | 2 -- language-monarch/src/test/kotlin/JsonParseTests.kt | 11 ++++++----- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/editor/src/main/java/io/github/rosemoe/sora/lang/analysis/AsyncIncrementalAnalyzeManager.java b/editor/src/main/java/io/github/rosemoe/sora/lang/analysis/AsyncIncrementalAnalyzeManager.java index 550a22287..384ad4afa 100644 --- a/editor/src/main/java/io/github/rosemoe/sora/lang/analysis/AsyncIncrementalAnalyzeManager.java +++ b/editor/src/main/java/io/github/rosemoe/sora/lang/analysis/AsyncIncrementalAnalyzeManager.java @@ -461,11 +461,9 @@ private void initialize() { styles.blocks = computeBlocks(shadowed, delegate); styles.setSuppressSwitch(delegate.suppressSwitch); styles.finishBuilding(); - if (!abort) { - sendNewStyles(styles); - } - Log.e("AsyncAnalysis", "Analyze finished in " + (System.currentTimeMillis() - time) + "ms"); + if (!abort) + sendNewStyles(styles); } public boolean handleMessage(@NonNull Message msg) { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt index 3a2f4d2e7..970b0f48d 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt @@ -70,11 +70,8 @@ class MonarchColorScheme( themeModel.load() } - val value = themeModel.value - println("current theme: ${value.defaults.oldTextMateStyle}, name: ${value.name}, loaded: ${themeModel.isLoaded}") - if (value.defaults.oldTextMateStyle) { applyTMTheme(value.defaults) } else { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt index ce2c6d86d..0f01c62b0 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt @@ -76,8 +76,6 @@ class TokenThemeAdapter : JsonAdapter() { reader.endObject() - println("$themeName $tokenThemeRuleList") - return TokenTheme.createFromRawTokenTheme( tokenThemeRuleList, emptyList(), diff --git a/language-monarch/src/test/kotlin/JsonParseTests.kt b/language-monarch/src/test/kotlin/JsonParseTests.kt index a8f65127f..c60a67bb6 100644 --- a/language-monarch/src/test/kotlin/JsonParseTests.kt +++ b/language-monarch/src/test/kotlin/JsonParseTests.kt @@ -1,8 +1,3 @@ -import io.github.rosemoe.sora.langs.monarch.theme.toLanguageConfiguration -import io.github.rosemoe.sora.langs.monarch.theme.toTokenTheme -import org.junit.Test -import java.io.File - /******************************************************************************* * sora-editor - the awesome code editor for Android * https://github.com/Rosemoe/sora-editor @@ -27,6 +22,12 @@ import java.io.File * additional information or have any questions ******************************************************************************/ +import io.github.rosemoe.sora.langs.monarch.theme.toLanguageConfiguration +import io.github.rosemoe.sora.langs.monarch.theme.toTokenTheme +import org.junit.Test +import java.io.File + + class JsonParseTests { @Test From 4bb11d7a329d5204e9ab111b656015d1f8915bef Mon Sep 17 00:00:00 2001 From: dingyi Date: Sat, 7 Dec 2024 06:34:39 +0800 Subject: [PATCH 29/40] refactor(language-monarch): merge surroundingPairs into autoClosingPairs This commit merges `surroundingPairs` into `autoClosingPairs` in Monarch language configuration to simplify symbol pair matching. The logic for handling symbol pairs has been updated to consider both `surroundingPairs` and `autoClosingPairs` when determining matching pairs. If a pair is defined in both lists, the `notIn` property from both definitions is merged. Additionally, the behavior of auto-closing pairs has been refined. Now, auto-closing pairs will not be completed if no text is selected, preventing unintended insertions. This change aligns the behavior with common editor practices and improves user experience. --- .../langs/monarch/MonarchSymbolPairMatch.kt | 79 ++++++++++--------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt index 49bf18bf8..365398eb2 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt @@ -27,6 +27,7 @@ package io.github.rosemoe.sora.langs.monarch import io.github.dingyi222666.monarch.types.StandardTokenType import io.github.rosemoe.sora.lang.styling.Span import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.AutoClosingPairConditional +import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.BaseAutoClosingPair import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration import io.github.rosemoe.sora.text.Content import io.github.rosemoe.sora.text.ContentLine @@ -70,19 +71,22 @@ class MonarchSymbolPairMatch( languageConfiguration.surroundingPairs ?: emptyList() val autoClosingPairs: List = - languageConfiguration.autoClosingPairs ?: emptyList() + languageConfiguration.autoClosingPairs?.toMutableList() ?: emptyList() - val mergePairs = - mutableListOf() - - mergePairs.addAll(autoClosingPairs) + val pairs = mutableMapOf() + autoClosingPairs.forEach { + pairs[it.open] = SymbolPair( + it.open, + it.close, + SymbolPairEx(it, false) + ) + } for (surroundingPair in surroundingPairs) { - - val originAutoClosingPair = mergePairs.find { + val originAutoClosingPair = autoClosingPairs.find { it.open == surroundingPair.open && it.close == surroundingPair.close - } + } as? AutoClosingPairConditional val surroundingPairNotInList = if (surroundingPair is AutoClosingPairConditional) { surroundingPair.notIn @@ -90,46 +94,39 @@ class MonarchSymbolPairMatch( if (originAutoClosingPair == null) { - mergePairs.add( - AutoClosingPairConditional( - surroundingPair.open, - surroundingPair.close, - surroundingPairNotInList, - true - ) + pairs[surroundingPair.open] = SymbolPair( + surroundingPair.open, + surroundingPair.close, + SymbolPairEx(surroundingPair, false) ) continue } - mergePairs.remove(originAutoClosingPair) - mergePairs.add( - AutoClosingPairConditional( - surroundingPair.open, - surroundingPair.close, - (surroundingPairNotInList + originAutoClosingPair.notIn).distinct(), - true - ) + pairs.remove(surroundingPair.open) + val pair = AutoClosingPairConditional( + surroundingPair.open, + surroundingPair.close, + (surroundingPairNotInList + originAutoClosingPair.notIn).distinct(), + true ) + pairs[pair.open] = SymbolPair( + pair.open, + pair.close, + SymbolPairEx(pair, true) + ) + } - mergePairs.forEach { - putPair( - it.open, - SymbolPair( - it.open, - it.close, - SymbolPairEx(it) - ) - ) - } - - + pairs.forEach { + putPair(it.key, it.value) } + } class SymbolPairEx( - autoClosingPairConditional: AutoClosingPairConditional + private val autoClosingPairConditional: BaseAutoClosingPair, + private val isAutoClosingPair: Boolean ) : SymbolPair.SymbolPairEx { @@ -139,7 +136,10 @@ class MonarchSymbolPairMatch( init { run { - val excludeTokenTypeList = autoClosingPairConditional.notIn.toMutableList() + val excludeTokenTypeList = + if (autoClosingPairConditional is AutoClosingPairConditional) + autoClosingPairConditional.notIn.toMutableList() + else emptyList() if (excludeTokenTypeList.isEmpty()) { excludeTokenTypesArray = null @@ -175,6 +175,11 @@ class MonarchSymbolPairMatch( return isSurroundingPair } + // No text was selected, so should not complete surrounding pair + if (!isAutoClosingPair) { + return false; + } + val excludedTokenTypes = excludeTokenTypesArray ?: return true val cursor = editor.cursor From b88bde23a6d0da581e8427da42c5eed02bc62c90 Mon Sep 17 00:00:00 2001 From: dingyi Date: Sat, 7 Dec 2024 06:35:04 +0800 Subject: [PATCH 30/40] build: upgrade regex-lib-oniguruma to 1.0.3 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5915dc8fd..fdafcc653 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -33,7 +33,7 @@ jdt-annotation = { module = "org.eclipse.jdt:org.eclipse.jdt.annotation", versio monarch-code = { module = "io.github.dingyi222666.monarch:monarch", version = "1.0.3" } monarch-language-pack = { module = "io.github.dingyi222666.monarch:monarch-language-pack", version = "1.0.2" } monarch-json = { module = "io.github.dingyi222666.monarch:monarch-json-loader", version = "1.0.2" } -regex-onig = { module = "io.github.dingyi222666.regex-lib:regex-lib-oniguruma", version = "1.0.2" } +regex-onig = { module = "io.github.dingyi222666.regex-lib:regex-lib-oniguruma", version = "1.0.3" } regex-re2j = { module = "io.github.dingyi222666.regex-lib:regex-lib-re2j", version = "1.0.2" } tests-google-truth = { module = "com.google.truth:truth", version = "1.4.2" } From 38cf7b1ba11586190e89d59a4e6c1738092603ca Mon Sep 17 00:00:00 2001 From: dingyi Date: Sat, 7 Dec 2024 06:47:11 +0800 Subject: [PATCH 31/40] fix(language-monarch): correct symbol pair matching behavior This commit fixes an issue where auto-closing pairs defined in Monarch language configurations were not being properly matched due to an incorrect flag in the SymbolPairEx initialization. The isMonarch flag is now correctly set to true, ensuring that auto-closing pair logic functions as intended within Monarch language definitions. --- .../github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt index 365398eb2..3c508bc61 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchSymbolPairMatch.kt @@ -79,7 +79,7 @@ class MonarchSymbolPairMatch( pairs[it.open] = SymbolPair( it.open, it.close, - SymbolPairEx(it, false) + SymbolPairEx(it, true) ) } From eed25d1d857a5ba7902b2626320d38a453eb4d79 Mon Sep 17 00:00:00 2001 From: Rosemoe <2073412493@qq.com> Date: Mon, 9 Dec 2024 11:58:05 +0800 Subject: [PATCH 32/40] refact(lang-monarch): rename typo in package name --- .../github/rosemoe/sora/app/MainActivity.kt | 19 +++++++++--------- .../java/io/github/rosemoe/sora/app/Utils.kt | 4 ++-- .../sora/langs/monarch/MonarchAnalyzer.kt | 6 +++--- .../sora/langs/monarch/MonarchColorScheme.kt | 8 ++++---- .../sora/langs/monarch/MonarchLanguage.kt | 7 ++----- .../FileProviderRegistry.kt | 4 ++-- .../GrammarRegistry.kt | 10 +++++----- .../MonarchGrammarRegistry.kt | 20 +++++-------------- .../{registery => registry}/ThemeRegistry.kt | 6 +++--- .../dsl/GrammarDefinitionDSL.kt | 4 ++-- .../dsl/MonarchGrammarDefinitionDSL.kt | 9 +++------ .../GrammarDefinitionReader.kt | 6 +++--- .../MonarchGrammarDefinitionReader.kt | 8 +++----- .../model/GrammarDefinition.kt | 2 +- .../model/ThemeModel.kt | 4 ++-- .../provider/AssetsFileResolver.kt | 2 +- .../provider/FileResolver.kt | 2 +- 17 files changed, 52 insertions(+), 69 deletions(-) rename language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/{registery => registry}/FileProviderRegistry.kt (93%) rename language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/{registery => registry}/GrammarRegistry.kt (95%) rename language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/{registery => registry}/MonarchGrammarRegistry.kt (73%) rename language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/{registery => registry}/ThemeRegistry.kt (95%) rename language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/{registery => registry}/dsl/GrammarDefinitionDSL.kt (94%) rename language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/{registery => registry}/dsl/MonarchGrammarDefinitionDSL.kt (93%) rename language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/{registery => registry}/grammardefinition/GrammarDefinitionReader.kt (95%) rename language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/{registery => registry}/grammardefinition/MonarchGrammarDefinitionReader.kt (88%) rename language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/{registery => registry}/model/GrammarDefinition.kt (95%) rename language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/{registery => registry}/model/ThemeModel.kt (94%) rename language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/{registery => registry}/provider/AssetsFileResolver.kt (95%) rename language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/{registery => registry}/provider/FileResolver.kt (96%) diff --git a/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt b/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt index f034713af..eeafca7be 100644 --- a/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt +++ b/app/src/main/java/io/github/rosemoe/sora/app/MainActivity.kt @@ -63,9 +63,9 @@ import io.github.rosemoe.sora.lang.diagnostic.DiagnosticsContainer import io.github.rosemoe.sora.langs.java.JavaLanguage import io.github.rosemoe.sora.langs.monarch.MonarchColorScheme import io.github.rosemoe.sora.langs.monarch.MonarchLanguage -import io.github.rosemoe.sora.langs.monarch.registery.MonarchGrammarRegistry -import io.github.rosemoe.sora.langs.monarch.registery.dsl.monarchLanguages -import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeSource +import io.github.rosemoe.sora.langs.monarch.registry.MonarchGrammarRegistry +import io.github.rosemoe.sora.langs.monarch.registry.dsl.monarchLanguages +import io.github.rosemoe.sora.langs.monarch.registry.model.ThemeSource import io.github.rosemoe.sora.langs.textmate.TextMateColorScheme import io.github.rosemoe.sora.langs.textmate.TextMateLanguage import io.github.rosemoe.sora.langs.textmate.registry.FileProviderRegistry @@ -359,8 +359,8 @@ class MainActivity : AppCompatActivity() { */ private fun setupMonarch() { // Add assets file provider so that files in assets can be loaded - io.github.rosemoe.sora.langs.monarch.registery.FileProviderRegistry.addProvider( - io.github.rosemoe.sora.langs.monarch.registery.provider.AssetsFileResolver( + io.github.rosemoe.sora.langs.monarch.registry.FileProviderRegistry.addProvider( + io.github.rosemoe.sora.langs.monarch.registry.provider.AssetsFileResolver( applicationContext.assets // use application context ) ) @@ -378,8 +378,8 @@ class MainActivity : AppCompatActivity() { themes.forEach { name -> val path = "textmate/$name.json" - io.github.rosemoe.sora.langs.monarch.registery.ThemeRegistry.loadTheme( - io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel( + io.github.rosemoe.sora.langs.monarch.registry.ThemeRegistry.loadTheme( + io.github.rosemoe.sora.langs.monarch.registry.model.ThemeModel( ThemeSource(path, name) ).apply { if (name != "quietlight") { @@ -389,7 +389,7 @@ class MainActivity : AppCompatActivity() { ) } - io.github.rosemoe.sora.langs.monarch.registery.ThemeRegistry.setTheme("quietlight") + io.github.rosemoe.sora.langs.monarch.registry.ThemeRegistry.setTheme("quietlight") } /** @@ -493,7 +493,8 @@ class MainActivity : AppCompatActivity() { val editor = binding.editor var editorColorScheme = editor.colorScheme if (editorColorScheme !is MonarchColorScheme) { - editorColorScheme = MonarchColorScheme.create(io.github.rosemoe.sora.langs.monarch.registery.ThemeRegistry.currentTheme) + editorColorScheme = + MonarchColorScheme.create(io.github.rosemoe.sora.langs.monarch.registry.ThemeRegistry.currentTheme) editor.colorScheme = editorColorScheme switchThemeIfRequired(this, editor) } diff --git a/app/src/main/java/io/github/rosemoe/sora/app/Utils.kt b/app/src/main/java/io/github/rosemoe/sora/app/Utils.kt index b2e8c6c3d..22b4b19f0 100644 --- a/app/src/main/java/io/github/rosemoe/sora/app/Utils.kt +++ b/app/src/main/java/io/github/rosemoe/sora/app/Utils.kt @@ -40,7 +40,7 @@ fun switchThemeIfRequired(context: Context, editor: CodeEditor) { if (editor.colorScheme is TextMateColorScheme) { ThemeRegistry.getInstance().setTheme("darcula") } else if (editor.colorScheme is MonarchColorScheme) { - io.github.rosemoe.sora.langs.monarch.registery.ThemeRegistry.setTheme("darcula") + io.github.rosemoe.sora.langs.monarch.registry.ThemeRegistry.setTheme("darcula") } else { editor.colorScheme = SchemeDarcula() } @@ -48,7 +48,7 @@ fun switchThemeIfRequired(context: Context, editor: CodeEditor) { if (editor.colorScheme is TextMateColorScheme) { ThemeRegistry.getInstance().setTheme("quietlight") } else if (editor.colorScheme is MonarchColorScheme) { - io.github.rosemoe.sora.langs.monarch.registery.ThemeRegistry.setTheme("quietlight") + io.github.rosemoe.sora.langs.monarch.registry.ThemeRegistry.setTheme("quietlight") } else { editor.colorScheme = EditorColorScheme() } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt index 8dcbf488e..18d083804 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt @@ -45,9 +45,9 @@ import io.github.rosemoe.sora.lang.styling.TextStyle import io.github.rosemoe.sora.langs.monarch.folding.FoldingHelper import io.github.rosemoe.sora.langs.monarch.folding.IndentRange import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration -import io.github.rosemoe.sora.langs.monarch.registery.ThemeChangeListener -import io.github.rosemoe.sora.langs.monarch.registery.ThemeRegistry -import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel +import io.github.rosemoe.sora.langs.monarch.registry.ThemeChangeListener +import io.github.rosemoe.sora.langs.monarch.registry.ThemeRegistry +import io.github.rosemoe.sora.langs.monarch.registry.model.ThemeModel import io.github.rosemoe.sora.langs.monarch.utils.checkSurrogate import io.github.rosemoe.sora.langs.monarch.utils.convertUnicodeOffsetToUtf16 import io.github.rosemoe.sora.text.Content diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt index 970b0f48d..ac3da71f4 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchColorScheme.kt @@ -25,10 +25,10 @@ package io.github.rosemoe.sora.langs.monarch import android.graphics.Color -import io.github.rosemoe.sora.langs.monarch.registery.ThemeChangeListener -import io.github.rosemoe.sora.langs.monarch.registery.ThemeRegistry -import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel -import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeSource +import io.github.rosemoe.sora.langs.monarch.registry.ThemeChangeListener +import io.github.rosemoe.sora.langs.monarch.registry.ThemeRegistry +import io.github.rosemoe.sora.langs.monarch.registry.model.ThemeModel +import io.github.rosemoe.sora.langs.monarch.registry.model.ThemeSource import io.github.rosemoe.sora.langs.monarch.theme.ThemeDefaultColors import io.github.rosemoe.sora.widget.CodeEditor import io.github.rosemoe.sora.widget.schemes.EditorColorScheme diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt index affe77e57..9bb8c7aa3 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt @@ -26,9 +26,6 @@ package io.github.rosemoe.sora.langs.monarch import android.os.Bundle import io.github.dingyi222666.monarch.language.Language -import io.github.dingyi222666.regex.GlobalRegexLib -import io.github.dingyi222666.regex.oniguruma.OnigRegexLib -import io.github.dingyi222666.regex.regex.re2j.Re2JRegexLib import io.github.rosemoe.sora.lang.EmptyLanguage import io.github.rosemoe.sora.lang.analysis.AnalyzeManager import io.github.rosemoe.sora.lang.completion.CompletionHelper @@ -36,8 +33,8 @@ import io.github.rosemoe.sora.lang.completion.CompletionPublisher import io.github.rosemoe.sora.lang.completion.IdentifierAutoComplete import io.github.rosemoe.sora.lang.smartEnter.NewlineHandler import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration -import io.github.rosemoe.sora.langs.monarch.registery.MonarchGrammarRegistry -import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition +import io.github.rosemoe.sora.langs.monarch.registry.MonarchGrammarRegistry +import io.github.rosemoe.sora.langs.monarch.registry.model.GrammarDefinition import io.github.rosemoe.sora.text.CharPosition import io.github.rosemoe.sora.text.ContentReference import io.github.rosemoe.sora.util.MyCharacter diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/FileProviderRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/FileProviderRegistry.kt similarity index 93% rename from language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/FileProviderRegistry.kt rename to language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/FileProviderRegistry.kt index 7b08fada2..6b37c228c 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/FileProviderRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/FileProviderRegistry.kt @@ -21,9 +21,9 @@ * Please contact Rosemoe by email 2073412493@qq.com if you need * additional information or have any questions */ -package io.github.rosemoe.sora.langs.monarch.registery +package io.github.rosemoe.sora.langs.monarch.registry -import io.github.rosemoe.sora.langs.monarch.registery.provider.FileResolver +import io.github.rosemoe.sora.langs.monarch.registry.provider.FileResolver import java.io.InputStream diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/GrammarRegistry.kt similarity index 95% rename from language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt rename to language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/GrammarRegistry.kt index 20f56f6b5..c513e2584 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/GrammarRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/GrammarRegistry.kt @@ -21,14 +21,14 @@ * Please contact Rosemoe by email 2073412493@qq.com if you need * additional information or have any questions */ -package io.github.rosemoe.sora.langs.monarch.registery +package io.github.rosemoe.sora.langs.monarch.registry import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration -import io.github.rosemoe.sora.langs.monarch.registery.dsl.LanguageDefinitionBuilder -import io.github.rosemoe.sora.langs.monarch.registery.dsl.LanguageDefinitionListBuilder -import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition -import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel +import io.github.rosemoe.sora.langs.monarch.registry.dsl.LanguageDefinitionBuilder +import io.github.rosemoe.sora.langs.monarch.registry.dsl.LanguageDefinitionListBuilder +import io.github.rosemoe.sora.langs.monarch.registry.model.GrammarDefinition +import io.github.rosemoe.sora.langs.monarch.registry.model.ThemeModel abstract class GrammarRegistry { private var parent: GrammarRegistry? = null diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/MonarchGrammarRegistry.kt similarity index 73% rename from language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt rename to language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/MonarchGrammarRegistry.kt index 1e003699d..ff7b5a39e 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/MonarchGrammarRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/MonarchGrammarRegistry.kt @@ -22,28 +22,18 @@ * additional information or have any questions ******************************************************************************/ -package io.github.rosemoe.sora.langs.monarch.registery +package io.github.rosemoe.sora.langs.monarch.registry import com.squareup.moshi.Moshi import io.github.dingyi222666.monarch.language.Language import io.github.dingyi222666.monarch.language.LanguageRegistry -import io.github.dingyi222666.monarch.loader.dsl.splitToRegex import io.github.dingyi222666.monarch.loader.json.addLast import io.github.dingyi222666.monarch.types.IThemeService import io.github.dingyi222666.monarch.types.ITokenTheme -import io.github.rosemoe.sora.langs.monarch.languageconfiguration.LanguageConfigurationAdapter -import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration -import io.github.rosemoe.sora.langs.monarch.registery.dsl.LanguageDefinitionBuilder -import io.github.rosemoe.sora.langs.monarch.registery.dsl.LanguageDefinitionListBuilder -import io.github.rosemoe.sora.langs.monarch.registery.dsl.MonarchLanguageDefinitionBuilder -import io.github.rosemoe.sora.langs.monarch.registery.dsl.MonarchLanguageDefinitionListBuilder -import io.github.rosemoe.sora.langs.monarch.registery.grammardefinition.MonarchGrammarDefinitionReader -import io.github.rosemoe.sora.langs.monarch.registery.grammardefinition.ParsedGrammarDefinitionList -import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition -import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel -import io.github.rosemoe.sora.langs.monarch.theme.MoshiRoot -import io.github.rosemoe.sora.langs.monarch.theme.TokenTheme -import io.github.rosemoe.sora.langs.monarch.theme.TokenThemeAdapter +import io.github.rosemoe.sora.langs.monarch.registry.grammardefinition.MonarchGrammarDefinitionReader +import io.github.rosemoe.sora.langs.monarch.registry.grammardefinition.ParsedGrammarDefinitionList +import io.github.rosemoe.sora.langs.monarch.registry.model.GrammarDefinition +import io.github.rosemoe.sora.langs.monarch.registry.model.ThemeModel import io.github.rosemoe.sora.langs.monarch.theme.adapter import java.io.File diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/ThemeRegistry.kt similarity index 95% rename from language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt rename to language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/ThemeRegistry.kt index 5fcec856f..b9e73df41 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/ThemeRegistry.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/ThemeRegistry.kt @@ -22,11 +22,11 @@ * additional information or have any questions ******************************************************************************/ -package io.github.rosemoe.sora.langs.monarch.registery +package io.github.rosemoe.sora.langs.monarch.registry -import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeModel -import io.github.rosemoe.sora.langs.monarch.registery.model.ThemeSource +import io.github.rosemoe.sora.langs.monarch.registry.model.ThemeModel +import io.github.rosemoe.sora.langs.monarch.registry.model.ThemeSource object ThemeRegistry { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/dsl/GrammarDefinitionDSL.kt similarity index 94% rename from language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt rename to language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/dsl/GrammarDefinitionDSL.kt index 85d39d940..94aa25055 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/GrammarDefinitionDSL.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/dsl/GrammarDefinitionDSL.kt @@ -22,9 +22,9 @@ * additional information or have any questions ******************************************************************************/ -package io.github.rosemoe.sora.langs.monarch.registery.dsl +package io.github.rosemoe.sora.langs.monarch.registry.dsl -import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition +import io.github.rosemoe.sora.langs.monarch.registry.model.GrammarDefinition abstract class LanguageDefinitionListBuilder { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/dsl/MonarchGrammarDefinitionDSL.kt similarity index 93% rename from language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt rename to language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/dsl/MonarchGrammarDefinitionDSL.kt index a08f46acd..3359adbf8 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/dsl/MonarchGrammarDefinitionDSL.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/dsl/MonarchGrammarDefinitionDSL.kt @@ -22,17 +22,14 @@ * additional information or have any questions ******************************************************************************/ -package io.github.rosemoe.sora.langs.monarch.registery.dsl +package io.github.rosemoe.sora.langs.monarch.registry.dsl -import android.util.Log import io.github.dingyi222666.monarch.language.Language import io.github.dingyi222666.monarch.loader.json.loadMonarchJson import io.github.dingyi222666.monarch.types.IMonarchLanguage -import io.github.rosemoe.sora.langs.monarch.registery.FileProviderRegistry -import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition +import io.github.rosemoe.sora.langs.monarch.registry.FileProviderRegistry +import io.github.rosemoe.sora.langs.monarch.registry.model.GrammarDefinition import io.github.rosemoe.sora.langs.monarch.theme.toLanguageConfiguration -import java.io.File -import java.nio.charset.Charset class MonarchLanguageDefinitionListBuilder : diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/GrammarDefinitionReader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/grammardefinition/GrammarDefinitionReader.kt similarity index 95% rename from language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/GrammarDefinitionReader.kt rename to language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/grammardefinition/GrammarDefinitionReader.kt index 07ce10c98..ff878f82f 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/GrammarDefinitionReader.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/grammardefinition/GrammarDefinitionReader.kt @@ -22,14 +22,14 @@ * additional information or have any questions ******************************************************************************/ -package io.github.rosemoe.sora.langs.monarch.registery.grammardefinition +package io.github.rosemoe.sora.langs.monarch.registry.grammardefinition import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonReader import com.squareup.moshi.JsonWriter import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration -import io.github.rosemoe.sora.langs.monarch.registery.FileProviderRegistry -import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition +import io.github.rosemoe.sora.langs.monarch.registry.FileProviderRegistry +import io.github.rosemoe.sora.langs.monarch.registry.model.GrammarDefinition import io.github.rosemoe.sora.langs.monarch.theme.toLanguageConfiguration abstract class GrammarDefinitionReader : JsonAdapter>() { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/MonarchGrammarDefinitionReader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/grammardefinition/MonarchGrammarDefinitionReader.kt similarity index 88% rename from language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/MonarchGrammarDefinitionReader.kt rename to language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/grammardefinition/MonarchGrammarDefinitionReader.kt index 761c42420..fea0579aa 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/grammardefinition/MonarchGrammarDefinitionReader.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/grammardefinition/MonarchGrammarDefinitionReader.kt @@ -22,14 +22,12 @@ * additional information or have any questions ******************************************************************************/ -package io.github.rosemoe.sora.langs.monarch.registery.grammardefinition +package io.github.rosemoe.sora.langs.monarch.registry.grammardefinition -import com.squareup.moshi.JsonReader -import com.squareup.moshi.JsonWriter import io.github.dingyi222666.monarch.language.Language import io.github.dingyi222666.monarch.loader.json.loadMonarchJson -import io.github.rosemoe.sora.langs.monarch.registery.FileProviderRegistry -import io.github.rosemoe.sora.langs.monarch.registery.model.GrammarDefinition +import io.github.rosemoe.sora.langs.monarch.registry.FileProviderRegistry +import io.github.rosemoe.sora.langs.monarch.registry.model.GrammarDefinition class MonarchGrammarDefinitionReader : GrammarDefinitionReader() { diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/GrammarDefinition.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/model/GrammarDefinition.kt similarity index 95% rename from language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/GrammarDefinition.kt rename to language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/model/GrammarDefinition.kt index 0454e0be2..f0d46975d 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/GrammarDefinition.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/model/GrammarDefinition.kt @@ -21,7 +21,7 @@ * Please contact Rosemoe by email 2073412493@qq.com if you need * additional information or have any questions */ -package io.github.rosemoe.sora.langs.monarch.registery.model; +package io.github.rosemoe.sora.langs.monarch.registry.model; import io.github.rosemoe.sora.langs.monarch.languageconfiguration.model.LanguageConfiguration diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/model/ThemeModel.kt similarity index 94% rename from language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt rename to language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/model/ThemeModel.kt index 2cbb2b725..bc7e14cfd 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/model/ThemeModel.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/model/ThemeModel.kt @@ -21,9 +21,9 @@ * Please contact Rosemoe by email 2073412493@qq.com if you need * additional information or have any questions */ -package io.github.rosemoe.sora.langs.monarch.registery.model +package io.github.rosemoe.sora.langs.monarch.registry.model -import io.github.rosemoe.sora.langs.monarch.registery.FileProviderRegistry +import io.github.rosemoe.sora.langs.monarch.registry.FileProviderRegistry import io.github.rosemoe.sora.langs.monarch.theme.TokenTheme import io.github.rosemoe.sora.langs.monarch.theme.toTokenTheme diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/provider/AssetsFileResolver.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/provider/AssetsFileResolver.kt similarity index 95% rename from language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/provider/AssetsFileResolver.kt rename to language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/provider/AssetsFileResolver.kt index e3b531ab5..6f6c281c3 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/provider/AssetsFileResolver.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/provider/AssetsFileResolver.kt @@ -21,7 +21,7 @@ * Please contact Rosemoe by email 2073412493@qq.com if you need * additional information or have any questions */ -package io.github.rosemoe.sora.langs.monarch.registery.provider +package io.github.rosemoe.sora.langs.monarch.registry.provider import android.content.res.AssetManager import java.io.InputStream diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/provider/FileResolver.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/provider/FileResolver.kt similarity index 96% rename from language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/provider/FileResolver.kt rename to language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/provider/FileResolver.kt index 6ce50ba48..828f4f559 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registery/provider/FileResolver.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/registry/provider/FileResolver.kt @@ -22,7 +22,7 @@ * additional information or have any questions ******************************************************************************/ -package io.github.rosemoe.sora.langs.monarch.registery.provider +package io.github.rosemoe.sora.langs.monarch.registry.provider import java.io.File import java.io.FileInputStream From 70832e1eeeb5d1a4950b0a2cfdfaf9d16d9924ee Mon Sep 17 00:00:00 2001 From: Rosemoe <2073412493@qq.com> Date: Mon, 9 Dec 2024 12:35:42 +0800 Subject: [PATCH 33/40] fix(lang-monarch): identifier counter and recognizer not properly working --- .../sora/langs/monarch/MonarchAnalyzer.kt | 17 ++++++++++++----- .../sora/langs/monarch/MonarchLanguage.kt | 9 ++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt index 18d083804..456472239 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchAnalyzer.kt @@ -237,23 +237,30 @@ class MonarchAnalyzer( if (language.createIdentifiers && tokenType == StandardTokenType.Other ) { - val end = if (index + 1 == tokensLength) + var end = if (index + 1 == tokensLength) lineC.length else line.convertUnicodeOffsetToUtf16( lineTokens.tokens[2 * (index + 1)], surrogate ) - if (end > startIndex && MyCharacter.isJavaIdentifierStart(line[startIndex])) { + var start = startIndex + while (start < end && line[start] == ' ') { + start++ + } + while (end > start && line[end - 1] == ' ') { + end-- + } + if (end > start && MyCharacter.isJavaIdentifierStart(line[start])) { var isValidIdentifier = true - for (j in startIndex + 1 until end) { + for (j in start + 1 until end) { if (!MyCharacter.isJavaIdentifierPart(line[j])) { isValidIdentifier = false break } } if (isValidIdentifier) { - identifiers?.add(line.substring(startIndex, end)) + identifiers?.add(line.substring(start, end)) } } } @@ -307,7 +314,7 @@ class MonarchAnalyzer( super.onAbandonState(state) if (language.createIdentifiers) { state.identifiers?.forEach { identifier -> - syncIdentifiers.identifierIncrease(identifier) + syncIdentifiers.identifierDecrease(identifier) } } } diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt index 9bb8c7aa3..3da53b27e 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt @@ -57,7 +57,8 @@ class MonarchLanguage( MonarchSymbolPairMatch(this) } - internal var createIdentifiers = false + internal val createIdentifiers + get() = autoCompleteEnabled var tabSize = 4 @@ -81,7 +82,6 @@ class MonarchLanguage( override fun useTab() = useTab - override fun requireAutoComplete( content: ContentReference, position: CharPosition, @@ -100,8 +100,7 @@ class MonarchLanguage( } override fun getNewlineHandlers(): Array? = - newlineHandlers ?: super.getNewlineHandlers() - + newlineHandlers ?: super.newlineHandlers fun setCompleterKeywords(keywords: Array) { autoCompleter.setKeywords(keywords, false) @@ -113,7 +112,7 @@ class MonarchLanguage( ) { val old = monarchAnalyzer if (old != null) { - old.setReceiver(null) + old.receiver = null old.destroy() } try { From fe03069a439ed0d8cb64c4ba1bfc78b951ea6b3d Mon Sep 17 00:00:00 2001 From: Rosemoe <2073412493@qq.com> Date: Mon, 9 Dec 2024 12:47:26 +0800 Subject: [PATCH 34/40] fix(lang-monarch): local property hides parent method --- .../github/rosemoe/sora/langs/monarch/MonarchLanguage.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt index 3da53b27e..61b9e4820 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt @@ -64,7 +64,7 @@ class MonarchLanguage( var useTab = false - internal var newlineHandlers: Array? = emptyArray() + internal var localNewlineHandlers: Array? = emptyArray() internal lateinit var newlineHandler: MonarchNewlineHandler @@ -100,7 +100,8 @@ class MonarchLanguage( } override fun getNewlineHandlers(): Array? = - newlineHandlers ?: super.newlineHandlers + localNewlineHandlers ?: arrayOf() + fun setCompleterKeywords(keywords: Array) { autoCompleter.setKeywords(keywords, false) @@ -127,7 +128,7 @@ class MonarchLanguage( } this.languageConfiguration = languageConfiguration newlineHandler = MonarchNewlineHandler(this) - newlineHandlers = arrayOf(newlineHandler) + localNewlineHandlers = arrayOf(newlineHandler) if (languageConfiguration != null) { // because the editor will only get the symbol pair matcher once // (caching object to stop repeated new object created), From 1ec76d73613fcd680cbfc81e95cc3a1e07dba13f Mon Sep 17 00:00:00 2001 From: Rosemoe <2073412493@qq.com> Date: Mon, 9 Dec 2024 12:48:53 +0800 Subject: [PATCH 35/40] fix(lang-monarch): indent text inverted for tab --- .../rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt index 7f51aba48..84d455722 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt @@ -130,12 +130,10 @@ class MonarchNewlineHandler( var afterEnterIndent = afterEnterAction.indentation - var indent = "" - - indent = if (language.useTab()) { - " ".repeat(language.tabSize) - } else { + val indent = if (language.useTab()) { "\t" + } else { + " ".repeat(language.tabSize) } From 47a99c5a73ccb6761961fc0977ba1b1f17df2b13 Mon Sep 17 00:00:00 2001 From: Rosemoe <2073412493@qq.com> Date: Mon, 9 Dec 2024 12:54:55 +0800 Subject: [PATCH 36/40] chore(lang-monarch): remove unused internal property --- .../rosemoe/sora/langs/monarch/MonarchLanguage.kt | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt index 61b9e4820..8f301520a 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchLanguage.kt @@ -64,9 +64,7 @@ class MonarchLanguage( var useTab = false - internal var localNewlineHandlers: Array? = emptyArray() - internal lateinit var newlineHandler: MonarchNewlineHandler - + internal var localNewlineHandlers: Array = emptyArray() init { createAnalyzerAndNewlineHandler(grammar, languageConfiguration) @@ -99,9 +97,7 @@ class MonarchLanguage( autoCompleter.requireAutoComplete(content, position, prefix, publisher, idt) } - override fun getNewlineHandlers(): Array? = - localNewlineHandlers ?: arrayOf() - + override fun getNewlineHandlers(): Array = localNewlineHandlers fun setCompleterKeywords(keywords: Array) { autoCompleter.setKeywords(keywords, false) @@ -127,8 +123,7 @@ class MonarchLanguage( e.printStackTrace() } this.languageConfiguration = languageConfiguration - newlineHandler = MonarchNewlineHandler(this) - localNewlineHandlers = arrayOf(newlineHandler) + localNewlineHandlers = arrayOf(MonarchNewlineHandler(this)) if (languageConfiguration != null) { // because the editor will only get the symbol pair matcher once // (caching object to stop repeated new object created), From 6fa1444a7f7b00694bbdc64fa723a4ea390f6a42 Mon Sep 17 00:00:00 2001 From: Rosemoe <2073412493@qq.com> Date: Mon, 9 Dec 2024 13:35:36 +0800 Subject: [PATCH 37/40] fix(lang-monarch): conflict value of `getPrecedingValidLine` --- .../langs/monarch/MonarchNewlineHandler.kt | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt index 84d455722..40e0ef4ca 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt @@ -98,7 +98,6 @@ class MonarchNewlineHandler( } enterAction = getEnterAction(text, position) - indentForEnter = null if (enterAction == null) { @@ -112,23 +111,18 @@ class MonarchNewlineHandler( // https://github.com/microsoft/vscode/blob/bf63ea1932dd253745f38a4cbe26bb9be01801b1/src/vs/editor/common/languages/autoIndent.ts#L278 val currentLineText = text.getLineString(position.line) - val beforeEnterText = currentLineText.substring(0, position.column) - val afterEnterText = currentLineText.substring(position.column) - val beforeEnterIndent = beforeEnterText.getLeadingWhitespace(0, beforeEnterText.length) val afterEnterAction = getInheritIndentForLine( WrapperContent(text, position.line, beforeEnterText), - true, position.line + 1 ) ?: return beforeEnterIndent to beforeEnterIndent - var afterEnterIndent = afterEnterAction.indentation val indent = if (language.useTab()) { "\t" @@ -293,7 +287,6 @@ class MonarchNewlineHandler( enterResult = onEnterSupport.onEnter(previousLineText, beforeEnterText, afterEnterText) } catch (e: Exception) { e.printStackTrace() - // onUnexpectedError(e); } if (enterResult == null) { @@ -331,8 +324,8 @@ class MonarchNewlineHandler( /** * Get nearest preceding line which doesn't match unIndentPattern or contains all whitespace. * Result: - * -1: run into the boundary of embedded languages - * 0: every line above are invalid + * -2: run into the boundary of embedded languages + * -1: every line above are invalid * else: nearest preceding line of the same language */ fun getPrecedingValidLine(content: WrapperContent, lineNumber: Int): Int { @@ -345,14 +338,13 @@ class MonarchNewlineHandler( lineContent ) || lineContent.isEmpty() ) { - continue; + continue } return lastLineNumber } - } - return -1 + return -2 } /** @@ -370,11 +362,15 @@ class MonarchNewlineHandler( private fun getInheritIndentForLine( model: WrapperContent, - honorIntentialIndent: Boolean, line: Int + line: Int, + honorIntentialIndent: Boolean = true ): InheritIndentResult? { // https://github.com/microsoft/vscode/blob/bf63ea1932dd253745f38a4cbe26bb9be01801b1/src/vs/editor/common/languages/autoIndent.ts#L73 - if (line < 1 || indentRulesSupport == null) { + if (indentRulesSupport == null) { + return null + } + if (line < 1) { return InheritIndentResult("", 0) } @@ -382,9 +378,9 @@ class MonarchNewlineHandler( val precedingUnIgnoredLine = getPrecedingValidLine(model, line) - if (precedingUnIgnoredLine < 0) { + if (precedingUnIgnoredLine < -1) { return null - } else if (precedingUnIgnoredLine < 1) { + } else if (precedingUnIgnoredLine < 0) { return InheritIndentResult("", 0) } From 7e903a0dd7d765f3ae977b3b424f78e35f8f3cf6 Mon Sep 17 00:00:00 2001 From: Rosemoe <2073412493@qq.com> Date: Mon, 9 Dec 2024 14:04:14 +0800 Subject: [PATCH 38/40] fix(lang-monarch): `EnterSupport` is not created when language configuration does not offer `onEnterRules` --- .../rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt | 8 +------- .../sora/langs/monarch/languageconfiguration/loader.kt | 2 +- .../languageconfiguration/model/LanguageConfiguration.kt | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt index 40e0ef4ca..c90f8c250 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/MonarchNewlineHandler.kt @@ -71,13 +71,7 @@ class MonarchNewlineHandler( val brackets = languageConfiguration.brackets val indentationsRules = languageConfiguration.indentationRules - if (enterRules != null) { - enterSupport = - OnEnterSupport( - brackets, - enterRules - ) - } + enterSupport = OnEnterSupport(brackets, enterRules) if (indentationsRules != null) { indentRulesSupport = IndentRulesSupport( diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt index cf08dead4..fc003f0c0 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/loader.kt @@ -57,7 +57,7 @@ class LanguageConfigurationAdapter : JsonAdapter() { var indentationRules: IndentationRule? = null - var onEnterRules: List? = null + var onEnterRules: List = listOf() var autoCloseBefore: String? = null diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt index 608b89471..7ce40be9a 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt @@ -53,7 +53,7 @@ data class LanguageConfiguration( /** * The language's rules to be evaluated when pressing Enter. */ - val onEnterRules: List? = null, + val onEnterRules: List = listOf(), /** * The language's auto closing pairs. The 'close' character is automatically inserted with the * 'open' character is typed. If not set, the configured brackets will be used. From dbdecfbeff15df6f033eaaa66bd5ee4221761f70 Mon Sep 17 00:00:00 2001 From: Rosemoe <2073412493@qq.com> Date: Mon, 9 Dec 2024 16:26:45 +0800 Subject: [PATCH 39/40] chore: add scopes for EPL-licensed files and update copyright for monarch source files --- .gitignore | 4 --- .idea/.gitignore | 3 ++ .idea/copyright/profiles_settings.xml | 3 ++ .idea/copyright/tm4e_EPL.xml | 6 ++++ .idea/scopes/tm4e_epl_licensed.xml | 3 ++ .../monarch/languageconfiguration/loader.kt | 30 +++++++------------ .../model/AutoClosingPair.kt | 30 +++++++------------ .../model/CommentRule.kt | 30 +++++++------------ .../model/CompleteEnterAction.kt | 30 +++++++------------ .../model/EnterAction.kt | 30 +++++++------------ .../model/FoldingMarkers.kt | 30 +++++++------------ .../model/FoldingRules.kt | 30 +++++++------------ .../model/IndentAction.kt | 30 +++++++------------ .../model/IndentationRule.kt | 30 +++++++------------ .../model/LanguageConfiguration.kt | 30 +++++++------------ .../model/OnEnterRule.kt | 30 +++++++------------ .../support/IndentRulesSupport.kt | 30 +++++++------------ .../support/OnEnterSupport.kt | 30 +++++++------------ .../sora/langs/monarch/theme/ColorMap.kt | 30 +++++++------------ .../monarch/theme/ExternalThemeTrieElement.kt | 30 +++++++------------ .../langs/monarch/theme/ThemeDefaultColors.kt | 30 +++++++------------ .../langs/monarch/theme/ThemeTrieElement.kt | 30 +++++++------------ .../monarch/theme/ThemeTrieElementRule.kt | 30 +++++++------------ .../sora/langs/monarch/theme/TokenTheme.kt | 30 +++++++------------ .../sora/langs/monarch/theme/loader.kt | 30 +++++++------------ .../rosemoe/sora/langs/monarch/theme/parse.kt | 30 +++++++------------ .../rosemoe/sora/langs/monarch/theme/types.kt | 30 +++++++------------ 27 files changed, 235 insertions(+), 444 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/copyright/tm4e_EPL.xml create mode 100644 .idea/scopes/tm4e_epl_licensed.xml diff --git a/.gitignore b/.gitignore index 9aed413ce..33dc85ab8 100644 --- a/.gitignore +++ b/.gitignore @@ -85,7 +85,3 @@ lint/generated/ lint/outputs/ lint/tmp/ # lint/reports/ - -# Idea props -.idea/ -/.idea/ diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 000000000..26d33521a --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml index f2f17f7a8..36b6243de 100644 --- a/.idea/copyright/profiles_settings.xml +++ b/.idea/copyright/profiles_settings.xml @@ -1,5 +1,8 @@ + + +

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.languageconfiguration diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt index 436e1eee8..7937715cc 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/AutoClosingPair.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CommentRule.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CommentRule.kt index f7fad4285..53ba0292b 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CommentRule.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CommentRule.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CompleteEnterAction.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CompleteEnterAction.kt index 79ecb8681..f206ee3bd 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CompleteEnterAction.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/CompleteEnterAction.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/EnterAction.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/EnterAction.kt index 0144b89dd..a3af8920e 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/EnterAction.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/EnterAction.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingMarkers.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingMarkers.kt index c22029d5d..6287758f7 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingMarkers.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingMarkers.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingRules.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingRules.kt index 12f8e2207..024712bfb 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingRules.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/FoldingRules.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentAction.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentAction.kt index fc548b781..8ab62327c 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentAction.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentAction.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentationRule.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentationRule.kt index f92395a3b..a6a89cba9 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentationRule.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/IndentationRule.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt index 7ce40be9a..e0e65226f 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/LanguageConfiguration.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/OnEnterRule.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/OnEnterRule.kt index 1ead70b73..f4723ee33 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/OnEnterRule.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/model/OnEnterRule.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.model diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/IndentRulesSupport.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/IndentRulesSupport.kt index ea174351d..6a6b4ed91 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/IndentRulesSupport.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/IndentRulesSupport.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.support diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt index 20d9d7ec8..e3a01e4e1 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/languageconfiguration/support/OnEnterSupport.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.languageconfiguration.support diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt index fd028b05c..0618fe52c 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ColorMap.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.theme diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ExternalThemeTrieElement.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ExternalThemeTrieElement.kt index b9074d78d..491d2756d 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ExternalThemeTrieElement.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ExternalThemeTrieElement.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.theme diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt index e079d4039..9883bad71 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeDefaultColors.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.theme diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt index e2f1260c7..66cc970b6 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElement.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.theme diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElementRule.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElementRule.kt index fc7091633..fc1fd167a 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElementRule.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/ThemeTrieElementRule.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.theme diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt index 80f1f3aed..713dc90ad 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/TokenTheme.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.theme diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt index 0f01c62b0..46042ced1 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/loader.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.theme diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt index 31b5fa03f..ad575afb9 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/parse.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.theme diff --git a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/types.kt b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/types.kt index 0651de72b..12eb9085b 100644 --- a/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/types.kt +++ b/language-monarch/src/main/java/io/github/rosemoe/sora/langs/monarch/theme/types.kt @@ -1,25 +1,15 @@ /******************************************************************************* - * sora-editor - the awesome code editor for Android - * https://github.com/Rosemoe/sora-editor - * Copyright (C) 2020-2024 Rosemoe + * Copyright (c) 2015-2017 Angelo ZERR. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + *

+ * SPDX-License-Identifier: EPL-2.0 + *

+ * Contributors: + * Angelo Zerr - initial API and implementation + * Sebastian Thomschke (Vegard IT GmbH) - add previousLineText support * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * Please contact Rosemoe by email 2073412493@qq.com if you need - * additional information or have any questions ******************************************************************************/ package io.github.rosemoe.sora.langs.monarch.theme From cc7ba2ab54976782eb356117e4046844953c0bc6 Mon Sep 17 00:00:00 2001 From: Rosemoe <2073412493@qq.com> Date: Mon, 9 Dec 2024 16:36:38 +0800 Subject: [PATCH 40/40] chore: cleanup in `AsyncIncrementalAnalyzeManager` --- .../sora/lang/analysis/AsyncIncrementalAnalyzeManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/editor/src/main/java/io/github/rosemoe/sora/lang/analysis/AsyncIncrementalAnalyzeManager.java b/editor/src/main/java/io/github/rosemoe/sora/lang/analysis/AsyncIncrementalAnalyzeManager.java index 384ad4afa..d80a7ae6d 100644 --- a/editor/src/main/java/io/github/rosemoe/sora/lang/analysis/AsyncIncrementalAnalyzeManager.java +++ b/editor/src/main/java/io/github/rosemoe/sora/lang/analysis/AsyncIncrementalAnalyzeManager.java @@ -445,7 +445,6 @@ public void offerMessage(@NonNull Message msg) { } private void initialize() { - var time = System.currentTimeMillis(); styles = new Styles(spans = new LockedSpans()); S state = getInitialState(); var mdf = spans.modify();