From 84ab4d481ce56991a6635e87c5f000b056411087 Mon Sep 17 00:00:00 2001
From: hyb1996 <946994919@qq.com>
Date: Mon, 26 Feb 2018 19:52:47 +0800
Subject: [PATCH] chore: find and replace
---
app/build.gradle | 4 +-
.../ui/edit/editor/CodeEditor.java | 94 ++++++++++++-------
app/src/main/res/values/strings.xml | 1 +
.../java/com/stardust/util/TextUtils.java | 91 ++++++++++++++++++
4 files changed, 155 insertions(+), 35 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index b5b9b046..d010d142 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -8,8 +8,8 @@ android {
applicationId "com.stardust.scriptdroid"
minSdkVersion 17
targetSdkVersion 23
- versionCode 254
- versionName "3.1.0 Alpha4"
+ versionCode 255
+ versionName "3.1.0 Alpha5"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
ndk {
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditor.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditor.java
index b298062c..0637399f 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditor.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditor.java
@@ -4,12 +4,15 @@ import android.content.Context;
import android.graphics.Canvas;
import android.support.design.widget.Snackbar;
import android.util.AttributeSet;
+import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
+import com.android.dx.util.IntList;
import com.stardust.autojs.script.JsBeautifier;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.ui.edit.theme.Theme;
import com.stardust.util.ClipboardUtil;
+import com.stardust.util.TextUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -43,9 +46,6 @@ public class CodeEditor extends HVScrollView {
}
- private CharSequence mReplacement = "";
- private String mKeywords;
- private int mFoundIndex = -1;
private CodeEditText mCodeEditText;
private TextViewRedoUndo mTextViewRedoUndo;
private JavaScriptHighlighter mJavaScriptHighlighter;
@@ -53,6 +53,12 @@ public class CodeEditor extends HVScrollView {
private JsBeautifier mJsBeautifier;
private MaterialDialog mProcessDialog;
+
+ private CharSequence mReplacement = "";
+ private String mKeywords;
+ private Matcher mMatcher;
+ private int mFoundIndex = -1;
+
public CodeEditor(Context context) {
super(context);
init();
@@ -206,23 +212,68 @@ public class CodeEditor extends HVScrollView {
mTextViewRedoUndo.redo();
}
+ public void find(String keywords, boolean usingRegex) {
+ if (usingRegex) {
+ mMatcher = Pattern.compile(keywords).matcher(mCodeEditText.getText());
+ mKeywords = null;
+ } else {
+ mKeywords = keywords;
+ mMatcher = null;
+ }
+ findNext();
+ }
+
+ public void replace(String keywords, String replacement, boolean usingRegex) {
+ mReplacement = replacement == null ? "" : replacement;
+ find(keywords, usingRegex);
+ }
+
+ public void replaceAll(String keywords, String replacement, boolean usingRegex) {
+ if (!usingRegex) {
+ keywords = Pattern.quote(keywords);
+ }
+ String text = mCodeEditText.getText().toString();
+ text = text.replaceAll(keywords, replacement);
+ setText(text);
+ }
public void findNext() {
- Matcher matcher = Pattern.compile(mKeywords).matcher(mCodeEditText.getText());
- if (!matcher.find(mFoundIndex + 1)) {
- return;
+ int foundIndex;
+ if (mMatcher == null) {
+ if (mKeywords == null)
+ return;
+ foundIndex = TextUtils.indexOf(mCodeEditText.getText(), mKeywords, mFoundIndex + 1);
+ if (foundIndex >= 0)
+ mCodeEditText.setSelection(foundIndex, foundIndex + mKeywords.length());
+ } else if (mMatcher.find(mFoundIndex + 1)) {
+ foundIndex = mMatcher.start();
+ mCodeEditText.setSelection(foundIndex, foundIndex + mMatcher.group().length());
+ } else {
+ foundIndex = -1;
+ }
+ if (foundIndex < 0 && mFoundIndex >= 0) {
+ mFoundIndex = -1;
+ findNext();
+ } else {
+ mFoundIndex = foundIndex;
}
- mFoundIndex = matcher.start();
- mCodeEditText.setSelection(mFoundIndex, mFoundIndex + mKeywords.length());
}
public void findPrev() {
- // FIXME: 2018/2/21 lastIndexOf不支持正则
+ if (mMatcher != null){
+ Toast.makeText(getContext(), R.string.error_regex_find_prev, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ int len = mCodeEditText.getText().length();
if (mFoundIndex <= 0) {
- mFoundIndex = mCodeEditText.getText().length();
+ mFoundIndex = len;
}
int index = mCodeEditText.getText().toString().lastIndexOf(mKeywords, mFoundIndex - 1);
if (index < 0) {
+ if (mFoundIndex != len) {
+ mFoundIndex = len;
+ findPrev();
+ }
return;
}
mFoundIndex = index;
@@ -250,29 +301,6 @@ public class CodeEditor extends HVScrollView {
});
}
- public void find(String keywords, boolean usingRegex) {
- if (usingRegex) {
- mKeywords = keywords;
- } else {
- mKeywords = Pattern.quote(keywords);
- }
- mFoundIndex = -1;
- findNext();
- }
-
- public void replace(String keywords, String replacement, boolean usingRegex) {
- mReplacement = replacement == null ? "" : replacement;
- find(keywords, usingRegex);
- }
-
- public void replaceAll(String keywords, String replacement, boolean usingRegex) {
- if (!usingRegex) {
- keywords = Pattern.quote(keywords);
- }
- String text = mCodeEditText.getText().toString();
- text = text.replaceAll(keywords, replacement);
- setText(text);
- }
public void insert(String insertText) {
int selection = Math.max(mCodeEditText.getSelectionStart(), 0);
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index f2714bf7..aae36b5e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -348,4 +348,5 @@
字体大小
预览
字体大小: %d
+ 正则表达式不能向前查找
diff --git a/common/src/main/java/com/stardust/util/TextUtils.java b/common/src/main/java/com/stardust/util/TextUtils.java
index 644f085d..c077ec87 100644
--- a/common/src/main/java/com/stardust/util/TextUtils.java
+++ b/common/src/main/java/com/stardust/util/TextUtils.java
@@ -55,4 +55,95 @@ public class TextUtils {
}
return -1;
}
+
+ public static int indexOf(CharSequence source,
+ CharSequence target,
+ int fromIndex) {
+ if (source instanceof String && target instanceof String) {
+ return ((String) source).indexOf((String) target);
+ }
+ if (fromIndex >= source.length()) {
+ return (target.length() == 0 ? source.length() : -1);
+ }
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ }
+ if (target.length() == 0) {
+ return fromIndex;
+ }
+
+ char first = target.charAt(0);
+ int max = (source.length() - target.length());
+
+ for (int i = fromIndex; i <= max; i++) {
+ /* Look for first character. */
+ if (source.charAt(i) != first) {
+ while (++i <= max && source.charAt(i) != first) ;
+ }
+
+ /* Found first character, now look at the rest of v2 */
+ if (i <= max) {
+ int j = i + 1;
+ int end = j + target.length() - 1;
+ for (int k = 1; j < end && source.charAt(j)
+ == target.charAt(k); j++, k++)
+ ;
+
+ if (j == end) {
+ /* Found whole string. */
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public static int lastIndexOf(CharSequence source,
+ CharSequence target,
+ int fromIndex) {
+ if (source instanceof String && target instanceof String) {
+ return ((String) source).lastIndexOf((String) target);
+ }
+ /*
+ * Check arguments; return immediately where possible. For
+ * consistency, don't check for null str.
+ */
+ int rightIndex = source.length() - target.length();
+ if (fromIndex < 0) {
+ return -1;
+ }
+ if (fromIndex > rightIndex) {
+ fromIndex = rightIndex;
+ }
+ /* Empty string always matches. */
+ if (target.length() == 0) {
+ return fromIndex;
+ }
+
+ int strLastIndex = target.length() - 1;
+ char strLastChar = target.charAt(strLastIndex);
+ int min = target.length() - 1;
+ int i = min + fromIndex;
+
+ startSearchForLastChar:
+ while (true) {
+ while (i >= min && source.charAt(i) != strLastChar) {
+ i--;
+ }
+ if (i < min) {
+ return -1;
+ }
+ int j = i - 1;
+ int start = j - (target.length() - 1);
+ int k = strLastIndex - 1;
+
+ while (j > start) {
+ if (source.charAt(j--) != target.charAt(k--)) {
+ i--;
+ continue startSearchForLastChar;
+ }
+ }
+ return start + 1;
+ }
+ }
}
\ No newline at end of file