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) {