Improved IServerSettings implementation

This commit is contained in:
Akash Yadav
2022-03-21 18:33:36 +05:30
parent 9841b59f9f
commit f083bfea9c
13 changed files with 149 additions and 184 deletions
+2
View File
@@ -0,0 +1,2 @@
# Contributing
You can build AndroidIDE on Android Studio. Building AndroidIDE on AndroidIDE itself is also possible but you might face difficulties doing so. So, Android Studio is recommended.
+14 -70
View File
@@ -1,30 +1,22 @@
<p align="center">
<img src="./images/icon.png" width="150"/>
<h1 align="center"><b>AndroidIDE</b></h1>
<img src="./images/header.png" style="width: 70%;"/>
</p>
<p align="center">
<img src="https://img.shields.io/badge/Minimum%20SDK-26-%23ff5252" alt="Minimum SDK"/>
<img src="https://github.com/itsaky/AndroidIDE/actions/workflows/android_workflow.yml/badge.svg" alt="CI Build Status"/>
<a href="./LICENSE"><img src="https://img.shields.io/badge/License-GPLv3-blue.svg" alt="GPL v3 License"/></a>
<br>
<a href="https://t.me/androidide_discussions"><img src="https://img.shields.io/badge/Telegram-90CAF9?style=flag&logo=telegram&logoColor=white" alt="Join us on Telegram"/></a>
</p><br>
## Main Features
- Supports Gradle
- Comes with OpenJDK 11.0.12
- Provides auto completion for Java and XML. It also has basic (reserved) completion for Gradle files.
More features will be implemented as we continue to develop this app.
## Features to be implemented
- [x] Advanced Java Auto Complete
- [x] Terminal
- [x] Custom environment variables (for Build & Terminal)
- [x] SDK Manager (Available via terminal)
- [x] Gradlew support (with some limitations)
## Features
- [x] Gradle support.
- [x] `JDK 11` and `JDK 17` available for use.
- [x] Terminal with necessary packages.
- [x] Custom environment variables (for Build & Terminal).
- [x] SDK Manager (Available via terminal).
- [x] API information for classes and their members (since, removed, deprecated).
- [ ] Implement language servers
- [ ] Language servers
- [x] Java
- [ ] XML
- [ ] Kotlin
- [ ] UI Designer
@@ -45,67 +37,19 @@ Git is currently available only in the terminal i.e. no GUI interface for `git`.
- Gradle Wrapper is supported. But, it requires that the project's application module is named 'app'.
- SDK Manager is already included in Android SDK and is accessible in AndroidIDE via its Terminal. But, you cannot use it to install some tools (like NDK) because those tools are not built for Android.
- No official NDK support because we haven't built the NDK for Android.
- No Android Gradle Plugin versions other than v7.0.2 are supported (due to AAPT2).
The app is still being developed actively. It's in beta stage and may not be stable. if you have any issues using the app, please let us know.
## Issues/suggestions
You should report bugs and suggest features/enhancements [here](https://github.com/itsaky/AndroidIDE/issues).
Describe the issue/request briefly. Provide steps to reproduce the issue. If you need any help, you should discuss it [here](https://t.me/androidide_discussions).
Describe the issue/request briefly. Provide steps to reproduce the issue.
If you open a build related issue, please provide these details:
- Device model
- Android Version
- Full build output with stacktrace.
If you need any help, you should discuss it [here](https://t.me/androidide_discussions).
## Screenshots
| Main Screen | Terminal |
| ----------- | -------- |
| <img src="images/main_screen.jpg" width="100" height="200" alt="AndroidIDE Main Screen" /> | <img src="images/terminal.jpg" width="100" height="200" alt="AndroidIDE Terminal" /> |
| Build Output | Java Completion |
| ------------ | --------------- |
| <img src="images/build_output.jpg" width="100" height="200" alt="AndroidIDE Build Output" /> | <img src="images/java_completion.jpg" width="100" height="200" alt="AndroidIDE Java Completion" /> |
| XML Completion | Screenshot |
| -------------- | ---------- |
| Widgets | <img src="images/xml_completion_widgets.jpg" width="100" height="200" alt="AndroidIDE XML Completion - Widgets" />
| Attributes | <img src="images/xml_completion_attributes.jpg" width="100" height="200" alt="AndroidIDE XML Completion - Attributes" />
| Attribute Values | <img src="images/xml_completion_enums.jpg" width="100" height="200" alt="AndroidIDE XML Completion - Attribute Values" />
| Gradle Support | File Tree |
| -------------- | --------- |
| <img src="images/gradle_buildscript.jpg" width="100" height="200" alt="AndroidIDE Gradle Support" /> | <img src="images/file_tree.jpg" width="100" height="200" alt="AndroidIDE File Tree" /> |
## Posts to help you get started
- [Installing AndroidIDE](https://telegra.ph/How-to-install-AndroidIDE-09-11)
- Author: [Marvin Stelter](https://github.com/MarvinStelter)
- [Create your first project](https://itsaky.github.io/create-your-first-project-in-androidIDE/)
- Author: [Akash Yadav](https://github.com/itsaky)
## Developers
This project was initially developed by [Akash Yadav](https://github.com/itsaky) and [Marvin Stelter](https://github.com/MarvinStelter). We appreciate the efforts of anyone who contributes to this project.
Provide a proper title and a short description for issues.
## Contributing
You can contribute to AndroidIDE in one of the following ways :
- Fix bugs
- Implement new features
- Report bugs
- Suggest a change
- Request a feature
- Improve the documentation
If you create new source files, please make sure you include the license header in every file.
### Things to take care of
There are some things that you should take care of while writing related code.
- Layout Inflater adapters
- [Read the docs](./xml-inflater/src/main/java/com/itsaky/inflater/adapters/README.md) about layout inflater adapters.
### Any other ways to contribute?
You can also write blog posts or create YouTube videos to help newbies get started.
If you do and want us to feature it here, open an issue.
See the [contributing guide](./CONTRIBUTING.md).
## Thanks to
- [Rosemoe](https://github.com/Rosemoe) for the awesome [CodeEditor](https://github.com/Rosemoe/sora-editor)
@@ -135,4 +79,4 @@ You should have received a copy of the GNU General Public License
along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
```
Any violations to the license can be reported either by opening an issue or writing a mail to us directly.
Any violations to the license can be reported either by opening an issue or writing a mail to us directly.
@@ -88,7 +88,7 @@ import com.itsaky.androidide.managers.PreferenceManager;
import com.itsaky.androidide.managers.ToolsManager;
import com.itsaky.androidide.models.DiagnosticGroup;
import com.itsaky.androidide.models.LogLine;
import com.itsaky.androidide.models.PrefBasedJavaServerSettings;
import com.itsaky.lsp.java.models.JavaServerSettings;
import com.itsaky.androidide.models.SaveResult;
import com.itsaky.androidide.models.SearchResult;
import com.itsaky.androidide.models.SheetOption;
@@ -1446,7 +1446,7 @@ public class EditorActivity extends StudioActivity
final var params = new InitializeParams(workspaceRoots);
javaLanguageServer.connectClient(client);
javaLanguageServer.applySettings(PrefBasedJavaServerSettings.getInstance());
javaLanguageServer.applySettings(JavaServerSettings.getInstance());
javaLanguageServer.initialize(params);
}
@@ -1,8 +1,6 @@
/************************************************************************************
/*
* This file is part of AndroidIDE.
*
*
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
@@ -16,30 +14,33 @@
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*
**************************************************************************************/
*/
package com.itsaky.androidide.fragments.preferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceFragmentCompat;
import com.itsaky.androidide.app.StudioApp;
import com.itsaky.androidide.managers.PreferenceManager;
public abstract class BasePreferenceFragment extends PreferenceFragmentCompat {
protected PreferenceManager mPrefManager;
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = super.onCreateView(inflater, container, savedInstanceState);
v.setBackgroundColor(
ContextCompat.getColor(
StudioApp.getInstance(), com.itsaky.androidide.R.color.content_background));
if (v != null) {
v.setBackgroundColor(
ContextCompat.getColor(
StudioApp.getInstance(),
com.itsaky.androidide.R.color.content_background));
}
return v;
}
@@ -49,8 +50,6 @@ public abstract class BasePreferenceFragment extends PreferenceFragmentCompat {
}
protected PreferenceManager getPrefManager() {
return mPrefManager == null
? mPrefManager = new PreferenceManager(getContext())
: mPrefManager;
return StudioApp.getInstance().getPrefManager();
}
}
@@ -31,8 +31,8 @@ import static com.itsaky.androidide.managers.PreferenceManager.KEY_EDITOR_HORIZO
import static com.itsaky.androidide.managers.PreferenceManager.KEY_EDITOR_PRINTABLE_CHARS;
import static com.itsaky.androidide.managers.PreferenceManager.KEY_EDITOR_TAB_SIZE;
import static com.itsaky.androidide.managers.PreferenceManager.KEY_EDITOR_USE_POPUP;
import static com.itsaky.androidide.models.PrefBasedJavaServerSettings.KEY_JAVA_PREF_GOOGLE_CODE_STYLE;
import static com.itsaky.androidide.models.PrefBasedJavaServerSettings.KEY_JAVA_PREF_MATCH_LOWER;
import static com.itsaky.lsp.java.models.JavaServerSettings.KEY_JAVA_PREF_GOOGLE_CODE_STYLE;
import static com.itsaky.lsp.java.models.JavaServerSettings.KEY_COMPLETIONS_MATCH_LOWER;
import android.os.Bundle;
import android.view.LayoutInflater;
@@ -47,7 +47,7 @@ import com.itsaky.androidide.R;
import com.itsaky.androidide.app.StudioApp;
import com.itsaky.androidide.databinding.LayoutTextSizeSliderBinding;
import com.itsaky.androidide.models.ConstantsBridge;
import com.itsaky.androidide.models.PrefBasedJavaServerSettings;
import com.itsaky.lsp.java.models.JavaServerSettings;
import com.itsaky.androidide.utils.DialogUtils;
public class EditorPreferences extends BasePreferenceFragment
@@ -121,7 +121,7 @@ public class EditorPreferences extends BasePreferenceFragment
autoSave.setTitle(getString(R.string.idepref_editor_autoSave_title));
autoSave.setSummary(getString(R.string.idepref_editor_autoSave_summary));
javaMatchLower.setKey(KEY_JAVA_PREF_MATCH_LOWER);
javaMatchLower.setKey(KEY_COMPLETIONS_MATCH_LOWER);
javaMatchLower.setIcon(R.drawable.ic_text_lower);
javaMatchLower.setTitle(getString(R.string.idepref_java_matchLower_title));
javaMatchLower.setSummary(getString(R.string.idepref_java_matchLower_summary));
@@ -170,7 +170,7 @@ public class EditorPreferences extends BasePreferenceFragment
horizontalPopup.setChecked(getPrefManager().getBoolean(KEY_EDITOR_HORIZONTAL_POPUP, false));
drawHex.setChecked(getPrefManager().getBoolean(KEY_EDITOR_DRAW_HEX, true));
autoSave.setChecked(getPrefManager().getBoolean(KEY_EDITOR_AUTO_SAVE, false));
javaMatchLower.setChecked(getPrefManager().getBoolean(KEY_JAVA_PREF_MATCH_LOWER, false));
javaMatchLower.setChecked(getPrefManager().getBoolean(KEY_COMPLETIONS_MATCH_LOWER, false));
useGoogleCodeStyle.setChecked(
getPrefManager().getBoolean(KEY_JAVA_PREF_GOOGLE_CODE_STYLE, false));
visiblePasswordFlag.setChecked(getPrefManager().getBoolean(KEY_EDITOR_FLAG_PASSWORD, true));
@@ -190,10 +190,6 @@ public class EditorPreferences extends BasePreferenceFragment
case KEY_EDITOR_FONT_LIGATURES:
ConstantsBridge.EDITOR_PREF_LIGATURES_CHANGED = true;
break;
case KEY_JAVA_PREF_MATCH_LOWER:
final var javaServer = StudioApp.getInstance().getJavaLanguageServer();
javaServer.applySettings(PrefBasedJavaServerSettings.getInstance());
break;
}
getPrefManager().putBoolean(preference.getKey(), value);
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

@@ -25,6 +25,8 @@ package com.itsaky.lsp.api;
*/
public interface IServerSettings {
String KEY_COMPLETIONS_MATCH_LOWER = "idepref_editor_completions_matchLower";
/**
* Called by language server to check if the completions are enabled. If not enabled, the server
* should not was time and memory computing completions.
@@ -0,0 +1,56 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.lsp.util;
import androidx.annotation.Nullable;
import com.itsaky.androidide.app.BaseApplication;
import com.itsaky.androidide.managers.PreferenceManager;
import com.itsaky.lsp.api.IServerSettings;
/**
* {@link IServerSettings} implementation which uses {@link
* com.itsaky.androidide.managers.PreferenceManager PreferencesManager} to read common settings.
*
* @author Akash Yadav
*/
public abstract class PrefBasedServerSettings extends DefaultServerSettings {
private PreferenceManager prefs;
@Nullable
public PreferenceManager getPrefs() {
if (prefs == null) {
final var app = BaseApplication.getBaseInstance();
if (app != null) {
prefs = app.getPrefManager();
}
}
return prefs;
}
@Override
public boolean shouldMatchAllLowerCase() {
final var prefs = getPrefs();
if (prefs != null) {
return prefs.getBoolean(KEY_COMPLETIONS_MATCH_LOWER, true);
}
return false;
}
}
@@ -19,6 +19,7 @@ package com.itsaky.lsp.java;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.itsaky.androidide.utils.Logger;
import com.itsaky.lsp.api.ICompletionProvider;
import com.itsaky.lsp.api.IDocumentHandler;
@@ -26,8 +27,8 @@ import com.itsaky.lsp.api.ILanguageClient;
import com.itsaky.lsp.api.ILanguageServer;
import com.itsaky.lsp.api.IServerSettings;
import com.itsaky.lsp.java.compiler.JavaCompilerService;
import com.itsaky.lsp.java.models.DefaultJavaServerSettings;
import com.itsaky.lsp.java.models.JavaServerConfiguration;
import com.itsaky.lsp.java.models.JavaServerSettings;
import com.itsaky.lsp.java.providers.CodeActionProvider;
import com.itsaky.lsp.java.providers.CodeFormatProvider;
import com.itsaky.lsp.java.providers.CompletionProvider;
@@ -54,6 +55,7 @@ import com.itsaky.lsp.models.ServerCapabilities;
import com.itsaky.lsp.models.SignatureHelp;
import com.itsaky.lsp.models.SignatureHelpParams;
import com.itsaky.lsp.util.NoCompletionsProvider;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
@@ -89,7 +91,7 @@ public class JavaLanguageServer implements ILanguageServer, IDocumentHandler {
public IServerSettings getSettings() {
if (settings == null) {
settings = new DefaultJavaServerSettings();
settings = JavaServerSettings.getInstance();
}
return settings;
@@ -1,34 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.lsp.java.models;
import com.itsaky.lsp.util.DefaultServerSettings;
/**
* Default settings for the java language server.
*
* @author Akash Yadav
*/
public class DefaultJavaServerSettings extends DefaultServerSettings {
public static final int CODE_STYLE_AOSP = 0;
public static final int CODE_STYLE_GOOGLE = 1;
public int getCodeStyle() {
return CODE_STYLE_AOSP;
}
}
@@ -14,51 +14,41 @@
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.models;
package com.itsaky.lsp.java.models;
import androidx.annotation.NonNull;
import com.itsaky.androidide.app.StudioApp;
import com.itsaky.androidide.managers.PreferenceManager;
import com.itsaky.lsp.java.models.DefaultJavaServerSettings;
import com.itsaky.lsp.util.PrefBasedServerSettings;
/**
* Server settings for the java language server.
*
* @author Akash Yadav
*/
public class PrefBasedJavaServerSettings extends DefaultJavaServerSettings {
public class JavaServerSettings extends PrefBasedServerSettings {
public static final String KEY_JAVA_PREF_MATCH_LOWER = "idepref_editor_java_matchLower";
public static final String KEY_JAVA_PREF_GOOGLE_CODE_STYLE =
"idepref_editor_java_googleCodeStyle";
private static PrefBasedJavaServerSettings instance;
private final PreferenceManager prefs;
public PrefBasedJavaServerSettings() {
this.prefs = StudioApp.getInstance().getPrefManager();
}
public static final int CODE_STYLE_AOSP = 0;
public static final int CODE_STYLE_GOOGLE = 1;
private static JavaServerSettings instance;
@NonNull
public static PrefBasedJavaServerSettings getInstance() {
public static JavaServerSettings getInstance() {
if (instance == null) {
instance = new PrefBasedJavaServerSettings();
instance = new JavaServerSettings();
}
return instance;
}
@Override
public boolean shouldMatchAllLowerCase() {
return prefs.getBoolean(KEY_JAVA_PREF_MATCH_LOWER, false);
}
@Override
public int getCodeStyle() {
if (prefs.getBoolean(KEY_JAVA_PREF_GOOGLE_CODE_STYLE, false)) {
return CODE_STYLE_GOOGLE;
final PreferenceManager prefs = getPrefs();
if (prefs != null) {
if (prefs.getBoolean(KEY_JAVA_PREF_GOOGLE_CODE_STYLE, false)) {
return CODE_STYLE_GOOGLE;
}
}
return CODE_STYLE_AOSP;
@@ -20,13 +20,15 @@ package com.itsaky.lsp.java.providers;
import static com.itsaky.androidide.utils.Logger.instance;
import androidx.annotation.NonNull;
import com.google.common.io.CharSink;
import com.google.common.io.CharSource;
import com.google.googlejavaformat.java.Formatter;
import com.google.googlejavaformat.java.JavaFormatterOptions;
import com.itsaky.androidide.utils.Logger;
import com.itsaky.lsp.api.IServerSettings;
import com.itsaky.lsp.java.models.DefaultJavaServerSettings;
import com.itsaky.lsp.java.models.JavaServerSettings;
import java.io.StringWriter;
import java.io.Writer;
@@ -39,11 +41,11 @@ public class CodeFormatProvider {
private static final Logger LOG = instance("JavaCodeFormatProvider");
private final DefaultJavaServerSettings settings;
private final JavaServerSettings settings;
public CodeFormatProvider(IServerSettings settings) {
assert settings instanceof DefaultJavaServerSettings;
this.settings = (DefaultJavaServerSettings) settings;
assert settings instanceof JavaServerSettings;
this.settings = (JavaServerSettings) settings;
}
public CharSequence format(CharSequence input) {
@@ -64,7 +66,7 @@ public class CodeFormatProvider {
return JavaFormatterOptions.builder()
.formatJavadoc(true)
.style(
settings.getCodeStyle() == DefaultJavaServerSettings.CODE_STYLE_AOSP
settings.getCodeStyle() == JavaServerSettings.CODE_STYLE_AOSP
? JavaFormatterOptions.Style.AOSP
: JavaFormatterOptions.Style.GOOGLE)
.build();
@@ -19,6 +19,7 @@ package com.itsaky.lsp.xml.providers;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.itsaky.androidide.app.BaseApplication;
import com.itsaky.androidide.lexers.xml.XMLLexer;
import com.itsaky.androidide.utils.CharSequenceReader;
@@ -33,18 +34,21 @@ import com.itsaky.lsp.models.CompletionItemKind;
import com.itsaky.lsp.models.CompletionParams;
import com.itsaky.lsp.models.CompletionResult;
import com.itsaky.lsp.models.InsertTextFormat;
import com.itsaky.lsp.util.StringUtils;
import com.itsaky.lsp.xml.R;
import com.itsaky.sdk.SDKInfo;
import com.itsaky.widgets.models.Widget;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.Token;
import org.jetbrains.annotations.Contract;
import java.nio.file.Path;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.Token;
import org.jetbrains.annotations.Contract;
/**
* Completion provider for the XML Language
@@ -70,6 +74,21 @@ public class CompletionProvider extends AbstractServiceProvider implements IComp
this.sdkInfo = sdkInfo;
}
@NonNull
@Contract(pure = true)
private static CompletionItem createNamespaceCompletion(String name, String value) {
final var item = new CompletionItem();
item.setLabel(name + "Ns");
item.setDetail(
BaseApplication.getBaseInstance().getString(R.string.msg_add_namespace_decl, name));
item.setInsertText(String.format("xmlns:%1$s=\"%2$s\"", name, value));
item.setKind(CompletionItemKind.SNIPPET);
item.setSortText(
"1000" + item.getLabel()); // This item is expected to be at the last of the
// completion list
return item;
}
@Override
public boolean canComplete(Path file) {
return ICompletionProvider.super.canComplete(file)
@@ -127,6 +146,7 @@ public class CompletionProvider extends AbstractServiceProvider implements IComp
return EMPTY;
}
final var matchLower = getSettings().shouldMatchAllLowerCase();
final var result = new CompletionResult();
final var attrs = sdkInfo.getAttrInfo();
// final var parser = XmlUtils.newParser (contents);
@@ -153,7 +173,7 @@ public class CompletionProvider extends AbstractServiceProvider implements IComp
if (attr != null && attr.hasPossibleValues()) {
Set<String> values = attr.possibleValues;
for (String value : values) {
if (value.toLowerCase(Locale.US).startsWith(prefix)) {
if (StringUtils.matchesPartialName(value, prefix, matchLower)) {
result.getItems().add(valueAsCompletion(value));
}
}
@@ -162,7 +182,7 @@ public class CompletionProvider extends AbstractServiceProvider implements IComp
} else {
for (Map.Entry<String, Attr> entry : attrs.getAttributes().entrySet()) {
Attr attr = entry.getValue();
if (attr.name.toLowerCase(Locale.US).startsWith(prefix)) {
if (StringUtils.matchesPartialName(attr.name, prefix, matchLower)) {
result.getItems().add(attrAsCompletion(attr));
}
}
@@ -170,15 +190,15 @@ public class CompletionProvider extends AbstractServiceProvider implements IComp
// Shortcuts for automatically declaring namespaces
// These completions are proposed if you type 'androidNs', 'appNs' or 'toolsNs'
// Idea is shamelessly copied from Android Studio 😂
if ("android".startsWith(prefix)) {
if (StringUtils.matchesPartialName("android", prefix, matchLower)) {
result.getItems().add(createNamespaceCompletion("android", ANDROID_NS));
}
if ("app".startsWith(prefix)) {
if (StringUtils.matchesPartialName("app", prefix, matchLower)) {
result.getItems().add(createNamespaceCompletion("app", APP_NS));
}
if ("tools".startsWith(prefix)) {
if (StringUtils.matchesPartialName("tools", prefix, matchLower)) {
result.getItems().add(createNamespaceCompletion("tools", TOOLS_NS));
}
}
@@ -191,7 +211,8 @@ public class CompletionProvider extends AbstractServiceProvider implements IComp
prefix = prefix.toLowerCase(Locale.ROOT);
for (var widget : this.sdkInfo.getWidgetInfo().getWidgets()) {
var name = widget.simpleName.toLowerCase(Locale.ROOT);
if (name.startsWith(prefix)) {
if (StringUtils.matchesPartialName(
name, prefix, getSettings().shouldMatchAllLowerCase())) {
result.getItems().add(widgetNameAsCompletion(widget, slash));
}
}
@@ -279,21 +300,6 @@ public class CompletionProvider extends AbstractServiceProvider implements IComp
return sb.toString();
}
@NonNull
@Contract(pure = true)
private static CompletionItem createNamespaceCompletion(String name, String value) {
final var item = new CompletionItem();
item.setLabel(name + "Ns");
item.setDetail(
BaseApplication.getBaseInstance().getString(R.string.msg_add_namespace_decl, name));
item.setInsertText(String.format("xmlns:%1$s=\"%2$s\"", name, value));
item.setKind(CompletionItemKind.SNIPPET);
item.setSortText(
"1000" + item.getLabel()); // This item is expected to be at the last of the
// completion list
return item;
}
private static class IsInValueScanner {
private final int cursorIndex;