mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
-Enhanced implementation of JLS
This commit is contained in:
Binary file not shown.
@@ -92,6 +92,7 @@ import me.piruin.quickaction.QuickAction;
|
||||
import com.itsaky.lsp.DidSaveTextDocumentParams;
|
||||
import com.itsaky.lsp.DidChangeTextDocumentParams;
|
||||
import com.itsaky.lsp.TextDocumentIdentifier;
|
||||
import com.itsaky.lsp.JavaColors;
|
||||
|
||||
public class EditorActivity extends StudioActivity implements FileTreeFragment.FileActionListener,
|
||||
IDEService.BuildListener,
|
||||
@@ -705,6 +706,13 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void javaColors(JavaColors colors) {
|
||||
final File file = new File(colors.uri);
|
||||
final EditorFragment editor = mPagerAdapter.findEditorByFile(file);
|
||||
editor.setJavaColors(colors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMessage(ShowMessageParams params) {
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.itsaky.androidide.fragments.preferences.EditorPreferences;
|
||||
import com.itsaky.androidide.interfaces.JLSRequestor;
|
||||
import com.itsaky.androidide.language.groovy.GroovyLanguage;
|
||||
import com.itsaky.androidide.language.java.JavaLanguage;
|
||||
import com.itsaky.androidide.language.java.JavaLanguageAnalyzer;
|
||||
import com.itsaky.androidide.language.xml.XMLLanguage;
|
||||
import com.itsaky.androidide.language.xml.lexer.XMLLexer;
|
||||
import com.itsaky.androidide.models.AndroidProject;
|
||||
@@ -24,6 +25,7 @@ import com.itsaky.androidide.utils.VersionedFileManager;
|
||||
import com.itsaky.lsp.Diagnostic;
|
||||
import com.itsaky.lsp.DidChangeTextDocumentParams;
|
||||
import com.itsaky.lsp.DidSaveTextDocumentParams;
|
||||
import com.itsaky.lsp.JavaColors;
|
||||
import com.itsaky.lsp.Range;
|
||||
import com.itsaky.lsp.TextDocumentContentChangeEvent;
|
||||
import com.itsaky.lsp.TextDocumentIdentifier;
|
||||
@@ -55,6 +57,8 @@ public class EditorFragment extends BaseFragment implements EditorEventListener,
|
||||
private JLSRequestor jlsRequestor;
|
||||
private static AndroidProject project;
|
||||
|
||||
private JavaLanguage mJavaLanguage;
|
||||
|
||||
public static final String KEY_FILE_PATH = "file_path";
|
||||
public static final String KEY_PROJECT = "project";
|
||||
public static final String EXT_JAVA = ".java";
|
||||
@@ -75,6 +79,14 @@ public class EditorFragment extends BaseFragment implements EditorEventListener,
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setJavaColors(JavaColors colors) {
|
||||
if(mJavaLanguage != null) {
|
||||
JavaLanguageAnalyzer analyzer = (JavaLanguageAnalyzer) mJavaLanguage.getAnalyzer();
|
||||
analyzer.setJavaColors(colors);
|
||||
binding.editorCodeEditor.notifySpansChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public static EditorFragment newInstance(File file, AndroidProject project) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(KEY_FILE_PATH, file.getAbsolutePath());
|
||||
@@ -221,7 +233,7 @@ public class EditorFragment extends BaseFragment implements EditorEventListener,
|
||||
private void postRead() {
|
||||
binding.editorCodeEditor.setFile(getFile());
|
||||
if (mFile.isFile() && mFile.getName().endsWith(EXT_JAVA)) {
|
||||
binding.editorCodeEditor.setEditorLanguage(new JavaLanguage(project));
|
||||
binding.editorCodeEditor.setEditorLanguage(mJavaLanguage = new JavaLanguage(project));
|
||||
binding.editorCodeEditor.setColorScheme(new SchemeVS2019());
|
||||
} else if (mFile.isFile() && mFile.getName().endsWith(EXT_XML)) {
|
||||
binding.editorCodeEditor.setEditorLanguage(new XMLLanguage());
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
package com.itsaky.androidide.language.java;
|
||||
|
||||
import com.itsaky.androidide.app.StudioApp;
|
||||
import com.itsaky.androidide.syntax.lexer.Lexer;
|
||||
import com.itsaky.androidide.syntax.lexer.impls.java.JavaLexerImpl;
|
||||
import com.itsaky.androidide.syntax.lexer.tokens.Token;
|
||||
import com.itsaky.lsp.Range;
|
||||
import io.github.rosemoe.editor.interfaces.CodeAnalyzer;
|
||||
import io.github.rosemoe.editor.text.TextAnalyzeResult;
|
||||
import io.github.rosemoe.editor.text.TextAnalyzer;
|
||||
import java.util.ArrayList;
|
||||
import com.blankj.utilcode.util.ThrowableUtils;
|
||||
import java.util.List;
|
||||
import com.itsaky.lsp.JavaColors;
|
||||
|
||||
public class JavaLanguageAnalyzer implements CodeAnalyzer {
|
||||
|
||||
private JavaColors colors;
|
||||
|
||||
@Override
|
||||
public void analyze(CharSequence content, TextAnalyzeResult colors, TextAnalyzer.AnalyzeThread.Delegate delegate) {
|
||||
try {
|
||||
JavaLexerImpl lexer = new JavaLexerImpl(content.toString(), colors);
|
||||
lexer.setJavaColors(this.colors);
|
||||
lexer.init();
|
||||
|
||||
// Adding spans, hex colors, block lines and all is handled by JavaLexerImpl
|
||||
@@ -33,4 +34,8 @@ public class JavaLanguageAnalyzer implements CodeAnalyzer {
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void setJavaColors(JavaColors colors) {
|
||||
this.colors = colors;
|
||||
}
|
||||
}
|
||||
|
||||
+73
-17
@@ -7,27 +7,36 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.itsaky.androidide.app.StudioApp;
|
||||
import com.itsaky.androidide.models.AndroidProject;
|
||||
import com.itsaky.androidide.shell.ShellServer;
|
||||
import com.itsaky.androidide.utils.Environment;
|
||||
import com.itsaky.androidide.utils.FileUtil;
|
||||
import com.itsaky.androidide.utils.Logger;
|
||||
import com.itsaky.lsp.CancelParams;
|
||||
import com.itsaky.lsp.CodeActionParams;
|
||||
import com.itsaky.lsp.CompletionItem;
|
||||
import com.itsaky.lsp.CompletionList;
|
||||
import com.itsaky.lsp.DidChangeConfigurationParams;
|
||||
import com.itsaky.lsp.DidChangeTextDocumentParams;
|
||||
import com.itsaky.lsp.DidCloseTextDocumentParams;
|
||||
import com.itsaky.lsp.DidOpenTextDocumentParams;
|
||||
import com.itsaky.lsp.DidSaveTextDocumentParams;
|
||||
import com.itsaky.lsp.DocumentFormattingParams;
|
||||
import com.itsaky.lsp.InitializeParams;
|
||||
import com.itsaky.lsp.JavaColors;
|
||||
import com.itsaky.lsp.JavaReportProgressParams;
|
||||
import com.itsaky.lsp.JavaStartProgressParams;
|
||||
import com.itsaky.lsp.LanguageClient;
|
||||
import com.itsaky.lsp.Message;
|
||||
import com.itsaky.lsp.PublishDiagnosticsParams;
|
||||
import com.itsaky.lsp.TextDocumentPositionParams;
|
||||
import com.itsaky.lsp.TextEdit;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
@@ -45,10 +54,13 @@ public class JavaLanguageServer implements ShellServer.Callback {
|
||||
|
||||
private LanguageClient client;
|
||||
private Socket server;
|
||||
private OutputStream send;
|
||||
private BufferedOutputStream send;
|
||||
|
||||
private final ConcurrentHashMap<Integer, Integer> completionRequests = new ConcurrentHashMap<>();
|
||||
private final BlockingQueue<CompletionList> responseQueue = new ArrayBlockingQueue<CompletionList>(1);
|
||||
private final ConcurrentHashMap<Integer, Integer> formattingRequests = new ConcurrentHashMap<>();
|
||||
|
||||
private final BlockingQueue<CompletionList> completionResponseQueue = new ArrayBlockingQueue<>(20);
|
||||
private final BlockingQueue<List<TextEdit>> formattingResponseQueue = new ArrayBlockingQueue<>(20);
|
||||
|
||||
private static final String START_COMMAND = "java " +
|
||||
"--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED " +
|
||||
@@ -87,10 +99,12 @@ public class JavaLanguageServer implements ShellServer.Callback {
|
||||
String line;
|
||||
while((line = reader.readLine()) != null) {
|
||||
final String temp = line;
|
||||
if(temp == null || temp.trim().length() <= 0) continue;
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
onServerOut(temp);
|
||||
});
|
||||
}
|
||||
logger.i("Socket disconnected");
|
||||
} catch (Throwable e) {
|
||||
logEx(e);
|
||||
}
|
||||
@@ -103,13 +117,13 @@ public class JavaLanguageServer implements ShellServer.Callback {
|
||||
}
|
||||
|
||||
private Socket connectAndGet() {
|
||||
int tryCount = 0;
|
||||
while(server == null || send == null || !server.isConnected()) {
|
||||
try {
|
||||
server = new Socket(SOCKET_HOST, SOCKET_PORT);
|
||||
send = server.getOutputStream();
|
||||
OutputStream o = server.getOutputStream();
|
||||
if(o != null)
|
||||
send = new BufferedOutputStream(o);
|
||||
} catch (IOException e) {
|
||||
tryCount++;
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e2) {}
|
||||
@@ -175,11 +189,26 @@ public class JavaLanguageServer implements ShellServer.Callback {
|
||||
completionRequests.put(id, id);
|
||||
CompletionList result = null;
|
||||
try {
|
||||
result = responseQueue.take();
|
||||
result = completionResponseQueue.take();
|
||||
} catch (InterruptedException e) {}
|
||||
return Pair.create(id, result);
|
||||
}
|
||||
|
||||
public void resolveCompletion(CompletionItem item) {
|
||||
write(Method.RESOLVE_COMPLETION, gson.toJson(item));
|
||||
}
|
||||
|
||||
public List<TextEdit> formatting(DocumentFormattingParams params) {
|
||||
int id = write(Method.FORMATTING, gson.toJson(params));
|
||||
formattingRequests.put(id, id);
|
||||
List<TextEdit> edits = null;
|
||||
return edits;
|
||||
}
|
||||
|
||||
public void codeActions(CodeActionParams p) {
|
||||
write(Method.CODE_ACTION, gson.toJson(p));
|
||||
}
|
||||
|
||||
public void cancelRequest(int requestId) {
|
||||
CancelParams p = new CancelParams();
|
||||
p.id = requestId;
|
||||
@@ -190,12 +219,13 @@ public class JavaLanguageServer implements ShellServer.Callback {
|
||||
final int id = UNIVERSION_ID++;
|
||||
msg.id = id;
|
||||
if(this.send != null) {
|
||||
final String body = gson.toJson(msg);
|
||||
final String head = String.format("Content-Length: %d\r\n\r\n", body.length());
|
||||
// Message must end with a \n so that server can read it correctly
|
||||
final String body = gson.toJson(msg) + "\n";
|
||||
final byte[] bodyBytes = body.getBytes(StandardCharsets.UTF_8);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
logger.i(body);
|
||||
send.write(head.concat(body).getBytes(StandardCharsets.UTF_8));
|
||||
send.write(bodyBytes);
|
||||
send.flush();
|
||||
} catch (Throwable e) {
|
||||
logger.e("Error writing to server: " + ThrowableUtils.getFullStackTrace(e));
|
||||
}
|
||||
@@ -219,18 +249,31 @@ public class JavaLanguageServer implements ShellServer.Callback {
|
||||
|
||||
@Override
|
||||
public void output(CharSequence charSequence) {
|
||||
logger.d(charSequence);
|
||||
writeOut(charSequence.toString());
|
||||
}
|
||||
|
||||
private BufferedOutputStream os;
|
||||
|
||||
private void writeOut(String data) {
|
||||
try {
|
||||
if(os == null) {
|
||||
os = new BufferedOutputStream(new FileOutputStream(new File(FileUtil.getExternalStorageDir(), "ide_xlog/out.txt"), true));
|
||||
}
|
||||
os.write(data.getBytes());
|
||||
os.flush();
|
||||
} catch (Throwable th) {
|
||||
logger.e(ThrowableUtils.getFullStackTrace(th));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called on UI Thread, do not perform time consuming or networking tasks
|
||||
*/
|
||||
private void onServerOut(String line) {
|
||||
if(line == null || line.trim().length() <= 0) return;
|
||||
if(line.contains(CONTENT_LENGTH)) line = line.substring(0, line.lastIndexOf(CONTENT_LENGTH));
|
||||
logger.v(line);
|
||||
if(this.client == null) return;
|
||||
try {
|
||||
logger.v(line);
|
||||
JsonObject obj = new JsonParser().parse(line.trim()).getAsJsonObject();
|
||||
if(obj.has(Key.METHOD)) {
|
||||
final String method = obj.get(Key.METHOD).getAsString();
|
||||
@@ -240,21 +283,29 @@ public class JavaLanguageServer implements ShellServer.Callback {
|
||||
} else if(method.equals(Method.JLS_PROGRESS_START)) {
|
||||
JavaStartProgressParams params = gson.fromJson(obj.get(Key.PARAMS).toString(), JavaStartProgressParams.class);
|
||||
client.javaProgressStart(params);
|
||||
} if(method.equals(Method.JLS_PROGRESS_REPORT)) {
|
||||
} else if(method.equals(Method.JLS_PROGRESS_REPORT)) {
|
||||
JavaReportProgressParams params = gson.fromJson(obj.get(Key.PARAMS).toString(), JavaReportProgressParams.class);
|
||||
client.javaProgressReport(params);
|
||||
} if(method.equals(Method.JLS_PROGRESS_END)) {
|
||||
} else if(method.equals(Method.JLS_PROGRESS_END)) {
|
||||
client.javaProgressEnd();
|
||||
} else if(method.equals(Method.JAVA_COLORS)) {
|
||||
JavaColors colors = gson.fromJson(obj.get(Key.PARAMS).toString(), JavaColors.class);
|
||||
client.javaColors(colors);
|
||||
}
|
||||
} else if(obj.has(Key.ID)) {
|
||||
int id = obj.get(Key.ID).getAsInt();
|
||||
if(completionRequests.containsKey(id)) {
|
||||
final CompletionList list = gson.fromJson(obj.get(Key.RESULT).getAsJsonObject(), CompletionList.class);
|
||||
responseQueue.put(list);
|
||||
completionResponseQueue.put(list);
|
||||
} else if(formattingRequests.containsKey(id)) {
|
||||
final List<TextEdit> list = gson.fromJson(obj.get(Key.RESULT).getAsJsonObject(), TypeToken.getParameterized(List.class, TextEdit.class).getType());
|
||||
formattingResponseQueue.put(list);
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
logger.e("onServerOut", ThrowableUtils.getFullStackTrace(th));
|
||||
logger.e("onServerOut", line, ThrowableUtils.getFullStackTrace(th));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,6 +334,8 @@ public class JavaLanguageServer implements ShellServer.Callback {
|
||||
public static final String PREPARE_RENAME = "textDocument/prepareRename";
|
||||
public static final String RENAME = "textDocument/rename";
|
||||
|
||||
public static final String FORMATTING = "textDocument/formatting";
|
||||
|
||||
public static final String CODE_ACTION = "textDocument/codeAction";
|
||||
|
||||
public static final String CANCEL_REQUEST = "$/cancelRequest";
|
||||
@@ -300,5 +353,8 @@ public class JavaLanguageServer implements ShellServer.Callback {
|
||||
public static final String PARAMS = "params";
|
||||
public static final String ID = "id";
|
||||
public static final String RESULT = "result";
|
||||
|
||||
public static final String STATICS = "statics";
|
||||
public static final String FIELDS = "fields";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@ import com.blankj.utilcode.util.ThrowableUtils;
|
||||
import com.itsaky.androidide.utils.Logger;
|
||||
import com.itsaky.lsp.CompletionItem;
|
||||
import com.itsaky.lsp.CompletionItemKind;
|
||||
import io.github.rosemoe.editor.text.CharPosition;
|
||||
import com.itsaky.lsp.Position;
|
||||
import com.itsaky.lsp.TextEdit;
|
||||
import io.github.rosemoe.editor.text.Cursor;
|
||||
import io.github.rosemoe.editor.widget.CodeEditor;
|
||||
import java.util.List;
|
||||
|
||||
public class CompletionItemWrapper implements SuggestItem, Comparable {
|
||||
|
||||
@@ -62,6 +64,22 @@ public class CompletionItemWrapper implements SuggestItem, Comparable {
|
||||
|
||||
if(shiftLeft && !atEnd)
|
||||
editor.moveSelectionLeft();
|
||||
|
||||
final List<TextEdit> edits = item.additionalTextEdits;
|
||||
if(edits != null && edits.size() > 0) {
|
||||
for(int i=0;i<edits.size();i++) {
|
||||
final TextEdit edit = edits.get(i);
|
||||
if(edit == null || edit.range == null || edit.newText == null) continue;
|
||||
final Position start = edit.range.start;
|
||||
final Position end = edit.range.end;
|
||||
if(start == null || end == null) continue;
|
||||
if(start.equals(end)) {
|
||||
editor.getText().insert(start.line, start.character, edit.newText);
|
||||
} else {
|
||||
editor.getText().replace(start.line, start.character, end.line, end.character, edit.newText);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
Logger.instance("CompletionItemWrapper").e("onSelectThis, Error: ", ThrowableUtils.getFullStackTrace(th));
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ public class LogReceiver extends BroadcastReceiver {
|
||||
Matcher m = LOG_HEAD_PATTERN.matcher(line);
|
||||
LogLine log = null;
|
||||
final boolean find = line != null && line.trim().length() > 2 /*if length() == 2 then only [] is available*/ && m.find();
|
||||
Logger.instance().i("line -> " + line + "\nlogTag find() -> " + find);
|
||||
if(find) {
|
||||
String date = "";
|
||||
String time = "";
|
||||
@@ -83,10 +82,8 @@ public class LogReceiver extends BroadcastReceiver {
|
||||
} else {
|
||||
log = new LogLine("", "", "", "", "", "", line);
|
||||
}
|
||||
|
||||
Logger.instance().i("log = " + log + "\nlogListener = " + listener);
|
||||
|
||||
if(log != null && listener != null) {
|
||||
Logger.instance().i("listener.appendLogLine(...) log ->\n" + log);
|
||||
listener.appendLogLine(log);
|
||||
logTag = null;
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
package com.itsaky.androidide.syntax.lexer.impls.java;
|
||||
|
||||
import android.graphics.Color;
|
||||
import com.itsaky.androidide.language.java.parser.JavaLexer;
|
||||
import com.itsaky.androidide.syntax.lexer.Lexer;
|
||||
import com.itsaky.androidide.syntax.lexer.impls.BaseJavaLexer;
|
||||
import com.itsaky.androidide.syntax.lexer.tokens.Token;
|
||||
import com.itsaky.androidide.syntax.lexer.tokens.TokenType;
|
||||
import com.itsaky.lsp.Range;
|
||||
import io.github.rosemoe.editor.struct.BlockLine;
|
||||
import io.github.rosemoe.editor.struct.HexColor;
|
||||
import io.github.rosemoe.editor.text.CharPosition;
|
||||
import io.github.rosemoe.editor.text.TextAnalyzeResult;
|
||||
import io.github.rosemoe.editor.widget.EditorColorScheme;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.List;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import com.itsaky.lsp.JavaColors;
|
||||
|
||||
public class JavaLexerImpl extends BaseJavaLexer implements Lexer {
|
||||
|
||||
private JavaColors javaColors;
|
||||
|
||||
public JavaLexerImpl(String content, TextAnalyzeResult colors) {
|
||||
this.content = content;
|
||||
this.colors = colors;
|
||||
@@ -41,7 +41,11 @@ public class JavaLexerImpl extends BaseJavaLexer implements Lexer {
|
||||
builtinTypes.add(JavaLexer.LONG);
|
||||
builtinTypes.add(JavaLexer.SHORT);
|
||||
}
|
||||
|
||||
|
||||
public void setJavaColors(JavaColors colors) {
|
||||
this.javaColors = colors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() throws IOException {
|
||||
lexer = new JavaLexer(CharStreams.fromReader(new StringReader(content)));
|
||||
@@ -60,6 +64,7 @@ public class JavaLexerImpl extends BaseJavaLexer implements Lexer {
|
||||
@Override
|
||||
public int line() {
|
||||
// currentToken's line index starts from 1
|
||||
// so we reduce it by 1
|
||||
int line = currentToken.getLine() - 1;
|
||||
this.lastLine = line;
|
||||
return line;
|
||||
@@ -238,6 +243,21 @@ public class JavaLexerImpl extends BaseJavaLexer implements Lexer {
|
||||
wasClassName = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(isClassName(line, column)) {
|
||||
colors.addIfNeeded(line, column, EditorColorScheme.IDENTIFIER_NAME);
|
||||
break;
|
||||
}
|
||||
|
||||
if(isFieldOrStatic(line, column)) {
|
||||
colors.addIfNeeded(line, column, EditorColorScheme.FIELD);
|
||||
break;
|
||||
}
|
||||
|
||||
if(isPackageName(line, column)) {
|
||||
colors.addIfNeeded(line, column, EditorColorScheme.PACKAGE_NAME);
|
||||
break;
|
||||
}
|
||||
|
||||
colors.addIfNeeded(line, column, EditorColorScheme.TEXT_NORMAL);
|
||||
break;
|
||||
@@ -286,4 +306,66 @@ public class JavaLexerImpl extends BaseJavaLexer implements Lexer {
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
private boolean isPackageName(int line, int column) {
|
||||
if(javaColors == null || javaColors.packages == null) return false;
|
||||
final List<Range> packages = javaColors.packages;
|
||||
if(packages != null && packages.size() > 0) {
|
||||
for(int i=0;i<packages.size();i++) {
|
||||
final Range range = packages.get(i);
|
||||
if(range == null) continue;
|
||||
if(range.start.line == line && range.start.character == column)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isClassName(int line, int column) {
|
||||
if(javaColors == null || javaColors.classNames == null) return false;
|
||||
final List<Range> names = javaColors.classNames;
|
||||
if(names != null && names.size() > 0) {
|
||||
for(int i=0;i<names.size();i++) {
|
||||
final Range range = names.get(i);
|
||||
if(range == null) continue;
|
||||
if(range.start.line == line && range.start.character == column)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isFieldOrStatic(int line, int column) {
|
||||
return isField(line, column) || isStatic(line, column);
|
||||
}
|
||||
|
||||
private boolean isField(int line, int column) {
|
||||
if(javaColors == null || javaColors.fields == null) return false;
|
||||
final List<Range> fields = javaColors.fields;
|
||||
if(fields != null && fields.size() > 0) {
|
||||
for(int i=0;i<fields.size();i++) {
|
||||
final Range range = fields.get(i);
|
||||
if(range == null) continue;
|
||||
if(range.start.line == line && range.start.character == column)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isStatic(int line, int column) {
|
||||
if(javaColors == null || javaColors.statics == null) return false;
|
||||
final List<Range> statics = javaColors.statics;
|
||||
if(statics != null && statics.size() > 0) {
|
||||
for(int i=0;i<statics.size();i++) {
|
||||
final Range range = statics.get(i);
|
||||
if(range == null) continue;
|
||||
if(range.start.line == line && range.start.character == column)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,6 @@ import androidx.annotation.Px;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import com.itsaky.androidide.R;
|
||||
import com.itsaky.androidide.app.StudioApp;
|
||||
import com.itsaky.androidide.utils.Logger;
|
||||
import com.itsaky.lsp.Diagnostic;
|
||||
import com.itsaky.lsp.Position;
|
||||
import com.itsaky.lsp.Range;
|
||||
@@ -603,6 +602,12 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public void notifySpansChanged() {
|
||||
if(mSpanner != null) {
|
||||
mSpanner.analyze(getText());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define symbol pairs for any language,
|
||||
|
||||
@@ -59,6 +59,9 @@ public class EditorColorScheme {
|
||||
|
||||
//-----------------Highlight colors-----------
|
||||
|
||||
public static final int FIELD = 35;
|
||||
public static final int STATIC_FIELD = 36;
|
||||
public static final int PACKAGE_NAME = 37;
|
||||
public static final int ANNOTATION = 28;
|
||||
public static final int FUNCTION_NAME = 27;
|
||||
public static final int IDENTIFIER_NAME = 26;
|
||||
@@ -107,7 +110,7 @@ public class EditorColorScheme {
|
||||
/**
|
||||
* Max pre-defined color id
|
||||
*/
|
||||
protected static final int END_COLOR_ID = 34;
|
||||
protected static final int END_COLOR_ID = 37;
|
||||
/**
|
||||
* Real color saver
|
||||
*/
|
||||
@@ -116,7 +119,7 @@ public class EditorColorScheme {
|
||||
* Host editor object
|
||||
*/
|
||||
private CodeEditor mEditor;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new ColorScheme for the given editor
|
||||
*
|
||||
@@ -267,6 +270,13 @@ public class EditorColorScheme {
|
||||
case LOG_INFO :
|
||||
color = 0xff4caf50;
|
||||
break;
|
||||
case FIELD :
|
||||
case STATIC_FIELD :
|
||||
color = 0xFFF0BE4B;
|
||||
break;
|
||||
case PACKAGE_NAME :
|
||||
color = 0xffF0BE4B;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unexpected type:" + type);
|
||||
}
|
||||
|
||||
@@ -3,4 +3,11 @@ package com.itsaky.lsp;
|
||||
public class FormattingOptions {
|
||||
public int tabSize;
|
||||
public boolean insertSpaces;
|
||||
|
||||
public FormattingOptions(){}
|
||||
|
||||
public FormattingOptions(int tabSize, boolean insertSpaces) {
|
||||
this.tabSize = tabSize;
|
||||
this.insertSpaces = insertSpaces;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.itsaky.lsp;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
public class JavaColors {
|
||||
|
||||
@SerializedName("uri")
|
||||
public URI uri;
|
||||
|
||||
@SerializedName("statics")
|
||||
public List<Range> statics;
|
||||
|
||||
@SerializedName("fields")
|
||||
public List<Range> fields;
|
||||
|
||||
@SerializedName("classNames")
|
||||
public List<Range> classNames;
|
||||
|
||||
@SerializedName("packages")
|
||||
public List<Range> packages;
|
||||
}
|
||||
@@ -6,10 +6,14 @@ public interface LanguageClient {
|
||||
void javaProgressStart(JavaStartProgressParams params);
|
||||
void javaProgressReport(JavaReportProgressParams params);
|
||||
void javaProgressEnd();
|
||||
|
||||
void publishDiagnostics(PublishDiagnosticsParams params);
|
||||
void javaColors(JavaColors colors);
|
||||
|
||||
void showMessage(ShowMessageParams params);
|
||||
void registerCapability(String method, JsonElement options);
|
||||
void customNotification(String method, JsonElement params);
|
||||
|
||||
void registerCapability(String method, JsonElement options);
|
||||
|
||||
void onServerStarted(int currentId);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.itsaky.lsp;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
public class Position {
|
||||
public int line, character;
|
||||
|
||||
@@ -12,7 +14,7 @@ public class Position {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return line + "," + character;
|
||||
return new GsonBuilder().setPrettyPrinting().create().toJson(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.itsaky.lsp;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
public class Range {
|
||||
public Position start, end;
|
||||
|
||||
@@ -12,7 +14,7 @@ public class Range {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return start + "-" + end;
|
||||
return new GsonBuilder().setPrettyPrinting().create().toJson(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
package com.itsaky.lsp;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
public class TextEdit {
|
||||
public Range range;
|
||||
@@ -13,7 +14,7 @@ public class TextEdit {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return range + "/" + newText;
|
||||
return new GsonBuilder().setPrettyPrinting().create().toJson(this);
|
||||
}
|
||||
|
||||
public static final TextEdit NONE = new TextEdit(Range.NONE, "");
|
||||
|
||||
Reference in New Issue
Block a user