1
0
forked from x/icebergs
This commit is contained in:
shaoying 2020-03-09 02:00:57 +08:00
parent 6277c5536d
commit a41cfb5a49
21 changed files with 1022 additions and 957 deletions

View File

@ -155,3 +155,10 @@ func Run(arg ...string) string {
os.Exit(frame.code) os.Exit(frame.code)
return "" 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",
)
}

View File

@ -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 { if _, e := os.Stat(m.Conf(ice.WEB_SERVE, "meta.volcanos.path")); e == nil {
// 初始化成功 // 初始化成功
m.Conf(ice.WEB_SERVE, "meta.init", "true") 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 { } else {
web.ServeMux.ServeHTTP(w, r) web.ServeMux.ServeHTTP(w, r)
} }
@ -745,6 +743,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
default: default:
// 启动服务 // 启动服务
m.Target().Start(m, "self") 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( 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( ), List: kit.List(
kit.MDB_INPUT, "text", "value", "", "name", "name", kit.MDB_INPUT, "text", "value", "", "name", "name",
kit.MDB_INPUT, "button", "value", "创建", "action", "auto", 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) { ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) > 1 { if len(arg) > 1 {
switch arg[1] { switch arg[1] {
@ -913,12 +913,17 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
// 启动任务 // 启动任务
m.Option("cmd_dir", p) m.Option("cmd_dir", p)
m.Option("cmd_type", "daemon") m.Option("cmd_type", "daemon")
m.Option("cmd_env", "ctx_log", "boot.log") m.Optionv("cmd_env",
m.Option("cmd_env", "PATH", kit.Path(path.Join(p, "bin"))+":"+os.Getenv("PATH")) "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]) 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.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]) 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 { if len(arg) == 1 {
m.Option("cache.limit", 30) m.Option("cache.limit", 30)
// 收藏列表 // 收藏列表
m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, favor), "", "", func(index int, value map[string]interface{}) { 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 return
} }

View File

@ -82,6 +82,7 @@ const ( // WEB
WEB_WORKER = "worker" WEB_WORKER = "worker"
) )
const ( // LOG const ( // LOG
// 数据
LOG_ENABLE = "enable" LOG_ENABLE = "enable"
LOG_IMPORT = "import" LOG_IMPORT = "import"
LOG_CREATE = "create" LOG_CREATE = "create"
@ -92,16 +93,23 @@ const ( // LOG
LOG_REMOVE = "remove" LOG_REMOVE = "remove"
LOG_EXPORT = "export" LOG_EXPORT = "export"
// 事件
LOG_LISTEN = "listen" LOG_LISTEN = "listen"
LOG_SIGNAL = "signal" LOG_SIGNAL = "signal"
LOG_TIMERS = "timers" LOG_TIMERS = "timers"
LOG_EVENTS = "events" LOG_EVENTS = "events"
// 状态
LOG_BEGIN = "begin" LOG_BEGIN = "begin"
LOG_START = "start" LOG_START = "start"
LOG_SERVE = "serve" LOG_SERVE = "serve"
LOG_CLOSE = "close" LOG_CLOSE = "close"
// 权限
LOG_LOGIN = "login"
LOG_LOGOUT = "logout"
// 分类
LOG_CMDS = "cmds" LOG_CMDS = "cmds"
LOG_COST = "cost" LOG_COST = "cost"
LOG_INFO = "info" LOG_INFO = "info"

View File

@ -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

View File

@ -2,11 +2,9 @@ package code
import ( import (
"github.com/shylinux/icebergs" "github.com/shylinux/icebergs"
_ "github.com/shylinux/icebergs/base"
"github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/base/web"
"github.com/shylinux/toolkits" "github.com/shylinux/toolkits"
"io/ioutil"
"os" "os"
"path" "path"
"strings" "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) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save("login") 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) { "compile": {Name: "compile [os [arch]]", Help: "编译", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { 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])) target := path.Join(m.Conf("publish", "meta.path"), path.Base(arg[0]))
os.Remove(target) os.Remove(target)
os.MkdirAll(path.Dir(target), 0777)
os.Link(arg[0], target) os.Link(arg[0], target)
// 发布记录 // 发布记录
@ -114,188 +182,6 @@ var Index = &ice.Context{Name: "code", Help: "编程中心",
m.Cmd("exit") 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"])
}
})
}
}},
}, },
} }

View File

