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