opt: use my code completion implement instead CodeMirror's
This commit is contained in:
@@ -1 +1 @@
|
|||||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":246},"path":"release-3.0.0 Alpha46.apk","properties":{"packageId":"com.stardust.scriptdroid","split":"","minSdkVersion":"17"}}]
|
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":246},"path":"release-3.0.0 Beta.apk","properties":{"packageId":"com.stardust.scriptdroid","split":"","minSdkVersion":"17"}}]
|
||||||
@@ -1,306 +0,0 @@
|
|||||||
function autoJsGlobalScope(){
|
|
||||||
function FUNCTION(url){
|
|
||||||
var f = function(){};
|
|
||||||
f.__url__ = url;
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
function VARIABLE(url){
|
|
||||||
return {
|
|
||||||
__url__: url
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var app = {
|
|
||||||
"uninstall": FUNCTION("app.html#app_app_uninstall_packagename"),
|
|
||||||
"viewFile": FUNCTION("app.html#app_app_viewfile_path"),
|
|
||||||
"editFile": FUNCTION("app.html#app_app_editfile_path"),
|
|
||||||
"openUrl": FUNCTION("app.html#app_app_openurl_url"),
|
|
||||||
"launchPackage": FUNCTION("app.html#app_app_takephoto_path"),
|
|
||||||
"launch": FUNCTION("globals.html#globals_launchpackage_packagename"),
|
|
||||||
"launchApp": FUNCTION("globals.html#globals_launchapp_appname"),
|
|
||||||
"getPackageName": FUNCTION("globals.html#globals_getpackagename_appname"),
|
|
||||||
"openAppSetting": FUNCTION("globals.html#globals_getappname_packagename"),
|
|
||||||
__url__: "app.html"
|
|
||||||
};
|
|
||||||
var automator = {
|
|
||||||
"click": FUNCTION("widgets-based-automation.html#widgets_based_automation_click_text_i"),
|
|
||||||
"longClick": FUNCTION("widgets-based-automation.html#widgets_based_automation_longclick_text_i"),
|
|
||||||
"press": FUNCTION(),
|
|
||||||
"swipe": FUNCTION(),
|
|
||||||
"gesture": FUNCTION(),
|
|
||||||
"gestures": FUNCTION(),
|
|
||||||
"gestureAsync": FUNCTION(),
|
|
||||||
"gesturesAsync": FUNCTION(),
|
|
||||||
"scrollDown": FUNCTION("widgets-based-automation.html#widgets_based_automation_scrollup_i"),
|
|
||||||
"scrollUp": FUNCTION("widgets-based-automation.html#widgets_based_automation_scrollup_i"),
|
|
||||||
"input": FUNCTION("widgets-based-automation.html#widgets_based_automation_input_i_text"),
|
|
||||||
"setText": FUNCTION("widgets-based-automation.html#widgets_based_automation_settext_i_text"),
|
|
||||||
__url__: "widgets-based-automation.html"
|
|
||||||
};
|
|
||||||
var console = {
|
|
||||||
"show": FUNCTION("console.html#console_console_show"),
|
|
||||||
"hide": FUNCTION(),
|
|
||||||
"clear": FUNCTION("console.html#console_console_clear"),
|
|
||||||
"verbose": FUNCTION("console.html#console_console_verbose_data_args"),
|
|
||||||
"info": FUNCTION("console.html#console_console_info_data_args"),
|
|
||||||
"log": FUNCTION("console.html#console_console_log_data_args"),
|
|
||||||
"warn": FUNCTION("console.html#console_console_warn_data_args"),
|
|
||||||
"error": FUNCTION("console.html#console_console_error_data_args"),
|
|
||||||
"assert": FUNCTION("console.html#console_console_assert_value_message"),
|
|
||||||
__url__: "console.html"
|
|
||||||
};
|
|
||||||
var dialogs = {
|
|
||||||
"select": FUNCTION(),
|
|
||||||
"singleChoice": FUNCTION(),
|
|
||||||
"multiChoice": FUNCTION(),
|
|
||||||
"rawInput": FUNCTION(),
|
|
||||||
"input": FUNCTION(),
|
|
||||||
"alert": FUNCTION(),
|
|
||||||
"confirm": FUNCTION(),
|
|
||||||
"prompt": FUNCTION()
|
|
||||||
};
|
|
||||||
var images = {
|
|
||||||
"saveImage": FUNCTION("images.html#images_images_saveimage_image_path"),
|
|
||||||
"pixel": FUNCTION("images.html#images_images_pixel_image_x_y"),
|
|
||||||
"read": FUNCTION(),
|
|
||||||
"requestScreenCapture": FUNCTION("images.html#images_requestscreencapture_width_height"),
|
|
||||||
"captureScreen": FUNCTION("images.html#images_capturescreen"),
|
|
||||||
"findColor": FUNCTION("images.html#images_images_findcolor_image_color_options"),
|
|
||||||
"findColorInRegion": FUNCTION("images.html#images_images_findcolorinregion_img_color_x_y_width_height_threads_algorithm_threshold"),
|
|
||||||
"findColorEquals": FUNCTION("images.html#images_images_findcolorequals_img_color_x_y_width_height_threads"),
|
|
||||||
__url__: "images.html"
|
|
||||||
};
|
|
||||||
var colors = {
|
|
||||||
"red": FUNCTION("images.html#images_colors_red_color"),
|
|
||||||
"green": FUNCTION("images.html#images_colors_green_color"),
|
|
||||||
"blue": FUNCTION("images.html#images_colors_blue_color"),
|
|
||||||
"alpha": FUNCTION("images.html#images_colors_alpha_color"),
|
|
||||||
"toString": FUNCTION("images.html#images_colors_tostring_color"),
|
|
||||||
"rgb": FUNCTION("images.html#images_colors_rgb_red_green_blue"),
|
|
||||||
"argb": FUNCTION("images.html#images_colors_argb_alpha_red_green_blue"),
|
|
||||||
__url__: "images.html#images_colors"
|
|
||||||
};
|
|
||||||
var events = {
|
|
||||||
"emitter": FUNCTION("events.html#events_events_emitter"),
|
|
||||||
"observeKey": FUNCTION("events.html#events_events_observekey"),
|
|
||||||
"observeTouch": FUNCTION("events.html#events_events_observetouch"),
|
|
||||||
"observeNotification": FUNCTION("events.html#events_obversenotification"),
|
|
||||||
"onKeyDown": FUNCTION("events.html#events_events_onkeydown_keyname_listener"),
|
|
||||||
"onKeyUp": FUNCTION("events.html#events_events_onkeyup_keyname_listener"),
|
|
||||||
"onceKeyDown": FUNCTION("events.html#events_events_oncekeydown_keyname_listener"),
|
|
||||||
"onceKeyUp": FUNCTION("events.html#events_events_oncekeyup_keyname_listener"),
|
|
||||||
"onToast": FUNCTION("events.html#events_toast"),
|
|
||||||
"onNotification": FUNCTION("events.html#events_notification"),
|
|
||||||
"removeAllKeyDownListeners": FUNCTION("events.html#events_events_removeallkeydownlisteners_keyname"),
|
|
||||||
"removeAllKeyUpListeners": FUNCTION("events.html#events_events_removeallkeyuplisteners_keyname"),
|
|
||||||
"onTouch": FUNCTION("events.html#events_events_ontouch_listener"),
|
|
||||||
"removeAllTouchListeners": FUNCTION("events.html#events_events_removealltouchlisteners"),
|
|
||||||
"getTouchEventTimeout": FUNCTION("events.html#events_events_gettoucheventtimeout"),
|
|
||||||
"setTouchEventTimeout": FUNCTION("events.html#events_events_settoucheventtimeout_timeout"),
|
|
||||||
"on": FUNCTION("events.html#events_eventemitter_on_eventname_listener"),
|
|
||||||
"once": FUNCTION("events.html#events_eventemitter_once_eventname_listener"),
|
|
||||||
"emit": FUNCTION("events.html#events_eventemitter_emit_eventname_args"),
|
|
||||||
"getListeners": FUNCTION(),
|
|
||||||
"addListener": FUNCTION("events.html#events_eventemitter_addlistener_eventname_listener"),
|
|
||||||
"eventNames": FUNCTION("events.html#events_eventemitter_eventnames"),
|
|
||||||
"listenerCount": FUNCTION("events.html#events_eventemitter_listenercount_eventname"),
|
|
||||||
"listeners": FUNCTION("events.html#events_eventemitter_listeners_eventname"),
|
|
||||||
"prependListener": FUNCTION("events.html#events_eventemitter_prependlistener_eventname_listener"),
|
|
||||||
"prependOnceListener": FUNCTION("events.html#events_eventemitter_prependoncelistener_eventname_listener"),
|
|
||||||
"removeAllListeners": FUNCTION("events.html#events_eventemitter_removealllisteners_eventname"),
|
|
||||||
"removeListener": FUNCTION("events.html#events_eventemitter_removelistener_eventname_listener"),
|
|
||||||
"setMaxListeners": FUNCTION("events.html#events_eventemitter_setmaxlisteners_n"),
|
|
||||||
"getMaxListeners": FUNCTION("events.html#events_eventemitter_getmaxlisteners"),
|
|
||||||
"defaultMaxListeners": FUNCTION("events.html#events_eventemitter_defaultmaxlisteners"),
|
|
||||||
__url__: "events.html"
|
|
||||||
};
|
|
||||||
var files = {
|
|
||||||
"open": FUNCTION(),
|
|
||||||
"isFile": FUNCTION("files.html#files_files_isfile_path"),
|
|
||||||
"isDir": FUNCTION("files.html#files_files_isdir_path"),
|
|
||||||
"isEmptyDir": FUNCTION("files.html#files_files_isemptydir_path"),
|
|
||||||
"join": FUNCTION("files.html#files_files_join_parent_child"),
|
|
||||||
"create": FUNCTION("files.html#files_files_create_path"),
|
|
||||||
"createIfNotExists": FUNCTION("files.html#files_files_createifnotexists_path"),
|
|
||||||
"exists": FUNCTION("files.html#files_files_exists_path"),
|
|
||||||
"ensureDir": FUNCTION("files.html#files_files_ensuredir_path"),
|
|
||||||
"read": FUNCTION("files.html#files_files_read_path_encoding_utf_8"),
|
|
||||||
"write": FUNCTION("files.html#files_files_write_path_text_encoding_utf_8"),
|
|
||||||
"copy": FUNCTION("files.html#files_files_copy_frompath_topath"),
|
|
||||||
"move": FUNCTION("files.html#files_files_move_frompath_topath"),
|
|
||||||
"rename": FUNCTION("files.html#files_files_rename_path_newname"),
|
|
||||||
"renameWithoutExtension": FUNCTION("files.html#files_files_renamewithoutextension_path_newname"),
|
|
||||||
"getName": FUNCTION("files.html#files_files_getname_path"),
|
|
||||||
"getExtension": FUNCTION("files.html#files_files_getextension_path"),
|
|
||||||
"getNameWithoutExtension": FUNCTION("files.html#files_files_getnamewithoutextension_path"),
|
|
||||||
"remove": FUNCTION("files.html#files_files_remove_path"),
|
|
||||||
"removeDir": FUNCTION("files.html#files_files_removedir_path"),
|
|
||||||
"getSdcardPath": FUNCTION("files.html#files_files_getsdcardpath"),
|
|
||||||
"listDir": FUNCTION("files.html#files_files_listdir_path_filter"),
|
|
||||||
__url__: "files.html"
|
|
||||||
};
|
|
||||||
var timers = {
|
|
||||||
"setTimeout": FUNCTION("timers.html#timers_settimeout_callback_delay_args"),
|
|
||||||
"clearTimeout": FUNCTION("timers.html#timers_cleartimeout_id"),
|
|
||||||
"setInterval": FUNCTION("timers.html#timers_setinterval_callback_delay_args"),
|
|
||||||
"clearInterval": FUNCTION("timers.html#timers_clearinterval_id"),
|
|
||||||
"setImmediate": FUNCTION("timers.html#timers_setimmediate_callback_args"),
|
|
||||||
"clearImmediate": FUNCTION("timers.html#timers_clearimmediate_id")
|
|
||||||
};
|
|
||||||
var globals = {
|
|
||||||
"app": app,
|
|
||||||
"automator": automator,
|
|
||||||
"console": console,
|
|
||||||
"dialogs": dialogs,
|
|
||||||
"events": events,
|
|
||||||
"images": images,
|
|
||||||
"files": files,
|
|
||||||
"timers": timers,
|
|
||||||
"ui": {},
|
|
||||||
|
|
||||||
"click": FUNCTION(),
|
|
||||||
"longClick": FUNCTION(),
|
|
||||||
"press": FUNCTION(),
|
|
||||||
"swipe": FUNCTION(),
|
|
||||||
"gesture": FUNCTION(),
|
|
||||||
"gestures": FUNCTION(),
|
|
||||||
"gestureAsync": FUNCTION(),
|
|
||||||
"gesturesAsync": FUNCTION(),
|
|
||||||
"scrollDown": FUNCTION(),
|
|
||||||
"scrollUp": FUNCTION(),
|
|
||||||
"input": FUNCTION(),
|
|
||||||
"setText": FUNCTION(),
|
|
||||||
|
|
||||||
"print": FUNCTION(),
|
|
||||||
"log": FUNCTION(),
|
|
||||||
"err": FUNCTION(),
|
|
||||||
"openConsole": FUNCTION(),
|
|
||||||
"clearConsole": FUNCTION(),
|
|
||||||
|
|
||||||
"rawInput": FUNCTION(),
|
|
||||||
"input": FUNCTION(),
|
|
||||||
"alert": FUNCTION(),
|
|
||||||
"confirm": FUNCTION(),
|
|
||||||
"prompt": FUNCTION(),
|
|
||||||
|
|
||||||
"requestScreenCapture": FUNCTION(),
|
|
||||||
"captureScreen": FUNCTION(),
|
|
||||||
"findColor": FUNCTION(),
|
|
||||||
"findColorInRegion": FUNCTION(),
|
|
||||||
"findColorEquals": FUNCTION(),
|
|
||||||
|
|
||||||
"open": FUNCTION(),
|
|
||||||
|
|
||||||
"id": FUNCTION(),
|
|
||||||
"idContains": FUNCTION(),
|
|
||||||
"idStartsWith": FUNCTION(),
|
|
||||||
"idEndsWith": FUNCTION(),
|
|
||||||
"idMatches": FUNCTION(),
|
|
||||||
"text": FUNCTION(),
|
|
||||||
"textContains": FUNCTION(),
|
|
||||||
"textStartsWith": FUNCTION(),
|
|
||||||
"textEndsWith": FUNCTION(),
|
|
||||||
"textMatches": FUNCTION(),
|
|
||||||
"desc": FUNCTION(),
|
|
||||||
"descContains": FUNCTION(),
|
|
||||||
"descStartsWith": FUNCTION(),
|
|
||||||
"descEndsWith": FUNCTION(),
|
|
||||||
"descMatches": FUNCTION(),
|
|
||||||
"className": FUNCTION(),
|
|
||||||
"classNameContains": FUNCTION(),
|
|
||||||
"classNameStartsWith": FUNCTION(),
|
|
||||||
"classNameEndsWith": FUNCTION(),
|
|
||||||
"classNameMatches": FUNCTION(),
|
|
||||||
"packageName": FUNCTION(),
|
|
||||||
"packageNameContains": FUNCTION(),
|
|
||||||
"packageNameStartsWith": FUNCTION(),
|
|
||||||
"packageNameEndsWith": FUNCTION(),
|
|
||||||
"packageNameMatches": FUNCTION(),
|
|
||||||
"bounds": FUNCTION(),
|
|
||||||
"boundsInside": FUNCTION(),
|
|
||||||
"boundsContains": FUNCTION(),
|
|
||||||
"drawingOrder": FUNCTION(),
|
|
||||||
"checkable": FUNCTION(),
|
|
||||||
"checked": FUNCTION(),
|
|
||||||
"focusable": FUNCTION(),
|
|
||||||
"focused": FUNCTION(),
|
|
||||||
"visibleToUser": FUNCTION(),
|
|
||||||
"accessibilityFocused": FUNCTION(),
|
|
||||||
"selected": FUNCTION(),
|
|
||||||
"clickable": FUNCTION(),
|
|
||||||
"longClickable": FUNCTION(),
|
|
||||||
"enabled": FUNCTION(),
|
|
||||||
"password": FUNCTION(),
|
|
||||||
"scrollable": FUNCTION(),
|
|
||||||
"editable": FUNCTION(),
|
|
||||||
"contentInvalid": FUNCTION(),
|
|
||||||
"contextClickable": FUNCTION(),
|
|
||||||
"multiLine": FUNCTION(),
|
|
||||||
"dismissable": FUNCTION(),
|
|
||||||
"checkable": FUNCTION(),
|
|
||||||
"checked": FUNCTION(),
|
|
||||||
"focusable": FUNCTION(),
|
|
||||||
"focused": FUNCTION(),
|
|
||||||
"visibleToUser": FUNCTION(),
|
|
||||||
"accessibilityFocused": FUNCTION(),
|
|
||||||
"selected": FUNCTION(),
|
|
||||||
"clickable": FUNCTION(),
|
|
||||||
"longClickable": FUNCTION(),
|
|
||||||
"enabled": FUNCTION(),
|
|
||||||
"password": FUNCTION(),
|
|
||||||
"scrollable": FUNCTION(),
|
|
||||||
"editable": FUNCTION(),
|
|
||||||
"contentInvalid": FUNCTION(),
|
|
||||||
"contextClickable": FUNCTION(),
|
|
||||||
"multiLine": FUNCTION(),
|
|
||||||
"dismissable": FUNCTION(),
|
|
||||||
|
|
||||||
"SetScreenMetrics": FUNCTION(),
|
|
||||||
"Tap": FUNCTION(),
|
|
||||||
"Swipe": FUNCTION(),
|
|
||||||
"Screencap": FUNCTION(),
|
|
||||||
"KeyCode": FUNCTION(),
|
|
||||||
"Home": FUNCTION(),
|
|
||||||
"Back": FUNCTION(),
|
|
||||||
"Power": FUNCTION(),
|
|
||||||
"Up": FUNCTION(),
|
|
||||||
"Down": FUNCTION(),
|
|
||||||
"Left": FUNCTION(),
|
|
||||||
"Right": FUNCTION(),
|
|
||||||
"OK": FUNCTION(),
|
|
||||||
"VolumeUp": FUNCTION(),
|
|
||||||
"VolumeDown": FUNCTION(),
|
|
||||||
"Menu": FUNCTION(),
|
|
||||||
"Camera": FUNCTION(),
|
|
||||||
"Text": FUNCTION(),
|
|
||||||
|
|
||||||
"loop": FUNCTION(),
|
|
||||||
"setTimeout": FUNCTION(),
|
|
||||||
"clearTimeout": FUNCTION(),
|
|
||||||
"setInterval": FUNCTION(),
|
|
||||||
"clearInterval": FUNCTION(),
|
|
||||||
"setImmediate": FUNCTION(),
|
|
||||||
"clearImmediate": FUNCTION(),
|
|
||||||
|
|
||||||
"newInjectableWebClient": FUNCTION(),
|
|
||||||
"newInjectableWebView": FUNCTION(),
|
|
||||||
|
|
||||||
"toast": FUNCTION(),
|
|
||||||
"toastLog": FUNCTION(),
|
|
||||||
"sleep": FUNCTION(),
|
|
||||||
"isStopped": FUNCTION(),
|
|
||||||
"notStopped": FUNCTION(),
|
|
||||||
"exit": FUNCTION(),
|
|
||||||
"setClip": FUNCTION(),
|
|
||||||
"getClip": FUNCTION(),
|
|
||||||
"currentPackage": FUNCTION(),
|
|
||||||
"currentActivity": FUNCTION(),
|
|
||||||
"waitForActivity": FUNCTION(),
|
|
||||||
"waitForPackage": FUNCTION(),
|
|
||||||
"setScreenMetrics": FUNCTION(),
|
|
||||||
|
|
||||||
"context": {},
|
|
||||||
"activity": {}
|
|
||||||
};
|
|
||||||
return globals;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,171 +0,0 @@
|
|||||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
||||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
|
||||||
|
|
||||||
(function(mod) {
|
|
||||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
||||||
mod(require("../../lib/codemirror"));
|
|
||||||
else if (typeof define == "function" && define.amd) // AMD
|
|
||||||
define(["../../lib/codemirror"], mod);
|
|
||||||
else // Plain browser env
|
|
||||||
mod(CodeMirror);
|
|
||||||
})(function(CodeMirror) {
|
|
||||||
var Pos = CodeMirror.Pos;
|
|
||||||
|
|
||||||
function forEach(arr, f) {
|
|
||||||
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function arrayContains(arr, item) {
|
|
||||||
if (!Array.prototype.indexOf) {
|
|
||||||
var i = arr.length;
|
|
||||||
while (i--) {
|
|
||||||
if (arr[i] === item) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return arr.indexOf(item) != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
function scriptHint(editor, keywords, getToken, options) {
|
|
||||||
// Find the token at the cursor
|
|
||||||
var cur = editor.getCursor(), token = getToken(editor, cur);
|
|
||||||
if (/\b(?:string|comment)\b/.test(token.type)) return;
|
|
||||||
token.state = CodeMirror.innerMode(editor.getMode(), token.state).state;
|
|
||||||
|
|
||||||
// If it's not a 'word-style' token, ignore the token.
|
|
||||||
if (!/^[\w$_]*$/.test(token.string)) {
|
|
||||||
token = {start: cur.ch, end: cur.ch, string: "", state: token.state,
|
|
||||||
type: token.string == "." ? "property" : null};
|
|
||||||
} else if (token.end > cur.ch) {
|
|
||||||
token.end = cur.ch;
|
|
||||||
token.string = token.string.slice(0, cur.ch - token.start);
|
|
||||||
}
|
|
||||||
|
|
||||||
var tprop = token;
|
|
||||||
// If it is a property, find out what it is a property of.
|
|
||||||
while (tprop.type == "property") {
|
|
||||||
tprop = getToken(editor, Pos(cur.line, tprop.start));
|
|
||||||
if (tprop.string != ".") return;
|
|
||||||
tprop = getToken(editor, Pos(cur.line, tprop.start));
|
|
||||||
if (!context) var context = [];
|
|
||||||
context.push(tprop);
|
|
||||||
}
|
|
||||||
var c = getCompletions(token, context, keywords, options);
|
|
||||||
return {list: c.list,
|
|
||||||
urls: c.urls,
|
|
||||||
from: Pos(cur.line, token.start),
|
|
||||||
to: Pos(cur.line, token.end)};
|
|
||||||
}
|
|
||||||
|
|
||||||
function javascriptHint(editor, options) {
|
|
||||||
return scriptHint(editor, javascriptKeywords,
|
|
||||||
function (e, cur) {return e.getTokenAt(cur);},
|
|
||||||
options);
|
|
||||||
};
|
|
||||||
CodeMirror.registerHelper("hint", "javascript", javascriptHint);
|
|
||||||
|
|
||||||
function getCoffeeScriptToken(editor, cur) {
|
|
||||||
// This getToken, it is for coffeescript, imitates the behavior of
|
|
||||||
// getTokenAt method in javascript.js, that is, returning "property"
|
|
||||||
// type and treat "." as indepenent token.
|
|
||||||
var token = editor.getTokenAt(cur);
|
|
||||||
if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
|
|
||||||
token.end = token.start;
|
|
||||||
token.string = '.';
|
|
||||||
token.type = "property";
|
|
||||||
}
|
|
||||||
else if (/^\.[\w$_]*$/.test(token.string)) {
|
|
||||||
token.type = "property";
|
|
||||||
token.start++;
|
|
||||||
token.string = token.string.replace(/\./, '');
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
function coffeescriptHint(editor, options) {
|
|
||||||
return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options);
|
|
||||||
}
|
|
||||||
CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint);
|
|
||||||
|
|
||||||
var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
|
|
||||||
"toUpperCase toLowerCase split concat match replace search").split(" ");
|
|
||||||
var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " +
|
|
||||||
"lastIndexOf every some filter forEach map reduce reduceRight ").split(" ");
|
|
||||||
var funcProps = "prototype apply call bind".split(" ");
|
|
||||||
var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " +
|
|
||||||
"if in instanceof new null return switch throw true try typeof var void while with").split(" ");
|
|
||||||
var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
|
|
||||||
"if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
|
|
||||||
|
|
||||||
function forAllProps(obj, callback) {
|
|
||||||
for (var name in obj) {
|
|
||||||
var value = obj[name];
|
|
||||||
callback(name, value.__url__);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
//unreachable
|
|
||||||
if (!Object.getOwnPropertyNames || !Object.getPrototypeOf) {
|
|
||||||
for (var name in obj) callback(name)
|
|
||||||
} else {
|
|
||||||
for (var o = obj; o; o = Object.getPrototypeOf(o))
|
|
||||||
Object.getOwnPropertyNames(o).forEach(callback)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCompletions(token, context, keywords, options) {
|
|
||||||
var found = [], start = token.string, global = options && options.globalScope || window;
|
|
||||||
var urls = [];
|
|
||||||
function maybeAdd(str, url) {
|
|
||||||
if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) {
|
|
||||||
found.push(str);
|
|
||||||
urls.push(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function gatherCompletions(obj) {
|
|
||||||
if (typeof obj == "string") forEach(stringProps, maybeAdd);
|
|
||||||
else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
|
|
||||||
else if (obj instanceof Function) forEach(funcProps, maybeAdd);
|
|
||||||
forAllProps(obj, maybeAdd)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context && context.length) {
|
|
||||||
// If this is a property, see if it belongs to some object we can
|
|
||||||
// find in the current environment.
|
|
||||||
var obj = context.pop(), base;
|
|
||||||
if (obj.type && obj.type.indexOf("variable") === 0) {
|
|
||||||
if (options && options.additionalContext)
|
|
||||||
base = options.additionalContext[obj.string];
|
|
||||||
if (!options || options.useGlobalScope !== false)
|
|
||||||
base = base || global[obj.string];
|
|
||||||
} else if (obj.type == "string") {
|
|
||||||
base = "";
|
|
||||||
} else if (obj.type == "atom") {
|
|
||||||
base = 1;
|
|
||||||
} else if (obj.type == "function") {
|
|
||||||
if (global.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
|
|
||||||
(typeof global.jQuery == 'function'))
|
|
||||||
base = global.jQuery();
|
|
||||||
else if (global._ != null && (obj.string == '_') && (typeof global._ == 'function'))
|
|
||||||
base = global._();
|
|
||||||
}
|
|
||||||
while (base != null && context.length)
|
|
||||||
base = base[context.pop().string];
|
|
||||||
if (base != null) gatherCompletions(base);
|
|
||||||
} else {
|
|
||||||
// If not, just look in the global object and any local scope
|
|
||||||
// (reading into JS mode internals to get at the local and global variables)
|
|
||||||
for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
|
|
||||||
for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name);
|
|
||||||
if (!options || options.useGlobalScope !== false)
|
|
||||||
gatherCompletions(global);
|
|
||||||
forEach(keywords, maybeAdd);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
list: found,
|
|
||||||
urls: urls
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -28,13 +28,6 @@
|
|||||||
<script src="codemirror/addon/fold/indent-fold.js"></script>
|
<script src="codemirror/addon/fold/indent-fold.js"></script>
|
||||||
<script src="codemirror/addon/fold/comment-fold.js"></script>
|
<script src="codemirror/addon/fold/comment-fold.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<!-- 代码补全 -->
|
|
||||||
<link rel="stylesheet" href="codemirror/addon/hint/show-hint.css">
|
|
||||||
<script src="codemirror/addon/autojs/autojs-hint.js"></script>
|
|
||||||
<script src="codemirror/addon/hint/anyword-hint.js"></script>
|
|
||||||
<script src="codemirror/addon/hint/show-hint.js"></script>
|
|
||||||
|
|
||||||
<!-- 代码格式化 -->
|
<!-- 代码格式化 -->
|
||||||
<script type="text/javascript" src="beautify/beautify.min.js"></script>
|
<script type="text/javascript" src="beautify/beautify.min.js"></script>
|
||||||
|
|
||||||
@@ -43,7 +36,6 @@
|
|||||||
<script type="text/javascript" src="codemirror/addon/search/searchcursor.js"></script>
|
<script type="text/javascript" src="codemirror/addon/search/searchcursor.js"></script>
|
||||||
|
|
||||||
<!-- Auto.js -->
|
<!-- Auto.js -->
|
||||||
<script type="text/javascript" src="codemirror/addon/autojs/autojs-global-scope.js"></script>
|
|
||||||
<script type="text/javascript" src="codemirror/addon/autojs/autojs.js"></script>
|
<script type="text/javascript" src="codemirror/addon/autojs/autojs.js"></script>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
|
|||||||
@@ -1,56 +1,4 @@
|
|||||||
var ExcludedIntelliSenseTriggerKeys =
|
|
||||||
{
|
|
||||||
"8": "backspace",
|
|
||||||
"9": "tab",
|
|
||||||
"13": "enter",
|
|
||||||
"16": "shift",
|
|
||||||
"17": "ctrl",
|
|
||||||
"18": "alt",
|
|
||||||
"19": "pause",
|
|
||||||
"20": "capslock",
|
|
||||||
"27": "escape",
|
|
||||||
"32": "space",
|
|
||||||
"33": "pageup",
|
|
||||||
"34": "pagedown",
|
|
||||||
"35": "end",
|
|
||||||
"36": "home",
|
|
||||||
"37": "left",
|
|
||||||
"38": "up",
|
|
||||||
"39": "right",
|
|
||||||
"40": "down",
|
|
||||||
"45": "insert",
|
|
||||||
"46": "delete",
|
|
||||||
"91": "left window key",
|
|
||||||
"92": "right window key",
|
|
||||||
"93": "select",
|
|
||||||
"107": "add",
|
|
||||||
"109": "subtract",
|
|
||||||
"110": "decimal point",
|
|
||||||
"111": "divide",
|
|
||||||
"112": "f1",
|
|
||||||
"113": "f2",
|
|
||||||
"114": "f3",
|
|
||||||
"115": "f4",
|
|
||||||
"116": "f5",
|
|
||||||
"117": "f6",
|
|
||||||
"118": "f7",
|
|
||||||
"119": "f8",
|
|
||||||
"120": "f9",
|
|
||||||
"121": "f10",
|
|
||||||
"122": "f11",
|
|
||||||
"123": "f12",
|
|
||||||
"144": "numlock",
|
|
||||||
"145": "scrolllock",
|
|
||||||
"186": "semicolon",
|
|
||||||
"187": "equalsign",
|
|
||||||
"188": "comma",
|
|
||||||
"189": "dash",
|
|
||||||
"190": "period",
|
|
||||||
"191": "slash",
|
|
||||||
"192": "graveaccent",
|
|
||||||
"220": "backslash",
|
|
||||||
"222": "quote"
|
|
||||||
};
|
|
||||||
var editor = CodeMirror(document.body, {
|
var editor = CodeMirror(document.body, {
|
||||||
lineNumbers: true, // 显示行数
|
lineNumbers: true, // 显示行数
|
||||||
indentUnit: 4, // 缩进单位为4
|
indentUnit: 4, // 缩进单位为4
|
||||||
@@ -63,26 +11,16 @@ var editor = CodeMirror(document.body, {
|
|||||||
theme: 'neo' // 使用neo主题
|
theme: 'neo' // 使用neo主题
|
||||||
});
|
});
|
||||||
editor.setOption("fullScreen", true);
|
editor.setOption("fullScreen", true);
|
||||||
editor.setOption("hintOptions", {
|
|
||||||
completeSingle: false,
|
editor.setCursor({line: 0, ch: 0});
|
||||||
globalScope: autoJsGlobalScope()
|
editor.on('change', function(){
|
||||||
});
|
var c = editor.getCursor();
|
||||||
var id = null;
|
if(typeof(__bridge__) != 'undefined'){
|
||||||
editor.on("keyup", function(editor, event)
|
__bridge__.onKeyUp(editor.getLine(c.line), c.ch);
|
||||||
{
|
}else{
|
||||||
if (!ExcludedIntelliSenseTriggerKeys[(event.keyCode || event.which).toString()] )
|
console.log(editor.getLine(c.line), c.ch);
|
||||||
{
|
|
||||||
if(id != null){
|
|
||||||
clearTimeout(id);
|
|
||||||
}
|
|
||||||
id = setTimeout(function(){
|
|
||||||
editor.showHint({
|
|
||||||
completeSingle: false
|
|
||||||
})
|
|
||||||
}, 100);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
editor.setCursor({line: 0, ch: 0});
|
|
||||||
|
|
||||||
window.onload = function(){
|
window.onload = function(){
|
||||||
autojs(editor);
|
autojs(editor);
|
||||||
|
|||||||
@@ -0,0 +1,132 @@
|
|||||||
|
package com.stardust.scriptdroid.model.autocomplete;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.stardust.scriptdroid.model.indices.Module;
|
||||||
|
import com.stardust.scriptdroid.model.indices.Modules;
|
||||||
|
import com.stardust.scriptdroid.model.indices.Property;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2018/2/3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class AutoCompletion {
|
||||||
|
|
||||||
|
public interface AutoCompleteCallback {
|
||||||
|
|
||||||
|
void updateCodeCompletion(CodeCompletions codeCompletions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Pattern STATEMENT = Pattern.compile("([A-Za-z]+\\.)?([a-zA-Z][a-zA-Z0-9_]*)?$");
|
||||||
|
|
||||||
|
private String mModuleName;
|
||||||
|
private String mPropertyPrefill;
|
||||||
|
private List<Module> mModules;
|
||||||
|
private DictionaryTree<Property> mGlobalPropertyTree = new DictionaryTree<>();
|
||||||
|
private AutoCompleteCallback mAutoCompleteCallback;
|
||||||
|
|
||||||
|
public AutoCompletion(Context context) {
|
||||||
|
buildDictionaryTree(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoCompleteCallback(AutoCompleteCallback autoCompleteCallback) {
|
||||||
|
mAutoCompleteCallback = autoCompleteCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildDictionaryTree(Context context) {
|
||||||
|
Modules.getInstance().getModules(context)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.doOnNext(this::buildDictionaryTree)
|
||||||
|
.subscribe(modules -> mModules = modules);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildDictionaryTree(List<Module> modules) {
|
||||||
|
for (Module module : modules) {
|
||||||
|
mGlobalPropertyTree.putWord(module.getName(), module.asGlobalProperty());
|
||||||
|
for (Property property : module.getProperties()) {
|
||||||
|
if (property.isGlobal())
|
||||||
|
mGlobalPropertyTree.putWord(property.getKey(), property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCursorChange(String line, int cursor) {
|
||||||
|
if (cursor <= 0 || line == null || line.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mModules == null || mAutoCompleteCallback == null)
|
||||||
|
return;
|
||||||
|
findStatementOnCursor(line, cursor);
|
||||||
|
if (mPropertyPrefill == null && mModuleName == null)
|
||||||
|
return;
|
||||||
|
Module module = getModule(mModuleName);
|
||||||
|
List<CodeCompletion> completions = findCodeCompletion(module, mPropertyPrefill);
|
||||||
|
CodeCompletions codeCompletions = new CodeCompletions(cursor, completions);
|
||||||
|
mAutoCompleteCallback.updateCodeCompletion(codeCompletions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Module getModule(String moduleName) {
|
||||||
|
if (moduleName == null)
|
||||||
|
return null;
|
||||||
|
for (Module module : mModules) {
|
||||||
|
if (module.getName().equals(moduleName)) {
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findStatementOnCursor(String line, int cursor) {
|
||||||
|
Matcher matcher = STATEMENT.matcher(line.substring(0, cursor));
|
||||||
|
if (!matcher.find()) {
|
||||||
|
mModuleName = mPropertyPrefill = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (matcher.groupCount() == 2) {
|
||||||
|
String module = matcher.group(1);
|
||||||
|
mModuleName = module == null ? null : module.substring(0, module.length() - 1);
|
||||||
|
mPropertyPrefill = matcher.group(2);
|
||||||
|
} else {
|
||||||
|
mModuleName = null;
|
||||||
|
mPropertyPrefill = matcher.group(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<CodeCompletion> findCodeCompletion(Module module, String propertyPrefill) {
|
||||||
|
if (module == null)
|
||||||
|
return findCodeCompletionForGlobal(propertyPrefill);
|
||||||
|
return findCodeCompletionForModule(module, propertyPrefill);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<CodeCompletion> findCodeCompletionForModule(Module module, String propertyPrefill) {
|
||||||
|
List<CodeCompletion> completions = new ArrayList<>();
|
||||||
|
int len = propertyPrefill == null ? 0 : propertyPrefill.length();
|
||||||
|
for (Property property : module.getProperties()) {
|
||||||
|
if (propertyPrefill == null || property.getKey().startsWith(propertyPrefill)) {
|
||||||
|
completions.add(new CodeCompletion(property.getKey(), property.getUrl(), len));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return completions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<CodeCompletion> findCodeCompletionForGlobal(String propertyPrefill) {
|
||||||
|
List<DictionaryTree.Entry<Property>> result = mGlobalPropertyTree.searchByPrefill(propertyPrefill);
|
||||||
|
List<CodeCompletion> completions = new ArrayList<>();
|
||||||
|
for (DictionaryTree.Entry<Property> entry : result) {
|
||||||
|
Property property = entry.tag;
|
||||||
|
completions.add(new CodeCompletion(property.getKey(), property.getUrl(), propertyPrefill.length()));
|
||||||
|
}
|
||||||
|
return completions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.stardust.scriptdroid.model.autocomplete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2018/2/3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CodeCompletion {
|
||||||
|
|
||||||
|
private final String mHint;
|
||||||
|
private final String mUrl;
|
||||||
|
private final String mInsertText;
|
||||||
|
private final int mInsertPos;
|
||||||
|
|
||||||
|
public CodeCompletion(String hint, String url, int insertPos) {
|
||||||
|
mHint = hint;
|
||||||
|
mUrl = url;
|
||||||
|
mInsertPos = insertPos;
|
||||||
|
mInsertText = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeCompletion(String hint, String url, String insertText) {
|
||||||
|
mHint = hint;
|
||||||
|
mUrl = url;
|
||||||
|
mInsertText = insertText;
|
||||||
|
mInsertPos = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHint() {
|
||||||
|
return mHint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return mUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInsertText() {
|
||||||
|
if (mInsertText != null)
|
||||||
|
return mInsertText;
|
||||||
|
if (mInsertPos == 0) {
|
||||||
|
return mHint;
|
||||||
|
}
|
||||||
|
return mHint.substring(mInsertPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.stardust.scriptdroid.model.autocomplete;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2017/9/27.
|
||||||
|
*/
|
||||||
|
public class CodeCompletions {
|
||||||
|
|
||||||
|
|
||||||
|
private int mFrom;
|
||||||
|
private List<CodeCompletion> mCompletions;
|
||||||
|
|
||||||
|
public CodeCompletions(int cursor, List<CodeCompletion> completions) {
|
||||||
|
mFrom = cursor;
|
||||||
|
mCompletions = completions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CodeCompletions just(List<String> hints) {
|
||||||
|
List<CodeCompletion> completions = new ArrayList<>(hints.size());
|
||||||
|
for (String hint : hints) {
|
||||||
|
completions.add(new CodeCompletion(hint, null, 0));
|
||||||
|
}
|
||||||
|
return new CodeCompletions(-1, completions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFrom() {
|
||||||
|
return mFrom;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return mCompletions.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHint(int position) {
|
||||||
|
return mCompletions.get(position).getHint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeCompletion get(int pos) {
|
||||||
|
return mCompletions.get(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl(int pos) {
|
||||||
|
return mCompletions.get(pos).getUrl();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package com.stardust.scriptdroid.model.autocomplete;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2018/2/3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class DictionaryTree<T> {
|
||||||
|
|
||||||
|
private static class Node<T> {
|
||||||
|
|
||||||
|
char ch;
|
||||||
|
Map<Character, Node<T>> children = new TreeMap<>();
|
||||||
|
String wordEndHere;
|
||||||
|
T tag;
|
||||||
|
|
||||||
|
Node(char ch) {
|
||||||
|
this.ch = ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Entry<T> {
|
||||||
|
public String word;
|
||||||
|
public T tag;
|
||||||
|
|
||||||
|
public Entry(String word, T tag) {
|
||||||
|
this.word = word;
|
||||||
|
this.tag = tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node<T> mRoot = new Node<>('@');
|
||||||
|
|
||||||
|
public void putWord(String word, T tag) {
|
||||||
|
Node<T> node = mRoot;
|
||||||
|
for (int i = 0; i < word.length(); i++) {
|
||||||
|
node = getOrCreateNode(node, word.charAt(i));
|
||||||
|
}
|
||||||
|
node.tag = tag;
|
||||||
|
node.wordEndHere = word;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public List<Entry<T>> searchByPrefill(String prefill) {
|
||||||
|
Node<T> node = mRoot;
|
||||||
|
for (int i = 0; i < prefill.length(); i++) {
|
||||||
|
node = node.children.get(prefill.charAt(i));
|
||||||
|
if (node == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Entry<T>> entries = new ArrayList<>();
|
||||||
|
collectChildren(node, entries);
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void collectChildren(Node<T> node, List<Entry<T>> entries) {
|
||||||
|
for (Map.Entry<Character, Node<T>> entry : node.children.entrySet()) {
|
||||||
|
Node<T> child = entry.getValue();
|
||||||
|
if (child.wordEndHere != null) {
|
||||||
|
entries.add(new Entry<>(child.wordEndHere, child.tag));
|
||||||
|
}
|
||||||
|
collectChildren(child, entries);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node<T> getOrCreateNode(Node<T> parent, char ch) {
|
||||||
|
Node<T> child = parent.children.get(ch);
|
||||||
|
if (child == null) {
|
||||||
|
child = new Node<>(ch);
|
||||||
|
parent.children.put(ch, child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.stardust.scriptdroid.ui.edit.completion;
|
package com.stardust.scriptdroid.model.autocomplete;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@@ -12,7 +12,6 @@ import java.util.List;
|
|||||||
public class Module {
|
public class Module {
|
||||||
|
|
||||||
@SerializedName("properties")
|
@SerializedName("properties")
|
||||||
|
|
||||||
private List<Property> mProperties = new ArrayList<>();
|
private List<Property> mProperties = new ArrayList<>();
|
||||||
|
|
||||||
@SerializedName("url")
|
@SerializedName("url")
|
||||||
@@ -53,4 +52,8 @@ public class Module {
|
|||||||
public void setSummary(String summary) {
|
public void setSummary(String summary) {
|
||||||
mSummary = summary;
|
mSummary = summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Property asGlobalProperty() {
|
||||||
|
return new Property(mName, mUrl, mSummary, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,16 @@ public class Property {
|
|||||||
@SerializedName("global")
|
@SerializedName("global")
|
||||||
private boolean mGlobal;
|
private boolean mGlobal;
|
||||||
|
|
||||||
|
public Property() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Property(String key, String url, String summary, boolean global) {
|
||||||
|
mUrl = url;
|
||||||
|
mKey = key;
|
||||||
|
mSummary = summary;
|
||||||
|
mGlobal = global;
|
||||||
|
}
|
||||||
|
|
||||||
public String getUrl() {
|
public String getUrl() {
|
||||||
return mUrl;
|
return mUrl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,9 +63,9 @@ public class CodeMirrorEditor extends FrameLayout {
|
|||||||
|
|
||||||
|
|
||||||
public interface Callback {
|
public interface Callback {
|
||||||
void onChange();
|
|
||||||
|
|
||||||
void updateCodeCompletion(int fromLine, int fromCh, int toLine, int toCh, String[] list, String[] urls);
|
void onKeyUp(String line, int ch);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String[] sAvailableThemes;
|
private static String[] sAvailableThemes;
|
||||||
@@ -134,17 +134,14 @@ public class CodeMirrorEditor extends FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setTheme(final String theme) {
|
public void setTheme(final String theme) {
|
||||||
mPageFinished.promise().done(new DoneCallback<Void>() {
|
mPageFinished.promise().done(result -> {
|
||||||
@Override
|
evalJavaScript(String.format(Locale.getDefault(),
|
||||||
public void onDone(Void result) {
|
"var e = document.createElement('link');e.setAttribute('rel', 'stylesheet');" +
|
||||||
evalJavaScript(String.format(Locale.getDefault(),
|
"e.setAttribute('type', 'text/css');e.setAttribute('href', '%s');" +
|
||||||
"var e = document.createElement('link');e.setAttribute('rel', 'stylesheet');" +
|
"document.getElementsByTagName('head')[0].appendChild(e);",
|
||||||
"e.setAttribute('type', 'text/css');e.setAttribute('href', '%s');" +
|
"codemirror/theme/" + theme + ".css"));
|
||||||
"document.getElementsByTagName('head')[0].appendChild(e);",
|
evalJavaScript(String.format(Locale.getDefault(), "editor.setOption('theme', '%s');", theme));
|
||||||
"codemirror/theme/" + theme + ".css"));
|
mTheme = theme;
|
||||||
evalJavaScript(String.format(Locale.getDefault(), "editor.setOption('theme', '%s');", theme));
|
|
||||||
mTheme = theme;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,19 +439,11 @@ public class CodeMirrorEditor extends FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JavascriptInterface
|
@JavascriptInterface
|
||||||
public void onTextChange() {
|
public void onKeyUp(String line, int cursor) {
|
||||||
if (mCallback == null) {
|
if (mCallback == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mWebView.post(() -> mCallback.onChange());
|
mWebView.post(() -> mCallback.onKeyUp(line, cursor));
|
||||||
}
|
|
||||||
|
|
||||||
@JavascriptInterface
|
|
||||||
public void updateCodeCompletion(final int fromLine, final int fromCh, final int toLine, final int toCh, final String[] list, final String[] urls) {
|
|
||||||
if (mCallback == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mWebView.post(() -> mCallback.updateCodeCompletion(fromLine, fromCh, toLine, toCh, list, urls));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -534,28 +523,4 @@ public class CodeMirrorEditor extends FrameLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MyInputConnection extends InputConnectProxy {
|
|
||||||
|
|
||||||
public MyInputConnection(InputConnection inputConnection) {
|
|
||||||
super(inputConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean sendKeyEvent(KeyEvent event) {
|
|
||||||
Log.d(LOG_TAG, "sendKeyEvent: " + event);
|
|
||||||
return super.sendKeyEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean performContextMenuAction(int id) {
|
|
||||||
if (id == android.R.id.selectAll) {
|
|
||||||
post(CodeMirrorEditor.this::selectAll);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (id == android.R.id.startSelectingText) {
|
|
||||||
evalJavaScript("editor.setSelection(editor.getCursor(), {line: editor.getCursor().line, ch: editor.getCursor().ch - 1});");
|
|
||||||
}
|
|
||||||
return super.performContextMenuAction(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,18 +19,19 @@ import android.widget.ImageView;
|
|||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
import com.stardust.autojs.engine.JavaScriptEngine;
|
import com.stardust.autojs.engine.JavaScriptEngine;
|
||||||
import com.stardust.autojs.execution.ScriptExecution;
|
import com.stardust.autojs.execution.ScriptExecution;
|
||||||
import com.stardust.autojs.script.JavaScriptFileSource;
|
|
||||||
import com.stardust.pio.PFiles;
|
import com.stardust.pio.PFiles;
|
||||||
import com.stardust.scriptdroid.Pref;
|
import com.stardust.scriptdroid.Pref;
|
||||||
import com.stardust.scriptdroid.R;
|
import com.stardust.scriptdroid.R;
|
||||||
|
import com.stardust.scriptdroid.model.autocomplete.AutoCompletion;
|
||||||
|
import com.stardust.scriptdroid.model.autocomplete.CodeCompletion;
|
||||||
import com.stardust.scriptdroid.model.indices.Module;
|
import com.stardust.scriptdroid.model.indices.Module;
|
||||||
import com.stardust.scriptdroid.model.indices.Property;
|
import com.stardust.scriptdroid.model.indices.Property;
|
||||||
import com.stardust.scriptdroid.model.script.Scripts;
|
import com.stardust.scriptdroid.model.script.Scripts;
|
||||||
import com.stardust.scriptdroid.ui.doc.ManualDialog;
|
import com.stardust.scriptdroid.ui.doc.ManualDialog;
|
||||||
import com.stardust.scriptdroid.ui.edit.completion.CodeCompletions;
|
import com.stardust.scriptdroid.model.autocomplete.CodeCompletions;
|
||||||
import com.stardust.scriptdroid.ui.edit.completion.CodeCompletionBar;
|
import com.stardust.scriptdroid.ui.edit.completion.CodeCompletionBar;
|
||||||
import com.stardust.scriptdroid.ui.edit.completion.InputMethodEnhancedBarColors;
|
import com.stardust.scriptdroid.ui.edit.completion.InputMethodEnhancedBarColors;
|
||||||
import com.stardust.scriptdroid.ui.edit.completion.Symbols;
|
import com.stardust.scriptdroid.model.autocomplete.Symbols;
|
||||||
import com.stardust.scriptdroid.ui.edit.keyboard.FunctionsKeyboardHelper;
|
import com.stardust.scriptdroid.ui.edit.keyboard.FunctionsKeyboardHelper;
|
||||||
import com.stardust.scriptdroid.ui.edit.keyboard.FunctionsKeyboardView;
|
import com.stardust.scriptdroid.ui.edit.keyboard.FunctionsKeyboardView;
|
||||||
import com.stardust.scriptdroid.ui.log.LogActivity_;
|
import com.stardust.scriptdroid.ui.log.LogActivity_;
|
||||||
@@ -101,9 +102,9 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
|||||||
private String mName;
|
private String mName;
|
||||||
private File mFile;
|
private File mFile;
|
||||||
private boolean mReadOnly = false;
|
private boolean mReadOnly = false;
|
||||||
|
|
||||||
private ScriptExecution mScriptExecution;
|
private ScriptExecution mScriptExecution;
|
||||||
private boolean mTextChanged = false;
|
private boolean mTextChanged = false;
|
||||||
|
private AutoCompletion mAutoCompletion;
|
||||||
private FunctionsKeyboardHelper mFunctionsKeyboardHelper;
|
private FunctionsKeyboardHelper mFunctionsKeyboardHelper;
|
||||||
private BroadcastReceiver mOnRunFinishedReceiver = new BroadcastReceiver() {
|
private BroadcastReceiver mOnRunFinishedReceiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
@@ -220,34 +221,27 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
|||||||
mSymbolBar.setCodeCompletions(Symbols.getSymbols());
|
mSymbolBar.setCodeCompletions(Symbols.getSymbols());
|
||||||
mCodeCompletionBar.setOnHintClickListener(this);
|
mCodeCompletionBar.setOnHintClickListener(this);
|
||||||
mSymbolBar.setOnHintClickListener(this);
|
mSymbolBar.setOnHintClickListener(this);
|
||||||
|
mAutoCompletion = new AutoCompletion(getContext());
|
||||||
|
mAutoCompletion.setAutoCompleteCallback(mCodeCompletionBar::setCodeCompletions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void setUpEditor() {
|
private void setUpEditor() {
|
||||||
setTheme(PreferenceManager.getDefaultSharedPreferences(getContext())
|
setTheme(PreferenceManager.getDefaultSharedPreferences(getContext())
|
||||||
.getString(KEY_EDITOR_THEME, mEditor.getTheme()));
|
.getString(KEY_EDITOR_THEME, mEditor.getTheme()));
|
||||||
mEditor.setCallback(new CodeMirrorEditor.Callback() {
|
mEditor.setCallback((line, cursor) -> {
|
||||||
@Override
|
mTextChanged = true;
|
||||||
public void onChange() {
|
setMenuItemStatus(R.id.save, true);
|
||||||
mTextChanged = true;
|
autoComplete(line, cursor);
|
||||||
setMenuItemStatus(R.id.save, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateCodeCompletion(int fromLine, int fromCh, int toLine, int toCh, final String[] list, final String[] urls) {
|
|
||||||
mCodeCompletionBar.setCodeCompletions(new CodeCompletions(
|
|
||||||
new CodeCompletions.Pos(fromLine, fromCh),
|
|
||||||
new CodeCompletions.Pos(toLine, toCh),
|
|
||||||
Arrays.asList(list),
|
|
||||||
Arrays.asList(urls)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void autoComplete(String line, int cursor) {
|
||||||
|
mAutoCompletion.onCursorChange(line, cursor);
|
||||||
|
}
|
||||||
|
|
||||||
public void setTheme(String theme) {
|
public void setTheme(String theme) {
|
||||||
mEditor.setTheme(theme);
|
mEditor.setTheme(theme);
|
||||||
mInputMethodEnhanceBar.setBackgroundColor(InputMethodEnhancedBarColors.getBackgroundColor(theme));
|
mInputMethodEnhanceBar.setBackgroundColor(InputMethodEnhancedBarColors.getBackgroundColor(theme));
|
||||||
@@ -403,21 +397,16 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onHintClick(CodeCompletions completions, int pos) {
|
public void onHintClick(CodeCompletions completions, int pos) {
|
||||||
if (completions.shouldBeInserted()) {
|
CodeCompletion completion = completions.get(pos);
|
||||||
mEditor.insert(completions.getHints().get(pos));
|
mEditor.insert(completion.getInsertText());
|
||||||
return;
|
|
||||||
}
|
|
||||||
mEditor.replace(completions.getHints().get(pos), completions.getFrom().line, completions.getFrom().ch,
|
|
||||||
completions.getTo().line, completions.getTo().ch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onHintLongClick(CodeCompletions completions, int pos) {
|
public void onHintLongClick(CodeCompletions completions, int pos) {
|
||||||
String url = completions.getUrltAt(pos);
|
CodeCompletion completion = completions.get(pos);
|
||||||
if (url == null)
|
if (completion.getUrl() == null)
|
||||||
return;
|
return;
|
||||||
showManual(url, completions.getHints().get(pos));
|
showManual(completion.getUrl(), completion.getHint());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showManual(String url, String title) {
|
private void showManual(String url, String title) {
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
package com.stardust.scriptdroid.ui.edit.completion;
|
package com.stardust.scriptdroid.ui.edit.completion;
|
||||||
|
|
||||||
import android.content.ClipData;
|
|
||||||
import android.content.ClipboardManager;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
@@ -11,26 +8,10 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
|
||||||
import android.workground.WrapContentLinearLayoutManager;
|
import android.workground.WrapContentLinearLayoutManager;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import com.stardust.pio.UncheckedIOException;
|
|
||||||
import com.stardust.scriptdroid.R;
|
import com.stardust.scriptdroid.R;
|
||||||
import com.stardust.scriptdroid.tool.GsonUtils;
|
import com.stardust.scriptdroid.model.autocomplete.CodeCompletions;
|
||||||
import com.stardust.util.ClipboardUtil;
|
|
||||||
import com.stardust.util.UnderuseExecutors;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on 2017/2/17.
|
* Created by Stardust on 2017/2/17.
|
||||||
@@ -51,7 +32,7 @@ public class CodeCompletionBar extends RecyclerView {
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
int position = getChildViewHolder(v).getAdapterPosition();
|
int position = getChildViewHolder(v).getAdapterPosition();
|
||||||
if (position >= 0 && position < mCodeCompletions.getHints().size()) {
|
if (position >= 0 && position < mCodeCompletions.size()) {
|
||||||
if (mOnHintClickListener != null) {
|
if (mOnHintClickListener != null) {
|
||||||
mOnHintClickListener.onHintClick(mCodeCompletions, position);
|
mOnHintClickListener.onHintClick(mCodeCompletions, position);
|
||||||
}
|
}
|
||||||
@@ -64,7 +45,7 @@ public class CodeCompletionBar extends RecyclerView {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onLongClick(View v) {
|
public boolean onLongClick(View v) {
|
||||||
int position = getChildViewHolder(v).getAdapterPosition();
|
int position = getChildViewHolder(v).getAdapterPosition();
|
||||||
if (position < 0 || position >= mCodeCompletions.getHints().size())
|
if (position < 0 || position >= mCodeCompletions.size())
|
||||||
return false;
|
return false;
|
||||||
if (mOnHintClickListener != null) {
|
if (mOnHintClickListener != null) {
|
||||||
mOnHintClickListener.onHintLongClick(mCodeCompletions, position);
|
mOnHintClickListener.onHintLongClick(mCodeCompletions, position);
|
||||||
@@ -122,7 +103,7 @@ public class CodeCompletionBar extends RecyclerView {
|
|||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||||
TextView textView = ((TextView) holder.itemView);
|
TextView textView = ((TextView) holder.itemView);
|
||||||
textView.setText(mCodeCompletions.getHints().get(position));
|
textView.setText(mCodeCompletions.getHint(position));
|
||||||
if (mTextColor != 0) {
|
if (mTextColor != 0) {
|
||||||
textView.setTextColor(mTextColor);
|
textView.setTextColor(mTextColor);
|
||||||
}
|
}
|
||||||
@@ -130,7 +111,7 @@ public class CodeCompletionBar extends RecyclerView {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return mCodeCompletions == null ? 0 : mCodeCompletions.getHints().size();
|
return mCodeCompletions == null ? 0 : mCodeCompletions.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
package com.stardust.scriptdroid.ui.edit.completion;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Stardust on 2017/9/27.
|
|
||||||
*/
|
|
||||||
// TODO: 2017/10/24 refactor
|
|
||||||
public class CodeCompletions {
|
|
||||||
|
|
||||||
public static class Pos {
|
|
||||||
public int line;
|
|
||||||
public int ch;
|
|
||||||
|
|
||||||
public Pos(int line, int ch) {
|
|
||||||
this.line = line;
|
|
||||||
this.ch = ch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Pos mFrom;
|
|
||||||
private Pos mTo;
|
|
||||||
private List<String> mHints;
|
|
||||||
private List<String> mUrls;
|
|
||||||
|
|
||||||
public CodeCompletions(Pos from, Pos to, List<String> hints, List<String> urls) {
|
|
||||||
mFrom = from;
|
|
||||||
mTo = to;
|
|
||||||
mHints = hints;
|
|
||||||
mUrls = urls;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CodeCompletions just(List<String> hints) {
|
|
||||||
return new CodeCompletions(null, null, hints, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pos getFrom() {
|
|
||||||
return mFrom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pos getTo() {
|
|
||||||
return mTo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUrltAt(int pos) {
|
|
||||||
if (mUrls == null)
|
|
||||||
return null;
|
|
||||||
return mUrls.get(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getHints() {
|
|
||||||
return mHints;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean shouldBeInserted() {
|
|
||||||
return mFrom == null && mTo == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user