1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-25 16:58:06 +08:00

add yac.fun

This commit is contained in:
shaoying 2019-07-23 09:31:43 +08:00
parent 7efe28f17f
commit 4753646ff0
9 changed files with 408 additions and 105 deletions

View File

@ -38,7 +38,7 @@ syn match shyCommand "\(^\|\t\| \|$(\)[a-zA-Z0-9_\.]\+\>"
call Keys("Operator", ["new"])
call Keys("Statment", ["config", "cache"])
call Keys("Statment", ["return", "source"])
call Keys("Statment", ["if", "for", "else", "else if", "end"])
call Keys("Statment", ["if", "else", "else if", "for", "fun", "end"])
call Keys("Statment", ["let", "var"])
" context nfs
call Keys("SubCommand", ["import", "export", "load", "save"])

View File

@ -88,9 +88,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
"timer": &ctx.Config{Name: "timer", Value: map[string]interface{}{
"list": map[string]interface{}{}, "next": "",
}, Help: "定时器"},
"time": &ctx.Config{Name: "timer", Value: map[string]interface{}{
"unit": 1000, "close": "open",
}, Help: "时间参数"},
"project": &ctx.Config{Name: "project", Value: map[string]interface{}{
"github": "https://github.com/shylinux/context",
@ -384,7 +381,7 @@ func main() {
} else if e := cmd.Wait(); e != nil {
m.Echo("error: ").Echo("%s\n", e)
}
m.Conf("daemon", []string{h, "finish_time"}, time.Now().Format(m.Conf("time_format")))
m.Conf("daemon", []string{h, "finish_time"}, time.Now().Format(m.Conf("time", "format")))
})
return e
}
@ -547,7 +544,7 @@ func main() {
if len(arg) == 0 {
m.Confm("timer", "list", func(key string, timer map[string]interface{}) {
m.Add("append", "key", key)
m.Add("append", "action_time", time.Unix(0, timer["action_time"].(int64)/int64(m.Confi("time", "unit"))*1000000000).Format(m.Conf("time_format")))
m.Add("append", "action_time", time.Unix(0, timer["action_time"].(int64)/int64(m.Confi("time", "unit"))*1000000000).Format(m.Conf("time", "format")))
m.Add("append", "order", timer["order"])
m.Add("append", "time", timer["time"])
m.Add("append", "cmd", timer["cmd"])
@ -649,11 +646,12 @@ func main() {
Help: "查看时间, when: 输入的时间戳, 剩余参数是时间偏移",
Form: map[string]int{"time_format": 1, "time_close": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
format := kit.Select(m.Conf("time", "format"), m.Option("time_format"))
t, stamp := time.Now(), true
if len(arg) > 0 {
if i, e := strconv.ParseInt(arg[0], 10, 64); e == nil {
t, stamp, arg = time.Unix(int64(i/int64(m.Confi("time", "unit"))), 0), false, arg[1:]
} else if n, e := time.ParseInLocation(m.Confx("time_format"), arg[0], time.Local); e == nil {
} else if n, e := time.ParseInLocation(format, arg[0], time.Local); e == nil {
t, arg = n, arg[1:]
} else {
for _, v := range []string{"01-02", "2006-01-02", "15:04:05", "15:04"} {
@ -722,13 +720,13 @@ func main() {
}
}
m.Append("datetime", t.Format(m.Confx("time_format")))
m.Append("datetime", t.Format(format))
m.Append("timestamp", t.Unix()*int64(m.Confi("time", "unit")))
if stamp {
m.Echo("%d", t.Unix()*int64(m.Confi("time", "unit")))
} else {
m.Echo(t.Format(m.Confx("time_format")))
m.Echo(t.Format(format))
}
return
}},

View File

@ -4,5 +4,5 @@ var version = struct {
host string
self int
}{
"2019-07-22 22:15:19", "ZYB-20190522USI", 199,
"2019-07-23 08:08:38", "com.mac_1", 209,
}

View File

@ -98,7 +98,7 @@ func (m *Message) Time(arg ...interface{}) string {
}
}
str := m.Conf("time_format")
str := m.Conf("time", "format")
if len(arg) > 1 {
str = fmt.Sprintf(arg[0].(string), arg[1:]...)
} else if len(arg) > 0 {
@ -401,7 +401,7 @@ func (m *Message) Table(cbs ...interface{}) *Message {
}
//计算列宽
space := m.Confx("table_space")
space := kit.Select(m.Conf("table", "space"), m.Option("table.space"))
depth, width := 0, map[string]int{}
for _, k := range m.Meta["append"] {
if len(m.Meta[k]) > depth {
@ -420,9 +420,9 @@ func (m *Message) Table(cbs ...interface{}) *Message {
if len(cbs) > 0 {
cb = cbs[0].(func(maps map[string]string, list []string, line int) (goon bool))
} else {
row := m.Confx("table_row_sep")
col := m.Confx("table_col_sep")
compact := kit.Right(m.Confx("table_compact"))
row := kit.Select(m.Conf("table", "row_sep"), m.Option("table.row_sep"))
col := kit.Select(m.Conf("table", "col_sep"), m.Option("table.col_sep"))
compact := kit.Right(kit.Select(m.Conf("table", "compact"), m.Option("table.compact")))
cb = func(maps map[string]string, lists []string, line int) bool {
for i, v := range lists {
if k := m.Meta["append"][i]; compact {
@ -603,7 +603,7 @@ func (m *Message) Cmd(args ...interface{}) *Message {
msg.Log("cmd", "%s %s %v %v", c.Name, key, arg, msg.Meta["option"])
msg.Hand = true
x.Hand(msg, c, key, msg.Form(x, arg)...)
msg.Log("cmd", "%s %s %v %v", c.Name, key, len(msg.Meta["result"]), msg.Meta["append"])
// msg.Log("cmd", "%s %s %v %v", c.Name, key, len(msg.Meta["result"]), msg.Meta["append"])
return
target := msg.target

View File

@ -575,8 +575,8 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
}},
"note": &ctx.Command{Name: "note [model [name [type name]...]]|[index [name data...]]|[value name data...]|[name model data...]",
Form: map[string]int{"eq": 2, "begin": 2, "offset": 1, "limit": 1}, Help: "记事", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
offset := kit.Int(kit.Select(m.Conf("page_offset"), m.Option("offset")))
limit := kit.Int(kit.Select(m.Conf("page_limit"), m.Option("limit")))
offset := kit.Int(kit.Select(m.Conf("table", "offset"), m.Option("table.offset")))
limit := kit.Int(kit.Select(m.Conf("table", "limit"), m.Option("table.limit")))
// 节点列表
if len(arg) == 0 {

View File

@ -921,9 +921,10 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
}
// 语句堆栈
stack := kit.Stack{}
stack := &kit.Stack{}
stack.Push(m.Option("stack.key", "source"), m.Options("stack.run", true), m.Optioni("stack.pos", 0))
m.Optionv("bio.ctx", m.Target())
m.Optionv("bio.stack", stack)
line, bio := "", bufio.NewScanner(nfs)
for nfs.prompt(); ; nfs.prompt() {
@ -948,27 +949,11 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
// 解析数据
for i := m.Capi("ninput") - 1; i < m.Capi("ninput"); i++ {
line = m.Conf("input", []interface{}{i, "line"})
// 结束语句
if strings.TrimSpace(line) == "end" {
m.Log("stack", "pop: %v", stack.Peek().String("/"))
if stack.Pop(); m.Options("stack.run") && m.Option("stack.key") == "for" {
i = m.Optioni("stack.pos") - 1
}
frame := stack.Peek()
m.Options("stack.run", frame.Run)
m.Option("stack.key", frame.Key)
continue
}
// 跳过语句
if !m.Options("stack.run") && !strings.HasPrefix(strings.TrimSpace(line), "else") {
m.Log("stack", "skip %v", line)
continue
}
m.Optionv("input", m.Confv("input"))
m.Optioni("stack.pos", i)
// 执行语句
msg := m.Cmd("yac.parse", line+"\n").Set("option", "bio.pos", i)
msg := m.Cmd("yac.parse", line+"\n")
nfs.print(m.Conf("prompt"), line)
nfs.print(msg.Meta["result"]...)
@ -977,21 +962,6 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
m.Optionv("bio.ctx", v)
}
// 压栈语句
if msg.Has("stack.key") {
m.Log("stack", "push %v", stack.Push(
m.Option("stack.key", msg.Append("stack.key")),
m.Options("stack.run", msg.Appends("stack.run")),
m.Optioni("stack.pos", i),
).String("\\"))
}
if msg.Has("stack.run") {
m.Log("stack", "set: run = %v", m.Options("stack.run", msg.Appends("stack.run")))
}
if msg.Has("stack.else") {
m.Options("stack.else", msg.Appends("stack.else"))
}
// 跳转语句
if msg.Appends("bio.pos0") {
i = int(msg.Appendi("bio.pos0")) - 1
@ -1002,7 +972,8 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
if msg.Appends("bio.end") {
m.Copy(msg, "append")
m.Copy(msg, "result")
break
msg.Appends("bio.end", "")
return true
}
}
line = ""
@ -1060,7 +1031,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
msg.Add(field, value)
case "":
m.Log("recv", "time %v", time.Now().Format(m.Conf("time_format")))
m.Log("recv", "time %v", time.Now().Format(m.Conf("time", "format")))
if head == "detail" { // 接收请求
msg.Detail(-1, "_route")
msg.Option("remote_code", code)
@ -1210,7 +1181,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
"commit": map[string]interface{}{"args": []interface{}{"commit", "-am"}},
"branch": map[string]interface{}{"args": []interface{}{"branch", "-v"}},
"status": map[string]interface{}{"args": []interface{}{"status", "-sb"}},
"log": map[string]interface{}{"args": []interface{}{"log", "-n", "@page.limit", "--skip", "@page.offset", "pretty", "date"}},
"log": map[string]interface{}{"args": []interface{}{"log", "-n", "@table.limit", "--skip", "@table.offset", "pretty", "date"}},
"trans": map[string]interface{}{
"date": "--date=format:%m/%d %H:%M",
"pretty": "--pretty=format:%h %ad %an %s",
@ -1319,7 +1290,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
if s.IsDir() {
dir(m, p, 0, kit.Right(m.Has("dir_deep")), m.Confx("dir_type"), trip, rg,
strings.Split(m.Confx("dir_fields", strings.Join(arg[1:], " ")), " "),
m.Conf("time_format"))
m.Conf("time", "format"))
} else {
if s.Size() < int64(m.Confi("buf_size")) {
p0 := p + ".tmp0"
@ -1336,7 +1307,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
}
m.Append("file", p)
m.Append("size", s.Size())
m.Append("time", s.ModTime().Format(m.Conf("time_format")))
m.Append("time", s.ModTime().Format(m.Conf("time", "format")))
} else {
m.Append("directory", p)
}
@ -1496,7 +1467,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
n := 0
offset := kit.Int(value["offset"])
bio := bufio.NewScanner(f)
for i := 0; i < m.Optioni("page.limit") && bio.Scan(); i++ {
for i := 0; i < m.Optioni("table.limit") && bio.Scan(); i++ {
text := bio.Text()
if len(arg) == 0 || strings.Contains(text, arg[0]) {
m.Add("append", "index", index)
@ -1689,7 +1660,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
m.Option("filepath", p)
m.Option("filename", s.Name())
m.Option("filesize", s.Size())
m.Option("filetime", s.ModTime().Format(m.Conf("time_format")))
m.Option("filetime", s.ModTime().Format(m.Conf("time", "format")))
switch {
case strings.HasSuffix(arg[0], ".json"):

View File

@ -191,7 +191,7 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string, level int)
m.Log("debug", "%s %s/%d word: %d point: %d end: %d", "train", strings.Repeat("#", level), level, len(word), len(points), len(ends))
return len(word), points, ends
}
func (yac *YAC) parse(m *ctx.Message, msg *ctx.Message, page int, void int, line string, level int) (string, []string, int) {
func (yac *YAC) parse(m *ctx.Message, msg *ctx.Message, stack *kit.Stack, page int, void int, line string, level int) (string, []string, int) {
m.Log("debug", "%s %s\\%d %s(%d): %s", "parse", strings.Repeat("#", level), level, yac.name(page), page, line)
lex, hash, word := yac.lex, 0, []string{}
@ -223,7 +223,7 @@ func (yac *YAC) parse(m *ctx.Message, msg *ctx.Message, page int, void int, line
if state == nil {
for i := 0; i < m.Confi("meta", "ncell"); i++ {
if x := yac.mat[s][byte(i)]; i < m.Confi("meta", "nlang") && x != nil {
if l, w, _ := yac.parse(m, msg, i, void, line, level+1); l != line {
if l, w, _ := yac.parse(m, msg, stack, i, void, line, level+1); l != line {
line, word, state = l, append(word, w...), x
break
}
@ -242,19 +242,16 @@ func (yac *YAC) parse(m *ctx.Message, msg *ctx.Message, page int, void int, line
if hash == 0 {
word = word[:0]
} else if !m.Confs("exec", []string{yac.hand[hash], "disable"}) {
//执行命令
cmd := msg.Spawn(m.Optionv("bio.ctx"))
if cmd.Cmd(yac.hand[hash], word); cmd.Hand {
word = cmd.Meta["result"]
}
//切换模块
if v := cmd.Optionv("bio.ctx"); v != nil {
m.Optionv("bio.ctx", v)
}
for _, key := range []string{"stack.key", "stack.run", "stack.else"} {
if cmd.Has(key) {
msg.Appends(key, cmd.Appends(key))
} else if !m.Confs("exec", []string{"disable", yac.hand[hash]}) {
if stack.Peek().Run || m.Confs("exec", []string{"always", yac.hand[hash]}) {
//执行命令
cmd := msg.Spawn(m.Optionv("bio.ctx"))
if cmd.Cmd(yac.hand[hash], word); cmd.Hand {
word = cmd.Meta["result"]
}
//切换模块
if v := cmd.Optionv("bio.ctx"); v != nil {
m.Optionv("bio.ctx", v)
}
}
}
@ -336,6 +333,8 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
map[string]interface{}{"page": "stm", "hash": "for", "word": []interface{}{"for", "rep{", "exp", "}"}},
map[string]interface{}{"page": "stm", "hash": "else", "word": []interface{}{"else", "opt{", "if", "exp", "}"}},
map[string]interface{}{"page": "stm", "hash": "end", "word": []interface{}{"end"}},
map[string]interface{}{"page": "stm", "hash": "fun", "word": []interface{}{"fun", "key", "rep{", "key", "}"}},
/*
map[string]interface{}{"page": "op1", "hash": "op1", "word": []interface{}{"mul{", "-z", "-n", "}"}},
@ -359,14 +358,37 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
}, Help: "语法集合的最大数量"},
"exec": &ctx.Config{Name: "info", Value: map[string]interface{}{
"void": map[string]interface{}{"disable": true},
"num": map[string]interface{}{"disable": true},
"key": map[string]interface{}{"disable": true},
"op1": map[string]interface{}{"disable": true},
"op2": map[string]interface{}{"disable": true},
"word": map[string]interface{}{"disable": true},
"line": map[string]interface{}{"disable": true},
"disable": map[string]interface{}{
"void": true,
"num": true,
"key": true,
"op1": true,
"op2": true,
"word": true,
"line": true,
},
"always": map[string]interface{}{
"if": true,
"else": true,
"end": true,
"for": true,
},
}, Help: "嵌套层级日志的标记"},
"alias": &ctx.Config{Name: "alias", Value: map[string]interface{}{
"~": []string{"context"},
"!": []string{"message"},
":": []string{"command"},
"::": []string{"command", "list"},
"note": []string{"mdb.note"},
"pwd": []string{"nfs.pwd"},
"path": []string{"nfs.path"},
"dir": []string{"nfs.dir"},
"git": []string{"nfs.git"},
"brow": []string{"web.brow"},
"ifconfig": []string{"tcp.ifconfig"},
}, Help: "启动脚本"},
},
Commands: map[string]*ctx.Command{
"_init": &ctx.Command{Name: "_init", Help: "添加语法规则, page: 语法集合, hash: 语句类型, word: 语法模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
@ -398,10 +420,11 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
}},
"parse": &ctx.Command{Name: "parse line", Help: "解析语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
stack := m.Optionv("bio.stack").(*kit.Stack)
m.Optioni("yac.page", yac.page[m.Conf("nline")])
m.Optioni("yac.void", yac.page[m.Conf("nvoid")])
_, word, _ := yac.parse(m, m, m.Optioni("yac.page"), m.Optioni("yac.void"), arg[0], 1)
_, word, _ := yac.parse(m, m, stack, m.Optioni("yac.page"), m.Optioni("yac.void"), arg[0], 1)
m.Result(word)
}
return
@ -742,21 +765,282 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
"com": &ctx.Command{Name: "com", Help: "解析注释", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
return
}},
"cmd": &ctx.Command{Name: "cmd word", Help: "解析命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
// 解析别名
detail := []string{}
if alias, ok := m.Confv("alias", arg[0]).([]string); ok {
detail, arg = append(detail, alias...), arg[1:]
}
detail = append(detail, arg...)
// 目标切换
target := m.Optionv("bio.ctx")
if detail[0] != "context" {
defer func() { m.Optionv("bio.ctx", target) }()
}
// 解析脚本
msg := m
for k, v := range m.Confv("system", "script").(map[string]interface{}) {
if strings.HasSuffix(detail[0], "."+k) {
msg = m.Spawn(m.Optionv("bio.ctx"))
detail[0] = m.Cmdx("nfs.path", detail[0])
detail = append([]string{v.(string)}, detail...)
break
}
}
// 解析路由
if msg == m {
if routes := strings.Split(detail[0], "."); len(routes) > 1 && !strings.Contains(detail[0], ":") {
route := strings.Join(routes[:len(routes)-1], ".")
if msg = m.Find(route, false); msg == nil {
msg = m.Find(route, true)
}
if msg == nil {
m.Echo("%s not exist", route)
return
}
detail[0] = routes[len(routes)-1]
} else {
msg = m.Spawn(m.Optionv("bio.ctx"))
}
}
msg.Copy(m, "option").Copy(m, "append")
// 解析命令
args, rest := []string{}, []string{}
exports := []map[string]string{}
exec, execexec := true, false
for i := 0; i < len(detail); i++ {
switch detail[i] {
case "?":
if !kit.Right(detail[i+1]) {
return
}
i++
case "??":
exec = false
execexec = execexec || kit.Right(detail[i+1])
i++
case "<":
m.Cmdy("nfs.import", detail[i+1])
i++
case ">":
exports = append(exports, map[string]string{"file": detail[i+1]})
i++
case ">$":
if i == len(detail)-2 {
exports = append(exports, map[string]string{"cache": detail[i+1], "index": "result"})
i += 1
break
}
exports = append(exports, map[string]string{"cache": detail[i+1], "index": detail[i+2]})
i += 2
case ">@":
if i == len(detail)-2 {
exports = append(exports, map[string]string{"config": detail[i+1], "index": "result"})
i += 1
break
}
exports = append(exports, map[string]string{"config": detail[i+1], "index": detail[i+2]})
i += 2
case "|":
detail, rest = detail[:i], detail[i+1:]
case "%":
rest = append(rest, "select")
detail, rest = detail[:i], append(rest, detail[i+1:]...)
default:
args = append(args, detail[i])
}
}
if !exec && !execexec {
return
}
// 执行命令
if msg.Set("detail", args).Cmd(); !msg.Hand {
msg.Cmd("system", args)
}
if msg.Appends("bio.ctx1") {
target = msg.Target()
}
// 管道命令
if len(rest) > 0 {
pipe := msg.Spawn()
pipe.Copy(msg, "append").Copy(msg, "result").Cmd("cmd", rest)
msg.Set("append").Copy(pipe, "append")
msg.Set("result").Copy(pipe, "result")
}
// 导出结果
for _, v := range exports {
if v["file"] != "" {
m.Sess("nfs").Copy(msg, "option").Copy(msg, "append").Copy(msg, "result").Cmd("export", v["file"])
msg.Set("result")
}
if v["cache"] != "" {
if v["index"] == "result" {
m.Cap(v["cache"], strings.Join(msg.Meta["result"], ""))
} else {
m.Cap(v["cache"], msg.Append(v["index"]))
}
}
if v["config"] != "" {
if v["index"] == "result" {
m.Conf(v["config"], strings.Join(msg.Meta["result"], ""))
} else {
m.Conf(v["config"], msg.Append(v["index"]))
}
}
}
// 返回结果
m.Optionv("bio.ctx", msg.Target())
m.Set("append").Copy(msg, "append")
m.Set("result").Copy(msg, "result")
return
}},
"alias": &ctx.Command{Name: "alias [short [long...]]|[delete short]|[import module [command [alias]]]",
Help: "查看、定义或删除命令别名, short: 命令别名, long: 命令原名, delete: 删除别名, import导入模块所有命令",
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch len(arg) {
case 0:
m.Cmdy("ctx.config", "alias")
case 1:
m.Cmdy("ctx.config", "alias", arg[0])
default:
switch arg[0] {
case "delete":
alias := m.Confm("alias")
m.Echo("delete: %s %v\n", arg[1], alias[arg[1]])
delete(alias, arg[1])
case "import":
msg := m.Find(arg[1], false)
if msg == nil {
msg = m.Find(arg[1], true)
}
if msg == nil {
m.Echo("%s not exist", arg[1])
return
}
module := msg.Cap("module")
for k, _ := range msg.Target().Commands {
if len(k) > 0 && k[0] == '/' {
continue
}
if len(arg) == 2 {
m.Confv("alias", k, []string{module + "." + k})
m.Log("info", "import %s.%s", module, k)
continue
}
if key := k; k == arg[2] {
if len(arg) > 3 {
key = arg[3]
}
m.Confv("alias", key, []string{module + "." + k})
m.Log("info", "import %s.%s as %s", module, k, key)
break
}
}
default:
m.Confv("alias", arg[0], arg[1:])
m.Log("info", "%s: %v", arg[0], arg[1:])
}
}
return
}},
"if": &ctx.Command{Name: "if exp", Help: "条件语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Appends("stack.else", true)
m.Push("stack.key", arg[0])
m.Push("stack.run", m.Options("stack.run") && kit.Right(arg[1]))
if m.Appends("stack.run") {
m.Appends("stack.else", false)
stack := m.Optionv("bio.stack").(*kit.Stack)
p := stack.Push(arg[0], stack.Peek().Run && kit.Right(arg[1]), m.Optioni("stack.pos"))
m.Log("stack", "push %v", p.String("\\"))
if p.Run {
p.Done = true
}
return
}},
"else": &ctx.Command{Name: "else", Help: "条件语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
p := m.Optionv("bio.stack").(*kit.Stack).Peek()
p.Run = !p.Done && !p.Run && (len(arg) == 1 || kit.Right(arg[2]))
m.Log("stack", "set: run = %v", p.Run)
if p.Run {
p.Done = true
}
return
}},
"end": &ctx.Command{Name: "end", Help: "结束语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
p := m.Optionv("bio.stack").(*kit.Stack).Pop()
m.Log("stack", "pop: %v", p.String("/"))
switch p.Key {
case "for":
if p.Run {
m.Appendi("bio.pos0", p.Pos)
}
case "fun":
end := m.Optioni("stack.pos")
self := p.Data.(*ctx.Command)
help := []string{}
for i, v := range m.Optionv("input").([]interface{}) {
if p.Pos < i && i < end {
val := v.(map[string]interface{})
help = append(help, val["line"].(string))
}
}
self.Help = help
}
return
}},
"fun": &ctx.Command{Name: "fun", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
p := m.Optionv("bio.stack").(*kit.Stack).Push(arg[0], false, m.Optioni("stack.pos"))
m.Log("stack", "push %v", p.String("\\"))
self := &ctx.Command{Name: strings.Join(arg[1:], " "), Help: []string{"pwd", "ls"}}
self.Hand = func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
stack := &kit.Stack{}
stack.Push("fun", true, 0)
m.Optionv("bio.stack", stack)
help := self.Help.([]string)
// 解析数据
for i := 0; i < len(help); i++ {
line := help[i]
m.Optioni("stack.pos", i)
// 执行语句
msg := m.Cmd("yac.parse", line+"\n")
// 跳转语句
if msg.Appends("bio.pos0") {
i = int(msg.Appendi("bio.pos0")) - 1
msg.Append("bio.pos0", "")
}
// 结束脚本
if msg.Appends("bio.end") {
m.Copy(msg, "append")
m.Copy(msg, "result")
msg.Appends("bio.end", "")
break
}
}
return
}
m.Target().Commands[arg[1]] = self
p.Data = self
return
}},
"for": &ctx.Command{Name: "for [[express ;] condition]|[index message meta value]",
Help: "循环语句, express: 每次循环运行的表达式, condition: 循环条件, index: 索引消息, message: 消息编号, meta: value: ",
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Push("stack.key", arg[0])
m.Push("stack.run", m.Options("stack.run") && kit.Right(arg[1]))
stack := m.Optionv("bio.stack").(*kit.Stack)
m.Log("stack", "push %v", stack.Push(arg[0], stack.Peek().Run && kit.Right(arg[1]), m.Optioni("stack.pos")).String("\\"))
/*
if cli, ok := m.Target().Server.(*YAC); m.Assert(ok) {
@ -816,13 +1100,6 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
*/
return
}},
"else": &ctx.Command{Name: "else", Help: "条件语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Appends("stack.run", m.Options("stack.else") && !m.Options("stack.run") && (len(arg) == 1 || kit.Right(arg[2])))
if m.Appends("stack.run") {
m.Appends("stack.else", false)
}
return
}},
"label": &ctx.Command{Name: "label name", Help: "记录当前脚本的位置, name: 位置名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if cli, ok := m.Target().Server.(*YAC); m.Assert(ok) {

View File

@ -525,6 +525,52 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心",
}
return
}},
"tmux": &ctx.Command{Name: "tmux buffer", Help: "终端管理, buffer: 查看复制", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch arg[0] {
case "buffer":
bufs := strings.Split(m.Spawn().Cmd("system", "tmux", "list-buffers").Result(0), "\n")
n := 3
if m.Option("limit") != "" {
n = m.Optioni("limit")
}
for i, b := range bufs {
if i >= n {
break
}
bs := strings.SplitN(b, ": ", 3)
if len(bs) > 1 {
m.Add("append", "buffer", bs[0][:len(bs[0])])
m.Add("append", "length", bs[1][:len(bs[1])-6])
m.Add("append", "strings", bs[2][1:len(bs[2])-1])
}
}
if m.Option("index") == "" {
m.Echo(m.Spawn().Cmd("system", "tmux", "show-buffer").Result(0))
} else {
m.Echo(m.Spawn().Cmd("system", "tmux", "show-buffer", "-b", m.Option("index")).Result(0))
}
}
return
}},
"windows": &ctx.Command{Name: "windows", Help: "windows", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Append("nclient", strings.Count(m.Spawn().Cmd("system", "tmux", "list-clients").Result(0), "\n"))
m.Append("nsession", strings.Count(m.Spawn().Cmd("system", "tmux", "list-sessions").Result(0), "\n"))
m.Append("nwindow", strings.Count(m.Spawn().Cmd("system", "tmux", "list-windows", "-a").Result(0), "\n"))
m.Append("npane", strings.Count(m.Spawn().Cmd("system", "tmux", "list-panes", "-a").Result(0), "\n"))
m.Append("nbuf", strings.Count(m.Spawn().Cmd("system", "tmux", "list-buffers").Result(0), "\n"))
m.Append("ncmd", strings.Count(m.Spawn().Cmd("system", "tmux", "list-commands").Result(0), "\n"))
m.Append("nkey", strings.Count(m.Spawn().Cmd("system", "tmux", "list-keys").Result(0), "\n"))
m.Table()
return
}},
"notice": &ctx.Command{Name: "notice", Help: "睡眠, time(ns/us/ms/s/m/h): 时间值(纳秒/微秒/毫秒/秒/分钟/小时)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Cmd("cli.system", "osascript", "-e", fmt.Sprintf("display notification \"%s\"", kit.Select("", arg, 0)))
return
}},
},
}

View File

@ -11,25 +11,36 @@ type Frame struct {
Pos int
deep int
// list []string
Done bool
Data interface{}
}
func (f *Frame) String(meta string) string {
return fmt.Sprintf("%s%s%d %s %t", strings.Repeat("#", f.deep), meta, f.deep, f.Key, f.Run)
}
var bottom = &Frame{}
type Stack struct {
fs []*Frame
Target interface{}
fs []*Frame
}
func (s *Stack) Push(key string, run bool, pos int) *Frame {
s.fs = append(s.fs, &Frame{Key: key, Run: run, Pos: pos, deep: len(s.fs)})
return s.fs[len(s.fs)-1]
}
func (s *Stack) Peek() *Frame {
if len(s.fs) == 0 {
return bottom
}
return s.fs[len(s.fs)-1]
}
func (s *Stack) Pop() *Frame {
if len(s.fs) == 0 {
return bottom
}
f := s.fs[len(s.fs)-1]
s.fs = s.fs[:len(s.fs)-1]
return f
}
func (s *Stack) Push(key string, run bool, pos int) *Frame {
s.fs = append(s.fs, &Frame{key, run, pos, len(s.fs)})
return s.fs[len(s.fs)-1]
}
func (s *Stack) Peek() *Frame {
return s.fs[len(s.fs)-1]
}