diff --git a/frame.js b/frame.js index 9457a420..fe0a8e9f 100644 --- a/frame.js +++ b/frame.js @@ -860,7 +860,10 @@ Volcanos(chat.ONMOTION, {help: "动态特效", _init: function(can, target) { Volcanos(chat.ONKEYMAP, {help: "键盘交互", _focus: [], _init: function(can, target) { document.body.onclick = function(event) { if (window.webview) { - if (event.target.tagName == "A") { can.user.open(event.target.href) } + if (can.page.tagis(event.target, html.A)) { + event.shiftKey? window.outopen(event.target.href): can.user.open(event.target.href) + return + } } if (can.page.tagis( event.target, html.SELECT, html.INPUT, html.TEXTAREA)) { return } can.page.Select(can, document.body, can.page.Keys("fieldset.input.key.float"), function(item) { @@ -870,6 +873,9 @@ Volcanos(chat.ONKEYMAP, {help: "键盘交互", _focus: [], _init: function(can, can.onkeymap._build(can), document.body.onkeydown = function(event) { var msg = can.request(event, {model: "normal"}); if (event.metaKey && window.webview) { msg.Option("model", "webview") + if (event.key >= "0" && event.key <= "9") { + can.onengine.signal(can, chat.ONKEYDOWN, msg); if (msg.Option(ice.MSG_HANDLE) == ice.TRUE) { return } + } } else if (can.page.tagis(event.target, html.SELECT, html.INPUT, html.TEXTAREA)) { return } else { can.onengine.signal(can, chat.ONKEYDOWN, msg); if (msg.Option(ice.MSG_HANDLE) == ice.TRUE) { return } } @@ -913,8 +919,9 @@ Volcanos(chat.ONKEYMAP, {help: "键盘交互", _focus: [], _init: function(can, _mode: { webview: { q: function(event, can, target) { window.terminate() }, - o: function(event, can, target) { window.outopen(location.href) }, - t: function(event, can, target) { window.terminal(location.href) }, + o: function(event, can, target) { window.openurl(location.href) }, + p: function(event, can, target) { window.openapp("QuickTime Player") }, + t: function(event, can, target) { window.opencmd("cd contexts; pwd") }, w: function(event, can, target) { can.user.close() }, r: function(event, can, target) { can.user.reload(true) }, f: function(event, can, target) { can.onengine.signal(can, chat.ONOPENSEARCH, can.request({}, {type: mdb.FOREACH})) }, diff --git a/plugin/local/code/inner.js b/plugin/local/code/inner.js index 51fb8f47..c1c58670 100644 --- a/plugin/local/code/inner.js +++ b/plugin/local/code/inner.js @@ -10,7 +10,7 @@ Volcanos(chat.ONIMPORT, {help: "导入数据", }), can.ui.project), can.user.isMobile && !can.user.isLandscape() && can.onmotion.hidden(can, can.ui.project) }, tabview: function(can, path, file, line, cb) { var key = can.onexport.keys(can, path, file) - function isCommand() { return path == ctx.COMMAND || line == ctx.INDEX } + function isCommand() { return path == ctx.COMMAND || line == ctx.INDEX || line == code.XTERM } function isDream() { return line == web.DREAM } function show(skip) { if (can.isCmdMode()) { can.onimport._title(can, path+file) } @@ -100,12 +100,19 @@ Volcanos(chat.ONSYNTAX, {help: "语法高亮", _init: function(can, msg, cb) { return can.base.isFunc(cb) && cb(msg._content = msg._content||can.page.insertBefore(can, [{type: html.IFRAME, src: can.misc.MergePodCmd(can, {pod: can.Option(nfs.FILE)}), height: can.ui.content.offsetHeight-4, width: can.ui.content.offsetWidth}], can.ui._content)) } + + var meta = {index: msg.Option(ctx.INDEX), args: can.Option(nfs.PATH) == ctx.COMMAND && can.Option(nfs.LINE) != ctx.INDEX? [can.Option(nfs.LINE)]: []} + if (can.Option(nfs.LINE) == code.XTERM) { + meta = {index: "web.code.xterm", args: can.Option(nfs.FILE)} + } else { + can.onimport.layout(can) + } - can.onimport.layout(can) - return can.onimport.plug(can, {index: msg.Option(ctx.INDEX), args: can.Option(nfs.PATH) == ctx.COMMAND && can.Option(nfs.LINE) != ctx.INDEX? [can.Option(nfs.LINE)]: []}, can.ui._content, function(sub) { + return can.onimport.plug(can, meta, can.ui._content, function(sub) { sub.onimport.size(sub, sub.ConfHeight(can.ui.content.offsetHeight-3*html.ACTION_HEIGHT+sub.onexport.statusHeight(sub)), sub.ConfWidth(can.ui.content.offsetWidth), true) msg._plugin = sub, can.base.isFunc(cb) && cb(msg._content = can.ui._content), can.onmotion.delay(can, function() { sub.Focus() }) sub.onaction.close = function() { can.onaction.back(can), msg._tab._close() } + sub.onimport.title = function(_, title) { can.page.Modify(can, msg._tab, title) } sub.onimport._open = function(sub, msg, _arg) { var url = can.base.ParseURL(_arg), ls = url.origin.split("/chat/pod/") if (_arg.indexOf(location.origin) == 0 && ls.length > 1) { return can.onimport.tabview(can, can.Option(nfs.PATH), ls[1].split(ice.PS)[0], web.DREAM), sub.Update() @@ -314,6 +321,11 @@ Volcanos(chat.ONACTION, {help: "控件交互", _trans: {link: "链接", width: " Volcanos(chat.ONIMPORT, {help: "导入数据", _keydown: function(can) { if (!can.isCmdMode()) { return } can.onkeymap._build(can), can._root.onengine.listen(can, chat.ONKEYDOWN, function(event) { + if ((event.ctrlKey || event.metaKey) && event.key >= "0" && event.key <= "9") { + return can.page.Select(can, can.ui._tabs, "div.tabs", function(target, index) { + if (index+1 == event.key) { target.click() } + }) + } can._key_list = can.onkeymap._parse(event, can, mdb.PLUGIN, can._key_list, can.ui.content) }) }, diff --git a/plugin/local/code/inner/syntax.js b/plugin/local/code/inner/syntax.js index 23db1a3c..d981a294 100644 --- a/plugin/local/code/inner/syntax.js +++ b/plugin/local/code/inner/syntax.js @@ -295,6 +295,7 @@ Volcanos(chat.ONSYNTAX, {help: "语法高亮", "event": code.KEYWORD, "target": code.KEYWORD, "window": code.KEYWORD, + "document": code.KEYWORD, "location": code.KEYWORD, "null": code.CONSTANT, diff --git a/plugin/local/code/vimer.js b/plugin/local/code/vimer.js index 03668699..997c9aeb 100644 --- a/plugin/local/code/vimer.js +++ b/plugin/local/code/vimer.js @@ -27,11 +27,12 @@ Volcanos(chat.ONIMPORT, {help: "导入数据", _init: function(can, msg, cb, tar }, [""]) Volcanos(chat.ONFIGURE, {help: "索引导航", create: function(can, target, zone, path) { - can.isCmdMode()? can.onappend._action(can, can.base.Obj(can._msg.Option(ice.MSG_ACTION)), target): can.onmotion.hidden(can, target.parentNode) + can.isCmdMode()? can.onappend._action(can, can.base.Obj(can._msg.Option(ice.MSG_ACTION)).concat(window.webview? ["编辑器", "浏览器"]: []), target): can.onmotion.hidden(can, target.parentNode) }, - recent: function(can, target, zone, path) { + recent: function(can, target, zone, path) { var total = 0 can.runAction(can.request({}), code.FAVOR, ["_vimer"], function(msg) { var list = {}; msg.Table(function(item) { list[item.path+item.file] = item }), can.core.Item(list, function(path, item) { + zone._total(++total) can.page.Append(can, target, [{text: [item.name||item.file, html.DIV, html.ITEM], onclick: function(event) { can.onimport.tabview(can, can.Option(nfs.PATH), item.file, ctx.INDEX) }}]) @@ -39,6 +40,7 @@ Volcanos(chat.ONFIGURE, {help: "索引导航", }) can.runAction(can.request({}), code.FAVOR, ["_recent"], function(msg) { var list = {}; msg.Table(function(item) { list[item.path+item.file] = item }), can.core.Item(list, function(path, item) { + zone._total(++total) can.page.Append(can, target, [{text: [path.split(ice.PS).slice(-2).join(ice.PS), html.DIV, html.ITEM], onclick: function(event) { can.onimport.tabview(can, item.path, item.file) }}]) @@ -79,7 +81,7 @@ Volcanos(chat.ONFIGURE, {help: "索引导航", }, xterm: function(can, target, zone) { can.runAction({}, ice.RUN, [code.XTERM], function(msg) { msg.Table(function(item) { - can.onimport.item(can, item, function(event) { can.onimport.tabview(can, ctx.COMMAND, code.XTERM, item.hash) }, function(event) {}, target) + can.onimport.item(can, item, function(event) { can.onimport.tabview(can, can.Option(nfs.PATH), item.hash, code.XTERM) }, function(event) {}, target) }), zone._total(msg.Length()) }) }, plugin: function(can, target, zone) { var total = 0 @@ -151,23 +153,33 @@ Volcanos(chat.ONKEYMAP, {help: "键盘交互", }), yy: shy("复制当前行", function(event, can, target, count) { - can._last_text = can.current.text() + var list = [], line = can.current.line; for (var i = 0; i < count; i++) { + list.push(can.core.Value(can.page.Select(can, line, "td.text")[0], "innerText")), line = line.nextSibling + } can._last_text = list + return true }), dd: shy("剪切当前行", function(event, can, target, count) { - var line = can.onaction.selectLine(can), text = can.current.text() - can.onaction.selectLine(can, can.onaction.deleteLine(can, line)), can._last_text = text - can.undo.push(function() { can.onaction.insertLine(can, text, line), can.onaction.selectLine(can, line) }) - var callee = arguments.callee; can.redo.push(function() { callee(can) }) + var list = []; for (var i = 0; i < count; i++) { (function() { + var line = can.onaction.selectLine(can), text = can.current.text(); list.push(text) + can.onaction.selectLine(can, can.onaction.deleteLine(can, line)) + can.undo.push(function() { can.onaction.insertLine(can, text, line), can.onaction.selectLine(can, line) }) + var callee = arguments.callee; can.redo.push(function() { callee(can) }) + })() } can._last_text = list + return true }), - p: shy("粘贴", function(can) { - var line = can.onaction.insertLine(can, can._last_text, can.current.next()) - can.undo.push(function() { can.onaction.deleteLine(can, line), can.onaction.selectLine(can, line-1) }) - var call = arguments.callee; can.redo.push(function() { call(event, can) }) + p: shy("粘贴", function(can) { if (!can._last_text) { return } + for (var i = can._last_text.length-1; i >= 0; i--) { (function() { + var line = can.onaction.insertLine(can, can._last_text[i], can.current.next()) + can.undo.push(function() { can.onaction.deleteLine(can, line), can.onaction.selectLine(can, line-1) }) + var call = arguments.callee; can.redo.push(function() { call(event, can) }) + })() } }), - P: shy("粘贴", function(can) { - var line = can.onaction.insertLine(can, can._last_text, can.current.line) - can.undo.push(function() { can.onaction.deleteLine(can, line), can.onaction.selectLine(can, line+1) }) - var call = arguments.callee; can.redo.push(function() { call(event, can) }) + P: shy("粘贴", function(can) { if (!can._last_text) { return } + for (var i = 0; i < can._last_text.length; i++) { (function() { + var line = can.onaction.insertLine(can, can._last_text[i], can.current.line) + can.undo.push(function() { can.onaction.deleteLine(can, line), can.onaction.selectLine(can, line+1) }) + var call = arguments.callee; can.redo.push(function() { call(event, can) }) + })() } }), J: shy("合并两行", function(can) { var next = can.current.next(); if (!next) { return } @@ -309,6 +321,12 @@ Volcanos(chat.ONACTION, {help: "控件交互", can.onimport.exts(can, list[0]) }) }, + "编辑器": function(event, can) { + window.opencmd("cd ~/contexts; vim "+can.Option(nfs.PATH)+can.Option(nfs.FILE)+" +"+can.Option(nfs.LINE)) + }, + "浏览器": function(event, can) { + window.openurl(location.href) + }, _complete: function(event, can, target) { target = target||can.ui.complete if (event == undefined) { return } diff --git a/plugin/local/code/xterm.js b/plugin/local/code/xterm.js index d8e2e260..8444529a 100644 --- a/plugin/local/code/xterm.js +++ b/plugin/local/code/xterm.js @@ -13,11 +13,12 @@ Volcanos(chat.ONIMPORT, {help: "导入数据", _init: function(can, msg, cb) { c can.onmotion.delay(can, function() { fitAddon.fit() }) term.loadAddon(new WebLinksAddon.WebLinksAddon()) - term.onTitleChange(function(title) { can.isCmdMode() && can.user.title(title) }) + term.onTitleChange(function(title) { can.sup.onimport.title(can, title) }) term.onResize(function(size) { can.onimport._resize(can, size) }) term.onData(function(data) { can.onimport._input(can, data) }) term.onCursorMove(function() { can.onexport.term(can) }) + can.sup.onimport.title(can, item.name) can._current = term, term._item = item term.open(can._output), term.focus() }, diff --git a/plugin/state.js b/plugin/state.js index 535a78e1..bfd4820e 100644 --- a/plugin/state.js +++ b/plugin/state.js @@ -92,6 +92,9 @@ Volcanos(chat.ONIMPORT, {help: "导入数据", _process: function(can, msg) { var sub = can.core.Value(can, chat._OUTPUTS_CURRENT); if (!sub) { return } sub.ConfHeight(can.ConfHeight()), sub.ConfWidth(can.ConfWidth()) if (mode) { sub.Mode(can.Mode(mode)), sub.onlayout[mode](sub) } else { can.onaction["刷新页面"]({}, can, "刷新页面", sub) } }, + title: function(can, title) { + can.isCmdMode() && can.user.title(title) + }, }) Volcanos(chat.ONACTION, {help: "交互操作", list: [ "刷新页面", "刷新数据", "切换浮动", "切换全屏", "共享工具", "远程控制", "打开链接", "生成链接", "生成脚本", "生成图片", [