mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
Append newline in String literals in Java and Groovy
This commit is contained in:
@@ -193,8 +193,6 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F
|
||||
mBinding.tabs.setupWithViewPager(mBinding.editorViewPager);
|
||||
mBinding.tabs.setOnTabSelectedListener(this);
|
||||
mBinding.fabView.setOnClickListener(v -> showViewOptions());
|
||||
// mBinding.diagnosticTextContainer.setVisibility(View.GONE);
|
||||
// mBinding.diagnosticText.setClickable(false);
|
||||
|
||||
createQuickActions();
|
||||
|
||||
@@ -705,6 +703,8 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F
|
||||
startActivity(IntentUtils.getShareTextIntent(getString(R.string.msg_share_app)));
|
||||
} else if(id == R.id.editornav_close_project) {
|
||||
confirmProjectClose();
|
||||
} else if (id == R.id.editornav_terminal) {
|
||||
openTerminal();
|
||||
}
|
||||
mBinding.getRoot().closeDrawer(GravityCompat.START);
|
||||
return false;
|
||||
@@ -1004,6 +1004,12 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F
|
||||
////////////// PRIVATE APIS /////////////////////
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
private void openTerminal () {
|
||||
final Intent intent = new Intent(this, TerminalActivity.class);
|
||||
intent.putExtra(TerminalActivity.KEY_WORKING_DIRECTORY, mProject.getProjectPath());
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
private void startLanguageServers() {
|
||||
LSP.setActivityProvider(this);
|
||||
LSP.Java.start(() -> {
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.itsaky.terminal.view.TerminalView;
|
||||
import com.itsaky.terminal.view.TerminalViewClient;
|
||||
import java.util.Map;
|
||||
import org.json.JSONException;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class TerminalActivity extends StudioActivity {
|
||||
|
||||
@@ -42,12 +43,14 @@ public class TerminalActivity extends StudioActivity {
|
||||
private final Client client = new Client();
|
||||
private static final Logger LOG = Logger.instance("TerminalActivity");
|
||||
|
||||
public static final String KEY_WORKING_DIRECTORY = "terminal_workingDirectory";
|
||||
|
||||
@Override
|
||||
protected View bindLayout() {
|
||||
binding = ActivityTerminalBinding.inflate(getLayoutInflater());
|
||||
terminal = new TerminalView(this, null);
|
||||
terminal.setTerminalViewClient(client);
|
||||
terminal.attachSession(createSession());
|
||||
terminal.attachSession(createSession(getWorkingDirectory()));
|
||||
terminal.setKeepScreenOn(true);
|
||||
terminal.setTextSize(currentTextSize = SizeUtils.dp2px(10));
|
||||
terminal.setTypeface(TypefaceUtils.jetbrainsMono());
|
||||
@@ -65,6 +68,18 @@ public class TerminalActivity extends StudioActivity {
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
private String getWorkingDirectory() {
|
||||
final Bundle extras = getIntent().getExtras();
|
||||
if(extras != null && extras.containsKey(KEY_WORKING_DIRECTORY)) {
|
||||
String directory = extras.getString(KEY_WORKING_DIRECTORY, null);
|
||||
if(directory == null || directory.trim().length() <= 0) {
|
||||
directory = Environment.HOME.getAbsolutePath();
|
||||
}
|
||||
return directory;
|
||||
}
|
||||
return Environment.HOME.getAbsolutePath();
|
||||
}
|
||||
|
||||
private KeyListener getKeyListener() {
|
||||
return listener == null ? listener = new KeyListener(terminal) : listener;
|
||||
@@ -99,7 +114,7 @@ public class TerminalActivity extends StudioActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private TerminalSession createSession() {
|
||||
private TerminalSession createSession(final String workingDirectory) {
|
||||
final Map<String, String> envs = Environment.getEnvironment(true);
|
||||
final String[] env = new String[envs.size()];
|
||||
int i=0;
|
||||
@@ -110,7 +125,7 @@ public class TerminalActivity extends StudioActivity {
|
||||
|
||||
session = new TerminalSession(
|
||||
Environment.SHELL.getAbsolutePath(), // Shell command
|
||||
Environment.HOME.getAbsolutePath(), // Working directory
|
||||
workingDirectory, // Working directory
|
||||
new String[]{}, // Arguments
|
||||
env, // Environment variables
|
||||
TerminalEmulator.DEFAULT_TERMINAL_TRANSCRIPT_ROWS, // Transcript rows
|
||||
|
||||
@@ -62,17 +62,11 @@ public class CompletionListAdapter extends EditorCompletionAdapter {
|
||||
|
||||
showApiInfoIfNeeded(item, binding.completionApiInfo);
|
||||
|
||||
final ViewTreeObserver.OnGlobalLayoutListener listener = new ViewTreeObserver.OnGlobalLayoutListener(){
|
||||
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
binding.getRoot().getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
ViewGroup.LayoutParams p = binding.completionIconText.getLayoutParams();
|
||||
p.height = binding.getRoot().getHeight();
|
||||
binding.completionIconText.setLayoutParams(p);
|
||||
}
|
||||
};
|
||||
binding.getRoot().getViewTreeObserver().addOnGlobalLayoutListener(listener);
|
||||
binding.getRoot().getViewTreeObserver().addOnGlobalLayoutListener(() -> {
|
||||
ViewGroup.LayoutParams p = binding.completionIconText.getLayoutParams();
|
||||
p.height = binding.getRoot().getHeight();
|
||||
binding.completionIconText.setLayoutParams(p);
|
||||
});
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.itsaky.androidide.handlers;
|
||||
|
||||
import com.itsaky.androidide.EditorActivity;
|
||||
import android.view.View;
|
||||
import com.itsaky.androidide.R;
|
||||
import com.itsaky.androidide.managers.PreferenceManager;
|
||||
import com.itsaky.androidide.models.AndroidProject;
|
||||
@@ -106,6 +106,7 @@ public class BuildServiceHandler extends IDEHandler implements IDEService.BuildL
|
||||
|
||||
activity().getApp().getPrefManager().putBoolean(PreferenceManager.KEY_IS_FIRST_PROJECT_BUILD, false);
|
||||
activity().invalidateOptionsMenu();
|
||||
activity().getBinding().buildProgressIndicator.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,6 +118,7 @@ public class BuildServiceHandler extends IDEHandler implements IDEService.BuildL
|
||||
|
||||
activity().getApp().getPrefManager().putBoolean(PreferenceManager.KEY_IS_FIRST_PROJECT_BUILD, false);
|
||||
activity().invalidateOptionsMenu();
|
||||
activity().getBinding().buildProgressIndicator.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -136,12 +138,13 @@ public class BuildServiceHandler extends IDEHandler implements IDEService.BuildL
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare() {
|
||||
public void prepareBuild() {
|
||||
boolean isFirstBuild = activity().getApp().getPrefManager().getBoolean(PreferenceManager.KEY_IS_FIRST_PROJECT_BUILD, true);
|
||||
activity().setStatus(activity().getString(isFirstBuild ? R.string.preparing_first : R.string.preparing));
|
||||
if(isFirstBuild) {
|
||||
activity().showFirstBuildNotice();
|
||||
}
|
||||
activity().getBinding().buildProgressIndicator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private boolean isClasspathValid(String path) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.itsaky.androidide.language.groovy;
|
||||
import com.itsaky.androidide.syntax.lexer.impls.groovy.GroovyLexerImpl;
|
||||
import com.itsaky.lsp.SemanticHighlight;
|
||||
import com.itsaky.lsp.services.IDELanguageServer;
|
||||
import io.github.rosemoe.editor.interfaces.EditorLanguage;
|
||||
import io.github.rosemoe.editor.text.Content;
|
||||
import io.github.rosemoe.editor.text.TextAnalyzeResult;
|
||||
import io.github.rosemoe.editor.text.TextAnalyzer;
|
||||
@@ -11,11 +12,17 @@ import java.util.Map;
|
||||
import org.eclipse.lsp4j.Diagnostic;
|
||||
|
||||
public class GroovyAnalyzer extends io.github.rosemoe.editor.langs.AbstractCodeAnalyzer {
|
||||
|
||||
|
||||
private final EditorLanguage language;
|
||||
public GroovyAnalyzer (EditorLanguage language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void analyze(IDELanguageServer server, File file, CharSequence content, TextAnalyzeResult colors, TextAnalyzer.AnalyzeThread.Delegate delegate) {
|
||||
try {
|
||||
GroovyLexerImpl lexer = new GroovyLexerImpl((Content) content, colors);
|
||||
GroovyLexerImpl lexer = new GroovyLexerImpl(this.language, (Content) content, colors);
|
||||
lexer.init();
|
||||
|
||||
// Adding spans, hex colors, block lines and all is handled by JavaLexerImpl
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.itsaky.lsp.services.IDELanguageServer;
|
||||
import io.github.rosemoe.editor.interfaces.AutoCompleteProvider;
|
||||
import io.github.rosemoe.editor.interfaces.CodeAnalyzer;
|
||||
import io.github.rosemoe.editor.interfaces.NewlineHandler;
|
||||
import io.github.rosemoe.editor.text.CharPosition;
|
||||
import io.github.rosemoe.editor.text.TextUtils;
|
||||
import io.github.rosemoe.editor.widget.SymbolPairMatch;
|
||||
import java.io.File;
|
||||
@@ -26,7 +27,7 @@ public class GroovyLanguage extends BaseLanguage {
|
||||
|
||||
public GroovyLanguage(File file) {
|
||||
super(file);
|
||||
analyzer = new GroovyAnalyzer();
|
||||
analyzer = new GroovyAnalyzer(this);
|
||||
completor = new GroovyAutoComplete();
|
||||
}
|
||||
|
||||
@@ -107,7 +108,7 @@ public class GroovyLanguage extends BaseLanguage {
|
||||
class BraceHandler implements NewlineHandler {
|
||||
|
||||
@Override
|
||||
public boolean matchesRequirement(String beforeText, String afterText) {
|
||||
public boolean matchesRequirement(String beforeText, String afterText, CharPosition cursor) {
|
||||
beforeText = beforeText.trim();
|
||||
afterText = afterText.trim();
|
||||
return beforeText.endsWith("{") && afterText.startsWith("}");
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.itsaky.lsp.services.IDELanguageServer;
|
||||
import io.github.rosemoe.editor.interfaces.AutoCompleteProvider;
|
||||
import io.github.rosemoe.editor.interfaces.CodeAnalyzer;
|
||||
import io.github.rosemoe.editor.interfaces.NewlineHandler;
|
||||
import io.github.rosemoe.editor.text.CharPosition;
|
||||
import io.github.rosemoe.editor.text.TextUtils;
|
||||
import io.github.rosemoe.editor.widget.SymbolPairMatch;
|
||||
import java.io.File;
|
||||
@@ -22,14 +23,20 @@ public class JavaLanguage extends BaseLanguage {
|
||||
private final JavaLexerImpl lexer;
|
||||
private final JavaAutoComplete complete;
|
||||
|
||||
private final NewlineHandler[] newlineHandlers;
|
||||
|
||||
public JavaLanguage() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public JavaLanguage(File file) {
|
||||
super(file);
|
||||
this.lexer = new JavaLexerImpl();
|
||||
this.lexer = new JavaLexerImpl(this);
|
||||
this.complete = new JavaAutoComplete();
|
||||
|
||||
this.newlineHandlers = new NewlineHandler[2];
|
||||
this.newlineHandlers[0] = new BraceHandler();
|
||||
this.newlineHandlers[1] = this.lexer.stringHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,10 +99,8 @@ public class JavaLanguage extends BaseLanguage {
|
||||
@Override
|
||||
public CharSequence format(CharSequence content) {
|
||||
return content;
|
||||
}
|
||||
|
||||
private NewlineHandler[] newlineHandlers = new NewlineHandler[] { new BraceHandler() };
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public NewlineHandler[] getNewlineHandlers() {
|
||||
return newlineHandlers;
|
||||
@@ -104,7 +109,7 @@ public class JavaLanguage extends BaseLanguage {
|
||||
class BraceHandler implements NewlineHandler {
|
||||
|
||||
@Override
|
||||
public boolean matchesRequirement(String beforeText, String afterText) {
|
||||
public boolean matchesRequirement(String beforeText, String afterText, CharPosition cursor) {
|
||||
return beforeText.endsWith("{") && afterText.startsWith("}");
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import java.util.Optional;
|
||||
import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
|
||||
import org.eclipse.lsp4j.FileChangeType;
|
||||
import org.eclipse.lsp4j.FileEvent;
|
||||
import com.blankj.utilcode.util.ThreadUtils;
|
||||
|
||||
public class IDEService implements ShellServer.Callback {
|
||||
|
||||
@@ -77,8 +78,8 @@ public class IDEService implements ShellServer.Callback {
|
||||
this.isRunning = true;
|
||||
}
|
||||
|
||||
public IDEService setListener(BuildListener listener) {
|
||||
this.listener = listener;
|
||||
public IDEService setListener(final BuildListener listener) {
|
||||
this.listener = listener == null ? null : new MainThreadBuildListener(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -285,7 +286,7 @@ public class IDEService implements ShellServer.Callback {
|
||||
shell.bgAppend(String.format("cd \"%s\"", new File(projectRoot, "app").getAbsolutePath()));
|
||||
shell.bgAppend(getArguments(task.getTasks()));
|
||||
isBuilding = true;
|
||||
listener.prepare();
|
||||
listener.prepareBuild();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,6 +386,78 @@ public class IDEService implements ShellServer.Callback {
|
||||
return isBuilding;
|
||||
}
|
||||
|
||||
private class MainThreadBuildListener implements BuildListener {
|
||||
|
||||
private final BuildListener listener;
|
||||
|
||||
public MainThreadBuildListener(BuildListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBuildModified() {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
listener.onBuildModified();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProjectLoaded(IDEProject project, Optional<IDEModule> appModule) {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
listener.onProjectLoaded(project, appModule);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartingGradleDaemon(GradleTask task) {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
listener.onStartingGradleDaemon(task);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRunTask(GradleTask task, String name) {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
listener.onRunTask(task, name);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBuildSuccessful(GradleTask task, String msg) {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
listener.onBuildSuccessful(task, msg);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBuildFailed(GradleTask task, String msg) {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
listener.onBuildFailed(task, msg);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveFiles() {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
listener.saveFiles();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendOutput(GradleTask task, CharSequence text) {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
listener.appendOutput(task, text);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareBuild() {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
listener.prepareBuild();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A client should implement this interface to get callbacks about a build
|
||||
*/
|
||||
@@ -449,7 +522,7 @@ public class IDEService implements ShellServer.Callback {
|
||||
/**
|
||||
* Called to notify the client to prepare for a build
|
||||
*/
|
||||
void prepare();
|
||||
void prepareBuild();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import com.blankj.utilcode.util.ThreadUtils;
|
||||
|
||||
public class ShellServer extends Thread {
|
||||
|
||||
|
||||
+58
-2
@@ -5,18 +5,32 @@ 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.androidide.utils.LSPUtils;
|
||||
import io.github.rosemoe.editor.interfaces.NewlineHandler;
|
||||
import io.github.rosemoe.editor.struct.BlockLine;
|
||||
import io.github.rosemoe.editor.text.CharPosition;
|
||||
import io.github.rosemoe.editor.text.Content;
|
||||
import io.github.rosemoe.editor.text.TextAnalyzeResult;
|
||||
import io.github.rosemoe.editor.text.TextUtils;
|
||||
import io.github.rosemoe.editor.widget.EditorColorScheme;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import io.github.rosemoe.editor.interfaces.EditorLanguage;
|
||||
|
||||
public class GroovyLexerImpl extends BaseJavaLexer implements Lexer {
|
||||
|
||||
public GroovyLexerImpl(Content content, TextAnalyzeResult colors) {
|
||||
|
||||
private final EditorLanguage language;
|
||||
private final Map<Integer, List<Range>> stringMap = new HashMap<>();
|
||||
public final MultilineStringHandler stringHandler = new MultilineStringHandler();
|
||||
|
||||
public GroovyLexerImpl(EditorLanguage language, Content content, TextAnalyzeResult colors) {
|
||||
this.language = language;
|
||||
this.content = content;
|
||||
this.colors = colors;
|
||||
this.maxSwitch = 0;
|
||||
@@ -283,4 +297,46 @@ public class GroovyLexerImpl extends BaseJavaLexer implements Lexer {
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
private class MultilineStringHandler implements NewlineHandler {
|
||||
|
||||
@Override
|
||||
public boolean matchesRequirement(String beforeText, String afterText, CharPosition cursor) {
|
||||
if(language == null || stringMap == null || stringMap.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final List<Range> ranges = stringMap.get(cursor.line);
|
||||
if(ranges == null || ranges.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isInRanges(ranges, cursor.line, cursor.column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NewlineHandler.HandleResult handleNewline(String beforeText, String afterText, int tabSize) {
|
||||
int count = TextUtils.countLeadingSpaceCount(beforeText, tabSize);
|
||||
int advance = language.getIndentAdvance(beforeText) + 1;
|
||||
final StringBuilder sb = new StringBuilder("\\n\" + \n") // Appends: \n" + <new-line>
|
||||
.append(TextUtils.createIndent(count + advance, tabSize, language.useTab()))
|
||||
.append("\"");
|
||||
return new HandleResult(sb, 0);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,8 @@ import com.itsaky.androidide.syntax.lexer.tokens.TokenType;
|
||||
import com.itsaky.androidide.utils.LSPUtils;
|
||||
import com.itsaky.androidide.utils.Logger;
|
||||
import com.itsaky.lsp.SemanticHighlight;
|
||||
import com.itsaky.lsp.SemanticHighlightsParams;
|
||||
import com.itsaky.lsp.services.IDELanguageServer;
|
||||
import com.itsaky.lsp.services.IDETextDocumentService;
|
||||
import io.github.rosemoe.editor.interfaces.NewlineHandler;
|
||||
import io.github.rosemoe.editor.struct.BlockLine;
|
||||
import io.github.rosemoe.editor.struct.Span;
|
||||
import io.github.rosemoe.editor.text.CharPosition;
|
||||
@@ -20,28 +19,34 @@ import io.github.rosemoe.editor.text.Content;
|
||||
import io.github.rosemoe.editor.text.Indexer;
|
||||
import io.github.rosemoe.editor.text.TextAnalyzeResult;
|
||||
import io.github.rosemoe.editor.text.TextAnalyzer;
|
||||
import io.github.rosemoe.editor.text.TextUtils;
|
||||
import io.github.rosemoe.editor.widget.EditorColorScheme;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.eclipse.lsp4j.Diagnostic;
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import io.github.rosemoe.editor.interfaces.EditorLanguage;
|
||||
|
||||
public class JavaLexerImpl extends io.github.rosemoe.editor.langs.AbstractCodeAnalyzer {
|
||||
|
||||
private final EditorLanguage language;
|
||||
private HighlightRangeHelper helper;
|
||||
private Map<Integer, Map<Integer, Diagnostic>> diagnostics = new HashMap<>();
|
||||
private final Map<Integer, List<Range>> stringMap = new HashMap<>();
|
||||
|
||||
public final MultilineStringHandler stringHandler = new MultilineStringHandler();
|
||||
|
||||
public JavaLexerImpl(EditorLanguage language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSemanticHighlights(SemanticHighlight highlights) {
|
||||
@@ -59,6 +64,9 @@ public class JavaLexerImpl extends io.github.rosemoe.editor.langs.AbstractCodeAn
|
||||
} catch (Throwable th) {
|
||||
return;
|
||||
}
|
||||
|
||||
stringMap.clear();
|
||||
|
||||
while (delegate.shouldAnalyze()) {
|
||||
// null = EOF
|
||||
if(lexer.nextToken() == null)
|
||||
@@ -120,6 +128,48 @@ public class JavaLexerImpl extends io.github.rosemoe.editor.langs.AbstractCodeAn
|
||||
return diagnostics.get(line);
|
||||
}
|
||||
|
||||
private class MultilineStringHandler implements NewlineHandler {
|
||||
|
||||
@Override
|
||||
public boolean matchesRequirement(String beforeText, String afterText, CharPosition cursor) {
|
||||
if(language == null || stringMap == null || stringMap.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final List<Range> ranges = stringMap.get(cursor.line);
|
||||
if(ranges == null || ranges.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isInRanges(ranges, cursor.line, cursor.column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NewlineHandler.HandleResult handleNewline(String beforeText, String afterText, int tabSize) {
|
||||
int count = TextUtils.countLeadingSpaceCount(beforeText, tabSize);
|
||||
int advance = language.getIndentAdvance(beforeText) + 1;
|
||||
final StringBuilder sb = new StringBuilder("\\n\" + \n") // Appends: \n" + <new-line>
|
||||
.append(TextUtils.createIndent(count + advance, tabSize, language.useTab()))
|
||||
.append("\"");
|
||||
return new HandleResult(sb, 0);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
public class JavaLexerAnalyzer extends BaseJavaLexer implements Lexer {
|
||||
|
||||
private final HighlightRangeHelper helper;
|
||||
@@ -250,7 +300,16 @@ public class JavaLexerImpl extends io.github.rosemoe.editor.langs.AbstractCodeAn
|
||||
Position start = new Position(line, column);
|
||||
Position end = new Position(line, column + currentToken.getText().length());
|
||||
colors.addStringRange(line, new Range(start, end));
|
||||
|
||||
|
||||
{
|
||||
List<Range> ranges = stringMap.get(line);
|
||||
if(ranges == null) {
|
||||
ranges = new ArrayList<>();
|
||||
}
|
||||
ranges.add(new Range(start, end));
|
||||
stringMap.put(line, ranges);
|
||||
}
|
||||
|
||||
addHexColorIfPresent();
|
||||
break;
|
||||
case JavaLexer.LPAREN :
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.rosemoe.editor.interfaces;
|
||||
import io.github.rosemoe.editor.text.CharPosition;
|
||||
|
||||
/**
|
||||
* Perform text processing when user enters '\n' and selection size is 0
|
||||
@@ -27,7 +28,7 @@ public interface NewlineHandler {
|
||||
* @param afterText Text of line after cursor
|
||||
* @return Whether this handler should be called
|
||||
*/
|
||||
boolean matchesRequirement(String beforeText, String afterText);
|
||||
boolean matchesRequirement(String beforeText, String afterText, CharPosition cursor);
|
||||
|
||||
/**
|
||||
* Handle newline and return processed content to insert
|
||||
|
||||
@@ -4334,7 +4334,7 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
|
||||
boolean consumed = false;
|
||||
for (NewlineHandler handler : handlers) {
|
||||
if (handler != null) {
|
||||
if (handler.matchesRequirement(beforeText, afterText)) {
|
||||
if (handler.matchesRequirement(beforeText, afterText, getCursor().left())) {
|
||||
try {
|
||||
NewlineHandler.HandleResult result = handler.handleNewline(beforeText, afterText, getTabWidth());
|
||||
if (result != null) {
|
||||
|
||||
@@ -28,6 +28,14 @@
|
||||
android:background="@color/primaryDarkColor"
|
||||
android:id="@+id/editor_toolbar"/>
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/build_progress_indicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone"
|
||||
app:indicatorColor="@color/secondaryColor"/>
|
||||
|
||||
<com.itsaky.androidide.views.MaterialBanner
|
||||
android:id="@+id/syncBanner"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
<group
|
||||
android:title="@string/group_project"
|
||||
android:id="@+id/editornav_group_project">
|
||||
<item
|
||||
android:id="@+id/editornav_terminal"
|
||||
android:icon="@drawable/ic_terminal"
|
||||
android:title="@string/btn_terminal"/>
|
||||
<item
|
||||
android:id="@+id/editornav_close_project"
|
||||
android:icon="@drawable/ic_close"
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Reference in New Issue
Block a user