Do not trigger completion in comments

Added some optimizations
This commit is contained in:
Akash Yadav
2021-10-26 09:21:24 +05:30
parent cb8540950e
commit d914906439
15 changed files with 147 additions and 202 deletions
Binary file not shown.
@@ -91,6 +91,7 @@ import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DidChangeConfigurationParams;
import org.eclipse.lsp4j.InitializeResult;
import org.eclipse.lsp4j.Position;
import java.util.Collections;
public class EditorActivity extends StudioActivity implements FileTreeFragment.FileActionListener,
TabLayout.OnTabSelectedListener,
@@ -926,24 +927,24 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F
new TaskExecutor().executeAsync(() -> {
IDELanguageServer javaServer = LSPProvider.getServerForLanguage(LSPProvider.LANGUAGE_JAVA);
if(javaServer == null) return null;
List<String> cps = mProject.getClassPaths();
JsonObject settings = new JsonObject();
JsonObject java = new JsonObject();
JsonArray classPath = new JsonArray();
for(int i=0;i<cps.size();i++) {
classPath.add(cps.get(i));
}
java.add("classPath", classPath);
settings.add("java", java);
DidChangeConfigurationParams params = new DidChangeConfigurationParams();
params.setSettings(settings);
javaServer.getWorkspaceService().didChangeConfiguration(params);
return null;
}, __ -> {
setStatus(getString(getApp().areCompletorsStarted() ? R.string.msg_service_started : R.string.msg_starting_completion_failed));
@@ -962,8 +963,7 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F
final List<File> files = mPagerAdapter.getOpenedFiles();
final EditorFragment editorFragment = mPagerAdapter.getFrag(index);
final File removed = files.get(index);
frags.remove(index);
files.remove(index);
@@ -19,6 +19,7 @@ public class EditorPreferences extends BasePreferenceFragment implements Prefere
public static final String KEY_EDITOR_PRINTABLE_CHARS = "idepref_editor_nonPrintableFlags";
public static final String KEY_EDITOR_DRAW_HEX = "idepref_editor_drawHexColors";
public static final String KEY_EDITOR_TAB_SIZE = "idepref_editor_tabSize";
public static final String KEY_EDITOR_JAVADOC_ENABLED = "idepref_editor_javadocEnabled";
@Override
public void onCreatePreferences(Bundle p1, String p2) {
@@ -5,8 +5,11 @@ import com.itsaky.androidide.lsp.handlers.JLSHandler;
import com.itsaky.androidide.utils.Logger;
import com.itsaky.lsp.services.IDELanguageServer;
import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.lsp4j.ClientCapabilities;
import org.eclipse.lsp4j.ClientInfo;
import org.eclipse.lsp4j.ColorProviderCapabilities;
@@ -1,11 +1,8 @@
package com.itsaky.androidide.lsp;
import com.itsaky.lsp.SemanticHighlight;
import com.itsaky.lsp.SemanticHighlightsParams;
import com.itsaky.lsp.services.IDELanguageServer;
import com.itsaky.lsp.services.IDETextDocumentService;
import com.itsaky.lsp.services.IDEWorkspaceService;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.eclipse.lsp4j.CallHierarchyIncomingCall;
@@ -153,7 +150,6 @@ public class LanguageServerWrapper implements IDELanguageServer {
@Override
public void setTrace(SetTraceParams params) {
}
class TextDocumentServiceWrapper implements IDETextDocumentService {
@@ -45,9 +45,6 @@ public class JLSHandler implements LSPHandler {
}
try {
// Why not directly use 'java' command?
// I tried doing the same, but it ends up throwing unexpected errors.
// Something related to FileSystem...
mShellBuilder = new ProcessBuilder("/system/bin/sh");
mShellBuilder.directory(Environment.HOME);
mShellBuilder.redirectErrorStream(false);
@@ -22,7 +22,7 @@ public class PreferenceManager {
public static final String KEY_EDITORFLAG_WS_EMPTY_LINE = "idepref_editor_wsEmptyLine";
public static final String KEY_EDITORFLAG_LINE_BREAK = "idepref_editor_lineBreak";
public static final String KEY_EDITOR_DRAW_HEX = "idepref_editor_drawHexColors";
public static final String KEY_GRADLE_CURRENT_DIR = "idepref_customGradle_currentFolder";
public static final String KEY_GRADLE_FILENAMES = "idepref_customGradle_folderNames";
public static final String KEY_GRADLECMD_STACKTRACRE = "idepref_gradleCmd_stacktrace";
@@ -40,7 +40,7 @@ public class PreferenceManager {
public PreferenceManager(Context ctx) {
this.prefs = androidx.preference.PreferenceManager.getDefaultSharedPreferences(ctx);
}
public PreferenceManager putInt(String key, int val) {
prefs.edit().putInt(key, val).apply();
return this;
@@ -164,4 +164,13 @@ public class PreferenceManager {
public boolean confirmProjectOpen() {
return getBoolean(GeneralPreferences.KEY_CONFIRM_PROJECT_OPEN, false);
}
public void setJavadocHighlightEnabled (boolean enabled) {
putBoolean(EditorPreferences.KEY_EDITOR_JAVADOC_ENABLED, enabled);
}
public boolean isJavadocHighlightEnabled() {
return getBoolean(EditorPreferences.KEY_EDITOR_JAVADOC_ENABLED, true);
}
}
@@ -17,7 +17,7 @@ public class ToolsManager {
private static PreferenceManager prefs;
public static final int JLS_VERSION = 21;
public static final int JLS_VERSION = 22;
public static final int LOGSENDER_VERSION = 1;
public static final int CLEANER_VERSION = 1;
public static final int GRADLE_API_VERSION = 2;
@@ -228,43 +228,13 @@ public class HighlightRangeHelper {
}
private int containsStartPosition (List<Range> ranges, int line, int column) {
int index = binarySearchStartPosition(ranges, line, column);
int index = LSPUtils.binarySearchStartPosition(ranges, line, column);
if(index >= 0 && index < ranges.size()) {
return index;
}
return -1;
}
private int binarySearchStartPosition(List<Range> ranges, int line, int column) {
int left = 0, right = ranges.size() - 1;
while (left <= right) {
int mid = (left + right) / 2;
final Range range = ranges.get(mid);
final int l = range.getStart().getLine();
final int c = range.getStart().getCharacter();
// Compare lines
if(l < line) {
left = mid + 1;
} else if(l > line) {
right = mid - 1;
} else {
// Lines are same. Compare by columns
if(c < column) {
left = mid + 1;
} else if (c > column) {
right = mid - 1;
} else {
// Found!
return mid;
}
}
}
return -1;
}
public boolean isEnumType(int line, int column) {
if(highlights == null || highlights.enumTypes == null) return false;
@@ -42,7 +42,6 @@ public class JavaLexerImpl extends io.github.rosemoe.editor.langs.AbstractCodeAn
private HighlightRangeHelper helper;
private Map<Integer, Map<Integer, Diagnostic>> diagnostics = new HashMap<>();
private final Map<Integer, Map<Integer, Diagnostic>> customDiagnostics = new HashMap<>();
@Override
public void setSemanticHighlights(SemanticHighlight highlights) {
@@ -324,6 +323,10 @@ public class JavaLexerImpl extends io.github.rosemoe.editor.langs.AbstractCodeAn
final Indexer indexer = content.getIndexer();
final CharPosition endPos = indexer.getCharPosition(currentToken.getStopIndex());
final Position startPosition = new Position(line, column);
final Position endPosition = new Position(endPos.line, endPos.column);
colors.addCommentRange(line, new Range(startPosition, endPosition));
int l = line;
int c = column;
@@ -385,6 +388,11 @@ public class JavaLexerImpl extends io.github.rosemoe.editor.langs.AbstractCodeAn
span = colors.addIfNeeded(line, column, EditorColorScheme.COMMENT);
wasClassName = false;
final CharPosition a = content.getIndexer().getCharPosition(currentToken.getStopIndex());
final Position s = new Position(line, column);
final Position e = new Position(a.line, a.column);
colors.addCommentRange(line, new Range(s, e));
String lineComment = currentToken.getText();
if(lineComment != null) {
lineComment = lineComment.trim();
@@ -1,10 +1,12 @@
package com.itsaky.androidide.utils;
import java.util.Comparator;
import java.util.List;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DiagnosticSeverity;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import java.util.Comparator;
import java.util.ArrayList;
public class LSPUtils {
@@ -24,6 +26,25 @@ public class LSPUtils {
&& p1.getCharacter() == p2.getCharacter();
}
public static boolean isInRange (Range range, Position position) {
final int line = position.getLine();
final int column = position.getCharacter();
return isInRange(range, line, column);
}
public static boolean isInRange (Range range, int line, int column) {
final int startLine = range.getStart().getLine();
final int startCol = range.getStart().getCharacter();
final int endLine = range.getEnd().getLine();
final int endCol = range.getEnd().getCharacter();
if(startLine == endLine) {
return startCol <= column && column <= endCol;
} else {
return startLine <= line && line <= endLine;
}
}
public static boolean isEqual(Range r1, Range r2) {
if(r1 == null) return false;
if(r2 == null) return false;
@@ -59,6 +80,35 @@ public class LSPUtils {
return range;
}
public static int binarySearchStartPosition(List<Range> ranges, int line, int column) {
int left = 0, right = ranges.size() - 1;
while (left <= right) {
int mid = (left + right) / 2;
final Range range = ranges.get(mid);
final int l = range.getStart().getLine();
final int c = range.getStart().getCharacter();
// Compare lines
if(l < line) {
left = mid + 1;
} else if(l > line) {
right = mid - 1;
} else {
// Lines are same. Compare by columns
if(c < column) {
left = mid + 1;
} else if (c > column) {
right = mid - 1;
} else {
// Found!
return mid;
}
}
}
return -1;
}
public static final Comparator<Range> RANGE_START_COMPARATOR = new Comparator<Range>() {
@Override
@@ -15,13 +15,11 @@
*/
package io.github.rosemoe.editor.struct;
import android.graphics.Typeface;
import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import io.github.rosemoe.editor.widget.EditorColorScheme;
import org.eclipse.lsp4j.Range;
/**
* The span model
*
@@ -29,45 +27,12 @@ import org.eclipse.lsp4j.Range;
*/
public class Span {
/**
* Flag for {@link Span#problemFlags}.
*
* Indicates this span is in ERROR region
*/
public static final int FLAG_ERROR = 1 << 4;
/**
* Flag for {@link Span#problemFlags}.
*
* Indicates this span is in WARNING region
*/
public static final int FLAG_WARNING = 1 << 3;
/**
* Flag for {@link Span#problemFlags}.
*
* Indicates this span is in INFO region
*/
public static final int FLAG_INFO = 1 << 2;
/**
* Flag for {@link Span#problemFlags}.
*
* Indicates this span is in INFO region
*/
public static final int FLAG_HINT = 1 << 1;
/**
* Flag for {@link Span#problemFlags}.
*
* Indicates this span is in DEPRECATED region
*/
public static final int FLAG_DEPRECATED = 1;
private static final BlockingQueue<Span> cacheQueue = new ArrayBlockingQueue<>(8192 * 2);
public int line;
public int column;
public int colorId;
public int underlineColor = 0;
public int problemFlags;
public Range problemRange;
/**
* Create a new span
*
@@ -113,7 +78,7 @@ public class Span {
underlineColor = color;
return this;
}
/**
* Get span start column
*
@@ -144,5 +109,4 @@ public class Span {
colorId = column = underlineColor = 0;
return cacheQueue.offer(this);
}
}
@@ -42,7 +42,8 @@ public class TextAnalyzeResult {
private boolean determined = false;
private final Map<Integer, List<Range>> stringMap = new HashMap<>();
private final Map<Integer, List<Range>> commentMap = new HashMap<>();
/**
* Create a new result
*/
@@ -57,16 +58,26 @@ public class TextAnalyzeResult {
return stringMap;
}
public Map<Integer, List<Range>> getCommentMap() {
return commentMap;
}
public void addStringRange(int line, Range range) {
if(stringMap.containsKey(line)) {
List<Range> ranges = stringMap.get(line);
ranges.add(range);
stringMap.put(line, ranges);
} else {
List<Range> ranges = new ArrayList<>();
ranges.add(range);
stringMap.put(line, ranges);
List<Range> ranges = stringMap.get(line);
if(ranges == null) {
ranges = new ArrayList<>();
}
ranges.add(range);
stringMap.put(line, ranges);
}
public void addCommentRange (int line, Range range) {
List<Range> ranges = commentMap.get(line);
if(ranges == null) {
ranges = new ArrayList<>();
}
ranges.add(range);
commentMap.put(line, ranges);
}
public void addHexColor(HexColor index, int color) {
@@ -247,61 +258,4 @@ public class TextAnalyzeResult {
public List<List<Span>> getSpanMap() {
return mSpanMap;
}
/**
* Marks a region with the given flag.
* This can only be called after {@link TextAnalyzeResult#determine(int)} is called.
*/
public void markProblemRegion(int newFlag, int startLine, int startColumn, int endLine, int endColumn) {
if (!determined) {
return;
}
for (int line = startLine; line <= endLine; line++) {
int start = (line == startLine ? startColumn : 0);
int end = (line == endLine ? endColumn : Integer.MAX_VALUE);
List<Span> spans = mSpanMap.get(line);
int increment;
for (int i = 0; i < spans.size(); i += increment) {
Span span = spans.get(i);
increment = 1;
if (span.column >= end) {
break;
}
int spanEnd = (i + 1 >= spans.size() ? Integer.MAX_VALUE : spans.get(i + 1).column);
if (spanEnd >= start) {
int regionStartInSpan = Math.max(span.column, start);
int regionEndInSpan = Math.min(end, spanEnd);
if (regionStartInSpan == span.column) {
if (regionEndInSpan == spanEnd) {
span.problemFlags |= newFlag;
} else {
increment = 2;
Span nSpan = span.copy();
nSpan.column = regionEndInSpan;
spans.add(i + 1, nSpan);
span.problemFlags |= newFlag;
}
} else {
//regionStartInSpan > span.column
if (regionEndInSpan == spanEnd) {
increment = 2;
Span nSpan = span.copy();
nSpan.column = regionStartInSpan;
spans.add(i + 1, nSpan);
nSpan.problemFlags |= newFlag;
} else {
increment = 3;
Span span1 = span.copy();
span1.column = regionStartInSpan;
span1.problemFlags |= newFlag;
Span span2 = span.copy();
span2.column = regionEndInSpan;
spans.add(i + 1, span1);
spans.add(i + 2, span2);
}
}
}
}
}
}
}
@@ -136,6 +136,7 @@ import org.eclipse.lsp4j.TextDocumentItem;
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import android.os.Handler;
import com.itsaky.androidide.utils.LSPUtils;
/**
* CodeEditor is a editor that can highlight text regions by doing basic syntax analyzing
@@ -314,9 +315,6 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
private List<String> mSignatureHelpTriggerChars = new ArrayList<>();
private Map<HexColor, Integer> mLineColors;
private Map<Integer, List<Range>> stringMap;
private File currentFile;
public CodeEditor(Context context) {
@@ -604,7 +602,6 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
setDefaultFocusHighlightEnabled(false);
}
mLineColors = new HashMap<HexColor, Integer>();
mErrorColor = Color.parseColor("#FF5252");
mWarningColor = Color.parseColor("#FFD740");
mRect2.set(-1, -1, -1, -1);
@@ -643,21 +640,6 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
}
}
public void setStringMap(Map<Integer, List<Range>> map) {
this.stringMap = map;
}
public CodeEditor setLineColors(HashMap<HexColor, Integer> map) {
this.mLineColors = map;
return this;
}
public CodeEditor putLineColor(HexColor index, int color) {
createMapIfNull();
mLineColors.put(index, color);
return this;
}
public void notifySpansChanged() {
if(mSpanner != null) {
mSpanner.analyze(getText());
@@ -1128,12 +1110,6 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
if (time > 3.0) {
}
}
private void createMapIfNull() {
if(this.mLineColors == null) {
this.mLineColors = new HashMap<HexColor, Integer>();
}
}
/**
* Paint the view on given Canvas
@@ -1471,7 +1447,8 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
}
// Draw hex colors
if(isLineColorsEnabled() && mLineColors != null && mLineColors.size() > 0) {
final Map<HexColor, Integer> mLineColors = isLineColorsEnabled() && mSpanner != null ? mSpanner.getResult().getHexColors() : null;
if(mLineColors != null && mLineColors.size() > 0) {
for(HexColor c : mLineColors.keySet()) {
if(c != null && c.isSameLine(line) && mLineColors.get(c) != null) {
final int paintStart = Math.max(firstVisibleChar, c.start.column);
@@ -1496,7 +1473,7 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
mPaint.setStrokeWidth(getDpUnit() * 1.4f);
final List<Diagnostic> diags = getEditorLanguage().getAnalyzer().findDiagnosticsContainingLine(line);
final int size = diags == null ? 0 : diags.size();
LOG.info("Diagnostics for line " + line, JSONUtility.prettyPrinter.toJson(diags), "size=" + size);
for(int i=0;i<size;i++) {
Diagnostic d = diags.get(i);
if(d == null) continue;
@@ -1510,7 +1487,7 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
final RectF r = new RectF();
r.bottom = getRowBottom(line) - getOffsetY() - mDpUnit * 1;
r.top = r.bottom - getRowHeight() * 0.2f;
r.left = paintingOffset + measureText(mBuffer, firstVisibleChar, paintStart - firstVisibleChar);
r.left = measureText(mBuffer, 0, startCol) - getOffsetX();
r.right = r.left + width;
mPaint.setColor(diagnosticColor(d.getSeverity()));
drawDiagnostics(r, canvas, mPaint);
@@ -4832,17 +4809,42 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
return new TextDocumentIdentifier(getFile().toURI().toString());
}
private boolean isInString() {
private boolean isCursorInString() {
final int line = getCursor().getLeftLine();
final int column = getCursor().getLeftColumn();
if(stringMap == null || stringMap.isEmpty() || !stringMap.containsKey(line)) return false;
List<Range> strings = stringMap.get(line);
if(strings == null || strings.isEmpty()) return false;
for(int i=0;i<strings.size();i++) {
Range r = strings.get(i);
if(r.getStart().getCharacter() <= column && column <= r.getEnd().getCharacter())
return true;
final Map<Integer, List<Range>> stringMap = mSpanner == null ? null : mSpanner.getResult().getStringMap();
if(stringMap == null || stringMap.isEmpty()) {
return false;
}
return isInRanges(stringMap.get(line), line, column);
}
private boolean isCursorInComment () {
final int line = getCursor().getLeftLine();
final int column = getCursor().getLeftColumn();
final Map<Integer, List<Range>> commentMap = mSpanner == null ? null : mSpanner.getResult().getCommentMap();
if(commentMap == null || commentMap.isEmpty()) {
return false;
}
return isInRanges(commentMap.get(line), line, column);
}
private boolean isInRanges (List<Range> ranges, int line, int column) {
if(ranges == null || ranges.isEmpty()) {
return false;
}
for (Range range : ranges) {
if (LSPUtils.isInRange(range, line, column)) {
return true;
}
}
return false;
}
@@ -4881,7 +4883,7 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
// Auto completion
// Trigger only when autocompletion is enabled and cursor is not in a string token
if (isAutoCompletionEnabled() && !isInString()) {
if (isAutoCompletionEnabled() && !isCursorInString() && !isCursorInComment()) {
if ((mConnection.mComposingLine == -1 || mCompletionOnComposing) && endColumn != 0 && startLine == endLine) {
int end = endColumn;
while (endColumn > 0) {
@@ -5009,12 +5011,6 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
@Override
public void onAnalyzeDone(TextAnalyzer provider) {
if (provider == mSpanner) {
if(mSpanner.getResult().getHexColors().size() > 0) {
setLineColors(mSpanner.getResult().getHexColors());
}
if(mSpanner.getResult().getStringMap().size() > 0) {
setStringMap(mSpanner.getResult().getStringMap());
}
if (mHighlightCurrentBlock) {
mCursorPosition = findCursorBlock();
}
@@ -1,7 +1,6 @@
package com.itsaky.lsp.services;
import java.util.concurrent.CompletableFuture;
import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.InitializeResult;
import org.eclipse.lsp4j.InitializedParams;
@@ -10,8 +9,6 @@ import org.eclipse.lsp4j.WorkDoneProgressCancelParams;
import org.eclipse.lsp4j.jsonrpc.services.JsonDelegate;
import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
import org.eclipse.lsp4j.services.TextDocumentService;
import org.eclipse.lsp4j.services.WorkspaceService;
/**
* Custom implementation of {@link org.eclipse.lsp4j.services.LanguageServer}.