1
0
forked from x/icebergs
This commit is contained in:
IT 老营长 @云轩领航-创始人 2023-05-11 13:10:22 +08:00
parent 0abc171bf8
commit cd621f13c1
27 changed files with 81 additions and 64 deletions

View File

@ -45,7 +45,7 @@ func init() {
m.Push(arg[0], m.Option(ice.MSG_USERNAME))
}
}},
mdb.CREATE: {Name: "create usernick username* userrole=void,tech userzone", Hand: func(m *ice.Message, arg ...string) {
mdb.CREATE: {Name: "create usernick username* userrole=void,tech userzone background", Hand: func(m *ice.Message, arg ...string) {
_user_create(m, m.Option(USERNAME), m.OptionSimple(USERNICK, USERROLE, USERZONE)...)
}},
}, mdb.HashAction(mdb.SHORT, USERNAME, mdb.FIELD, "time,usernick,username,userrole,userzone"), mdb.ImportantHashAction())},
@ -78,9 +78,10 @@ func UserRoot(m *ice.Message, arg ...string) *ice.Message {
userrole := kit.Select(ROOT, arg, 2)
username := kit.Select(ice.Info.Username, arg, 1)
usernick := kit.Select(UserNick(m, username), arg, 0)
background := kit.Select("usr/icons/background.jpg", UserInfo(m, username, BACKGROUND, ""))
if len(arg) > 0 {
m.Cmd(USER, mdb.CREATE, usernick, username, userrole, userzone)
ice.Info.Username = username
m.Cmd(USER, mdb.CREATE, usernick, username, userrole, userzone, background)
}
return SessAuth(m, kit.Dict(USERNICK, usernick, USERNAME, username, USERROLE, userrole))
}

View File

@ -112,10 +112,19 @@ func init() {
if h == "" && value[PID] != pid {
return
}
mdb.HashModify(m, mdb.HASH, value[mdb.HASH], STATUS, STOP)
mdb.HashModify(m, mdb.HASH, kit.Select(h, value[mdb.HASH]), STATUS, STOP)
m.Cmd(gdb.SIGNAL, gdb.KILL, value[PID])
})
}},
mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) {
h, pid := m.Option(mdb.HASH), m.Option(PID)
mdb.HashSelects(m, h).Table(func(value ice.Maps) {
if h == "" && value[PID] != pid {
return
}
mdb.HashRemove(m, kit.Select(h, value[mdb.HASH]))
})
}},
}, mdb.StatusHashAction(mdb.FIELD, "time,hash,status,pid,cmd,dir,env")), Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelect(m, arg...).Table(func(value ice.Maps) {
switch value[STATUS] {

View File

@ -42,9 +42,13 @@ func Process(m *ice.Message, key string, args ice.Any, arg ...string) {
func ProcessField(m *ice.Message, cmd string, args ice.Any, arg ...string) *ice.Message {
if cmd = kit.Select(m.ActionKey(), cmd); !kit.HasPrefixList(arg, ice.RUN) {
m.Cmdy(COMMAND, cmd).Push(ARGS, kit.Format(_process_args(m, args))).Options(ice.MSG_INDEX, m.PrefixKey()).ProcessField(ACTION, m.ActionKey(), ice.RUN)
} else {
if pod := m.Option(ice.POD); pod != "" {
m.Options(ice.POD, "").Cmdy("web.space", pod, cmd, arg[1:])
} else {
kit.If(aaa.Right(m, cmd, arg[1:]), func() { m.Cmdy(cmd, arg[1:]) })
}
}
return m
}
func ProcessFloat(m *ice.Message, arg ...string) {

View File

@ -28,8 +28,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) {
for {
select {
case <-time.Tick(t):
// m.Option(ice.LOG_DISABLE, ice.TRUE)
m.Cmd(TIMER, HAPPEN)
m.Cmd(TIMER, HAPPEN, kit.Dict(ice.LOG_DISABLE, ice.TRUE))
case s, ok := <-f.s:
if !ok {
return

View File

@ -33,6 +33,6 @@ func init() {
mdb.PRUNES: {Hand: func(m *ice.Message, arg ...string) { mdb.HashPrunesValue(m, mdb.COUNT, "0") }},
HAPPEN: {Hand: func(m *ice.Message, arg ...string) { _timer_action(m, time.Now(), arg...) }},
RESTART: {Name: "restart count=3", Hand: func(m *ice.Message, arg ...string) { mdb.HashModify(m, m.OptionSimple(mdb.HashShort(m)), arg) }},
}, mdb.HashAction(mdb.FIELD, "time,hash,name,delay,interval,count,cmd", TICK, "600s"))},
}, mdb.HashAction(mdb.FIELD, "time,hash,name,delay,interval,count,cmd", TICK, "1s"))},
})
}

