diff --git a/editor-treesitter/src/main/java/io/github/rosemoe/sora/editor/ts/TsAnalyzeManager.kt b/editor-treesitter/src/main/java/io/github/rosemoe/sora/editor/ts/TsAnalyzeManager.kt
index 07057a32b..efd0c1dd3 100644
--- a/editor-treesitter/src/main/java/io/github/rosemoe/sora/editor/ts/TsAnalyzeManager.kt
+++ b/editor-treesitter/src/main/java/io/github/rosemoe/sora/editor/ts/TsAnalyzeManager.kt
@@ -26,9 +26,6 @@ import io.github.rosemoe.sora.lang.analysis.StyleReceiver
import io.github.rosemoe.sora.lang.styling.Styles
import io.github.rosemoe.sora.text.CharPosition
import io.github.rosemoe.sora.text.ContentReference
-import kotlinx.coroutines.CoroutineName
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
/**
* @author Akash Yadav
diff --git a/editor/build.gradle.kts b/editor/build.gradle.kts
index bd29bc629..324defc45 100644
--- a/editor/build.gradle.kts
+++ b/editor/build.gradle.kts
@@ -33,7 +33,9 @@ dependencies {
implementation(libs.androidx.annotation)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.constraintlayout)
-
+ implementation(libs.androidx.tracing)
+ implementation(libs.androidx.tracing.ktx)
+
implementation(libs.common.utilcode)
implementation(libs.google.material)
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/ui/TracingEditorRenderer.kt b/editor/src/main/java/com/itsaky/androidide/editor/ui/TracingEditorRenderer.kt
new file mode 100644
index 000000000..c0a4776b3
--- /dev/null
+++ b/editor/src/main/java/com/itsaky/androidide/editor/ui/TracingEditorRenderer.kt
@@ -0,0 +1,285 @@
+/*
+ * 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.ui
+
+import android.graphics.Canvas
+import android.graphics.Rect
+import android.graphics.RectF
+import android.graphics.RenderNode
+import android.os.Build
+import androidx.annotation.RequiresApi
+import com.itsaky.androidide.editor.BuildConfig
+import io.github.rosemoe.sora.lang.styling.CodeBlock
+import io.github.rosemoe.sora.lang.styling.Spans
+import io.github.rosemoe.sora.text.ContentLine
+import io.github.rosemoe.sora.util.LongArrayList
+import io.github.rosemoe.sora.util.MutableInt
+import io.github.rosemoe.sora.widget.CodeEditor
+import io.github.rosemoe.sora.widget.EditorRenderer
+
+/**
+ * An implementation of [EditorRenderer] which traces the whole drawing process for [IDEEditor].
+ *
+ * @author Akash Yadav
+ */
+class TracingEditorRenderer(
+ private val enabled: Boolean = BuildConfig.DEBUG,
+ editor: CodeEditor
+) : EditorRenderer(editor) {
+
+ override fun draw(canvas: Canvas) = trace("draw") {
+ super.draw(canvas)
+ }
+
+ @RequiresApi(Build.VERSION_CODES.Q)
+ override fun updateLineDisplayList(renderNode: RenderNode?, line: Int, spans: Spans.Reader?) =
+ trace("updateLineDisplayList") {
+ super.updateLineDisplayList(renderNode, line, spans)
+ }
+
+ override fun drawSingleTextLine(canvas: Canvas?, line: Int, offsetX: Float, offsetY: Float,
+ spans: Spans.Reader?, visibleOnly: Boolean) = trace("drawSingleTextLine") {
+ super.drawSingleTextLine(canvas, line, offsetX, offsetY, spans, visibleOnly)
+ }
+
+ override fun drawView(canvas: Canvas?) = trace("drawView") {
+ super.drawView(canvas)
+ }
+
+ override fun drawUserGutterBackground(canvas: Canvas?, right: Int) =
+ trace("drawUserGutterBackground") {
+ super.drawUserGutterBackground(canvas, right)
+ }
+
+ override fun drawStuckLineNumbers(canvas: Canvas?, candidates: MutableList?,
+ offset: Float, lineNumberWidth: Float, lineNumberColor: Int) = trace("drawStuckLineNumbers") {
+ super.drawStuckLineNumbers(canvas, candidates, offset, lineNumberWidth, lineNumberColor)
+ }
+
+ override fun drawStuckLines(canvas: Canvas?, candidates: MutableList?, offset: Float) =
+ trace("drawStuckLines") {
+ super.drawStuckLines(canvas, candidates, offset)
+ }
+
+ override fun drawHardwrapMarker(canvas: Canvas?, offset: Float) = trace("drawHardwrapMarker") {
+ super.drawHardwrapMarker(canvas, offset)
+ }
+
+ override fun drawSideIcons(canvas: Canvas?, offset: Float) = trace("drawSideIcons") {
+ super.drawSideIcons(canvas, offset)
+ }
+
+ override fun drawFormatTip(canvas: Canvas?) = trace("drawFormatTip") {
+ super.drawFormatTip(canvas)
+ }
+
+ override fun drawColor(canvas: Canvas?, color: Int, rect: RectF?) = trace("drawColor") {
+ super.drawColor(canvas, color, rect)
+ }
+
+ override fun drawColor(canvas: Canvas?, color: Int, rect: Rect?) = trace("drawColor") {
+ super.drawColor(canvas, color, rect)
+ }
+
+ override fun drawColorRound(canvas: Canvas?, color: Int, rect: RectF?) = trace("drawColorRound") {
+ super.drawColorRound(canvas, color, rect)
+ }
+
+ override fun drawRowBackground(canvas: Canvas?, color: Int, row: Int) =
+ trace("drawRowBackground") {
+ super.drawRowBackground(canvas, color, row)
+ }
+
+ override fun drawRowBackground(canvas: Canvas?, color: Int, row: Int, right: Int) =
+ trace("drawRowBackground") {
+ super.drawRowBackground(canvas, color, row, right)
+ }
+
+ override fun drawLineNumber(canvas: Canvas?, line: Int, row: Int, offsetX: Float, width: Float,
+ color: Int) = trace("drawLineNumber") {
+ super.drawLineNumber(canvas, line, row, offsetX, width, color)
+ }
+
+ override fun drawLineNumberBackground(canvas: Canvas?, offsetX: Float, width: Float, color: Int) =
+ trace("drawLineNumberBackground") {
+ super.drawLineNumberBackground(canvas, offsetX, width, color)
+ }
+
+ override fun drawDivider(canvas: Canvas?, offsetX: Float, color: Int) = trace("drawDivider") {
+ super.drawDivider(canvas, offsetX, color)
+ }
+
+ override fun drawRows(canvas: Canvas?, offset: Float, postDrawLineNumbers: LongArrayList?,
+ postDrawCursor: MutableList?, postDrawCurrentLines: LongArrayList?,
+ requiredFirstLn: MutableInt?) = trace("drawRows") {
+ super.drawRows(canvas, offset, postDrawLineNumbers, postDrawCursor, postDrawCurrentLines,
+ requiredFirstLn)
+ }
+
+ override fun drawDiagnosticIndicators(canvas: Canvas?, offset: Float) =
+ trace("drawDiagnosticIndicators") {
+ super.drawDiagnosticIndicators(canvas, offset)
+ }
+
+ override fun drawWhitespaces(canvas: Canvas?, offset: Float, line: Int, row: Int, rowStart: Int,
+ rowEnd: Int, min: Int, max: Int) = trace("drawWhitespaces") {
+ super.drawWhitespaces(canvas, offset, line, row, rowStart, rowEnd, min, max)
+ }
+
+ override fun drawMiniGraph(canvas: Canvas?, offset: Float, row: Int, graph: String?) =
+ trace("drawMiniGraph") {
+ super.drawMiniGraph(canvas, offset, row, graph)
+ }
+
+ override fun getRowTopForBackground(row: Int) = trace("getRowTopForBackground") {
+ return@trace super.getRowTopForBackground(row)
+ }
+
+ override fun getRowBottomForBackground(row: Int) = trace("getRowBottomForBackground") {
+ return@trace super.getRowBottomForBackground(row)
+ }
+
+ override fun drawRowRegionBackground(canvas: Canvas?, row: Int, line: Int, highlightStart: Int,
+ highlightEnd: Int, rowStart: Int, rowEnd: Int, color: Int) = trace("drawRowRegionBackground") {
+ super.drawRowRegionBackground(canvas, row, line, highlightStart, highlightEnd, rowStart, rowEnd,
+ color)
+ }
+
+ override fun drawRowBackgroundRect(canvas: Canvas?, rect: RectF?) =
+ trace("drawRowBackgroundRect") {
+ super.drawRowBackgroundRect(canvas, rect)
+ }
+
+ override fun drawRegionText(canvas: Canvas?, offsetX: Float, baseline: Float, line: Int,
+ startIndex: Int, endIndex: Int, contextStart: Int, contextEnd: Int, isRtl: Boolean,
+ columnCount: Int, color: Int) = trace("drawRegionText") {
+ super.drawRegionText(canvas, offsetX, baseline, line, startIndex, endIndex, contextStart,
+ contextEnd, isRtl, columnCount, color)
+ }
+
+ override fun drawRegionTextDirectional(canvas: Canvas?, offsetX: Float, baseline: Float,
+ line: Int, startIndex: Int, endIndex: Int, contextStart: Int, contextEnd: Int, columnCount: Int,
+ color: Int) = trace("drawRegionTextDirectional") {
+ super.drawRegionTextDirectional(canvas, offsetX, baseline, line, startIndex, endIndex,
+ contextStart, contextEnd, columnCount, color)
+ }
+
+ override fun drawFunctionCharacter(canvas: Canvas?, offsetX: Float, offsetY: Float, width: Float,
+ ch: Char) = trace("drawFunctionCharacter") {
+ super.drawFunctionCharacter(canvas, offsetX, offsetY, width, ch)
+ }
+
+ override fun drawText(canvas: Canvas?, line: ContentLine?, index: Int, count: Int,
+ contextStart: Int, contextCount: Int, isRtl: Boolean, offX: Float, offY: Float,
+ lineNumber: Int) = trace("drawText") {
+ super.drawText(canvas, line, index, count, contextStart, contextCount, isRtl, offX, offY,
+ lineNumber)
+ }
+
+ override fun drawTextRunDirect(canvas: Canvas?, src: CharArray?, index: Int, count: Int,
+ contextStart: Int, contextCount: Int, offX: Float, offY: Float, isRtl: Boolean) =
+ trace("drawTextRunDirect") {
+ super.drawTextRunDirect(canvas, src, index, count, contextStart, contextCount, offX, offY,
+ isRtl)
+ }
+
+ override fun drawEdgeEffect(canvas: Canvas?) = trace("drawEdgeEffect") {
+ super.drawEdgeEffect(canvas)
+ }
+
+ override fun drawBlockLines(canvas: Canvas?, offsetX: Float) = trace("drawBlockLines") {
+ super.drawBlockLines(canvas, offsetX)
+ }
+
+ override fun drawSideBlockLine(canvas: Canvas?) = trace("drawSideBlockLine") {
+ super.drawSideBlockLine(canvas)
+ }
+
+ override fun drawScrollBars(canvas: Canvas?) = trace("drawScrollBars") {
+ super.drawScrollBars(canvas)
+ }
+
+ override fun drawScrollBarTrackVertical(canvas: Canvas?) = trace("drawScrollBarTrackVertical") {
+ super.drawScrollBarTrackVertical(canvas)
+ }
+
+ override fun drawScrollBarVertical(canvas: Canvas?) = trace("drawScrollBarVertical") {
+ super.drawScrollBarVertical(canvas)
+ }
+
+ override fun drawLineInfoPanel(canvas: Canvas?, topY: Float, length: Float) =
+ trace("drawLineInfoPanel") {
+ super.drawLineInfoPanel(canvas, topY, length)
+ }
+
+ override fun drawScrollBarTrackHorizontal(canvas: Canvas?) =
+ trace("drawScrollBarTrackHorizontal") {
+ super.drawScrollBarTrackHorizontal(canvas)
+ }
+
+ override fun patchSnippetRegions(canvas: Canvas?, textOffset: Float) =
+ trace("patchSnippetRegions") {
+ super.patchSnippetRegions(canvas, textOffset)
+ }
+
+ override fun patchHighlightedDelimiters(canvas: Canvas?, textOffset: Float) =
+ trace("patchHighlightedDelimiters") {
+ super.patchHighlightedDelimiters(canvas, textOffset)
+ }
+
+ override fun patchTextRegionWithColor(canvas: Canvas?, textOffset: Float, start: Int, end: Int,
+ color: Int, backgroundColor: Int, underlineColor: Int) = trace("patchTextRegionWithColor") {
+ super.patchTextRegionWithColor(canvas, textOffset, start, end, color, backgroundColor,
+ underlineColor)
+ }
+
+ override fun patchTextRegions(canvas: Canvas?, textOffset: Float,
+ positions: MutableList?, patch: PatchDraw) = trace("patchTextRegions") {
+ super.patchTextRegions(canvas, textOffset, positions, patch)
+ }
+
+ override fun drawSelectionOnAnimation(canvas: Canvas?) = trace("drawSelectionOnAnimation") {
+ super.drawSelectionOnAnimation(canvas)
+ }
+
+ override fun drawScrollBarHorizontal(canvas: Canvas?) = trace("drawScrollBarHorizontal") {
+ super.drawScrollBarHorizontal(canvas)
+ }
+
+ override fun buildMeasureCacheForLines(startLine: Int, endLine: Int, timestamp: Long,
+ useCachedContent: Boolean) = trace("buildMeasureCacheForLines") {
+ super.buildMeasureCacheForLines(startLine, endLine, timestamp, useCachedContent)
+ }
+
+ override fun buildMeasureCacheForLines(startLine: Int, endLine: Int) =
+ trace("buildMeasureCacheForLines") {
+ super.buildMeasureCacheForLines(startLine, endLine)
+ }
+
+ override fun measureText(text: ContentLine?, line: Int, index: Int, count: Int) =
+ trace("measureText") {
+ return@trace super.measureText(text, line, index, count)
+ }
+
+ private inline fun trace(section: String, crossinline action: () -> T): T =
+ if (enabled) {
+ androidx.tracing.trace(section, action)
+ } else {
+ action()
+ }
+}
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 7dc674f69..c0fb6552c 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -69,6 +69,8 @@ androidx-transition = { module = "androidx.transition:transition-ktx", version =
androidx-nav-fragment = { module = "androidx.navigation:navigation-fragment-ktx", version.ref = "androidx-navigation" }
androidx-nav-ui = { module = "androidx.navigation:navigation-ui-ktx", version.ref = "androidx-navigation" }
androidx-nav-dynamic_features = { module = "androidx.navigation:navigation-dynamic-features-fragment", version.ref = "androidx-navigation" }
+androidx-tracing = { module = "androidx.tracing:tracing", version = "1.1.0" }
+androidx-tracing-ktx = { module = "androidx.tracing:tracing-ktx", version = "1.1.0" }
androidx-work = { module = "androidx.work:work-runtime", version.ref = "androidx-work" }
androidx-work-ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "androidx-work" }
diff --git a/subprojects/projects/src/main/java/com/itsaky/androidide/projects/ProjectManagerImpl.kt b/subprojects/projects/src/main/java/com/itsaky/androidide/projects/ProjectManagerImpl.kt
index 36f310835..361fe6535 100644
--- a/subprojects/projects/src/main/java/com/itsaky/androidide/projects/ProjectManagerImpl.kt
+++ b/subprojects/projects/src/main/java/com/itsaky/androidide/projects/ProjectManagerImpl.kt
@@ -134,7 +134,7 @@ class ProjectManagerImpl : IProjectManager, EventReceiver {
}
// wait for the indexing to finish
- runBlocking { jobs.toList().awaitAll() }
+ jobs.toList().awaitAll()
}
}