forked from x/ContextOS
add plugin tmux
This commit is contained in:
parent
4c3223f63f
commit
624c0f3c90
@ -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=
|
||||
|
@ -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"),
|
||||
}
|
||||
|
||||
// 启动服务
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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":
|
||||
|
@ -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{}{
|
||||
|
@ -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{}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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{}) {
|
||||
|
@ -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 \
|
||||
|
220
src/plugin/tmux/index.go
Normal file
220
src/plugin/tmux/index.go
Normal file
@ -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:]))
|
||||
}
|
4
src/plugin/tmux/index.js
Normal file
4
src/plugin/tmux/index.js
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
{init: function(page, pane, field, option, output) {
|
||||
kit.Log("hello world")
|
||||
}}
|
38
src/plugin/tmux/index.shy
Normal file
38
src/plugin/tmux/index.shy
Normal file
@ -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
|
||||
|
1
src/plugin/tmux/local.shy
Normal file
1
src/plugin/tmux/local.shy
Normal file
@ -0,0 +1 @@
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user