Move syntax highligting to codeview components (#1196)

TODO

- Issues of https://codeberg.org/gitnex-garage/useLangDefs

https://codeberg.org/gitnex/GitNex/issues/1180

Also see https://codeberg.org/gitnex-garage/useLangDefs

Co-authored-by: qwerty287 <ndev@web.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/1196
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
This commit is contained in:
qwerty287 2022-09-30 05:04:01 +02:00 committed by M M Arif
parent 325560c08d
commit 211fdab250
31 changed files with 1740 additions and 1013 deletions

View File

@ -87,7 +87,6 @@ Thanks to all the open source libraries, contributors and donators.
- [wasabeef/picasso-transformations](https://github.com/wasabeef/picasso-transformations)
- [cats-oss/android-gpuimage](https://github.com/cats-oss/android-gpuimage)
- [noties/Markwon](https://github.com/noties/Markwon)
- [noties/Prism4j](https://github.com/noties/Prism4j)
- [ocpsoft/prettytime](https://github.com/ocpsoft/prettytime)
- [ramseth001/TextDrawable](https://github.com/ramseth001/TextDrawable)
- [vdurmont/emoji-java](https://github.com/vdurmont/emoji-java)

View File

@ -94,8 +94,6 @@ dependencies {
implementation "io.noties.markwon:recycler:$markwon_version"
implementation "io.noties.markwon:recycler-table:$markwon_version"
implementation "io.noties.markwon:simple-ext:$markwon_version"
implementation 'org.codeberg.qwerty287:markwonprism4j:9d3ef078cd'
implementation 'org.codeberg.qwerty287:Prism4j:3.0.0'
implementation 'com.google.guava:guava:31.1-android'
implementation "io.noties.markwon:image-picasso:$markwon_version"
implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9"

View File

@ -10,14 +10,14 @@ import com.amrdeveloper.codeview.Code;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.EnumUtils;
import org.mian.gitnex.R;
import org.mian.gitnex.core.MainGrammarLocator;
import org.mian.gitnex.databinding.ActivityCodeEditorBinding;
import org.mian.gitnex.helpers.codeeditor.CustomCodeViewAdapter;
import org.mian.gitnex.helpers.codeeditor.LanguageManager;
import org.mian.gitnex.helpers.codeeditor.LanguageName;
import org.mian.gitnex.helpers.codeeditor.SourcePositionListener;
import org.mian.gitnex.helpers.codeeditor.ThemeName;
import org.mian.gitnex.helpers.codeeditor.languages.Language;
import org.mian.gitnex.helpers.codeeditor.languages.UnknownLanguage;
import org.mian.gitnex.helpers.codeeditor.theme.Theme;
/**
* @author AmrDeveloper
@ -25,10 +25,9 @@ import org.mian.gitnex.helpers.codeeditor.ThemeName;
*/
public class CodeEditorActivity extends BaseActivity {
private final ThemeName currentTheme = ThemeName.FIVE_COLOR;
private Theme currentTheme;
private ActivityCodeEditorBinding binding;
private LanguageManager languageManager;
private LanguageName currentLanguage = LanguageName.UNKNOWN;
private Language currentLanguage = new UnknownLanguage();
@Override
public void onCreate(Bundle savedInstanceState) {
@ -44,15 +43,13 @@ public class CodeEditorActivity extends BaseActivity {
String fileContent = getIntent().getStringExtra("fileContent");
String fileExtension;
currentTheme = Theme.getDefaultTheme(this);
if (getIntent().getStringExtra("fileExtension") != null) {
fileExtension = getIntent().getStringExtra("fileExtension").toUpperCase();
fileExtension =
MainGrammarLocator.fromExtension(getIntent().getStringExtra("fileExtension"));
if (EnumUtils.isValidEnum(LanguageName.class, fileExtension)) {
currentLanguage = LanguageName.valueOf(fileExtension);
} else {
currentLanguage = LanguageName.UNKNOWN;
}
currentLanguage = Language.fromName(fileExtension);
}
configCodeView(currentLanguage, fileContent);
@ -65,7 +62,7 @@ public class CodeEditorActivity extends BaseActivity {
setResult(Activity.RESULT_OK, intent);
}
private void configCodeView(LanguageName currentLanguage, String fileContent) {
private void configCodeView(Language currentLanguage, String fileContent) {
binding.codeView.setTypeface(
Typeface.createFromAsset(ctx.getAssets(), "fonts/sourcecodeproregular.ttf"));
@ -79,9 +76,8 @@ public class CodeEditorActivity extends BaseActivity {
binding.codeView.setTabLength(4);
binding.codeView.setEnableAutoIndentation(true);
// Setup the language and theme with SyntaxManager helper class
languageManager = new LanguageManager(this, binding.codeView);
languageManager.applyTheme(currentLanguage, currentTheme);
// Set up the language and theme with SyntaxManager helper class
currentLanguage.applyTheme(this, binding.codeView, currentTheme);
// Setup auto pair complete
final Map<Character, Character> pairCompleteMap = new HashMap<>();
@ -97,7 +93,7 @@ public class CodeEditorActivity extends BaseActivity {
binding.codeView.enablePairCompleteCenterCursor(true);
binding.codeView.setText(fileContent);
// Setup the auto complete and auto indenting for the current language
// Set up the auto complete and auto indenting for the current language
configLanguageAutoComplete();
configLanguageAutoIndentation();
}
@ -106,13 +102,13 @@ public class CodeEditorActivity extends BaseActivity {
boolean useModernAutoCompleteAdapter = true;
if (useModernAutoCompleteAdapter) {
List<Code> codeList = languageManager.getLanguageCodeList(currentLanguage);
List<Code> codeList = currentLanguage.getCodeList();
CustomCodeViewAdapter adapter = new CustomCodeViewAdapter(this, codeList);
binding.codeView.setAdapter(adapter);
} else {
String[] languageKeywords = languageManager.getLanguageKeywords(currentLanguage);
String[] languageKeywords = currentLanguage.getKeywords();
final int layoutId = R.layout.list_item_suggestion;
@ -125,10 +121,8 @@ public class CodeEditorActivity extends BaseActivity {
}
private void configLanguageAutoIndentation() {
binding.codeView.setIndentationStarts(
languageManager.getLanguageIndentationStarts(currentLanguage));
binding.codeView.setIndentationEnds(
languageManager.getLanguageIndentationEnds(currentLanguage));
binding.codeView.setIndentationStarts(currentLanguage.getIndentationStarts());
binding.codeView.setIndentationEnds(currentLanguage.getIndentationEnds());
}
private void configCodeViewPlugins() {
@ -139,7 +133,7 @@ public class CodeEditorActivity extends BaseActivity {
}
private void configLanguageName() {
binding.languageName.setText(currentLanguage.name().toLowerCase());
binding.languageName.setText(currentLanguage.getName().toLowerCase());
}
private void configSourcePositionListener() {

View File

@ -1,38 +1,13 @@
package org.mian.gitnex.core;
import androidx.annotation.NonNull;
import io.noties.prism4j.DefaultGrammarLocator;
import io.noties.prism4j.Grammar;
import io.noties.prism4j.GrammarLocator;
import io.noties.prism4j.Prism4j;
import java.util.Set;
/**
* @author opyale
*/
public class MainGrammarLocator implements GrammarLocator {
public class MainGrammarLocator {
public static final String DEFAULT_FALLBACK_LANGUAGE = "clike";
public static final String DEFAULT_FALLBACK_LANGUAGE = null; // "clike";
private static final DefaultGrammarLocator defaultGrammarLocator = new DefaultGrammarLocator();
private static volatile MainGrammarLocator instance;
private MainGrammarLocator() {}
public static MainGrammarLocator getInstance() {
if (instance == null) {
synchronized (MainGrammarLocator.class) {
if (instance == null) {
instance = new MainGrammarLocator();
}
}
}
return instance;
}
public String fromExtension(String extension) {
public static String fromExtension(String extension) {
switch (extension.toLowerCase()) {
case "b":
@ -84,9 +59,9 @@ public class MainGrammarLocator implements GrammarLocator {
case "md":
return "markdown";
case "xml":
case "html":
case "htm":
// case "xml":
// case "html":
// case "htm":
case "mathml":
case "svg":
return "markup";
@ -113,16 +88,4 @@ public class MainGrammarLocator implements GrammarLocator {
return extension;
}
@Override
public Grammar grammar(@NonNull Prism4j prism4j, @NonNull String language) {
return defaultGrammarLocator.grammar(prism4j, language);
}
@NonNull @Override
public Set<String> languages() {
return defaultGrammarLocator.languages();
}
}

View File

@ -9,10 +9,6 @@ import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import de.qwerty287.markwonprism4j.Prism4jTheme;
import de.qwerty287.markwonprism4j.Prism4jThemeDarkula;
import de.qwerty287.markwonprism4j.Prism4jThemeDefault;
import de.qwerty287.markwonprism4j.SyntaxHighlightPlugin;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.MarkwonConfiguration;
@ -33,7 +29,6 @@ import io.noties.markwon.recycler.MarkwonAdapter;
import io.noties.markwon.recycler.SimpleEntry;
import io.noties.markwon.recycler.table.TableEntry;
import io.noties.markwon.recycler.table.TableEntryPlugin;
import io.noties.prism4j.Prism4j;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
@ -58,6 +53,8 @@ import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.core.MainGrammarLocator;
import org.mian.gitnex.helpers.codeeditor.markwon.MarkwonHighlighter;
import org.mian.gitnex.helpers.codeeditor.theme.Theme;
import org.mian.gitnex.helpers.contexts.IssueContext;
import org.mian.gitnex.helpers.contexts.RepositoryContext;
import stormpot.Allocator;
@ -177,11 +174,6 @@ public class Markdown {
private void setup() {
Prism4jTheme prism4jTheme =
AppUtil.getColorFromAttribute(context, R.attr.isDark) == 1
? Prism4jThemeDarkula.create()
: Prism4jThemeDefault.create();
Markwon.Builder builder =
Markwon.builder(context)
.usePlugin(CorePlugin.create())
@ -197,9 +189,9 @@ public class Markdown {
PicassoImagesPlugin.create(
PicassoService.getInstance(context).get()))
.usePlugin(
SyntaxHighlightPlugin.create(
new Prism4j(MainGrammarLocator.getInstance()),
prism4jTheme,
MarkwonHighlighter.create(
context,
Theme.getDefaultTheme(context),
MainGrammarLocator.DEFAULT_FALLBACK_LANGUAGE))
.usePlugin(
new AbstractMarkwonPlugin() {
@ -333,11 +325,6 @@ public class Markdown {
linkPostProcessor.repository = repository;
}
Prism4jTheme prism4jTheme =
AppUtil.getColorFromAttribute(context, R.attr.isDark) == 1
? Prism4jThemeDarkula.create()
: Prism4jThemeDefault.create();
final InlineParserFactory inlineParserFactory =
MarkwonInlineParser.factoryBuilder()
.addInlineProcessor(new IssueInlineProcessor())
@ -359,9 +346,9 @@ public class Markdown {
PicassoImagesPlugin.create(
PicassoService.getInstance(context).get()))
.usePlugin(
SyntaxHighlightPlugin.create(
new Prism4j(MainGrammarLocator.getInstance()),
prism4jTheme,
MarkwonHighlighter.create(
context,
Theme.getDefaultTheme(context),
MainGrammarLocator.DEFAULT_FALLBACK_LANGUAGE))
.usePlugin(
new AbstractMarkwonPlugin() {

View File

@ -1,136 +0,0 @@
package org.mian.gitnex.helpers.codeeditor;
import android.content.Context;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.mian.gitnex.helpers.codeeditor.languages.GoLanguage;
import org.mian.gitnex.helpers.codeeditor.languages.HtmlLanguage;
import org.mian.gitnex.helpers.codeeditor.languages.JavaLanguage;
import org.mian.gitnex.helpers.codeeditor.languages.PhpLanguage;
import org.mian.gitnex.helpers.codeeditor.languages.PythonLanguage;
import org.mian.gitnex.helpers.codeeditor.languages.XmlLanguage;
/**
* @author AmrDeveloper
* @author M M Arif
*/
public class LanguageManager {
private final Context context;
private final CodeView codeView;
public LanguageManager(Context context, CodeView codeView) {
this.context = context;
this.codeView = codeView;
}
public void applyTheme(LanguageName language, ThemeName theme) {
if (theme == ThemeName.FIVE_COLOR) {
applyFiveColorsDarkTheme(language);
}
}
public String[] getLanguageKeywords(LanguageName language) {
switch (language) {
case JAVA:
return JavaLanguage.getKeywords(context);
case PY:
return PythonLanguage.getKeywords(context);
case GO:
return GoLanguage.getKeywords(context);
case PHP:
return PhpLanguage.getKeywords(context);
case XML:
return XmlLanguage.getKeywords(context);
case HTML:
return HtmlLanguage.getKeywords(context);
default:
return new String[] {};
}
}
public List<Code> getLanguageCodeList(LanguageName language) {
switch (language) {
case JAVA:
return JavaLanguage.getCodeList(context);
case PY:
return PythonLanguage.getCodeList(context);
case GO:
return GoLanguage.getCodeList(context);
case PHP:
return PhpLanguage.getCodeList(context);
case XML:
return XmlLanguage.getCodeList(context);
case HTML:
return HtmlLanguage.getCodeList(context);
default:
return new ArrayList<>();
}
}
public Set<Character> getLanguageIndentationStarts(LanguageName language) {
switch (language) {
case JAVA:
return JavaLanguage.getIndentationStarts();
case PY:
return PythonLanguage.getIndentationStarts();
case GO:
return GoLanguage.getIndentationStarts();
case PHP:
return PhpLanguage.getIndentationStarts();
case XML:
return XmlLanguage.getIndentationStarts();
case HTML:
return HtmlLanguage.getIndentationStarts();
default:
return new HashSet<>();
}
}
public Set<Character> getLanguageIndentationEnds(LanguageName language) {
switch (language) {
case JAVA:
return JavaLanguage.getIndentationEnds();
case PY:
return PythonLanguage.getIndentationEnds();
case GO:
return GoLanguage.getIndentationEnds();
case PHP:
return PhpLanguage.getIndentationEnds();
case XML:
return XmlLanguage.getIndentationEnds();
case HTML:
return HtmlLanguage.getIndentationEnds();
default:
return new HashSet<>();
}
}
private void applyFiveColorsDarkTheme(LanguageName language) {
switch (language) {
case JAVA:
JavaLanguage.applyFiveColorsDarkTheme(context, codeView);
break;
case PY:
PythonLanguage.applyFiveColorsDarkTheme(context, codeView);
break;
case GO:
GoLanguage.applyFiveColorsDarkTheme(context, codeView);
break;
case PHP:
PhpLanguage.applyFiveColorsDarkTheme(context, codeView);
break;
case XML:
XmlLanguage.applyFiveColorsDarkTheme(context, codeView);
break;
case HTML:
HtmlLanguage.applyFiveColorsDarkTheme(context, codeView);
break;
}
}
}

View File

@ -1,15 +0,0 @@
package org.mian.gitnex.helpers.codeeditor;
/**
* @author AmrDeveloper
* @author M M Arif
*/
public enum LanguageName {
UNKNOWN, // no language is specified or app currently does not support the mentioned language
JAVA, // java
PY, // python with py extension
GO, // go lang
PHP, // php
XML, // xml
HTML // html
}

View File

@ -11,12 +11,6 @@ import android.widget.EditText;
*/
public class SourcePositionListener {
@FunctionalInterface
public interface OnPositionChanged {
void onPositionChange(int line, int column);
}
private OnPositionChanged onPositionChanged;
public SourcePositionListener(EditText editText) {
@ -45,4 +39,10 @@ public class SourcePositionListener {
public void setOnPositionChanged(OnPositionChanged listener) {
onPositionChanged = listener;
}
@FunctionalInterface
public interface OnPositionChanged {
void onPositionChange(int line, int column);
}
}

View File

@ -1,9 +0,0 @@
package org.mian.gitnex.helpers.codeeditor;
/**
* @author AmrDeveloper
* @author M M Arif
*/
public enum ThemeName {
FIVE_COLOR
}

View File

@ -0,0 +1,164 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.Keyword;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
/**
* @author qwerty287
*/
public class CLanguage extends Language {
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*");
private static final Pattern PATTERN_MULTI_LINE_COMMENT =
Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+");
private static final Pattern PATTERN_OPERATION =
Pattern.compile(
":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*");
private static final Pattern PATTERN_TODO_COMMENT =
Pattern.compile("//\\s?(TODO|todo)\\s[^\n]*");
private static final Pattern PATTERN_NUMBERS = Pattern.compile("\\b(\\d*[.]?\\d+)\\b");
private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']");
private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]");
private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+");
public static String getCommentStart() {
return "//";
}
public static String getCommentEnd() {
return "";
}
@Override
public Pattern getPattern(LanguageElement element) {
switch (element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case BUILTIN:
return PATTERN_BUILTINS;
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case HEX:
return PATTERN_HEX;
case SINGLE_LINE_COMMENT:
return PATTERN_SINGLE_LINE_COMMENT;
case MULTI_LINE_COMMENT:
return PATTERN_MULTI_LINE_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case OPERATION:
return PATTERN_OPERATION;
case TODO_COMMENT:
return PATTERN_TODO_COMMENT;
case GENERIC:
case ANNOTATION:
default:
return null;
}
}
@Override
public String[] getKeywords() {
return new String[] {
"alignas",
"alignof",
"auto",
"bool",
"break",
"case",
"char",
"const",
"constexpr",
"continue",
"default",
"do",
"double",
"else",
"enum",
"extern",
"false",
"float",
"for",
"goto",
"if",
"inline",
"int",
"long",
"nullptr",
"register",
"restrict",
"return",
"short",
"signed",
"sizeof",
"static",
"static_assert",
"struct",
"switch",
"thread_local",
"true",
"typedef",
"typeof",
"typeof_unqual",
"union",
"unsigned",
"void",
"volatile",
"while",
"_Alignas",
"_Alignof",
"_Atomic",
"_BitInt",
"_Bool",
"_Complex",
"_Decimal128",
"_Decimal32",
"_Decimal64",
"_Generic",
"_Imaginary",
"_Noreturn",
"_Static_assert",
"_Thread_local",
};
}
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords();
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
@Override
public String getName() {
return "C";
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
}

View File

@ -0,0 +1,154 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.Keyword;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
/**
* @author qwerty287
*/
public class CppLanguage extends Language {
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*");
private static final Pattern PATTERN_MULTI_LINE_COMMENT =
Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+");
private static final Pattern PATTERN_OPERATION =
Pattern.compile(
":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*");
private static final Pattern PATTERN_GENERIC = Pattern.compile("<[a-zA-Z0-9,<>]+>");
private static final Pattern PATTERN_TODO_COMMENT =
Pattern.compile("//\\s?(TODO|todo)\\s[^\n]*");
private static final Pattern PATTERN_NUMBERS = Pattern.compile("\\b(\\d*[.]?\\d+)\\b");
private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']");
private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]");
private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+");
public static String getCommentStart() {
return "//";
}
public static String getCommentEnd() {
return "";
}
@Override
public Pattern getPattern(LanguageElement element) {
switch (element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case BUILTIN:
return PATTERN_BUILTINS;
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case HEX:
return PATTERN_HEX;
case SINGLE_LINE_COMMENT:
return PATTERN_SINGLE_LINE_COMMENT;
case MULTI_LINE_COMMENT:
return PATTERN_MULTI_LINE_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case OPERATION:
return PATTERN_OPERATION;
case TODO_COMMENT:
return PATTERN_TODO_COMMENT;
case GENERIC:
return PATTERN_GENERIC;
case ANNOTATION:
default:
return null;
}
}
@Override
public String[] getKeywords() {
return new String[] {
"asm double",
"new",
"switch",
"auto",
"else",
"operator",
"template",
"break",
"enum",
"private",
"this",
"case",
"extern",
"protected",
"throw",
"catch",
"float",
"public",
"try",
"char",
"for",
"register",
"typedef",
"class",
"friend",
"return",
"union",
"const",
"goto",
"short",
"unsigned",
"continue",
"if",
"signed",
"virtual",
"default",
"inline",
"sizeof",
"void",
"delete",
"int",
"static",
"volatile",
"do",
"long",
"struct",
"while"
};
}
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords();
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
@Override
public String getName() {
return "Cpp";
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
}

View File

@ -1,30 +1,18 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import android.content.Context;
import android.content.res.Resources;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import com.amrdeveloper.codeview.Keyword;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import org.mian.gitnex.R;
/**
* @author AmrDeveloper
* @author M M Arif
*/
public class GoLanguage {
// Language Keywords
private static final Pattern PATTERN_KEYWORDS =
Pattern.compile(
"\\b(break|default|func|interface|case|defer|"
+ "go|map|struct|chan|else|goto|package|switch|const"
+ "|fallthrough|if|range|type|continue|for|import|return|var|"
+ "string|true|false|new|nil|byte|bool|int|int8|int16|int32|int64)\\b");
public class GoLanguage extends Language {
// Brackets and Colons
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
@ -32,9 +20,12 @@ public class GoLanguage {
// Data
private static final Pattern PATTERN_NUMBERS = Pattern.compile("\\b(\\d*[.]?\\d+)\\b");
private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']");
private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]");
private static final Pattern PATTERN_STRING = Pattern.compile("[\"`](.*?)[\"`]");
private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*");
private static final Pattern PATTERN_TODO_COMMENT =
Pattern.compile("//\\s?(TODO|todo)\\s[^\n]*");
private static final Pattern PATTERN_MULTI_LINE_COMMENT =
Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+");
@ -42,71 +33,121 @@ public class GoLanguage {
Pattern.compile(
":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*");
public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) {
codeView.resetSyntaxPatternList();
codeView.resetHighlighter();
Resources resources = context.getResources();
// View Background
codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null));
// Syntax Colors
codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(
PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(
PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(
PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(
PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(
PATTERN_SINGLE_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(
PATTERN_MULTI_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(
PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null));
codeView.addSyntaxPattern(
PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null));
// Default Color
codeView.setTextColor(resources.getColor(R.color.five_dark_white, null));
codeView.reHighlightSyntax();
@Override
public String[] getKeywords() {
return new String[] {
"break",
"default",
"func",
"interface",
"select",
"case",
"defer",
"go",
"map",
"struct",
"chan",
"else",
"goto",
"package",
"switch",
"const",
"fallthrough",
"if",
"bool",
"byte",
"cap",
"close",
"complex",
"complex64",
"complex128",
"uint16",
"copy",
"false",
"float32",
"float64",
"imag",
"int",
"int8",
"int16",
"uint32",
"int32",
"int64",
"len",
"make",
"new",
"nil",
"uint64",
"range",
"type",
"continue",
"for",
"import",
"return",
"var"
};
}
public static String[] getKeywords(Context context) {
return context.getResources().getStringArray(R.array.go_keywords);
}
public static List<Code> getCodeList(Context context) {
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
String[] keywords = getKeywords();
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
@Override
public String getName() {
return "Go";
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
public static String getCommentStart() {
return "//";
}
@Override
public Pattern getPattern(LanguageElement element) {
switch (element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case BUILTIN:
return PATTERN_BUILTINS;
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case HEX:
return PATTERN_HEX;
case SINGLE_LINE_COMMENT:
return PATTERN_SINGLE_LINE_COMMENT;
case MULTI_LINE_COMMENT:
return PATTERN_MULTI_LINE_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case OPERATION:
return PATTERN_OPERATION;
case TODO_COMMENT:
return PATTERN_TODO_COMMENT;
public static String getCommentEnd() {
return "";
case GENERIC:
// TODO supported by Go 1.18
case ANNOTATION:
default:
return null;
}
}
}

View File

@ -1,29 +1,17 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import android.content.Context;
import android.content.res.Resources;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import com.amrdeveloper.codeview.Keyword;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import org.mian.gitnex.R;
/**
* @author M M Arif
*/
public class HtmlLanguage {
// Language Keywords
private static final Pattern PATTERN_KEYWORDS =
Pattern.compile(
"\\b(<html|<DOCTYPE|<head|<title|<body|<style|<script|src|href"
+ "<h1|<h2|<h3|<h4|<h5|<h6|<br|<hr|<section|<header|<footer|<select|<img|<embed|<iframe|<div|<p|code|strong|small|template|"
+ "input|form|textarea|button|option|label|fieldset|legend|datalist|frame|map|area|canvas|picture|svg|audio|source|track|video|"
+ "link|nav|ul|ol|li|table|caption|th|tr|td|thead|tbody|tfooter|col|span|main|article|aside|meta|base|noscript|object|param|)\\b");
public class HtmlLanguage extends Language {
// Brackets and Colons
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
@ -33,74 +21,12 @@ public class HtmlLanguage {
private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']");
private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]");
private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*");
private static final Pattern PATTERN_MULTI_LINE_COMMENT =
Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("<!--.*-->");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+");
private static final Pattern PATTERN_OPERATION =
Pattern.compile(
":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*");
public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) {
codeView.resetSyntaxPatternList();
codeView.resetHighlighter();
Resources resources = context.getResources();
// View Background
codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null));
// Syntax Colors
codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(
PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(
PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(
PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(
PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(
PATTERN_SINGLE_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(
PATTERN_MULTI_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(
PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null));
codeView.addSyntaxPattern(
PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null));
// Default Color
codeView.setTextColor(resources.getColor(R.color.five_dark_white, null));
codeView.reHighlightSyntax();
}
public static String[] getKeywords(Context context) {
return context.getResources().getStringArray(R.array.html_keywords);
}
public static List<Code> getCodeList(Context context) {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
public static String getCommentStart() {
return "//";
}
@ -108,4 +34,141 @@ public class HtmlLanguage {
public static String getCommentEnd() {
return "";
}
@Override
public Pattern getPattern(LanguageElement element) {
switch (element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case BUILTIN:
return PATTERN_BUILTINS;
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case HEX:
return PATTERN_HEX;
case SINGLE_LINE_COMMENT:
case MULTI_LINE_COMMENT:
return PATTERN_SINGLE_LINE_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case OPERATION:
return PATTERN_OPERATION;
case GENERIC:
case TODO_COMMENT:
case ANNOTATION:
default:
return null;
}
}
@Override
public String[] getKeywords() {
return new String[] {
"<html",
"<DOCTYPE",
"<head",
"<title",
"<body",
"<h1",
"<h2",
"<h3",
"<h4",
"<h5",
"<h6",
"<br",
"<hr",
"<section",
"<header",
"<footer",
"<select",
"<img",
"<embed",
"<iframe",
"<style",
"<script",
"<div",
"<p",
"code",
"strong",
"small",
"template",
"form",
"input",
"textarea",
"button",
"option",
"label",
"fieldset",
"legend",
"datalist",
"frame",
"map",
"area",
"canvas",
"picture",
"svg",
"audio",
"source",
"track",
"video",
"link",
"nav",
"ul",
"ol",
"li",
"table",
"caption",
"th",
"tr",
"td",
"thead",
"tbody",
"tfooter",
"col",
"span",
"main",
"article",
"aside",
"meta",
"base",
"noscript",
"object",
"param",
"src",
"href"
};
}
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords();
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
@Override
public String getName() {
return "HTML";
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
}

View File

@ -1,33 +1,18 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import android.content.Context;
import android.content.res.Resources;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import com.amrdeveloper.codeview.Keyword;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import org.mian.gitnex.R;
/**
* @author AmrDeveloper
* @author M M Arif
*/
public class JavaLanguage {
// Language Keywords
private static final Pattern PATTERN_KEYWORDS =
Pattern.compile(
"\\b(abstract|boolean|break|byte|case|catch"
+ "|char|class|continue|default|do|double|else"
+ "|enum|extends|final|finally|float|for|if"
+ "|implements|import|instanceof|int|interface"
+ "|long|native|new|null|package|private|protected"
+ "|public|return|short|static|strictfp|super|switch"
+ "|synchronized|this|throw|transient|try|void|volatile|while)\\b");
public class JavaLanguage extends Language {
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*");
@ -39,78 +24,13 @@ public class JavaLanguage {
":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*");
private static final Pattern PATTERN_GENERIC = Pattern.compile("<[a-zA-Z0-9,<>]+>");
private static final Pattern PATTERN_ANNOTATION = Pattern.compile("@.[a-zA-Z0-9]+");
private static final Pattern PATTERN_TODO_COMMENT = Pattern.compile("//TODO[^\n]*");
private static final Pattern PATTERN_TODO_COMMENT =
Pattern.compile("//\\s?(TODO|todo)\\s[^\n]*");
private static final Pattern PATTERN_NUMBERS = Pattern.compile("\\b(\\d*[.]?\\d+)\\b");
private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']");
private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]");
private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+");
public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) {
codeView.resetSyntaxPatternList();
codeView.resetHighlighter();
Resources resources = context.getResources();
// View Background
codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null));
// Syntax Colors
codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(
PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(
PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(
PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(
PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(
PATTERN_SINGLE_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(
PATTERN_MULTI_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(
PATTERN_ANNOTATION, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(
PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null));
codeView.addSyntaxPattern(
PATTERN_GENERIC, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(
PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null));
// Default Color
codeView.setTextColor(resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(PATTERN_TODO_COMMENT, resources.getColor(R.color.gold, null));
codeView.reHighlightSyntax();
}
public static String[] getKeywords(Context context) {
return context.getResources().getStringArray(R.array.java_keywords);
}
public static List<Code> getCodeList(Context context) {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
public static String getCommentStart() {
return "//";
}
@ -118,4 +38,119 @@ public class JavaLanguage {
public static String getCommentEnd() {
return "";
}
@Override
public Pattern getPattern(LanguageElement element) {
switch (element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case BUILTIN:
return PATTERN_BUILTINS;
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case HEX:
return PATTERN_HEX;
case SINGLE_LINE_COMMENT:
return PATTERN_SINGLE_LINE_COMMENT;
case MULTI_LINE_COMMENT:
return PATTERN_MULTI_LINE_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case OPERATION:
return PATTERN_OPERATION;
case GENERIC:
return PATTERN_GENERIC;
case TODO_COMMENT:
return PATTERN_TODO_COMMENT;
case ANNOTATION:
return PATTERN_ANNOTATION;
default:
return null;
}
}
@Override
public String[] getKeywords() {
return new String[] {
"public",
"private",
"protected",
"package",
"abstract",
"boolean",
"break",
"byte",
"case",
"catch",
"char",
"class",
"continue",
"default",
"do",
"double",
"else",
"enum",
"extends",
"final",
"finally",
"float",
"for",
"if",
"implements",
"import",
"instanceof",
"int",
"interface",
"long",
"native",
"new",
"return",
"short",
"static",
"strictfp",
"super",
"switch",
"synchronized",
"this",
"throw",
"transient",
"try",
"void",
"volatile",
"while"
};
}
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords();
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
@Override
public String getName() {
return "Java";
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
}

View File

@ -0,0 +1,168 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.Keyword;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
/**
* @author qwerty287
*/
public class JavaScriptLanguage extends Language {
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*");
private static final Pattern PATTERN_MULTI_LINE_COMMENT =
Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+");
private static final Pattern PATTERN_OPERATION =
Pattern.compile(
":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*");
private static final Pattern PATTERN_TODO_COMMENT =
Pattern.compile("//\\s?(TODO|todo)\\s[^\n]*");
private static final Pattern PATTERN_NUMBERS = Pattern.compile("\\b(\\d*[.]?\\d+)\\b");
private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']");
private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]");
private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+");
public static String getCommentStart() {
return "//";
}
public static String getCommentEnd() {
return "";
}
@Override
public Pattern getPattern(LanguageElement element) {
switch (element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case BUILTIN:
return PATTERN_BUILTINS;
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case HEX:
return PATTERN_HEX;
case SINGLE_LINE_COMMENT:
return PATTERN_SINGLE_LINE_COMMENT;
case MULTI_LINE_COMMENT:
return PATTERN_MULTI_LINE_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case OPERATION:
return PATTERN_OPERATION;
case TODO_COMMENT:
return PATTERN_TODO_COMMENT;
case ANNOTATION:
case GENERIC:
default:
return null;
}
}
@Override
public String[] getKeywords() {
return new String[] {
"abstract",
"arguments",
"boolean",
"break",
"byte",
"case",
"catch",
"char",
"const",
"continue",
"debugger",
"default",
"delete",
"do",
"double",
"else",
"eval",
"false",
"final",
"finally",
"float",
"for",
"function",
"goto",
"if",
"implements",
"in",
"instanceof",
"int",
"interface",
"let",
"long",
"native",
"new",
"null",
"package",
"private",
"protected",
"public",
"return",
"short",
"static",
"switch",
"synchronized",
"this",
"throw",
"throws",
"transient",
"true",
"try",
"typeof",
"var",
"void",
"volatile",
"while",
"with",
"yield",
"class",
"enum",
"export",
"extends",
"import",
"super"
};
}
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords();
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
@Override
public String getName() {
return "JavaScript";
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
}

View File

@ -0,0 +1,98 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.Keyword;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
/**
* @author qwerty287
*/
public class JsonLanguage extends Language {
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*");
private static final Pattern PATTERN_MULTI_LINE_COMMENT =
Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+");
private static final Pattern PATTERN_TODO_COMMENT =
Pattern.compile("//\\s?(TODO|todo)\\s[^\n]*");
private static final Pattern PATTERN_NUMBERS = Pattern.compile("\\b(\\d*[.]?\\d+)\\b");
private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']");
private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]");
public static String getCommentStart() {
return "//";
}
public static String getCommentEnd() {
return "";
}
@Override
public Pattern getPattern(LanguageElement element) {
switch (element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case SINGLE_LINE_COMMENT:
return PATTERN_SINGLE_LINE_COMMENT;
case MULTI_LINE_COMMENT:
return PATTERN_MULTI_LINE_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case TODO_COMMENT:
return PATTERN_TODO_COMMENT;
case BUILTIN:
case OPERATION:
case ANNOTATION:
case HEX:
case GENERIC:
default:
return null;
}
}
@Override
public String[] getKeywords() {
return new String[] {"false", "true", "null"};
}
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords();
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
@Override
public String getName() {
return "JSON";
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
characterSet.add('[');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
characterSet.add(']');
return characterSet;
}
}

View File

@ -0,0 +1,91 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import android.content.Context;
import android.content.res.Resources;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
import org.mian.gitnex.helpers.codeeditor.theme.Theme;
/**
* @author qwerty287
*/
public abstract class Language {
private static HashMap<String, Language> languages = null;
private static void initializeMap() {
if (languages == null) {
languages = new HashMap<>();
Language[] languagesArray =
new Language[] {
new JavaLanguage(),
new PythonLanguage(),
new GoLanguage(),
new PhpLanguage(),
new XmlLanguage(),
new HtmlLanguage(),
new JavaScriptLanguage(),
new TypeScriptLanguage(),
new JsonLanguage(),
new CppLanguage(),
new CLanguage()
};
for (Language l : languagesArray) {
languages.put(l.getName().toUpperCase(), l);
}
}
}
public static Language fromName(String name) {
initializeMap();
return isValid(name) ? languages.get(name.toUpperCase()) : new UnknownLanguage();
}
public static boolean isValid(String name) {
initializeMap();
return languages.containsKey(name.toUpperCase());
}
public abstract Pattern getPattern(LanguageElement element);
public abstract Set<Character> getIndentationStarts();
public abstract Set<Character> getIndentationEnds();
public abstract String[] getKeywords();
public abstract List<Code> getCodeList();
public abstract String getName();
public void applyTheme(Context context, CodeView codeView, Theme theme) {
codeView.resetSyntaxPatternList();
codeView.resetHighlighter();
Resources resources = context.getResources();
// View Background
codeView.setBackgroundColor(resources.getColor(theme.getBackgroundColor(), null));
// Syntax Colors
for (LanguageElement e : Objects.requireNonNull(LanguageElement.class.getEnumConstants())) {
Pattern p = getPattern(e);
if (p != null) {
codeView.addSyntaxPattern(p, resources.getColor(theme.getColor(e), null));
}
}
// Default Color
codeView.setTextColor(resources.getColor(theme.getDefaultColor(), null));
codeView.reHighlightSyntax();
}
}

View File

@ -0,0 +1,20 @@
package org.mian.gitnex.helpers.codeeditor.languages;
/**
* @author qwerty287
*/
public enum LanguageElement {
KEYWORD,
ATTRIBUTE,
BUILTIN,
NUMBER,
HEX,
OPERATION,
GENERIC,
ANNOTATION,
CHAR,
STRING,
SINGLE_LINE_COMMENT,
TODO_COMMENT,
MULTI_LINE_COMMENT
}

View File

@ -1,31 +1,17 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import android.content.Context;
import android.content.res.Resources;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import com.amrdeveloper.codeview.Keyword;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import org.mian.gitnex.R;
/**
* @author M M Arif
*/
public class PhpLanguage {
// Language Keywords
private static final Pattern PATTERN_KEYWORDS =
Pattern.compile(
"\\b(<?php|__construct|var_dump|define|echo|var|float|"
+ "int|bool|false|true|function|private|public|protected|interface|return|copy|struct|abstract|extends|"
+ "trait|static|namespace|implements|__set|__get|unlink|this|try|catch|Throwable|Exception|pdo|"
+ "str_replace|form|date|abs|min|max|strtotime|mktime|"
+ "foreach|require_once|include_once|hash|array|range|break|continue|preg_match|preg_match_all|preg_replace|"
+ "throw|new|and|or|if|else|elseif|switch|case|default|match|require|include|goto|do|while|for|map|)\\b");
public class PhpLanguage extends Language {
// Brackets and Colons
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
@ -35,74 +21,16 @@ public class PhpLanguage {
private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']");
private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]");
private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("(//|#)[^\\n]*");
private static final Pattern PATTERN_MULTI_LINE_COMMENT =
Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+");
private static final Pattern PATTERN_TODO_COMMENT =
Pattern.compile("(//|#)\\s?(TODO|todo)\\s[^\\n]*");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("(?<=->)[a-zA-Z0-9_]+");
private static final Pattern PATTERN_OPERATION =
Pattern.compile(
":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*");
public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) {
codeView.resetSyntaxPatternList();
codeView.resetHighlighter();
Resources resources = context.getResources();
// View Background
codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null));
// Syntax Colors
codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(
PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(
PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(
PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(
PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(
PATTERN_SINGLE_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(
PATTERN_MULTI_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(
PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null));
codeView.addSyntaxPattern(
PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null));
// Default Color
codeView.setTextColor(resources.getColor(R.color.five_dark_white, null));
codeView.reHighlightSyntax();
}
public static String[] getKeywords(Context context) {
return context.getResources().getStringArray(R.array.php_keywords);
}
public static List<Code> getCodeList(Context context) {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
public static String getCommentStart() {
return "//";
}
@ -110,4 +38,146 @@ public class PhpLanguage {
public static String getCommentEnd() {
return "";
}
@Override
public Pattern getPattern(LanguageElement element) {
switch (element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case BUILTIN:
return PATTERN_BUILTINS;
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case HEX:
return PATTERN_HEX;
case SINGLE_LINE_COMMENT:
return PATTERN_SINGLE_LINE_COMMENT;
case MULTI_LINE_COMMENT:
return PATTERN_MULTI_LINE_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case OPERATION:
return PATTERN_OPERATION;
case TODO_COMMENT:
return PATTERN_TODO_COMMENT;
case ANNOTATION:
// TODO supported by PHP
case GENERIC:
default:
return null;
}
}
@Override
public String[] getKeywords() {
return new String[] {
"<?php",
"__construct",
"var_dump",
"define",
"echo",
"var",
"float",
"int",
"bool",
"false",
"true",
"function",
"private",
"public",
"protected",
"interface",
"return",
"copy",
"struct",
"abstract",
"extends",
"trait",
"static",
"namespace",
"implements",
"__set",
"__get",
"unlink",
"this",
"try",
"catch",
"Throwable",
"Exception",
"pdo",
"throw",
"new",
"and",
"or",
"if",
"else",
"elseif",
"switch",
"case",
"default",
"match",
"require",
"include",
"require_once",
"include_once",
"goto",
"do",
"while",
"for",
"foreach",
"map",
"hash",
"array",
"range",
"break",
"continue",
"preg_match",
"preg_match_all",
"preg_replace",
"str_replace",
"form",
"date",
"abs",
"min",
"max",
"strtotime",
"mktime",
"use",
"enum",
"class"
};
}
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords();
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
@Override
public String getName() {
return "PHP";
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
}

View File

@ -1,30 +1,18 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import android.content.Context;
import android.content.res.Resources;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import com.amrdeveloper.codeview.Keyword;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import org.mian.gitnex.R;
/**
* @author AmrDeveloper
* @author M M Arif
*/
public class PythonLanguage {
// Language Keywords
private static final Pattern PATTERN_KEYWORDS =
Pattern.compile(
"\\b(False|await|else|import|pass|None|break|except|in|raise"
+ "|True|class|finally|is|return|and|continue|for|lambda"
+ "|try|as|def|from|nonlocal|while|assert|del|global|not"
+ "|with|async|elif|if|or|yield)\\b");
public class PythonLanguage extends Language {
// Brackets and Colons
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
@ -34,70 +22,14 @@ public class PythonLanguage {
private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']");
private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]");
private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+");
private static final Pattern PATTERN_TODO_COMMENT = Pattern.compile("#TODO[^\n]*");
private static final Pattern PATTERN_TODO_COMMENT =
Pattern.compile("#\\s?(TODO|todo)\\s[^\n]*");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+");
private static final Pattern PATTERN_OPERATION =
Pattern.compile(
":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*");
private static final Pattern PATTERN_HASH_COMMENT = Pattern.compile("#(?!TODO )[^\\n]*");
public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) {
codeView.resetSyntaxPatternList();
codeView.resetHighlighter();
Resources resources = context.getResources();
// View Background
codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null));
// Syntax Colors
codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(
PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(
PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(
PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(
PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(
PATTERN_HASH_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(
PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null));
codeView.addSyntaxPattern(
PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null));
// Default Color
codeView.setTextColor(resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(PATTERN_TODO_COMMENT, resources.getColor(R.color.gold, null));
codeView.reHighlightSyntax();
}
public static String[] getKeywords(Context context) {
return context.getResources().getStringArray(R.array.python_keywords);
}
public static List<Code> getCodeList(Context context) {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add(':');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
return new HashSet<>();
}
private static final Pattern PATTERN_ANNOTATION = Pattern.compile("@.[a-zA-Z0-9_]+");
public static String getCommentStart() {
return "#";
@ -106,4 +38,105 @@ public class PythonLanguage {
public static String getCommentEnd() {
return "";
}
@Override
public Pattern getPattern(LanguageElement element) {
switch (element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case BUILTIN:
return PATTERN_BUILTINS;
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case HEX:
return PATTERN_HEX;
case SINGLE_LINE_COMMENT:
return PATTERN_HASH_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case OPERATION:
return PATTERN_OPERATION;
case TODO_COMMENT:
return PATTERN_TODO_COMMENT;
case ANNOTATION:
return PATTERN_ANNOTATION;
case GENERIC:
case MULTI_LINE_COMMENT:
default:
return null;
}
}
@Override
public String[] getKeywords() {
return new String[] {
"False",
"await",
"else",
"import",
"pass",
"None",
"break",
"except",
"in",
"raise",
"True",
"class",
"finally",
"is",
"return",
"and",
"continue",
"for",
"lambda",
"try",
"as",
"def",
"from",
"nonlocal",
"while",
"assert",
"del",
"global",
"not",
"with",
"async",
"elif",
"if",
"or",
"yield",
};
}
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords();
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
@Override
public String getName() {
return "Python";
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add(':');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
return new HashSet<>();
}
}

View File

@ -0,0 +1,21 @@
package org.mian.gitnex.helpers.codeeditor.languages;
/**
* @author qwerty287
*/
public class TypeScriptLanguage extends JavaScriptLanguage {
@Override
public String[] getKeywords() {
String[] js = super.getKeywords();
String[] tsAdditions = {"declare", "module"};
String[] ts = new String[js.length + tsAdditions.length];
System.arraycopy(js, 0, ts, 0, js.length);
System.arraycopy(tsAdditions, 0, ts, js.length, tsAdditions.length);
return ts;
}
@Override
public String getName() {
return "TypeScript";
}
}

View File

@ -0,0 +1,43 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import com.amrdeveloper.codeview.Code;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
/**
* @author qwerty287
*/
public class UnknownLanguage extends Language {
@Override
public Pattern getPattern(LanguageElement element) {
return null;
}
@Override
public Set<Character> getIndentationStarts() {
return Set.of();
}
@Override
public Set<Character> getIndentationEnds() {
return Set.of();
}
@Override
public String[] getKeywords() {
return new String[0];
}
@Override
public List<Code> getCodeList() {
return new ArrayList<>();
}
@Override
public String getName() {
return "Unknown";
}
}

View File

@ -1,25 +1,17 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import android.content.Context;
import android.content.res.Resources;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import com.amrdeveloper.codeview.Keyword;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import org.mian.gitnex.R;
/**
* @author M M Arif
*/
public class XmlLanguage {
// Language Keywords
private static final Pattern PATTERN_KEYWORDS =
Pattern.compile("\\b(<xml|version|encoding)\\b");
public class XmlLanguage extends Language {
// Brackets and Colons
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
@ -29,79 +21,83 @@ public class XmlLanguage {
private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']");
private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]");
private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*");
private static final Pattern PATTERN_MULTI_LINE_COMMENT =
Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("<!--.*-->");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+");
private static final Pattern PATTERN_OPERATION =
Pattern.compile(
":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*");
public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) {
codeView.resetSyntaxPatternList();
codeView.resetHighlighter();
Resources resources = context.getResources();
// View Background
codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null));
// Syntax Colors
codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(
PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(
PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(
PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(
PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(
PATTERN_SINGLE_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(
PATTERN_MULTI_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(
PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null));
codeView.addSyntaxPattern(
PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null));
// Default Color
codeView.setTextColor(resources.getColor(R.color.five_dark_white, null));
codeView.reHighlightSyntax();
public static String getCommentStart() {
return "<!--";
}
public static String[] getKeywords(Context context) {
return context.getResources().getStringArray(R.array.xml_keywords);
public static String getCommentEnd() {
return "-->";
}
public static List<Code> getCodeList(Context context) {
@Override
public Pattern getPattern(LanguageElement element) {
switch (element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case BUILTIN:
return PATTERN_BUILTINS;
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case HEX:
return PATTERN_HEX;
case SINGLE_LINE_COMMENT:
case MULTI_LINE_COMMENT:
return PATTERN_SINGLE_LINE_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case OPERATION:
return PATTERN_OPERATION;
case GENERIC:
case TODO_COMMENT:
case ANNOTATION:
default:
return null;
}
}
@Override
public String[] getKeywords() {
return new String[] {
"<xml", "encoding", "version",
};
}
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
String[] keywords = getKeywords();
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
@Override
public String getName() {
return "XML";
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
public static String getCommentStart() {
return "//";
}
public static String getCommentEnd() {
return "";
}
}

View File

@ -0,0 +1,47 @@
package org.mian.gitnex.helpers.codeeditor.markwon;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.MarkwonConfiguration;
import io.noties.markwon.core.MarkwonTheme;
import org.mian.gitnex.helpers.codeeditor.theme.Theme;
/**
* @author qwerty287
*/
public class MarkwonHighlighter extends AbstractMarkwonPlugin {
private final Theme theme;
private final Context context;
private final String fallbackLanguage;
public MarkwonHighlighter(
Context context, @NonNull Theme theme, @Nullable String fallbackLanguage) {
this.theme = theme;
this.context = context;
this.fallbackLanguage = fallbackLanguage;
}
@NonNull public static MarkwonHighlighter create(Context context, @NonNull Theme theme) {
return create(context, theme, null);
}
@NonNull public static MarkwonHighlighter create(
Context context, @NonNull Theme theme, @Nullable String fallbackLanguage) {
return new MarkwonHighlighter(context, theme, fallbackLanguage);
}
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder.codeTextColor(context.getResources().getColor(theme.getDefaultColor(), null))
.codeBackgroundColor(
context.getResources().getColor(theme.getBackgroundColor(), null));
}
@Override
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
builder.syntaxHighlight(SyntaxHighlighter.create(context, theme, fallbackLanguage));
}
}

View File

@ -0,0 +1,77 @@
package org.mian.gitnex.helpers.codeeditor.markwon;
import android.content.Context;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.noties.markwon.syntax.SyntaxHighlight;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.mian.gitnex.core.MainGrammarLocator;
import org.mian.gitnex.helpers.codeeditor.languages.Language;
import org.mian.gitnex.helpers.codeeditor.languages.LanguageElement;
import org.mian.gitnex.helpers.codeeditor.theme.Theme;
/**
* @author qwerty287
*/
public class SyntaxHighlighter implements SyntaxHighlight {
private final Theme theme;
private final Context context;
private final String fallback;
protected SyntaxHighlighter(Context context, @NonNull Theme theme, @Nullable String fallback) {
this.context = context;
this.theme = theme;
this.fallback = fallback;
}
@NonNull public static SyntaxHighlighter create(Context context, @NonNull Theme theme) {
return new SyntaxHighlighter(context, theme, null);
}
@NonNull public static SyntaxHighlighter create(
Context context, @NonNull Theme theme, @Nullable String fallback) {
return new SyntaxHighlighter(context, theme, fallback);
}
@NonNull @Override
public CharSequence highlight(@Nullable String info, @NonNull String code) {
if (code.isEmpty()) {
return code;
}
if (info == null) {
info = fallback;
}
if (info != null) {
info = MainGrammarLocator.fromExtension(info);
}
Editable highlightedCode = new SpannableStringBuilder(code);
Language l = Language.fromName(info);
for (LanguageElement e : Objects.requireNonNull(LanguageElement.class.getEnumConstants())) {
Pattern p = l.getPattern(e);
if (p != null) {
Matcher matcher = p.matcher(highlightedCode);
while (matcher.find()) {
highlightedCode.setSpan(
new ForegroundColorSpan(
context.getResources().getColor(theme.getColor(e), null)),
matcher.start(),
matcher.end(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
return highlightedCode;
}
}

View File

@ -0,0 +1,51 @@
package org.mian.gitnex.helpers.codeeditor.theme;
import androidx.annotation.ColorRes;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.codeeditor.languages.LanguageElement;
/**
* @author qwerty287
* @author M M Arif
*/
public class FiveColorsDarkTheme implements Theme {
@Override
@ColorRes
public int getColor(LanguageElement element) {
switch (element) {
case HEX:
case NUMBER:
case KEYWORD:
case OPERATION:
case GENERIC:
return R.color.five_dark_purple;
case CHAR:
case STRING:
return R.color.five_dark_yellow;
case BUILTIN:
return R.color.five_dark_white;
case SINGLE_LINE_COMMENT:
case MULTI_LINE_COMMENT:
return R.color.five_dark_grey;
case ATTRIBUTE:
case TODO_COMMENT:
case ANNOTATION:
return R.color.five_dark_blue;
default:
return R.color.five_dark_white;
}
}
@Override
@ColorRes
public int getDefaultColor() {
return R.color.five_dark_white;
}
@Override
@ColorRes
public int getBackgroundColor() {
return R.color.five_dark_black;
}
}

View File

@ -0,0 +1,51 @@
package org.mian.gitnex.helpers.codeeditor.theme;
import androidx.annotation.ColorRes;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.codeeditor.languages.LanguageElement;
/**
* @author qwerty287
* @author M M Arif
*/
public class FiveColorsTheme implements Theme {
@Override
@ColorRes
public int getColor(LanguageElement element) {
switch (element) {
case HEX:
case NUMBER:
case KEYWORD:
case OPERATION:
case GENERIC:
return R.color.five_dark_purple;
case CHAR:
case STRING:
return R.color.five_yellow;
case BUILTIN:
return R.color.five_dark_black;
case SINGLE_LINE_COMMENT:
case MULTI_LINE_COMMENT:
return R.color.five_dark_grey;
case ATTRIBUTE:
case TODO_COMMENT:
case ANNOTATION:
return R.color.five_dark_blue;
default:
return R.color.five_dark_black;
}
}
@Override
@ColorRes
public int getDefaultColor() {
return R.color.five_dark_black;
}
@Override
@ColorRes
public int getBackgroundColor() {
return R.color.five_background_grey;
}
}

View File

@ -0,0 +1,32 @@
package org.mian.gitnex.helpers.codeeditor.theme;
import android.content.Context;
import androidx.annotation.ColorRes;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.codeeditor.languages.LanguageElement;
/**
* @author qwerty287
*/
public interface Theme {
FiveColorsTheme FIVE_COLORS = new FiveColorsTheme();
FiveColorsDarkTheme FIVE_COLORS_DARK = new FiveColorsDarkTheme();
static Theme getDefaultTheme(Context context) {
return AppUtil.getColorFromAttribute(context, R.attr.isDark) == 1
? FIVE_COLORS_DARK
: FIVE_COLORS;
}
@ColorRes
int getColor(LanguageElement element);
@ColorRes
int getDefaultColor();
@ColorRes
int getBackgroundColor();
}

View File

@ -16,21 +16,17 @@ import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import de.qwerty287.markwonprism4j.Prism4jSyntaxHighlight;
import de.qwerty287.markwonprism4j.Prism4jTheme;
import de.qwerty287.markwonprism4j.Prism4jThemeDarkula;
import de.qwerty287.markwonprism4j.Prism4jThemeDefault;
import io.noties.prism4j.Prism4j;
import org.mian.gitnex.R;
import org.mian.gitnex.core.MainGrammarLocator;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.codeeditor.markwon.SyntaxHighlighter;
import org.mian.gitnex.helpers.codeeditor.theme.Theme;
/**
* @author opyale
*/
public class SyntaxHighlightedArea extends LinearLayout {
private Prism4jTheme prism4jTheme;
private Theme theme;
private TextView sourceView;
private LinesView linesView;
@ -53,10 +49,7 @@ public class SyntaxHighlightedArea extends LinearLayout {
public void setup() {
prism4jTheme =
AppUtil.getColorFromAttribute(getContext(), R.attr.isDark) == 1
? Prism4jThemeDarkula.create()
: Prism4jThemeDefault.create();
theme = Theme.getDefaultTheme(getContext());
sourceView = new TextView(getContext());
@ -67,7 +60,8 @@ public class SyntaxHighlightedArea extends LinearLayout {
Typeface.createFromAsset(
getContext().getAssets(), "fonts/sourcecodeproregular.ttf"));
sourceView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
sourceView.setTextColor(prism4jTheme.textColor());
sourceView.setTextColor(
getContext().getResources().getColor(theme.getDefaultColor(), null));
sourceView.setTextIsSelectable(true);
int padding = AppUtil.getPixelsFromDensity(getContext(), 5);
@ -93,12 +87,13 @@ public class SyntaxHighlightedArea extends LinearLayout {
linesView.getPaint().setTypeface(sourceView.getTypeface());
linesView.getPaint().setTextSize(sourceView.getTextSize());
linesView.setBackgroundColor(prism4jTheme.background());
linesView.setTextColor(prism4jTheme.textColor());
linesView.setLineColor(prism4jTheme.textColor());
linesView.setBackgroundColor(
getContext().getResources().getColor(theme.getBackgroundColor(), null));
linesView.setTextColor(getContext().getResources().getColor(theme.getDefaultColor(), null));
linesView.setLineColor(getContext().getResources().getColor(theme.getDefaultColor(), null));
setOrientation(HORIZONTAL);
setBackgroundColor(prism4jTheme.background());
setBackgroundColor(getContext().getResources().getColor(theme.getBackgroundColor(), null));
addView(linesView);
addView(horizontalScrollView);
}
@ -112,18 +107,16 @@ public class SyntaxHighlightedArea extends LinearLayout {
() -> {
try {
MainGrammarLocator mainGrammarLocator =
MainGrammarLocator.getInstance();
CharSequence highlightedSource =
Prism4jSyntaxHighlight.create(
new Prism4j(mainGrammarLocator),
prism4jTheme,
SyntaxHighlighter.create(
getContext(),
theme,
MainGrammarLocator
.DEFAULT_FALLBACK_LANGUAGE)
.highlight(
mainGrammarLocator.fromExtension(
extension),
MainGrammarLocator.fromExtension(
extension)
.toUpperCase(),
source);
getActivity()

View File

@ -74,4 +74,6 @@
<color name="five_dark_grey">#a9b1ae</color>
<color name="five_dark_white">#ffffff</color>
<color name="gold">#e6b121</color>
<color name="five_yellow">#fdc92f</color>
<color name="five_background_grey">#f5f2f0</color>
</resources>

View File

@ -1,304 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--HTML Keywords List-->
<string-array name="html_keywords">
<item><![CDATA[<html]]></item>
<item><![CDATA[<DOCTYPE]]></item>
<item><![CDATA[<head]]></item>
<item><![CDATA[<title]]></item>
<item><![CDATA[<body]]></item>
<item><![CDATA[<h1]]></item>
<item><![CDATA[<h2]]></item>
<item><![CDATA[<h3]]></item>
<item><![CDATA[<h4]]></item>
<item><![CDATA[<h5]]></item>
<item><![CDATA[<h6]]></item>
<item><![CDATA[<br]]></item>
<item><![CDATA[<hr]]></item>
<item><![CDATA[<section]]></item>
<item><![CDATA[<header]]></item>
<item><![CDATA[<footer]]></item>
<item><![CDATA[<select]]></item>
<item><![CDATA[<img]]></item>
<item><![CDATA[<embed]]></item>
<item><![CDATA[<iframe]]></item>
<item><![CDATA[<style]]></item>
<item><![CDATA[<script]]></item>
<item><![CDATA[<div]]></item>
<item><![CDATA[<p]]></item>
<item>code</item>
<item>strong</item>
<item>small</item>
<item>template</item>
<item>form</item>
<item>input</item>
<item>textarea</item>
<item>button</item>
<item>option</item>
<item>label</item>
<item>fieldset</item>
<item>legend</item>
<item>datalist</item>
<item>frame</item>
<item>map</item>
<item>area</item>
<item>canvas</item>
<item>picture</item>
<item>svg</item>
<item>audio</item>
<item>source</item>
<item>track</item>
<item>video</item>
<item>link</item>
<item>nav</item>
<item>ul</item>
<item>ol</item>
<item>li</item>
<item>table</item>
<item>caption</item>
<item>th</item>
<item>tr</item>
<item>td</item>
<item>thead</item>
<item>tbody</item>
<item>tfooter</item>
<item>col</item>
<item>span</item>
<item>main</item>
<item>article</item>
<item>aside</item>
<item>meta</item>
<item>base</item>
<item>noscript</item>
<item>object</item>
<item>param</item>
<item>src</item>
<item>href</item>
</string-array>
<!--XML Keywords List-->
<string-array name="xml_keywords">
<item><![CDATA[<xml]]></item>
<item>encoding</item>
<item>version</item>
</string-array>
<!--PHP Keywords List-->
<string-array name="php_keywords">
<item><![CDATA[<?php]]></item>
<item>__construct</item>
<item>var_dump</item>
<item>define</item>
<item>echo</item>
<item>var</item>
<item>float</item>
<item>int</item>
<item>bool</item>
<item>false</item>
<item>true</item>
<item>function</item>
<item>private</item>
<item>public</item>
<item>protected</item>
<item>interface</item>
<item>return</item>
<item>copy</item>
<item>struct</item>
<item>abstract</item>
<item>extends</item>
<item>trait</item>
<item>static</item>
<item>namespace</item>
<item>implements</item>
<item>__set</item>
<item>__get</item>
<item>unlink</item>
<item>this</item>
<item>try</item>
<item>catch</item>
<item>Throwable</item>
<item>Exception</item>
<item>pdo</item>
<item>throw</item>
<item>new</item>
<item>and</item>
<item>or</item>
<item>if</item>
<item>else</item>
<item>elseif</item>
<item>switch</item>
<item>case</item>
<item>default</item>
<item>match</item>
<item>require</item>
<item>include</item>
<item>require_once</item>
<item>include_once</item>
<item>goto</item>
<item>do</item>
<item>while</item>
<item>for</item>
<item>foreach</item>
<item>map</item>
<item>hash</item>
<item>array</item>
<item>range</item>
<item>break</item>
<item>continue</item>
<item>preg_match</item>
<item>preg_match_all</item>
<item>preg_replace</item>
<item>str_replace</item>
<item>form</item>
<item>date</item>
<item>abs</item>
<item>min</item>
<item>max</item>
<item>strtotime</item>
<item>mktime</item>
</string-array>
<!--Java Keywords List-->
<string-array name="java_keywords">
<item>public</item>
<item>private</item>
<item>protected</item>
<item>package</item>
<item>abstract</item>
<item>boolean</item>
<item>break</item>
<item>byte</item>
<item>case</item>
<item>catch</item>
<item>char</item>
<item>class</item>
<item>continue</item>
<item>default</item>
<item>do</item>
<item>double</item>
<item>else</item>
<item>enum</item>
<item>extends</item>
<item>final</item>
<item>finally</item>
<item>float</item>
<item>for</item>
<item>if</item>
<item>implements</item>
<item>import</item>
<item>instanceof</item>
<item>int</item>
<item>interface</item>
<item>long</item>
<item>native</item>
<item>new</item>
<item>return</item>
<item>short</item>
<item>static</item>
<item>strictfp</item>
<item>super</item>
<item>switch</item>
<item>synchronized</item>
<item>this</item>
<item>throw</item>
<item>transient</item>
<item>try</item>
<item>void</item>
<item>volatile</item>
<item>while</item>
</string-array>
<!--GoLang Keywords List-->
<string-array name="go_keywords">
<item>break</item>
<item>default</item>
<item>func</item>
<item>interface</item>
<item>select</item>
<item>case</item>
<item>defer</item>
<item>go</item>
<item>map</item>
<item>struct</item>
<item>chan</item>
<item>else</item>
<item>goto</item>
<item>package</item>
<item>switch</item>
<item>const</item>
<item>fallthrough</item>
<item>if</item>
<item>bool</item>
<item>byte</item>
<item>cap</item>
<item>close</item>
<item>complex</item>
<item>complex64</item>
<item>complex128</item>
<item>uint16</item>
<item>copy</item>
<item>false</item>
<item>float32</item>
<item>float64</item>
<item>imag</item>
<item>int</item>
<item>int8</item>
<item>int16</item>
<item>uint32</item>
<item>int32</item>
<item>int64</item>
<item>len</item>
<item>make</item>
<item>new</item>
<item>nil</item>
<item>uint64</item>
<item>range</item>
<item>type</item>
<item>continue</item>
<item>for</item>
<item>import</item>
<item>return</item>
<item>var</item>
</string-array>
<!--Python Keywords List-->
<string-array name="python_keywords">
<item>False</item>
<item>await</item>
<item>else</item>
<item>import</item>
<item>pass</item>
<item>None</item>
<item>break</item>
<item>except</item>
<item>in</item>
<item>raise</item>
<item>True</item>
<item>class</item>
<item>finally</item>
<item>is</item>
<item>return</item>
<item>and</item>
<item>continue</item>
<item>for</item>
<item>lambda</item>
<item>try</item>
<item>as</item>
<item>def</item>
<item>from</item>
<item>nonlocal</item>
<item>while</item>
<item>assert</item>
<item>del</item>
<item>global</item>
<item>not</item>
<item>with</item>
<item>async</item>
<item>elif</item>
<item>if</item>
<item>or</item>
<item>yield</item>
</string-array>
</resources>