mirror of https://github.com/Hilbis/Hilbish
Compare commits
22 Commits
af67bbd625
...
17a3e2c0c4
Author | SHA1 | Date |
---|---|---|
sammyette | 17a3e2c0c4 | |
sammyette | 4fdc99db88 | |
sammyette | 69fcd8e348 | |
sammyette | 0c904321f4 | |
sammyette | 4d07f166b6 | |
sammyette | f37f5b7ddc | |
sammyette | 80e6dedf9e | |
sammyette | 57a65cb039 | |
sammyette | a5f695eb98 | |
sammyette | 40a90c899b | |
sammyette | a15b1030d4 | |
sammyette | e335ef5994 | |
sammyette | 56045ed236 | |
sammyette | 8a1614ab59 | |
sammyette | cc43cb2d6e | |
sammyette | 1ba0dd183c | |
sammyette | 44d63a398a | |
sammyette | 92448eec67 | |
sammyette | 4e882b376b | |
sammyette | 5f8d942f0a | |
sammyette | 41e5e3f789 | |
sammyette | 826b0789cb |
|
@ -4,9 +4,12 @@ on:
|
|||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- v[0-9]+.*
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
|
@ -25,7 +28,7 @@ jobs:
|
|||
|
||||
- name: Set branch name
|
||||
id: branch
|
||||
run: echo "BRANCH_NAME=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> "$GITHUB_ENV"
|
||||
run: echo "BRANCH_NAME=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/*/}}" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Fix base URL
|
||||
if: env.BRANCH_NAME != 'master' && github.repository_owner == 'Rosettea'
|
||||
|
|
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -1,7 +1,8 @@
|
|||
# 🎀 Changelog
|
||||
|
||||
## Unreleased
|
||||
## [2.3.0] - 2024-07-20
|
||||
### Added
|
||||
- `commander.registry` function to get all registered commanders.
|
||||
- `fs.pipe` function to get a pair of connected files (a pipe).
|
||||
- Added an alternative 2nd parameter to `hilbish.run`, which is `streams`.
|
||||
`streams` is a table of input and output streams to run the command with.
|
||||
|
@ -28,9 +29,18 @@ hilbish.run('wc -l', {
|
|||
})
|
||||
```
|
||||
|
||||
### Changed
|
||||
- The `-S` flag will be set to Hilbish's absolute path
|
||||
- Hilbish now builds on any Unix (if any dependencies also work, which should.)
|
||||
|
||||
### Fixed
|
||||
- Fix ansi attributes causing issues with text when cut off in greenhouse
|
||||
- Fix greenhouse appearing on terminal resize
|
||||
- Fix crashes when history goes out of bounds when using history navigation
|
||||
- `exec` command should return if no arg presented
|
||||
- Commanders can now be cancelled by Ctrl-C and wont hang the shell anymore.
|
||||
See [issue 198](https://github.com/Rosettea/Hilbish/issues/198).
|
||||
- Shell interpreter can now preserve its environment and set PWD properly.
|
||||
|
||||
## [2.2.3] - 2024-04-27
|
||||
### Fixed
|
||||
|
@ -748,6 +758,7 @@ This input for example will prompt for more input to complete:
|
|||
|
||||
First "stable" release of Hilbish.
|
||||
|
||||
[2.3.0]: https://github.com/Rosettea/Hilbish/compare/v2.2.3...v2.3.0
|
||||
[2.2.3]: https://github.com/Rosettea/Hilbish/compare/v2.2.2...v2.2.3
|
||||
[2.2.2]: https://github.com/Rosettea/Hilbish/compare/v2.2.1...v2.2.2
|
||||
[2.2.1]: https://github.com/Rosettea/Hilbish/compare/v2.2.0...v2.2.1
|
||||
|
|
71
api.go
71
api.go
|
@ -39,18 +39,24 @@ var hshMod *moonlight.Table
|
|||
func hilbishLoader(mlr *moonlight.Runtime) moonlight.Value {
|
||||
var exports = map[string]moonlight.Export{
|
||||
"alias": {hlalias, 2, false},
|
||||
/*
|
||||
"appendPath": {hlappendPath, 1, false},
|
||||
/*
|
||||
"complete": {hlcomplete, 2, false},
|
||||
*/
|
||||
"cwd": {hlcwd, 0, false},
|
||||
/*
|
||||
"exec": {hlexec, 1, false},
|
||||
*/
|
||||
"runnerMode": {hlrunnerMode, 1, false},
|
||||
/*
|
||||
"goro": {hlgoro, 1, true},
|
||||
"highlighter": {hlhighlighter, 1, false},
|
||||
"hinter": {hlhinter, 1, false},
|
||||
"multiprompt": {hlmultiprompt, 1, false},
|
||||
"prependPath": {hlprependPath, 1, false},
|
||||
*/
|
||||
"prompt": {hlprompt, 1, true},
|
||||
/*
|
||||
"inputMode": {hlinputMode, 1, false},
|
||||
"interval": {hlinterval, 2, false},
|
||||
"read": {hlread, 1, false},
|
||||
|
@ -81,15 +87,15 @@ func hilbishLoader(mlr *moonlight.Runtime) moonlight.Value {
|
|||
//util.SetField(rtm, mod, "vimMode", rt.NilValue)
|
||||
|
||||
// hilbish.userDir table
|
||||
//hshuser := userDirLoader(rtm)
|
||||
//mod.Set(rt.StringValue("userDir"), rt.TableValue(hshuser))
|
||||
hshuser := userDirLoader()
|
||||
hshMod.SetField("userDir", moonlight.TableValue(hshuser))
|
||||
|
||||
// hilbish.os table
|
||||
//hshos := hshosLoader(rtm)
|
||||
//mod.Set(rt.StringValue("os"), rt.TableValue(hshos))
|
||||
|
||||
// hilbish.aliases table
|
||||
//aliases = newAliases()
|
||||
aliases = newAliases()
|
||||
//aliasesModule := aliases.Loader(rtm)
|
||||
//mod.Set(rt.StringValue("aliases"), rt.TableValue(aliasesModule))
|
||||
|
||||
|
@ -104,16 +110,16 @@ func hilbishLoader(mlr *moonlight.Runtime) moonlight.Value {
|
|||
//mod.Set(rt.StringValue("completions"), rt.TableValue(hshcomp))
|
||||
|
||||
// hilbish.runner table
|
||||
//runnerModule := runnerModeLoader(rtm)
|
||||
//mod.Set(rt.StringValue("runner"), rt.TableValue(runnerModule))
|
||||
runnerModule := runnerModeLoader(mlr)
|
||||
hshMod.SetField("runner", moonlight.TableValue(runnerModule))
|
||||
|
||||
// hilbish.jobs table
|
||||
//jobs = newJobHandler()
|
||||
jobs = newJobHandler()
|
||||
//jobModule := jobs.loader(rtm)
|
||||
//mod.Set(rt.StringValue("jobs"), rt.TableValue(jobModule))
|
||||
|
||||
// hilbish.timers table
|
||||
//timers = newTimersModule()
|
||||
timers = newTimersModule()
|
||||
//timersModule := timers.loader(rtm)
|
||||
//mod.Set(rt.StringValue("timers"), rt.TableValue(timersModule))
|
||||
|
||||
|
@ -127,8 +133,9 @@ func hilbishLoader(mlr *moonlight.Runtime) moonlight.Value {
|
|||
//util.SetField(rtm, versionModule, "release", rt.StringValue(releaseName))
|
||||
//mod.Set(rt.StringValue("version"), rt.TableValue(versionModule))
|
||||
|
||||
//pluginModule := moduleLoader(rtm)
|
||||
//mod.Set(rt.StringValue("module"), rt.TableValue(pluginModule))
|
||||
// very meta
|
||||
moduleModule := moduleLoader(mlr)
|
||||
hshMod.SetField("module", moonlight.TableValue(moduleModule))
|
||||
|
||||
return moonlight.TableValue(hshMod)
|
||||
}
|
||||
|
@ -288,10 +295,10 @@ func hlrun(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
// cwd() -> string
|
||||
// Returns the current directory of the shell.
|
||||
// #returns string
|
||||
func hlcwd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
func hlcwd(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
cwd, _ := os.Getwd()
|
||||
|
||||
return c.PushingNext1(t.Runtime, rt.StringValue(cwd)), nil
|
||||
return mlr.PushNext1(c, moonlight.StringValue(cwd)), nil
|
||||
}
|
||||
|
||||
|
||||
|
@ -344,17 +351,18 @@ hilbish.prompt '%u@%h :%d $'
|
|||
-- prompt: user@hostname: ~/directory $
|
||||
#example
|
||||
*/
|
||||
func hlprompt(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
err := c.Check1Arg()
|
||||
func hlprompt(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
err := mlr.Check1Arg(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p, err := c.StringArg(0)
|
||||
p, err := mlr.StringArg(c, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
typ := "left"
|
||||
// optional 2nd arg
|
||||
/*
|
||||
if len(c.Etc()) != 0 {
|
||||
ltyp := c.Etc()[0]
|
||||
var ok bool
|
||||
|
@ -363,6 +371,7 @@ func hlprompt(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
return nil, errors.New("bad argument to run (expected string, got " + ltyp.TypeName() + ")")
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
switch typ {
|
||||
case "left":
|
||||
|
@ -459,20 +468,21 @@ hilbish.appendPath {
|
|||
'~/.local/bin'
|
||||
}
|
||||
#example
|
||||
func hlappendPath(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.Check1Arg(); err != nil {
|
||||
*/
|
||||
func hlappendPath(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
if err := mlr.Check1Arg(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
arg := c.Arg(0)
|
||||
arg := mlr.Arg(c, 0)
|
||||
|
||||
// check if dir is a table or a string
|
||||
if arg.Type() == rt.TableType {
|
||||
util.ForEach(arg.AsTable(), func(k rt.Value, v rt.Value) {
|
||||
if v.Type() == rt.StringType {
|
||||
appendPath(v.AsString())
|
||||
if moonlight.Type(arg) == moonlight.TableType {
|
||||
moonlight.ForEach(moonlight.ToTable(arg), func(_ moonlight.Value, v moonlight.Value) {
|
||||
if moonlight.Type(v) == moonlight.StringType {
|
||||
appendPath(moonlight.ToString(v))
|
||||
}
|
||||
})
|
||||
} else if arg.Type() == rt.StringType {
|
||||
} else if moonlight.Type(arg) == moonlight.StringType {
|
||||
appendPath(arg.AsString())
|
||||
} else {
|
||||
return nil, errors.New("bad argument to appendPath (expected string or table, got " + arg.TypeName() + ")")
|
||||
|
@ -491,6 +501,7 @@ func appendPath(dir string) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// exec(cmd)
|
||||
// Replaces the currently running Hilbish instance with the supplied command.
|
||||
// This can be used to do an in-place restart.
|
||||
|
@ -742,6 +753,7 @@ func hlinputMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
|
||||
return c.Next(), nil
|
||||
}
|
||||
*/
|
||||
|
||||
// runnerMode(mode)
|
||||
// Sets the execution/runner mode for interactive Hilbish.
|
||||
|
@ -752,25 +764,24 @@ func hlinputMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
// will call it to execute user input instead.
|
||||
// Read [about runner mode](../features/runner-mode) for more information.
|
||||
// #param mode string|function
|
||||
func hlrunnerMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.Check1Arg(); err != nil {
|
||||
func hlrunnerMode(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
if err := mlr.Check1Arg(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mode := c.Arg(0)
|
||||
mode := mlr.Arg(c, 0)
|
||||
|
||||
switch mode.Type() {
|
||||
case rt.StringType:
|
||||
switch moonlight.Type(mode) {
|
||||
case moonlight.StringType:
|
||||
switch mode.AsString() {
|
||||
case "hybrid", "hybridRev", "lua", "sh": runnerMode = mode
|
||||
default: return nil, errors.New("execMode: expected either a function or hybrid, hybridRev, lua, sh. Received " + mode.AsString())
|
||||
}
|
||||
case rt.FunctionType: runnerMode = mode
|
||||
case moonlight.FunctionType: runnerMode = mode
|
||||
default: return nil, errors.New("execMode: expected either a function or hybrid, hybridRev, lua, sh. Received " + mode.TypeName())
|
||||
}
|
||||
|
||||
return c.Next(), nil
|
||||
}
|
||||
*/
|
||||
|
||||
// hinter(line, pos)
|
||||
// The command line hint handler. It gets called on every key insert to
|
||||
|
|
33
exec.go
33
exec.go
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
@ -269,8 +270,6 @@ func execCommand(cmd string, strms *streams) (io.Writer, io.Writer, error) {
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
runner, _ := interp.New()
|
||||
|
||||
if strms == nil {
|
||||
strms = &streams{}
|
||||
}
|
||||
|
@ -353,7 +352,35 @@ func execHandle(bg bool) interp.ExecHandlerFunc {
|
|||
sinks.Set(rt.StringValue("out"), rt.UserDataValue(stdout.ud))
|
||||
sinks.Set(rt.StringValue("err"), rt.UserDataValue(stderr.ud))
|
||||
|
||||
luaexitcode, err := l.Call1(rt.FunctionValue(cmd), rt.TableValue(luacmdArgs), rt.TableValue(sinks))
|
||||
//t := rt.NewThread(l)
|
||||
sig := make(chan os.Signal)
|
||||
exit := make(chan bool)
|
||||
|
||||
luaexitcode := rt.IntValue(63)
|
||||
var err error
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
exit <- true
|
||||
}
|
||||
}()
|
||||
|
||||
signal.Notify(sig, os.Interrupt)
|
||||
select {
|
||||
case <-sig:
|
||||
//t.KillContext()
|
||||
return
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
go func() {
|
||||
// TODO: call in thread function?
|
||||
//luaexitcode, err = l.CallInThread1(t, rt.FunctionValue(cmd), rt.TableValue(luacmdArgs), rt.TableValue(sinks))
|
||||
exit <- true
|
||||
}()
|
||||
|
||||
<-exit
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Error in command:\n" + err.Error())
|
||||
return interp.NewExitStatus(1)
|
||||
|
|
11
go.mod
11
go.mod
|
@ -1,6 +1,8 @@
|
|||
module hilbish
|
||||
|
||||
go 1.18
|
||||
go 1.21
|
||||
|
||||
toolchain go1.22.2
|
||||
|
||||
require (
|
||||
github.com/arnodel/golua v0.0.0-20230215163904-e0b5347eaaa1
|
||||
|
@ -9,8 +11,8 @@ require (
|
|||
github.com/maxlandon/readline v1.0.14
|
||||
github.com/pborman/getopt v1.1.0
|
||||
github.com/sahilm/fuzzy v0.1.1
|
||||
golang.org/x/sys v0.19.0
|
||||
golang.org/x/term v0.19.0
|
||||
golang.org/x/sys v0.22.0
|
||||
golang.org/x/term v0.22.0
|
||||
mvdan.cc/sh/v3 v3.8.0
|
||||
)
|
||||
|
||||
|
@ -19,13 +21,14 @@ require (
|
|||
github.com/arnodel/strftime v0.1.6 // indirect
|
||||
github.com/evilsocket/islazy v1.11.0 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||
github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
)
|
||||
|
||||
replace mvdan.cc/sh/v3 => github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20220524215627-dfd9a4fa219b
|
||||
replace mvdan.cc/sh/v3 => github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20240720131751-805c301321fd
|
||||
|
||||
replace github.com/maxlandon/readline => ./readline
|
||||
|
||||
|
|
44
go.sum
44
go.sum
|
@ -1,7 +1,7 @@
|
|||
github.com/Rosettea/golua v0.0.0-20240427174124-d239074c1749 h1:jIFnWBTsYw8s7RX7H2AOXjDVhWP3ol7OzUVaPN2KnGI=
|
||||
github.com/Rosettea/golua v0.0.0-20240427174124-d239074c1749/go.mod h1:9jzpYPiU2is0HVGCiuIOBSXdergHUW44IEjmuN1UrIE=
|
||||
github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20220524215627-dfd9a4fa219b h1:s5eDMhBk6H1BgipgLub/gv9qeyBaTuiHM0k3h2/9TSE=
|
||||
github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20220524215627-dfd9a4fa219b/go.mod h1:R09vh/04ILvP2Gj8/Z9Jd0Dh0ZIvaucowMEs6abQpWs=
|
||||
github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20240720131751-805c301321fd h1:THNle0FR2g7DMO1y3Bx1Zr7rYeiLXt3st3UkxEsMzL4=
|
||||
github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20240720131751-805c301321fd/go.mod h1:YZalN5H7WNQw3DGij6IvHsEhn5YMW7M2FCwG6gnfKy4=
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
|
||||
github.com/arnodel/strftime v0.1.6 h1:0hc0pUvk8KhEMXE+htyaOUV42zNcf/csIbjzEFCJqsw=
|
||||
|
@ -10,45 +10,37 @@ github.com/atsushinee/go-markdown-generator v0.0.0-20191121114853-83f9e1f68504 h
|
|||
github.com/atsushinee/go-markdown-generator v0.0.0-20191121114853-83f9e1f68504/go.mod h1:kHBCvAXJIatTX1pw6tLiOspjGc3MhUDRlog9yrCUS+k=
|
||||
github.com/blackfireio/osinfo v1.0.5 h1:6hlaWzfcpb87gRmznVf7wSdhysGqLRz9V/xuSdCEXrA=
|
||||
github.com/blackfireio/osinfo v1.0.5/go.mod h1:Pd987poVNmd5Wsx6PRPw4+w7kLlf9iJxoRKPtPAjOrA=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.15 h1:cKRCLMj3Ddm54bKSpemfQ8AtYFBhAI2MPmdys22fBdc=
|
||||
github.com/creack/pty v1.1.15/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
|
||||
github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/evilsocket/islazy v1.11.0 h1:B5w6uuS6ki6iDG+aH/RFeoMb8ijQh/pGabewqp2UeJ0=
|
||||
github.com/evilsocket/islazy v1.11.0/go.mod h1:muYH4x5MB5YRdkxnrOtrXLIBX6LySj1uFIqys94LKdo=
|
||||
github.com/google/renameio v1.0.1/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
|
||||
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
|
||||
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
|
||||
github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0 h1:LiZB1h0GIcudcDci2bxbqI6DXV8bF8POAnArqvRrIyw=
|
||||
github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0/go.mod h1:F/7q8/HZz+TXjlsoZQQKVYvXTZaFH4QRa3y+j1p7MS0=
|
||||
github.com/pborman/getopt v1.1.0 h1:eJ3aFZroQqq0bWmraivjQNt6Dmm5M0h2JcDW38/Azb0=
|
||||
github.com/pborman/getopt v1.1.0/go.mod h1:FxXoW1Re00sQG/+KIkuSqRL/LwQgSkv7uyac+STFsbk=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.1-0.20210923151022-86f73c517451 h1:d1PiN4RxzIFXCJTvRkvSkKqwtRAl5ZV4lATKtQI0B7I=
|
||||
github.com/rogpeppe/go-internal v1.8.1-0.20210923151022-86f73c517451/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA=
|
||||
github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210925032602-92d5a993a665/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20210916214954-140adaaadfaf/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
||||
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
|
||||
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
mvdan.cc/editorconfig v0.2.0/go.mod h1:lvnnD3BNdBYkhq+B4uBuFFKatfp02eB6HixDvEz91C0=
|
||||
|
|
|
@ -26,12 +26,12 @@ this function will set the user prompt.
|
|||
package bait
|
||||
|
||||
import (
|
||||
"errors"
|
||||
//"errors"
|
||||
|
||||
"hilbish/moonlight"
|
||||
"hilbish/util"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"github.com/arnodel/golua/lib/packagelib"
|
||||
)
|
||||
|
||||
type listenerType int
|
||||
|
@ -48,26 +48,21 @@ type Listener struct{
|
|||
typ listenerType
|
||||
once bool
|
||||
caller func(...interface{})
|
||||
luaCaller *rt.Closure
|
||||
luaCaller *moonlight.Closure
|
||||
}
|
||||
|
||||
type Bait struct{
|
||||
Loader packagelib.Loader
|
||||
recoverer Recoverer
|
||||
handlers map[string][]*Listener
|
||||
rtm *rt.Runtime
|
||||
rtm *moonlight.Runtime
|
||||
}
|
||||
|
||||
// New creates a new Bait instance.
|
||||
func New(rtm *rt.Runtime) *Bait {
|
||||
func New(rtm *moonlight.Runtime) *Bait {
|
||||
b := &Bait{
|
||||
handlers: make(map[string][]*Listener),
|
||||
rtm: rtm,
|
||||
}
|
||||
b.Loader = packagelib.Loader{
|
||||
Load: b.loaderFunc,
|
||||
Name: "bait",
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
@ -88,16 +83,16 @@ func (b *Bait) Emit(event string, args ...interface{}) {
|
|||
|
||||
if handle.typ == luaListener {
|
||||
funcVal := rt.FunctionValue(handle.luaCaller)
|
||||
var luaArgs []rt.Value
|
||||
var luaArgs []moonlight.Value
|
||||
for _, arg := range args {
|
||||
var luarg rt.Value
|
||||
var luarg moonlight.Value
|
||||
switch arg.(type) {
|
||||
case rt.Value: luarg = arg.(rt.Value)
|
||||
case moonlight.Value: luarg = arg.(moonlight.Value)
|
||||
default: luarg = rt.AsValue(arg)
|
||||
}
|
||||
luaArgs = append(luaArgs, luarg)
|
||||
}
|
||||
_, err := rt.Call1(b.rtm.MainThread(), funcVal, luaArgs...)
|
||||
_, err := b.rtm.Call1(funcVal, luaArgs...)
|
||||
if err != nil {
|
||||
if event != "error" {
|
||||
b.Emit("error", event, handle.luaCaller, err.Error())
|
||||
|
@ -129,8 +124,8 @@ func (b *Bait) On(event string, handler func(...interface{})) *Listener {
|
|||
}
|
||||
|
||||
// OnLua adds a Lua function handler for an event.
|
||||
func (b *Bait) OnLua(event string, handler *rt.Closure) *Listener {
|
||||
listener :=&Listener{
|
||||
func (b *Bait) OnLua(event string, handler *moonlight.Closure) *Listener {
|
||||
listener := &Listener{
|
||||
typ: luaListener,
|
||||
luaCaller: handler,
|
||||
}
|
||||
|
@ -212,18 +207,20 @@ func (b *Bait) callRecoverer(event string, handler *Listener, err interface{}) {
|
|||
b.recoverer(event, handler, err)
|
||||
}
|
||||
|
||||
func (b *Bait) loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
|
||||
exports := map[string]util.LuaExport{
|
||||
"catch": util.LuaExport{b.bcatch, 2, false},
|
||||
func (b *Bait) Loader(rtm *moonlight.Runtime) moonlight.Value {
|
||||
exports := map[string]moonlight.Export{
|
||||
"catch": {b.bcatch, 2, false},
|
||||
/*
|
||||
"catchOnce": util.LuaExport{b.bcatchOnce, 2, false},
|
||||
"throw": util.LuaExport{b.bthrow, 1, true},
|
||||
"release": util.LuaExport{b.brelease, 2, false},
|
||||
"hooks": util.LuaExport{b.bhooks, 1, false},
|
||||
*/
|
||||
}
|
||||
mod := rt.NewTable()
|
||||
util.SetExports(rtm, mod, exports)
|
||||
mod := moonlight.NewTable()
|
||||
rtm.SetExports(mod, exports)
|
||||
|
||||
return rt.TableValue(mod), nil
|
||||
return moonlight.TableValue(mod)
|
||||
}
|
||||
|
||||
func handleHook(t *rt.Thread, c *rt.GoCont, name string, catcher *rt.Closure, args ...interface{}) {
|
||||
|
@ -258,8 +255,8 @@ bait.catch('hilbish.exit', function()
|
|||
end)
|
||||
#example
|
||||
*/
|
||||
func (b *Bait) bcatch(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
name, catcher, err := util.HandleStrCallback(t, c)
|
||||
func (b *Bait) bcatch(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
name, catcher, err := util.HandleStrCallback(mlr, c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -269,6 +266,7 @@ func (b *Bait) bcatch(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
return c.Next(), nil
|
||||
}
|
||||
|
||||
/*
|
||||
// catchOnce(name, cb)
|
||||
// Catches an event, but only once. This will remove the hook immediately after it runs for the first time.
|
||||
// #param name string The name of the event
|
||||
|
@ -315,6 +313,7 @@ func (b *Bait) bhooks(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
|
||||
return c.PushingNext1(t.Runtime, rt.TableValue(luaHandlers)), nil
|
||||
}
|
||||
*/
|
||||
|
||||
// release(name, catcher)
|
||||
// Removes the `catcher` for the event with `name`.
|
||||
|
@ -333,6 +332,7 @@ bait.release('event', hookCallback)
|
|||
-- and now hookCallback will no longer be ran for the event.
|
||||
#example
|
||||
*/
|
||||
/*
|
||||
func (b *Bait) brelease(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
name, catcher, err := util.HandleStrCallback(t, c)
|
||||
if err != nil {
|
||||
|
@ -343,6 +343,7 @@ func (b *Bait) brelease(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
|
||||
return c.Next(), nil
|
||||
}
|
||||
*/
|
||||
|
||||
// throw(name, ...args)
|
||||
// #param name string The name of the hook.
|
||||
|
@ -358,6 +359,7 @@ bait.catch('gretting', function(greetTo)
|
|||
end)
|
||||
#example
|
||||
*/
|
||||
/*
|
||||
func (b *Bait) bthrow(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.Check1Arg(); err != nil {
|
||||
return nil, err
|
||||
|
@ -374,3 +376,4 @@ func (b *Bait) bthrow(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
|
||||
return c.Next(), nil
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -33,42 +33,37 @@ This sink is for writing errors, as the name would suggest.
|
|||
package commander
|
||||
|
||||
import (
|
||||
"hilbish/moonlight"
|
||||
"hilbish/util"
|
||||
"hilbish/golibs/bait"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"github.com/arnodel/golua/lib/packagelib"
|
||||
)
|
||||
|
||||
type Commander struct{
|
||||
Events *bait.Bait
|
||||
Loader packagelib.Loader
|
||||
Commands map[string]*rt.Closure
|
||||
}
|
||||
|
||||
func New(rtm *rt.Runtime) *Commander {
|
||||
func New(rtm *moonlight.Runtime) *Commander {
|
||||
c := &Commander{
|
||||
Events: bait.New(rtm),
|
||||
Commands: make(map[string]*rt.Closure),
|
||||
}
|
||||
c.Loader = packagelib.Loader{
|
||||
Load: c.loaderFunc,
|
||||
Name: "commander",
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Commander) loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
|
||||
exports := map[string]util.LuaExport{
|
||||
"register": util.LuaExport{c.cregister, 2, false},
|
||||
"deregister": util.LuaExport{c.cderegister, 1, false},
|
||||
"registry": util.LuaExport{c.cregistry, 0, false},
|
||||
func (c *Commander) Loader(rtm *moonlight.Runtime) moonlight.Value {
|
||||
exports := map[string]moonlight.Export{
|
||||
"register": {c.cregister, 2, false},
|
||||
"deregister": {c.cderegister, 1, false},
|
||||
"registry": {c.cregistry, 0, false},
|
||||
}
|
||||
mod := rt.NewTable()
|
||||
util.SetExports(rtm, mod, exports)
|
||||
mod := moonlight.NewTable()
|
||||
rtm.SetExports(mod, exports)
|
||||
|
||||
return rt.TableValue(mod), nil
|
||||
return moonlight.TableValue(mod)
|
||||
}
|
||||
|
||||
// register(name, cb)
|
||||
|
@ -88,8 +83,8 @@ commander.register('hello', function(args, sinks)
|
|||
end)
|
||||
#example
|
||||
*/
|
||||
func (c *Commander) cregister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) {
|
||||
cmdName, cmd, err := util.HandleStrCallback(t, ct)
|
||||
func (c *Commander) cregister(mlr *moonlight.Runtime, ct *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
cmdName, cmd, err := util.HandleStrCallback(mlr, ct)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -102,11 +97,11 @@ func (c *Commander) cregister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) {
|
|||
// deregister(name)
|
||||
// Removes the named command. Note that this will only remove Commander-registered commands.
|
||||
// #param name string Name of the command to remove.
|
||||
func (c *Commander) cderegister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) {
|
||||
if err := ct.Check1Arg(); err != nil {
|
||||
func (c *Commander) cderegister(mlr *moonlight.Runtime, ct *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
if err := mlr.Check1Arg(ct); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmdName, err := ct.StringArg(0)
|
||||
cmdName, err := mlr.StringArg(ct, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -120,14 +115,14 @@ func (c *Commander) cderegister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) {
|
|||
// Returns all registered commanders. Returns a list of tables with the following keys:
|
||||
// - `exec`: The function used to run the commander. Commanders require args and sinks to be passed.
|
||||
// #returns table
|
||||
func (c *Commander) cregistry(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) {
|
||||
registryLua := rt.NewTable()
|
||||
func (c *Commander) cregistry(mlr *moonlight.Runtime, ct *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
registryLua := moonlight.NewTable()
|
||||
for cmdName, cmd := range c.Commands {
|
||||
cmdTbl := rt.NewTable()
|
||||
cmdTbl.Set(rt.StringValue("exec"), rt.FunctionValue(cmd))
|
||||
cmdTbl := moonlight.NewTable()
|
||||
cmdTbl.SetField("exec", rt.FunctionValue(cmd))
|
||||
|
||||
registryLua.Set(rt.StringValue(cmdName), rt.TableValue(cmdTbl))
|
||||
registryLua.SetField(cmdName, moonlight.TableValue(cmdTbl))
|
||||
}
|
||||
|
||||
return ct.PushingNext1(t.Runtime, rt.TableValue(registryLua)), nil
|
||||
return mlr.PushNext1(ct, moonlight.TableValue(registryLua)), nil
|
||||
}
|
||||
|
|
|
@ -14,37 +14,51 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"hilbish/moonlight"
|
||||
"hilbish/util"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"github.com/arnodel/golua/lib/packagelib"
|
||||
"github.com/arnodel/golua/lib/iolib"
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
)
|
||||
|
||||
var Loader = packagelib.Loader{
|
||||
Load: loaderFunc,
|
||||
Name: "fs",
|
||||
type fs struct{
|
||||
runner *interp.Runner
|
||||
}
|
||||
|
||||
func loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
|
||||
exports := map[string]util.LuaExport{
|
||||
"cd": util.LuaExport{fcd, 1, false},
|
||||
"mkdir": util.LuaExport{fmkdir, 2, false},
|
||||
"stat": util.LuaExport{fstat, 1, false},
|
||||
"readdir": util.LuaExport{freaddir, 1, false},
|
||||
"abs": util.LuaExport{fabs, 1, false},
|
||||
"basename": util.LuaExport{fbasename, 1, false},
|
||||
"dir": util.LuaExport{fdir, 1, false},
|
||||
"glob": util.LuaExport{fglob, 1, false},
|
||||
"join": util.LuaExport{fjoin, 0, true},
|
||||
"pipe": util.LuaExport{fpipe, 0, false},
|
||||
func New(runner *interp.Runner) *fs {
|
||||
return &fs{
|
||||
runner: runner,
|
||||
}
|
||||
mod := rt.NewTable()
|
||||
util.SetExports(rtm, mod, exports)
|
||||
mod.Set(rt.StringValue("pathSep"), rt.StringValue(string(os.PathSeparator)))
|
||||
mod.Set(rt.StringValue("pathListSep"), rt.StringValue(string(os.PathListSeparator)))
|
||||
}
|
||||
|
||||
return rt.TableValue(mod), nil
|
||||
func (f *fs) Loader(rtm *moonlight.Runtime) moonlight.Value {
|
||||
exports := map[string]moonlight.Export{
|
||||
/*
|
||||
"cd": util.LuaExport{f.fcd, 1, false},
|
||||
"mkdir": util.LuaExport{f.fmkdir, 2, false},
|
||||
"stat": util.LuaExport{f.fstat, 1, false},
|
||||
*/
|
||||
"readdir": {f.freaddir, 1, false},
|
||||
/*
|
||||
"abs": util.LuaExport{f.fabs, 1, false},
|
||||
"basename": util.LuaExport{f.fbasename, 1, false},
|
||||
*/
|
||||
"dir": {f.fdir, 1, false},
|
||||
/*
|
||||
"glob": util.LuaExport{f.fglob, 1, false},
|
||||
"join": util.LuaExport{f.fjoin, 0, true},
|
||||
"pipe": util.LuaExport{f.fpipe, 0, false},
|
||||
*/
|
||||
}
|
||||
|
||||
mod := moonlight.NewTable()
|
||||
rtm.SetExports(mod, exports)
|
||||
|
||||
mod.SetField("pathSep", rt.StringValue(string(os.PathSeparator)))
|
||||
mod.SetField("pathListSep", rt.StringValue(string(os.PathListSeparator)))
|
||||
|
||||
return moonlight.TableValue(mod)
|
||||
}
|
||||
|
||||
// abs(path) -> string
|
||||
|
@ -52,7 +66,7 @@ func loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
|
|||
// This can be used to resolve short paths like `..` to `/home/user`.
|
||||
// #param path string
|
||||
// #returns string
|
||||
func fabs(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
func (f *fs) fabs(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
path, err := c.StringArg(0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -72,7 +86,7 @@ func fabs(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
// `.` will be returned.
|
||||
// #param path string Path to get the base name of.
|
||||
// #returns string
|
||||
func fbasename(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
func (f *fs) fbasename(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.Check1Arg(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -87,7 +101,7 @@ func fbasename(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
// cd(dir)
|
||||
// Changes Hilbish's directory to `dir`.
|
||||
// #param dir string Path to change directory to.
|
||||
func fcd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
func (f *fs) fcd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.Check1Arg(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -101,6 +115,7 @@ func fcd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
interp.Dir(path)(f.runner)
|
||||
|
||||
return c.Next(), err
|
||||
}
|
||||
|
@ -110,16 +125,17 @@ func fcd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
// `~/Documents/doc.txt` then this function will return `~/Documents`.
|
||||
// #param path string Path to get the directory for.
|
||||
// #returns string
|
||||
func fdir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.Check1Arg(); err != nil {
|
||||
func (f *fs) fdir(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
if err := mlr.Check1Arg(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
path, err := c.StringArg(0)
|
||||
path, err := mlr.StringArg(c, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c.PushingNext(t.Runtime, rt.StringValue(filepath.Dir(path))), nil
|
||||
next := mlr.PushNext1(c, moonlight.StringValue(filepath.Dir(path)))
|
||||
return next, nil
|
||||
}
|
||||
|
||||
// glob(pattern) -> matches (table)
|
||||
|
@ -141,7 +157,7 @@ print(matches)
|
|||
-- -> {'init.lua', 'code.lua'}
|
||||
#example
|
||||
*/
|
||||
func fglob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
func (f *fs) fglob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.Check1Arg(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -175,7 +191,7 @@ print(fs.join(hilbish.userDir.config, 'hilbish'))
|
|||
-- -> '/home/user/.config/hilbish' on Linux
|
||||
#example
|
||||
*/
|
||||
func fjoin(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
func (f *fs) fjoin(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
strs := make([]string, len(c.Etc()))
|
||||
for i, v := range c.Etc() {
|
||||
if v.Type() != rt.StringType {
|
||||
|
@ -202,7 +218,7 @@ func fjoin(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
fs.mkdir('./foo/bar', true)
|
||||
#example
|
||||
*/
|
||||
func fmkdir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
func (f *fs) fmkdir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.CheckNArgs(2); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -233,7 +249,7 @@ func fmkdir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
// The type returned is a Lua file, same as returned from `io` functions.
|
||||
// #returns File
|
||||
// #returns File
|
||||
func fpipe(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
func (f *fs) fpipe(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
rf, wf, err := os.Pipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -248,16 +264,16 @@ func fpipe(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
// Returns a list of all files and directories in the provided path.
|
||||
// #param dir string
|
||||
// #returns table
|
||||
func freaddir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.Check1Arg(); err != nil {
|
||||
func (f *fs) freaddir(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
if err := mlr.Check1Arg(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dir, err := c.StringArg(0)
|
||||
dir, err := mlr.StringArg(c, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dir = util.ExpandHome(dir)
|
||||
names := rt.NewTable()
|
||||
names := moonlight.NewTable()
|
||||
|
||||
dirEntries, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
|
@ -267,7 +283,7 @@ func freaddir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
names.Set(rt.IntValue(int64(i + 1)), rt.StringValue(entry.Name()))
|
||||
}
|
||||
|
||||
return c.PushingNext1(t.Runtime, rt.TableValue(names)), nil
|
||||
return mlr.PushNext1(c, moonlight.TableValue(names)), nil
|
||||
}
|
||||
|
||||
// stat(path) -> {}
|
||||
|
@ -296,7 +312,7 @@ Would print the following:
|
|||
]]--
|
||||
#example
|
||||
*/
|
||||
func fstat(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
func (f *fs) fstat(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.Check1Arg(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -5,52 +5,47 @@ package terminal
|
|||
import (
|
||||
"os"
|
||||
|
||||
"hilbish/util"
|
||||
"hilbish/moonlight"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"github.com/arnodel/golua/lib/packagelib"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
var termState *term.State
|
||||
var Loader = packagelib.Loader{
|
||||
Load: loaderFunc,
|
||||
Name: "terminal",
|
||||
}
|
||||
|
||||
func loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
|
||||
exports := map[string]util.LuaExport{
|
||||
"setRaw": util.LuaExport{termsetRaw, 0, false},
|
||||
"restoreState": util.LuaExport{termrestoreState, 0, false},
|
||||
"size": util.LuaExport{termsize, 0, false},
|
||||
"saveState": util.LuaExport{termsaveState, 0, false},
|
||||
func Loader(rtm *moonlight.Runtime) moonlight.Value {
|
||||
exports := map[string]moonlight.Export{
|
||||
"setRaw": {termsetRaw, 0, false},
|
||||
"restoreState": {termrestoreState, 0, false},
|
||||
"size": {termsize, 0, false},
|
||||
"saveState": {termsaveState, 0, false},
|
||||
}
|
||||
|
||||
mod := rt.NewTable()
|
||||
util.SetExports(rtm, mod, exports)
|
||||
mod := moonlight.NewTable()
|
||||
rtm.SetExports(mod, exports)
|
||||
|
||||
return rt.TableValue(mod), nil
|
||||
return moonlight.TableValue(mod)
|
||||
}
|
||||
|
||||
// size()
|
||||
// Gets the dimensions of the terminal. Returns a table with `width` and `height`
|
||||
// NOTE: The size refers to the amount of columns and rows of text that can fit in the terminal.
|
||||
func termsize(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
func termsize(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
w, h, err := term.GetSize(int(os.Stdin.Fd()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dimensions := rt.NewTable()
|
||||
dimensions := moonlight.NewTable()
|
||||
dimensions.Set(rt.StringValue("width"), rt.IntValue(int64(w)))
|
||||
dimensions.Set(rt.StringValue("height"), rt.IntValue(int64(h)))
|
||||
|
||||
return c.PushingNext1(t.Runtime, rt.TableValue(dimensions)), nil
|
||||
return mlr.PushNext1(c, moonlight.TableValue(dimensions)), nil
|
||||
}
|
||||
|
||||
// saveState()
|
||||
// Saves the current state of the terminal.
|
||||
func termsaveState(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
func termsaveState(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
state, err := term.GetState(int(os.Stdin.Fd()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -62,7 +57,7 @@ func termsaveState(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
|
||||
// restoreState()
|
||||
// Restores the last saved state of the terminal
|
||||
func termrestoreState(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
func termrestoreState(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
err := term.Restore(int(os.Stdin.Fd()), termState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -73,7 +68,7 @@ func termrestoreState(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
|
||||
// setRaw()
|
||||
// Puts the terminal into raw mode.
|
||||
func termsetRaw(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
func termsetRaw(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
_, err := term.MakeRaw(int(os.Stdin.Fd()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
23
lua.go
23
lua.go
|
@ -5,10 +5,10 @@ import (
|
|||
"os"
|
||||
|
||||
//"hilbish/util"
|
||||
//"hilbish/golibs/bait"
|
||||
//"hilbish/golibs/commander"
|
||||
//"hilbish/golibs/fs"
|
||||
//"hilbish/golibs/terminal"
|
||||
"hilbish/golibs/bait"
|
||||
"hilbish/golibs/commander"
|
||||
"hilbish/golibs/fs"
|
||||
"hilbish/golibs/terminal"
|
||||
|
||||
"hilbish/moonlight"
|
||||
)
|
||||
|
@ -24,21 +24,21 @@ func luaInit() {
|
|||
l.DoString("hilbish = require 'hilbish'")
|
||||
|
||||
// Add fs and terminal module module to Lua
|
||||
/*
|
||||
lib.LoadLibs(l, fs.Loader)
|
||||
lib.LoadLibs(l, terminal.Loader)
|
||||
f := fs.New(runner)
|
||||
l.LoadLibrary(f.Loader, "fs")
|
||||
|
||||
l.LoadLibrary(terminal.Loader, "terminal")
|
||||
|
||||
cmds = commander.New(l)
|
||||
lib.LoadLibs(l, cmds.Loader)
|
||||
l.LoadLibrary(cmds.Loader, "commander")
|
||||
|
||||
hooks = bait.New(l)
|
||||
hooks.SetRecoverer(func(event string, handler *bait.Listener, err interface{}) {
|
||||
fmt.Println("Error in `error` hook handler:", err)
|
||||
hooks.Off(event, handler)
|
||||
})
|
||||
|
||||
lib.LoadLibs(l, hooks.Loader)
|
||||
|
||||
l.LoadLibrary(hooks.Loader, "bait")
|
||||
/*
|
||||
// Add Ctrl-C handler
|
||||
hooks.On("signal.sigint", func(...interface{}) {
|
||||
if !interactive {
|
||||
|
@ -54,6 +54,7 @@ func luaInit() {
|
|||
// Add more paths that Lua can require from
|
||||
_, err := l.DoString("package.path = package.path .. " + requirePaths)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintln(os.Stderr, "Could not add Hilbish require paths! Libraries will be missing. This shouldn't happen.")
|
||||
}
|
||||
|
||||
|
|
3
main.go
3
main.go
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/pborman/getopt"
|
||||
"github.com/maxlandon/readline"
|
||||
"golang.org/x/term"
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -38,9 +39,11 @@ var (
|
|||
cmds *commander.Commander
|
||||
defaultConfPath string
|
||||
defaultHistPath string
|
||||
runner *interp.Runner
|
||||
)
|
||||
|
||||
func main() {
|
||||
runner, _ = interp.New()
|
||||
curuser, _ = user.Current()
|
||||
homedir := curuser.HomeDir
|
||||
confDir, _ = os.UserConfigDir()
|
||||
|
|
24
module.go
24
module.go
|
@ -3,9 +3,7 @@ package main
|
|||
import (
|
||||
"plugin"
|
||||
|
||||
"hilbish/util"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"hilbish/moonlight"
|
||||
)
|
||||
|
||||
// #interface module
|
||||
|
@ -46,13 +44,13 @@ func Loader(rtm *rt.Runtime) rt.Value {
|
|||
This can be compiled with `go build -buildmode=plugin plugin.go`.
|
||||
If you attempt to require and print the result (`print(require 'plugin')`), it will show "hello world!"
|
||||
*/
|
||||
func moduleLoader(rtm *rt.Runtime) *rt.Table {
|
||||
exports := map[string]util.LuaExport{
|
||||
func moduleLoader(mlr *moonlight.Runtime) *moonlight.Table {
|
||||
exports := map[string]moonlight.Export{
|
||||
"load": {moduleLoad, 2, false},
|
||||
}
|
||||
|
||||
mod := rt.NewTable()
|
||||
util.SetExports(rtm, mod, exports)
|
||||
mod := moonlight.NewTable()
|
||||
mlr.SetExports(mod, exports)
|
||||
|
||||
return mod
|
||||
}
|
||||
|
@ -62,12 +60,12 @@ func moduleLoader(rtm *rt.Runtime) *rt.Table {
|
|||
// Loads a module at the designated `path`.
|
||||
// It will throw if any error occurs.
|
||||
// #param path string
|
||||
func moduleLoad(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.CheckNArgs(1); err != nil {
|
||||
func moduleLoad(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
if err := mlr.Check1Arg(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
path, err := c.StringArg(0)
|
||||
path, err := mlr.StringArg(c, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -82,12 +80,12 @@ func moduleLoad(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
loader, ok := value.(func(*rt.Runtime) rt.Value)
|
||||
loader, ok := value.(func(*moonlight.Runtime) moonlight.Value)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
val := loader(t.Runtime)
|
||||
val := loader(mlr)
|
||||
|
||||
return c.PushingNext1(t.Runtime, val), nil
|
||||
return mlr.PushNext1(c, val), nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package moonlight
|
||||
|
||||
import (
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
||||
type GoCont struct{
|
||||
cont *rt.GoCont
|
||||
thread *rt.Thread
|
||||
}
|
||||
type Cont = rt.Cont
|
||||
type Closure = rt.Closure
|
||||
|
||||
func (gc *GoCont) Next() Cont {
|
||||
return gc.cont.Next()
|
||||
}
|
|
@ -6,20 +6,32 @@ import (
|
|||
|
||||
type GoFunctionFunc = rt.GoFunctionFunc
|
||||
|
||||
type GoCont = rt.GoCont
|
||||
type Cont = rt.Cont
|
||||
|
||||
func (mlr *Runtime) CheckNArgs(c *GoCont, num int) error {
|
||||
return c.CheckNArgs(num)
|
||||
return c.cont.CheckNArgs(num)
|
||||
}
|
||||
|
||||
func (mlr *Runtime) Check1Arg(c *GoCont) error {
|
||||
return c.cont.CheckNArgs(1)
|
||||
}
|
||||
|
||||
func (mlr *Runtime) StringArg(c *GoCont, num int) (string, error) {
|
||||
return c.StringArg(num)
|
||||
return c.cont.StringArg(num)
|
||||
}
|
||||
|
||||
func (mlr *Runtime) ClosureArg(c *GoCont, num int) (*Closure, error) {
|
||||
return c.cont.ClosureArg(num)
|
||||
}
|
||||
|
||||
func (mlr *Runtime) Arg(c *GoCont, num int) Value {
|
||||
return c.cont.Arg(num)
|
||||
}
|
||||
|
||||
func (mlr *Runtime) GoFunction(fun GoToLuaFunc) rt.GoFunctionFunc {
|
||||
return func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
gocont := GoCont(*c)
|
||||
gocont := GoCont{
|
||||
cont: c,
|
||||
thread: t,
|
||||
}
|
||||
return fun(mlr, &gocont)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,3 +33,12 @@ func specificRuntimeToGeneric(rtm *rt.Runtime) *Runtime {
|
|||
func (mlr *Runtime) UnderlyingRuntime() *rt.Runtime {
|
||||
return mlr.rt
|
||||
}
|
||||
|
||||
// Push will push a Lua value onto the stack.
|
||||
func (mlr *Runtime) Push(c *GoCont, v Value) {
|
||||
c.cont.Push(c.thread.Runtime, v)
|
||||
}
|
||||
|
||||
func (mlr *Runtime) PushNext1(c *GoCont, v Value) Cont {
|
||||
return c.cont.PushingNext1(c.thread.Runtime, v)
|
||||
}
|
||||
|
|
|
@ -22,8 +22,31 @@ func (t *Table) SetField(key string, value Value) {
|
|||
t.lt.Set(rt.StringValue(key), value)
|
||||
}
|
||||
|
||||
func (t *Table) Set(key Value, value Value) {
|
||||
t.lt.Set(key, value)
|
||||
}
|
||||
|
||||
func ForEach(tbl *Table, cb func(key Value, val Value)) {
|
||||
nextVal := rt.NilValue
|
||||
for {
|
||||
key, val, _ := tbl.lt.Next(nextVal)
|
||||
if key == rt.NilValue {
|
||||
break
|
||||
}
|
||||
nextVal = key
|
||||
|
||||
cb(Value(key), Value(val))
|
||||
}
|
||||
}
|
||||
|
||||
func (mlr *Runtime) GlobalTable() *Table {
|
||||
return &Table{
|
||||
lt: mlr.rt.GlobalEnv(),
|
||||
}
|
||||
}
|
||||
|
||||
func convertToMoonlightTable(t *rt.Table) *Table {
|
||||
return &Table{
|
||||
lt: t,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,12 @@ import (
|
|||
)
|
||||
|
||||
type Value = rt.Value
|
||||
type ValueType = rt.ValueType
|
||||
const (
|
||||
StringType = rt.StringType
|
||||
FunctionType = rt.FunctionType
|
||||
TableType = rt.TableType
|
||||
)
|
||||
|
||||
func StringValue(str string) Value {
|
||||
return rt.StringValue(str)
|
||||
|
@ -21,3 +27,15 @@ func BoolValue(b bool) Value {
|
|||
func TableValue(t *Table) Value {
|
||||
return rt.TableValue(t.lt)
|
||||
}
|
||||
|
||||
func Type(v Value) ValueType {
|
||||
return ValueType(v.Type())
|
||||
}
|
||||
|
||||
func ToString(v Value) string {
|
||||
return v.AsString()
|
||||
}
|
||||
|
||||
func ToTable(v Value) *Table {
|
||||
return convertToMoonlightTable(v.AsTable())
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"hilbish/util"
|
||||
"hilbish/moonlight"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
@ -49,17 +49,15 @@ hilbish.runnerMode(function(input)
|
|||
end)
|
||||
```
|
||||
*/
|
||||
func runnerModeLoader(rtm *rt.Runtime) *rt.Table {
|
||||
exports := map[string]util.LuaExport{
|
||||
/*
|
||||
func runnerModeLoader(rtm *moonlight.Runtime) *moonlight.Table {
|
||||
exports := map[string]moonlight.Export{
|
||||
"sh": {shRunner, 1, false},
|
||||
"lua": {luaRunner, 1, false},
|
||||
"setMode": {hlrunnerMode, 1, false},
|
||||
*/
|
||||
}
|
||||
|
||||
mod := rt.NewTable()
|
||||
util.SetExports(rtm, mod, exports)
|
||||
mod := moonlight.NewTable()
|
||||
rtm.SetExports(mod, exports)
|
||||
|
||||
return mod
|
||||
}
|
||||
|
@ -78,27 +76,27 @@ func _runnerMode() {}
|
|||
// Runs a command in Hilbish's shell script interpreter.
|
||||
// This is the equivalent of using `source`.
|
||||
// #param cmd string
|
||||
func shRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.Check1Arg(); err != nil {
|
||||
func shRunner(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
if err := mlr.Check1Arg(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd, err := c.StringArg(0)
|
||||
cmd, err := mlr.StringArg(c, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, exitCode, cont, err := execSh(aliases.Resolve(cmd))
|
||||
var luaErr rt.Value = rt.NilValue
|
||||
var luaErr moonlight.Value = rt.NilValue
|
||||
if err != nil {
|
||||
luaErr = rt.StringValue(err.Error())
|
||||
luaErr = moonlight.StringValue(err.Error())
|
||||
}
|
||||
runnerRet := rt.NewTable()
|
||||
runnerRet.Set(rt.StringValue("input"), rt.StringValue(cmd))
|
||||
runnerRet.Set(rt.StringValue("exitCode"), rt.IntValue(int64(exitCode)))
|
||||
runnerRet.Set(rt.StringValue("continue"), rt.BoolValue(cont))
|
||||
runnerRet.Set(rt.StringValue("err"), luaErr)
|
||||
runnerRet := moonlight.NewTable()
|
||||
runnerRet.SetField("input", moonlight.StringValue(cmd))
|
||||
runnerRet.SetField("exitCode", moonlight.IntValue(int(exitCode)))
|
||||
runnerRet.SetField("continue", moonlight.BoolValue(cont))
|
||||
runnerRet.SetField("err", luaErr)
|
||||
|
||||
return c.PushingNext(t.Runtime, rt.TableValue(runnerRet)), nil
|
||||
return mlr.PushNext1(c, moonlight.TableValue(runnerRet)), nil
|
||||
}
|
||||
|
||||
// #interface runner
|
||||
|
@ -106,24 +104,25 @@ func shRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
// Evaluates `cmd` as Lua input. This is the same as using `dofile`
|
||||
// or `load`, but is appropriated for the runner interface.
|
||||
// #param cmd string
|
||||
func luaRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.Check1Arg(); err != nil {
|
||||
func luaRunner(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
if err := mlr.Check1Arg(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd, err := c.StringArg(0)
|
||||
cmd, err := mlr.StringArg(c, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
input, exitCode, err := handleLua(cmd)
|
||||
var luaErr rt.Value = rt.NilValue
|
||||
var luaErr moonlight.Value = rt.NilValue
|
||||
if err != nil {
|
||||
luaErr = rt.StringValue(err.Error())
|
||||
luaErr = moonlight.StringValue(err.Error())
|
||||
}
|
||||
runnerRet := rt.NewTable()
|
||||
runnerRet.Set(rt.StringValue("input"), rt.StringValue(input))
|
||||
runnerRet.Set(rt.StringValue("exitCode"), rt.IntValue(int64(exitCode)))
|
||||
runnerRet.Set(rt.StringValue("err"), luaErr)
|
||||
runnerRet := moonlight.NewTable()
|
||||
runnerRet.SetField("input", moonlight.StringValue(input))
|
||||
runnerRet.SetField("exitCode", moonlight.IntValue(int(exitCode)))
|
||||
runnerRet.SetField("err", luaErr)
|
||||
|
||||
return c.PushingNext(t.Runtime, rt.TableValue(runnerRet)), nil
|
||||
|
||||
return mlr.PushNext1(c, moonlight.TableValue(runnerRet)), nil
|
||||
}
|
||||
|
|
10
util/util.go
10
util/util.go
|
@ -4,6 +4,8 @@ import (
|
|||
"strings"
|
||||
"os/user"
|
||||
|
||||
"hilbish/moonlight"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
||||
|
@ -15,15 +17,15 @@ func SetField(module *rt.Table, field string, value rt.Value) {
|
|||
|
||||
// HandleStrCallback handles function parameters for Go functions which take
|
||||
// a string and a closure.
|
||||
func HandleStrCallback(t *rt.Thread, c *rt.GoCont) (string, *rt.Closure, error) {
|
||||
if err := c.CheckNArgs(2); err != nil {
|
||||
func HandleStrCallback(mlr *moonlight.Runtime, c *moonlight.GoCont) (string, *moonlight.Closure, error) {
|
||||
if err := mlr.CheckNArgs(c, 2); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
name, err := c.StringArg(0)
|
||||
name, err := mlr.StringArg(c, 0)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
cb, err := c.ClosureArg(1)
|
||||
cb, err := mlr.ClosureArg(c, 1)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
|
4
vars.go
4
vars.go
|
@ -11,8 +11,8 @@ var (
|
|||
|
||||
// Version info
|
||||
var (
|
||||
ver = "v2.2.3"
|
||||
releaseName = "Poppy"
|
||||
ver = "v2.3.0"
|
||||
releaseName = "Alyssum"
|
||||
|
||||
gitCommit string
|
||||
gitBranch string
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
title: "v2.3 Release"
|
||||
date: 2024-07-20T10:05:17-04:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
|
||||
> The release with full changelogs and prebuilt binaries can be
|
||||
seen at the [v2.3.0](https://github.com/Rosettea/Hilbish/releases/tag/v2.3.0)
|
||||
tag.
|
||||
|
||||
Hilbish v2.3 has now been released! This is small feature and bug fix release
|
||||
which took a while to cme ut since I took a long break from programming in general.
|
||||
The next release will be great, so stay tuned for that.
|
||||
|
||||
# Features
|
||||
## Pipes (via Lua)
|
||||
Commands can now be piped to each other via the Lua API with the `hilbish.run`
|
||||
function and an `fs.pipe`.
|
||||
|
||||
Here is a minimal example of the new usage which allows users to now pipe commands
|
||||
directly via Lua functions:
|
||||
|
||||
```lua
|
||||
local fs = require 'fs'
|
||||
local pr, pw = fs.pipe()
|
||||
hilbish.run('ls -l', {
|
||||
stdout = pw,
|
||||
stderr = pw,
|
||||
})
|
||||
|
||||
pw:close()
|
||||
|
||||
hilbish.run('wc -l', {
|
||||
stdin = pr
|
||||
})
|
||||
```
|
||||
|
||||
This also means it's easier to make commands output to any stream output,
|
||||
including in commanders.
|
||||
|
||||
# Bug Fixes
|
||||
- Commanders can now be cancelled with Ctrl-C, which means if they froze for some reason
|
||||
they can now be exited.
|
||||
- The shell script interpreter now keeps its environment, and this also fixes the
|
||||
current working directory being wrong with some commands.
|
||||
- Some greenhouse bugs have been fixed, like randomly appearing when resizing the terminal
|
||||
and some text attributes like color appearing where they weren't supposed to.
|
Loading…
Reference in New Issue