From 624c0f3c90a3bc2a13f8005049b26fdfff0e8fc1 Mon Sep 17 00:00:00 2001 From: shaoying Date: Tue, 10 Sep 2019 16:45:21 +0800 Subject: [PATCH] add plugin tmux --- bin/boot.sh | 2 +- src/contexts/cli/cli.go | 16 +-- src/contexts/cli/version.go | 2 +- src/contexts/ctx/misc.go | 2 + src/contexts/log/log.go | 4 +- src/contexts/nfs/nfs.go | 93 ++++++++------- src/contexts/web/web.go | 2 - src/examples/code/code.go | 177 ---------------------------- src/plugin/context/index.shy | 1 + src/plugin/tmux/index.go | 220 +++++++++++++++++++++++++++++++++++ src/plugin/tmux/index.js | 4 + src/plugin/tmux/index.shy | 38 ++++++ src/plugin/tmux/local.shy | 1 + src/toolkit/misc.go | 6 +- usr/librarys/example.css | 6 + usr/librarys/example.js | 13 ++- usr/librarys/toolkit.js | 8 ++ 17 files changed, 356 insertions(+), 239 deletions(-) create mode 100644 src/plugin/tmux/index.go create mode 100644 src/plugin/tmux/index.js create mode 100644 src/plugin/tmux/index.shy create mode 100644 src/plugin/tmux/local.shy diff --git a/bin/boot.sh b/bin/boot.sh index ae8237b8..c4e03a45 100755 --- a/bin/boot.sh +++ b/bin/boot.sh @@ -6,7 +6,7 @@ ctx_log=${ctx_log:="var/log"} ctx_app=${ctx_app:="bench"} -ctx_bin=${ctx_app} && [ -f bin/${ctx_app} ] && ctx_bin=$(pwd)/bin/${ctx_app} +ctx_bin=${ctx_bin:=`which ${ctx_app}`} && [ -f bin/${ctx_app} ] && ctx_bin=$(pwd)/bin/${ctx_app} # ctx_cas= # ctx_ups= # ctx_box= diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index 5bf6d620..bf713887 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -246,7 +246,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", "cmd_env": 2, "cmd_log": 1, "cmd_temp": -1, - "cmd_parse": 2, + "cmd_parse": 3, "cmd_error": 0, "cmd_select": -1, "app_log": 1, @@ -427,8 +427,9 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", case "cut": bio := bufio.NewScanner(out) bio.Scan() - for heads := kit.Split(bio.Text(), kit.Int(kit.Select("-1", m.Optionv("cmd_parse"), 1))); bio.Scan(); { - for i, v := range kit.Split(bio.Text(), len(heads)) { + c := byte(kit.Select(" ", m.Optionv("cmd_parse"), 2)[0]) + for heads := kit.Split(bio.Text(), c, kit.Int(kit.Select("-1", m.Optionv("cmd_parse"), 1))); bio.Scan(); { + for i, v := range kit.Split(bio.Text(), c, len(heads)) { m.Add("append", heads[i], v) } } @@ -869,7 +870,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", env := []string{ "cmd_env", "GOOS", goos, "cmd_env", "GOARCH", arch, "cmd_env", "GOTMPDIR", tmp, "cmd_env", "GOCACHE", tmp, - "cmd_env", "GOPATH", m.Conf("runtime", "boot.ctx_home")+":"+os.Getenv("GOPATH"), + "cmd_env", "GOPATH", m.Conf("runtime", "boot.ctx_home")+string(os.PathListSeparator)+os.Getenv("GOPATH"), "cmd_env", "PATH", os.Getenv("PATH"), } @@ -907,7 +908,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", for _, v := range arg[1:] { m.Cmd("nfs.copy", path.Join(q, v), path.Join(p, v)) } - m.Cmdy("nfs.dir", q, "time", "size", "hashs", "path") + m.Cmdy("nfs.dir", q, "time", "size", "hashs", "path", "dir_sort", "path", "str") return e } @@ -928,7 +929,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", m.Push("file", q) } } - m.Table() + m.Sort("file").Table() return }}, "upgrade": &ctx.Command{Name: "upgrade project|bench|system|portal|plugin|restart|script", Help: "服务升级", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { @@ -996,7 +997,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", // 加载脚本 if p != "" { - msg.Target().Configs["_index"].Value = []interface{}{} + msg.Target().Configs["_index"] = &ctx.Config{Name: "_index", Value: []interface{}{}} msg.Optionv("bio.ctx", msg.Target()) msg.Cmdy("nfs.source", p) msg.Confv("ssh.componet", arg[0], msg.Confv("_index")) @@ -1102,6 +1103,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", "cmd_env", "ctx_home", m.Conf("runtime", "boot.ctx_home"), "cmd_env", "ctx_ups", fmt.Sprintf("127.0.0.1%s", m.Conf("runtime", "boot.ssh_port")), "cmd_env", "ctx_box", fmt.Sprintf("http://127.0.0.1%s", m.Conf("runtime", "boot.web_port")), + "cmd_env", "ctx_bin", m.Conf("runtime", "boot.ctx_bin"), } // 启动服务 diff --git a/src/contexts/cli/version.go b/src/contexts/cli/version.go index a818895a..5bca2f7f 100644 --- a/src/contexts/cli/version.go +++ b/src/contexts/cli/version.go @@ -4,5 +4,5 @@ var version = struct { host string self int }{ - "2019-09-02 20:11:08", "centos", 489, + "2019-09-10 15:30:05", "centos", 502, } diff --git a/src/contexts/ctx/misc.go b/src/contexts/ctx/misc.go index 90e4445a..62420150 100644 --- a/src/contexts/ctx/misc.go +++ b/src/contexts/ctx/misc.go @@ -115,6 +115,8 @@ func (m *Message) Format(arg ...interface{}) string { m.Table() case "time": meta = append(meta, m.Time()) + case "mill": + meta = append(meta, fmt.Sprintf("%d", int64(m.time.UnixNano())/1000%1000000)) case "code": meta = append(meta, kit.Format(m.code)) case "ship": diff --git a/src/contexts/log/log.go b/src/contexts/log/log.go index d64c4715..c0a74ea6 100644 --- a/src/contexts/log/log.go +++ b/src/contexts/log/log.go @@ -135,7 +135,7 @@ var Index = &ctx.Context{Name: "log", Help: "日志中心", "meta": map[string]interface{}{ "short": []interface{}{"time", "ship"}, "long": []interface{}{"time", "ship"}, - "cost": []interface{}{"time", "ship", "cost"}, + "cost": []interface{}{"time", "ship", "mill"}, }, "debug": map[string]interface{}{"value": []interface{}{"debug"}}, @@ -158,7 +158,7 @@ var Index = &ctx.Context{Name: "log", Help: "日志中心", "error": map[string]interface{}{"value": []interface{}{"error", "red"}}, "trace": map[string]interface{}{"value": []interface{}{"error", "red"}}, - "cmd": map[string]interface{}{"value": []interface{}{"bench", "green", "cost"}, + "cmd": map[string]interface{}{"value": []interface{}{"bench", "green"}, "lex": map[string]interface{}{"value": []interface{}{"debug", "green"}}, "yac": map[string]interface{}{"value": []interface{}{"debug", "green"}}, "cli": map[string]interface{}{ diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index 2deb2726..d1c92086 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -548,6 +548,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", "date": "--date=format:%m/%d %H:%M", "pretty": "--pretty=format:%h %ad %an %s", }, + "local": "usr/local", }, Help: "版本管理"}, "dir": &ctx.Config{Name: "dir", Value: map[string]interface{}{ "fields": "time size line path", @@ -703,51 +704,57 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", arg = arg[1:] } - if len(arg) > 0 && arg[0] == "sum" { - args := []string{} - if m.Options("git_dir") { - args = append(args, "-C", m.Option("git_dir")) - } - if args = append(args, "log", "--shortstat", "--pretty=commit: %ad", "--date=iso"); len(arg) > 1 { - args = append(args, arg[1:]...) - } else { - args = append(args, "--reverse") - } - - if out, e := exec.Command("git", args...).CombinedOutput(); e == nil { - for _, v := range strings.Split(string(out), "commit: ") { - if l := strings.Split(v, "\n"); len(l) > 2 { - fs := strings.Split(strings.TrimSpace(l[2]), ", ") - hs := strings.Split(l[0], " ") - m.Add("append", "date", hs[0]) - - if adds := strings.Split(fs[1], " "); len(fs) > 2 { - dels := strings.Split(fs[2], " ") - m.Add("append", "adds", adds[0]) - m.Add("append", "dels", dels[0]) - } else if adds[1] == "insertions(+)" { - m.Add("append", "adds", adds[0]) - m.Add("append", "dels", "0") - } else { - m.Add("append", "adds", "0") - m.Add("append", "dels", adds[0]) - } - m.Add("append", "hour", strings.Split(hs[1], ":")[0]) - m.Add("append", "time", hs[1]) - } else if len(l[0]) > 0 { - hs := strings.Split(l[0], " ") - m.Add("append", "date", hs[0]) - m.Add("append", "adds", 0) - m.Add("append", "dels", 0) - m.Add("append", "hour", strings.Split(hs[1], ":")[0]) - m.Add("append", "time", hs[1]) - } + if len(arg) > 0 { + switch arg[0] { + case "local": + m.Cmd("cli.system", "git", "clone", arg[1], "cmd_dir", m.Conf("git", "local")) + return + case "sum": + args := []string{} + if m.Options("git_dir") { + args = append(args, "-C", m.Option("git_dir")) } - m.Table() - } else { - m.Log("warn", "%v", string(out)) + if args = append(args, "log", "--shortstat", "--pretty=commit: %ad", "--date=iso"); len(arg) > 1 { + args = append(args, arg[1:]...) + } else { + args = append(args, "--reverse") + } + + if out, e := exec.Command("git", args...).CombinedOutput(); e == nil { + for _, v := range strings.Split(string(out), "commit: ") { + if l := strings.Split(v, "\n"); len(l) > 2 { + fs := strings.Split(strings.TrimSpace(l[2]), ", ") + hs := strings.Split(l[0], " ") + m.Add("append", "date", hs[0]) + + if adds := strings.Split(fs[1], " "); len(fs) > 2 { + dels := strings.Split(fs[2], " ") + m.Add("append", "adds", adds[0]) + m.Add("append", "dels", dels[0]) + } else if adds[1] == "insertions(+)" { + m.Add("append", "adds", adds[0]) + m.Add("append", "dels", "0") + } else { + m.Add("append", "adds", "0") + m.Add("append", "dels", adds[0]) + } + m.Add("append", "hour", strings.Split(hs[1], ":")[0]) + m.Add("append", "time", hs[1]) + } else if len(l[0]) > 0 { + hs := strings.Split(l[0], " ") + m.Add("append", "date", hs[0]) + m.Add("append", "adds", 0) + m.Add("append", "dels", 0) + m.Add("append", "hour", strings.Split(hs[1], ":")[0]) + m.Add("append", "time", hs[1]) + } + } + m.Table() + } else { + m.Log("warn", "%v", string(out)) + } + return } - return } cmds := []string{} diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index 1ad97920..aa4803be 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -186,7 +186,6 @@ func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) { } // 用户登录 - msg.Log("time", "parse: %v", msg.Format("cost")) if msg.Put("option", "request", r).Put("option", "response", w).Sess("web", msg); web.Login(msg, w, r) { msg.Log("cmd", "%s [] %v", key, msg.Meta["option"]) cmd.Hand(msg, msg.Target(), msg.Option("path")) @@ -876,7 +875,6 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", continue } // 执行命令 - m.Log("time", "check: %v", m.Format("cost")) msg.Cmd(arg) } } diff --git a/src/examples/code/code.go b/src/examples/code/code.go index 2933657f..44da9dad 100644 --- a/src/examples/code/code.go +++ b/src/examples/code/code.go @@ -203,64 +203,6 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", "data": []interface{}{}, "view": map[string]interface{}{"default": []interface{}{"index", "time", "text", "code", "output"}}, }, Help: "闪存"}, - "mux": &ctx.Config{Name: "mux", Value: map[string]interface{}{ - "cmd_timeout": "100ms", - "view": map[string]interface{}{ - "session": []interface{}{ - "session_id", - "session_name", - "session_windows", - "session_height", - "session_width", - "session_created_string", - }, - "window": []interface{}{ - "window_id", - "window_name", - "window_panes", - "window_height", - "window_width", - }, - "pane": []interface{}{ - "pane_id", - "pane_index", - "pane_tty", - "pane_height", - "pane_width", - }, - }, - "bind": map[string]interface{}{ - "0": map[string]interface{}{}, - "1": map[string]interface{}{ - "x": []interface{}{"kill-session"}, - }, - "2": map[string]interface{}{ - "x": []interface{}{"kill-window"}, - "s": []interface{}{"swap-window", "-s"}, - "e": []interface{}{"rename-window"}, - }, - "3": map[string]interface{}{ - "x": []interface{}{"kill-pane"}, - "b": []interface{}{"break-pane"}, - "h": []interface{}{"split-window", "-h"}, - "v": []interface{}{"split-window", "-v"}, - - "r": []interface{}{"send-keys"}, - "p": []interface{}{"pipe-pane"}, - "g": []interface{}{"capture-pane", "-p"}, - - "s": []interface{}{"swap-pane", "-d", "-s"}, - "mh": []interface{}{"move-pane", "-h", "-s"}, - "mv": []interface{}{"move-pane", "-v", "-s"}, - - "H": []interface{}{"resize-pane", "-L"}, - "L": []interface{}{"resize-pane", "-R"}, - "J": []interface{}{"resize-pane", "-D"}, - "K": []interface{}{"resize-pane", "-U"}, - "Z": []interface{}{"resize-pane", "-Z"}, - }, - }, - }, Help: "文档管理"}, "schedule": &ctx.Config{Name: "schedule", Value: map[string]interface{}{ "data": []interface{}{}, "view": map[string]interface{}{ @@ -375,125 +317,6 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", return }}, - "mux": &ctx.Command{Name: "mux [session [window [pane]]] args...", Help: "终端管理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - // 会话列表 - if len(arg) == 0 { - view := kit.View([]string{"session"}, m.Confm("mux", "view")) - for _, row := range strings.Split(strings.TrimSpace(m.Cmdx("cli.system", "tmux", "list-sessions", "-F", fmt.Sprintf("#{%s}", strings.Join(view, "},#{")))), "\n") { - for j, col := range strings.Split(row, ",") { - m.Add("append", view[j], col) - } - } - m.Table() - return - } - if v := m.Confv("mux", []string{"bind", "0", arg[0]}); v != nil { - m.Cmdy("cli.system", "tmux", v, arg[1:]) - return - } - - //窗口列表 - if len(arg) == 1 { - view := kit.View([]string{"window"}, m.Confm("mux", "view")) - for _, row := range strings.Split(strings.TrimSpace(m.Cmdx("cli.system", "tmux", "list-windows", "-t", arg[0], "-F", fmt.Sprintf("#{%s}", strings.Join(view, "},#{")))), "\n") { - for j, col := range strings.Split(row, ",") { - m.Add("append", view[j], col) - } - } - m.Table() - return - } - - switch arg[1] { - // 创建会话 - case "create": - m.Cmdy("cli.system", "tmux", "new-session", "-s", arg[0], arg[2:], "-d", "cmd_env", "TMUX", "") - return - // 检查会话 - case "exist": - m.Cmdy("cli.system", "tmux", "has-session", "-t", arg[0]) - return - // 会话操作 - default: - if v := m.Confv("mux", []string{"bind", "1", arg[1]}); v != nil { - m.Cmdy("cli.system", "tmux", v, "-t", arg[0], arg[2:]) - return - } - } - - target := fmt.Sprintf("%s:%s", arg[0], arg[1]) - // 面板列表 - if len(arg) == 2 { - view := kit.View([]string{"pane"}, m.Confm("mux", "view")) - for _, row := range strings.Split(strings.TrimSpace(m.Cmdx("cli.system", "tmux", "list-panes", "-t", target, "-F", fmt.Sprintf("#{%s}", strings.Join(view, "},#{")))), "\n") { - for j, col := range strings.Split(row, ",") { - m.Add("append", view[j], col) - } - } - m.Table() - return - } - - switch arg[2] { - // 创建窗口 - case "create": - m.Cmdy("cli.system", "tmux", "new-window", "-t", arg[0], "-n", arg[1], arg[3:]) - return - // 窗口操作 - default: - if v := m.Confv("mux", []string{"bind", "2", arg[2]}); v != nil { - m.Cmdy("cli.system", "tmux", v, arg[3:], "-t", target) - return - } - } - - // 面板内容 - if target = fmt.Sprintf("%s:%s.%s", arg[0], arg[1], arg[2]); len(arg) == 3 { - m.Cmdy("cli.system", "tmux", "capture-pane", "-t", target, "-p") - return - } - - switch arg[3] { - case "run": - m.Cmd("cli.system", "tmux", "send-keys", "-t", target, "clear", "Enter") - time.Sleep(kit.Duration(m.Conf("mux", "cmd_timeout"))) - prompt := strings.TrimSpace(m.Cmdx("cli.system", "tmux", "capture-pane", "-t", target, "-p")) - m.Log("info", "wait for prompt %v", prompt) - - m.Cmd("cli.system", "tmux", "send-keys", "-t", target, strings.Join(arg[4:], " "), "Enter") - for i := 0; i < 1000; i++ { - time.Sleep(kit.Duration(m.Conf("mux", "cmd_timeout"))) - list := strings.Split(m.Cmdx("cli.system", "tmux", "capture-pane", "-t", target, "-p"), "\n") - m.Log("info", "current %v", list) - for j := len(list)-1; j >= 0; j-- { - if list[j] != "" { - if list[j] == prompt { - i = 1000 - } - break - } - } - } - return - } - - if v := m.Confv("mux", []string{"bind", "3", arg[3]}); v != nil { - switch arg[3] { - case "r": - m.Cmd("cli.system", "tmux", "send-keys", "-t", target, strings.Join(arg[4:], " "), "Enter") - time.Sleep(kit.Duration(m.Conf("mux", "cmd_timeout"))) - m.Cmdy("cli.system", "tmux", "capture-pane", "-t", target, "-p") - case "p": - m.Cmdy("cli.system", "tmux", "pipe-pane", "-t", target, arg[4:]) - default: - m.Cmdy("cli.system", "tmux", v, arg[4:], "-t", target) - } - return - } - - m.Cmdy("cli.system", "tmux", "send-keys", "-t", target, arg[3:]) - return - }}, "schedule": &ctx.Command{Name: "schedule [time name place]", Help: "行程安排", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if len(arg) == 0 { // 会话列表 m.Confm("schedule", "data", func(index int, value map[string]interface{}) { diff --git a/src/plugin/context/index.shy b/src/plugin/context/index.shy index 2d1b6d22..44cd43d7 100644 --- a/src/plugin/context/index.shy +++ b/src/plugin/context/index.shy @@ -3,6 +3,7 @@ kit project "项目" private \ select "" values plugin values review values submit values trend values stats values stat values init action auto \ text "" name see imports plugin_see action auto \ button "执行" \ + button "返回" click Last \ exports see name see kit compile "编译" private \ diff --git a/src/plugin/tmux/index.go b/src/plugin/tmux/index.go new file mode 100644 index 00000000..bf135e27 --- /dev/null +++ b/src/plugin/tmux/index.go @@ -0,0 +1,220 @@ +package main + +import ( + "contexts/cli" + "contexts/ctx" + "toolkit" + + "strings" + "time" + "fmt" + "os" +) + +var Index = &ctx.Context{Name: "tmux", Help: "终端管理", + Caches: map[string]*ctx.Cache{}, + Configs: map[string]*ctx.Config{ + "mux": &ctx.Config{Name: "mux", Value: map[string]interface{}{ + "cmd_timeout": "100ms", + "view": map[string]interface{}{ + "session": []interface{}{ + "session_id", + "session_name", + "session_windows", + "session_height", + "session_width", + "session_created_string", + }, + "window": []interface{}{ + "window_id", + "window_name", + "window_panes", + "window_height", + "window_width", + }, + "pane": []interface{}{ + "pane_id", + "pane_index", + "pane_tty", + "pane_height", + "pane_width", + }, + }, + "bind": map[string]interface{}{ + "0": map[string]interface{}{}, + "1": map[string]interface{}{ + "x": []interface{}{"kill-session"}, + }, + "2": map[string]interface{}{ + "x": []interface{}{"kill-window"}, + "s": []interface{}{"swap-window", "-s"}, + "e": []interface{}{"rename-window"}, + }, + "3": map[string]interface{}{ + "x": []interface{}{"kill-pane"}, + "b": []interface{}{"break-pane"}, + "h": []interface{}{"split-window", "-h"}, + "v": []interface{}{"split-window", "-v"}, + + "r": []interface{}{"send-keys"}, + "p": []interface{}{"pipe-pane"}, + "g": []interface{}{"capture-pane", "-p"}, + + "s": []interface{}{"swap-pane", "-d", "-s"}, + "mh": []interface{}{"move-pane", "-h", "-s"}, + "mv": []interface{}{"move-pane", "-v", "-s"}, + + "H": []interface{}{"resize-pane", "-L"}, + "L": []interface{}{"resize-pane", "-R"}, + "J": []interface{}{"resize-pane", "-D"}, + "K": []interface{}{"resize-pane", "-U"}, + "Z": []interface{}{"resize-pane", "-Z"}, + }, + }, + }, Help: "文档管理"}, + }, + Commands: map[string]*ctx.Command{ + "mux": &ctx.Command{Name: "mux [session [window [pane]]] args...", Help: "终端管理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + // 会话列表 + if len(arg) == 0 { + view := kit.View([]string{"session"}, m.Confm("mux", "view")) + for _, row := range strings.Split(strings.TrimSpace(m.Cmdx("cli.system", "tmux", "list-sessions", "-F", fmt.Sprintf("#{%s}", strings.Join(view, "},#{")))), "\n") { + for j, col := range strings.Split(row, ",") { + m.Add("append", view[j], col) + } + } + m.Table() + return + } + if v := m.Confv("mux", []string{"bind", "0", arg[0]}); v != nil { + m.Cmdy("cli.system", "tmux", v, arg[1:]) + return + } + + //窗口列表 + if len(arg) == 1 { + view := kit.View([]string{"window"}, m.Confm("mux", "view")) + for _, row := range strings.Split(strings.TrimSpace(m.Cmdx("cli.system", "tmux", "list-windows", "-t", arg[0], "-F", fmt.Sprintf("#{%s}", strings.Join(view, "},#{")))), "\n") { + for j, col := range strings.Split(row, ",") { + m.Add("append", view[j], col) + } + } + m.Table() + return + } + + switch arg[1] { + // 创建会话 + case "create": + m.Cmdy("cli.system", "tmux", "new-session", "-s", arg[0], arg[2:], "-d", "cmd_env", "TMUX", "") + return + // 检查会话 + case "exist": + m.Cmdy("cli.system", "tmux", "has-session", "-t", arg[0]) + return + // 会话操作 + default: + if v := m.Confv("mux", []string{"bind", "1", arg[1]}); v != nil { + m.Cmdy("cli.system", "tmux", v, "-t", arg[0], arg[2:]) + return + } + } + + target := fmt.Sprintf("%s:%s", arg[0], arg[1]) + // 面板列表 + if len(arg) == 2 { + view := kit.View([]string{"pane"}, m.Confm("mux", "view")) + for _, row := range strings.Split(strings.TrimSpace(m.Cmdx("cli.system", "tmux", "list-panes", "-t", target, "-F", fmt.Sprintf("#{%s}", strings.Join(view, "},#{")))), "\n") { + for j, col := range strings.Split(row, ",") { + m.Add("append", view[j], col) + } + } + m.Table() + return + } + + switch arg[2] { + // 创建窗口 + case "create": + m.Cmdy("cli.system", "tmux", "new-window", "-t", arg[0], "-n", arg[1], arg[3:]) + return + // 窗口操作 + default: + if v := m.Confv("mux", []string{"bind", "2", arg[2]}); v != nil { + m.Cmdy("cli.system", "tmux", v, arg[3:], "-t", target) + return + } + } + + // 面板内容 + if target = fmt.Sprintf("%s:%s.%s", arg[0], arg[1], arg[2]); len(arg) == 3 { + m.Cmdy("cli.system", "tmux", "capture-pane", "-t", target, "-p") + return + } + + switch arg[3] { + case "run": + m.Cmd("cli.system", "tmux", "send-keys", "-t", target, "clear", "Enter") + time.Sleep(kit.Duration(m.Conf("mux", "cmd_timeout"))) + prompt := strings.TrimSpace(m.Cmdx("cli.system", "tmux", "capture-pane", "-t", target, "-p")) + m.Log("info", "wait for prompt %v", prompt) + + m.Cmd("cli.system", "tmux", "send-keys", "-t", target, strings.Join(arg[4:], " "), "Enter") + for i := 0; i < 1000; i++ { + time.Sleep(kit.Duration(m.Conf("mux", "cmd_timeout"))) + list := strings.Split(m.Cmdx("cli.system", "tmux", "capture-pane", "-t", target, "-p"), "\n") + m.Log("info", "current %v", list) + for j := len(list)-1; j >= 0; j-- { + if list[j] != "" { + if list[j] == prompt { + i = 1000 + } + break + } + } + } + return + } + + if v := m.Confv("mux", []string{"bind", "3", arg[3]}); v != nil { + switch arg[3] { + case "r": + m.Cmd("cli.system", "tmux", "send-keys", "-t", target, "clear", "Enter") + m.Cmd("cli.system", "tmux", "clear-history", "-t", target) + time.Sleep(kit.Duration("10ms")) + + m.Cmd("cli.system", "tmux", "send-keys", "-t", target, strings.Join(arg[4:], " "), "Enter") + time.Sleep(kit.Duration(m.Conf("mux", "cmd_timeout"))) + m.Cmdy("cli.system", "tmux", "capture-pane", "-t", target, "-p", "-S", "-1000") + case "p": + m.Cmdy("cli.system", "tmux", "pipe-pane", "-t", target, arg[4:]) + default: + m.Cmdy("cli.system", "tmux", v, arg[4:], "-t", target) + } + return + } + + m.Cmdy("cli.system", "tmux", "send-keys", "-t", target, arg[3:]) + return + }}, + "buf": &ctx.Command{Name: "buf", Help: "缓存管理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + switch len(arg) { + case 0: + m.Cmdy("cli.system", "tmux", "list-buffer", "cmd_parse", "cut", 3, ":") + m.Meta["append"][0] = "cur" + m.Meta["cur"] = m.Meta["0"] + + case 2: + m.Cmdy("cli.system", "tmux", "set-buffer", "-b", arg[0], arg[1]) + fallthrough + case 1: + m.Cmdy("cli.system", "tmux", "show-buffer", "-b", arg[0]) + } + return + }}, + }, +} + +func main() { + fmt.Print(cli.Index.Plugin(Index, os.Args[1:])) +} diff --git a/src/plugin/tmux/index.js b/src/plugin/tmux/index.js new file mode 100644 index 00000000..8c8f3659 --- /dev/null +++ b/src/plugin/tmux/index.js @@ -0,0 +1,4 @@ + +{init: function(page, pane, field, option, output) { + kit.Log("hello world") +}} diff --git a/src/plugin/tmux/index.shy b/src/plugin/tmux/index.shy new file mode 100644 index 00000000..e4f31d36 --- /dev/null +++ b/src/plugin/tmux/index.shy @@ -0,0 +1,38 @@ + +kit buffer "粘贴板" public buf \ + text "0" name index imports plugin_tmux_bindex action auto \ + text "" name txt action auto \ + button "查看" action auto \ + button "返回" click Last \ + exports tmux_bindex cur + +kit session "会话" private mux \ + button "查看" action auto \ + exports tmux_sess session_name + +kit windows "窗口" private mux \ + text "" imports plugin_tmux_sess action auto \ + button "查看" \ + exports tmux_wins window_name + +kit pane "面板" private mux \ + text "" imports plugin_tmux_sess \ + text "" imports plugin_tmux_wins action auto \ + button "查看" \ + exports tmux_pane pane_index + +kit view "内容" private mux \ + text "" imports plugin_tmux_sess \ + text "" imports plugin_tmux_wins \ + text "" imports plugin_tmux_pane action auto \ + button "查看" \ + exports tmux_pane pane_index + +kit cmd "命令" private mux _ _ _ r \ + text "" imports plugin_tmux_sess \ + text "" imports plugin_tmux_wins \ + text "" imports plugin_tmux_pane \ + text "pwd" view long \ + button "执行" \ + exports tmux_pane pane_index + diff --git a/src/plugin/tmux/local.shy b/src/plugin/tmux/local.shy new file mode 100644 index 00000000..0519ecba --- /dev/null +++ b/src/plugin/tmux/local.shy @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/toolkit/misc.go b/src/toolkit/misc.go index 692edc94..3fcf67d7 100644 --- a/src/toolkit/misc.go +++ b/src/toolkit/misc.go @@ -44,14 +44,14 @@ func Create(p string) (*os.File, string, error) { return f, p, e } -func Split(str string, n int) []string { +func Split(str string, c byte, n int) []string { res := []string{} for i, j := 0, 0; i < len(str); i++ { - if str[i] == ' ' { + if str[i] == c { continue } for j = i; j < len(str); j++ { - if str[j] == ' ' { + if str[j] == c { break } } diff --git a/usr/librarys/example.css b/usr/librarys/example.css index ae774455..dec49c2c 100644 --- a/usr/librarys/example.css +++ b/usr/librarys/example.css @@ -271,6 +271,9 @@ fieldset table caption { fieldset table tr:hover { background-color:lightgreen; } +fieldset table tr.select { + background-color:lightgreen; +} fieldset table th { font-family:monospace; background-color:lightgreen; @@ -292,6 +295,9 @@ fieldset table td.clip { fieldset table td:hover { background-color:red; } +fieldset table td.select { + background-color:red; +} fieldset pre code, fieldset code pre { color:white; font-size:14px; diff --git a/usr/librarys/example.js b/usr/librarys/example.js index b5689dda..da1c5286 100644 --- a/usr/librarys/example.js +++ b/usr/librarys/example.js @@ -696,6 +696,7 @@ function Plugin(page, pane, field, runs) { var meta = field.Meta var name = meta.name var args = meta.args || [] + var inputs = JSON.parse(meta.inputs || "[]") var display = JSON.parse(meta.display||'{}') var feature = JSON.parse(meta.feature||'{}') var exports = JSON.parse(meta.exports||'["",""]') @@ -777,8 +778,11 @@ function Plugin(page, pane, field, runs) { }).field.Plugin }, Last: function() { + console.log(meta) var list = history.pop() - list && (list.target.value = list.value, plugin.Check()) + list? (list.target.value = list.value): inputs.map(function(item) { + option[item.name].value = item.value + }), plugin.Check() }, Help: function(type, action) { @@ -999,13 +1003,16 @@ function Plugin(page, pane, field, runs) { } return true }) - item.type != "textarea" && event.key == "Enter" && plugin.Check(action.target) + if (item.type != "textarea" && event.key == "Enter") { + history.push({target: action.target, value: action.target.value}); + plugin.Check(action.target) + } }, }, exports: JSON.parse(meta.exports||'["",""]'), }) - JSON.parse(meta.inputs || "[]").map(function(item) { + inputs.map(function(item) { plugin.Append(item, item.name, item.value) }) return page[field.id] = pane[field.id] = pane[name] = field, field.Plugin = plugin diff --git a/usr/librarys/toolkit.js b/usr/librarys/toolkit.js index d57ef71d..98495e26 100644 --- a/usr/librarys/toolkit.js +++ b/usr/librarys/toolkit.js @@ -410,6 +410,12 @@ kit = toolkit = { var target = event.target var dataset = target.dataset var head = target.parentElement.parentElement.querySelector("tr") + kit.Selector(table, "tr.select", function(item) { + item.className = "" + }) + kit.Selector(table, "td.select", function(item) { + item.className = "" + }) target.parentElement.childNodes.forEach(function(item, i) { if (item != target) { return @@ -421,6 +427,8 @@ kit = toolkit = { } var name = head.childNodes[i].innerText if (name.startsWith(field)) { + item.className = "select" + item.parentElement.className = "select" typeof cb == "function" && cb(event, item.innerText, name,item.parentNode.Meta) } kit.CopyText()