diff --git a/app/src/main/java/com/itsaky/androidide/activities/editor/EditorHandlerActivity.kt b/app/src/main/java/com/itsaky/androidide/activities/editor/EditorHandlerActivity.kt
index 1e175019e..f88936ba4 100644
--- a/app/src/main/java/com/itsaky/androidide/activities/editor/EditorHandlerActivity.kt
+++ b/app/src/main/java/com/itsaky/androidide/activities/editor/EditorHandlerActivity.kt
@@ -152,8 +152,6 @@ open class EditorHandlerActivity : ProjectHandlerActivity(), IEditorHandler {
}
}
viewModel.openedFilesCache = null
-
- executeAsync { IDEColorSchemeProvider.init() }
} catch (err: Throwable) {
log.error("Failed to reopen recently opened files", err)
}
diff --git a/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt b/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt
index 8d64b439a..f38a98d4e 100755
--- a/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt
+++ b/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt
@@ -57,6 +57,8 @@ class IDEApplication : BaseApplication() {
.addIndex(LspApiEventsIndex())
.addIndex(LspJavaEventsIndex())
.installDefaultEventBus()
+
+ executeAsync { IDEColorSchemeProvider.init() }
}
private fun handleCrash(thread: Thread, th: Throwable) {
diff --git a/app/src/main/java/com/itsaky/androidide/ui/editor/CodeEditorView.java b/app/src/main/java/com/itsaky/androidide/ui/editor/CodeEditorView.java
index 194d4734a..b82669bab 100644
--- a/app/src/main/java/com/itsaky/androidide/ui/editor/CodeEditorView.java
+++ b/app/src/main/java/com/itsaky/androidide/ui/editor/CodeEditorView.java
@@ -16,8 +16,6 @@
*/
package com.itsaky.androidide.ui.editor;
-import static com.itsaky.androidide.editor.schemes.LanguageSpecProvider.getLanguageSpec;
-import static com.itsaky.androidide.editor.schemes.LocalCaptureSpecProvider.newLocalCaptureSpec;
import static com.itsaky.androidide.preferences.internal.EditorPreferencesKt.FLAG_LINE_BREAK;
import static com.itsaky.androidide.preferences.internal.EditorPreferencesKt.FLAG_PASSWORD;
import static com.itsaky.androidide.preferences.internal.EditorPreferencesKt.FLAG_WS_EMPTY_LINE;
@@ -59,7 +57,6 @@ import com.itsaky.androidide.editor.language.cpp.CppLanguage;
import com.itsaky.androidide.editor.language.groovy.GroovyLanguage;
import com.itsaky.androidide.editor.language.java.JavaLanguage;
import com.itsaky.androidide.editor.language.kotlin.KotlinLanguage;
-import com.itsaky.androidide.editor.language.treesitter.TreeSitterLanguage;
import com.itsaky.androidide.editor.language.xml.XMLLanguage;
import com.itsaky.androidide.editor.schemes.IDEColorSchemeProvider;
import com.itsaky.androidide.editor.ui.EditorSearchLayout;
@@ -73,7 +70,6 @@ import com.itsaky.androidide.lsp.xml.XMLLanguageServer;
import com.itsaky.androidide.models.Range;
import com.itsaky.androidide.preferences.internal.EditorPreferencesKt;
import com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE;
-import com.itsaky.androidide.treesitter.java.TSLanguageJava;
import com.itsaky.androidide.utils.FileUtil;
import com.itsaky.androidide.utils.ILogger;
import com.itsaky.androidide.utils.LSPUtils;
@@ -212,10 +208,7 @@ public class CodeEditorView extends LinearLayout {
switch (ext) {
case "java":
IDEColorSchemeProvider.INSTANCE.readScheme(binding.editor::setColorScheme);
- final var tsLangJava = TSLanguageJava.newInstance();
- final var localsSpec = newLocalCaptureSpec(ext);
- final var languageSpec = getLanguageSpec(getContext(), ext, tsLangJava, localsSpec);
- return new TreeSitterLanguage(new JavaLanguage(), languageSpec, ext);
+ return new JavaLanguage(getContext());
case "xml":
return new XMLLanguage();
case "gradle":
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/language/TreeSitterLanguage.kt b/editor/src/main/java/com/itsaky/androidide/editor/language/TreeSitterLanguage.kt
new file mode 100644
index 000000000..911bf228e
--- /dev/null
+++ b/editor/src/main/java/com/itsaky/androidide/editor/language/TreeSitterLanguage.kt
@@ -0,0 +1,64 @@
+/*
+ * This file is part of AndroidIDE.
+ *
+ * AndroidIDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AndroidIDE 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with AndroidIDE. If not, see .
+ */
+
+package com.itsaky.androidide.editor.language
+
+import android.content.Context
+import com.itsaky.androidide.editor.schemes.IDEColorSchemeProvider
+import com.itsaky.androidide.editor.schemes.LanguageSpecProvider
+import com.itsaky.androidide.editor.schemes.LanguageSpecProvider.getLanguageSpec
+import com.itsaky.androidide.editor.schemes.LocalCaptureSpecProvider
+import com.itsaky.androidide.editor.schemes.LocalCaptureSpecProvider.newLocalCaptureSpec
+import com.itsaky.androidide.treesitter.TSLanguage
+import io.github.rosemoe.sora.editor.ts.TsAnalyzeManager
+import io.github.rosemoe.sora.editor.ts.TsLanguageSpec
+import io.github.rosemoe.sora.editor.ts.TsTheme
+import io.github.rosemoe.sora.lang.analysis.AnalyzeManager
+
+/**
+ * Tree Sitter language implementation.
+ *
+ * @author Akash Yadav
+ */
+abstract class TreeSitterLanguage(
+ context: Context,
+ lang: TSLanguage,
+ type: String
+) : IDELanguage() {
+
+ private lateinit var tsTheme: TsTheme
+ private lateinit var languageSpec: TsLanguageSpec
+ private val analyzer by lazy { TsAnalyzeManager(languageSpec, tsTheme) }
+
+ init {
+ this.languageSpec = getLanguageSpec(context, type, lang, newLocalCaptureSpec(type))
+ this.tsTheme = TsTheme(languageSpec.tsQuery)
+ IDEColorSchemeProvider.readScheme { scheme ->
+ val langScheme =
+ checkNotNull(scheme.languages[type]) { "No color scheme found for file type '$type'" }
+ langScheme.styles.forEach { tsTheme.putStyleRule(it.key, it.value.makeStyle()) }
+ }
+ }
+
+ override fun getAnalyzeManager(): AnalyzeManager {
+ return this.analyzer
+ }
+
+ override fun destroy() {
+ languageSpec.close()
+ }
+}
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/language/java/JavaLanguage.java b/editor/src/main/java/com/itsaky/androidide/editor/language/java/JavaLanguage.java
deleted file mode 100755
index eef7feee4..000000000
--- a/editor/src/main/java/com/itsaky/androidide/editor/language/java/JavaLanguage.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * This file is part of AndroidIDE.
- *
- * AndroidIDE is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * AndroidIDE 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with AndroidIDE. If not, see .
- */
-package com.itsaky.androidide.editor.language.java;
-
-import androidx.annotation.NonNull;
-
-import com.itsaky.androidide.editor.language.CommonSymbolPairs;
-import com.itsaky.androidide.editor.language.IDELanguage;
-import com.itsaky.androidide.editor.language.BraceHandler;
-import com.itsaky.androidide.editor.language.CommonCompletionProvider;
-import com.itsaky.androidide.lexers.java.JavaLexer;
-import com.itsaky.androidide.lexers.java.JavaParser;
-import com.itsaky.androidide.lsp.api.ILanguageServer;
-import com.itsaky.androidide.lsp.api.ILanguageServerRegistry;
-import com.itsaky.androidide.lsp.java.JavaLanguageServer;
-import com.itsaky.androidide.utils.ILogger;
-
-import org.antlr.v4.runtime.CharStreams;
-import org.antlr.v4.runtime.Token;
-
-import java.io.StringReader;
-
-import io.github.rosemoe.sora.lang.analysis.AnalyzeManager;
-import io.github.rosemoe.sora.lang.smartEnter.NewlineHandler;
-import io.github.rosemoe.sora.text.ContentReference;
-import io.github.rosemoe.sora.util.MyCharacter;
-import io.github.rosemoe.sora.widget.SymbolPairMatch;
-
-public class JavaLanguage extends IDELanguage {
-
- private static final ILogger LOG = ILogger.newInstance("JavaLanguage");
- private final NewlineHandler[] newlineHandlers;
- private JavaAnalyzer analyzer;
-
- public JavaLanguage() {
- final var server = getLanguageServer();
- this.analyzer = new JavaAnalyzer();
-
- this.newlineHandlers = new NewlineHandler[1];
- this.newlineHandlers[0] = new BraceHandler(this::getIndentAdvance, this::useTab);
- }
-
- @Override
- protected ILanguageServer getLanguageServer() {
- return ILanguageServerRegistry.getDefault().getServer(JavaLanguageServer.SERVER_ID);
- }
-
- @Override
- protected boolean checkIsCompletionChar(final char c) {
- return MyCharacter.isJavaIdentifierPart(c) || c == '.';
- }
-
- @Override
- public int getIndentAdvance(@NonNull String line) {
- try {
- JavaLexer lexer = new JavaLexer(CharStreams.fromReader(new StringReader(line)));
- Token token;
- int advance = 0;
- while (((token = lexer.nextToken()) != null && token.getType() != token.EOF)) {
- switch (token.getType()) {
- case JavaLexer.LBRACE:
- advance++;
- break;
- case JavaParser.RBRACE:
- advance--;
- break;
- }
- }
- advance = Math.max(0, advance);
- return advance * getTabSize();
- } catch (Throwable e) {
- LOG.error("Error calculating indent advance", e);
- }
-
- return 0;
- }
-
- @NonNull
- @Override
- public AnalyzeManager getAnalyzeManager() {
- return analyzer;
- }
-
- @Override
- public int getInterruptionLevel() {
- return INTERRUPTION_LEVEL_SLIGHT;
- }
-
- @Override
- public int getIndentAdvance(@NonNull ContentReference content, int line, int column) {
- return getIndentAdvance(content.getLine(line).substring(0, column));
- }
-
- @Override
- public SymbolPairMatch getSymbolPairs() {
- return new JavaSymbolPairs();
- }
-
- @Override
- public NewlineHandler[] getNewlineHandlers() {
- return newlineHandlers;
- }
-
- @Override
- public void destroy() {
- analyzer = null;
- }
-
- public static class JavaSymbolPairs extends CommonSymbolPairs {
- public JavaSymbolPairs() {
- super();
- super.putPair('<', new SymbolPairMatch.SymbolPair("<", ">"));
- }
- }
-}
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/language/java/JavaLanguage.kt b/editor/src/main/java/com/itsaky/androidide/editor/language/java/JavaLanguage.kt
new file mode 100644
index 000000000..99740c552
--- /dev/null
+++ b/editor/src/main/java/com/itsaky/androidide/editor/language/java/JavaLanguage.kt
@@ -0,0 +1,75 @@
+/*
+ * This file is part of AndroidIDE.
+ *
+ * AndroidIDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AndroidIDE 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with AndroidIDE. If not, see .
+ */
+
+package com.itsaky.androidide.editor.language.java
+
+import android.content.Context
+import com.itsaky.androidide.editor.language.BraceHandler
+import com.itsaky.androidide.editor.language.CommonSymbolPairs
+import com.itsaky.androidide.editor.language.TreeSitterLanguage
+import com.itsaky.androidide.lsp.api.ILanguageServer
+import com.itsaky.androidide.lsp.api.ILanguageServerRegistry
+import com.itsaky.androidide.lsp.java.JavaLanguageServer
+import com.itsaky.androidide.treesitter.java.TSLanguageJava
+import io.github.rosemoe.sora.lang.smartEnter.NewlineHandler
+import io.github.rosemoe.sora.text.ContentReference
+import io.github.rosemoe.sora.util.MyCharacter
+import io.github.rosemoe.sora.widget.SymbolPairMatch
+
+/**
+ * Tree Sitter language specification for Java.
+ *
+ * @author Akash Yadav
+ */
+class JavaLanguage(context: Context) :
+ TreeSitterLanguage(context, TSLanguageJava.newInstance(), TS_TYPE) {
+
+ companion object {
+ const val TS_TYPE = "java"
+ }
+
+ override fun getLanguageServer(): ILanguageServer? {
+ return ILanguageServerRegistry.getDefault().getServer(JavaLanguageServer.SERVER_ID)
+ }
+
+ override fun checkIsCompletionChar(c: Char): Boolean {
+ return MyCharacter.isJavaIdentifierPart(c) || c == '.'
+ }
+
+ override fun getInterruptionLevel(): Int {
+ return INTERRUPTION_LEVEL_SLIGHT
+ }
+
+ override fun getIndentAdvance(content: ContentReference, line: Int, column: Int): Int {
+ // TODO Implement this with tree-sitter
+ return 0
+ }
+
+ override fun getSymbolPairs(): SymbolPairMatch {
+ return JavaSymbolPairs()
+ }
+
+ override fun getNewlineHandlers(): Array {
+ return arrayOf(BraceHandler({ line -> this.getIndentAdvance(line!!) }) { useTab() })
+ }
+
+ internal open class JavaSymbolPairs : CommonSymbolPairs() {
+ init {
+ super.putPair('<', SymbolPair("<", ">"))
+ }
+ }
+}
diff --git a/tests/test-home/.androidide/init/model.jar b/tests/test-home/.androidide/init/model.jar
index d17001438..3686a3363 100644
Binary files a/tests/test-home/.androidide/init/model.jar and b/tests/test-home/.androidide/init/model.jar differ