@ -4,43 +4,43 @@ import (
"github.com/shylinux/icebergs" "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/core/code" "github.com/shylinux/icebergs/core/code"
"github.com/shylinux/toolkits" "github.com/shylinux/toolkits"
"os"
"os/exec"
"path"
"strings" "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: "虚拟机", var Index = &ice.Context{Name: "docker", Help: "虚拟机",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
"docker": {Name: "docker", Help: "虚拟机", Value: kit.Data(kit.MDB_SHORT, "name")}, "docker": {Name: "docker", Help: "虚拟机", Value: kit.Data(kit.MDB_SHORT, "name")},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {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) {
// if m.Richs(ice.WEB_FAVOR, nil, "alpine.init", nil) == nil { m.Watch(ice.DREAM_START, m.Prefix("auto"))
// 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) {}},
"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"} prefix := []string{ice.CLI_SYSTEM, "docker", "image"}
if len(arg) > 2 { if len(arg) > 1 && arg[0] == "action" {
switch arg[1] { switch arg[1] {
case "运行": case "运行":
m.Cmdy(prefix[:2], "run", "-dt", m.Option("REPOSITORY")+":"+m.Option("TAG")).Set("append") 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 { if len(arg) > 0 {
// 下载镜像 // 下载镜像
m.Cmdy(prefix, "pull", arg[0]+":"+kit.Select("latest", arg, 1)).Set("append") m.Cmdy(prefix, "pull", arg[0]+":"+kit.Select("latest", arg, 1)).Set("append")
return return
} }
// 镜像列表 // 镜像列表
m.Split(strings.Replace(m.Cmdx(prefix, "ls"), "IMAGE ID", "IMAGE_ID", 1), "index", " ", "\n") m.Split(strings.Replace(m.Cmdx(prefix, "ls"), "IMAGE ID", "IMAGE_ID", 1), "index", " ", "\n")
m.Sort("REPOSITORY") m.Sort("REPOSITORY")
}}, }},
"container": {Name: "container", Help: "容器管理", Meta: kit.Dict( "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) {
"exports", []string{"CONTAINER_ID", "CONTAINER_ID"},
"detail", []string{"进入", "启动", "停止", "重启", "清理", "编辑", "删除"}), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
prefix := []string{ice.CLI_SYSTEM, "docker", "container"} prefix := []string{ice.CLI_SYSTEM, "docker", "container"}
if len(arg) > 2 { if len(arg) > 1 && arg[0] == "action" {
switch arg[1] { switch arg[1] {
case "进入": case "进入":
m.Cmd("cli.tmux.session").Table(func(index int, value map[string]string, head []string) { m.Cmdy(ice.CLI_SYSTEM, "tmux", "new-window", "-t", m.Option("NAMES"), "-n", m.Option("NAMES"),
if value["tag"] == "1" { "-PF", "#{session_name}:#{window_name}.1", "docker exec -it "+m.Option("NAMES")+" bash").Set("append")
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")
}
})
return return
case "停止": case "停止":
m.Cmd(prefix, "stop", m.Option("CONTAINER_ID")) m.Cmdy(prefix, "stop", m.Option("CONTAINER_ID"))
case "启动": case "启动":
m.Cmd(prefix, "start", m.Option("CONTAINER_ID")) m.Cmdy(prefix, "start", m.Option("CONTAINER_ID"))
case "重启": case "重启":
m.Cmd(prefix, "restart", m.Option("CONTAINER_ID")) m.Cmdy(prefix, "restart", m.Option("CONTAINER_ID"))
case "清理": case "清理":
m.Cmd(prefix, "prune", "-f") m.Cmdy(prefix, "prune", "-f")
case "modify": case "modify":
switch arg[2] { switch arg[2] {
case "NAMES": case "NAMES":
m.Cmd(prefix, "rename", arg[4], arg[3]) m.Cmdy(prefix, "rename", arg[4], arg[3])
} }
case "delete": case "delete":
m.Cmdy(prefix, "rm", m.Option("CONTAINER_ID")).Set("append") 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") m.Sort("NAMES")
}}, }},
"command": {Name: "command", Help: "命令", List: kit.List( "command": {Name: "command", Help: "命令", List: kit.List(
kit.MDB_INPUT, "text", "name", "CONTAINER_ID", "imports", "CONTAINER_ID", kit.MDB_INPUT, "text", "name", "CONTAINER_ID",
kit.MDB_INPUT, "text", "name", "command", kit.MDB_INPUT, "text", "name", "cmd", "className", "args cmd",
kit.MDB_INPUT, "button", "name", "执行", kit.MDB_INPUT, "button", "value", "执行",
), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ), 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"} prefix := []string{ice.CLI_SYSTEM, "docker", "container"}
m.Cmdy(prefix, "exec", arg[0], arg[1:]).Set("append") 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
}},
}, },
} }

