feat: lazy load interfaces

lazy-interfaces
TorchedSammy 2022-06-19 22:31:45 -04:00
parent 226605a996
commit a707018cfa
Signed by: sammyette
GPG Key ID: 904FC49417B44DCD
4 changed files with 144 additions and 56 deletions

146
api.go
View File

@ -56,8 +56,13 @@ func hilbishLoad(rtm *rt.Runtime) (rt.Value, func()) {
modmt := rt.NewTable() modmt := rt.NewTable()
mod := rt.NewTable() mod := rt.NewTable()
interfacer := util.NewInterfacer(mod)
modIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { modIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
arg := c.Arg(1) arg := c.Arg(1)
if ifaceName, ok := arg.TryString(); ok {
interfacer.Load(ifaceName)
}
val := mod.Get(arg) val := mod.Get(arg)
return c.PushingNext1(t.Runtime, val), nil return c.PushingNext1(t.Runtime, val), nil
@ -119,68 +124,97 @@ Check out the {blue}{bold}guide{reset} command to get started.
util.SetFieldProtected(fakeMod, mod, "exitCode", rt.IntValue(0), "Exit code of last exected command") util.SetFieldProtected(fakeMod, mod, "exitCode", rt.IntValue(0), "Exit code of last exected command")
util.Document(fakeMod, "Hilbish's core API, containing submodules and functions which relate to the shell itself.") util.Document(fakeMod, "Hilbish's core API, containing submodules and functions which relate to the shell itself.")
// hilbish.userDir table interfacer.Add([]*util.Interface{
hshuser := rt.NewTable() {
Name: "userDir",
Description: "User directories to store configs and/or modules.",
Setup: func() *rt.Table {
hshuser := rt.NewTable()
util.SetField(rtm, hshuser, "config", rt.StringValue(confDir), "User's config directory") util.SetField(rtm, hshuser, "config", rt.StringValue(confDir), "User's config directory")
util.SetField(rtm, hshuser, "data", rt.StringValue(userDataDir), "XDG data directory") util.SetField(rtm, hshuser, "data", rt.StringValue(userDataDir), "XDG data directory")
util.Document(hshuser, "User directories to store configs and/or modules.")
mod.Set(rt.StringValue("userDir"), rt.TableValue(hshuser))
// hilbish.os table return hshuser
hshos := rt.NewTable() },
info, _ := osinfo.GetOSInfo() },
{
Name: "os",
Description: "OS info interface",
Setup: func() *rt.Table {
hshos := rt.NewTable()
info, _ := osinfo.GetOSInfo()
util.SetField(rtm, hshos, "family", rt.StringValue(info.Family), "Family name of the current OS") util.SetField(rtm, hshos, "family", rt.StringValue(info.Family), "Family name of the current OS")
util.SetField(rtm, hshos, "name", rt.StringValue(info.Name), "Pretty name of the current OS") util.SetField(rtm, hshos, "name", rt.StringValue(info.Name), "Pretty name of the current OS")
util.SetField(rtm, hshos, "version", rt.StringValue(info.Version), "Version of the current OS") util.SetField(rtm, hshos, "version", rt.StringValue(info.Version), "Version of the current OS")
util.Document(hshos, "OS info interface")
mod.Set(rt.StringValue("os"), rt.TableValue(hshos))
// hilbish.aliases table return hshos
aliases = newAliases() },
aliasesModule := aliases.Loader(rtm) },
util.Document(aliasesModule, "Alias inferface for Hilbish.") {
mod.Set(rt.StringValue("aliases"), rt.TableValue(aliasesModule)) Name: "aliases",
Description: "Alias management interface",
Setup: func() *rt.Table {
return aliases.Loader(rtm)
},
},
{
Name: "history",
Description: "History interface.",
Setup: func() *rt.Table {
return lr.Loader(rtm)
},
},
{
Name: "completion",
Description: "Completions interface.",
Setup: func() *rt.Table {
return completionLoader(rtm)
},
},
{
Name: "runner",
Description: "Runner/exec interface for Hilbish.",
Setup: func() *rt.Table {
return runnerModeLoader(rtm)
},
},
{
Name: "jobs",
Description: "(Background) job interface.",
Setup: func() *rt.Table {
return jobs.loader(rtm)
},
},
{
Name: "timers",
Description: "Timer interface, for control of all intervals and timeouts.",
Setup: func() *rt.Table {
return timers.loader(rtm)
},
},
{
Name: "editor",
Description: "",
Setup: func() *rt.Table {
return editorLoader(rtm)
},
},
{
Name: "version",
Description: "Version info interface.",
Setup: func() *rt.Table {
versionModule := rt.NewTable()
// hilbish.history table util.SetField(rtm, versionModule, "branch", rt.StringValue(gitBranch), "Git branch Hilbish was compiled from")
historyModule := lr.Loader(rtm) util.SetField(rtm, versionModule, "full", rt.StringValue(getVersion()), "Full version info, including release name")
mod.Set(rt.StringValue("history"), rt.TableValue(historyModule)) util.SetField(rtm, versionModule, "commit", rt.StringValue(gitCommit), "Git commit Hilbish was compiled from")
util.Document(historyModule, "History interface for Hilbish.") util.SetField(rtm, versionModule, "release", rt.StringValue(releaseName), "Release name")
// hilbish.completion table return versionModule
hshcomp := completionLoader(rtm) },
util.Document(hshcomp, "Completions interface for Hilbish.") },
mod.Set(rt.StringValue("completion"), rt.TableValue(hshcomp)) })
// hilbish.runner table
runnerModule := runnerModeLoader(rtm)
util.Document(runnerModule, "Runner/exec interface for Hilbish.")
mod.Set(rt.StringValue("runner"), rt.TableValue(runnerModule))
// hilbish.jobs table
jobs = newJobHandler()
jobModule := jobs.loader(rtm)
util.Document(jobModule, "(Background) job interface.")
mod.Set(rt.StringValue("jobs"), rt.TableValue(jobModule))
// hilbish.timers table
timers = newTimerHandler()
timerModule := timers.loader(rtm)
util.Document(timerModule, "Timer interface, for control of all intervals and timeouts.")
mod.Set(rt.StringValue("timers"), rt.TableValue(timerModule))
editorModule := editorLoader(rtm)
util.Document(editorModule, "")
mod.Set(rt.StringValue("editor"), rt.TableValue(editorModule))
versionModule := rt.NewTable()
util.SetField(rtm, versionModule, "branch", rt.StringValue(gitBranch), "Git branch Hilbish was compiled from")
util.SetField(rtm, versionModule, "full", rt.StringValue(getVersion()), "Full version info, including release name")
util.SetField(rtm, versionModule, "commit", rt.StringValue(gitCommit), "Git commit Hilbish was compiled from")
util.SetField(rtm, versionModule, "release", rt.StringValue(releaseName), "Release name")
util.Document(versionModule, "Version info interface.")
mod.Set(rt.StringValue("version"), rt.TableValue(versionModule))
return rt.TableValue(fakeMod), nil return rt.TableValue(fakeMod), nil
} }

