diff --git a/src/assets/plugins/codemirror/addon/hint/anyword-hint.js b/src/assets/plugins/codemirror/addon/hint/anyword-hint-modified.js similarity index 100% rename from src/assets/plugins/codemirror/addon/hint/anyword-hint.js rename to src/assets/plugins/codemirror/addon/hint/anyword-hint-modified.js diff --git a/src/assets/plugins/codemirror/addon/hint/javascript-hint.js b/src/assets/plugins/codemirror/addon/hint/javascript-hint-modified.js similarity index 98% rename from src/assets/plugins/codemirror/addon/hint/javascript-hint.js rename to src/assets/plugins/codemirror/addon/hint/javascript-hint-modified.js index 6bcec41..ca9b001 100644 --- a/src/assets/plugins/codemirror/addon/hint/javascript-hint.js +++ b/src/assets/plugins/codemirror/addon/hint/javascript-hint-modified.js @@ -61,11 +61,9 @@ } else { // add anyword var anyword = CodeMirror.hint.anyword(editor, options).list - if (anyword[0] != token.string) { - anyword.forEach(a => { + anyword.forEach(a => { if (!hints.includes(a)) hints.push(a) - }) - } + }) // add specialVars var specialVars = localStorage['specialVars'] if(specialVars) specialVars.split(',').forEach(s => { diff --git a/src/assets/plugins/codemirror/addon/hint/python-hint-additional.js b/src/assets/plugins/codemirror/addon/hint/python-hint-additional.js new file mode 100644 index 0000000..afac49a --- /dev/null +++ b/src/assets/plugins/codemirror/addon/hint/python-hint-additional.js @@ -0,0 +1,121 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: https://codemirror.net/LICENSE +// python-hints by fofolee + +(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 scriptHint(editor, 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; + var innerMode = CodeMirror.innerMode(editor.getMode(), token.state); + if (innerMode.mode.helperType === "json") return; + token.state = innerMode.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 hints = [], + lineText = editor.getLine(cur.line) + if (token.type == "property") { + // 已导入模块的属性(方法)提示 + mod = getToken(editor, Pos(cur.line, token.start - 1)).string; + if (editor.loadedPyModes && editor.loadedPyModes[mod]) { + var context = editor.loadedPyModes[mod] + hints = token.string ? context.filter(x => x.slice(0, token.string.length) == token.string) : context + } + } else if (token.string == "") { + if (!token.end && editor.loadedPyModes && editor.loadedPyModes.loading && cur.line) { + // 获取已导入的模块 + var lastline = editor.getLine(cur.line - 1) + mods = lastline.replace('import', '').trim().split(',').map(x => x.trim()) + mods.forEach(mod => { + dirPythonMod(mod, items => { + editor.loadedPyModes[mod] = items + }) + }) + editor.loadedPyModes.loading = false + } + } else if (/^import/.test(lineText)) { + // 已安装模块提示 + hints = JSON.parse(localStorage['pyModules']).filter(x => x.slice(0, token.string.length) == token.string) + editor.loadedPyModes || (editor.loadedPyModes = {}) + editor.loadedPyModes.loading = true + } else { + // 关键字提示 + hints = getCommonHints().filter(x => x.slice(0, token.string.length) == token.string) + // 特殊变量提示 + var specialVars = localStorage['specialVars'] + if (specialVars) specialVars.split(',').forEach(s => { + if (s.toUpperCase().slice(2, token.string.length + 2) == token.string.toUpperCase()) hints.push(s) + }) + // 本地单词提示 + var anyword = CodeMirror.hint.anyword(editor, options).list + anyword.forEach(a => { + if (!hints.includes(a)) hints.push(a) + }) + } + return { + list: hints, + from: Pos(cur.line, token.start), + to: Pos(cur.line, token.end) + }; + } + + function pythonHint(editor, options) { + return scriptHint(editor, function(e, cur) { return e.getTokenAt(cur); }, options); + }; + CodeMirror.registerHelper("hint", "python", pythonHint); + + function getCommonHints(py3) { + var wordOperators = ["and", "or", "not", "is"] + var commonKeywords = ["as", "assert", "break", "class", "continue", + "def", "del", "elif", "else", "except", "finally", + "for", "from", "global", "if", "import", + "lambda", "pass", "raise", "return", + "try", "while", "with", "yield", "in" + ]; + var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callable", "chr", + "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod", + "enumerate", "eval", "filter", "float", "format", "frozenset", + "getattr", "globals", "hasattr", "hash", "help", "hex", "id", + "input", "int", "isinstance", "issubclass", "iter", "len", + "list", "locals", "map", "max", "memoryview", "min", "next", + "object", "oct", "open", "ord", "pow", "property", "range", + "repr", "reversed", "round", "set", "setattr", "slice", + "sorted", "staticmethod", "str", "sum", "super", "tuple", + "type", "vars", "zip", "__import__", "NotImplemented", + "Ellipsis", "__debug__" + ]; + var myKeywords, myBuiltins + if (py3) { + myKeywords = ["nonlocal", "False", "True", "None", "async", "await"] + myBuiltins = ["ascii", "bytes", "exec", "print"] + } else { + myKeywords = ["exec", "print"] + myBuiltins = ["apply", "basestring", "buffer", "cmp", "coerce", "execfile", + "file", "intern", "long", "raw_input", "reduce", "reload", + "unichr", "unicode", "xrange", "False", "True", "None" + ] + } + return wordOperators.concat(commonKeywords, commonBuiltins, myKeywords, myBuiltins) + } +}); \ No newline at end of file diff --git a/src/assets/plugins/codemirror/addon/hint/show-hint.js b/src/assets/plugins/codemirror/addon/hint/show-hint-modified.js similarity index 100% rename from src/assets/plugins/codemirror/addon/hint/show-hint.js rename to src/assets/plugins/codemirror/addon/hint/show-hint-modified.js diff --git a/src/assets/plugins/codemirror/mode/applescript/applescript.js b/src/assets/plugins/codemirror/mode/applescript/applescript-additional.js similarity index 100% rename from src/assets/plugins/codemirror/mode/applescript/applescript.js rename to src/assets/plugins/codemirror/mode/applescript/applescript-additional.js diff --git a/src/assets/plugins/codemirror/mode/cmd/cmd-additional.js b/src/assets/plugins/codemirror/mode/cmd/cmd-additional.js new file mode 100644 index 0000000..e52d5d6 --- /dev/null +++ b/src/assets/plugins/codemirror/mode/cmd/cmd-additional.js @@ -0,0 +1,174 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: https://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) { + "use strict"; + + CodeMirror.defineMode('cmd', function() { + + var words = {}; + + function define(style, dict) { + for (var i = 0; i < dict.length; i++) { + words[dict[i]] = style; + } + }; + + var commonAtoms = ["true", "false"] + var commonKeywords = 'goto|call|exit|break|exist|defined|errorlevel|cmdextversion|if|else|for|EQU|NEQ|LSS|LEQ|GTR|GEQ'.split('|') + var commonCommands = 'assoc|bcdedit|cd|chcp|chdir|cls|color|copy|date|del|dir|echo|endlocal|erase|format|ftype|graftabl|md|mkdir|mklink|mode|more|move|path|pause|popd|prompt|pushd|rd|rem|ren|rename|rmdir|robocopy|set|setlocal|shift|start|time|title|tree|type|ver|verify|vol|wmic'.split("|") + + function cmdHint(editor, options) { + var cur = editor.getCursor(), + token = editor.getTokenAt(cur); + if (token.string == "") return + // 关键字提示 + var hints = commonAtoms.concat(commonKeywords, commonCommands) + var localCommands = JSON.parse(localStorage['cmdCommands']).filter(x => !hints.includes(x)) + hints = hints.concat(localCommands).filter(x => x.slice(0, token.string.length) == token.string) + // 特殊变量提示 + var specialVars = localStorage['specialVars'] + if (specialVars) specialVars.split(',').forEach(s => { + if (s.toUpperCase().slice(2, token.string.length + 2) == token.string.toUpperCase()) hints.push(s) + }) + // 本地单词提示 + var anyword = CodeMirror.hint.anyword(editor, options).list + anyword.forEach(a => { + if (!hints.includes(a)) hints.push(a) + }) + return { + list: hints, + from: CodeMirror.Pos(cur.line, token.start), + to: CodeMirror.Pos(cur.line, token.end) + }; + } + + CodeMirror.registerHelper("hint", "cmd", cmdHint); + + define('atom', commonAtoms); + define('keyword', commonKeywords); + define('builtin', commonCommands); + + function tokenBase(stream, state) { + if (stream.eatSpace()) return null; + + var sol = stream.sol(); + var ch = stream.next(); + + // if (ch === '\\') { + // stream.next(); + // return null; + // } + if (ch === '\'' || ch === '"') { + state.tokens.unshift(tokenString(ch, ch === "`" ? "quote" : "string")); + return tokenize(stream, state); + } + if (ch === ':') { + // if (sol && stream.eat('!')) { + // stream.skipToEnd(); + // return 'meta'; // 'comment'? + // } + if (stream.eat(':')) { + stream.skipToEnd(); + return 'comment'; + } + } + if (ch === '%') { + state.tokens.unshift(tokenDollar); + return tokenize(stream, state); + } + if (ch === '+' || ch === '=' || ch === '@') { + return 'operator'; + } + if (ch === '-') { + stream.eat(ch); + stream.eatWhile(/\w/); + return 'attribute'; + } + if (/^[0-9\.]/.test(ch)) { + stream.eatWhile(/\d/); + if (stream.eol() || !/\w/.test(stream.peek())) { + return 'number'; + } + } + stream.eatWhile(/[\w-]/); + var cur = stream.current(); + if (stream.peek() === '=' && /\w+/.test(cur)) return 'def'; + return words.hasOwnProperty(cur) ? words[cur] : null; + } + + function tokenString(quote, style) { + var close = quote == "(" ? ")" : quote == "{" ? "}" : quote + return function(stream, state) { + var next, escaped = false; + while ((next = stream.next()) != null) { + if (next === close && !escaped) { + state.tokens.shift(); + break; + } else if (next === '$' && !escaped && quote !== "'" && stream.peek() != close) { + escaped = true; + stream.backUp(1); + state.tokens.unshift(tokenDollar); + break; + } else if (!escaped && quote !== close && next === quote) { + state.tokens.unshift(tokenString(quote, style)) + return tokenize(stream, state) + } else if (!escaped && /['"]/.test(next) && !/['"]/.test(quote)) { + state.tokens.unshift(tokenStringStart(next, "string")); + stream.backUp(1); + break; + } + escaped = !escaped && next === '\\'; + } + return style; + }; + }; + + function tokenStringStart(quote, style) { + return function(stream, state) { + state.tokens[0] = tokenString(quote, style) + stream.next() + return tokenize(stream, state) + } + } + + var tokenDollar = function(stream, state) { + if (state.tokens.length > 1) stream.eat('$'); + var ch = stream.next() + if (/['"({]/.test(ch)) { + state.tokens[0] = tokenString(ch, ch == "(" ? "quote" : ch == "{" ? "def" : "string"); + return tokenize(stream, state); + } + if (!/\d/.test(ch)) stream.eatWhile(/\w/); + state.tokens.shift(); + return 'def'; + }; + + function tokenize(stream, state) { + return (state.tokens[0] || tokenBase)(stream, state); + }; + + return { + startState: function() { return { tokens: [] }; }, + token: function(stream, state) { + return tokenize(stream, state); + }, + closeBrackets: "()[]{}''\"\"", + lineComment: '::', + fold: "brace" + }; + }); + + CodeMirror.defineMIME('text/x-sh', 'cmd'); + // Apache uses a slightly different Media Type for cmd scripts + // http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types + CodeMirror.defineMIME('application/x-sh', 'cmd'); + +}); \ No newline at end of file diff --git a/src/assets/plugins/codemirror/mode/cmd/cmd.js b/src/assets/plugins/codemirror/mode/cmd/cmd.js deleted file mode 100644 index d8a4d52..0000000 --- a/src/assets/plugins/codemirror/mode/cmd/cmd.js +++ /dev/null @@ -1,150 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: https://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) { -"use strict"; - -CodeMirror.defineMode('cmd', function() { - - var words = {}; - function define(style, dict) { - for(var i = 0; i < dict.length; i++) { - words[dict[i]] = style; - } - }; - - var commonAtoms = ["true", "false"] - var commonKeywords = 'goto|call|exit|break|exist|defined|errorlevel|cmdextversion|if|else|for|EQU|NEQ|LSS|LEQ|GTR|GEQ'.split('|') - var commonCommands = 'assoc|bcdedit|cd|chcp|chdir|cls|color|copy|date|del|dir|echo|endlocal|erase|format|ftype|graftabl|md|mkdir|mklink|mode|more|move|path|pause|popd|prompt|pushd|rd|rem|ren|rename|rmdir|robocopy|set|setlocal|shift|start|time|title|tree|type|ver|verify|vol|wmic'.split("|") - commonCommands = commonCommands.concat(getCmdCommand()) - - - CodeMirror.registerHelper("hintWords", "cmd", commonAtoms.concat(commonKeywords, commonCommands)); - - define('atom', commonAtoms); - define('keyword', commonKeywords); - define('builtin', commonCommands); - - function tokenBase(stream, state) { - if (stream.eatSpace()) return null; - - var sol = stream.sol(); - var ch = stream.next(); - - // if (ch === '\\') { - // stream.next(); - // return null; - // } - if (ch === '\'' || ch === '"') { - state.tokens.unshift(tokenString(ch, ch === "`" ? "quote" : "string")); - return tokenize(stream, state); - } - if (ch === ':') { - // if (sol && stream.eat('!')) { - // stream.skipToEnd(); - // return 'meta'; // 'comment'? - // } - if (stream.eat(':')) { - stream.skipToEnd(); - return 'comment'; - } - } - if (ch === '%') { - state.tokens.unshift(tokenDollar); - return tokenize(stream, state); - } - if (ch === '+' || ch === '=' || ch === '@') { - return 'operator'; - } - if (ch === '-') { - stream.eat(ch); - stream.eatWhile(/\w/); - return 'attribute'; - } - if (/^[0-9\.]/.test(ch)) { - stream.eatWhile(/\d/); - if(stream.eol() || !/\w/.test(stream.peek())) { - return 'number'; - } - } - stream.eatWhile(/[\w-]/); - var cur = stream.current(); - if (stream.peek() === '=' && /\w+/.test(cur)) return 'def'; - return words.hasOwnProperty(cur) ? words[cur] : null; - } - - function tokenString(quote, style) { - var close = quote == "(" ? ")" : quote == "{" ? "}" : quote - return function(stream, state) { - var next, escaped = false; - while ((next = stream.next()) != null) { - if (next === close && !escaped) { - state.tokens.shift(); - break; - } else if (next === '$' && !escaped && quote !== "'" && stream.peek() != close) { - escaped = true; - stream.backUp(1); - state.tokens.unshift(tokenDollar); - break; - } else if (!escaped && quote !== close && next === quote) { - state.tokens.unshift(tokenString(quote, style)) - return tokenize(stream, state) - } else if (!escaped && /['"]/.test(next) && !/['"]/.test(quote)) { - state.tokens.unshift(tokenStringStart(next, "string")); - stream.backUp(1); - break; - } - escaped = !escaped && next === '\\'; - } - return style; - }; - }; - - function tokenStringStart(quote, style) { - return function(stream, state) { - state.tokens[0] = tokenString(quote, style) - stream.next() - return tokenize(stream, state) - } - } - - var tokenDollar = function(stream, state) { - if (state.tokens.length > 1) stream.eat('$'); - var ch = stream.next() - if (/['"({]/.test(ch)) { - state.tokens[0] = tokenString(ch, ch == "(" ? "quote" : ch == "{" ? "def" : "string"); - return tokenize(stream, state); - } - if (!/\d/.test(ch)) stream.eatWhile(/\w/); - state.tokens.shift(); - return 'def'; - }; - - function tokenize(stream, state) { - return (state.tokens[0] || tokenBase) (stream, state); - }; - - return { - startState: function() {return {tokens:[]};}, - token: function(stream, state) { - return tokenize(stream, state); - }, - closeBrackets: "()[]{}''\"\"", - lineComment: '::', - fold: "brace" - }; -}); - -CodeMirror.defineMIME('text/x-sh', 'cmd'); -// Apache uses a slightly different Media Type for cmd scripts -// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types -CodeMirror.defineMIME('application/x-sh', 'cmd'); - -}); diff --git a/src/assets/plugins/codemirror/mode/powershell/powershell.js b/src/assets/plugins/codemirror/mode/powershell/powershell-modified.js similarity index 100% rename from src/assets/plugins/codemirror/mode/powershell/powershell.js rename to src/assets/plugins/codemirror/mode/powershell/powershell-modified.js diff --git a/src/assets/plugins/codemirror/mode/python/index.html b/src/assets/plugins/codemirror/mode/python/index.html deleted file mode 100644 index bdfc8f5..0000000 --- a/src/assets/plugins/codemirror/mode/python/index.html +++ /dev/null @@ -1,207 +0,0 @@ - - -CodeMirror: Python mode - - - - - - - - - - -
-

Python mode

- -
- - -

Cython mode

- -
- - -

Configuration Options for Python mode:

- -

Advanced Configuration Options:

-

Usefull for superset of python syntax like Enthought enaml, IPython magics and questionmark help

- - - -

MIME types defined: text/x-python and text/x-cython.

-
diff --git a/src/assets/plugins/codemirror/mode/python/python.js b/src/assets/plugins/codemirror/mode/python/python-modified.js similarity index 87% rename from src/assets/plugins/codemirror/mode/python/python.js rename to src/assets/plugins/codemirror/mode/python/python-modified.js index ffd4599..919899d 100644 --- a/src/assets/plugins/codemirror/mode/python/python.js +++ b/src/assets/plugins/codemirror/mode/python/python-modified.js @@ -72,9 +72,7 @@ "unichr", "unicode", "xrange", "False", "True", "None"]); var stringPrefixes = new RegExp("^(([rubf]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i"); } - // python/lib - var libs = "BaseHTTPServer|Bastion|CGIHTTPServer|ConfigParser|Cookie|DocXMLRPCServer|HTMLParser|MimeWriter|Queue|SimpleHTTPServer|SimpleXMLRPCServer|SocketServer|StringIO|UserDict|UserList|UserString|_LWPCookieJar|_MozillaCookieJar|__future__|__phello__.foo|_abcoll|_osx_support|_pyio|_strptime|_threading_local|_weakrefset|abc|aifc|antigravity|anydbm|argparse|ast|asynchat|asyncore|atexit|audiodev|base64|bdb|binhex|bisect|cProfile|calendar|cgi|cgitb|chunk|cmd|code|codecs|codeop|collections|colorsys|commands|compileall|contextlib|cookielib|copy|copy_reg|csv|dbhash|decimal|difflib|dircache|dis|doctest|dumbdbm|dummy_thread|dummy_threading|filecmp|fileinput|fnmatch|formatter|fpformat|fractions|ftplib|functools|genericpath|getopt|getpass|gettext|glob|gzip|hashlib|heapq|hmac|htmlentitydefs|htmllib|httplib|ihooks|imaplib|imghdr|imputil|inspect|io|keyword|linecache|locale|macpath|macurl2path|mailbox|mailcap|markupbase|md5|mhlib|mimetools|mimetypes|mimify|modulefinder|multifile|mutex|netrc|new|nntplib|ntpath|nturl2path|numbers|opcode|optparse|os|pdb|pickle|pickletools|pipes|pkgutil|platform|plistlib|popen2|poplib|posixfile|posixpath|pprint|profile|pstats|pty|py_compile|pyclbr|pydoc|quopri|random|re|repr|rexec|rfc822|rlcompleter|robotparser|runpy|sched|sets|sgmllib|sha|shelve|shlex|shutil|site|smtpd|smtplib|sndhdr|socket|sre|sre_compile|sre_constants|sre_parse|ssl|stat|statvfs|string|stringold|stringprep|struct|subprocess|sunau|sunaudio|symbol|symtable|sysconfig|sys|tabnanny|tarfile|telnetlib|tempfile|textwrap|this|threading|timeit|toaiff|token|tokenize|trace|traceback|tty|types|urllib|urllib2|urlparse|user|uu|uuid|warnings|wave|weakref|webbrowser|whichdb|xdrlib|xmllib|xmlrpclib|zipfile|bsddb|curses|encoding|idlelib|Tkinter|msilib|unittest|compiler|distutil|ensurepip|importlib|lib2to3|multiprocessing|sqlite3|wsgiref|ctype|email|hotshot|json|logging|pydoc_data|xml|requests|BeautifulSoup" - CodeMirror.registerHelper("hintWords", "python", myKeywords.concat(myBuiltins, libs.split("|"))); + // CodeMirror.registerHelper("hintWords", "python", myKeywords.concat(myBuiltins, libs.split("|"))); var keywords = wordRegexp(myKeywords); var builtins = wordRegexp(myBuiltins); diff --git a/src/assets/plugins/codemirror/mode/python/test.js b/src/assets/plugins/codemirror/mode/python/test.js deleted file mode 100644 index 2b605b8..0000000 --- a/src/assets/plugins/codemirror/mode/python/test.js +++ /dev/null @@ -1,44 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: https://codemirror.net/LICENSE - -(function() { - var mode = CodeMirror.getMode({indentUnit: 4}, - {name: "python", - version: 3, - singleLineStringErrors: false}); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } - - // Error, because "foobarhello" is neither a known type or property, but - // property was expected (after "and"), and it should be in parentheses. - MT("decoratorStartOfLine", - "[meta @dec]", - "[keyword def] [def function]():", - " [keyword pass]"); - - MT("decoratorIndented", - "[keyword class] [def Foo]:", - " [meta @dec]", - " [keyword def] [def function]():", - " [keyword pass]"); - - MT("matmulWithSpace:", "[variable a] [operator @] [variable b]"); - MT("matmulWithoutSpace:", "[variable a][operator @][variable b]"); - MT("matmulSpaceBefore:", "[variable a] [operator @][variable b]"); - var before_equal_sign = ["+", "-", "*", "/", "=", "!", ">", "<"]; - for (var i = 0; i < before_equal_sign.length; ++i) { - var c = before_equal_sign[i] - MT("before_equal_sign_" + c, "[variable a] [operator " + c + "=] [variable b]"); - } - - MT("fValidStringPrefix", "[string f'this is a]{[variable formatted]}[string string']"); - MT("fValidExpressioninFString", "[string f'expression ]{[number 100][operator *][number 5]}[string string']"); - MT("fInvalidFString", "[error f'this is wrong}]"); - MT("fNestedFString", "[string f'expression ]{[number 100] [operator +] [string f'inner]{[number 5]}[string ']}[string string']"); - MT("uValidStringPrefix", "[string u'this is an unicode string']"); - - MT("nestedString", "[string f']{[variable b][[ [string \"c\"] ]]}[string f'] [comment # oops]") - - MT("bracesInFString", "[string f']{[variable x] [operator +] {}}[string !']") - - MT("nestedFString", "[string f']{[variable b][[ [string f\"c\"] ]]}[string f'] [comment # oops]") -})(); diff --git a/src/assets/plugins/codemirror/mode/shell/index.html b/src/assets/plugins/codemirror/mode/shell/index.html deleted file mode 100644 index 6aed459..0000000 --- a/src/assets/plugins/codemirror/mode/shell/index.html +++ /dev/null @@ -1,66 +0,0 @@ - - -CodeMirror: Shell mode - - - - - - - - - - -
-