View File

@ -74,6 +74,45 @@ var Index = &ice.Context{Name: "git", Help: "代码库",
}) })
m.Sort("name") 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( "status": {Name: "status repos", Help: "状态", Meta: kit.Dict(
"detail", []interface{}{"add", "reset", "remove", kit.Dict("name", "commit", "args", kit.List( "detail", []interface{}{"add", "reset", "remove", kit.Dict("name", "commit", "args", kit.List(
kit.MDB_INPUT, "select", "name", "type", "values", []string{"add", "opt"}, 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) { ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
prefix := []string{ice.CLI_SYSTEM, "git"} 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.Richs("repos", nil, m.Option("name"), func(key string, value map[string]interface{}) {
m.Option("cmd_dir", kit.Value(value, "meta.path")) m.Option("cmd_dir", kit.Value(value, "meta.path"))
switch arg[1] { 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
}
// 提交统计 "_sum": {Name: "_sum [path] [total] [count|date] args...", Help: "统计", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
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) {
if len(arg) > 0 { if len(arg) > 0 {
if s, e := os.Stat(arg[0] + "/.git"); e == nil && s.IsDir() { if s, e := os.Stat(arg[0] + "/.git"); e == nil && s.IsDir() {
m.Option("cmd_dir", arg[0]) 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( "trend": {Name: "check name [path [repos]]", Help: "检查", Meta: kit.Dict("display", "/plugin/story/trend"), List: kit.List(
"display", "/plugin/story/trend",
), List: kit.List(
kit.MDB_INPUT, "text", "name", "repos", "action", "auto", kit.MDB_INPUT, "text", "name", "repos", "action", "auto",
kit.MDB_INPUT, "text", "name", "begin_time", "figure", "date", kit.MDB_INPUT, "text", "name", "begin_time", "figure", "date",
kit.MDB_INPUT, "button", "name", "执行", "action", "auto", kit.MDB_INPUT, "button", "name", "执行", "action", "auto",
@ -247,32 +246,6 @@ var Index = &ice.Context{Name: "git", Help: "代码库",
} }
m.Cmdy("total", arg) 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")
}},
}, },
} }

View File

@ -18,7 +18,7 @@ var Index = &ice.Context{Name: "input", Help: "输入法",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
"input": {Name: "input", Help: "输入法", Value: kit.Data( "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", "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) { "load": {Name: "load file [name]", Help: "加载词库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { 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")) m.Echo("wubi86: %v", m.Conf("input", "wubi86.meta.count"))
return return
} }
arg = append(arg, path.Join("usr", m.Conf("input", "meta.repos"), "wubi86")) 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) { if f, e := os.Open(arg[0]); m.Assert(e) {
bio := bufio.NewScanner(f) 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() { for bio.Scan() {
if strings.HasPrefix(bio.Text(), "#") { if strings.HasPrefix(bio.Text(), "#") {
continue continue
} }
line := kit.Split(bio.Text(), " \t") line := kit.Split(bio.Text())
if line[2] == "0" { if line[2] == "0" {
continue 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"))) 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) { "push": {Name: "push lib text code [weight]", Help: "添加词汇", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
lib := kit.Select("person", arg, 2)
m.Option("cache.least", 0) m.Option("cache.least", 0)
m.Option("cache.limit", 0) m.Option("cache.limit", 0)
m.Option("cache.store", path.Join(m.Conf("input", "meta.store"), lib)) m.Option("cache.store", path.Join(m.Conf("input", "meta.store"), arg[0]))
m.Echo("%s: %d", lib, m.Grow("input", lib, kit.Dict("text", arg[0], "code", arg[1], "weight", kit.Select("99990000", arg, 3)))) 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) { "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) lib := kit.Select("person", arg, 0)
m.Option("cache.offend", kit.Select("0", arg, 1)) m.Option("cache.offend", kit.Select("0", arg, 1))
m.Option("cache.limit", kit.Select("10", arg, 2)) 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) { "save": {Name: "save lib [filename]", Help: "导出词库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
lib := kit.Select("person", arg, 0) lib := kit.Select("person", arg, 0)
m.Option("cache.limit", 1000000) if f, p, e := kit.Create(kit.Select(path.Join("usr", m.Conf("input", "meta.repos"), lib), arg, 1)); m.Assert(e) {
m.Option("cache.offend", 0)
if f, p, e := kit.Create(path.Join("usr", m.Conf("input", "meta.repos"), lib)); m.Assert(e) {
defer f.Close() defer f.Close()
n := 0 n := 0
m.Option("cache.offend", 0)
m.Option("cache.limit", -2)
m.Grows("input", lib, "", "", func(index int, value map[string]interface{}) { m.Grows("input", lib, "", "", func(index int, value map[string]interface{}) {
n++ if value["code"] != "z" {
fmt.Fprintf(f, "%s %s %s\n", value["text"], value["code"], value["weight"]) n++
fmt.Fprintf(f, "%s %s %s\n", value["text"], value["code"], value["weight"])
}
}) })
m.Log(ice.LOG_EXPORT, "%s: %d", p, n) m.Log(ice.LOG_EXPORT, "%s: %d", p, n)
m.Echo("%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 { if line, e := bio.Read(); e != nil {
break break
} else if len(line) < 3 { } else if len(line) < 3 {
} else { } else {
if method == "word" && i == 0 { 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) } func init() { code.Index.Register(Index, nil) }

View File

@ -1,9 +1,10 @@
package misc package misc
import ( import (
_ "github.com/shylinux/icebergs/misc/chrome"
_ "github.com/shylinux/icebergs/misc/docker" _ "github.com/shylinux/icebergs/misc/docker"
_ "github.com/shylinux/icebergs/misc/git" _ "github.com/shylinux/icebergs/misc/git"
_ "github.com/shylinux/icebergs/misc/input" _ "github.com/shylinux/icebergs/misc/input"
_ "github.com/shylinux/icebergs/misc/tmux" _ "github.com/shylinux/icebergs/misc/tmux"
_ "github.com/shylinux/icebergs/misc/vim"
_ "github.com/shylinux/icebergs/misc/zsh"
) )

View File

@ -4,29 +4,14 @@ import (
"github.com/shylinux/icebergs" "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/core/code" "github.com/shylinux/icebergs/core/code"
"github.com/shylinux/toolkits" "github.com/shylinux/toolkits"
"os" "os"
"path" "path"
"strings" "strings"
"time" "time"
) )
type Frame struct { var Index = &ice.Context{Name: "tmux", Help: "工作台",
}
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: "命令行",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
"buffer": {Name: "buffer", Help: "缓存", Value: kit.Data()}, "buffer": {Name: "buffer", Help: "缓存", Value: kit.Data()},
@ -53,63 +38,95 @@ var Index = &ice.Context{Name: "tmux", Help: "命令行",
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
"init": {Name: "init", Help: "初始化", 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, "web.code.tmux.auto") m.Watch(ice.DREAM_START, m.Prefix("auto"))
m.Watch(ice.FAVOR_START, "web.code.tmux.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"} { for _, v := range []string{"auto.sh", "auto.vim"} {
p := path.Join(m.Conf("web.code.publish", "meta.path"), v) p := path.Join(m.Conf("web.code.publish", "meta.path"), v)
if _, e := os.Stat(p); e != nil && os.IsNotExist(e) { if _, e := os.Stat(p); e != nil && os.IsNotExist(e) {
// 下载脚本
if h := m.Cmdx(ice.WEB_SPIDE, "shy", "cache", "GET", "/publish/"+v); h != "" { 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.Cmd(ice.WEB_STORY, ice.STORY_WATCH, h, p)
m.Log(ice.LOG_EXPORT, "%s: %s", 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( share, dev := "", kit.Select(m.Conf(ice.CLI_RUNTIME, "conf.ctx_dev"), m.Conf(ice.CLI_RUNTIME, "host.ctx_self"))
kit.MDB_INPUT, "text", "name", "name", m.Richs(ice.WEB_SPACE, nil, arg[0], func(key string, value map[string]interface{}) {
kit.MDB_INPUT, "button", "value", "保存", share = kit.Format(value["share"])
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
}
if len(arg) > 1 { // 环境变量
// 设置缓存 m.Option("cmd_env", "TMUX", "", "ctx_dev", dev, "ctx_share", share)
m.Cmd("cli.system", "tmux", "set-buffer", "-b", arg[0], arg[1]) 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( "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", "session", "action", "auto",
kit.MDB_INPUT, "text", "name", "window", "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", kit.MDB_INPUT, "button", "value", "返回", "cb", "Last",
), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
prefix := []string{"cli.system", "tmux"} prefix := []string{"cli.system", "tmux"}
if len(arg) > 3 { if len(arg) > 1 && arg[0] == "action" {
switch arg[1] { switch arg[1] {
case "运行": case "运行":
target := "" 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) { "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), 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) { "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") 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) }

View File

@ -1,63 +1,105 @@
" 变量定义 " 变量定义
func! ShyDefine(name, value) 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 endfunc
" 输出日志 " 输出日志
" call ShyDefine("g:ShyLog", "/dev/null") call ShyDefine("g:ShyLog", "/dev/null")
call ShyDefine("g:ShyLog", "shy.log")
fun! ShyLog(...) fun! ShyLog(...)
call writefile([strftime("%Y-%m-%d %H:%M:%S ") . join(a:000, " ")], g:ShyLog, "a") call writefile([strftime("%Y-%m-%d %H:%M:%S ") . join(a:000, " ")], g:ShyLog, "a")
endfun endfun
command -nargs=+ ShyLog call writefile([strftime("%Y-%m-%d %H:%M:%S ") . join([<f-args>], " ")], g:ShyLog, "a")
" 后端通信 " 后端通信
call ShyDefine("g:ctx_sid", "") call ShyDefine("g:ctx_sid", "")
call ShyDefine("g:ctx_url", (len($ctx_dev) > 1? $ctx_dev: "http://127.0.0.1:9020") . "/code/vim") call ShyDefine("g:ctx_url", (len($ctx_dev) > 1? $ctx_dev: "http://127.0.0.1:9020") . "/code/vim/")
fun! ShySend(arg) fun! ShySend(cmd, arg)
if has_key(a:arg, "sub") && a:arg["sub"] != "" if has_key(a:arg, "sub") && a:arg["sub"] != ""
let temp = tempname() let temp = tempname()
call writefile(split(a:arg["sub"], "\n"), temp, "b") call writefile(split(a:arg["sub"], "\n"), temp, "b")
let a:arg["sub"] = "@" . temp let a:arg["sub"] = "@" . temp
endif endif
let a:arg["buf"] = bufname("%")
let a:arg["sid"] = g:ctx_sid let a:arg["sid"] = g:ctx_sid
let a:arg["pwd"] = getcwd() let a:arg["pwd"] = getcwd()
let a:arg["buf"] = bufname("%")
let a:arg["row"] = line(".")
let a:arg["col"] = col(".")
let args = "" let args = ""
for k in sort(keys(a:arg)) for k in sort(keys(a:arg))
let args = args . " -F '" . k . "=" . a:arg[k] . "' " let args = args . " -F '" . k . "=" . a:arg[k] . "' "
endfor endfor
return system("curl -s " . g:ctx_url . args . " 2>/dev/null") return system("curl -s " . g:ctx_url . a:cmd . 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)
endfun endfun
" 用户登录 " 用户登录
fun! ShyLogout() fun! ShyLogout()
if g:ctx_sid == "" | return | endif if g:ctx_sid != "" | call ShySend("logout", {}) | endif
call ShySends("logout")
endfun endfun
fun! ShyLogin() 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 endfun
call ShyLogin() 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("<afile>")})
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() 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_tab = input("tab: ", g:favor_tab)
let g:favor_note = input("note: ", g:favor_note) 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 endfun
fun! ShyFavors() 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 = "" let page = "" | let note = ""
for i in range(0, len(res)-1, 2) for i in range(0, len(res)-1, 2)
if res[i] != page if res[i] != page
@ -68,22 +110,6 @@ fun! ShyFavors()
endfor endfor
if note != "" | lexpr note | lopen | let note = "" | endif if note != "" | lexpr note | lopen | let note = "" | endif
endfun endfun
" 数据同步
fun! ShySync(target)
if bufname("%") == "ControlP" | return | end
if a:target == "read" || a:target == "write"
call ShySend({"cmd": a:target, "arg": expand("<afile>")})
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) fun! ShyCheck(target)
if a:target == "cache" if a:target == "cache"
call ShySync("bufs") call ShySync("bufs")
@ -101,6 +127,10 @@ fun! ShyCheck(target)
end end
endfun endfun
" 任务列表 " 任务列表
fun! ShyTask() fun! ShyTask()
call ShySend({"cmd": "tasklet", "arg": input("target: "), "sub": input("detail: ")}) call ShySend({"cmd": "tasklet", "arg": input("target: "), "sub": input("detail: ")})
@ -116,38 +146,43 @@ fun! ShyTag(word)
execute "tag " . a:word execute "tag " . a:word
endfun endfun
" 输入转换 " 自动刷新
fun! ShyTrans(code) let ShyComeList = {}
return split(ShySend({"cmd": "trans", "arg": a:code, "pre": getline("."), "row": line("."), "col": col(".")}), "\n") fun! ShyCome(buf, row, action, extra)
endfun if a:action == "refresh"
" 清空历史
fun! ShyInput() if a:extra["count"] > 0 | call deletebufline(a:buf, a:row+1, a:row+a:extra["count"]) | endif
call ShyLog("input", v:char, line("."), col(".")) let a:extra["count"] = 0
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
endif endif
" 刷新命令
" 符号转换 for line in reverse(split(ShySend({"cmd": "trans", "arg": getbufline(a:buf, a:row)[0]}), "\n"))
if a:base == "," | return ["", ","] | end call appendbufline(a:buf, a:row, line)
if a:base == "." | return ["。", "."] | end let a:extra["count"] += 1
" 单词转换 endfor
return ShyTrans(a:base) " 插入表头
call appendbufline(a:buf, a:row, strftime(" ~~ %Y-%m-%d %H:%M:%S"))
let a:extra["count"] += 1
endfun endfun
set completefunc=ShyComplete fun! ShyUpdate(timer)
let what = g:ShyComeList[a:timer]
" 帮助信息 call ShyLog("timer", a:timer, what)
fun! ShyHelp() call ShyCome(what["buf"], what["row"], what["action"], what)
echo ShySend({"cmd": "help"}) 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 endfun
" 事件回调 " 事件回调
@ -156,16 +191,15 @@ autocmd! BufReadPost * call ShySync("bufs")
autocmd! BufReadPost * call ShySync("read") autocmd! BufReadPost * call ShySync("read")
autocmd! BufWritePre * call ShySync("write") autocmd! BufWritePre * call ShySync("write")
autocmd! CmdlineLeave * call ShySync("exec") autocmd! CmdlineLeave * call ShySync("exec")
autocmd! QuickFixCmdPost * call ShyCheck("fixs") " autocmd! QuickFixCmdPost * call ShyCheck("fixs")
autocmd! InsertLeave * call ShySync("insert") autocmd! InsertLeave * call ShySync("insert")
autocmd! InsertCharPre * call ShyInput()
" 按键映射 " 按键映射
nnoremap <C-G><C-G> :call ShyGrep(expand("<cword>"))<CR>
nnoremap <C-G><C-R> :call ShyCheck("cache")<CR>
nnoremap <C-G><C-F> :call ShyFavor()<CR> nnoremap <C-G><C-F> :call ShyFavor()<CR>
nnoremap <C-G>f :call ShyFavors()<CR> nnoremap <C-G>f :call ShyFavors()<CR>
nnoremap <C-G><C-T> :call ShyTask()<CR> " nnoremap <C-G><C-G> :call ShyGrep(expand("<cword>"))<CR>
" nnoremap <C-G><C-R> :call ShyCheck("cache")<CR>
" nnoremap <C-G><C-T> :call ShyTask()<CR>
nnoremap <C-G><C-K> :call ShyComes("refresh")<CR>
inoremap <C-K> <C-X><C-U> inoremap <C-K> <C-X><C-U>
vnoremap <C-K> :call ShyTrans()

107
misc/vim/vim.go Normal file
View File

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

9
misc/vim/vim.js Normal file
View File

@ -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: []})

1
misc/vim/vim.shy Normal file
View File

@ -0,0 +1 @@
title "vim"

179
misc/zsh/auto.sh Normal file
View File

@ -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

34
misc/zsh/ctx_err Normal file
View File

@ -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

34
misc/zsh/log Normal file
View File

@ -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

214
misc/zsh/zsh.go Normal file
View File

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

9
misc/zsh/zsh.js Normal file
View File

@ -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: []})

1
misc/zsh/zsh.shy Normal file
View File

@ -0,0 +1 @@
title "zsh"

View File

@ -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 { func (m *Message) Split(str string, field string, space string, enter string) *Message {
indexs := []int{} indexs := []int{}
fields := kit.Split(field, space) fields := kit.Split(field, space, "{}")
for i, l := range kit.Split(str, enter) { for i, l := range kit.Split(str, enter, "{}") {
if i == 0 && (field == "" || field == "index") { if i == 0 && (field == "" || field == "index") {
// 表头行 // 表头行
fields = kit.Split(l, space) fields = kit.Split(l, space)