4
lua.go
View File

@ -17,6 +17,10 @@ import (
var minimalconf = `hilbish.prompt '& '` var minimalconf = `hilbish.prompt '& '`
func luaInit() { func luaInit() {
aliases = newAliases()
jobs = newJobHandler()
timers = newTimerHandler()
l = rt.New(os.Stdout) l = rt.New(os.Stdout)
lib.LoadAll(l) lib.LoadAll(l)

View File

@ -4,6 +4,47 @@ import (
rt "github.com/arnodel/golua/runtime" rt "github.com/arnodel/golua/runtime"
) )
// Interface is a Hilbish API interface.
type Interface struct{
Name string
Description string
Setup func() *rt.Table
}
type Interfacer struct{
ifaces map[string]*Interface
loaded []string
mod *rt.Table
}
func NewInterfacer(mod *rt.Table) *Interfacer {
return &Interfacer{
ifaces: make(map[string]*Interface),
loaded: []string{},
mod: mod,
}
}
func (i *Interfacer) Add(ifaces []*Interface) {
for _, iface := range ifaces {
i.ifaces[iface.Name] = iface
}
// "claim" the name in interfacer module, to make sure user cant
// overrides (like in hilbish table)
// i.mod.Set(rt.StringValue(iface.Name), rt.BoolValue(true))
}
func (i *Interfacer) Load(name string) {
if iface := i.ifaces[name]; iface != nil && !contains(i.loaded, name) {
println(name)
mod := iface.Setup()
Document(mod, iface.Description)
i.mod.Set(rt.StringValue(iface.Name), rt.TableValue(mod))
i.loaded = append(i.loaded, iface.Name)
}
}
// LuaExport represents a Go function which can be exported to Lua. // LuaExport represents a Go function which can be exported to Lua.
type LuaExport struct { type LuaExport struct {
Function rt.GoFunctionFunc Function rt.GoFunctionFunc

View File

@ -175,3 +175,12 @@ func AbbrevHome(path string) string {
return path return path
} }
func contains(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}