View File

@ -28,7 +28,7 @@ func _tar_list(m *ice.Message, p string, cb func(*tar.Header, *tar.Reader, int))
i := 0
for r := tar.NewReader(r); ; i++ {
h, e := r.Next()
if m.Warn(e) {
if m.Warn(e) || e == io.EOF {
break
}
if h.Size == 0 {

View File

@ -114,7 +114,7 @@ func init() {
_dream_list(m).Cut("name,status,time")
case nfs.BINARY:
m.Cmdy(nfs.DIR, ice.BIN, "path,size,hashs,time", kit.Dict(nfs.DIR_TYPE, nfs.TYPE_BIN))
m.Cmd(nfs.DIR, ice.USR_LOCAL_WORK, func(value ice.Maps) {
m.Cmd(nfs.DIR, ice.USR_LOCAL_WORK, kit.Dict(nfs.DIR_TYPE, nfs.TYPE_BOTH), func(value ice.Maps) {
m.Cmdy(nfs.DIR, path.Join(value[nfs.PATH], ice.BIN), "path,size,hashs,time", kit.Dict(nfs.DIR_TYPE, nfs.TYPE_BIN))
})
default:

View File

@ -10,6 +10,7 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/log"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/tcp"
@ -136,7 +137,7 @@ func RenderPodCmd(m *ice.Message, pod, cmd string, arg ...ice.Any) {
}
func RenderCmd(m *ice.Message, cmd string, arg ...ice.Any) { RenderPodCmd(m, "", cmd, arg...) }
func renderVersion(m *ice.Message) string {
if strings.Contains(m.R.URL.RawQuery, "debug=true") {
if m.R != nil && strings.Contains(m.R.URL.RawQuery, "debug=true") || m.Option(log.DEBUG) == ice.TRUE {
return kit.Format("?_v=%v&_t=%d", ice.Info.Make.Version, time.Now().Unix())
}
return ""

View File

@ -53,6 +53,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
} else {
r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, nfs.DF)[0])
}
kit.If(path.Join(r.URL.Path) == nfs.PS, func() { r.URL.Path = kit.Select(nfs.PS, mdb.Config(m, "main")) })
if m.Logs(r.Header.Get(ice.MSG_USERIP), r.Method, r.URL.String()); r.Method == http.MethodGet {
if msg := m.Spawn(w, r).Options(ice.MSG_USERUA, r.UserAgent()); path.Join(r.URL.Path) == nfs.PS {
return !Render(RenderMain(msg), msg.Option(ice.MSG_OUTPUT), kit.List(msg.Optionv(ice.MSG_ARGS))...)
@ -156,7 +157,7 @@ const (
const SERVE = "serve"
func init() {
Index.MergeCommands(ice.Commands{"/exit": {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(ice.EXIT) }},
Index.MergeCommands(ice.Commands{
SERVE: {Name: "serve name auto start", Help: "服务器", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { cli.NodeInfo(m, ice.Info.Pathname, WORKER) }},
DOMAIN: {Hand: func(m *ice.Message, arg ...string) {

View File

@ -104,12 +104,6 @@ func init() {
}},
PP(SHARE, CACHE): {Hand: func(m *ice.Message, arg ...string) { _share_cache(m, arg...) }},
PP(SHARE, LOCAL): {Hand: func(m *ice.Message, arg ...string) { ShareLocalFile(m, arg...) }},
PP(SHARE, LOCAL, aaa.AVATAR): {Hand: func(m *ice.Message, arg ...string) {
m.RenderDownload(strings.TrimPrefix(m.Cmdv(aaa.USER, m.Option(ice.MSG_USERNAME), aaa.AVATAR), PP(SHARE, LOCAL)))
}},
PP(SHARE, LOCAL, aaa.BACKGROUND): {Hand: func(m *ice.Message, arg ...string) {
m.RenderDownload(strings.TrimPrefix(m.Cmdv(aaa.USER, m.Option(ice.MSG_USERNAME), aaa.BACKGROUND), PP(SHARE, LOCAL)))
}},
PP(SHARE, PROXY): {Hand: func(m *ice.Message, arg ...string) { _share_proxy(m) }},
PP(SHARE, TOAST): {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(SPACE, arg[0], kit.UnMarshal(m.Option(ice.ARG))) }},
})

View File

@ -209,6 +209,12 @@ func init() {
ctx.ProcessOpen(m, m.MergePod(m.Option(mdb.NAME), arg))
}
}},
"main": {Hand: func(m *ice.Message, arg ...string) {
kit.If(mdb.Config(m, "main"), func(cmd string) { RenderPodCmd(m, "", cmd) }, func() {
m.RenderResult(nfs.Template(m.Options(nfs.VERSION, renderVersion(m)), "main.html"))
})
m.Optionv(ice.MSG_ARGS, kit.Simple(m.Optionv(ice.MSG_ARGS)))
}},
nfs.PS: {Hand: func(m *ice.Message, arg ...string) { _space_fork(m) }},
}, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,type,name,text", ctx.ACTION, OPEN, REDIAL, kit.Dict("a", 3000, "b", 1000, "c", 1000)), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
if len(arg) < 2 {

View File

@ -26,6 +26,7 @@ const (
AUTO = "auto"
LIST = "list"
BACK = "back"
MAIN = "main"
BASE = "base"
CORE = "core"

View File

@ -36,7 +36,6 @@ func init() {
Index.MergeCommands(ice.Commands{
FAVOR: {Name: "favor hash auto create upload getClipboardData", Help: "收藏夹", Actions: ice.MergeActions(ice.Actions{
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
mdb.IsSearchForEach(m, arg, func() []string { return []string{web.LINK, m.CommandKey(), m.MergePodCmd("", "")} })
if arg[0] == mdb.FOREACH {
m.Cmd("", ice.OptionFields("")).Table(func(value ice.Maps) {
if arg[1] == "" || arg[1] == value[mdb.TYPE] || strings.Contains(value[mdb.TEXT], arg[1]) {

View File

@ -13,6 +13,18 @@ const IFRAME = "iframe"
func init() {
Index.MergeCommands(ice.Commands{
IFRAME: {Name: "iframe hash auto", Help: "浏览器", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
if m.Cmd("").Length() == 0 {
m.Cmd(web.SPIDE, ice.OptionFields(web.CLIENT_NAME, web.CLIENT_ORIGIN), func(value ice.Maps) {
if kit.IsIn(value[web.CLIENT_NAME], "ops", "dev", "com", "shy") {
m.Cmd("", mdb.CREATE, kit.Dict(mdb.NAME, value[web.CLIENT_NAME], web.LINK, value[web.CLIENT_ORIGIN]))
}
})
}
}},
mdb.CREATE: {Hand: func(m *ice.Message, arg ...string) {
mdb.HashCreate(m, mdb.TYPE, web.LINK, mdb.NAME, kit.ParseURL(m.Option(web.LINK)).Host, m.OptionSimple())
}},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
switch mdb.HashInputs(m, arg); arg[0] {
case mdb.NAME:
@ -40,10 +52,7 @@ func init() {
}
}},
FAVOR_TABLES: {Hand: func(m *ice.Message, arg ...string) {
switch arg[1] {
case web.LINK:
m.PushButton(IFRAME, mdb.REMOVE)
}
kit.If(arg[1] == web.LINK, func() { m.PushButton(IFRAME, mdb.REMOVE) })
}},
FAVOR_ACTION: {Hand: func(m *ice.Message, arg ...string) {
if m.Option(mdb.TYPE) != web.LINK {
@ -56,9 +65,6 @@ func init() {
ctx.ProcessField(m, m.PrefixKey(), []string{m.Option(mdb.TEXT)}, arg...)
}
}},
mdb.CREATE: {Hand: func(m *ice.Message, arg ...string) {
mdb.HashCreate(m, mdb.TYPE, web.LINK, mdb.NAME, kit.ParseURL(m.Option(web.LINK)).Host, m.OptionSimple())
}},
web.OPEN: {Hand: func(m *ice.Message, arg ...string) { ctx.ProcessOpen(m, m.Option(web.LINK)) }},
web.DREAM_CREATE: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd("", mdb.CREATE, kit.Dict(web.LINK, m.MergePod(m.Option(mdb.NAME))))
@ -71,9 +77,7 @@ func init() {
m.PushAction(web.OPEN, mdb.REMOVE).Action(mdb.CREATE, mdb.PRUNES)
}
} else {
if m.Length() == 0 {
m.Append(web.LINK, arg[0])
}
kit.If(m.Length() == 0, func() { m.Append(web.LINK, arg[0]) })
m.Action(web.FULL, web.OPEN).StatusTime(m.AppendSimple(web.LINK))
ctx.DisplayLocal(m, "")
}

View File

@ -28,8 +28,9 @@ func init() {
AppInstall(m, "Photos", web.WIKI_FEEL)
AppInstall(m, "Books", web.WIKI_WORD)
AppInstall(m, "", web.CODE_VIMER)
AppInstall(m, "", web.CHAT_FAVOR)
AppInstall(m, "", web.DREAM)
AppInstall(m, "", web.DREAM, mdb.ICON, "usr/icons/Mission Control.png")
AppInstall(m, "", web.CODE_GIT_REPOS, mdb.ICON, "usr/icons/git.jpg")
AppInstall(m, "", web.CODE_COMPILE, mdb.ICON, "usr/icons/go.png")
}},
code.INSTALL: {Hand: func(m *ice.Message, arg ...string) { AppInstall(m, arg[0], arg[1], arg[2:]...) }},
}, CmdHashAction("index,args"))},

View File

@ -12,20 +12,21 @@ import (
const DESKTOP = "desktop"
func init() {
Index.MergeCommands(ice.Commands{DESKTOP: {Actions: ice.MergeActions(ice.Actions{
Index.MergeCommands(ice.Commands{
DESKTOP: {Help: "应用桌面", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
if m.Cmd(DESKTOP).Length() == 0 {
DeskAppend(m, "Books", web.WIKI_WORD)
DeskAppend(m, "Photos", web.WIKI_FEEL)
DeskAppend(m, "Grapher", web.WIKI_DRAW)
DeskAppend(m, "Calendar", web.TEAM_PLAN, ctx.ARGS, team.MONTH)
DeskAppend(m, "", web.CHAT_FAVOR)
}
}},
web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
kit.Switch(m.Option(mdb.TYPE), kit.Simple(web.SERVER, web.WORKER), func() { m.PushButton(kit.Dict(m.CommandKey(), "桌面")) })
}},
}, web.DreamAction(), mdb.ImportantHashAction(), CmdHashAction())}})
}, web.DreamAction(), mdb.ImportantHashAction(), CmdHashAction())},
})
}
func DeskAppend(m *ice.Message, name, index string, arg ...string) {

View File

@ -15,10 +15,7 @@ func init() {
DockAppend(m, "Finder", Prefix(FINDER))
DockAppend(m, "Safari", web.CHAT_IFRAME)
DockAppend(m, "Terminal", web.CODE_XTERM)
DockAppend(m, "", web.CODE_GIT_REPOS, mdb.ICON, "usr/icons/git.jpg")
DockAppend(m, "", web.CODE_COMPILE, mdb.ICON, "usr/icons/go.png")
DockAppend(m, "", web.CODE_VIMER)
DockAppend(m, "", web.DREAM)
}
}},
}, mdb.ImportantHashAction(), CmdHashAction())}})

View File

@ -18,7 +18,7 @@ const POD = "pod"
func init() {
Index.MergeCommands(ice.Commands{
POD: {Name: "pod", Help: "节点", Actions: ice.MergeActions(ctx.CmdAction(), web.ApiAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) {
POD: {Actions: ice.MergeActions(ctx.CmdAction(), web.ApiAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 || kit.Select("", arg, 0) == "" {
web.RenderCmd(m, web.SPACE)
} else if strings.HasPrefix(m.Option(ice.MSG_USERUA), "git/") {
@ -29,7 +29,7 @@ func init() {
if m.Cmd(web.SPACE, arg[0]).Length() == 0 && nfs.Exists(m, path.Join(ice.USR_LOCAL_WORK, arg[0])) {
m.Cmd(web.DREAM, cli.START, kit.Dict(mdb.NAME, arg[0]))
}
web.RenderMain(m)
m.Cmdy(web.SPACE, arg[0], web.SPACE, ice.MAIN)
} else if arg[1] == CMD {
web.RenderPodCmd(m, arg[0], arg[2], arg[3:])
}

View File

@ -27,13 +27,16 @@ func _autogen_list(m *ice.Message) string {
}[m.Option(mdb.TYPE)])
}
func _autogen_source(m *ice.Message, main, file string) {
m.Cmd(nfs.DEFS, main, nfs.Template(m, ice.SRC_MAIN_SHY))
m.Cmd(nfs.PUSH, main, ssh.SOURCE+lex.SP+strings.TrimPrefix(file, ice.SRC+nfs.PS)+lex.NL)
// m.Cmd(nfs.DEFS, main, nfs.Template(m, ice.SRC_MAIN_SHY))
m.Cmd(nfs.DEFS, main, m.Cmdx(nfs.CAT, ice.SRC_MAIN_SHY))
m.Cmd(nfs.PUSH, main, lex.NL+ssh.SOURCE+lex.SP+strings.TrimPrefix(file, ice.SRC+nfs.PS)+lex.NL)
}
func _autogen_script(m *ice.Message, file string) { m.Cmd(nfs.DEFS, file, nfs.Template(m, "demo.shy")) }
func _autogen_module(m *ice.Message, file string) { m.Cmd(nfs.DEFS, file, nfs.Template(m, "demo.go")) }
func _autogen_import(m *ice.Message, main string, ctx string, mod string) {
m.Cmd(nfs.DEFS, main, nfs.Template(m, ice.SRC_MAIN_GO))
// m.Cmd(nfs.DEFS, main, nfs.Template(m, ice.SRC_MAIN_GO))
m.Cmd(nfs.DEFS, ice.MAKEFILE, m.Cmdx(nfs.CAT, ice.MAKEFILE))
m.Cmd(nfs.DEFS, main, m.Cmdx(nfs.CAT, ice.SRC_MAIN_GO))
begin, done, list := false, false, []string{}
m.Cmd(nfs.CAT, main, func(line string, index int) {
if begin && !done && strings.HasPrefix(line, ")") {

View File

@ -130,8 +130,13 @@ func _install_clear(m *ice.Message, arg ...string) {
})
}
func _install_trash(m *ice.Message, arg ...string) {
if m.Option(tcp.PORT) == "" {
nfs.Trash(m, m.Option(nfs.PATH))
} else {
m.Cmd(cli.DAEMON, mdb.REMOVE)
nfs.Trash(m, kit.Path(ice.USR_LOCAL_DAEMON, m.Option(tcp.PORT), m.Option(nfs.PATH)))
}
}
func _install_service(m *ice.Message, arg ...string) {
arg = kit.Split(path.Base(arg[0]), "_-.")[:1]
m.Fields(len(arg[1:]), "time,port,status,pid,cmd,dir")

View File

@ -153,7 +153,7 @@ func init() {
m.Cmdy(COMPLETE, kit.Ext(m.Option(mdb.FILE)), m.Option(nfs.FILE), m.Option(nfs.PATH))
}},
COMPILE: {Help: "编译", Hand: func(m *ice.Message, arg ...string) {
const app, _app = "usr/publish/contexts.app", "Contents/MacOS/contexts"
const app, _app = "usr/publish/Contexts.app", "Contents/MacOS/Contexts"
isWebview := func() bool { return strings.HasSuffix(os.Args[0], _app) }
cmds := []string{COMPILE, ice.SRC_MAIN_GO, ice.BIN_ICE_BIN}
if isWebview() {

View File

@ -69,9 +69,6 @@ const XTERM = "xterm"
func init() {
Index.MergeCommands(ice.Commands{
XTERM: {Name: "xterm hash auto", Help: "命令行", Actions: ice.MergeActions(ice.Actions{
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
mdb.IsSearchForEach(m, arg, func() []string { return []string{web.LINK, m.CommandKey(), m.MergePodCmd("", "")} })
}},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
switch mdb.HashInputs(m, arg); arg[0] {
case mdb.TYPE:

View File

@ -3,7 +3,6 @@ package shy
import (
_ "shylinux.com/x/icebergs/core/chat"
_ "shylinux.com/x/icebergs/core/chat/macos"
_ "shylinux.com/x/icebergs/core/chat/oauth"
_ "shylinux.com/x/icebergs/core/code"
_ "shylinux.com/x/icebergs/core/mall"
_ "shylinux.com/x/icebergs/core/team"

View File

@ -174,7 +174,7 @@ func (m *Message) FormatsMeta(w io.Writer, arg ...string) (res string) {
kit.For(m.meta[MSG_OPTION], func(i int, k string) {
kit.If(len(m.meta[k]) == 0 || len(m.meta[k]) == 1 && m.meta[k][0] == "", func() { m.meta[MSG_OPTION][i] = "" })
})
m.meta[MSG_OPTION] = kit.Filters(m.meta[MSG_OPTION], MSG_CMDS, MSG_FIELDS, MSG_SESSID, MSG_OPTS, MSG_OUTPUT, MSG_INDEX, "", "aaa.checker")
m.meta[MSG_OPTION] = kit.Filters(m.meta[MSG_OPTION], MSG_CMDS, MSG_FIELDS, MSG_SESSID, MSG_OPTS, MSG_INDEX, "", "aaa.checker")
kit.If(len(arg) == 0 && m.Option(DEBUG) == TRUE, func() { arg = []string{SP, SP, NL} })
bio, count, NL := bufio.NewWriter(w), 0, kit.Select("", arg, 2)
defer bio.Flush()

View File

@ -366,9 +366,6 @@ func init() {
m.Cmd(nfs.DIR, nfs.USR, func(value ice.Maps) { _repos_insert(m, value[nfs.PATH]) })
_repos_insert(m, kit.Path(""))
}},
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
mdb.IsSearchForEach(m, arg, func() []string { return []string{web.LINK, m.CommandKey(), m.MergePodCmd("", "")} })
}},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
switch arg[0] {
case COMMENT:

View File

@ -1,8 +1,6 @@
package misc
import (
_ "shylinux.com/x/icebergs/misc/bash"
_ "shylinux.com/x/icebergs/misc/git"
_ "shylinux.com/x/icebergs/misc/tmux"
_ "shylinux.com/x/icebergs/misc/vim"
)