diff --git a/base.go b/base.go index b54bb3d1..df1aa341 100644 --- a/base.go +++ b/base.go @@ -155,3 +155,10 @@ func Run(arg ...string) string { os.Exit(frame.code) return "" } +func ListLook(name string) []interface{} { + return kit.List( + kit.MDB_INPUT, "text", "name", name, "action", "auto", + kit.MDB_INPUT, "button", "name", "查看", "action", "auto", + kit.MDB_INPUT, "button", "name", "返回", "cb", "Last", + ) +} diff --git a/base/web/web.go b/base/web/web.go index 2af07e5c..e1da7192 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -340,11 +340,9 @@ func (web *Frame) ServeHTTP(w http.ResponseWriter, r *http.Request) { if _, e := os.Stat(m.Conf(ice.WEB_SERVE, "meta.volcanos.path")); e == nil { // 初始化成功 m.Conf(ice.WEB_SERVE, "meta.init", "true") - } else { - // 系统初始化 - w.Write([]byte(Refresh(m, 10))) - m.Event(ice.SYSTEM_INIT) } + w.Write([]byte(Refresh(m, 5))) + m.Event(ice.SYSTEM_INIT) } else { web.ServeMux.ServeHTTP(w, r) } @@ -745,6 +743,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", default: // 启动服务 m.Target().Start(m, "self") + m.Cmd(ice.WEB_SPACE, "connect", "self") } }}, ice.WEB_SPACE: {Name: "space", Help: "空间站", Meta: kit.Dict("exports", []string{"pod", "name"}), List: kit.List( @@ -884,6 +883,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", ), List: kit.List( kit.MDB_INPUT, "text", "value", "", "name", "name", kit.MDB_INPUT, "button", "value", "创建", "action", "auto", + kit.MDB_INPUT, "button", "value", "返回", "cb", "Last", ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) > 1 { switch arg[1] { @@ -913,12 +913,17 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", // 启动任务 m.Option("cmd_dir", p) m.Option("cmd_type", "daemon") - m.Option("cmd_env", "ctx_log", "boot.log") - m.Option("cmd_env", "PATH", kit.Path(path.Join(p, "bin"))+":"+os.Getenv("PATH")) + m.Optionv("cmd_env", + "ctx_log", "boot.log", + "ctx_mod", "ctx log gdb ssh", + "PATH", kit.Path(path.Join(p, "bin"))+":"+os.Getenv("PATH"), + ) m.Cmd(m.Confv(ice.WEB_DREAM, "meta.cmd"), "self", arg[0]) - time.Sleep(time.Second * 3) + time.Sleep(time.Second * 1) m.Event(ice.DREAM_START, arg...) } + m.Cmdy("nfs.dir", p) + return } // 任务列表 @@ -1016,11 +1021,15 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", m.Log(ice.LOG_CREATE, "favor: %s name: %s", favor, arg[0]) } + fields := []string{kit.MDB_TIME, kit.MDB_ID, kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT} + if len(arg) > 1 && arg[1] == "extra" { + fields, arg = append(fields, arg[2:]...), arg[:1] + } if len(arg) == 1 { m.Option("cache.limit", 30) // 收藏列表 m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, favor), "", "", func(index int, value map[string]interface{}) { - m.Push(kit.Format(index), value, []string{kit.MDB_TIME, kit.MDB_ID, kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT}) + m.Push(kit.Format(index), value, fields) }) return } diff --git a/conf.go b/conf.go index 656b1c1c..994f21ff 100644 --- a/conf.go +++ b/conf.go @@ -82,6 +82,7 @@ const ( // WEB WEB_WORKER = "worker" ) const ( // LOG + // 数据 LOG_ENABLE = "enable" LOG_IMPORT = "import" LOG_CREATE = "create" @@ -92,16 +93,23 @@ const ( // LOG LOG_REMOVE = "remove" LOG_EXPORT = "export" + // 事件 LOG_LISTEN = "listen" LOG_SIGNAL = "signal" LOG_TIMERS = "timers" LOG_EVENTS = "events" + // 状态 LOG_BEGIN = "begin" LOG_START = "start" LOG_SERVE = "serve" LOG_CLOSE = "close" + // 权限 + LOG_LOGIN = "login" + LOG_LOGOUT = "logout" + + // 分类 LOG_CMDS = "cmds" LOG_COST = "cost" LOG_INFO = "info" diff --git a/core/code/auto.sh b/core/code/auto.sh deleted file mode 100755 index e4a93cd2..00000000 --- a/core/code/auto.sh +++ /dev/null @@ -1,183 +0,0 @@ -#!/bin/sh - -if [ "${ctx_dev}" = "" ] || [ "${ctx_dev}" = "-" ]; then - ctx_dev="http://localhost:9095" -fi - -ctx_url=$ctx_dev"/code/zsh" -ctx_get=${ctx_get:="wget -q"} -ctx_curl=${ctx_curl:="curl"} -ctx_head=${ctx_head:="Content-Type: application/json"} -ctx_sid=${ctx_sid:=""} - -ctx_silent=${ctx_silent:=""} -ctx_err=${ctx_err:="/dev/null"} -ctx_welcome=${ctx_welcome:="^_^ Welcome to Context world ^_^"} -ctx_goodbye=${ctx_goodbye:="^_^ Goodbye to Context world ^_^"} - -ShyRight() { - [ "$1" = "" ] && return 1 - [ "$1" = "0" ] && return 1 - [ "$1" = "false" ] && return 1 - [ "$1" = "true" ] && return 0 - return 0 -} -ShyEcho() { - ShyRight "$ctx_silent" || echo "$@" -} -ShyLog() { - echo "$@" > $ctx_err -} - -ShyWord() { - echo "$*"|sed -e 's/\ /%20/g' -e 's/\n/\\n/g' -} -ShyForm() { - while [ $# -gt 1 ]; do - echo -n "`ShyWord "$1"`=`ShyWord "$2"`" - shift 2 && [ $# -gt 1 ] && echo -n "&" - done -} -ShyGet() { - local data=`ShyForm "$@" SHELL "${SHELL}" pwd "${PWD}" sid "${ctx_sid}"` - ${ctx_get} "${ctx_url}?${data}" -} -ShyLine() { - echo "$*"|sed -e 's/\"/\\\"/g' -e 's/\n/\\n/g' -} -ShyJSON() { - [ $# -eq 1 ] && echo \"`ShyLine "$1"`\" && return - echo -n "{" - while [ $# -gt 1 ]; do - echo -n \"`ShyLine "$1"`\"\:\"`ShyLine "$2"`\" - shift 2 && [ $# -gt 1 ] && echo -n "," - done - echo -n "}" -} -ShyPost() { - if [ "$SHELL" = "/bin/zsh" ]; then - ShyJSON "$@" SHELL "${SHELL}" pwd "${PWD}" sid "${ctx_sid}"|read data - else - local data=`ShyJSON "$@" SHELL "${SHELL}" pwd "${PWD}" sid "${ctx_sid}"` - fi - ${ctx_curl} -s "${ctx_url}" -H "${ctx_head}" -d "${data}" -} -ShyDownload() { - ${ctx_curl} -s "${ctx_url}" -F "cmd=download" -F "arg=$1" -F "sid=$ctx_sid" -} -ShyUpload() { - ${ctx_curl} -s "${ctx_url}" -F "cmd=upload" -F "upload=@$1" -F "sid=$ctx_sid" -} -ShyBench() { - ${ctx_curl} -s "${ctx_dev}/publish/boot.sh" | sh -s installs context -} -ShySend() { - local TEMP=`mktemp /tmp/tmp.XXXXXX` && "$@" > $TEMP - ShyRight "$ctx_silent" || cat $TEMP - ${ctx_curl} -s "${ctx_url}" -F "cmd=sync" -F "arg=$1" -F "args=$*" -F "sub=@$TEMP"\ - -F "SHELL=${SHELL}" -F "pwd=${PWD}" -F "sid=${ctx_sid}" -} -ShySends() { - local cmd=$1 && shift - local arg=$2 && shift - local TEMP=`mktemp /tmp/tmp.XXXXXX` && echo "$@" > $TEMP - ShyRight "$ctx_silent" || cat $TEMP - ${ctx_curl} -s "${ctx_url}" -F "cmd=$cmd" -F "arg=$arg" -F "sub=@$TEMP" \ - -F "SHELL=${SHELL}" -F "pwd=${PWD}" -F "sid=${ctx_sid}" -} -ShyRun() { - ctx_silent=false ShySend "$@" -} -Shy() { - local ctx_res=`ShyPost cmd "$1" arg "$2"` - case "$ctx_res" in - "PS1");; - *) [ -n "${ctx_res}" ] && ShyPost cmd "$1" arg "$2" res `sh -c ${ctx_res}` - esac -} - -ShyLogout() { - echo ${ctx_goodbye} && [ "$ctx_sid" != "" ] && Shy logout -} -ShyLogin() { - HOST=`hostname` ctx_sid=`ShyPost cmd login share "${ctx_share}" pid "$$" pane "${TMUX_PANE}" hostname "${HOST}" username "${USER}"` - [ "$ctx_begin" = "" ] && ctx_begin=`history|tail -n1|awk '{print $1}'` && echo "begin: ${ctx_begin}" - echo "sid: ${ctx_sid}" -} -ShyFavor() { - [ "$READLINE_LINE" != "" ] && set $READLINE_LINE && READLINE_LINE="" - [ "$1" != "" ] && ctx_tab=$1 && shift; [ "$1" != "" ] && ctx_note=$1 && shift - [ "$1" != "" ] && ctx_word=$1 || ctx_word=`history|tail -n1|head -n1` - ShyPost cmd favor arg "${ctx_word}" tab "${ctx_tab}" note "${ctx_note}" -} -ShyFavors() { - [ "$READLINE_LINE" != "" ] && set $READLINE_LINE && READLINE_LINE="" - ShyPost cmd favor tab "$1" limit "$2" -} -ShySync() { - [ "$ctx_sid" = "" ] && ShyLogin - - case "$1" in - "history") - ctx_end=`history|tail -n1|awk '{print $1}'` - ctx_begin=${ctx_begin:=$ctx_end} - ctx_count=`expr $ctx_end - $ctx_begin` - ShyEcho "sync $ctx_begin-$ctx_end count $ctx_count to $ctx_dev" - history|tail -n $ctx_count |while read line; do - ShySends history sub "$line" - done - ctx_begin=$ctx_end - ;; - ps) ShySend ps -ef ;; - *) ShySend "$@" - esac -} -ShySyncs() { - case "$1" in - "base") - ShySync df &>/dev/null - ShySync ps &>/dev/null - ShySync env &>/dev/null - ShySync free &>/dev/null - ShySync history - ;; - *) - esac -} -ShyHelp() { - ShyPost cmd help arg "$@" -} -ShyInit() { - [ "$ctx_begin" = "" ] && ctx_begin=`history|tail -n1|awk '{print $1}'` - - case "${SHELL##*/}" in - "zsh") - PROMPT='%![%*]%c$ ' - ;; - *) - PS1="\!-$$-\t[\u@\h]\W\$ " - PS1="\e[32m\!\e[0m-$$-\e[31m$SPY_OWNER\e[0m@\e[33m$SPY_ROLE\e[0m[\e[32m\t\e[0m]\W\$ " - PS1="\!-$$-\t[\u@\h]\W\$ " - PS1="\!-$$-\u@\h[\t]\W\$ " - ;; - esac - - if bind &>/dev/null; then - bind -x '"\C-G\C-R":ShySyncs base' - bind -x '"\C-G\C-F":ShyFavor' - bind -x '"\C-Gf":ShyFavor' - bind -x '"\C-GF":ShyFavors' - elif bindkey &>/dev/null; then - bindkey -s '\C-G\C-R' 'ShySyncs base\n' - setopt nosharehistory - fi - - echo "url: ${ctx_url}" - echo "pid: $$" - echo "begin: ${ctx_begin}" - echo "share: ${ctx_share}" - echo "pane: $TMUX_PANE" -} - -ShyInit && trap ShyLogout EXIT - diff --git a/core/code/code.go b/core/code/code.go index 4f01be45..cff73f03 100644 --- a/core/code/code.go +++ b/core/code/code.go @@ -2,11 +2,9 @@ package code import ( "github.com/shylinux/icebergs" - _ "github.com/shylinux/icebergs/base" "github.com/shylinux/icebergs/base/web" "github.com/shylinux/toolkits" - "io/ioutil" "os" "path" "strings" @@ -44,6 +42,75 @@ var Index = &ice.Context{Name: "code", Help: "编程中心", ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save("login") }}, + "login": {Name: "login", Help: "登录", List: ice.ListLook("key"), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) > 0 && arg[0] == "action" { + switch arg[1] { + case "modify": + m.Richs("login", nil, m.Option("key"), func(key string, value map[string]interface{}) { + m.Log(ice.LOG_MODIFY, "%s %s %v->%s", key, arg[2], value[arg[2]], arg[3]) + value[arg[2]] = arg[3] + }) + case "delete": + m.Log(ice.LOG_DELETE, "%s %s", m.Option("key"), m.Conf("login", kit.Keys("hash", m.Option("key")))) + m.Conf("login", kit.Keys("hash", m.Option("key")), "") + } + return + } + + switch kit.Select("list", arg, 0) { + case "open": + case "init": + if m.Option("sid") != "" && m.Confs("login", []string{"hash", m.Option("sid"), "status"}) { + // 复用会话 + m.Conf("login", []string{"hash", m.Option("sid"), "status"}, "login") + m.Log(ice.LOG_LOGIN, "sid: %s", m.Option("sid")) + m.Echo(m.Option("sid")) + return + } + + you := m.Conf(ice.WEB_SHARE, kit.Keys("hash", m.Option("share"), "name")) + // 添加会话 + h := m.Rich("login", nil, kit.Dict( + "status", "login", + "type", kit.Select("zsh", arg, 1), + "you", you, + "pwd", m.Option("pwd"), + "pid", m.Option("pid"), + "pane", m.Option("pane"), + "hostname", m.Option("hostname"), + "username", m.Option("username"), + )) + m.Log(ice.LOG_LOGIN, "sid: %s you: %s", h, you) + m.Echo(h) + + case "list": + // 会话列表 + m.Richs("login", nil, "*", func(key string, value map[string]interface{}) { + m.Push(key, value, []string{"time", "key", "type", "status", "you"}) + pwd := strings.Split(kit.Format(value["pwd"]), "/") + if len(pwd) > 3 { + m.Push("pwd", strings.Join(pwd[len(pwd)-3:len(pwd)], "/")) + } else { + m.Push("pwd", value["pwd"]) + } + m.Push(key, value, []string{"pid", "pane", "hostname", "username"}) + }) + + case "sync": + + case "exit": + // 退出会话 + m.Richs("login", nil, m.Option("sid"), func(key string, value map[string]interface{}) { + m.Log(ice.LOG_LOGOUT, "sid: %s", m.Option("sid")) + value["status"] = "logout" + }) + default: + // 会话详情 + m.Richs("login", nil, arg[0], func(key string, value map[string]interface{}) { + m.Push("detail", value) + }) + } + }}, "compile": {Name: "compile [os [arch]]", Help: "编译", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { @@ -86,6 +153,7 @@ var Index = &ice.Context{Name: "code", Help: "编程中心", // 发布文件 target := path.Join(m.Conf("publish", "meta.path"), path.Base(arg[0])) os.Remove(target) + os.MkdirAll(path.Dir(target), 0777) os.Link(arg[0], target) // 发布记录 @@ -114,188 +182,6 @@ var Index = &ice.Context{Name: "code", Help: "编程中心", m.Cmd("exit") } }}, - - "login": {Name: "login", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - switch kit.Select("list", arg, 0) { - case "open": - case "init": - if m.Option("sid") != "" { - if m.Confs("login", []string{"hash", m.Option("sid"), "status"}) { - m.Conf("login", []string{"hash", m.Option("sid"), "status"}, "login") - m.Echo(m.Option("sid")) - return - } - } - - you := m.Conf(ice.WEB_SHARE, kit.Keys("hash", m.Option("share"), "name")) - // 添加终端 - h := m.Rich("login", nil, kit.Dict( - "status", "login", - "type", kit.Select("zsh", arg, 1), - "you", you, - "pwd", m.Option("pwd"), - "pid", m.Option("pid"), - "pane", m.Option("pane"), - "hostname", m.Option("hostname"), - "username", m.Option("username"), - )) - m.Info("%s: %s", you, h) - m.Echo(h) - - case "list": - m.Richs("login", nil, "*", func(key string, value map[string]interface{}) { - m.Push(key, value, []string{"time", "type", "status", "you"}) - pwd := strings.Split(kit.Format(value["pwd"]), "/") - if len(pwd) > 3 { - m.Push("pwd", strings.Join(pwd[len(pwd)-3:len(pwd)], "/")) - } else { - m.Push("pwd", value["pwd"]) - } - - m.Push(key, value, []string{"pid", "pane", "hostname", "username"}) - }) - - case "exit": - m.Richs("login", nil, m.Option("sid"), func(key string, value map[string]interface{}) { - m.Info("logout: %s", m.Option("sid")) - value["status"] = "logout" - }) - } - }}, - "/zsh": {Name: "/zsh", Help: "命令行", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if f, _, e := m.R.FormFile("sub"); e == nil { - defer f.Close() - if b, e := ioutil.ReadAll(f); e == nil { - m.Option("sub", string(b)) - } - } - - m.Option("you", "") - m.Richs("login", nil, m.Option("sid"), func(key string, value map[string]interface{}) { - m.Option("you", value["you"]) - }) - m.Info("%s%s %s arg: %v sub: %v", m.Option("you"), cmd, m.Option("cmd"), m.Optionv("arg"), m.Optionv("sub")) - - m.Push("_output", "result") - switch m.Option("cmd") { - case "login": - m.Cmdy("login", "init", cmd) - case "logout": - m.Cmdy("login", "exit") - case "upload": - // 缓存文件 - you := m.Option("you") - m.Option("you", "") - msg := m.Cmd(ice.WEB_STORY, "upload") - m.Echo("data: %s\n", msg.Append("data")) - m.Echo("time: %s\n", msg.Append("time")) - m.Echo("type: %s\n", msg.Append("type")) - m.Echo("name: %s\n", msg.Append("name")) - m.Echo("size: %s\n", msg.Append("size")) - m.Push("_output", "result") - - // 下发文件 - m.Option("you", you) - m.Cmd(ice.WEB_SPACE, msg.Option("you"), ice.WEB_STORY, ice.STORY_PULL, "dev", msg.Append("name")) - - case "download": - // 下载文件 - m.Option("you", "") - if m.Cmdy(ice.WEB_STORY, "index", m.Option("arg")).Append("text") == "" { - m.Cmdy(ice.WEB_SPACE, m.Option("pod"), ice.WEB_STORY, "index", m.Optionv("arg")) - } - m.Append("_output", kit.Select("file", "result", m.Append("file") == "")) - - case "history": - vs := strings.SplitN(strings.TrimSpace(m.Option("arg")), " ", 2) - m.Cmd(ice.WEB_SPACE, m.Option("you"), ice.WEB_FAVOR, "zsh.history", "shell", m.Option("sid"), kit.Select("", vs, 1), - "sid", m.Option("sid"), "num", vs[0], "pwd", m.Option("pwd")) - m.Push("_output", "void") - - case "favor": - if m.Options("arg") { - m.Cmdy(ice.WEB_SPACE, m.Option("you"), ice.WEB_FAVOR, - m.Option("tab"), ice.TYPE_SHELL, m.Option("note"), m.Option("arg")) - break - } - m.Echo("#/bin/sh\n\n") - m.Cmd(ice.WEB_SPACE, m.Option("you"), ice.WEB_FAVOR, m.Option("tab")).Table(func(index int, value map[string]string, head []string) { - switch value["type"] { - case ice.TYPE_SHELL: - m.Echo("# %v:%v\n%v\n\n", value["type"], value["name"], value["text"]) - } - }) - m.Push("_output", "result") - } - }}, - "/vim": {Name: "/vim", Help: "编辑器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if f, _, e := m.R.FormFile("sub"); e == nil { - defer f.Close() - if b, e := ioutil.ReadAll(f); e == nil { - m.Option("sub", string(b)) - } - } - - m.Option("you", "") - m.Richs("login", nil, m.Option("sid"), func(key string, value map[string]interface{}) { - m.Option("you", value["you"]) - }) - m.Info("%s%s %s arg: %v sub: %v", m.Option("you"), cmd, m.Option("cmd"), m.Optionv("arg"), m.Optionv("sub")) - - m.Push("_output", "result") - switch m.Option("cmd") { - case "login": - m.Cmdy("login", "init", cmd) - case "logout": - m.Cmdy("login", "exit") - - case "read", "write", "exec": - m.Cmd(ice.WEB_FAVOR, "vim.history", "vimrc", m.Option("cmd"), m.Option("arg"), - "sid", m.Option("sid"), "pwd", m.Option("pwd"), "buf", m.Option("buf")) - - case "tasklet": - m.Cmd(ice.APP_MISS, m.Option("arg"), m.Option("sub")) - - case "trans": - if strings.HasPrefix(strings.TrimSpace(m.Option("arg")), "ice ") { - arg := kit.Split(strings.TrimPrefix(strings.TrimSpace(m.Option("arg")), "ice ")) - switch arg[0] { - case "add": - // 添加词汇 - m.Cmd("input.push", arg[1:]) - m.Option("arg", arg[2]) - default: - // 执行命令 - m.Set("append") - if m.Cmdy(arg).Table(); strings.TrimSpace(m.Result()) == "" { - m.Cmdy(ice.CLI_SYSTEM, arg) - } - m.Push("_output", "result") - return - } - } - // 词汇列表 - m.Cmd("input.find", m.Option("arg")).Table(func(index int, value map[string]string, head []string) { - m.Echo("%s\n", value["text"]) - m.Push("_output", "result") - }) - - case "favor": - if m.Options("arg") { - m.Cmd(ice.WEB_FAVOR, m.Option("tab"), "vimrc", m.Option("note"), m.Option("arg"), - "buf", m.Option("buf"), "line", m.Option("line"), "col", m.Option("col"), - ) - break - } - m.Cmd(ice.WEB_FAVOR, m.Option("tab"), "extra", "buf line col").Table(func(index int, value map[string]string, head []string) { - switch value["type"] { - case ice.TYPE_VIMRC: - m.Echo("%v\n", m.Option("tab")).Echo("%v:%v:%v:(%v): %v\n", - value["buf"], value["line"], value["col"], value["name"], value["text"]) - } - }) - } - }}, }, } diff --git a/misc/docker/docker.go b/misc/docker/docker.go index adbcb875..89407777 100644 --- a/misc/docker/docker.go +++ b/misc/docker/docker.go @@ -4,43 +4,43 @@ import ( "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/core/code" "github.com/shylinux/toolkits" - "os" - "os/exec" - "path" + "strings" - "time" ) -var Dockfile = ` -FROM {{options . "base"}} - -WORKDIR /home/{{options . "user"}}/context -Env ctx_dev {{options . "host"}} - -RUN wget -q -O - $ctx_dev/publish/boot.sh | sh -s install - -CMD sh bin/boot.sh - -` - var Index = &ice.Context{Name: "docker", Help: "虚拟机", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ "docker": {Name: "docker", Help: "虚拟机", Value: kit.Data(kit.MDB_SHORT, "name")}, }, Commands: map[string]*ice.Command{ - ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - // if m.Richs(ice.WEB_FAVOR, nil, "alpine.init", nil) == nil { - // m.Cmd(ice.WEB_FAVOR, "alpine.init", ice.TYPE_SHELL, "镜像源", `sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories`) - // m.Cmd(ice.WEB_FAVOR, "alpine.init", ice.TYPE_SHELL, "软件包", `apk add bash`) - // m.Cmd(ice.WEB_FAVOR, "alpine.init", ice.TYPE_SHELL, "软件包", `apk add curl`) - // } - }}, - ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, + "init": {Name: "init", Help: "初始化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Watch(ice.DREAM_START, m.Prefix("auto")) - "image": {Name: "image", Help: "镜像管理", Meta: kit.Dict("detail", []string{"运行", "清理", "删除"}), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if m.Richs(ice.WEB_FAVOR, nil, "alpine.auto", nil) == nil { + m.Cmd(ice.WEB_FAVOR, "alpine.auto", ice.TYPE_SHELL, "镜像源", `sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories`) + m.Cmd(ice.WEB_FAVOR, "alpine.auto", ice.TYPE_SHELL, "软件包", `apk add bash`) + m.Cmd(ice.WEB_FAVOR, "alpine.auto", ice.TYPE_SHELL, "软件包", `apk add curl`) + } + }}, + "auto": {Name: "auto", Help: "自动化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + prefix := []string{ice.CLI_SYSTEM, "docker"} + // 创建容器 + pid := m.Cmdx(prefix, "run", "-dt", "--name", arg[0], "--mount", kit.Format("type=bind,source=%s,target=/root", + kit.Path(m.Conf(ice.WEB_DREAM, "meta.path"), arg[0])), "alpine") + m.Log(ice.LOG_CREATE, "%s: %s", arg[0], pid) + + m.Cmd(ice.WEB_FAVOR, kit.Select("alpine.auto", arg, 1)).Table(func(index int, value map[string]string, head []string) { + if value["type"] == ice.TYPE_SHELL { + // 执行命令 + m.Cmd(prefix, "exec", arg[0], kit.Split(value["text"])) + } + }) + }}, + + "image": {Name: "image", Help: "镜像管理", Meta: kit.Dict("detail", []string{"运行", "清理", "删除"}), List: ice.ListLook("IMAGE_ID"), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { prefix := []string{ice.CLI_SYSTEM, "docker", "image"} - if len(arg) > 2 { + if len(arg) > 1 && arg[0] == "action" { switch arg[1] { case "运行": m.Cmdy(prefix[:2], "run", "-dt", m.Option("REPOSITORY")+":"+m.Option("TAG")).Set("append") @@ -54,46 +54,55 @@ var Index = &ice.Context{Name: "docker", Help: "虚拟机", } } + if len(arg) > 0 { + // 容器详情 + res := m.Cmdx(prefix, "inspect", arg[0]) + m.Push("detail", kit.KeyValue(map[string]interface{}{}, "", kit.Parse(nil, "", kit.Split(res)...))) + return + } + if len(arg) > 0 { // 下载镜像 m.Cmdy(prefix, "pull", arg[0]+":"+kit.Select("latest", arg, 1)).Set("append") return } + // 镜像列表 m.Split(strings.Replace(m.Cmdx(prefix, "ls"), "IMAGE ID", "IMAGE_ID", 1), "index", " ", "\n") m.Sort("REPOSITORY") }}, - "container": {Name: "container", Help: "容器管理", Meta: kit.Dict( - "exports", []string{"CONTAINER_ID", "CONTAINER_ID"}, - "detail", []string{"进入", "启动", "停止", "重启", "清理", "编辑", "删除"}), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + "container": {Name: "container", Help: "容器管理", List: ice.ListLook("CONTAINER_ID"), Meta: kit.Dict("detail", []string{"进入", "启动", "停止", "重启", "清理", "编辑", "删除"}), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { prefix := []string{ice.CLI_SYSTEM, "docker", "container"} - if len(arg) > 2 { + if len(arg) > 1 && arg[0] == "action" { switch arg[1] { case "进入": - m.Cmd("cli.tmux.session").Table(func(index int, value map[string]string, head []string) { - if value["tag"] == "1" { - m.Cmdy(ice.CLI_SYSTEM, "tmux", "new-window", "-t", value["session"], "-n", m.Option("NAMES"), - "-PF", "#{session_name}:#{window_name}.1", "docker exec -it "+m.Option("NAMES")+" sh").Set("append") - } - }) + m.Cmdy(ice.CLI_SYSTEM, "tmux", "new-window", "-t", m.Option("NAMES"), "-n", m.Option("NAMES"), + "-PF", "#{session_name}:#{window_name}.1", "docker exec -it "+m.Option("NAMES")+" bash").Set("append") return case "停止": - m.Cmd(prefix, "stop", m.Option("CONTAINER_ID")) + m.Cmdy(prefix, "stop", m.Option("CONTAINER_ID")) case "启动": - m.Cmd(prefix, "start", m.Option("CONTAINER_ID")) + m.Cmdy(prefix, "start", m.Option("CONTAINER_ID")) case "重启": - m.Cmd(prefix, "restart", m.Option("CONTAINER_ID")) + m.Cmdy(prefix, "restart", m.Option("CONTAINER_ID")) case "清理": - m.Cmd(prefix, "prune", "-f") + m.Cmdy(prefix, "prune", "-f") case "modify": switch arg[2] { case "NAMES": - m.Cmd(prefix, "rename", arg[4], arg[3]) + m.Cmdy(prefix, "rename", arg[4], arg[3]) } case "delete": m.Cmdy(prefix, "rm", m.Option("CONTAINER_ID")).Set("append") - return } + return + } + + if len(arg) > 0 { + // 容器详情 + res := m.Cmdx(prefix, "inspect", arg[0]) + m.Push("detail", kit.KeyValue(map[string]interface{}{}, "", kit.Parse(nil, "", kit.Split(res)...))) + return } // 容器列表 @@ -101,287 +110,17 @@ var Index = &ice.Context{Name: "docker", Help: "虚拟机", m.Sort("NAMES") }}, "command": {Name: "command", Help: "命令", List: kit.List( - kit.MDB_INPUT, "text", "name", "CONTAINER_ID", "imports", "CONTAINER_ID", - kit.MDB_INPUT, "text", "name", "command", - kit.MDB_INPUT, "button", "name", "执行", + kit.MDB_INPUT, "text", "name", "CONTAINER_ID", + kit.MDB_INPUT, "text", "name", "cmd", "className", "args cmd", + kit.MDB_INPUT, "button", "value", "执行", ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) < 2 { + m.Cmdy("container") + return + } prefix := []string{ice.CLI_SYSTEM, "docker", "container"} m.Cmdy(prefix, "exec", arg[0], arg[1:]).Set("append") }}, - - "_tmux": {Name: "tmux [session [window [pane cmd]]]", Help: "窗口", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := kit.Simple(m.Confv("prefix", "tmux")) - if len(arg) > 1 { - switch arg[1] { - case "cmd": - - case "favor": - env := m.Cmdx(prefix, "show-environment", "-g") + m.Cmdx(prefix, "show-environment", "-t", arg[0]) - for _, l := range strings.Split(env, "\n") { - if strings.HasPrefix(l, "ctx_") { - v := strings.SplitN(l, "=", 2) - m.Option(v[0], v[1]) - } - } - m.Option("ctx_dev", m.Option("ctx_self")) - - m.Confm("tmux", "favor."+kit.Select("index", arg, 4), func(index int, value string) { - if index == 0 { - keys := strings.Split(value, " ") - value = "export" - for _, k := range keys { - value += " " + k + "=" + m.Option(k) - } - - } - m.Cmdy(prefix, "send-keys", "-t", arg[0], value, "Enter") - time.Sleep(100 * time.Millisecond) - }) - m.Echo(strings.TrimSpace(m.Cmdx(prefix, "capture-pane", "-pt", arg[0]))) - return - } - } - return - }}, - "_docker": {Name: "docker image|volume|network|container", Help: "容器", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - prefix := kit.Simple(m.Confv("prefix", "docker")) - switch arg[0] { - case "image": - if prefix = append(prefix, "image"); len(arg) < 3 { - m.Cmdy(prefix, "ls", "cmd_parse", "cut", "cmd_headers", "IMAGE ID", "IMAGE_ID") - break - } - - switch arg[2] { - case "运行": - m.Cmdy(prefix[:2], "run", "-dt", m.Option("REPOSITORY")+":"+m.Option("TAG")) - case "清理": - m.Cmdy(prefix, "prune", "-f") - case "delete": - m.Cmdy(prefix, "rm", m.Option("IMAGE_ID")) - case "创建": - m.Option("base", m.Option("REPOSITORY")+":"+m.Option("TAG")) - app := m.Conf("runtime", "boot.ctx_app") - m.Option("name", app+":"+m.Time("20060102")) - m.Option("file", m.Conf("docker", "output")) - m.Option("user", m.Conf("runtime", "boot.username")) - m.Option("host", "http://"+m.Conf("runtime", "boot.hostname")+".local"+m.Conf("runtime", "boot.web_port")) - - if f, _, e := kit.Create(m.Option("file")); m.Assert(e) { - defer f.Close() - // if m.Assert(ctx.ExecuteStr(m, f, m.Conf("docker", "template."+app))) { - // m.Cmdy(prefix, "build", "-f", m.Option("file"), "-t", m.Option("name"), ".") - // } - } - - default: - if len(arg) == 3 { - m.Cmdy(prefix, "pull", arg[1]+":"+arg[2]) - break - } - } - - case "volume": - if prefix = append(prefix, "volume"); len(arg) == 1 { - m.Cmdy(prefix, "ls", "cmd_parse", "cut", "cmd_headers", "VOLUME NAME", "VOLUME_NAME") - break - } - - case "network": - if prefix = append(prefix, "network"); len(arg) == 1 { - m.Cmdy(prefix, "ls", "cmd_parse", "cut", "cmd_headers", "NETWORK ID", "NETWORK_ID") - break - } - - kit.Fetch(kit.Value(kit.UnMarshal(m.Cmdx(prefix, "inspect", arg[1])), "0.Containers"), func(key string, value map[string]interface{}) { - m.Push("CONTAINER_ID", key[:12]) - m.Push("name", value["Name"]) - m.Push("IPv4", value["IPv4Address"]) - m.Push("IPv6", value["IPV4Address"]) - m.Push("Mac", value["MacAddress"]) - }) - m.Table() - - case "container": - if prefix = append(prefix, "container"); len(arg) > 1 { - switch arg[2] { - case "进入": - m.Cmdy(m.Confv("prefix", "tmux"), "new-window", "-t", "", "-n", m.Option("CONTAINER_NAME"), - "-PF", "#{session_name}:#{window_name}.1", "docker exec -it "+arg[1]+" sh") - return - - case "停止": - m.Cmd(prefix, "stop", arg[1]) - - case "启动": - m.Cmd(prefix, "start", arg[1]) - - case "重启": - m.Cmd(prefix, "restart", arg[1]) - - case "清理": - m.Cmd(prefix, "prune", "-f") - - case "modify": - switch arg[3] { - case "NAMES": - m.Cmd(prefix, "rename", arg[1], arg[4:]) - } - - case "delete": - m.Cmdy(prefix, "rm", arg[1]) - - default: - if len(arg) == 2 { - m.Cmdy(prefix, "inspect", arg[1]) - return - } - m.Cmdy(prefix, "exec", arg[1], arg[2:]) - return - } - } - m.Cmdy(prefix, "ls", "-a", "cmd_parse", "cut", "cmd_headers", "CONTAINER ID", "CONTAINER_ID") - - case "command": - switch arg[3] { - case "base": - m.Echo("\n0[%s]$ %s %s\n", time.Now().Format("15:04:05"), arg[2], m.Conf("package", arg[2]+".update")) - m.Cmdy(prefix, "exec", arg[1], arg[2], strings.Split(m.Conf("package", arg[2]+".update"), " ")) - m.Confm("package", []string{arg[2], arg[3]}, func(index int, value string) { - m.Echo("\n%d[%s]$ %s %s %s\n", index+1, time.Now().Format("15:04:05"), arg[2], m.Conf("package", arg[2]+".install"), value) - m.Cmdy(prefix, "exec", arg[1], arg[2], strings.Split(m.Conf("package", arg[2]+".install"), " "), value) - }) - } - - default: - m.Cmdy(prefix, arg) - } - return - }}, - "_git": {Name: "git init|diff|status|commit|branch|remote|pull|push|sum", Help: "版本", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - prefix, arg := append(kit.Simple(m.Confv("prefix", "git")), "cmd_dir", kit.Select(".", arg[0])), arg[1:] - - switch arg[0] { - case "init": - if _, e := os.Stat(path.Join(prefix[len(prefix)-1], ".git")); e != nil { - m.Cmdy(prefix, "init") - } - if len(arg) > 1 { - m.Cmdy(prefix, "remote", "add", "-f", kit.Select("origin", arg, 2), arg[1]) - m.Cmdy(prefix, "pull", kit.Select("origin", arg, 2), kit.Select("master", arg, 3)) - } - - m.Confm("git", "alias", func(key string, value string) { - m.Cmdy(prefix, "config", "alias."+key, value) - }) - - case "diff": - m.Cmdy(prefix, "diff") - case "status": - m.Cmdy(prefix, "status", "-sb", "cmd_parse", "cut", " ", "2", "tags file") - case "commit": - if len(arg) > 1 && m.Cmdy(prefix, "commit", "-am", arg[1]).Result() == "" { - break - } - m.Cmdy(prefix, "log", "--stat", "-n", "3") - case "branch": - if len(arg) > 1 { - m.Cmd(prefix, "branch", arg[1]) - m.Cmd(prefix, "checkout", arg[1]) - } - for _, v := range strings.Split(m.Cmdx(prefix, "branch", "-v"), "\n") { - if len(v) > 0 { - m.Push("tags", v[:2]) - vs := strings.SplitN(strings.TrimSpace(v[2:]), " ", 2) - m.Push("branch", vs[0]) - vs = strings.SplitN(strings.TrimSpace(vs[1]), " ", 2) - m.Push("hash", vs[0]) - m.Push("note", strings.TrimSpace(vs[1])) - } - } - m.Table() - case "remote": - m.Cmdy(prefix, "remote", "-v", "cmd_parse", "cut", " ", "3", "remote url tag") - - case "push": - m.Cmdy(prefix, "push") - case "sum": - total := false - if len(arg) > 1 && arg[1] == "total" { - total, arg = true, arg[1:] - } - - args := []string{"log", "--shortstat", "--pretty=commit: %ad %n%s", "--date=iso", "--reverse"} - if len(arg) > 1 { - args = append(args, kit.Select("-n", "--since", strings.Contains(arg[1], "-"))) - if strings.Contains(arg[1], "-") && !strings.Contains(arg[1], ":") { - arg[1] = arg[1] + " 00:00:00" - } - args = append(args, arg[1:]...) - } else { - args = append(args, "-n", "30") - } - - var total_day time.Duration - count, count_add, count_del := 0, 0, 0 - if out, e := exec.Command("git", args...).CombinedOutput(); e == nil { - for i, v := range strings.Split(string(out), "commit: ") { - if i > 0 { - l := strings.Split(v, "\n") - hs := strings.Split(l[0], " ") - - add, del := "0", "0" - if len(l) > 3 { - fs := strings.Split(strings.TrimSpace(l[3]), ", ") - if adds := strings.Split(fs[1], " "); len(fs) > 2 { - dels := strings.Split(fs[2], " ") - add = adds[0] - del = dels[0] - } else if adds[1] == "insertions(+)" { - add = adds[0] - } else { - del = adds[0] - } - } - - if total { - if count++; i == 1 { - if t, e := time.Parse(ice.ICE_DATE, hs[0]); e == nil { - total_day = time.Now().Sub(t) - m.Append("from", hs[0]) - } - } - count_add += kit.Int(add) - count_del += kit.Int(del) - continue - } - - m.Push("date", hs[0]) - m.Push("adds", add) - m.Push("dels", del) - m.Push("rest", kit.Int(add)-kit.Int(del)) - m.Push("note", l[1]) - m.Push("hour", strings.Split(hs[1], ":")[0]) - m.Push("time", hs[1]) - } - } - if total { - m.Append("days", int(total_day.Hours())/24) - m.Append("commit", count) - m.Append("adds", count_add) - m.Append("dels", count_del) - m.Append("rest", count_add-count_del) - } - m.Table() - } else { - m.Log("warn", "%v", string(out)) - } - - default: - m.Cmdy(prefix, arg) - } - return - }}, }, } diff --git a/misc/git/git.go b/misc/git/git.go index 538e5559..b954645a 100644 --- a/misc/git/git.go +++ b/misc/git/git.go @@ -74,6 +74,45 @@ var Index = &ice.Context{Name: "git", Help: "代码库", }) m.Sort("name") }}, + "total": {Name: "total", Help: "统计", List: kit.List( + kit.MDB_INPUT, "text", "name", "name", "action", "auto", + kit.MDB_INPUT, "button", "name", "查看", "action", "auto", + kit.MDB_INPUT, "button", "name", "返回", "cb", "Last", + ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) > 0 { + // 提交详情 + m.Richs("repos", nil, arg[0], func(key string, value map[string]interface{}) { + m.Cmdy("_sum", kit.Value(value, "meta.path"), arg[1:]) + }) + return + } + + // 提交统计 + days := 0 + commit, adds, dels, rest := 0, 0, 0, 0 + m.Richs("repos", nil, "*", func(key string, value map[string]interface{}) { + if m.Conf("total", kit.Keys("meta.skip", kit.Value(value, "meta.name"))) == "true" { + return + } + m.Push("name", kit.Value(value, "meta.name")) + m.Copy(m.Cmd("_sum", kit.Value(value, "meta.path"), "total", "10000").Table(func(index int, value map[string]string, head []string) { + if kit.Int(value["days"]) > days { + days = kit.Int(value["days"]) + } + commit += kit.Int(value["commit"]) + adds += kit.Int(value["adds"]) + dels += kit.Int(value["dels"]) + rest += kit.Int(value["rest"]) + })) + }) + m.Push("name", "total") + m.Push("days", days) + m.Push("commit", commit) + m.Push("adds", adds) + m.Push("dels", dels) + m.Push("rest", rest) + m.Sort("adds", "int_r") + }}, "status": {Name: "status repos", Help: "状态", Meta: kit.Dict( "detail", []interface{}{"add", "reset", "remove", kit.Dict("name", "commit", "args", kit.List( kit.MDB_INPUT, "select", "name", "type", "values", []string{"add", "opt"}, @@ -86,7 +125,7 @@ var Index = &ice.Context{Name: "git", Help: "代码库", ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { prefix := []string{ice.CLI_SYSTEM, "git"} - if len(arg) > 0 && arg[0] == "action" { + if len(arg) > 1 && arg[0] == "action" { m.Richs("repos", nil, m.Option("name"), func(key string, value map[string]interface{}) { m.Option("cmd_dir", kit.Value(value, "meta.path")) switch arg[1] { @@ -119,46 +158,8 @@ var Index = &ice.Context{Name: "git", Help: "代码库", } }) }}, - "total": {Name: "total", Help: "统计", List: kit.List( - kit.MDB_INPUT, "text", "name", "name", "action", "auto", - kit.MDB_INPUT, "button", "name", "查看", "action", "auto", - kit.MDB_INPUT, "button", "name", "返回", "cb", "Last", - ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) > 0 { - // 提交详情 - m.Richs("repos", nil, arg[0], func(key string, value map[string]interface{}) { - m.Cmdy("sum", kit.Value(value, "meta.path"), arg[1:]) - }) - return - } - // 提交统计 - days := 0 - commit, adds, dels, rest := 0, 0, 0, 0 - m.Richs("repos", nil, "*", func(key string, value map[string]interface{}) { - if m.Conf("total", kit.Keys("meta.skip", kit.Value(value, "meta.name"))) == "true" { - return - } - m.Push("name", kit.Value(value, "meta.name")) - m.Copy(m.Cmd("sum", kit.Value(value, "meta.path"), "total", "10000").Table(func(index int, value map[string]string, head []string) { - if kit.Int(value["days"]) > days { - days = kit.Int(value["days"]) - } - commit += kit.Int(value["commit"]) - adds += kit.Int(value["adds"]) - dels += kit.Int(value["dels"]) - rest += kit.Int(value["rest"]) - })) - }) - m.Push("name", "total") - m.Push("days", days) - m.Push("commit", commit) - m.Push("adds", adds) - m.Push("dels", dels) - m.Push("rest", rest) - m.Sort("adds", "int_r") - }}, - "sum": {Name: "sum [path] [total] [count|date] args...", Help: "统计", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + "_sum": {Name: "_sum [path] [total] [count|date] args...", Help: "统计", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) > 0 { if s, e := os.Stat(arg[0] + "/.git"); e == nil && s.IsDir() { m.Option("cmd_dir", arg[0]) @@ -234,9 +235,7 @@ var Index = &ice.Context{Name: "git", Help: "代码库", } }}, - "trend": {Name: "check name [path [repos]]", Help: "检查", Meta: kit.Dict( - "display", "/plugin/story/trend", - ), List: kit.List( + "trend": {Name: "check name [path [repos]]", Help: "检查", Meta: kit.Dict("display", "/plugin/story/trend"), List: kit.List( kit.MDB_INPUT, "text", "name", "repos", "action", "auto", kit.MDB_INPUT, "text", "name", "begin_time", "figure", "date", kit.MDB_INPUT, "button", "name", "执行", "action", "auto", @@ -247,32 +246,6 @@ var Index = &ice.Context{Name: "git", Help: "代码库", } m.Cmdy("total", arg) }}, - - "check": {Name: "check name [path [repos]]", Help: "检查", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) > 1 { - m.Cmd("repos", arg) - } - }}, - "branch": {Name: "branch", Help: "分支", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := []string{ice.CLI_SYSTEM, "git", "branch"} - m.Richs("repos", nil, kit.Select("*", arg, 0), func(key string, value map[string]interface{}) { - m.Option("cmd_dir", kit.Value(value, "meta.path")) - for _, v := range strings.Split(m.Cmdx(prefix, "-v"), "\n") { - if len(v) > 0 { - m.Push("time", m.Cmdx(ice.CLI_SYSTEM, "git", "log", "-n", "1", "--pretty=%ad", "--date=iso")) - m.Push("name", kit.Value(value, "meta.name")) - - m.Push("tags", v[:2]) - vs := strings.SplitN(strings.TrimSpace(v[2:]), " ", 2) - m.Push("branch", vs[0]) - vs = strings.SplitN(strings.TrimSpace(vs[1]), " ", 2) - m.Push("hash", vs[0]) - m.Push("last", strings.TrimSpace(vs[1])) - } - } - }) - m.Sort("repos") - }}, }, } diff --git a/misc/input/input.go b/misc/input/input.go index 7988d556..20078383 100644 --- a/misc/input/input.go +++ b/misc/input/input.go @@ -18,7 +18,7 @@ var Index = &ice.Context{Name: "input", Help: "输入法", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ "input": {Name: "input", Help: "输入法", Value: kit.Data( - "store", "var/input/", "fsize", "100000", "limit", "2000", "least", "1000", + "store", "var/input/", "fsize", "200000", "limit", "5000", "least", "1000", "repos", "wubi-dict", "local", "some", )}, }, @@ -33,29 +33,32 @@ var Index = &ice.Context{Name: "input", Help: "输入法", "load": {Name: "load file [name]", Help: "加载词库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { // 默认词库 - if m.Cmd("web.code.git.check", m.Conf("input", "meta.repos")); m.Confs("input", "wubi86") { + if m.Cmd("web.code.git.repos", m.Conf("input", "meta.repos"), "usr/"+m.Conf("input", "meta.repos")); m.Confs("input", "wubi86") { m.Echo("wubi86: %v", m.Conf("input", "wubi86.meta.count")) return } arg = append(arg, path.Join("usr", m.Conf("input", "meta.repos"), "wubi86")) } - lib := kit.Select(path.Base(arg[0]), arg, 1) - - // 缓存配置 - m.Option("cache.least", m.Conf("input", "meta.least")) - m.Option("cache.limit", m.Conf("input", "meta.limit")) - m.Option("cache.fsize", m.Conf("input", "meta.fsize")) - m.Assert(os.RemoveAll(m.Option("cache.store", path.Join(m.Conf("input", "meta.store"), lib)))) - m.Conf("input", lib, "") if f, e := os.Open(arg[0]); m.Assert(e) { bio := bufio.NewScanner(f) + + // 清空数据 + lib := kit.Select(path.Base(arg[0]), arg, 1) + m.Assert(os.RemoveAll(m.Option("cache.store", path.Join(m.Conf("input", "meta.store"), lib)))) + m.Conf("input", lib, "") + + // 缓存配置 + m.Option("cache.least", m.Conf("input", "meta.least")) + m.Option("cache.limit", m.Conf("input", "meta.limit")) + m.Option("cache.fsize", m.Conf("input", "meta.fsize")) + // 加载词库 for bio.Scan() { if strings.HasPrefix(bio.Text(), "#") { continue } - line := kit.Split(bio.Text(), " \t") + line := kit.Split(bio.Text()) if line[2] == "0" { continue } @@ -67,14 +70,23 @@ var Index = &ice.Context{Name: "input", Help: "输入法", m.Echo("%s: %d", lib, m.Grow("input", lib, kit.Dict("text", "成功", "code", "z", "weight", "0"))) } }}, - "push": {Name: "push text code [weight [lib]]", Help: "添加词汇", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - lib := kit.Select("person", arg, 2) + "push": {Name: "push lib text code [weight]", Help: "添加词汇", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Option("cache.least", 0) m.Option("cache.limit", 0) - m.Option("cache.store", path.Join(m.Conf("input", "meta.store"), lib)) - m.Echo("%s: %d", lib, m.Grow("input", lib, kit.Dict("text", arg[0], "code", arg[1], "weight", kit.Select("99990000", arg, 3)))) + m.Option("cache.store", path.Join(m.Conf("input", "meta.store"), arg[0])) + m.Echo("%s: %d", arg[0], m.Grow("input", arg[0], kit.Dict( + "text", arg[1], "code", arg[2], "weight", kit.Select("9091929394", arg, 3)))) }}, "list": {Name: "list [lib [offend [limit]]]", Help: "查看词汇", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) == 0 { + kit.Fetch(m.Confv("input"), func(key string, value map[string]interface{}) { + if key != "meta" { + m.Push(key, value["meta"], []string{"key", "count"}) + } + }) + return + } + lib := kit.Select("person", arg, 0) m.Option("cache.offend", kit.Select("0", arg, 1)) m.Option("cache.limit", kit.Select("10", arg, 2)) @@ -84,14 +96,17 @@ var Index = &ice.Context{Name: "input", Help: "输入法", }}, "save": {Name: "save lib [filename]", Help: "导出词库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { lib := kit.Select("person", arg, 0) - m.Option("cache.limit", 1000000) - m.Option("cache.offend", 0) - if f, p, e := kit.Create(path.Join("usr", m.Conf("input", "meta.repos"), lib)); m.Assert(e) { + if f, p, e := kit.Create(kit.Select(path.Join("usr", m.Conf("input", "meta.repos"), lib), arg, 1)); m.Assert(e) { defer f.Close() + n := 0 + m.Option("cache.offend", 0) + m.Option("cache.limit", -2) m.Grows("input", lib, "", "", func(index int, value map[string]interface{}) { - n++ - fmt.Fprintf(f, "%s %s %s\n", value["text"], value["code"], value["weight"]) + if value["code"] != "z" { + n++ + fmt.Fprintf(f, "%s %s %s\n", value["text"], value["code"], value["weight"]) + } }) m.Log(ice.LOG_EXPORT, "%s: %d", p, n) m.Echo("%s: %d", p, n) @@ -122,6 +137,7 @@ var Index = &ice.Context{Name: "input", Help: "输入法", if line, e := bio.Read(); e != nil { break } else if len(line) < 3 { + } else { if method == "word" && i == 0 { // 添加收藏 @@ -141,4 +157,7 @@ var Index = &ice.Context{Name: "input", Help: "输入法", }, } +// ice add person 码神 dcpy +// 码神 + func init() { code.Index.Register(Index, nil) } diff --git a/misc/shy.go b/misc/shy.go index 70443071..6cd3c993 100644 --- a/misc/shy.go +++ b/misc/shy.go @@ -1,9 +1,10 @@ package misc import ( - _ "github.com/shylinux/icebergs/misc/chrome" _ "github.com/shylinux/icebergs/misc/docker" _ "github.com/shylinux/icebergs/misc/git" _ "github.com/shylinux/icebergs/misc/input" _ "github.com/shylinux/icebergs/misc/tmux" + _ "github.com/shylinux/icebergs/misc/vim" + _ "github.com/shylinux/icebergs/misc/zsh" ) diff --git a/misc/tmux/tmux.go b/misc/tmux/tmux.go index 95ef85f4..0afda055 100644 --- a/misc/tmux/tmux.go +++ b/misc/tmux/tmux.go @@ -4,29 +4,14 @@ import ( "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/core/code" "github.com/shylinux/toolkits" + "os" "path" "strings" "time" ) -type Frame struct { -} - -func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server { - return &Frame{} -} -func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server { - return f -} -func (f *Frame) Start(m *ice.Message, arg ...string) bool { - return true -} -func (f *Frame) Close(m *ice.Message, arg ...string) bool { - return true -} - -var Index = &ice.Context{Name: "tmux", Help: "命令行", +var Index = &ice.Context{Name: "tmux", Help: "工作台", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ "buffer": {Name: "buffer", Help: "缓存", Value: kit.Data()}, @@ -53,63 +38,95 @@ var Index = &ice.Context{Name: "tmux", Help: "命令行", }, Commands: map[string]*ice.Command{ "init": {Name: "init", Help: "初始化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Watch(ice.DREAM_START, "web.code.tmux.auto") - m.Watch(ice.FAVOR_START, "web.code.tmux.auto") + m.Watch(ice.DREAM_START, m.Prefix("auto")) + + if m.Richs(ice.WEB_FAVOR, nil, "tmux.auto", nil) == nil { + m.Cmd(ice.WEB_FAVOR, "tmux.auto", ice.TYPE_SHELL, "脚本", `curl $ctx_dev/publish/auto.sh > auto.sh`) + } for _, v := range []string{"auto.sh", "auto.vim"} { p := path.Join(m.Conf("web.code.publish", "meta.path"), v) if _, e := os.Stat(p); e != nil && os.IsNotExist(e) { + // 下载脚本 if h := m.Cmdx(ice.WEB_SPIDE, "shy", "cache", "GET", "/publish/"+v); h != "" { - os.Link(m.Cmd(ice.WEB_STORY, "index", h).Append("file"), p) - m.Log(ice.LOG_EXPORT, "%s: %s", h, p) + m.Cmd(ice.WEB_STORY, ice.STORY_WATCH, h, p) } } } }}, + "auto": {Name: "auto", Help: "初始化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + prefix := []string{ice.CLI_SYSTEM, "tmux"} - "text": {Name: "text", Help: "文本", - List: kit.List( - kit.MDB_INPUT, "text", "name", "name", - kit.MDB_INPUT, "button", "value", "保存", - kit.MDB_INPUT, "textarea", "name", "text", - ), - Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) > 1 && arg[1] != "" { - m.Cmd("cli.system", "tmux", "set-buffer", arg[1]) - } - m.Cmdy("cli.system", "tmux", "show-buffer").Set("append") - }}, - "buffer": {Name: "buffer", Help: "终端", - List: kit.List( - kit.MDB_INPUT, "text", "name", "buffer", "action", "auto", - kit.MDB_INPUT, "text", "name", "value", - kit.MDB_INPUT, "button", "value", "查看", "action", "auto", - kit.MDB_INPUT, "button", "value", "返回", "cb", "Last", - ), - Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) == 0 { - // 缓存列表 - for i, v := range kit.Split(m.Cmdx("cli.system", "tmux", "list-buffers"), "\n") { - ls := strings.SplitN(v, ": ", 3) - m.Push("buffer", ls[0]) - m.Push("size", ls[1]) - if i < 3 { - m.Push("text", m.Cmdx("cli.system", "tmux", "show-buffer", "-b", ls[0])) - } else { - m.Push("text", ls[2][1:]) - } - } - return - } + // 共享空间 + share, dev := "", kit.Select(m.Conf(ice.CLI_RUNTIME, "conf.ctx_dev"), m.Conf(ice.CLI_RUNTIME, "host.ctx_self")) + m.Richs(ice.WEB_SPACE, nil, arg[0], func(key string, value map[string]interface{}) { + share = kit.Format(value["share"]) + }) - if len(arg) > 1 { - // 设置缓存 - m.Cmd("cli.system", "tmux", "set-buffer", "-b", arg[0], arg[1]) - } + // 环境变量 + m.Option("cmd_env", "TMUX", "", "ctx_dev", dev, "ctx_share", share) + m.Option("cmd_dir", path.Join(m.Conf(ice.WEB_DREAM, "meta.path"), arg[0])) + if arg[0] != "" && m.Cmd(prefix, "has-session", "-t", arg[0]).Append("code") != "0" { + // 创建会话 + m.Cmd(prefix, "new-session", "-ds", arg[0]) + } + + // 连接参数 + m.Cmdy(prefix, "send-keys", "-t", arg[0], "export ctx_dev=", dev, "Enter") + m.Cmdy(prefix, "send-keys", "-t", arg[0], "export ctx_share=", share, "Enter") + + m.Cmd(ice.WEB_FAVOR, kit.Select("tmux.auto", arg, 1)).Table(func(index int, value map[string]string, head []string) { + switch value["type"] { + case "shell": + // 发送命令 + m.Cmdy(prefix, "send-keys", "-t", arg[0], value["text"], "Enter") + } + }) + }}, + + "text": {Name: "text", Help: "文本", List: kit.List( + kit.MDB_INPUT, "text", "name", "name", + kit.MDB_INPUT, "button", "value", "保存", + kit.MDB_INPUT, "textarea", "name", "text", + ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + prefix := []string{ice.CLI_SYSTEM, "tmux"} + if len(arg) > 1 && arg[1] != "" { + m.Cmd(prefix, "set-buffer", arg[1]) + } + m.Cmdy(prefix, "show-buffer").Set("append") + }}, + + "buffer": {Name: "buffer", Help: "缓存", List: kit.List( + kit.MDB_INPUT, "text", "name", "buffer", "action", "auto", + kit.MDB_INPUT, "text", "name", "value", + kit.MDB_INPUT, "button", "value", "查看", "action", "auto", + kit.MDB_INPUT, "button", "value", "返回", "cb", "Last", + ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + prefix := []string{ice.CLI_SYSTEM, "tmux"} + if len(arg) > 1 { + // 设置缓存 + m.Cmd(prefix, "set-buffer", "-b", arg[0], arg[1]) + } + + if len(arg) > 0 { // 查看缓存 - m.Cmdy("cli.system", "tmux", "show-buffer", "-b", arg[0]).Set("append") - }}, + m.Cmdy(prefix, "show-buffer", "-b", arg[0]).Set("append") + return + } + + // 缓存列表 + for i, v := range kit.Split(m.Cmdx(prefix, "list-buffers"), "\n") { + ls := strings.SplitN(v, ": ", 3) + m.Push("buffer", ls[0]) + m.Push("size", ls[1]) + if i < 3 { + m.Push("text", m.Cmdx(prefix, "show-buffer", "-b", ls[0])) + } else { + m.Push("text", ls[2][1:]) + } + } + }}, "session": {Name: "session", Help: "会话", Meta: kit.Dict("detail", []string{"选择", "运行", "编辑", "删除", "下载"}), List: kit.List( kit.MDB_INPUT, "text", "name", "session", "action", "auto", kit.MDB_INPUT, "text", "name", "window", "action", "auto", @@ -118,7 +135,7 @@ var Index = &ice.Context{Name: "tmux", Help: "命令行", kit.MDB_INPUT, "button", "value", "返回", "cb", "Last", ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { prefix := []string{"cli.system", "tmux"} - if len(arg) > 3 { + if len(arg) > 1 && arg[0] == "action" { switch arg[1] { case "运行": target := "" @@ -220,7 +237,7 @@ var Index = &ice.Context{Name: "tmux", Help: "命令行", } // 终端内容 - m.Cmdy("view", target) + m.Echo(strings.TrimSpace(m.Cmdx("view", target))) }}, "windows": {Name: "window", Help: "窗口", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Split(m.Cmdx(m.Confv(cmd, "meta.cmd"), "-t", kit.Select("", arg, 0), @@ -233,40 +250,7 @@ var Index = &ice.Context{Name: "tmux", Help: "命令行", "view": {Name: "view", Help: "终端", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Cmdy("cli.system", "tmux", "capture-pane", "-pt", kit.Select("", arg, 0)).Set("append") }}, - "auto": {Name: "auto", Help: "终端", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := []string{"cli.system", "tmux"} - if arg[0] == "" { - m.Cmd("web.code.tmux.session").Table(func(index int, value map[string]string, head []string) { - if value["tag"] == "1" { - arg[0] = value["session"] - } - }) - } - - m.Option("cmd_env", "TMUX", "") - p := path.Join(m.Conf(ice.WEB_DREAM, "meta.path"), arg[0]) - if s, e := os.Stat(p); e == nil && s.IsDir() { - m.Option("cmd_dir", p) - } - - // 创建会话 - if m.Cmd(prefix, "has-session", "-t", arg[0]).Append("code") != "0" { - m.Cmd(prefix, "new-session", "-ds", arg[0]) - } - - m.Cmdy(prefix, "send-keys", "-t", arg[0], "export ctx_dev=", kit.Select(m.Conf(ice.CLI_RUNTIME, "conf.ctx_dev"), m.Conf(ice.CLI_RUNTIME, "host.ctx_self")), "Enter") - m.Richs(ice.WEB_SPACE, nil, arg[0], func(key string, value map[string]interface{}) { - m.Cmdy(prefix, "send-keys", "-t", arg[0], "export ctx_share=", value["share"], "Enter") - }) - - m.Cmd(ice.WEB_FAVOR, kit.Select("tmux.auto", arg, 1)).Table(func(index int, value map[string]string, head []string) { - switch value["type"] { - case "shell": - m.Cmdy(prefix, "send-keys", "-t", arg[0], value["text"], "Enter") - } - }) - }}, }, } -func init() { code.Index.Register(Index, &Frame{}) } +func init() { code.Index.Register(Index, nil) } diff --git a/core/code/auto.vim b/misc/vim/auto.vim similarity index 50% rename from core/code/auto.vim rename to misc/vim/auto.vim index ffe75d3d..fc26fbe9 100644 --- a/core/code/auto.vim +++ b/misc/vim/auto.vim @@ -1,63 +1,105 @@ " 变量定义 func! ShyDefine(name, value) - if !exists("name") | exec "let " . a:name . " = \"" . a:value . "\"" | endif + if !exists(a:name) | exec "let " . a:name . " = \"" . a:value . "\"" | endif endfunc " 输出日志 -" call ShyDefine("g:ShyLog", "/dev/null") -call ShyDefine("g:ShyLog", "shy.log") +call ShyDefine("g:ShyLog", "/dev/null") fun! ShyLog(...) call writefile([strftime("%Y-%m-%d %H:%M:%S ") . join(a:000, " ")], g:ShyLog, "a") endfun -command -nargs=+ ShyLog call writefile([strftime("%Y-%m-%d %H:%M:%S ") . join([], " ")], g:ShyLog, "a") " 后端通信 call ShyDefine("g:ctx_sid", "") -call ShyDefine("g:ctx_url", (len($ctx_dev) > 1? $ctx_dev: "http://127.0.0.1:9020") . "/code/vim") -fun! ShySend(arg) +call ShyDefine("g:ctx_url", (len($ctx_dev) > 1? $ctx_dev: "http://127.0.0.1:9020") . "/code/vim/") +fun! ShySend(cmd, arg) if has_key(a:arg, "sub") && a:arg["sub"] != "" let temp = tempname() call writefile(split(a:arg["sub"], "\n"), temp, "b") let a:arg["sub"] = "@" . temp endif - let a:arg["buf"] = bufname("%") let a:arg["sid"] = g:ctx_sid let a:arg["pwd"] = getcwd() + let a:arg["buf"] = bufname("%") + let a:arg["row"] = line(".") + let a:arg["col"] = col(".") let args = "" for k in sort(keys(a:arg)) let args = args . " -F '" . k . "=" . a:arg[k] . "' " endfor - return system("curl -s " . g:ctx_url . args . " 2>/dev/null") -endfun -fun! ShySends(...) - let args = {} - if len(a:000) > 0 | let args["cmd"] = a:000[0] | endif - if len(a:000) > 1 | let args["arg"] = a:000[1] | endif - if len(a:000) > 2 | let args["sub"] = a:000[2] | endif - return ShySend(args) + return system("curl -s " . g:ctx_url . a:cmd . args . " 2>/dev/null") endfun " 用户登录 fun! ShyLogout() - if g:ctx_sid == "" | return | endif - call ShySends("logout") + if g:ctx_sid != "" | call ShySend("logout", {}) | endif endfun fun! ShyLogin() - let g:ctx_sid = ShySend({"cmd": "login", "share": $ctx_share, "pid": getpid(), "pane": $TMUX_PANE, "hostname": hostname(), "username": $USER}) + let g:ctx_sid = ShySend("login", {"share": $ctx_share, "pid": getpid(), "pane": $TMUX_PANE, "hostname": hostname(), "username": $USER}) +endfun +fun! ShyHelp() + echo ShySend("help", {}) endfun call ShyLogin() +" 数据同步 +fun! ShySync(target) + if bufname("%") == "ControlP" | return | end + + if a:target == "read" || a:target == "write" + call ShySend("sync", {"cmds": a:target, "arg": expand("")}) + elseif a:target == "exec" + call ShySend("sync", {"cmds": a:target, "arg": getcmdline()}) + elseif a:target == "insert" + call ShySend("sync", {"cmds": a:target, "sub": getreg(".")}) + else + let cmd = {"bufs": "buffers", "regs": "registers", "marks": "marks", "tags": "tags", "fixs": "clist"} + call ShySend("sync", {"cmds": a:target, "sub": execute(cmd[a:target])}) + endif +endfun + +" 输入补全 +fun! ShyInput(code) + return split(ShySend("input", {"cmds": a:code, "pre": getline("."), "row": line("."), "col": col(".")}), "\n") +endfun +fun! ShyComplete(firststart, base) + if a:firststart | let line = getline('.') | let start = col('.') - 1 + " 命令位置 + if match(line, '\s*ice ') == 0 | return match(line, "ice ") | endif + " 符号位置 + if line[start-1] !~ '\a' | return start - 1 | end + " 单词位置 + while start > 0 && line[start - 1] =~ '\a' | let start -= 1 | endwhile + return start + endif + + " 符号转换 + if a:base == "," | return [",", ","] | end + if a:base == "." | return ["。", "."] | end + if a:base == "\\" | return ["、", "\\"] | end + " 单词转换 + let list = ShyInput(a:base) + call ShyLog("trans", a:base, list) + return list +endfun +set completefunc=ShyComplete +set encoding=utf-8 +colorscheme torte +highlight Pmenu ctermfg=cyan ctermbg=darkblue +highlight PmenuSel ctermfg=darkblue ctermbg=cyan +highlight Comment ctermfg=cyan ctermbg=darkblue + " 收藏列表 +call ShyDefine("g:favor_tab", "") +call ShyDefine("g:favor_note", "") fun! ShyFavor() - if !exists("g:favor_tab") | let g:favor_tab = "" | endif - if !exists("g:favor_note") | let g:favor_note = "" | endif let g:favor_tab = input("tab: ", g:favor_tab) let g:favor_note = input("note: ", g:favor_note) - call ShySend({"cmd": "favor", "tab": g:favor_tab, "note": g:favor_note, "arg": getline("."), "line": getpos(".")[1], "col": getpos(".")[2]}) + call ShySend("favor", {"tab": g:favor_tab, "note": g:favor_note, "arg": getline("."), "row": getpos(".")[1], "col": getpos(".")[2]}) endfun fun! ShyFavors() - let res = split(ShySend({"cmd": "favor", "tab": input("tab: ")}), "\n") + let res = split(ShySend("favor", {"tab": input("tab: ", g:favor_tab)}), "\n") let page = "" | let note = "" for i in range(0, len(res)-1, 2) if res[i] != page @@ -68,22 +110,6 @@ fun! ShyFavors() endfor if note != "" | lexpr note | lopen | let note = "" | endif endfun - -" 数据同步 -fun! ShySync(target) - if bufname("%") == "ControlP" | return | end - - if a:target == "read" || a:target == "write" - call ShySend({"cmd": a:target, "arg": expand("")}) - elseif a:target == "exec" - call ShySend({"cmd": a:target, "arg": getcmdline()}) - elseif a:target == "insert" - call ShySend({"cmd": a:target, "sub": getreg("."), "row": line("."), "col": col(".")}) - else - let cmd = {"bufs": "buffers", "regs": "registers", "marks": "marks", "tags": "tags", "fixs": "clist"} - call ShySend({"cmd": "sync", "arg": a:target, "sub": execute(cmd[a:target])}) - endif -endfun fun! ShyCheck(target) if a:target == "cache" call ShySync("bufs") @@ -101,6 +127,10 @@ fun! ShyCheck(target) end endfun + + + + " 任务列表 fun! ShyTask() call ShySend({"cmd": "tasklet", "arg": input("target: "), "sub": input("detail: ")}) @@ -116,38 +146,43 @@ fun! ShyTag(word) execute "tag " . a:word endfun -" 输入转换 -fun! ShyTrans(code) - return split(ShySend({"cmd": "trans", "arg": a:code, "pre": getline("."), "row": line("."), "col": col(".")}), "\n") -endfun - -fun! ShyInput() - call ShyLog("input", v:char, line("."), col(".")) -endfun - -" 输入补全 -fun! ShyComplete(firststart, base) - if a:firststart | let line = getline('.') | let start = col('.') - 1 - " 命令位置 - if match(trim(line), "ice ") == 0 | return match(line, "ice ") | endif - " 符号位置 - if line[start-1] !~ "\a" | return start - 1 | end - " 单词位置 - while start > 0 && line[start - 1] =~ '\a' | let start -= 1 | endwhile - return start +" 自动刷新 +let ShyComeList = {} +fun! ShyCome(buf, row, action, extra) + if a:action == "refresh" + " 清空历史 + if a:extra["count"] > 0 | call deletebufline(a:buf, a:row+1, a:row+a:extra["count"]) | endif + let a:extra["count"] = 0 endif - - " 符号转换 - if a:base == "," | return [",", ","] | end - if a:base == "." | return ["。", "."] | end - " 单词转换 - return ShyTrans(a:base) + " 刷新命令 + for line in reverse(split(ShySend({"cmd": "trans", "arg": getbufline(a:buf, a:row)[0]}), "\n")) + call appendbufline(a:buf, a:row, line) + let a:extra["count"] += 1 + endfor + " 插入表头 + call appendbufline(a:buf, a:row, strftime(" ~~ %Y-%m-%d %H:%M:%S")) + let a:extra["count"] += 1 endfun -set completefunc=ShyComplete - -" 帮助信息 -fun! ShyHelp() - echo ShySend({"cmd": "help"}) +fun! ShyUpdate(timer) + let what = g:ShyComeList[a:timer] + call ShyLog("timer", a:timer, what) + call ShyCome(what["buf"], what["row"], what["action"], what) +endfun +fun! ShyComes(action) + " 低配命令 + if !exists("appendbufline") + for line in reverse(split(ShySend({"cmd": "trans", "arg": getline(".")}), "\n")) + call append(".", line) + endfor + return + endif + if !exists("b:timer") | let b:timer = -1 | endif + " 清除定时 + if b:timer > 0 | call timer_stop(b:timer) | let b:timer = -2 | return | endif + " 添加定时 + let b:timer = timer_start(1000, funcref('ShyUpdate'), {"repeat": -1}) + let g:ShyComeList[b:timer] = {"buf": bufname("."), "row": line("."), "pre": getline("."), "action": a:action, "count": 0} + call ShyLog("new timer", b:timer) endfun " 事件回调 @@ -156,16 +191,15 @@ autocmd! BufReadPost * call ShySync("bufs") autocmd! BufReadPost * call ShySync("read") autocmd! BufWritePre * call ShySync("write") autocmd! CmdlineLeave * call ShySync("exec") -autocmd! QuickFixCmdPost * call ShyCheck("fixs") +" autocmd! QuickFixCmdPost * call ShyCheck("fixs") autocmd! InsertLeave * call ShySync("insert") -autocmd! InsertCharPre * call ShyInput() " 按键映射 -nnoremap :call ShyGrep(expand("")) -nnoremap :call ShyCheck("cache") nnoremap :call ShyFavor() nnoremap f :call ShyFavors() -nnoremap :call ShyTask() +" nnoremap :call ShyGrep(expand("")) +" nnoremap :call ShyCheck("cache") +" nnoremap :call ShyTask() +nnoremap :call ShyComes("refresh") inoremap -vnoremap :call ShyTrans() diff --git a/misc/vim/vim.go b/misc/vim/vim.go new file mode 100644 index 00000000..a9fa7e74 --- /dev/null +++ b/misc/vim/vim.go @@ -0,0 +1,107 @@ +package vim + +import ( + "github.com/shylinux/icebergs" + "github.com/shylinux/icebergs/base/web" + "github.com/shylinux/icebergs/core/code" + "github.com/shylinux/toolkits" + + "io/ioutil" + "strings" +) + +var Index = &ice.Context{Name: "vim", Help: "编辑器", + Caches: map[string]*ice.Cache{}, + Configs: map[string]*ice.Config{ + "vim": {Name: "vim", Help: "编辑器", Value: kit.Data(kit.MDB_SHORT, "name")}, + }, + Commands: map[string]*ice.Command{ + ice.WEB_LOGIN: {Name: "_login", Help: "_login", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if f, _, e := m.R.FormFile("sub"); e == nil { + defer f.Close() + if b, e := ioutil.ReadAll(f); e == nil { + // 加载参数 + m.Option("sub", string(b)) + } + } + + m.Option("you", "") + m.Richs("login", nil, m.Option("sid"), func(key string, value map[string]interface{}) { + // 查找空间 + m.Option("you", value["you"]) + }) + + m.Info("%s %s cmd: %v sub: %v", m.Option("you"), m.Option(ice.MSG_USERURL), m.Optionv("cmds"), m.Optionv("sub")) + m.Append("_output", "result") + }}, + "/help": {Name: "/help", Help: "帮助", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Cmdy("help") + }}, + "/login": {Name: "/login", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Cmdy("login", "init", c.Name) + }}, + "/logout": {Name: "/logout", Help: "登出", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Cmdy("login", "exit") + }}, + + "/sync": {Name: "/sync", Help: "同步", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + switch arg[0] { + case "read", "write", "exec", "insert": + m.Cmd(ice.WEB_FAVOR, "vim.history", "vimrc", arg[0], kit.Select(m.Option("arg"), m.Option("sub")), + "sid", m.Option("sid"), "pwd", m.Option("pwd"), "buf", m.Option("buf"), "row", m.Option("row"), "col", m.Option("col")) + + default: + m.Richs("login", nil, m.Option("sid"), func(key string, value map[string]interface{}) { + kit.Value(value, kit.Keys("sync", arg[0]), kit.Dict( + "time", m.Time(), "text", m.Option("sub"), + "pwd", m.Option("pwd"), "buf", m.Option("buf"), + )) + }) + } + }}, + "/input": {Name: "/input", Help: "补全", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if strings.HasPrefix(strings.TrimSpace(arg[0]), "ice ") { + list := kit.Split(strings.TrimSpace(arg[0]), "ice ") + switch list[1] { + case "add": + // 添加词汇 + m.Cmd("web.code.input.push", list[2:]) + arg[0] = list[4] + default: + // 执行命令 + m.Set("append") + if m.Cmdy(arg); m.Result() == "" { + m.Table() + } + return + } + } + + // 词汇列表 + m.Cmd("web.code.input.find", arg[0]).Table(func(index int, value map[string]string, head []string) { + m.Echo("%s\n", value["text"]) + }) + m.Info("input %v", m.Result()) + }}, + "/favor": {Name: "/favor", Help: "收藏", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if m.Options("arg") { + // 添加收藏 + m.Cmd(ice.WEB_FAVOR, m.Option("tab"), "vimrc", m.Option("note"), m.Option("arg"), + "pwd", m.Option("pwd"), "buf", m.Option("buf"), "row", m.Option("row"), "col", m.Option("col"), + ) + return + } + + // 查看收藏 + m.Cmd(ice.WEB_FAVOR, m.Option("tab"), "extra", "extra.pwd", "extra.buf", "extra.row", "extra.col").Table(func(index int, value map[string]string, head []string) { + switch value["type"] { + case ice.TYPE_VIMRC: + m.Echo("%v\n", m.Option("tab")).Echo("%v:%v:%v:(%v): %v\n", + value["extra.buf"], value["extra.row"], value["extra.col"], value["name"], value["text"]) + } + }) + }}, + }, +} + +func init() { code.Index.Register(Index, &web.Frame{}) } diff --git a/misc/vim/vim.js b/misc/vim/vim.js new file mode 100644 index 00000000..957bfb22 --- /dev/null +++ b/misc/vim/vim.js @@ -0,0 +1,9 @@ +Volcanos("onimport", {help: "导入数据", list: [], + "init": function(can, msg, cb, output, action, option) {}, +}) +Volcanos("onaction", {help: "控件菜单", list: []}) +Volcanos("onchoice", {help: "控件交互", list: ["刷新"] + "刷新": function(event, can, value, cmd, target) {}, +}) +Volcanos("ondetail", {help: "控件详情", list: []}) +Volcanos("onexport", {help: "导出数据", list: []}) diff --git a/misc/vim/vim.shy b/misc/vim/vim.shy new file mode 100644 index 00000000..789c8d33 --- /dev/null +++ b/misc/vim/vim.shy @@ -0,0 +1 @@ +title "vim" diff --git a/misc/zsh/auto.sh b/misc/zsh/auto.sh new file mode 100644 index 00000000..f07477f0 --- /dev/null +++ b/misc/zsh/auto.sh @@ -0,0 +1,179 @@ +#!/bin/sh + +# 连接配置 +if [ "${ctx_dev}" = "" ] || [ "${ctx_dev}" = "-" ]; then + ctx_dev="http://localhost:9020" +fi +ctx_sid=${ctx_sid:=""} +ctx_share=${ctx_share:=""} +ctx_sh=`ps|grep $$|grep -v grep` + +# 请求配置 +ctx_head=${ctx_head:="Content-Type: application/json"} +ctx_curl=${ctx_curl:="curl"} +ctx_url=$ctx_dev"/code/zsh/" +ctx_cmd=${ctx_cmd:=""} + +# 输出配置 +ctx_silent=${ctx_silent:=""} +ctx_err=${ctx_err:="/dev/null"} +ctx_welcome=${ctx_welcome:="^_^ \033[32mWelcome to Context world\033[0m ^_^"} +ctx_goodbye=${ctx_goodbye:="v_v \033[31mGoodbye to Context world\033[0m v_v"} + +# 输出信息 +ShyRight() { + [ "$1" = "" ] && return 1 + [ "$1" = "0" ] && return 1 + [ "$1" = "false" ] && return 1 + return 0 +} +ShyEcho() { + ShyRight "$ctx_silent" || echo "$@" +} +ShyLog() { + echo "$@" > $ctx_err +} + +# 发送数据 +ShyLine() { + echo "$*"|sed -e 's/\"/\\\"/g' -e 's/\n/\\n/g' +} +ShyJSON() { + [ $# -eq 1 ] && echo \"`ShyLine "$1"`\" && return + echo -n "{" + while [ $# -gt 1 ]; do + echo -n \"`ShyLine "$1"`\"\:\"`ShyLine "$2"`\" + shift 2 && [ $# -gt 1 ] && echo -n "," + done + echo -n "}" +} +ShyPost() { + ctx_cmd="$1" && shift + case $ctx_sh in + *zsh) + ShyJSON SHELL "${SHELL:=bash}" pwd "${PWD:=/root}" sid "${ctx_sid:=0}" cmds "$@"|read data + ;; + *) + local data=`ShyJSON SHELL "${SHELL:=bash}" pwd "${PWD:=/root}" sid "${ctx_sid:=0}" cmds "$@"` + ;; + esac + echo $data > $ctx_err + ${ctx_curl} -s "${ctx_url}${ctx_cmd}" -H "${ctx_head}" -d "${data}" +} + +# 终端登录 +ShyHelp() { + ShyPost help "$@" +} +ShyLogin() { + HOST=`hostname` ctx_sid=`ShyPost login "" share "${ctx_share}" pid "$$" pane "${TMUX_PANE}" hostname "${HOST}" username "${USER}"` + echo "${ctx_welcome}" + echo "${ctx_dev}" + echo "sid: ${ctx_sid}" +} +ShyLogout() { + echo ${ctx_goodbye} && [ "$ctx_sid" != "" ] && ShyPost logout +} + +# 发送文件 +ShyDownload() { + ${ctx_curl} -s "${ctx_url}download" -F "cmds=$1" \ + -F "SHELL=${SHELL}" -F "pwd=${PWD}" -F "sid=${ctx_sid}" +} +ShyUpload() { + ${ctx_curl} -s "${ctx_url}upload" -F "upload=@$1" \ + -F "SHELL=${SHELL}" -F "pwd=${PWD}" -F "sid=${ctx_sid}" +} +ShySend() { + local TEMP=`mktemp /tmp/tmp.XXXXXX` && "$@" > $TEMP + ShyRight "$ctx_silent" || cat $TEMP + ${ctx_curl} -s "${ctx_url}sync" -F "cmds=$1" -F "cmds=$*" -F "sub=@$TEMP" \ + -F "SHELL=${SHELL}" -F "pwd=${PWD}" -F "sid=${ctx_sid}" +} + +# 同步数据 +ShySync() { + case "$1" in + "history") + ctx_end=`history|tail -n1|awk '{print $1}'` + ctx_begin=${ctx_begin:=$ctx_end} + ctx_count=`expr $ctx_end - $ctx_begin` + ShyEcho "sync $ctx_begin-$ctx_end count $ctx_count to $ctx_dev" + history|tail -n $ctx_count |while read line; do + ShyPost history "$line" + done + ctx_begin=$ctx_end + ;; + ps) ShySend ps -ef ;; + *) ShySend "$@" + esac +} +ShySyncs() { + case "$1" in + "base") + ShySync df &>/dev/null + ShySync ps &>/dev/null + ShySync env &>/dev/null + ShySync free &>/dev/null + ShySync history + ;; + *) + esac +} +ShyInput() { + if [ "$1" = "line" ] ; then + READLINE_LINE=`ShyPost input "$1" line "$READLINE_LINE" point "$READLINE_POINT"` + else + COMPREPLY=(`ShyPost input "$COMP_WORDS" line "$COMP_LINE" index "$COMP_CWORD" break "$COMP_WORDBREAKS"`) + fi +} +ShyFavor() { + cmd=$1; [ "$READLINE_LINE" != "" ] && set $READLINE_LINE && READLINE_LINE="" + if [ "$cmd" = "sh" ] ; then + # 查看收藏 + ctx_word="sh" + shift && [ "$1" != "" ] && ctx_tab="$1" + shift && [ "$1" != "" ] && ctx_note="$1" + else + # 添加收藏 + [ "$1" != "" ] && ctx_word="$*" || ctx_word=`history|tail -n1|head -n1|sed -e 's/^[\ 0-9]*//g'` + fi + ShyPost favor "${ctx_word}" tab "${ctx_tab}" note "${ctx_note}" +} + +ShyUpgrade() { + file=auto.sh && [ "$1" != "" ] && file=$1 + ${ctx_curl} -s $ctx_dev/publish/$file > $file && source auto.sh +} +ShyInit() { + [ "$ctx_begin" = "" ] && ctx_begin=`history|tail -n1|awk '{print $1}'` + + case "${SHELL##*/}" in + "zsh") PROMPT='%![%*]%c$ ' ;; + *) PS1="\!-$$-\u@\h[\t]\W\$ " ;; + esac + + if bind &>/dev/null; then + # bash + # bind 'TAB:complete' + bind 'TAB:menu-complete' + complete -F ShyInput word + bind -x '"\C-K":ShyInput line' + bind -x '"\C-G\C-F":ShyFavor' + bind -x '"\C-GF":ShyFavor sh' + bind -x '"\C-Gf":ShyFavor sh' + bind -x '"\C-G\C-G":ShySync history' + + elif bindkey &>/dev/null; then + # zsh + bindkey -s '\C-G\C-R' 'ShySyncs base\n' + setopt nosharehistory + fi + + echo "url: ${ctx_url}" + echo "pid: $$" + echo "begin: ${ctx_begin}" + echo "share: ${ctx_share}" + echo "pane: $TMUX_PANE" +} +ShyInit && trap ShyLogout EXIT diff --git a/misc/zsh/ctx_err b/misc/zsh/ctx_err new file mode 100644 index 00000000..df550372 --- /dev/null +++ b/misc/zsh/ctx_err @@ -0,0 +1,34 @@ +TERM_PROGRAM=Apple_Terminal +TERM=screen +SHELL=/bin/zsh +TMPDIR=/var/folders/4s/qvyll7yd0096xwz685cyg3780000gn/T/ +GOBIN=/Users/shaoying/go/bin +Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.Zo9k6rnWr0/Render +TERM_PROGRAM_VERSION=404 +TERM_SESSION_ID=255A0489-6A45-4FE0-BA47-3C669134541D +ZSH=/Users/shaoying/.oh-my-zsh +ZSH_TMUX_TERM=screen +USER=shaoying +_ZSH_TMUX_FIXED_CONFIG=/Users/shaoying/.oh-my-zsh/plugins/tmux/tmux.extra.conf +SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.zmZQbFPABY/Listeners +PAGER=less +TMUX=/private/tmp/tmux-501/default,7032,0 +LSCOLORS=Gxfxcxdxbxegedabagacad +PATH=/Users/shaoying/go/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin:/Users/shaoying/go/bin:/Users/shaoying/.fzf/bin +GOPROXY=https://goproxy.cn +PWD=/Users/shaoying/miss/contexts/usr/icebergs/misc/zsh +EDITOR=vim +XPC_FLAGS=0x0 +TMUX_PANE=%64 +XPC_SERVICE_NAME=0 +SHLVL=3 +HOME=/Users/shaoying +GOROOT=/usr/local/go +ctx_dev=http://mac.local:9020 +ctx_self=http://:9020 +PROMPT=%![%*]%c$ +LOGNAME=shaoying +LESS=-R +LC_CTYPE=UTF-8 +GOPATH=/Users/shaoying/go:/Users/shaoying/context +_=/usr/bin/env diff --git a/misc/zsh/log b/misc/zsh/log new file mode 100644 index 00000000..df550372 --- /dev/null +++ b/misc/zsh/log @@ -0,0 +1,34 @@ +TERM_PROGRAM=Apple_Terminal +TERM=screen +SHELL=/bin/zsh +TMPDIR=/var/folders/4s/qvyll7yd0096xwz685cyg3780000gn/T/ +GOBIN=/Users/shaoying/go/bin +Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.Zo9k6rnWr0/Render +TERM_PROGRAM_VERSION=404 +TERM_SESSION_ID=255A0489-6A45-4FE0-BA47-3C669134541D +ZSH=/Users/shaoying/.oh-my-zsh +ZSH_TMUX_TERM=screen +USER=shaoying +_ZSH_TMUX_FIXED_CONFIG=/Users/shaoying/.oh-my-zsh/plugins/tmux/tmux.extra.conf +SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.zmZQbFPABY/Listeners +PAGER=less +TMUX=/private/tmp/tmux-501/default,7032,0 +LSCOLORS=Gxfxcxdxbxegedabagacad +PATH=/Users/shaoying/go/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin:/Users/shaoying/go/bin:/Users/shaoying/.fzf/bin +GOPROXY=https://goproxy.cn +PWD=/Users/shaoying/miss/contexts/usr/icebergs/misc/zsh +EDITOR=vim +XPC_FLAGS=0x0 +TMUX_PANE=%64 +XPC_SERVICE_NAME=0 +SHLVL=3 +HOME=/Users/shaoying +GOROOT=/usr/local/go +ctx_dev=http://mac.local:9020 +ctx_self=http://:9020 +PROMPT=%![%*]%c$ +LOGNAME=shaoying +LESS=-R +LC_CTYPE=UTF-8 +GOPATH=/Users/shaoying/go:/Users/shaoying/context +_=/usr/bin/env diff --git a/misc/zsh/zsh.go b/misc/zsh/zsh.go new file mode 100644 index 00000000..d6c6c8a8 --- /dev/null +++ b/misc/zsh/zsh.go @@ -0,0 +1,214 @@ +package zsh + +import ( + "github.com/shylinux/icebergs" + "github.com/shylinux/icebergs/base/web" + "github.com/shylinux/icebergs/core/code" + "github.com/shylinux/toolkits" + + "io/ioutil" + "strings" + "unicode" +) + +var Index = &ice.Context{Name: "zsh", Help: "命令行", + Caches: map[string]*ice.Cache{}, + Configs: map[string]*ice.Config{ + "zsh": {Name: "zsh", Help: "命令行", Value: kit.Data(kit.MDB_SHORT, "name")}, + }, + Commands: map[string]*ice.Command{ + ice.WEB_LOGIN: {Name: "_login", Help: "_login", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if f, _, e := m.R.FormFile("sub"); e == nil { + defer f.Close() + if b, e := ioutil.ReadAll(f); e == nil { + // 加载参数 + m.Option("sub", string(b)) + } + } + + m.Option("you", "") + m.Richs("login", nil, m.Option("sid"), func(key string, value map[string]interface{}) { + // 查找空间 + m.Option("you", value["you"]) + }) + + m.Info("%s %s cmd: %v sub: %v", m.Option("you"), m.Option(ice.MSG_USERURL), m.Optionv("cmds"), m.Optionv("sub")) + m.Append("_output", "result") + }}, + "/help": {Name: "/help", Help: "帮助", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Cmdy("help") + }}, + "/login": {Name: "/login", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Cmdy("login", "init", c.Name) + }}, + "/logout": {Name: "/logout", Help: "登出", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Cmdy("login", "exit") + }}, + + "/download": {Name: "/download", Help: "下载", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + you := m.Option("you") + m.Option("you", "") + + if len(arg) == 0 || arg[0] == "" { + // 文件列表 + m.Cmdy(ice.WEB_SPACE, you, ice.WEB_STORY) + m.Table() + return + } + + // 查找文件 + if m.Cmdy(ice.WEB_STORY, "index", arg[0]).Append("text") == "" && you != "" { + // 上发文件 + m.Cmdy(ice.WEB_SPACE, you, ice.WEB_STORY, "index", arg[0]) + } + + // 下载文件 + m.Append("_output", kit.Select("file", "result", m.Append("file") == "")) + }}, + "/upload": {Name: "/upload", Help: "上传", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + you := m.Option("you") + m.Option("you", "") + + // 缓存文件 + msg := m.Cmd(ice.WEB_STORY, "upload") + m.Echo("data: %s\n", msg.Append("data")) + m.Echo("time: %s\n", msg.Append("time")) + m.Echo("type: %s\n", msg.Append("type")) + m.Echo("name: %s\n", msg.Append("name")) + m.Echo("size: %s\n", msg.Append("size")) + + if you != "" { + // 下发文件 + m.Cmd(ice.WEB_SPACE, you, ice.WEB_STORY, ice.STORY_PULL, "dev", msg.Append("name")) + } + }}, + "/sync": {Name: "/sync", Help: "同步", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + switch arg[0] { + default: + m.Richs("login", nil, m.Option("sid"), func(key string, value map[string]interface{}) { + kit.Value(value, kit.Keys("sync", arg[0]), kit.Dict( + "time", m.Time(), "text", m.Option("sub"), + "pwd", m.Option("pwd"), "cmd", arg[1:], + )) + }) + } + }}, + "/input": {Name: "/input", Help: "补全", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + list := kit.Split(m.Option("line"), m.Option("break")) + word := list[kit.Int(m.Option("index"))] + switch arg[0] { + case "shy": + m.Cmd("web.code.input.find", word).Table(func(index int, value map[string]string, head []string) { + m.Echo(value["text"]).Echo(" ") + }) + + case "line": + if strings.HasPrefix(m.Option("line"), "ice ") { + list := kit.Split(m.Option("line")) + switch list[1] { + case "add": + m.Cmd("web.code.input.push", list[2:]) + m.Option("line", list[4]) + m.Option("point", 0) + default: + m.Cmdy(list[1:]) + break + } + } + + line := []rune(m.Option("line")) + if begin := kit.Int(m.Option("point")); begin < len(line) { + m.Richs("login", nil, m.Option("sid"), func(key string, value map[string]interface{}) { + m.Echo(string(line[:begin])) + for i := begin; i < len(line); i++ { + if i-begin < 3 && i < len(line)-1 { + continue + } + // 编码转换 + for j := 0; j < 4; j++ { + code := string(line[begin : i+1-j]) + list := append(m.Cmd("web.code.input.find", code).Appendv("text"), code) + if len(list) > 1 { + m.Echo(kit.Select(code, list[0])) + m.Info("input %s->%s", code, list[0]) + i = i - j + break + } + } + // 输出编码 + begin = i + 1 + } + }) + break + } + fallthrough + case "end": + m.Richs("login", nil, m.Option("sid"), func(key string, value map[string]interface{}) { + last_text := kit.Format(kit.Value(value, "last.text")) + last_list := kit.Simple(kit.Value(value, "last.list")) + last_index := kit.Int(kit.Value(value, "last.index")) + + if last_text != "" && strings.HasSuffix(m.Option("line"), last_text) { + // 补全记录 + index := last_index + 1 + text := last_list[index%len(last_list)] + kit.Value(value, "last.index", index) + kit.Value(value, "last.text", text) + m.Echo(strings.TrimSuffix(m.Option("line"), last_text) + text) + m.Info("%d %v", index, last_list) + return + } + + line := []rune(m.Option("line")) + for i := len(line); i >= 0; i-- { + if i > 0 && len(line)-i < 4 && unicode.IsLower(line[i-1]) { + continue + } + + // 编码转换 + code := string(line[i:]) + list := append(m.Cmd("web.code.input.find", code).Appendv("text"), code) + value["last"] = kit.Dict("code", code, "text", list[0], "list", list, "index", 0) + + // 输出编码 + m.Echo(string(line[:i])) + m.Echo(kit.Select(code, list[0])) + m.Info("input %s->%s", code, list[0]) + break + } + }) + } + m.Info("trans: %v", m.Result()) + }}, + "/favor": {Name: "/favor", Help: "收藏", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + you := m.Option("you") + m.Option("you", "") + + if len(arg) > 0 && arg[0] != "sh" { + // 添加收藏 + if m.Cmdy(ice.WEB_FAVOR, m.Option("tab"), ice.TYPE_SHELL, m.Option("note"), arg[0]); you != "" { + m.Cmdy(ice.WEB_SPACE, you, ice.WEB_FAVOR, m.Option("tab"), ice.TYPE_SHELL, m.Option("note"), arg[0]) + } + return + } + + m.Echo("#/bin/sh\n\n") + m.Cmd(ice.WEB_SPACE, you, ice.WEB_FAVOR, m.Option("tab")).Table(func(index int, value map[string]string, head []string) { + switch value["type"] { + case ice.TYPE_SHELL: + // 查看收藏 + if m.Option("note") == "" || m.Option("note") == value["name"] { + m.Echo("# %v\n%v\n\n", value["name"], value["text"]) + } + } + }) + }}, + "/history": {Name: "/history", Help: "历史", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + vs := strings.SplitN(strings.TrimSpace(arg[0]), " ", 2) + m.Cmd(ice.WEB_SPACE, m.Option("you"), ice.WEB_FAVOR, "zsh.history", ice.TYPE_SHELL, vs[0], kit.Select("", vs, 1), + "sid", m.Option("sid"), "pwd", m.Option("pwd")) + }}, + }, +} + +func init() { code.Index.Register(Index, &web.Frame{}) } diff --git a/misc/zsh/zsh.js b/misc/zsh/zsh.js new file mode 100644 index 00000000..957bfb22 --- /dev/null +++ b/misc/zsh/zsh.js @@ -0,0 +1,9 @@ +Volcanos("onimport", {help: "导入数据", list: [], + "init": function(can, msg, cb, output, action, option) {}, +}) +Volcanos("onaction", {help: "控件菜单", list: []}) +Volcanos("onchoice", {help: "控件交互", list: ["刷新"] + "刷新": function(event, can, value, cmd, target) {}, +}) +Volcanos("ondetail", {help: "控件详情", list: []}) +Volcanos("onexport", {help: "导出数据", list: []}) diff --git a/misc/zsh/zsh.shy b/misc/zsh/zsh.shy new file mode 100644 index 00000000..f048dc4d --- /dev/null +++ b/misc/zsh/zsh.shy @@ -0,0 +1 @@ +title "zsh" diff --git a/type.go b/type.go index 946adf59..079b8e3c 100644 --- a/type.go +++ b/type.go @@ -647,8 +647,8 @@ func (m *Message) Parse(meta string, key string, arg ...string) *Message { } func (m *Message) Split(str string, field string, space string, enter string) *Message { indexs := []int{} - fields := kit.Split(field, space) - for i, l := range kit.Split(str, enter) { + fields := kit.Split(field, space, "{}") + for i, l := range kit.Split(str, enter, "{}") { if i == 0 && (field == "" || field == "index") { // 表头行 fields = kit.Split(l, space)