From df1ba45a6dfc22877b1b2efdd075dea68a79a46f Mon Sep 17 00:00:00 2001 From: shaoying Date: Sun, 10 Nov 2019 19:28:02 +0800 Subject: [PATCH] add m.Grows --- etc/conf/auto.vim | 88 +++++---- etc/exit.shy | 2 +- etc/init.shy | 2 +- src/contexts/ctx/misc.go | 98 +++++++++- src/contexts/ctx/type.go | 4 +- src/contexts/ssh/ssh.go | 13 +- src/examples/code/code.go | 352 ++++++++++++++++++------------------ src/examples/wiki/wiki.go | 11 ++ src/plugin/docker/index.shy | 5 +- src/toolkit/core.go | 30 +-- src/toolkit/misc.go | 29 +++ 11 files changed, 388 insertions(+), 246 deletions(-) diff --git a/etc/conf/auto.vim b/etc/conf/auto.vim index 2bfa29bc..abdf5d33 100644 --- a/etc/conf/auto.vim +++ b/etc/conf/auto.vim @@ -4,31 +4,60 @@ let ctx_head = "Content-Type: application/json" let ctx_sid = "" fun! ShyPost(arg) + let a:arg["buf"] = bufname("%") let a:arg["buf"] = bufname("%") let a:arg["pwd"] = getcwd() let a:arg["sid"] = g:ctx_sid for k in keys(a:arg) let a:arg[k] = substitute(a:arg[k], "'", "XXXXXsingleXXXXX", "g") endfor - - let data = json_encode(a:arg) - return system("curl -s '" . g:ctx_url . "' -H '" . g:ctx_head . "' -d '" . data . "' 2>/dev/null") + return system("curl -s '" . g:ctx_url . "' -H '" . g:ctx_head . "' -d '" . json_encode(a:arg) . "' 2>/dev/null") endfun fun! ShySync(target) if bufname("%") == "ControlP" return end - if a:target == "exec" - call ShyPost({"cmd": "exec", "arg": getcmdline()}) + + if a:target == "read" || a:target == "write" + call ShyPost({"cmd": a:target, "arg": expand("")}) + elseif a:target == "exec" + call ShyPost({"cmd": a:target, "arg": getcmdline()}) elseif a:target == "insert" - call ShyPost({"cmd": "insert", "arg": getreg("."), "row": line("."), "col": col(".")}) + call ShyPost({"cmd": a:target, "arg": getreg("."), "row": line("."), "col": col(".")}) else - let cmd = {"marks": "marks", "tags": "tags", "fixs": "clist", "bufs": "buffers", "regs": "registers"} + let cmd = {"bufs": "buffers", "regs": "registers", "marks": "marks", "tags": "tags", "fixs": "clist"} call ShyPost({"cmd": "sync", "arg": a:target, "sub": execute(cmd[a:target])}) endif endfun +fun! ShyCheck(target) + if a:target == "login" + if g:ctx_sid == "" + let arg = {"cmd": "login", "pid": getpid(), "pane": $TMUX_PANE, "hostname": hostname(), "username": $USER} + let g:ctx_sid = ShyPost(arg) + endif + elseif a:target == "exec" + let cmd = getcmdline() + if cmd != "" + call ShySync("exec") + if getcmdline() == "w" + call ShySync("regs") + call ShySync("marks") + call ShySync("tags") + endif + endif + elseif a:target == "fixs" + let l = len(getqflist()) + if l > 0 + execute "copen " . (l > 10? 10: l + 1) + call ShySync("fixs") + else + cclose + end + end +endfun + fun! Shy(action, target) let arg = {"arg": a:target, "cmd": a:action} let cmd = ShyPost(arg) @@ -38,47 +67,29 @@ fun! Shy(action, target) endif endfun -fun! ShyCheck(target) - if a:target == "exec" - let cmd = getcmdline() - if cmd != "" - call ShySync("exec") - if getcmdline() == "w" - call ShySync("tags") - call ShySync("regs") - call ShySync("marks") - endif - endif - elseif a:target == "fixs" - if len(getqflist()) > 1 - copen - call ShySync("fixs") - else - cclose - end - end -endfun fun! ShyLogout() call Shy("logout", "") -endfun -fun! ShyLogin() - let arg = {"cmd": "login", "pid": getpid(), "pane": $TMUX_PANE, "hostname": hostname(), "username": $USER} - let g:ctx_sid = ShyPost(arg) + let g:ctx_sid = "" endfun -call ShyLogin() +call ShyCheck("login") autocmd VimLeave * call ShyLogout() + autocmd InsertLeave * call ShySync("insert") autocmd CmdlineLeave * call ShyCheck("exec") -autocmd QuickFixCmdPost * call ShyCheck("fixs") - -autocmd BufReadPost * call Shy("read", expand("")) | call ShySync("bufs") +autocmd BufReadPost * call Shy("read", expand("")) +autocmd BufReadPost * call ShySync("bufs") autocmd BufWritePre * call Shy("write", expand("")) + +autocmd QuickFixCmdPost * call ShyCheck("fixs") +" call ShySync("bufs") +call ShySync("regs") +call ShySync("marks") +call ShySync("tags") +" call ShySync("fixs") + " autocmd BufUnload * call Shy("close", expand("")) | call ShySync("bufs") " autocmd CmdlineLeave * -call ShySync("tags") - - " autocmd CompleteDone * call Shy("sync", "regs") " autocmd InsertEnter * call Shy("sync", "regs") " autocmd CmdlineEnter * call Shy("sync", "regs") @@ -100,6 +111,5 @@ call ShySync("tags") " endfunction " call ColorNext() " command! NN call ColorNext() -" command! RR wa | source ~/.vimrc |e " command! SS mksession! etc/session.vim diff --git a/etc/exit.shy b/etc/exit.shy index ee5eb40d..e897a5ed 100644 --- a/etc/exit.shy +++ b/etc/exit.shy @@ -1,6 +1,6 @@ # 应用配置 ~code - config save var/tmp/vim.json vim + config save var/tmp/vim/vim.json vim config save var/tmp/zsh.json zsh # 系统配置 diff --git a/etc/init.shy b/etc/init.shy index 07d36a67..ec3c9011 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -19,7 +19,7 @@ # 应用配置 ~code config load tmp/zsh.json zsh - config load tmp/vim.json vim + config load tmp/vim/vim.json vim # 终端配置 ~cli diff --git a/src/contexts/ctx/misc.go b/src/contexts/ctx/misc.go index 29591126..2634cdc8 100644 --- a/src/contexts/ctx/misc.go +++ b/src/contexts/ctx/misc.go @@ -542,16 +542,18 @@ func (m *Message) Grow(key string, args interface{}, data interface{}) interface keys, e = r.Read() } + count := len(list) - least record, _ := meta["record"].([]interface{}) meta["record"] = append(record, map[string]interface{}{ "time": m.Time(), "offset": offset, "position": s.Size(), + "count": count, + "file": name, }) - end := len(list) - least for i, v := range list { - if i >= end { + if i >= count { break } @@ -564,12 +566,12 @@ func (m *Message) Grow(key string, args interface{}, data interface{}) interface w.Write(values) if i < least { - list[i] = list[end+i] + list[i] = list[count+i] } } - m.Log("info", "save %s offset %v+%v", name, offset, end) - meta["offset"] = offset + end + m.Log("info", "save %s offset %v+%v", name, offset, count) + meta["offset"] = offset + count list = list[:least] w.Flush() } @@ -578,3 +580,89 @@ func (m *Message) Grow(key string, args interface{}, data interface{}) interface m.Conf(key, args, cache) return list } +func (m *Message) Grows(key string, args interface{}, cb interface{}) map[string]interface{} { + cache := m.Confm(key, args) + if cache == nil { + return nil + } + meta, ok := cache["meta"].(map[string]interface{}) + if !ok { + return nil + } + list, ok := cache["list"].([]interface{}) + if !ok { + return nil + } + + offset := kit.Int(kit.Select("0", m.Option("cache.offset"))) + limit := kit.Int(kit.Select("10", m.Option("cache.limit"))) + current := kit.Int(meta["offset"]) + end := current + len(list) - offset + begin := end - limit + + data := make([]interface{}, 0, limit) + m.Log("info", "read current %v+%d %v-%v", current, len(list), begin, end) + if begin < current { + store, _ := meta["record"].([]interface{}) + for s := len(store) - 1; s > -1; s-- { + item, _ := store[s].(map[string]interface{}) + line := kit.Int(item["offset"]) + m.Log("info", "check history %v %v %v", s, line, item) + if begin < line && s > 0 { + continue + } + + for ; s < len(store); s++ { + if begin >= end { + break + } + item, _ := store[s].(map[string]interface{}) + if line+kit.Int(item["count"]) < begin { + continue + } + + name := kit.Format(item["file"]) + pos := kit.Int(item["position"]) + line := kit.Int(item["offset"]) + m.Log("info", "load history %v %v %v", s, line, item) + if f, e := os.Open(name); m.Assert(e) { + defer f.Close() + r := csv.NewReader(f) + heads, _ := r.Read() + m.Log("info", "load head %v", heads) + + f.Seek(int64(pos), os.SEEK_SET) + r = csv.NewReader(f) + for i := line; i < end; i++ { + lines, e := r.Read() + if e != nil { + break + } + + if i >= begin { + item := map[string]interface{}{} + for i := range heads { + item[heads[i]] = lines[i] + } + m.Log("info", "load line %v %v %v", i, len(data), item) + data = append(data, item) + begin = i + 1 + } else { + m.Log("info", "skip line %v", i) + } + } + } + } + break + } + } + + if begin < current { + begin = current + } + for i := begin - current; i < end-current; i++ { + m.Log("info", "cache data %v %v", i+current, list[i]) + data = append(data, list[i]) + } + return kit.Map(map[string]interface{}{"meta": meta, "list": data}, "", cb) +} diff --git a/src/contexts/ctx/type.go b/src/contexts/ctx/type.go index 8d65b737..9e52f15c 100644 --- a/src/contexts/ctx/type.go +++ b/src/contexts/ctx/type.go @@ -354,9 +354,9 @@ func (m *Message) Split(str string, arg ...string) *Message { if len(l) < v { m.Add("append", heads[i], "") } else if i == len(pos)-1 { - m.Add("append", heads[i], l[v:]) + m.Add("append", heads[i], strings.TrimSpace(l[v:])) } else { - m.Add("append", heads[i], l[v:pos[i+1]]) + m.Add("append", heads[i], strings.TrimSpace(l[v:pos[i+1]])) } } continue diff --git a/src/contexts/ssh/ssh.go b/src/contexts/ssh/ssh.go index e545ad37..08f368bc 100644 --- a/src/contexts/ssh/ssh.go +++ b/src/contexts/ssh/ssh.go @@ -403,7 +403,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", } return }}, - "data": {Name: "data show|save|create|insert", Help: "数据", Form: map[string]int{"format": 1, "fields": -1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + "data": {Name: "data show|insert|update [table [index] [key value]...]", Help: "数据", Form: map[string]int{"format": 1, "fields": -1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if len(arg) == 0 { arg = append(arg, "show") } @@ -421,7 +421,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", case 2: // 关系表 hide := map[string]bool{"create_time": true, "update_time": true, "extra": true} - m.Confm("flow", []string{m.Option("river"), "data", arg[1], "list"}, func(index int, value map[string]interface{}) { + m.Grows("flow", []string{m.Option("river"), "data", arg[1]}, func(meta map[string]interface{}, index int, value map[string]interface{}) { for k := range value { if !hide[k] { hide[k] = false @@ -440,7 +440,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", if m.Meta["append"] = []string{"id", "when"}; m.Has("fields") { keys = kit.Trans(m.Optionv("fields")) } - m.Confm("flow", []string{m.Option("river"), "data", arg[1], "list"}, func(index int, value map[string]interface{}) { + m.Grows("flow", []string{m.Option("river"), "data", arg[1]}, func(meta map[string]interface{}, index int, value map[string]interface{}) { for _, k := range keys { m.Push(k, kit.Format(value[k])) } @@ -487,7 +487,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", kit.Marshal(data["list"], path.Join(m.Conf("ssh.data", "path"), m.Option("river"), v, "/list.csv")) l := len(data["list"].([]interface{})) - m.Push("table", v).Push("count", l) + m.Push("table", v).Push("count", l+kit.Int(kit.Chain(data["meta"], "offset"))) m.Log("info", "save table %s:%s %d", m.Option("river"), v, l) } m.Table() @@ -507,6 +507,9 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", "create_user": m.Option("username"), "create_time": m.Time(), "create_tmpl": tmpl, + "store": path.Join(m.Conf("ssh.data", "path"), m.Option("river"), arg[1], "/auto.csv"), + "limit": "30", + "least": "10", }, "list": []interface{}{}, }) @@ -543,7 +546,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", data["id"] = id m.Log("info", "insert %s:%s %s", m.Option("river"), arg[1], kit.Format(data)) - m.Confv("flow", []string{m.Option("river"), "data", arg[1], "list", "-2"}, data) + m.Grow("flow", []string{m.Option("river"), "data", arg[1]}, data) m.Cmdy("ssh.data", "save", arg[1]) case "update": diff --git a/src/examples/code/code.go b/src/examples/code/code.go index 71a3fc5e..8aaa1dd6 100644 --- a/src/examples/code/code.go +++ b/src/examples/code/code.go @@ -49,16 +49,52 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", "git": {Name: "git", Help: "记录", Value: map[string]interface{}{ "alias": map[string]interface{}{"s": "status", "b": "branch"}, }}, - "vim": {Name: "vim", Help: "记录", Value: map[string]interface{}{ - "editor": map[string]interface{}{}, - "opens": map[string]interface{}{}, - }}, "zsh": {Name: "vim", Help: "记录", Value: map[string]interface{}{ "terminal": map[string]interface{}{}, "history": map[string]interface{}{}, }}, - "cache": {Name: "flow", Help: "记录", Value: map[string]interface{}{ - "store": "hi.csv", + "vim": {Name: "vim", Help: "编辑器", Value: map[string]interface{}{ + "editor": map[string]interface{}{"meta": map[string]interface{}{ + "fields": "time sid status pwd pid pane hostname username", + }}, + "favor": map[string]interface{}{}, + "opens": map[string]interface{}{"meta": map[string]interface{}{ + "fields": "time sid action file pwd", + "store": "var/tmp/vim/opens.csv", + "limit": "30", + "least": "10", + }}, + "cmds": map[string]interface{}{"meta": map[string]interface{}{ + "fields": "time sid cmd file pwd", + "store": "var/tmp/vim/cmds.csv", + "limit": "30", + "least": "10", + }}, + "txts": map[string]interface{}{"meta": map[string]interface{}{ + "fields": "time sid text line col file pwd", + "store": "var/tmp/vim/txts.csv", + "limit": "30", + "least": "10", + }}, + + "bufs": map[string]interface{}{"meta": map[string]interface{}{ + "fields": "sid buf tag file line", + }}, + "regs": map[string]interface{}{"meta": map[string]interface{}{ + "fields": "sid reg text", + }}, + "marks": map[string]interface{}{"meta": map[string]interface{}{ + "fields": "sid mark line col file", + }}, + "tags": map[string]interface{}{"meta": map[string]interface{}{ + "fields": "sid tag line file", + }}, + "fixs": map[string]interface{}{"meta": map[string]interface{}{ + "fields": "sid fix file line text", + }}, + }}, + "cache": {Name: "cache", Help: "缓存默认的全局配置", Value: map[string]interface{}{ + "store": "var/tmp/hi.csv", "limit": 6, "least": 3, }}, @@ -578,7 +614,7 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", m.Cmdy("cli.system", "gotags", "-f", kit.Select("tags", arg, 1), "-R", kit.Select("src", arg, 0)) return }}, - "vim": {Name: "vim", Help: "编辑器", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + "vim": {Name: "vim editor|prune|opens|cmds|txts|bufs|regs|marks|tags|fixs", Help: "编辑器", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { switch arg[0] { case "ctag": if f, p, e := kit.Create("etc/conf/tags"); m.Assert(e) { @@ -589,195 +625,161 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", m.Echo(p) } - case "editor": - m.Confm("vim", "editor", func(key string, value map[string]interface{}) { - m.Push([]string{"time", "sid", "status", "pwd", "pid", "pane", "hostname", "username"}, value) - }) - m.Sort("time", "time_r").Table() - case "opens": - m.Confm("vim", "opens", func(key string, value map[string]interface{}) { - value["sid"] = kit.Format(value["sid"])[:6] - m.Push([]string{"time", "sid", "action", "file"}, value) - }) - m.Sort("time", "time_r").Table() case "prune": ps := []string{} - m.Confm("vim", []string{"editor"}, func(key string, value map[string]interface{}) { + m.Confm("vim", "editor", func(key string, value map[string]interface{}) { if kit.Format(value["status"]) == "logout" { ps = append(ps, key) } }) for _, v := range ps { - for _, k := range []string{"editor", "exec", "tag", "fix", "buffer", "register"} { + for _, k := range []string{"editor", "bufs", "regs", "marks", "tags", "fixs"} { m.Log("info", "prune vim %v %v %v", k, v, kit.Formats(m.Conf("vim", []string{k, v}))) m.Confv("vim", []string{k, v}, "") } } + fallthrough + case "editor": + fields := strings.Split(kit.Select(m.Conf("vim", arg[0]+".meta.fields"), arg, 1), " ") + m.Confm("vim", arg[0]+".hash", func(key string, value map[string]interface{}) { + m.Push(fields, kit.Shortm(value, "times", "files", "sids")) + }) + if m.Appends("time") { + m.Sort("time", "time_r") + } - case "cmds": - m.Confm("vim", "exec", func(meta map[string]interface{}, index int, value map[string]interface{}) { - value["sid"] = kit.Format(value["sid"])[:6] - m.Push([]string{"time", "sid", "cmd", "file", "pwd"}, value) + case "opens", "cmds", "txts": + if len(arg) > 3 { + arg[3] = strings.Join(arg[3:], " ") + } + m.Option("cache.limit", kit.Select("10", arg, 1)) + m.Option("cache.offset", kit.Select("0", arg, 2)) + fields := strings.Split(kit.Select(m.Conf("vim", arg[0]+".meta.fields"), arg, 3), " ") + m.Grows("vim", arg[0], func(meta map[string]interface{}, index int, value map[string]interface{}) { + m.Push(fields, kit.Shortm(value, "times", "files", "sids")) }) - m.Sort("time", "time_r").Table() - case "txts": - m.Confm("vim", "insert", func(meta map[string]interface{}, index int, value map[string]interface{}) { - value["sid"] = kit.Format(value["sid"])[:6] - m.Push([]string{"time", "sid", "text", "line", "col", "file", "pwd"}, value) + if m.Appends("time") { + m.Sort("time", "time_r") + } + + case "bufs", "regs", "marks", "tags", "fixs": + if len(arg) > 3 { + arg[3] = strings.Join(arg[3:], " ") + } + fields := strings.Split(kit.Select(m.Conf("vim", arg[0]+".meta.fields"), arg, 3), " ") + m.Confm("vim", []string{arg[0], "hash"}, func(key string, index int, value map[string]interface{}) { + m.Log("fuck", "what %v ---%v--- %v", arg, value[arg[1]], strings.HasPrefix(kit.Format(value[arg[1]]), arg[2])) + if value["sid"] = key; len(arg) == 1 || arg[1] == "" || strings.HasPrefix(kit.Format(value[arg[1]]), arg[2]) { + m.Log("fuck", "----what %v %v %v", arg, len(arg), arg[1] == "") + m.Push(fields, kit.Shortm(value, "times", "files", "sids")) + } }) - m.Sort("time", "time_r").Table() - case "tags": - m.Confm("vim", "tag", func(key string, index int, value map[string]interface{}) { - m.Push("sid", key[:6]).Push([]string{"tag", "line", "file"}, value) - }) - m.Table() - case "fixs": - m.Confm("vim", "fix", func(key string, index int, value map[string]interface{}) { - m.Push("sid", key[:6]).Push([]string{"fix", "file", "line", "text"}, value) - }) - m.Table() - case "bufs": - m.Confm("vim", "buffer", func(key string, index int, value map[string]interface{}) { - m.Push("sid", key[:6]).Push([]string{"buf", "tag", "file", "line"}, value) - }) - m.Table() - case "regs": - m.Confm("vim", "register", func(key string, index int, value map[string]interface{}) { - m.Push("sid", key[:6]).Push([]string{"reg", "text"}, value) - }) - m.Table() - case "marks": - m.Confm("vim", "mark", func(key string, index int, value map[string]interface{}) { - m.Push("sid", key[:6]).Push([]string{"mark", "line", "col", "file"}, value) - }) - m.Table() } + m.Table() return }}, - "/vim": {Name: "/vim", Help: "编辑器", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + "/vim": {Name: "/vim sid pwd cmd arg sub", Help: "编辑器", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { m.Option("arg", strings.Replace(m.Option("arg"), "XXXXXsingleXXXXX", "'", -1)) m.Option("sub", strings.Replace(m.Option("sub"), "XXXXXsingleXXXXX", "'", -1)) - if !m.Has("res") { - switch m.Option("cmd") { - case "login": - name := kit.Hashs(m.Option("pid"), m.Option("hostname"), m.Option("username")) - m.Conf("vim", []string{"editor", name}, map[string]interface{}{ - "sid": name, - "status": "login", - "time": m.Time(), - "pwd": m.Option("pwd"), - "pid": m.Option("pid"), - "pane": m.Option("pane"), - "hostname": m.Option("hostname"), - "username": m.Option("username"), - }) - m.Echo(name) - return - case "logout": - name := m.Option("sid") - m.Conf("vim", []string{"editor", name, "status"}, "logout") - m.Conf("vim", []string{"editor", name, "time"}, m.Time()) - return - - case "read", "write", "close": - file := m.Option("arg") - if !path.IsAbs(m.Option("arg")) { - file = path.Join(m.Option("pwd"), m.Option("arg")) - } - - name := kit.Hashs(file) - m.Conf("vim", []string{"opens", name, "path"}, file) - m.Conf("vim", []string{"opens", name, "time"}, m.Time()) - m.Conf("vim", []string{"opens", name, "file"}, m.Option("arg")) - m.Conf("vim", []string{"opens", name, "action"}, m.Option("cmd")) - m.Conf("vim", []string{"opens", name, "pwd"}, m.Option("pwd")) - m.Conf("vim", []string{"opens", name, "sid"}, m.Option("sid")) - return - case "insert": - m.Option("cache.store", "he.csv") - m.Grow("vim", "insert", map[string]interface{}{ - "time": m.Time(), - "sid": m.Option("sid"), - "text": m.Option("arg"), - "line": m.Option("row"), - "col": m.Option("col"), - "file": m.Option("buf"), - "pwd": m.Option("pwd"), - }) - case "exec": - m.Option("cache.store", "he.csv") - m.Grow("vim", "exec", map[string]interface{}{ - "time": m.Time(), - "sid": m.Option("sid"), - "cmd": m.Option("arg"), - "file": m.Option("buf"), - "pwd": m.Option("pwd"), - }) - case "sync": - switch m.Option("arg") { - case "fixs": - if m.Conf("vim", []string{"fix", m.Option("sid")}, ""); strings.HasPrefix(m.Option("sub"), "\nError") { - break - } - m.Split(strings.TrimPrefix(m.Option("sub"), "\n"), " ", "3", "id file text").Table(func(index int, value map[string]string) { - vs := strings.Split(kit.Format(value["file"]), ":") - m.Conf("vim", []string{"fix", m.Option("sid"), "-2"}, map[string]interface{}{ - "fix": value["id"], - "file": vs[0], - "line": vs[1], - "text": value["text"], - }) - }) - m.Set("append").Set("result") - case "tags": - m.Conf("vim", []string{"tag", m.Option("sid")}, "") - m.Split(strings.TrimPrefix(m.Option("sub"), "\n"), " ", "6").Table(func(index int, value map[string]string) { - m.Conf("vim", []string{"tag", m.Option("sid"), "-2"}, map[string]interface{}{ - "tag": value["tag"], - "line": value["line"], - "file": value["in file/text"], - }) - }) - m.Set("append").Set("result") - case "bufs": - m.Conf("vim", []string{"buffer", m.Option("sid")}, "") - m.Split(strings.TrimSpace(m.Option("sub")), " ", "5", "id tag name some line").Table(func(index int, value map[string]string) { - m.Conf("vim", []string{"buffer", m.Option("sid"), "-2"}, map[string]interface{}{ - "buf": value["id"], - "tag": value["tag"], - "file": value["name"], - "line": value["line"], - }) - }) - m.Set("append").Set("result") - case "regs": - m.Conf("vim", []string{"register", m.Option("sid")}, "") - m.Split(strings.TrimPrefix(m.Option("sub"), "\n--- Registers ---\n"), " ", "2", "name text").Table(func(index int, value map[string]string) { - m.Conf("vim", []string{"register", m.Option("sid"), "-2"}, map[string]interface{}{ - "text": strings.Replace(strings.Replace(value["text"], "^I", "\t", -1), "^J", "\n", -1), - "reg": strings.TrimPrefix(value["name"], "\""), - }) - }) - m.Set("append").Set("result") - case "marks": - m.Conf("vim", []string{"mark", m.Option("sid")}, "") - m.Split(strings.TrimPrefix(m.Option("sub"), "\n"), " ", "4").Table(func(index int, value map[string]string) { - m.Conf("vim", []string{"mark", m.Option("sid"), "-2"}, map[string]interface{}{ - "mark": value["mark"], - "line": value["line"], - "col": value["col"], - "file": value["file/text"], - }) - }) - } - return - default: - return - } - } + m.Log("info", "vim %v %v %v", m.Option("cmd"), m.Option("arg"), m.Option("sub")) switch m.Option("cmd") { - case "read", "write", "close": + case "login": + name := kit.Hashs(m.Option("pid"), m.Option("hostname"), m.Option("username")) + m.Conf("vim", []string{"editor", "hash", name}, map[string]interface{}{ + "time": m.Time(), + "status": "login", + "sid": name, + "pwd": m.Option("pwd"), + "pid": m.Option("pid"), + "pane": m.Option("pane"), + "hostname": m.Option("hostname"), + "username": m.Option("username"), + }) + m.Echo(name) + case "logout": + name := m.Option("sid") + m.Conf("vim", []string{"editor", "hash", name, "time"}, m.Time()) + m.Conf("vim", []string{"editor", "hash", name, "status"}, "logout") + + case "read", "write": + m.Grow("vim", "opens", map[string]interface{}{ + "time": m.Time(), + "sid": m.Option("sid"), + "action": m.Option("cmd"), + "file": m.Option("arg"), + "pwd": m.Option("pwd"), + }) + case "exec": + m.Grow("vim", "cmds", map[string]interface{}{ + "time": m.Time(), + "sid": m.Option("sid"), + "cmd": m.Option("arg"), + "file": m.Option("buf"), + "pwd": m.Option("pwd"), + }) + case "insert": + m.Grow("vim", "txts", map[string]interface{}{ + "time": m.Time(), + "sid": m.Option("sid"), + "text": m.Option("arg"), + "line": m.Option("row"), + "col": m.Option("col"), + "file": m.Option("buf"), + "pwd": m.Option("pwd"), + }) + + case "sync": + m.Conf("vim", []string{m.Option("arg"), "hash", m.Option("sid")}, "") + switch m.Option("arg") { + case "bufs": + m.Split(strings.TrimSpace(m.Option("sub")), " ", "5", "id tag name some line").Table(func(index int, value map[string]string) { + m.Conf("vim", []string{m.Option("arg"), "hash", m.Option("sid"), "-2"}, map[string]interface{}{ + "buf": value["id"], + "tag": value["tag"], + "file": value["name"], + "line": value["line"], + }) + }) + case "regs": + m.Split(strings.TrimPrefix(m.Option("sub"), "\n--- Registers ---\n"), " ", "2", "name text").Table(func(index int, value map[string]string) { + m.Conf("vim", []string{m.Option("arg"), "hash", m.Option("sid"), "-2"}, map[string]interface{}{ + "text": strings.Replace(strings.Replace(value["text"], "^I", "\t", -1), "^J", "\n", -1), + "reg": strings.TrimPrefix(value["name"], "\""), + }) + }) + case "marks": + m.Split(strings.TrimPrefix(m.Option("sub"), "\n"), " ", "4").Table(func(index int, value map[string]string) { + m.Conf("vim", []string{m.Option("arg"), "hash", m.Option("sid"), "-2"}, map[string]interface{}{ + "mark": value["mark"], + "line": value["line"], + "col": value["col"], + "file": value["file/text"], + }) + }) + case "tags": + m.Split(strings.TrimPrefix(m.Option("sub"), "\n"), " ", "6").Table(func(index int, value map[string]string) { + m.Conf("vim", []string{m.Option("arg"), "hash", m.Option("sid"), "-2"}, map[string]interface{}{ + "tag": value["tag"], + "line": value["line"], + "file": value["in file/text"], + }) + }) + case "fixs": + if strings.HasPrefix(m.Option("sub"), "\nError") { + break + } + m.Split(strings.TrimPrefix(m.Option("sub"), "\n"), " ", "3", "id file text").Table(func(index int, value map[string]string) { + vs := strings.Split(kit.Format(value["file"]), ":") + m.Conf("vim", []string{m.Option("arg"), "hash", m.Option("sid"), "-2"}, map[string]interface{}{ + "fix": value["id"], + "file": vs[0], + "line": vs[1], + "text": value["text"], + }) + }) + } + m.Set("append").Set("result") } return }}, diff --git a/src/examples/wiki/wiki.go b/src/examples/wiki/wiki.go index f5c7bd36..9b0dc37d 100644 --- a/src/examples/wiki/wiki.go +++ b/src/examples/wiki/wiki.go @@ -119,6 +119,17 @@ var Index = &ctx.Context{Name: "wiki", Help: "文档中心", } return }}, + "tip": {Name: "tip", Help: "便签", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + switch arg[0] { + case "show": + m.Cmdy("ssh.data", "show", arg[1], arg[2:]) + case "insert": + m.Cmdy("ssh.data", "insert", arg[1], arg[2:]) + case "update": + m.Cmdy("ssh.data", "update", arg[1], arg[2:]) + } + return + }}, }, } diff --git a/src/plugin/docker/index.shy b/src/plugin/docker/index.shy index 7cc5de1b..d0518f63 100644 --- a/src/plugin/docker/index.shy +++ b/src/plugin/docker/index.shy @@ -67,8 +67,7 @@ kit git "记录" private "ssh._route" _ "web.code.git" \ exports branch branch \ button "查看" action auto -kit vim "编辑器" private "ssh._route" _ "web.code.vim" \ - text "" name pod imports plugin_pod \ - select "bufs" name cmd values editor values opens values cmds values txts values tags values fixs values bufs values regs values marks \ +kit vim "编辑器" private "web.code.vim" \ + select "bufs" name cmd values editor values prune values opens values cmds values txts values bufs values regs values marks values tags values fixs \ button "查看" action auto diff --git a/src/toolkit/core.go b/src/toolkit/core.go index 46ce4abc..0eb1a386 100644 --- a/src/toolkit/core.go +++ b/src/toolkit/core.go @@ -285,11 +285,6 @@ func Map(v interface{}, random string, args ...interface{}) map[string]interface } switch fun := args[0].(type) { - case func(map[string]interface{}): - if len(value) == 0 { - return nil - } - fun(value) case func(int, string): for i, v := range table { fun(i, Format(v)) @@ -310,6 +305,11 @@ func Map(v interface{}, random string, args ...interface{}) map[string]interface break } } + case func(map[string]interface{}): + if len(value) == 0 { + return nil + } + fun(value) case func(int, map[string]interface{}): for i := 0; i < len(table); i++ { @@ -317,15 +317,6 @@ func Map(v interface{}, random string, args ...interface{}) map[string]interface fun(i, val) } } - case func(map[string]interface{}, int, map[string]interface{}): - meta := value["meta"].(map[string]interface{}) - list := value["list"].([]interface{}) - - for i := 0; i < len(list); i++ { - if val, ok := list[i].(map[string]interface{}); ok { - fun(meta, i, val) - } - } case func(string, []interface{}): for k, v := range value { if val, ok := v.([]interface{}); ok { @@ -377,7 +368,7 @@ func Map(v interface{}, random string, args ...interface{}) map[string]interface } } } - case func(string, map[string]interface{}, int, map[string]interface{}): + case func(key string, meta map[string]interface{}, index int, value map[string]interface{}): keys := make([]string, 0, len(value)) for k, _ := range value { keys = append(keys, k) @@ -394,6 +385,15 @@ func Map(v interface{}, random string, args ...interface{}) map[string]interface } } } + case func(meta map[string]interface{}, index int, value map[string]interface{}): + meta := value["meta"].(map[string]interface{}) + list := value["list"].([]interface{}) + + for i := 0; i < len(list); i++ { + if val, ok := list[i].(map[string]interface{}); ok { + fun(meta, i, val) + } + } } return value } diff --git a/src/toolkit/misc.go b/src/toolkit/misc.go index f36ba1b5..774383f1 100644 --- a/src/toolkit/misc.go +++ b/src/toolkit/misc.go @@ -259,3 +259,32 @@ func IndexOf(list interface{}, value string) int { } return -1 } + +func Shortm(data map[string]interface{}, keys ...string) map[string]interface{} { + for _, k := range keys { + switch k { + case "times": + ls := strings.Split(Format(data["time"]), " ") + if len(ls) > 1 { + data["times"] = ls[1] + } else { + data["times"] = data["time"] + } + case "files": + data["files"] = path.Base(Format(data["file"])) + case "sids": + data["sids"] = Short(data["sid"], 6) + } + } + return data +} +func Short(arg interface{}, l int) string { + switch val := arg.(type) { + case string: + if len(val) > l { + return val[:l] + } + return val + } + return "" +}