Shell mode

- - - - - - -

MIME types defined: text/x-sh, application/x-sh.

-
diff --git a/src/assets/plugins/codemirror/mode/shell/shell-modified.js b/src/assets/plugins/codemirror/mode/shell/shell-modified.js new file mode 100644 index 0000000..4b6a987 --- /dev/null +++ b/src/assets/plugins/codemirror/mode/shell/shell-modified.js @@ -0,0 +1,174 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: https://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) { + "use strict"; + + CodeMirror.defineMode('shell', function() { + + var words = {}; + + function define(style, dict) { + for (var i = 0; i < dict.length; i++) { + words[dict[i]] = style; + } + }; + + var commonAtoms = ["true", "false"]; + var commonKeywords = ["if", "then", "do", "else", "elif", "while", "until", "for", "in", "esac", "fi", + "fin", "fil", "done", "exit", "set", "unset", "export", "function" + ]; + var commonCommands = 'ab|awk|bash|beep|cat|cc|cd|chown|chmod|chroot|clear|cp|curl|cut|diff|echo|find|gawk|gcc|get|git|grep|hg|kill|killall|ln|ls|make|mkdir|openssl|mv|nc|nl|node|npm|ping|ps|restart|rm|rmdir|sed|service|sh|shopt|shred|source|sort|sleep|ssh|start|stop|su|sudo|svn|tee|telnet|top|touch|vi|vim|wall|wc|wget|who|write|yes|zsh'.split("|") + + function shellHint(editor, options) { + var cur = editor.getCursor(), + token = editor.getTokenAt(cur); + if (token.string == "") return + // 关键字提示 + var hints = commonAtoms.concat(commonKeywords, commonCommands) + var localCommands = JSON.parse(localStorage['shellCommands']).filter(x => !hints.includes(x)) + hints = hints.concat(localCommands).filter(x => x.slice(0, token.string.length) == token.string) + // 特殊变量提示 + var specialVars = localStorage['specialVars'] + if (specialVars) specialVars.split(',').forEach(s => { + if (s.toUpperCase().slice(2, token.string.length + 2) == token.string.toUpperCase()) hints.push(s) + }) + // 本地单词提示 + var anyword = CodeMirror.hint.anyword(editor, options).list + anyword.forEach(a => { + if (!hints.includes(a)) hints.push(a) + }) + return { + list: hints, + from: CodeMirror.Pos(cur.line, token.start), + to: CodeMirror.Pos(cur.line, token.end) + }; + } + + CodeMirror.registerHelper("hint", "shell", shellHint); + + define('atom', commonAtoms); + define('keyword', commonKeywords); + define('builtin', commonCommands); + + function tokenBase(stream, state) { + if (stream.eatSpace()) return null; + + var sol = stream.sol(); + var ch = stream.next(); + + if (ch === '\\') { + stream.next(); + return null; + } + if (ch === '\'' || ch === '"' || ch === '`') { + state.tokens.unshift(tokenString(ch, ch === "`" ? "quote" : "string")); + return tokenize(stream, state); + } + if (ch === '#') { + if (sol && stream.eat('!')) { + stream.skipToEnd(); + return 'meta'; // 'comment'? + } + stream.skipToEnd(); + return 'comment'; + } + if (ch === '$') { + state.tokens.unshift(tokenDollar); + return tokenize(stream, state); + } + if (ch === '+' || ch === '=') { + return 'operator'; + } + if (ch === '-') { + stream.eat('-'); + stream.eatWhile(/\w/); + return 'attribute'; + } + if (/^[0-9\.]/.test(ch)) { + stream.eatWhile(/\d/); + if (stream.eol() || !/\w/.test(stream.peek())) { + return 'number'; + } + } + stream.eatWhile(/[\w-]/); + var cur = stream.current(); + if (stream.peek() === '=' && /\w+/.test(cur)) return 'def'; + return words.hasOwnProperty(cur) ? words[cur] : null; + } + + function tokenString(quote, style) { + var close = quote == "(" ? ")" : quote == "{" ? "}" : quote + return function(stream, state) { + var next, escaped = false; + while ((next = stream.next()) != null) { + if (next === close && !escaped) { + state.tokens.shift(); + break; + } else if (next === '$' && !escaped && quote !== "'" && stream.peek() != close) { + escaped = true; + stream.backUp(1); + state.tokens.unshift(tokenDollar); + break; + } else if (!escaped && quote !== close && next === quote) { + state.tokens.unshift(tokenString(quote, style)) + return tokenize(stream, state) + } else if (!escaped && /['"]/.test(next) && !/['"]/.test(quote)) { + state.tokens.unshift(tokenStringStart(next, "string")); + stream.backUp(1); + break; + } + escaped = !escaped && next === '\\'; + } + return style; + }; + }; + + function tokenStringStart(quote, style) { + return function(stream, state) { + state.tokens[0] = tokenString(quote, style) + stream.next() + return tokenize(stream, state) + } + } + + var tokenDollar = function(stream, state) { + if (state.tokens.length > 1) stream.eat('$'); + var ch = stream.next() + if (/['"({]/.test(ch)) { + state.tokens[0] = tokenString(ch, ch == "(" ? "quote" : ch == "{" ? "def" : "string"); + return tokenize(stream, state); + } + if (!/\d/.test(ch)) stream.eatWhile(/\w/); + state.tokens.shift(); + return 'def'; + }; + + function tokenize(stream, state) { + return (state.tokens[0] || tokenBase)(stream, state); + }; + + return { + startState: function() { return { tokens: [] }; }, + token: function(stream, state) { + return tokenize(stream, state); + }, + closeBrackets: "()[]{}''\"\"``", + lineComment: '#', + fold: "brace" + }; + }); + + CodeMirror.defineMIME('text/x-sh', 'shell'); + // Apache uses a slightly different Media Type for Shell scripts + // http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types + CodeMirror.defineMIME('application/x-sh', 'shell'); + +}); \ No newline at end of file diff --git a/src/assets/plugins/codemirror/mode/shell/shell.js b/src/assets/plugins/codemirror/mode/shell/shell.js deleted file mode 100644 index bc56f1e..0000000 --- a/src/assets/plugins/codemirror/mode/shell/shell.js +++ /dev/null @@ -1,148 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: https://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) { -"use strict"; - -CodeMirror.defineMode('shell', function() { - - var words = {}; - function define(style, dict) { - for(var i = 0; i < dict.length; i++) { - words[dict[i]] = style; - } - }; - - var commonAtoms = ["true", "false"]; - var commonKeywords = ["if", "then", "do", "else", "elif", "while", "until", "for", "in", "esac", "fi", - "fin", "fil", "done", "exit", "set", "unset", "export", "function"]; - var commonCommands = 'ab|awk|bash|beep|cat|cc|cd|chown|chmod|chroot|clear|cp|curl|cut|diff|echo|find|gawk|gcc|get|git|grep|hg|kill|killall|ln|ls|make|mkdir|openssl|mv|nc|nl|node|npm|ping|ps|restart|rm|rmdir|sed|service|sh|shopt|shred|source|sort|sleep|ssh|start|stop|su|sudo|svn|tee|telnet|top|touch|vi|vim|wall|wc|wget|who|write|yes|zsh'.split("|") - commonCommands = commonCommands.concat(getShellCommand()) - - CodeMirror.registerHelper("hintWords", "shell", commonAtoms.concat(commonKeywords, commonCommands)); - - define('atom', commonAtoms); - define('keyword', commonKeywords); - define('builtin', commonCommands); - - function tokenBase(stream, state) { - if (stream.eatSpace()) return null; - - var sol = stream.sol(); - var ch = stream.next(); - - if (ch === '\\') { - stream.next(); - return null; - } - if (ch === '\'' || ch === '"' || ch === '`') { - state.tokens.unshift(tokenString(ch, ch === "`" ? "quote" : "string")); - return tokenize(stream, state); - } - if (ch === '#') { - if (sol && stream.eat('!')) { - stream.skipToEnd(); - return 'meta'; // 'comment'? - } - stream.skipToEnd(); - return 'comment'; - } - if (ch === '$') { - state.tokens.unshift(tokenDollar); - return tokenize(stream, state); - } - if (ch === '+' || ch === '=') { - return 'operator'; - } - if (ch === '-') { - stream.eat('-'); - stream.eatWhile(/\w/); - return 'attribute'; - } - if (/^[0-9\.]/.test(ch)) { - stream.eatWhile(/\d/); - if(stream.eol() || !/\w/.test(stream.peek())) { - return 'number'; - } - } - stream.eatWhile(/[\w-]/); - var cur = stream.current(); - if (stream.peek() === '=' && /\w+/.test(cur)) return 'def'; - return words.hasOwnProperty(cur) ? words[cur] : null; - } - - function tokenString(quote, style) { - var close = quote == "(" ? ")" : quote == "{" ? "}" : quote - return function(stream, state) { - var next, escaped = false; - while ((next = stream.next()) != null) { - if (next === close && !escaped) { - state.tokens.shift(); - break; - } else if (next === '$' && !escaped && quote !== "'" && stream.peek() != close) { - escaped = true; - stream.backUp(1); - state.tokens.unshift(tokenDollar); - break; - } else if (!escaped && quote !== close && next === quote) { - state.tokens.unshift(tokenString(quote, style)) - return tokenize(stream, state) - } else if (!escaped && /['"]/.test(next) && !/['"]/.test(quote)) { - state.tokens.unshift(tokenStringStart(next, "string")); - stream.backUp(1); - break; - } - escaped = !escaped && next === '\\'; - } - return style; - }; - }; - - function tokenStringStart(quote, style) { - return function(stream, state) { - state.tokens[0] = tokenString(quote, style) - stream.next() - return tokenize(stream, state) - } - } - - var tokenDollar = function(stream, state) { - if (state.tokens.length > 1) stream.eat('$'); - var ch = stream.next() - if (/['"({]/.test(ch)) { - state.tokens[0] = tokenString(ch, ch == "(" ? "quote" : ch == "{" ? "def" : "string"); - return tokenize(stream, state); - } - if (!/\d/.test(ch)) stream.eatWhile(/\w/); - state.tokens.shift(); - return 'def'; - }; - - function tokenize(stream, state) { - return (state.tokens[0] || tokenBase) (stream, state); - }; - - return { - startState: function() {return {tokens:[]};}, - token: function(stream, state) { - return tokenize(stream, state); - }, - closeBrackets: "()[]{}''\"\"``", - lineComment: '#', - fold: "brace" - }; -}); - -CodeMirror.defineMIME('text/x-sh', 'shell'); -// Apache uses a slightly different Media Type for Shell scripts -// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types -CodeMirror.defineMIME('application/x-sh', 'shell'); - -}); diff --git a/src/assets/plugins/codemirror/mode/shell/test.js b/src/assets/plugins/codemirror/mode/shell/test.js deleted file mode 100644 index 7571d90..0000000 --- a/src/assets/plugins/codemirror/mode/shell/test.js +++ /dev/null @@ -1,73 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: https://codemirror.net/LICENSE - -(function() { - var mode = CodeMirror.getMode({}, "shell"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } - - MT("var", - "text [def $var] text"); - MT("varBraces", - "text[def ${var}]text"); - MT("varVar", - "text [def $a$b] text"); - MT("varBracesVarBraces", - "text[def ${a}${b}]text"); - - MT("singleQuotedVar", - "[string 'text $var text']"); - MT("singleQuotedVarBraces", - "[string 'text ${var} text']"); - - MT("doubleQuotedVar", - '[string "text ][def $var][string text"]'); - MT("doubleQuotedVarBraces", - '[string "text][def ${var}][string text"]'); - MT("doubleQuotedVarPunct", - '[string "text ][def $@][string text"]'); - MT("doubleQuotedVarVar", - '[string "][def $a$b][string "]'); - MT("doubleQuotedVarBracesVarBraces", - '[string "][def ${a}${b}][string "]'); - - MT("notAString", - "text\\'text"); - MT("escapes", - "outside\\'\\\"\\`\\\\[string \"inside\\`\\'\\\"\\\\`\\$notAVar\"]outside\\$\\(notASubShell\\)"); - - MT("subshell", - "[builtin echo] [quote $(whoami)] s log, stardate [quote `date`]."); - MT("doubleQuotedSubshell", - "[builtin echo] [string \"][quote $(whoami)][string 's log, stardate `date`.\"]"); - - MT("hashbang", - "[meta #!/bin/bash]"); - MT("comment", - "text [comment # Blurb]"); - - MT("numbers", - "[number 0] [number 1] [number 2]"); - MT("keywords", - "[keyword while] [atom true]; [keyword do]", - " [builtin sleep] [number 3]", - "[keyword done]"); - MT("options", - "[builtin ls] [attribute -l] [attribute --human-readable]"); - MT("operator", - "[def var][operator =]value"); - - MT("doubleParens", - "foo [quote $((bar))]") - - MT("nested braces", - "[builtin echo] [def ${A[${B}]]}]") - - MT("strings in parens", - "[def FOO][operator =]([quote $(<][string \"][def $MYDIR][string \"][quote /myfile grep ][string 'hello$'][quote )])") - - MT ("string ending in dollar", - '[def a][operator =][string "xyz$"]; [def b][operator =][string "y"]') - - MT ("quote ending in dollar", - "[quote $(echo a$)]") -})(); diff --git a/src/assets/plugins/codemirrorloader.js b/src/assets/plugins/codemirrorloader.js index 0119e32..2aff54e 100644 --- a/src/assets/plugins/codemirrorloader.js +++ b/src/assets/plugins/codemirrorloader.js @@ -3,11 +3,11 @@ main = "./assets/plugins/codemirror/lib/codemirror.js" modes = [ - "./assets/plugins/codemirror/mode/shell/shell.js", - "./assets/plugins/codemirror/mode/cmd/cmd.js", - "./assets/plugins/codemirror/mode/applescript/applescript.js", - "./assets/plugins/codemirror/mode/powershell/powershell.js", - "./assets/plugins/codemirror/mode/python/python.js", + "./assets/plugins/codemirror/mode/shell/shell-modified.js", + "./assets/plugins/codemirror/mode/cmd/cmd-additional.js", + "./assets/plugins/codemirror/mode/applescript/applescript-additional.js", + "./assets/plugins/codemirror/mode/powershell/powershell-modified.js", + "./assets/plugins/codemirror/mode/python/python-modified.js", "./assets/plugins/codemirror/mode/javascript/javascript.js", "./assets/plugins/codemirror/mode/ruby/ruby.js", "./assets/plugins/codemirror/mode/php/php.js", @@ -23,9 +23,10 @@ addons = [ "./assets/plugins/codemirror/addon/display/placeholder.js", "./assets/plugins/codemirror/addon/comment/comment.js", "./assets/plugins/codemirror/addon/selection/active-line.js", - "./assets/plugins/codemirror/addon/hint/show-hint.js", - "./assets/plugins/codemirror/addon/hint/anyword-hint.js", - "./assets/plugins/codemirror/addon/hint/javascript-hint.js", + "./assets/plugins/codemirror/addon/hint/show-hint-modified.js", + "./assets/plugins/codemirror/addon/hint/anyword-hint-modified.js", + "./assets/plugins/codemirror/addon/hint/javascript-hint-modified.js", + "./assets/plugins/codemirror/addon/hint/python-hint-additional.js", "./assets/plugins/codemirror/addon/edit/matchbrackets.js", "./assets/plugins/codemirror/addon/edit/closebrackets.js", "./assets/plugins/codemirror/addon/search/search.js",