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