6.3.4 Alpha - 修复 VSCode 插件保存文件丢失扩展名
This commit is contained in:
@@ -88,7 +88,7 @@ class Loopers(runtime: ScriptRuntime) : IdleHandler {
|
||||
if (mTimers.hasPendingCallbacks()) {
|
||||
return false
|
||||
}
|
||||
if (waitWhenIdle.get() || !waitIds.get().isEmpty()) {
|
||||
if (waitWhenIdle.get() == true || waitIds.get()?.isNotEmpty() == true) {
|
||||
return false
|
||||
}
|
||||
if ((Context.getCurrentContext() as AutoJsContext).hasPendingContinuation()) {
|
||||
@@ -104,11 +104,13 @@ class Loopers(runtime: ScriptRuntime) : IdleHandler {
|
||||
}
|
||||
|
||||
private fun initServantThread() {
|
||||
val lock = this@Loopers as Object
|
||||
ThreadCompat {
|
||||
Looper.prepare()
|
||||
mServantLooper = Looper.myLooper()
|
||||
synchronized(lock) { lock.notifyAll() }
|
||||
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
||||
synchronized(this@Loopers as Object) {
|
||||
notifyAll()
|
||||
}
|
||||
Looper.loop()
|
||||
}.start()
|
||||
}
|
||||
@@ -117,10 +119,10 @@ class Loopers(runtime: ScriptRuntime) : IdleHandler {
|
||||
get() {
|
||||
if (mServantLooper == null) {
|
||||
initServantThread()
|
||||
val lock = this@Loopers as Object
|
||||
synchronized(lock) {
|
||||
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
||||
synchronized(this@Loopers as Object) {
|
||||
try {
|
||||
lock.wait()
|
||||
wait()
|
||||
} catch (e: InterruptedException) {
|
||||
throw ScriptInterruptedException(e)
|
||||
}
|
||||
@@ -134,16 +136,16 @@ class Loopers(runtime: ScriptRuntime) : IdleHandler {
|
||||
}
|
||||
|
||||
fun waitWhenIdle(): Int {
|
||||
val id = maxWaitId.get()
|
||||
val id = maxWaitId.get()!!
|
||||
Log.d(LOG_TAG, "waitWhenIdle: $id")
|
||||
maxWaitId.set(id + 1)
|
||||
waitIds.get().add(id)
|
||||
waitIds.get()!!.add(id)
|
||||
return id
|
||||
}
|
||||
|
||||
fun doNotWaitWhenIdle(waitId: Int) {
|
||||
Log.d(LOG_TAG, "doNotWaitWhenIdle: $waitId")
|
||||
waitIds.get().remove(waitId)
|
||||
waitIds.get()!!.remove(waitId)
|
||||
}
|
||||
|
||||
fun waitWhenIdle(b: Boolean) {
|
||||
|
||||
@@ -27,6 +27,7 @@ class Timer @JvmOverloads constructor(runtime: ScriptRuntime, maxCallbackMillisF
|
||||
private val mHandlerCallbacks = SparseArray<Runnable?>()
|
||||
private var mCallbackMaxId = 0
|
||||
private val mRuntime: ScriptRuntime = runtime
|
||||
@Suppress("DEPRECATION")
|
||||
private val mHandler = looper?.let { Handler(it) } ?: Handler()
|
||||
private var mMaxCallbackUptimeMillis: Long = 0
|
||||
private val mMaxCallbackMillisForAllThread: VolatileBox<Long> = maxCallbackMillisForAllThread
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.concurrent.ConcurrentHashMap
|
||||
// ! Sorry but my current capabilities are not sufficient
|
||||
// ! to fully understand everything from above pull request(s),
|
||||
// ! so most of the code will remain as is. :)
|
||||
@Suppress("unused")
|
||||
open class TimerThread(
|
||||
private val scriptRuntime: ScriptRuntime,
|
||||
private val maxCallbackUptimeMillisForAllThreads: VolatileBox<Long>,
|
||||
@@ -43,6 +44,7 @@ open class TimerThread(
|
||||
}
|
||||
(scriptRuntime.engines.myEngine() as? RhinoJavaScriptEngine)?.enterContext()
|
||||
notifyRunning()
|
||||
@Suppress("DEPRECATION")
|
||||
Looper.myLooper()?.let {
|
||||
Handler(it).post(target)
|
||||
} ?: Handler().post(target)
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
@@ -26,11 +27,9 @@ import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.functions.Consumer;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
/**
|
||||
@@ -76,7 +75,7 @@ public class DevPluginResponseHandler implements Handler {
|
||||
.handler("save", data -> {
|
||||
String script = data.get("script").getAsString();
|
||||
String name = getName(data);
|
||||
saveScript(name, script);
|
||||
saveFile(name, script);
|
||||
return true;
|
||||
})
|
||||
.handler("stopAll", data -> {
|
||||
@@ -151,45 +150,56 @@ public class DevPluginResponseHandler implements Handler {
|
||||
return element.getAsString();
|
||||
}
|
||||
|
||||
private void saveScript(String name, String script) {
|
||||
private void saveFile(String name, String content) {
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
name = "untitled";
|
||||
}
|
||||
name = PFiles.getNameWithoutExtension(name);
|
||||
if (!name.endsWith(".js")) {
|
||||
name = name + ".js";
|
||||
name = getUntitledTitle();
|
||||
}
|
||||
name = PFiles.getName(name);
|
||||
|
||||
// @Comment by SuperMonster003 on Jun 1, 2022.
|
||||
// ! Keep the original extension name of source file.
|
||||
// name = PFiles.getNameWithoutExtension(name);
|
||||
// if (!name.endsWith(".js")) {
|
||||
// name = name + ".js";
|
||||
// }
|
||||
|
||||
File file = new File(WorkingDirectoryUtils.getPath(), name);
|
||||
PFiles.ensureDir(file.getPath());
|
||||
PFiles.write(file, script);
|
||||
ViewUtils.showToast(mContext, R.string.text_script_save_succeeded, true);
|
||||
PFiles.write(file, content);
|
||||
ViewUtils.showToast(mContext, R.string.text_remote_file_saved_to_local_storage_successfully, true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
@SuppressLint("CheckResult")
|
||||
private void saveProject(String name, String dir) {
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
name = "untitled";
|
||||
name = getUntitledTitle();
|
||||
}
|
||||
name = PFiles.getNameWithoutExtension(name);
|
||||
name = PFiles.getName(name);
|
||||
|
||||
File toDir = new File(WorkingDirectoryUtils.getPath(), name);
|
||||
Callable<String> stringCallable = () -> {
|
||||
copyDir(new File(dir), toDir);
|
||||
return toDir.getPath();
|
||||
};
|
||||
|
||||
Consumer<String> stringConsumer = dest -> ViewUtils
|
||||
.showToast(mContext, mContext.getString(R.string.text_project_save_succeeded) + "\n" + dest);
|
||||
Consumer<Throwable> throwableConsumer = err -> ViewUtils
|
||||
.showToast(mContext, mContext.getString(R.string.text_project_save_error) + "\n" + err.getMessage());
|
||||
|
||||
Observable
|
||||
.fromCallable(stringCallable)
|
||||
.fromCallable(() -> {
|
||||
copyDir(new File(dir), toDir);
|
||||
return toDir.getPath();
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(stringConsumer, throwableConsumer);
|
||||
.subscribe(
|
||||
dest -> ViewUtils.showToast(mContext, mContext.getString(R.string.text_remote_project_saved_to_local_storage_successfully), true),
|
||||
err -> {
|
||||
var msg = mContext.getString(R.string.text_failed_to_save_remote_project_to_local_storage);
|
||||
var e = err.getMessage();
|
||||
if (e != null) msg += "\n" + e;
|
||||
|
||||
new MaterialDialog.Builder(mContext)
|
||||
.title(R.string.text_failed)
|
||||
.content(msg)
|
||||
.positiveText(R.string.dialog_button_confirm)
|
||||
.show();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
@@ -209,4 +219,8 @@ public class DevPluginResponseHandler implements Handler {
|
||||
}
|
||||
}
|
||||
|
||||
private String getUntitledTitle() {
|
||||
return "untitled" + "-" + System.currentTimeMillis();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -531,10 +531,12 @@ class CodeEditor : HVScrollView {
|
||||
|
||||
@Suppress("RegExpSimplifiable")
|
||||
replaceSelectedLines(Regex("^(\\s{$insetPosition})(\\s*\\S+)")) { matchResult ->
|
||||
"$prefix\u0020"
|
||||
.also { selectionEnd += it.length }
|
||||
.also { hasEverMatched = true }
|
||||
.let { "${matchResult.groupValues[1]}$it${matchResult.groupValues[2]}" }
|
||||
"$prefix\u0020".let {
|
||||
selectionEnd += it.length
|
||||
hasEverMatched = true
|
||||
val (_, former, latter) = matchResult.groupValues
|
||||
"$former$it$latter"
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("ControlFlowWithEmptyBody")
|
||||
@@ -555,8 +557,9 @@ class CodeEditor : HVScrollView {
|
||||
var selectionEnd = codeEditText.selectionEnd
|
||||
|
||||
replaceSelectedLines(Regex("(\\s*)($prefix\\s?)(.*)")) { matchResult ->
|
||||
selectionEnd -= matchResult.groupValues[2].length
|
||||
"${matchResult.groupValues[1]}${matchResult.groupValues[3]}"
|
||||
val (_, former, feature, latter) = matchResult.groupValues
|
||||
selectionEnd -= feature.length
|
||||
"$former$latter"
|
||||
}
|
||||
|
||||
codeEditText.setSelection(selectionEnd)
|
||||
|
||||
Reference in New Issue
Block a user