From 669a883193ff8dc8fd92f84bd478baca3e4995c3 Mon Sep 17 00:00:00 2001 From: shaoying Date: Fri, 29 May 2020 23:48:24 +0800 Subject: [PATCH] opt split --- frame.js | 5 +- index.css | 16 ++++ lib/base.js | 4 +- lib/core.js | 58 ++++--------- plugin/inner.css | 13 +++ plugin/inner.js | 222 ++++++++++++++++++++++++++++++++++++++++------- 6 files changed, 241 insertions(+), 77 deletions(-) diff --git a/frame.js b/frame.js index b753c084..efe8e5bf 100644 --- a/frame.js +++ b/frame.js @@ -361,7 +361,7 @@ Volcanos("onappend", { _init: function(can, meta, list, cb, target, field) { var ui = can.page.Appends(can, can._toast, [ {text: [meta.title||"", "div", "title"]}, - {text: [meta.text||"执行成功", "div", "content"]}, + typeof meta.text == "object"? meta.text: {text: [meta.text||"执行成功", "div", "content"]}, {view: ["button"], list: meta.button}, {text: ["", "div", "duration"]}, ]) @@ -381,6 +381,9 @@ Volcanos("onappend", { _init: function(can, meta, list, cb, target, field) { }, function() { can.page.Modify(can, can._toast, {style: {display: "none"}}) }) + ui.Close = function() { + can.page.Modify(can, can._toast, {style: {display: "none"}}) + } return ui }, share: function(can, msg) { diff --git a/index.css b/index.css index 6737a091..ce4b6ed4 100644 --- a/index.css +++ b/index.css @@ -91,6 +91,22 @@ fieldset div.output { clear:both; overflow:auto; } +fieldset div.output>div.project { + float:left; +} +fieldset div.output>div.project>div.item { + clear:both; +} +fieldset div.output>div.project>div.item:hover { + border:solid 1px red; +} +fieldset div.output>pre.display { + padding:4px; + max-height:80px; + border:solid 2px red; + margin:0; + overflow:auto; +} fieldset div.code { color:white; font-size:14px; diff --git a/lib/base.js b/lib/base.js index 63602837..96fcb516 100644 --- a/lib/base.js +++ b/lib/base.js @@ -2,9 +2,9 @@ Volcanos("base", {help: "基础模块", isNone: function(c) {return c === undefined || c === null}, isSpace: function(c) {return c == " " || c == "Enter"}, - Path: function() {var res = "/" + Path: function() {var res = "" for (var i = 0; i < arguments.length; i++) { - res = (arguments[i].indexOf("/") == 0? "": res) + "/" + arguments[i] + res += (arguments[i].indexOf("/") == 0 || res.endsWith("/")? "": "/") + arguments[i] } return res }, diff --git a/lib/core.js b/lib/core.js index a3f6aa8b..dc5904fd 100644 --- a/lib/core.js +++ b/lib/core.js @@ -62,78 +62,56 @@ Volcanos("core", {help: "核心模块", }), Split: shy("分词器", function(str) { if (!str || !str.length) {return []} + var arg = []; for (var i = 1; i < arguments.length; i++) { arg.push(arguments[i]) } - var arg = []; for (var i = 1; i < arguments.length; i++) { - arg.push(arguments[i]) - } - + function trans(str) { var res = {}; for (var i = 0; i < str.length; i++) { res[str[i]] = true }; return res } // 空白符 - var sep = "\t ,\n" - if (arg.length > 0 && arg[0].length > 0) { - sep = arg[0] - } - for (var i = sep.length; i < 5; i++) { - sep += sep[0] - } - + var seps = trans(arg[0]||"\t ,\n"); // 分隔符 - var sup = "{[()]}" - if (arg.length > 1 && arg[1].length > 0) { - sup = arg[1] - } - for (var i = sup.length; i < 10; i++) { - sup += sup[0] - } - + var sups = trans(arg[1]||"{[(.:)]}"); // 引用符 - var sub = "'\"`" - if (arg.length > 2 && arg[2].length > 0) { - sub = arg[2] - } - for (var i = sub.length; i < 5; i++) { - sub += sub[0] - } + var subs = trans(arg[2]||"'\"`"); - var res = [] // 开始分词 - var list = str - var left = '\000', space = true, begin = 0 + var res = [], list = str; + var left = '\000', space = true, begin = 0; for (var i = 0; i < list.length; i++) { - if (list[i] == sep[0] || list[i] == sep[1] || list[i] == sep[2] || list[i] == sep[3] || list[i] == sep[4]) { + if (seps[list[i]]) { + // 空白符 if (left == '\000') { if (!space) { - // 空白分隔 res.push(list.slice(begin, i)) } + res.push({text: list.slice(i, i+1), type: "space", left: left}) space = true, begin = i+1 } - } else if (list[i] == sub[0] || list[i] == sub[1] || list[i] == sub[2] || list[i] == sub[3] || list[i] == sub[4]) { + } else if (subs[list[i]]) { + // 引用符 if (arg.length > 0) { if (left == '\000') { left = list[i] } else if (left == list[i]) { left = '\000' } - break } else { if (left == '\000') { left = list[i], space = false, begin = i+1 } else if (left == list[i]) { - // 引用分隔 - res.push({text: list.slice(begin, i), type: "str"}) + res.push({text: list.slice(begin, i), type: "string", left: left}) left = '\000', space = true, begin = i+1 } } - } else if (list[i] == sup[0] || list[i] == sup[1] || list[i] == sup[2] || list[i] == sup[3] || list[i] == sup[4] || list[i] == sup[5] || list[i] == sup[6] || list[i] == sup[7] || list[i] == sup[8] || list[i] == sup[9]) { + } else if (sups[list[i]]) { + // 分隔符 if (left == '\000') { if (!space) { res.push(list.slice(begin, i)) } - // 分隔分隔 res.push(list.slice(i, i+1)) space = true, begin = i+1 } } else if (list[0] == '\\') { + // 转义符 for (var i = i; i < list.length-1; i++) { list[i] = list[i+1] } @@ -145,9 +123,7 @@ Volcanos("core", {help: "核心模块", } // 末尾单词 - if (begin < list.length) { - res.push(list.slice(begin)) - } + if (begin < list.length) { res.push(list.slice(begin)) } return res }), }) diff --git a/plugin/inner.css b/plugin/inner.css index ab28ff52..4bc00988 100644 --- a/plugin/inner.css +++ b/plugin/inner.css @@ -38,8 +38,21 @@ fieldset.editor>div.output div.content>pre.item { height:20px; margin:0; } +fieldset.editor>div.output div.content>pre.item span.comment { + background-color:blue; + color:cyan; +} fieldset.editor>div.output div.content>pre.item span.keyword { color:yellow; + font-weight:bold; +} +fieldset.editor>div.output div.content>pre.item span.function { + color:cyan; + font-weight:bold; +} +fieldset.editor>div.output div.content>pre.item span.datatype { + color:lightgreen; + font-weight:bold; } fieldset.editor>div.output div.content>pre.item span.string { color:magenta; diff --git a/plugin/inner.js b/plugin/inner.js index 91c009ba..b48a7571 100644 --- a/plugin/inner.js +++ b/plugin/inner.js @@ -1,16 +1,16 @@ Volcanos("onimport", {help: "导入数据", _init: function(can, msg, list, cb, target) { target.innerHTML = ""; - can.onappend.table(can, target, "table", msg); + // can.onappend.table(can, target, "table", msg); can.history = [] can.ui = can.page.Append(can, target, [{view: ["editor", "textarea"], onkeydown: function(event) { - can.history.push(event.key); if (can.mode == "normal") { + can.history.push(event.key); if (can.mode != "insert") { event.stopPropagation() event.preventDefault() } can.Status("输入值", can.history.join()) var cb = can.onkeymap[can.mode][event.key] - if (typeof cb == "function") { can.history = []; return cb(event, can) } + if (typeof cb == "function") { return cb(event, can), can.history = [] } var map = can.onkeymap[can.mode]._engine for (var i = can.history.length-1; i > -1; i--) { @@ -22,7 +22,14 @@ Volcanos("onimport", {help: "导入数据", _init: function(can, msg, list, cb, }, onblur: function(event) { can.onaction.modifyLine(can, can.current, can.editor.value) - }}, {view: "lineno", style: {width: "30px"}}, {view: "content", style: {"margin-left": "30px"}}, ]); + }}, + {view: ["project", "div"], style: {width: "80px"}}, + {view: "lineno", style: {width: "30px"}}, + {view: "content"}, + {view: "preview"}, {view: ["display", "pre"]}, + ]); + can.onlayout.show_project(can); + can.onlayout.show_project(can); can.core.List(can.onkeymap.list, function(item) { var engine = {}; can.core.Item(can.onkeymap[item], function(key, cb) { var map = engine; @@ -34,41 +41,152 @@ Volcanos("onimport", {help: "导入数据", _init: function(can, msg, list, cb, }) console.log(can.onkeymap) + var ls = can.Option("name").split("."); + can.parse = ls.pop()||"txt"; can.editor = can.ui.editor, can.max = 0, can.ls = msg.Result().split("\n"); can.core.List(can.ls, function(item) { can.onaction.appendLine(can, item) }); can.Timer(100, function() { + can.onaction.project(can); can.onaction.selectLine(can, 0); can.onaction.mode(null, can, null, "normal"); - can.Status("文件名", can.Option("path")) - can.Status("解析器", "go") + can.Status("文件名", can.Option("name")) + can.Status("解析器", can.parse) }) return typeof cb == "function" && cb(msg); }, }, ["/plugin/inner.css"]) Volcanos("onsyntax", {help: "语法高亮", list: ["normal", "insert"], - go: { - line: function(can, line) { - var keyword = { - "package": "keyword", - "import": "keyword", - "func": "keyword", + parse: function(can, line) { var p = can.onsyntax[can.parse]; + function wrap(type, str) { return type? ''+str+'': str } + p && p.keyword && (line = can.core.List(can.core.Split(line), function(item, index, array) { + var text = item.text || item; + var key = p.keyword[text]; + + switch (item.type) { + case "string": return wrap("string", item.left+text+item.left); + case "space": return text + default: return wrap(key, text); } - can.core.List(can.core.Split(line), function(item) { var p = keyword[item]; - if (typeof item == "object") { - item.type == "str" && (line = line.replace(item.text, ''+item.text+'')) - } else { - p && (line = line.replace(item, ''+item+'')) - } - }) + }).join("")) + + p && p.prefix && can.core.Item(p.prefix, function(pre, type) { + if (line.startsWith(pre)) { line = wrap(type, line) } + }) + return p && p.line? p.line(can, line): line + }, + sh: { + keyword: { + "require": "keyword", + "export": "keyword", + "source": "keyword", + }, + prefix: { + "#": "comment", + }, + line: function(can, line) { return line }, }, + vim: { + keyword: { + syntax: "keyword", + highlight: "keyword", + }, + prefix: { + "\"": "comment", + }, + }, + shy: { + keyword: { + }, + prefix: { + "~": "keyword", + "#": "comment", + }, + }, + mod: { + keyword: { + "module": "keyword", + "require": "keyword", + "replace": "keyword", + "=>": "keyword", + }, + prefix: { + "#": "comment", + }, + }, + go: { + keyword: { + "package": "keyword", + "import": "keyword", + "func": "keyword", + "var": "keyword", + "type": "keyword", + "struct": "keyword", + "interface": "keyword", + + "if": "keyword", + "else": "keyword", + "for": "keyword", + "range": "keyword", + "break": "keyword", + "continue": "keyword", + "return": "keyword", + "defer": "keyword", + "switch": "keyword", + "case": "keyword", + "default": "keyword", + "fallthrough": "keyword", + "go": "keyword", + "select": "keyword", + + "map": "datatype", + "chan": "datatype", + "string": "datatype", + "error": "datatype", + "bool": "datatype", + "int": "datatype", + + "len": "datatype", + "cap": "datatype", + "copy": "datatype", + "append": "datatype", + + "nil": "string", + + "m": "function", + "msg": "function", + "kit": "keyword", + }, + }, }) -Volcanos("onkeymap", {help: "键盘交互", list: ["normal", "insert"], - normal: { - ":w": function(event, can) { +Volcanos("onkeymap", {help: "键盘交互", list: ["command", "normal", "insert"], + _command: function(can) { can.onaction.mode(null, can, null, "command") }, + _normal: function(can) { can.onaction.mode(null, can, null, "normal") }, + _insert: function(can) { can.onaction.mode(null, can, null, "insert") }, + _engine: { + w: function(event, can) { can.onaction.remote(event, can, null, "保存") }, + }, + command: { + Enter: function(event, can) { can.onkeymap._normal(can); + var line = can.history.slice(0, -1).join(""); + var cb = can.onkeymap._engine[line]; if (typeof cb == "function") { + return cb(event, can) + } + can.run(event, ["action", line, can.base.Path(can.Option("path"), can.Option("name"))], function(res) { + can.ui.display.innerHTML = res.Result() + }, true); + }, + jk: function(event, can) { can.history = can.history.slice(0, -1); + can.onkeymap.command.Enter(event, can); + }, + }, + normal: { + ":": function(event, can) { + can.onkeymap._command(can) + }, h: function(event, can) { can.editor.setSelectionRange(can.editor.selectionStart-1, can.editor.selectionStart-1) }, @@ -86,14 +204,14 @@ Volcanos("onkeymap", {help: "键盘交互", list: ["normal", "insert"], can.run(event) }, i: function(event, can) { - can.onaction.mode(event, can, null, "insert") + can.onkeymap._insert(can) }, O: function(event, can) { - can.onaction.mode(event, can, null, "insert") + can.onkeymap._insert(can) can.onaction.insertLine(can, can.current, "", true).click() }, o: function(event, can) { - can.onaction.mode(event, can, null, "insert") + can.onkeymap._insert(can) can.onaction.insertLine(can, can.current).click() }, yy: function(event, can) { @@ -121,7 +239,7 @@ Volcanos("onkeymap", {help: "键盘交互", list: ["normal", "insert"], }, Escape: function(event, can) { can.onaction.modifyLine(can, can.current, can.editor.value) - can.onaction.mode(event, can, null, "normal") + can.onkeymap._normal(can) }, Enter: function(event, can) { can.onaction.modifyLine(can, can.current, can.editor.value) @@ -136,15 +254,15 @@ Volcanos("onkeymap", {help: "键盘交互", list: ["normal", "insert"], can.page.DelText(can.editor, can.editor.selectionStart-1, 1) can.onaction.modifyLine(can, can.current, can.editor.value) - can.onaction.mode(event, can, null, "normal") + can.onkeymap._normal(can) event.stopPropagation() event.preventDefault() }, }, }) -Volcanos("onaction", {help: "控件交互", list: ["保存", "提交", ["mode", "normal", "insert"]], +Volcanos("onaction", {help: "控件交互", list: ["项目", "保存", "运行", "提交", ["mode", "normal", "insert"]], modifyLine: function(can, target, value) { - value = can.onsyntax.go.line(can, value) + value = can.onsyntax.parse(can, value) target.innerHTML = value }, deleteLine: function(can, target) { @@ -172,7 +290,7 @@ Volcanos("onaction", {help: "控件交互", list: ["保存", "提交", ["mode", can.page.Append(can, can.ui.lineno, [{view: ["item", "div", index+1], onclick: function(event) { can.onaction.selectLine(can, index) }}]) - value = can.onsyntax.go.line(can, value) + value = can.onsyntax.parse(can, value) return can.page.Append(can, can.ui.content, [{view: ["item", "pre", value||""], onclick: function(event) { can.onaction.selectLine(can, event.target) }}]).last @@ -188,20 +306,44 @@ Volcanos("onaction", {help: "控件交互", list: ["保存", "提交", ["mode", return target }, - remote: function(event, can, msg, key) { - msg = can.request(event), msg.Option("content", can.onexport.content(can)) - can.run(event, ["action", key, can.Option("path")], function(res) { + project: function(can) { can.ui.project.innerHTML = "" + can.run({}, ["action", "project", can.Option("path")], function(res) { + res.Table(function(value) { + can.page.Append(can, can.ui.project, [{text: [value.file, "div", "item"], onclick: function(event) { + if (value.file.endsWith("/")) { + can.Option("path", can.base.Path(can.Option("path"), value.file)) + can.onaction.project(can) + } else { + can.Option("name", value.file) + can.run(event) + } + }}]) + }) }, true) }, + + remote: function(event, can, msg, key, cb) { + msg = can.request(event), msg.Option("content", can.onexport.content(can)) + can.run(event, ["action", key, can.base.Path(can.Option("path"), can.Option("name"))], function(res) { + }, true) + }, mode: function(event, can, msg, value) { can.Action("mode", can.mode = value) can.Status("输入法", can.mode) return value }, + "项目": function(event, can, msg) { + can.onlayout.show_project(can) + }, "保存": function(event, can, msg) { can.onaction.remote(event, can, msg, "保存") }, + "运行": function(event, can, msg) { + can.run(event, ["action", can.parse, can.base.Path(can.Option("path"), can.Option("name"))], function(res) { + can.ui.display.innerHTML = res.Result() + }, true); + }, "提交": function(event, can, msg) { can.onaction.remote(event, can, msg, "提交") }, @@ -223,6 +365,20 @@ Volcanos("ondetail", {help: "菜单交互", list: ["删除行", "合并行", " can.onaction.appendLine(can) }, }) +Volcanos("onlayout", {help: "页面布局", list: [], + show_project: function(can) { + var hide = can.ui.project.style.display == "none" + can.page.Modify(can, can.ui.project, {style: { + display: hide? "": "none", + }}) + can.page.Modify(can, can.ui.content, {style: { + "margin-left": hide? "110px": "30px", + }}) + can.page.Modify(can, can.ui.display, {style: { + "margin-left": hide? "110px": "30px", + }}) + }, +}) Volcanos("onexport", {help: "导出数据", list: ["输入法", "输入值", "文件名", "解析器", "当前行"], content: function(can) { return can.page.Select(can, can._output, "div.content>pre.item", function(item) {