mirror of
https://github.com/TonyJiangWJ/Auto.js.git
synced 2026-06-21 21:01:43 +08:00
feat: brackets matching
This commit is contained in:
parent
445bcfa462
commit
3b2aac78fd
@ -11,7 +11,18 @@
|
||||
},
|
||||
"tokenColors": [
|
||||
{
|
||||
"scope": [
|
||||
"scope": "bracket.matched",
|
||||
"settings": {
|
||||
"foreground": "#76ff03"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "error",
|
||||
"settings": {
|
||||
"foreground": "#f44336"
|
||||
}
|
||||
},
|
||||
{ "scope": [
|
||||
"meta.embedded",
|
||||
"source.groovy.embedded"
|
||||
],
|
||||
|
||||
@ -7,6 +7,18 @@
|
||||
"foreground": "#333333"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "bracket.matched",
|
||||
"settings": {
|
||||
"foreground": "#76ff03"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "error",
|
||||
"settings": {
|
||||
"foreground": "#f44336"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"meta.embedded",
|
||||
@ -487,7 +499,6 @@
|
||||
"editor.background": "#F5F5F5",
|
||||
"editor.foreground": "#000000",
|
||||
"editor.lineHighlightBackground": "#E4F6D4",
|
||||
|
||||
"focusBorder": "#A6B39B",
|
||||
"pickerGroup.foreground": "#A6B39B",
|
||||
"pickerGroup.border": "#749351",
|
||||
|
||||
@ -46,4 +46,12 @@ public class TokenColor {
|
||||
public void setSettings(TokenColorSettings settings) {
|
||||
mSettings = settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TokenColor{" +
|
||||
"scope=" + mScope +
|
||||
", settings=" + mSettings.getForeground() +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,4 +32,6 @@ public class TokenColorSettings {
|
||||
public void setFontStyle(String fontStyle) {
|
||||
mFontStyle = fontStyle;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
package com.stardust.scriptdroid.ui.edit.editor;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2018/2/25.
|
||||
*/
|
||||
|
||||
public class BracketMatching {
|
||||
|
||||
public static int UNMATCHED_BRACKET = -2;
|
||||
public static int BRACKET_NOT_FOUND = -1;
|
||||
|
||||
|
||||
private static final char[] PAIR_LEFT = {'(', '{', '['};
|
||||
private static final char[] PAIR_RIGHT = {')', '}', ')'};
|
||||
|
||||
|
||||
public static int bracketMatching(CharSequence text, int index) {
|
||||
char ch = text.charAt(index);
|
||||
for (int i = 0; i < PAIR_LEFT.length; i++) {
|
||||
if (PAIR_LEFT[i] == ch) {
|
||||
return findRightBracket(text, index + 1, PAIR_LEFT[i], PAIR_RIGHT[i]);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < PAIR_RIGHT.length; i++) {
|
||||
if (PAIR_RIGHT[i] == ch) {
|
||||
return findLeftBracket(text, index - 1, PAIR_LEFT[i], PAIR_RIGHT[i]);
|
||||
}
|
||||
}
|
||||
return BRACKET_NOT_FOUND;
|
||||
}
|
||||
|
||||
public static int findLeftBracket(CharSequence text, int index, char left, char right) {
|
||||
int rightBracketCount = 0;
|
||||
for (int i = index; i >= 0; i--) {
|
||||
char ch = text.charAt(i);
|
||||
if (ch == left) {
|
||||
if (rightBracketCount == 0) {
|
||||
return i;
|
||||
}
|
||||
rightBracketCount--;
|
||||
} else if (ch == right) {
|
||||
rightBracketCount++;
|
||||
}
|
||||
}
|
||||
return UNMATCHED_BRACKET;
|
||||
}
|
||||
|
||||
public static int findRightBracket(CharSequence text, int index, char left, char right) {
|
||||
int leftBracketCount = 0;
|
||||
for (int i = index; i < text.length(); i++) {
|
||||
char ch = text.charAt(i);
|
||||
if (ch == left) {
|
||||
leftBracketCount++;
|
||||
} else if (ch == right) {
|
||||
if (leftBracketCount == 0) {
|
||||
return i;
|
||||
}
|
||||
leftBracketCount--;
|
||||
}
|
||||
}
|
||||
return BRACKET_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
@ -22,7 +22,6 @@ import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.support.v7.widget.AppCompatEditText;
|
||||
import android.text.Layout;
|
||||
import android.util.AttributeSet;
|
||||
@ -32,10 +31,12 @@ import android.view.Gravity;
|
||||
|
||||
import com.stardust.scriptdroid.BuildConfig;
|
||||
import com.stardust.scriptdroid.ui.edit.theme.Theme;
|
||||
import com.stardust.scriptdroid.ui.edit.theme.TokenMapping;
|
||||
import com.stardust.util.TextUtils;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import org.mozilla.javascript.Token;
|
||||
|
||||
import static com.stardust.scriptdroid.ui.edit.editor.BracketMatching.UNMATCHED_BRACKET;
|
||||
|
||||
/**
|
||||
* Created by Administrator on 2018/2/11.
|
||||
@ -56,6 +57,8 @@ public class CodeEditText extends AppCompatEditText {
|
||||
private TimingLogger mLogger = new TimingLogger(LOG_TAG, "draw");
|
||||
private Paint mLineHighlightPaint = new Paint();
|
||||
private int mFirstLineForDraw = -1, mLastLineForDraw;
|
||||
private int[] mMatchingBrackets = {-1, -1};
|
||||
private int mUnmatchedBracket = -1;
|
||||
|
||||
public CodeEditText(Context context) {
|
||||
super(context);
|
||||
@ -181,23 +184,31 @@ public class CodeEditText extends AppCompatEditText {
|
||||
int visibleCharStart = getVisibleCharIndex(paint, scrollX, lineStart, lineEnd);
|
||||
int visibleCharEnd = getVisibleCharIndex(paint, scrollX + mParentScrollView.getWidth(), lineStart, lineEnd) + 1;
|
||||
int previousColorPos = visibleCharStart;
|
||||
int previousColor = mHighlightTokens.getCharColor(previousColorPos);
|
||||
int previousColor = getCharColor(previousColorPos);
|
||||
if (DEBUG)
|
||||
Log.d(LOG_TAG, "draw line " + line + ": " + (visibleCharEnd - visibleCharStart));
|
||||
for (int i = visibleCharStart; i < visibleCharEnd && i < lineEnd; i++) {
|
||||
int i;
|
||||
for (i = visibleCharStart; i < visibleCharEnd; i++) {
|
||||
fontCount++;
|
||||
int color = mHighlightTokens.getCharColor(i);
|
||||
int color = getCharColor(i);
|
||||
if (previousColor != color) {
|
||||
drawText(canvas, paint, paddingLeft, lineBaseline, lineStart, previousColorPos, previousColorPos + fontCount, previousColor);
|
||||
drawText(canvas, paint, paddingLeft, lineBaseline, lineStart, previousColorPos, i, previousColor);
|
||||
previousColor = color;
|
||||
previousColorPos = i;
|
||||
fontCount = 1;
|
||||
}
|
||||
if (i == visibleCharEnd - 1) {
|
||||
drawText(canvas, paint, paddingLeft, lineBaseline, lineStart, previousColorPos, previousColorPos + fontCount, previousColor);
|
||||
}
|
||||
}
|
||||
drawText(canvas, paint, paddingLeft, lineBaseline, lineStart, previousColorPos, visibleCharEnd, previousColor);
|
||||
}
|
||||
|
||||
private int getCharColor(int i) {
|
||||
if (i == mUnmatchedBracket) {
|
||||
return mTheme.getColorForToken(Token.ERROR);
|
||||
}
|
||||
if (i == mMatchingBrackets[0] || i == mMatchingBrackets[1]) {
|
||||
return mTheme.getColorForToken(TokenMapping.TOKEN_MATCHED_BRACKET);
|
||||
}
|
||||
return mHighlightTokens.getCharColor(i);
|
||||
}
|
||||
|
||||
|
||||
@ -264,11 +275,39 @@ public class CodeEditText extends AppCompatEditText {
|
||||
return;
|
||||
}
|
||||
callCursorChangeCallback(getText(), selStart);
|
||||
checkParenthesesPairs(getText(), selStart);
|
||||
matchesBracket(getText(), selStart);
|
||||
}
|
||||
|
||||
private void checkParenthesesPairs(CharSequence text, int sel) {
|
||||
// TODO: 2018/2/24
|
||||
private void matchesBracket(CharSequence text, int cursor) {
|
||||
if (checkBracketMatchingAt(text, cursor)) {
|
||||
return;
|
||||
}
|
||||
if (checkBracketMatchingAt(text, cursor - 1)) {
|
||||
return;
|
||||
}
|
||||
mMatchingBrackets[0] = -1;
|
||||
mMatchingBrackets[1] = -1;
|
||||
mUnmatchedBracket = -1;
|
||||
}
|
||||
|
||||
private boolean checkBracketMatchingAt(CharSequence text, int cursor) {
|
||||
if (cursor < 0 || cursor >= text.length()) {
|
||||
return false;
|
||||
}
|
||||
int i = BracketMatching.bracketMatching(text, cursor);
|
||||
if (i >= 0) {
|
||||
mMatchingBrackets[0] = cursor;
|
||||
mMatchingBrackets[1] = i;
|
||||
mUnmatchedBracket = -1;
|
||||
return true;
|
||||
} else if (i == UNMATCHED_BRACKET) {
|
||||
mUnmatchedBracket = cursor;
|
||||
mMatchingBrackets[0] = -1;
|
||||
mMatchingBrackets[1] = -1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
private void callCursorChangeCallback(CharSequence text, int sel) {
|
||||
|
||||
@ -75,7 +75,7 @@ public class Theme {
|
||||
}
|
||||
|
||||
public static Theme getDefault(android.content.Context context) {
|
||||
return fromAssetsJson(context, "editor/theme/dark_plus.json");
|
||||
return fromAssetsJson(context, "editor/theme/light_plus.json");
|
||||
}
|
||||
|
||||
public static Theme fromJson(String json) {
|
||||
@ -140,4 +140,5 @@ public class Theme {
|
||||
return getName();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -15,6 +15,8 @@ import java.util.List;
|
||||
public class TokenMapping {
|
||||
|
||||
|
||||
public static final int TOKEN_MATCHED_BRACKET = Token.LAST_TOKEN + 1;
|
||||
|
||||
private static final List<Integer> KEYWORD = tokenNamesToTypes(Arrays.asList("return", "new", "delete", "typeof", "null", "this", "false", "true", "throw", "in", "instanceof", "yield", "try", "function", "if", "else", "switch", "case", "default", "while", "do", "for", "break", "continue", "var", "with", "catch", "finally", "void", "let", "const", "debugger"));
|
||||
private static final List<Integer> KEYWORD_CONTROL = tokenNamesToTypes(Arrays.asList("if", "else", "switch", "case", "break", "continue", "goto", "return", "try", "catch", "throw", "finally"));
|
||||
private static final List<Integer> KEYWORD_OPERATOR = Collections.emptyList();
|
||||
@ -29,13 +31,17 @@ public class TokenMapping {
|
||||
return KEYWORD_CONTROL;
|
||||
default:
|
||||
int token = tokenNameToType(scope);
|
||||
if (Token.isValidToken(token)) {
|
||||
if (isValidToken(token)) {
|
||||
return Collections.singletonList(token);
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public static boolean isValidToken(int token) {
|
||||
return token >= -1;
|
||||
}
|
||||
|
||||
public static int tokenNameToType(String name) {
|
||||
switch (name) {
|
||||
case "this.self":
|
||||
@ -46,6 +52,8 @@ public class TokenMapping {
|
||||
return Token.NAME;
|
||||
case "constant.numeric":
|
||||
return Token.NUMBER;
|
||||
case "bracket.matched":
|
||||
return TOKEN_MATCHED_BRACKET;
|
||||
|
||||
}
|
||||
for (int token = Token.ERROR; token < Token.LAST_TOKEN; token++) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user