Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 38 additions & 5 deletions .seal/typedefs/std/io/input.luau
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,39 @@ function input.editline(prompt: string, left: string, right: string?): string |
return nil :: any
end

export type InputReadOptions = {
--- The maximum number of bytes to read before returning; reading stops once this many bytes
--- have been read, even if the stream is still open. Accepts a plain `number` or a `FileSize`.
bytes: (number | FileSize)?,
--- A `Duration` (from `@std/time`) to wait for input before returning; reading stops once the
--- timeout elapses, even if the stream is still open.
timeout: Duration?,
}

--[=[
Reads all of stdin until EOF, returning the full contents as a string.
Reads from stdin, returning the bytes read and whether there may be more left to read.

Blocks until the stream closes — either a pipe closes or the user presses <kbd>Ctrl+D</kbd> in a TTY.
With no `options`, reads all of stdin until EOF and blocks until the stream closes — either a
pipe closes or the user presses <kbd>Ctrl+D</kbd> in a TTY.

Useful for consuming piped input in scripts, e.g. `echo "hello" | seal script.luau`.

## Parameters

- `options.bytes`: the maximum number of bytes to read before returning. Accepts a plain
`number` or a `FileSize` (from `@std/fs/filesize`). Reading stops once this many bytes have
been read, even if the stream is still open.
- `options.timeout`: a `Duration` (from `@std/time`) to wait for input before returning.
Reading stops once the timeout elapses, even if the stream is still open.

## Returns

- A `string` containing all bytes read from stdin before EOF.
Returns two values:

- A `string` containing the bytes read from stdin, or `nil` if nothing was read.
- A `boolean` that is `true` if reading stopped before EOF (i.e. because the `bytes` limit was
reached or the `timeout` elapsed and there may be more to read), and `false` if the stream
reached EOF.

## Errors

Expand All @@ -101,11 +124,21 @@ end
## Usage

```luau
-- read everything until EOF
local contents = input.read()
print(`got {#contents} bytes from stdin`)
print(`got {#(contents or "")} bytes from stdin`)

-- read at most 1 KB, or give up after 5 seconds
local chunk, more = input.read {
bytes = filesize.kilobytes(1),
timeout = time.seconds(5),
}
if more then
print("there's still more to read!")
end
```
]=]
function input.read(): string
function input.read(options: InputReadOptions?): (string?, boolean)
return nil :: any
end

Expand Down
28 changes: 14 additions & 14 deletions .seal/typedefs/std/process.luau
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ export type SpawnOptions = {
--- Represents the stdout and stderr streams of a `ChildProcess`, both ran in parallel threads
--- and streamed for nonblocking behavior.
export type ChildProcessStream = setmetatable<{
--> stream:read(count: number?, timeout: number?): string?
--> stream:read(count: number?, timeout: (Duration | number)?): string?
--[=[
Reads up to `count` bytes from the stream for up to `timeout` seconds, retrying while the stream remains empty.

Expand Down Expand Up @@ -410,8 +410,8 @@ export type ChildProcessStream = setmetatable<{
local current_data = child.stdout:read(nil, 0.0)
```
]=]
read: (self: ChildProcessStream, count: number?, timeout: number?) -> string?,
--> stream:read_exact(count: number, timeout: number?): string?
read: (self: ChildProcessStream, count: number?, timeout: (Duration | number)?) -> string?,
--> stream:read_exact(count: number, timeout: (Duration | number)?): string?
--[=[
Reads exactly `count` bytes from the stream, retrying until `count` bytes are available or `timeout` seconds elapse.

Expand Down Expand Up @@ -455,8 +455,8 @@ export type ChildProcessStream = setmetatable<{
end
```
]=]
read_exact: (self: ChildProcessStream, count: number, timeout: number?) -> string?,
--> stream:read_to(term: string, inclusive: boolean?, timeout: number?, allow_partial: boolean?): string?
read_exact: (self: ChildProcessStream, count: number, timeout: (Duration | number)?) -> string?,
--> stream:read_to(term: string, inclusive: boolean?, timeout: (Duration | number)?, allow_partial: boolean?): string?
--[=[
Keep reading from the stream until search `term` is encountered. This is especially useful if you're trying to read line-by-line,
or until a specific delimiter is encountered.
Expand All @@ -477,8 +477,8 @@ export type ChildProcessStream = setmetatable<{

Blocks the current VM until `term` is found, `timeout` seconds elapse, or the reader thread exits.
]=]
read_to: (self: ChildProcessStream, term: string, inclusive: boolean?, timeout: number?, allow_partial: boolean?) -> string?,
--> stream:fill(target: buffer, target_offset: number?, timeout: number?): number
read_to: (self: ChildProcessStream, term: string, inclusive: boolean?, timeout: (Duration | number)?, allow_partial: boolean?) -> string?,
--> stream:fill(target: buffer, target_offset: number?, timeout: (Duration | number)?): number
--[=[
Fill the `target` buffer with as many bytes as possible from the stream. Retries until the stream is nonempty or `timeout` seconds elapse.

Expand Down Expand Up @@ -508,8 +508,8 @@ export type ChildProcessStream = setmetatable<{
end
```
]=]
fill: (self: ChildProcessStream, target: buffer, target_offset: number?, timeout: number?) -> number,
--> stream:fill_exact(count: number, target: buffer, target_offset: number?, timeout: number?): boolean
fill: (self: ChildProcessStream, target: buffer, target_offset: number?, timeout: (Duration | number)?) -> number,
--> stream:fill_exact(count: number, target: buffer, target_offset: number?, timeout: (Duration | number)?): boolean
--[=[
Read exactly `count` bytes into the `target` buffer at `target_offset`, retrying until `count` bytes are available or `timeout` seconds elapse.

Expand All @@ -529,14 +529,14 @@ export type ChildProcessStream = setmetatable<{

Pass a `timeout` of `0` seconds to prevent this function from blocking!
]=]
fill_exact: (self: ChildProcessStream, count: number, target: buffer, target_offset: number?, timeout: number?) -> boolean,
fill_exact: (self: ChildProcessStream, count: number, target: buffer, target_offset: number?, timeout: (Duration | number)?) -> boolean,
--> stream:len(): number
--- Returns the current length/size of the stream's inner buffer.
len: (self: ChildProcessStream) -> number,
--> stream:capacity(): number
--- Returns the maximum capacity of the stream's inner buffer.
capacity: (self: ChildProcessStream) -> number,
--> for line in stream:lines(timeout: number?)
--> for line in stream:lines(timeout: (Duration | number)?)
--[=[
Iterate over the lines in the stream, blocking the current VM (Rust Thread) until all lines are read or the timeout has been reached.

Expand Down Expand Up @@ -578,8 +578,8 @@ export type ChildProcessStream = setmetatable<{
end
```
]=]
lines: (self: ChildProcessStream, timeout: number?) -> (() -> string),
--> for message in stream:iter(timeout: number?, write_delay_ms: number?)
lines: (self: ChildProcessStream, timeout: (Duration | number)?) -> (() -> string),
--> for message in stream:iter(timeout: (Duration | number)?, write_delay_ms: number?)
--[=[
Iterate over the stream with more granular options:

Expand All @@ -592,7 +592,7 @@ export type ChildProcessStream = setmetatable<{

This function does *not* strip preceding '\r's and trailing '\n's (unlike `:lines()` and generalized iteration).
]=]
iter: (self: ChildProcessStream, timeout: number?, write_delay_ms: number?) -> () -> string,
iter: (self: ChildProcessStream, timeout: (Duration | number)?, write_delay_ms: number?) -> () -> string,
}, {
--> for line in stream
--[=[
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ It can surreptitiously replace your shell and single-use Python scripts with Lua
- *seal* projects are more scalable than shell scripts.
- Built in terminal manipulation for TUIs.
- Powerful multithreading.
- <!-- Start-Precommit-Marker-1 -->1101<!-- End-Precommit-Marker-1 --> handcrafted error messages.
- <!-- Start-Precommit-Marker-1 -->1103<!-- End-Precommit-Marker-1 --> handcrafted error messages.

## Install

Expand Down
100 changes: 92 additions & 8 deletions docs/reference/std/io/input.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,60 @@ This function shares most semantics with `input.readline`, including the followi

---

### input.interrupt
## `export type` InputReadOptions

<h4>

```luau
function input.interrupt(key: "CtrlC" | "CtrlD"): interrupt
export type InputReadOptions = {
```

</h4>

---

### InputReadOptions.bytes

<h4>

```luau
bytes: (number | FileSize)?,
```

</h4>

The maximum number of bytes to read before returning; reading stops once this many bytes
have been read, even if the stream is still open. Accepts a plain `number` or a `FileSize`.

---

### InputReadOptions.timeout

<h4>

```luau
timeout: Duration?,
```

</h4>

A `Duration` (from `@std/time`) to wait for input before returning; reading stops once the
timeout elapses, even if the stream is still open.

---

```luau
} -- closes InputReadOptions
```

---

#### io.input.input.read

<h4>

```luau
function io.input.input.read(options: InputReadOptions?): (string?, boolean)
```

</h4>
Expand All @@ -142,15 +190,29 @@ function input.interrupt(key: "CtrlC" | "CtrlD"): interrupt

<summary> See the docs </summary

Reads all of stdin until EOF, returning the full contents as a string.
Reads from stdin, returning the bytes read and whether there may be more left to read.

Blocks until the stream closes — either a pipe closes or the user presses <kbd>Ctrl+D</kbd> in a TTY.
With no `options`, reads all of stdin until EOF and blocks until the stream closes — either a
pipe closes or the user presses <kbd>Ctrl+D</kbd> in a TTY.

Useful for consuming piped input in scripts, e.g. `echo "hello" | seal script.luau`.

## Parameters

- `options.bytes`: the maximum number of bytes to read before returning. Accepts a plain
`number` or a `FileSize` (from `@std/fs/filesize`). Reading stops once this many bytes have
been read, even if the stream is still open.
- `options.timeout`: a `Duration` (from `@std/time`) to wait for input before returning.
Reading stops once the timeout elapses, even if the stream is still open.

## Returns

- A `string` containing all bytes read from stdin before EOF.
Returns two values:

- A `string` containing the bytes read from stdin, or `nil` if nothing was read.
- A `boolean` that is `true` if reading stopped before EOF (i.e. because the `bytes` limit was
reached or the `timeout` elapsed and there may be more to read), and `false` if the stream
reached EOF.

## Errors

Expand All @@ -159,16 +221,38 @@ Useful for consuming piped input in scripts, e.g. `echo "hello" | seal script.lu
## Usage

```luau
-- read everything until EOF
local contents = input.read()
print(`got {#contents} bytes from stdin`)
print(`got {#(contents or "")} bytes from stdin`)

-- read at most 1 KB, or give up after 5 seconds
local chunk, more = input.read {
bytes = filesize.kilobytes(1),
timeout = time.seconds(5),
}
if more then
print("there's still more to read!")
end
```

Returns an `interrupt` userdata object. For reasons. Maybe control flow.

</details>

---

#### io.input.input.interrupt

<h4>

```luau
function io.input.input.interrupt(key: "CtrlC" | "CtrlD"): interrupt
```

</h4>

Returns an `interrupt` userdata object. For reasons. Maybe control flow.

---

Autogenerated from [std/io/input.luau](/.seal/typedefs/std/io/input.luau).

*seal* is best experienced with inline, in-editor documentation. Please see the linked typedefs file if this documentation is confusing, too verbose, or inaccurate.
14 changes: 7 additions & 7 deletions docs/reference/std/process.md
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,7 @@ export type ChildProcessStream = setmetatable<{
<h4>

```luau
function ChildProcessStream.read(self: ChildProcessStream, count: number?, timeout: number?) -> string?,
function ChildProcessStream.read(self: ChildProcessStream, count: number?, timeout: (Duration | number)?) -> string?,
```

</h4>
Expand Down Expand Up @@ -1069,7 +1069,7 @@ local current_data = child.stdout:read(nil, 0.0)
<h4>

```luau
function ChildProcessStream.read_exact(self: ChildProcessStream, count: number, timeout: number?) -> string?,
function ChildProcessStream.read_exact(self: ChildProcessStream, count: number, timeout: (Duration | number)?) -> string?,
```

</h4>
Expand Down Expand Up @@ -1129,7 +1129,7 @@ end
<h4>

```luau
function ChildProcessStream.read_to(self: ChildProcessStream, term: string, inclusive: boolean?, timeout: number?, allow_partial: boolean?) -> string?,
function ChildProcessStream.read_to(self: ChildProcessStream, term: string, inclusive: boolean?, timeout: (Duration | number)?, allow_partial: boolean?) -> string?,
```

</h4>
Expand Down Expand Up @@ -1166,7 +1166,7 @@ Blocks the current VM until `term` is found, `timeout` seconds elapse, or the re
<h4>

```luau
function ChildProcessStream.fill(self: ChildProcessStream, target: buffer, target_offset: number?, timeout: number?) -> number,
function ChildProcessStream.fill(self: ChildProcessStream, target: buffer, target_offset: number?, timeout: (Duration | number)?) -> number,
```

</h4>
Expand Down Expand Up @@ -1212,7 +1212,7 @@ end
<h4>

```luau
function ChildProcessStream.fill_exact(self: ChildProcessStream, count: number, target: buffer, target_offset: number?, timeout: number?) -> boolean,
function ChildProcessStream.fill_exact(self: ChildProcessStream, count: number, target: buffer, target_offset: number?, timeout: (Duration | number)?) -> boolean,
```

</h4>
Expand Down Expand Up @@ -1276,7 +1276,7 @@ function ChildProcessStream.capacity(self: ChildProcessStream) -> number,
<h4>

```luau
function ChildProcessStream.lines(self: ChildProcessStream, timeout: number?) -> (() -> string),
function ChildProcessStream.lines(self: ChildProcessStream, timeout: (Duration | number)?) -> (() -> string),
```

</h4>
Expand Down Expand Up @@ -1334,7 +1334,7 @@ end
<h4>

```luau
function ChildProcessStream.iter(self: ChildProcessStream, timeout: number?, write_delay_ms: number?) -> () -> string,
function ChildProcessStream.iter(self: ChildProcessStream, timeout: (Duration | number)?, write_delay_ms: number?) -> () -> string,
```

</h4>
Expand Down
Loading
Loading