mirror of https://github.com/Hilbis/Hilbish
chore: merge from master
commit
7531bbfd14
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -1,5 +1,15 @@
|
||||||
# 🎀 Changelog
|
# 🎀 Changelog
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
### Added
|
||||||
|
- Made a few additions to the sink type:
|
||||||
|
- `read()` method for retrieving input (so now the `in` sink of commanders is useful)
|
||||||
|
- `flush()` and `autoFlush()` related to flushing outputs
|
||||||
|
- `pipe` property to check if a sink with input is a pipe (like stdin)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Replaced `sed` in-place editing with `grep` and `mv` for compatibility with BSD utils
|
||||||
|
|
||||||
## [2.1.0] - 2022-02-10
|
## [2.1.0] - 2022-02-10
|
||||||
### Added
|
### Added
|
||||||
- Documented custom userdata types (Job and Timer Objects)
|
- Documented custom userdata types (Job and Timer Objects)
|
||||||
|
|
|
@ -34,4 +34,4 @@ tasks:
|
||||||
- rm -vrf
|
- rm -vrf
|
||||||
"{{.DESTDIR}}{{.BINDIR}}/hilbish"
|
"{{.DESTDIR}}{{.BINDIR}}/hilbish"
|
||||||
"{{.DESTDIR}}{{.LIBDIR}}"
|
"{{.DESTDIR}}{{.LIBDIR}}"
|
||||||
- sed -i '/hilbish/d' /etc/shells
|
- grep -v 'hilbish' /etc/shells > /tmp/shells.hilbish_uninstall && mv /tmp/shells.hilbish_uninstall /etc/shells
|
||||||
|
|
|
@ -109,6 +109,16 @@ A sink is a structure that has input and/or output to/from
|
||||||
a desination.
|
a desination.
|
||||||
|
|
||||||
### Methods
|
### Methods
|
||||||
|
#### autoFlush(auto)
|
||||||
|
Sets/toggles the option of automatically flushing output.
|
||||||
|
A call with no argument will toggle the value.
|
||||||
|
|
||||||
|
#### flush()
|
||||||
|
Flush writes all buffered input to the sink.
|
||||||
|
|
||||||
|
#### read() -> string
|
||||||
|
Reads input from the sink.
|
||||||
|
|
||||||
#### write(str)
|
#### write(str)
|
||||||
Writes data to a sink.
|
Writes data to a sink.
|
||||||
|
|
||||||
|
|
|
@ -180,6 +180,18 @@ function hilbish.jobs:foreground() end
|
||||||
--- @param cmd string
|
--- @param cmd string
|
||||||
function hilbish.runner.lua(cmd) end
|
function hilbish.runner.lua(cmd) end
|
||||||
|
|
||||||
|
--- Sets/toggles the option of automatically flushing output.
|
||||||
|
--- A call with no argument will toggle the value.
|
||||||
|
--- @param auto boolean|nil
|
||||||
|
function hilbish:autoFlush(auto) end
|
||||||
|
|
||||||
|
--- Flush writes all buffered input to the sink.
|
||||||
|
function hilbish:flush() end
|
||||||
|
|
||||||
|
--- Reads input from the sink.
|
||||||
|
--- @returns string
|
||||||
|
function hilbish:read() end
|
||||||
|
|
||||||
--- Writes data to a sink.
|
--- Writes data to a sink.
|
||||||
function hilbish:write(str) end
|
function hilbish:write(str) end
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ commander.register('bg', function(_, sinks)
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
local err = job.background()
|
local err = job:background()
|
||||||
if err then
|
if err then
|
||||||
sinks.out:writeln('bg: ' .. err)
|
sinks.out:writeln('bg: ' .. err)
|
||||||
return 2
|
return 2
|
||||||
|
|
|
@ -7,7 +7,7 @@ commander.register('fg', function(_, sinks)
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
local err = job.foreground() -- waits for job; blocks
|
local err = job:foreground() -- waits for job; blocks
|
||||||
if err then
|
if err then
|
||||||
sinks.out:writeln('fg: ' .. err)
|
sinks.out:writeln('fg: ' .. err)
|
||||||
return 2
|
return 2
|
||||||
|
|
106
sink.go
106
sink.go
|
@ -1,8 +1,10 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
"hilbish/util"
|
"hilbish/util"
|
||||||
|
|
||||||
|
@ -15,9 +17,11 @@ var sinkMetaKey = rt.StringValue("hshsink")
|
||||||
// A sink is a structure that has input and/or output to/from
|
// A sink is a structure that has input and/or output to/from
|
||||||
// a desination.
|
// a desination.
|
||||||
type sink struct{
|
type sink struct{
|
||||||
writer io.Writer
|
writer *bufio.Writer
|
||||||
reader io.Reader
|
reader *bufio.Reader
|
||||||
|
file *os.File
|
||||||
ud *rt.UserData
|
ud *rt.UserData
|
||||||
|
autoFlush bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupSinkType(rtm *rt.Runtime) {
|
func setupSinkType(rtm *rt.Runtime) {
|
||||||
|
@ -25,15 +29,35 @@ func setupSinkType(rtm *rt.Runtime) {
|
||||||
|
|
||||||
sinkMethods := rt.NewTable()
|
sinkMethods := rt.NewTable()
|
||||||
sinkFuncs := map[string]util.LuaExport{
|
sinkFuncs := map[string]util.LuaExport{
|
||||||
|
"flush": {luaSinkFlush, 1, false},
|
||||||
|
"read": {luaSinkRead, 1, false},
|
||||||
|
"autoFlush": {luaSinkAutoFlush, 2, false},
|
||||||
"write": {luaSinkWrite, 2, false},
|
"write": {luaSinkWrite, 2, false},
|
||||||
"writeln": {luaSinkWriteln, 2, false},
|
"writeln": {luaSinkWriteln, 2, false},
|
||||||
}
|
}
|
||||||
util.SetExports(l, sinkMethods, sinkFuncs)
|
util.SetExports(l, sinkMethods, sinkFuncs)
|
||||||
|
|
||||||
sinkIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
sinkIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
s, _ := sinkArg(c, 0)
|
||||||
|
|
||||||
arg := c.Arg(1)
|
arg := c.Arg(1)
|
||||||
val := sinkMethods.Get(arg)
|
val := sinkMethods.Get(arg)
|
||||||
|
|
||||||
|
if val != rt.NilValue {
|
||||||
|
return c.PushingNext1(t.Runtime, val), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
keyStr, _ := arg.TryString()
|
||||||
|
|
||||||
|
switch keyStr {
|
||||||
|
case "pipe":
|
||||||
|
val = rt.BoolValue(false)
|
||||||
|
if s.file != nil {
|
||||||
|
fileInfo, _ := s.file.Stat();
|
||||||
|
val = rt.BoolValue(fileInfo.Mode() & os.ModeCharDevice == 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return c.PushingNext1(t.Runtime, val), nil
|
return c.PushingNext1(t.Runtime, val), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +65,25 @@ func setupSinkType(rtm *rt.Runtime) {
|
||||||
l.SetRegistry(sinkMetaKey, rt.TableValue(sinkMeta))
|
l.SetRegistry(sinkMetaKey, rt.TableValue(sinkMeta))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #member
|
||||||
|
// read() -> string
|
||||||
|
// --- @returns string
|
||||||
|
// Reads input from the sink.
|
||||||
|
func luaSinkRead(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
if err := c.Check1Arg(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := sinkArg(c, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
str, _ := s.reader.ReadString('\n')
|
||||||
|
|
||||||
|
return c.PushingNext1(t.Runtime, rt.StringValue(str)), nil
|
||||||
|
}
|
||||||
|
|
||||||
// #member
|
// #member
|
||||||
// write(str)
|
// write(str)
|
||||||
// Writes data to a sink.
|
// Writes data to a sink.
|
||||||
|
@ -59,6 +102,9 @@ func luaSinkWrite(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s.writer.Write([]byte(data))
|
s.writer.Write([]byte(data))
|
||||||
|
if s.autoFlush {
|
||||||
|
s.writer.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
return c.Next(), nil
|
return c.Next(), nil
|
||||||
}
|
}
|
||||||
|
@ -81,22 +127,74 @@ func luaSinkWriteln(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s.writer.Write([]byte(data + "\n"))
|
s.writer.Write([]byte(data + "\n"))
|
||||||
|
if s.autoFlush {
|
||||||
|
s.writer.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Next(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// #member
|
||||||
|
// flush()
|
||||||
|
// Flush writes all buffered input to the sink.
|
||||||
|
func luaSinkFlush(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
if err := c.Check1Arg(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := sinkArg(c, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.writer.Flush()
|
||||||
|
|
||||||
|
return c.Next(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// #member
|
||||||
|
// autoFlush(auto)
|
||||||
|
// Sets/toggles the option of automatically flushing output.
|
||||||
|
// A call with no argument will toggle the value.
|
||||||
|
// --- @param auto boolean|nil
|
||||||
|
func luaSinkAutoFlush(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
s, err := sinkArg(c, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
v := c.Arg(1)
|
||||||
|
if v.Type() != rt.BoolType && v.Type() != rt.NilType {
|
||||||
|
return nil, fmt.Errorf("#1 must be a boolean")
|
||||||
|
}
|
||||||
|
|
||||||
|
value := !s.autoFlush
|
||||||
|
if v.Type() == rt.BoolType {
|
||||||
|
value = v.AsBool()
|
||||||
|
}
|
||||||
|
|
||||||
|
s.autoFlush = value
|
||||||
|
|
||||||
return c.Next(), nil
|
return c.Next(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSinkInput(r io.Reader) *sink {
|
func newSinkInput(r io.Reader) *sink {
|
||||||
s := &sink{
|
s := &sink{
|
||||||
reader: r,
|
reader: bufio.NewReader(r),
|
||||||
}
|
}
|
||||||
s.ud = sinkUserData(s)
|
s.ud = sinkUserData(s)
|
||||||
|
|
||||||
|
if f, ok := r.(*os.File); ok {
|
||||||
|
s.file = f
|
||||||
|
}
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSinkOutput(w io.Writer) *sink {
|
func newSinkOutput(w io.Writer) *sink {
|
||||||
s := &sink{
|
s := &sink{
|
||||||
writer: w,
|
writer: bufio.NewWriter(w),
|
||||||
|
autoFlush: true,
|
||||||
}
|
}
|
||||||
s.ud = sinkUserData(s)
|
s.ud = sinkUserData(s)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue