mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
Changed log priority implementation
This commit is contained in:
Generated
+2
@@ -141,10 +141,12 @@
|
||||
<entry key="..\:/Users/Akash Yadav/AndroidStudioProjects/android-ide/app/src/main/res/layout/layout_widget_item.xml" value="0.264" />
|
||||
<entry key="..\:/Users/Akash Yadav/AndroidStudioProjects/android-ide/app/src/main/res/menu/menu_designer_widgets.xml" value="0.20854700854700856" />
|
||||
<entry key="..\:/itsaky/.gradle/caches/transforms-3/e4862cae80f8754ca1a451ad3e00b14c/transformed/jetified-editor-0.10.11/res/drawable/round_select_all_20.xml" value="0.1305" />
|
||||
<entry key="app/src/main/res/drawable/bg_log_search_field.xml" value="0.3365" />
|
||||
<entry key="app/src/main/res/drawable/ic_gradle.xml" value="0.3265" />
|
||||
<entry key="app/src/main/res/drawable/ic_language_gradle.xml" value="0.3265" />
|
||||
<entry key="app/src/main/res/layout/activity_download.xml" value="0.35572916666666665" />
|
||||
<entry key="app/src/main/res/layout/fragment_log.xml" value="0.35572916666666665" />
|
||||
<entry key="app/src/main/res/layout/fragment_log_view.xml" value="0.35572916666666665" />
|
||||
<entry key="app/src/main/res/layout/layout_dialog_text_input.xml" value="0.35572916666666665" />
|
||||
<entry key="app/src/main/res/layout/layout_log_line.xml" value="0.35572916666666665" />
|
||||
</map>
|
||||
|
||||
Binary file not shown.
@@ -1407,7 +1407,7 @@ public class EditorActivity extends StudioActivity
|
||||
ProgressDialog.show(EditorActivity.this, null, getString(R.string.please_wait));
|
||||
CompletableFuture.runAsync(
|
||||
() -> {
|
||||
final var text = adapter.getAsString();
|
||||
final var text = adapter.allAsString();
|
||||
ThreadUtils.runOnUiThread(
|
||||
() -> {
|
||||
progress.dismiss();
|
||||
|
||||
@@ -22,21 +22,27 @@ import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.blankj.utilcode.util.SizeUtils
|
||||
import com.itsaky.androidide.adapters.LogLinesAdapter.VH
|
||||
import com.itsaky.androidide.models.LogLine
|
||||
import com.itsaky.androidide.utils.ILogger
|
||||
import com.itsaky.androidide.utils.ILogger.Priority.ERROR
|
||||
import com.itsaky.androidide.utils.ILogger.Priority.INFO
|
||||
import com.itsaky.androidide.utils.ILogger.Priority.WARNING
|
||||
import com.itsaky.androidide.utils.TypefaceUtils
|
||||
|
||||
/**
|
||||
* Adapter for the log view.
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
class LogLinesAdapter(private val lines: MutableList<LogLine> = mutableListOf()) :
|
||||
RecyclerView.Adapter<VH>() {
|
||||
class LogLinesAdapter : RecyclerView.Adapter<VH>() {
|
||||
|
||||
private val log = ILogger.newInstance(javaClass.simpleName)
|
||||
private val lines: MutableList<LogWrapper> = mutableListOf()
|
||||
var simpleFormatting = true
|
||||
|
||||
companion object {
|
||||
@@ -52,8 +58,9 @@ class LogLinesAdapter(private val lines: MutableList<LogLine> = mutableListOf())
|
||||
}
|
||||
|
||||
fun add(line: LogLine) {
|
||||
this.lines.add(line)
|
||||
this.notifyItemInserted(this.lines.lastIndex)
|
||||
val wrapped = wrap(line)
|
||||
this.lines.add(wrapped)
|
||||
notifyItemInserted(this.lines.lastIndex)
|
||||
|
||||
if (this.lines.size > MAX_LINES) {
|
||||
this.lines.removeAt(0)
|
||||
@@ -61,18 +68,13 @@ class LogLinesAdapter(private val lines: MutableList<LogLine> = mutableListOf())
|
||||
}
|
||||
}
|
||||
|
||||
fun getItem(index: Int) = this.lines[index]
|
||||
fun getLine(index: Int) = this.lines[index].log
|
||||
|
||||
fun getAsString() =
|
||||
fun allAsString() =
|
||||
StringBuilder()
|
||||
.apply {
|
||||
for (line in lines) {
|
||||
append(
|
||||
if (simpleFormatting) {
|
||||
line.toSimpleString()
|
||||
} else {
|
||||
line.toString()
|
||||
})
|
||||
append(lineString(line))
|
||||
append("\n")
|
||||
}
|
||||
}
|
||||
@@ -84,53 +86,73 @@ class LogLinesAdapter(private val lines: MutableList<LogLine> = mutableListOf())
|
||||
text.setTextSize(TypedValue.COMPLEX_UNIT_SP, 11f)
|
||||
text.setPaddingRelative(dp1, dp1 / 2, dp1, dp1 / 2)
|
||||
text.setTextIsSelectable(true)
|
||||
text.maxLines = 1
|
||||
text.typeface = TypefaceUtils.jetbrainsMono()
|
||||
return VH(text)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: VH, position: Int) {
|
||||
val line = getItem(position)
|
||||
val spanned =
|
||||
if (line is LogWrapper) {
|
||||
line.spanned!!
|
||||
} else {
|
||||
val spannable =
|
||||
SpannableString(
|
||||
if (simpleFormatting) line.toSimpleString() else line.toString())
|
||||
val color =
|
||||
when (line.priority) {
|
||||
LogLine.ERROR -> -0xbbcca
|
||||
LogLine.WARNING -> -0x14c5
|
||||
LogLine.INFO -> -0xb350b0
|
||||
else -> -0xa0a0b
|
||||
}
|
||||
spannable.setSpan(
|
||||
ForegroundColorSpan(color),
|
||||
0,
|
||||
spannable.length,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
lines[position] = LogWrapper(line).apply { spanned = spannable }
|
||||
spannable
|
||||
}
|
||||
val line = lines[position]
|
||||
if (!line.visible) {
|
||||
holder.itemView.visibility = View.GONE
|
||||
return
|
||||
} else {
|
||||
holder.itemView.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
val spanned = line.spannable
|
||||
holder.text.text = spanned
|
||||
}
|
||||
|
||||
override fun getItemCount() = this.lines.size
|
||||
|
||||
class LogWrapper(val log: LogLine) : LogLine() {
|
||||
private fun wrap(line: LogLine): LogWrapper {
|
||||
val spannable = SpannableString(lineString(line))
|
||||
val color =
|
||||
when (line.priority) {
|
||||
ERROR -> -0xbbcca
|
||||
WARNING -> -0x14c5
|
||||
INFO -> -0xb350b0
|
||||
else -> -0xa0a0b
|
||||
}
|
||||
spannable.setSpan(
|
||||
ForegroundColorSpan(color), 0, spannable.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
return LogWrapper(line, spannable).apply { visible = true }
|
||||
}
|
||||
|
||||
var spanned: Spannable? = null
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return this.log == other
|
||||
private fun lineString(logLine: LogLine) =
|
||||
if (simpleFormatting) {
|
||||
logLine.toSimpleString()
|
||||
} else {
|
||||
logLine.toString()
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return this.log.hashCode()
|
||||
}
|
||||
class LogWrapper(val log: LogLine, val spannable: Spannable) : LogLine() {
|
||||
|
||||
var visible = true
|
||||
|
||||
override fun toString() = this.log.toString()
|
||||
override fun toSimpleString(): String = this.log.toSimpleString()
|
||||
override fun formattedTagAndMessage(): String = this.log.formattedTagAndMessage()
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as LogWrapper
|
||||
|
||||
if (log != other.log) return false
|
||||
if (spannable != other.spannable) return false
|
||||
if (visible != other.visible) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = log.hashCode()
|
||||
result = 31 * result + spannable.hashCode()
|
||||
result = 31 * result + visible.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.itsaky.androidide.adapters.LogLinesAdapter
|
||||
import com.itsaky.androidide.databinding.FragmentLogBinding
|
||||
import com.itsaky.androidide.models.LogLine
|
||||
import com.itsaky.androidide.utils.ILogger
|
||||
import com.itsaky.androidide.utils.ILogger.Priority
|
||||
|
||||
/**
|
||||
* Fragment to show logs in a [androidx.recyclerview.widget.RecyclerView].
|
||||
@@ -37,7 +38,7 @@ abstract class LogViewFragment : Fragment() {
|
||||
private val log = ILogger.newInstance(javaClass.simpleName)
|
||||
var binding: FragmentLogBinding? = null
|
||||
var adapter: LogLinesAdapter? = null
|
||||
|
||||
|
||||
fun appendLog(line: LogLine) {
|
||||
if (this.binding == null || this.adapter == null) {
|
||||
return
|
||||
@@ -48,16 +49,16 @@ abstract class LogViewFragment : Fragment() {
|
||||
this.adapter!!.add(line)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract fun getLogType(): String
|
||||
|
||||
|
||||
abstract fun isSimpleFormattingEnabled(): Boolean
|
||||
|
||||
protected open fun logLine(priority: Int, tag: String, message: String) {
|
||||
val line = LogLine(ILogger.priorityChar(priority), tag, message)
|
||||
protected open fun logLine(priority: Priority, tag: String, message: String) {
|
||||
val line = LogLine(priority, tag, message)
|
||||
appendLog(line)
|
||||
}
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
@@ -66,12 +67,12 @@ abstract class LogViewFragment : Fragment() {
|
||||
binding = FragmentLogBinding.inflate(inflater, container, false)
|
||||
return binding!!.root
|
||||
}
|
||||
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val manager = LinearLayoutManager(requireContext())
|
||||
this.binding!!.lines.layoutManager = manager
|
||||
|
||||
|
||||
this.adapter = LogLinesAdapter()
|
||||
this.binding!!.lines.adapter = this.adapter
|
||||
}
|
||||
|
||||
@@ -1,120 +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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.language.logs;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.itsaky.androidide.language.IDELanguage;
|
||||
import com.itsaky.androidide.models.LogLine;
|
||||
import com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.github.rosemoe.sora.lang.analysis.AnalyzeManager;
|
||||
import io.github.rosemoe.sora.lang.analysis.SimpleAnalyzeManager;
|
||||
import io.github.rosemoe.sora.lang.completion.CompletionCancelledException;
|
||||
import io.github.rosemoe.sora.lang.completion.CompletionPublisher;
|
||||
import io.github.rosemoe.sora.lang.smartEnter.NewlineHandler;
|
||||
import io.github.rosemoe.sora.lang.styling.MappedSpans;
|
||||
import io.github.rosemoe.sora.lang.styling.Styles;
|
||||
import io.github.rosemoe.sora.text.CharPosition;
|
||||
import io.github.rosemoe.sora.text.ContentReference;
|
||||
import io.github.rosemoe.sora.widget.SymbolPairMatch;
|
||||
|
||||
public class LogLanguageImpl extends IDELanguage {
|
||||
|
||||
private static final LogAnalyzer analyzer = new LogAnalyzer();
|
||||
|
||||
public void addLine(LogLine line) {
|
||||
analyzer.addLine(line);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public AnalyzeManager getAnalyzeManager() {
|
||||
return analyzer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInterruptionLevel() {
|
||||
return INTERRUPTION_LEVEL_STRONG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requireAutoComplete(
|
||||
@NonNull ContentReference content,
|
||||
@NonNull CharPosition position,
|
||||
@NonNull CompletionPublisher publisher,
|
||||
@NonNull Bundle extraArguments)
|
||||
throws CompletionCancelledException {}
|
||||
|
||||
@Override
|
||||
public int getIndentAdvance(@NonNull ContentReference content, int line, int column) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence format(CharSequence text) {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SymbolPairMatch getSymbolPairs() {
|
||||
return new SymbolPairMatch.DefaultSymbolPairs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NewlineHandler[] getNewlineHandlers() {
|
||||
return new NewlineHandler[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {}
|
||||
|
||||
private static class LogAnalyzer extends SimpleAnalyzeManager<Void> {
|
||||
|
||||
private static final List<LogLine> lines = new ArrayList<>();
|
||||
|
||||
public LogAnalyzer addLine(LogLine line) {
|
||||
if (line != null) lines.add(line);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Styles analyze(StringBuilder text, Delegate<Void> delegate) {
|
||||
final var styles = new Styles();
|
||||
final var colors = new MappedSpans.Builder();
|
||||
int lastLine = 0;
|
||||
for (int i = 0; i < lines.size() && !delegate.isCancelled(); i++) {
|
||||
if (i == 0) colors.addNormalIfNull();
|
||||
LogLine line = lines.get(i);
|
||||
colors.addIfNeeded(i, 0, SchemeAndroidIDE.forLogPriority(line.priority));
|
||||
lastLine = i;
|
||||
}
|
||||
colors.determine(lastLine);
|
||||
|
||||
styles.spans = colors.build();
|
||||
|
||||
return styles;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,7 +152,7 @@ public class GradleBuildService extends Service implements BuildService, IToolin
|
||||
|
||||
@Override
|
||||
public void logMessage(@NonNull LogLine line) {
|
||||
SERVER_LOGGER.log(ILogger.priority(line.priorityChar), line.formattedTagAndMessage());
|
||||
SERVER_LOGGER.log(line.priority, line.formattedTagAndMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -316,12 +316,15 @@ public class GradleBuildService extends Service implements BuildService, IToolin
|
||||
|
||||
isBuildInProgress = true;
|
||||
return server
|
||||
.executeTasks(new TaskExecutionMessage(":", Arrays.asList(tasks), getGradleInstallationPath()))
|
||||
.executeTasks(
|
||||
new TaskExecutionMessage(":", Arrays.asList(tasks), getGradleInstallationPath()))
|
||||
.thenApply(this::markBuildAsFinished);
|
||||
}
|
||||
|
||||
private String getGradleInstallationPath() {
|
||||
return StudioApp.getInstance().getPrefManager().getString(BuildPreferences.KEY_CUSTOM_GRADLE_INSTALLATION, "");
|
||||
return StudioApp.getInstance()
|
||||
.getPrefManager()
|
||||
.getString(BuildPreferences.KEY_CUSTOM_GRADLE_INSTALLATION, "");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -338,7 +341,9 @@ public class GradleBuildService extends Service implements BuildService, IToolin
|
||||
|
||||
isBuildInProgress = true;
|
||||
return server
|
||||
.executeTasks(new TaskExecutionMessage(projectPath, Arrays.asList(tasks), getGradleInstallationPath()))
|
||||
.executeTasks(
|
||||
new TaskExecutionMessage(
|
||||
projectPath, Arrays.asList(tasks), getGradleInstallationPath()))
|
||||
.thenApply(this::markBuildAsFinished);
|
||||
}
|
||||
|
||||
@@ -398,7 +403,7 @@ public class GradleBuildService extends Service implements BuildService, IToolin
|
||||
return null;
|
||||
}
|
||||
|
||||
return new EventListener() {
|
||||
return new EventListener() {
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
|
||||
@@ -17,11 +17,6 @@
|
||||
*/
|
||||
package com.itsaky.androidide.syntax.colorschemes;
|
||||
|
||||
import static com.itsaky.androidide.models.LogLine.DEBUG;
|
||||
import static com.itsaky.androidide.models.LogLine.ERROR;
|
||||
import static com.itsaky.androidide.models.LogLine.INFO;
|
||||
import static com.itsaky.androidide.models.LogLine.WARNING;
|
||||
|
||||
import android.graphics.Color;
|
||||
|
||||
import io.github.rosemoe.sora.lang.styling.TextStyle;
|
||||
@@ -117,38 +112,6 @@ public class SchemeAndroidIDE extends EditorColorScheme {
|
||||
return TextStyle.makeStyle(id, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make style for the given log priority.
|
||||
*
|
||||
* @param priority The priority.
|
||||
* @return The style.
|
||||
*/
|
||||
public static long forLogPriority(int priority) {
|
||||
return get(getLogPriorityId(priority));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the appropriate color id for the given log line priority.
|
||||
*
|
||||
* @param priority The log line priority.
|
||||
* @return The color id.
|
||||
*/
|
||||
public static int getLogPriorityId(int priority) {
|
||||
if (priority == ERROR) {
|
||||
return LOG_ERROR;
|
||||
}
|
||||
|
||||
if (priority == WARNING) {
|
||||
return LOG_WARNING;
|
||||
}
|
||||
|
||||
if (priority == INFO) {
|
||||
return LOG_INFO;
|
||||
}
|
||||
|
||||
return DEBUG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyDefault() {
|
||||
// Apply default colors
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ 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 <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_focused="true">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:radius="8dp" />
|
||||
<solid android:color="@color/primaryDarkColor" />
|
||||
<stroke android:width="2dp" android:color="@color/secondaryColor" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:radius="8dp" />
|
||||
<solid android:color="@color/primaryLightColor" />
|
||||
<stroke android:width="0dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
||||
@@ -14,7 +14,10 @@
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<HorizontalScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/horizontalScrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true">
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="8dp" >
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
android:id="@+id/log_priority_spinner"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:entries="@array/logcat_units" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/tag_filter_input"
|
||||
style="@style/AppTheme.TextInputLayout.Outlined"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/hint_log_tag_filter"
|
||||
app:hintEnabled="true"
|
||||
app:hintTextColor="@color/secondaryColor" >
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:singleLine="true" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<com.itsaky.androidide.views.editor.IDEEditor
|
||||
android:id="@+id/editor"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -26,13 +26,12 @@
|
||||
<item>mm</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="logcat_units">
|
||||
<string-array name="logcat_priorities">
|
||||
<item>Verbose</item>
|
||||
<item>Debug</item>
|
||||
<item>Info</item>
|
||||
<item>Warning</item>
|
||||
<item>Error</item>
|
||||
<item>Fatal</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
@@ -139,9 +139,11 @@ public class RemoteEndpoint
|
||||
try {
|
||||
out.consume(notificationMessage);
|
||||
} catch (Exception exception) {
|
||||
int logLevel =
|
||||
JsonRpcException.indicatesStreamClosed(exception) ? ILogger.INFO : ILogger.WARNING;
|
||||
LOG.log(logLevel, "Failed to send notification message.", exception);
|
||||
ILogger.Priority priority =
|
||||
JsonRpcException.indicatesStreamClosed(exception)
|
||||
? ILogger.Priority.INFO
|
||||
: ILogger.Priority.WARNING;
|
||||
LOG.log(priority, "Failed to send notification message.", exception);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,29 +17,12 @@
|
||||
*/
|
||||
package com.itsaky.androidide.models;
|
||||
|
||||
import com.itsaky.androidide.utils.ILogger;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class LogLine {
|
||||
|
||||
// It makes things easier in LogLanguageImpl
|
||||
public static int INFO;
|
||||
public static int DEBUG;
|
||||
public static int ERROR;
|
||||
public static int WARNING;
|
||||
|
||||
static {
|
||||
try {
|
||||
final var klass = Class.forName("com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE");
|
||||
INFO = klass.getField("LOG_INFO").getInt(null);
|
||||
DEBUG = klass.getField("LOG_DEBUG").getInt(null);
|
||||
ERROR = klass.getField("LOG_ERROR").getInt(null);
|
||||
WARNING = klass.getField("LOG_WARNING").getInt(null);
|
||||
} catch (Throwable err) {
|
||||
INFO = 0;
|
||||
DEBUG = 1;
|
||||
ERROR = 2;
|
||||
WARNING = 3;
|
||||
}
|
||||
}
|
||||
|
||||
public String unformatted;
|
||||
public String date;
|
||||
public String time;
|
||||
@@ -47,35 +30,34 @@ public class LogLine {
|
||||
public String tid;
|
||||
public String tag;
|
||||
public String message;
|
||||
public char priorityChar;
|
||||
public int priority;
|
||||
public ILogger.Priority priority;
|
||||
public boolean formatted;
|
||||
|
||||
// For JSONRpc
|
||||
@SuppressWarnings("unused")
|
||||
protected LogLine() {}
|
||||
|
||||
public LogLine(char priorityChar, String tag, String message) {
|
||||
this("", "", "", "", priorityChar, tag, message);
|
||||
public LogLine(ILogger.Priority priority, String tag, String message) {
|
||||
this(priority, "", "", "", "", tag, message);
|
||||
}
|
||||
|
||||
public LogLine(
|
||||
ILogger.Priority priority,
|
||||
String date,
|
||||
String time,
|
||||
String pid,
|
||||
String tid,
|
||||
char priorityChar,
|
||||
String tag,
|
||||
String message) {
|
||||
this(date, time, pid, tid, priorityChar, tag, message, true);
|
||||
this(priority, date, time, pid, tid, tag, message, true);
|
||||
}
|
||||
|
||||
public LogLine(
|
||||
ILogger.Priority priority,
|
||||
String date,
|
||||
String time,
|
||||
String pid,
|
||||
String tid,
|
||||
char priorityChar,
|
||||
String tag,
|
||||
String message,
|
||||
boolean formatted) {
|
||||
@@ -83,40 +65,31 @@ public class LogLine {
|
||||
this.time = time;
|
||||
this.pid = pid;
|
||||
this.tid = tid;
|
||||
this.priorityChar = priorityChar;
|
||||
this.tag = tag;
|
||||
this.message = message;
|
||||
this.priority = parsePriority(priorityChar);
|
||||
this.priority = priority;
|
||||
this.formatted = formatted;
|
||||
}
|
||||
|
||||
private int parsePriority(char s) {
|
||||
final var c = Character.toLowerCase(s);
|
||||
if (c == 'w') {
|
||||
return WARNING;
|
||||
} else if (c == 'e') {
|
||||
return ERROR;
|
||||
} else if (c == 'i') {
|
||||
return INFO;
|
||||
} else {
|
||||
return DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
public LogLine(String unformatted) {
|
||||
this.unformatted = unformatted;
|
||||
this.formatted = false;
|
||||
}
|
||||
|
||||
private static ILogger.Priority parsePriority(char s) {
|
||||
return ILogger.priority(Character.toUpperCase(s));
|
||||
}
|
||||
|
||||
public static LogLine forLogString(final String log) {
|
||||
try {
|
||||
final var split = log.split("\\s", 7);
|
||||
return new LogLine(
|
||||
parsePriority(split[4].charAt(0)),
|
||||
split[0], // date
|
||||
split[1], // time
|
||||
split[2], // process id
|
||||
split[3], // thread id
|
||||
split[4].charAt(0), // priority
|
||||
// priority
|
||||
split[5], // tag
|
||||
split[6] // message
|
||||
);
|
||||
@@ -128,7 +101,9 @@ public class LogLine {
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.formatted
|
||||
? String.format("%s %s %s/%s %s/%s %s", date, time, pid, tid, priorityChar, tag, message)
|
||||
? String.format(
|
||||
"%s %s %s/%s %s/%s %s",
|
||||
date, time, pid, tid, ILogger.priorityChar(priority), tag, message)
|
||||
: this.unformatted;
|
||||
}
|
||||
|
||||
@@ -149,7 +124,8 @@ public class LogLine {
|
||||
|
||||
public String toSimpleString() {
|
||||
return this.formatted
|
||||
? String.format("%-25s %-2s %s", trimIfNeeded(tag, 25), priorityChar, message)
|
||||
? String.format(
|
||||
"%-25s %-2s %s", trimIfNeeded(tag, 25), ILogger.priorityChar(priority), message)
|
||||
: this.unformatted;
|
||||
}
|
||||
|
||||
@@ -158,4 +134,29 @@ public class LogLine {
|
||||
? String.format("%-25s %s", trimIfNeeded(tag, 25), message)
|
||||
: this.unformatted;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final LogLine logLine = (LogLine) o;
|
||||
return formatted == logLine.formatted
|
||||
&& Objects.equals(unformatted, logLine.unformatted)
|
||||
&& Objects.equals(date, logLine.date)
|
||||
&& Objects.equals(time, logLine.time)
|
||||
&& Objects.equals(pid, logLine.pid)
|
||||
&& Objects.equals(tid, logLine.tid)
|
||||
&& Objects.equals(tag, logLine.tag)
|
||||
&& Objects.equals(message, logLine.message)
|
||||
&& priority == logLine.priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(unformatted, date, time, pid, tid, tag, message, priority, formatted);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class AndroidLogger extends ILogger {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLog(int priority, String message) {
|
||||
protected void doLog(Priority priority, String message) {
|
||||
switch (priority) {
|
||||
case ERROR:
|
||||
Log.e(TAG, message);
|
||||
|
||||
@@ -48,11 +48,15 @@ import java.util.Objects;
|
||||
*/
|
||||
public abstract class ILogger {
|
||||
|
||||
public static final int DEBUG = 0;
|
||||
public static final int WARNING = 1;
|
||||
public static final int ERROR = 2;
|
||||
public static final int INFO = 3;
|
||||
public static final int VERBOSE = 4;
|
||||
/** Logging priority. */
|
||||
public enum Priority {
|
||||
DEBUG,
|
||||
WARNING,
|
||||
ERROR,
|
||||
INFO,
|
||||
VERBOSE
|
||||
}
|
||||
|
||||
private static final String MSG_SEPARATOR = " "; // Separate messages with a space.
|
||||
private static final List<LogListener> logListeners = new ArrayList<>();
|
||||
private static ILogger instance;
|
||||
@@ -86,52 +90,21 @@ public abstract class ILogger {
|
||||
return createInstance(tag);
|
||||
}
|
||||
|
||||
public static String priorityText(int priority) {
|
||||
switch (priority) {
|
||||
case DEBUG:
|
||||
return "DEBUG";
|
||||
case INFO:
|
||||
return "INFO";
|
||||
case VERBOSE:
|
||||
return "VERBOSE";
|
||||
case ERROR:
|
||||
return "ERROR";
|
||||
case WARNING:
|
||||
return "WARNING";
|
||||
default:
|
||||
return "<UNKNOWN>";
|
||||
}
|
||||
public static String priorityText(Priority priority) {
|
||||
return priority.name();
|
||||
}
|
||||
|
||||
public static char priorityChar(int priority) {
|
||||
switch (priority) {
|
||||
case INFO:
|
||||
return 'I';
|
||||
case VERBOSE:
|
||||
return 'V';
|
||||
case ERROR:
|
||||
return 'E';
|
||||
case WARNING:
|
||||
return 'W';
|
||||
default:
|
||||
return 'D';
|
||||
}
|
||||
public static char priorityChar(Priority priority) {
|
||||
return Character.toUpperCase(priorityText(priority).charAt(0));
|
||||
}
|
||||
|
||||
public static int priority(char priorityChar) {
|
||||
switch (priorityChar) {
|
||||
case 'I':
|
||||
return INFO;
|
||||
case 'V':
|
||||
return VERBOSE;
|
||||
case 'E':
|
||||
return ERROR;
|
||||
case 'W':
|
||||
return WARNING;
|
||||
case 'D':
|
||||
default:
|
||||
return DEBUG;
|
||||
public static Priority priority(char priorityChar) {
|
||||
for (var priority : Priority.values()) {
|
||||
if (priorityChar(priority) == priorityChar) {
|
||||
return priority;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid priority character: " + priorityChar);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,7 +114,7 @@ public abstract class ILogger {
|
||||
* @return This logger instance.
|
||||
*/
|
||||
public ILogger error(Object... messages) {
|
||||
return log(ERROR, messages);
|
||||
return log(Priority.ERROR, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,12 +124,12 @@ public abstract class ILogger {
|
||||
* @param messages The messages to log.
|
||||
* @return This logger instance.
|
||||
*/
|
||||
public ILogger log(int priority, Object... messages) {
|
||||
public ILogger log(Priority priority, Object... messages) {
|
||||
logAndNotify(priority, generateMessage(messages));
|
||||
return this;
|
||||
}
|
||||
|
||||
private void logAndNotify(int priority, String msg) {
|
||||
private void logAndNotify(Priority priority, String msg) {
|
||||
doLog(priority, msg);
|
||||
for (final var listener : logListeners) {
|
||||
listener.log(priority, TAG, msg);
|
||||
@@ -183,13 +156,13 @@ public abstract class ILogger {
|
||||
*
|
||||
* @param priority The priority for this log message.
|
||||
* @param message The full generated message for this log. Might contain new lines.
|
||||
* @see ILogger#DEBUG
|
||||
* @see ILogger#ERROR
|
||||
* @see ILogger#WARNING
|
||||
* @see ILogger#VERBOSE
|
||||
* @see ILogger#INFO
|
||||
* @see ILogger.Priority#DEBUG
|
||||
* @see ILogger.Priority#ERROR
|
||||
* @see ILogger.Priority#WARNING
|
||||
* @see ILogger.Priority#VERBOSE
|
||||
* @see ILogger.Priority#INFO
|
||||
*/
|
||||
protected abstract void doLog(int priority, String message);
|
||||
protected abstract void doLog(Priority priority, String message);
|
||||
|
||||
/**
|
||||
* Log warning messages.
|
||||
@@ -198,7 +171,7 @@ public abstract class ILogger {
|
||||
* @return This logger instance.
|
||||
*/
|
||||
public ILogger warn(Object... messages) {
|
||||
return log(WARNING, messages);
|
||||
return log(Priority.WARNING, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,7 +181,7 @@ public abstract class ILogger {
|
||||
* @return This logger instance.
|
||||
*/
|
||||
public ILogger verbose(Object... messages) {
|
||||
return log(VERBOSE, messages);
|
||||
return log(Priority.VERBOSE, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -218,7 +191,7 @@ public abstract class ILogger {
|
||||
* @return This logger instance.
|
||||
*/
|
||||
public ILogger info(Object... messages) {
|
||||
return log(INFO, messages);
|
||||
return log(Priority.INFO, messages);
|
||||
}
|
||||
|
||||
/** Logs the name of method and class which calls this method. */
|
||||
@@ -233,7 +206,7 @@ public abstract class ILogger {
|
||||
* @return This logger instance.
|
||||
*/
|
||||
public ILogger debug(Object... messages) {
|
||||
return log(DEBUG, messages);
|
||||
return log(Priority.DEBUG, messages);
|
||||
}
|
||||
|
||||
protected String getCallerClassDescription() {
|
||||
@@ -254,6 +227,6 @@ public abstract class ILogger {
|
||||
|
||||
/** A listener which can be used to listen to log events. */
|
||||
public interface LogListener {
|
||||
void log(int priority, String tag, String message);
|
||||
void log(Priority priority, String tag, String message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ public class JvmLogger extends ILogger {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLog(int priority, String message) {
|
||||
final var log = new LogLine(priorityChar(priority), TAG, message);
|
||||
protected void doLog(Priority priority, String message) {
|
||||
final var log = new LogLine(priority, TAG, message);
|
||||
if (interceptor != null) {
|
||||
interceptor.onLog(log);
|
||||
} else {
|
||||
|
||||
Binary file not shown.
@@ -17,14 +17,15 @@
|
||||
package com.itsaky.lsp.api.util
|
||||
|
||||
import com.itsaky.androidide.utils.ILogger
|
||||
import com.itsaky.androidide.utils.ILogger.Priority
|
||||
|
||||
/**
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
/** @author Akash Yadav */
|
||||
class ReflectiveLogListener(private val receiver: Class<out Any>) : ILogger.LogListener {
|
||||
override fun log(priority: Int, tag: String, message: String) {
|
||||
val method = receiver.getDeclaredMethod("log", Int::class.java, String::class.java, String::class.java)
|
||||
override fun log(priority: Priority, tag: String, message: String) {
|
||||
val method =
|
||||
receiver.getDeclaredMethod(
|
||||
"log", Priority::class.java, String::class.java, String::class.java)
|
||||
method.isAccessible = true
|
||||
method.invoke(null, priority, tag, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user