chore: find and replace

This commit is contained in:
hyb1996
2018-02-26 19:52:47 +08:00
parent a3fd8f2423
commit 84ab4d481c
4 changed files with 155 additions and 35 deletions

View File

@@ -8,8 +8,8 @@ android {
applicationId "com.stardust.scriptdroid" applicationId "com.stardust.scriptdroid"
minSdkVersion 17 minSdkVersion 17
targetSdkVersion 23 targetSdkVersion 23
versionCode 254 versionCode 255
versionName "3.1.0 Alpha4" versionName "3.1.0 Alpha5"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true multiDexEnabled true
ndk { ndk {

View File

@@ -4,12 +4,15 @@ import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.MaterialDialog;
import com.android.dx.util.IntList;
import com.stardust.autojs.script.JsBeautifier; import com.stardust.autojs.script.JsBeautifier;
import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.ui.edit.theme.Theme; import com.stardust.scriptdroid.ui.edit.theme.Theme;
import com.stardust.util.ClipboardUtil; import com.stardust.util.ClipboardUtil;
import com.stardust.util.TextUtils;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; 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 CodeEditText mCodeEditText;
private TextViewRedoUndo mTextViewRedoUndo; private TextViewRedoUndo mTextViewRedoUndo;
private JavaScriptHighlighter mJavaScriptHighlighter; private JavaScriptHighlighter mJavaScriptHighlighter;
@@ -53,6 +53,12 @@ public class CodeEditor extends HVScrollView {
private JsBeautifier mJsBeautifier; private JsBeautifier mJsBeautifier;
private MaterialDialog mProcessDialog; private MaterialDialog mProcessDialog;
private CharSequence mReplacement = "";
private String mKeywords;
private Matcher mMatcher;
private int mFoundIndex = -1;
public CodeEditor(Context context) { public CodeEditor(Context context) {
super(context); super(context);
init(); init();
@@ -206,23 +212,68 @@ public class CodeEditor extends HVScrollView {
mTextViewRedoUndo.redo(); 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() { public void findNext() {
Matcher matcher = Pattern.compile(mKeywords).matcher(mCodeEditText.getText()); int foundIndex;
if (!matcher.find(mFoundIndex + 1)) { if (mMatcher == null) {
return; 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() { 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) { if (mFoundIndex <= 0) {
mFoundIndex = mCodeEditText.getText().length(); mFoundIndex = len;
} }
int index = mCodeEditText.getText().toString().lastIndexOf(mKeywords, mFoundIndex - 1); int index = mCodeEditText.getText().toString().lastIndexOf(mKeywords, mFoundIndex - 1);
if (index < 0) { if (index < 0) {
if (mFoundIndex != len) {
mFoundIndex = len;
findPrev();
}
return; return;
} }
mFoundIndex = index; 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) { public void insert(String insertText) {
int selection = Math.max(mCodeEditText.getSelectionStart(), 0); int selection = Math.max(mCodeEditText.getSelectionStart(), 0);

View File

@@ -348,4 +348,5 @@
<string name="text_text_size">字体大小</string> <string name="text_text_size">字体大小</string>
<string name="text_preview">预览</string> <string name="text_preview">预览</string>
<string name="text_size_current_value" formatted="true">字体大小: %d</string> <string name="text_size_current_value" formatted="true">字体大小: %d</string>
<string name="error_regex_find_prev">正则表达式不能向前查找</string>
</resources> </resources>

View File

@@ -55,4 +55,95 @@ public class TextUtils {
} }
return -1; 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;
}
}
} }