https://github.com/ringtailsoftware/zig-embshell
Small embeddable command line shell in zig
https://github.com/ringtailsoftware/zig-embshell
cli embedded shell zig zig-package ziglang
Last synced: 10 months ago
JSON representation
Small embeddable command line shell in zig
- Host: GitHub
- URL: https://github.com/ringtailsoftware/zig-embshell
- Owner: ringtailsoftware
- License: mit
- Created: 2023-01-31T00:09:50.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2025-01-13T20:16:26.000Z (about 1 year ago)
- Last Synced: 2025-04-10T22:40:50.402Z (10 months ago)
- Topics: cli, embedded, shell, zig, zig-package, ziglang
- Language: Zig
- Homepage:
- Size: 39.1 KB
- Stars: 15
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: MIT-LICENSE
Awesome Lists containing this project
README
# EmbShell
A very small interactive command shell for (embedded) Zig programs.
EmbShell makes an ideal system monitor for debugging and interacting with a small embedded system. It interactively takes lines of text, parses commands and makes callbacks into handler functions.
Compared with Readline, Linenoise and Editline - EmbShell is tiny. It lacks most of their features, but it does have:
- Tab completion for command names
- Backspace for line editing
- No reliance on libc and very little use of Zig's `std` (ie. no fancy print formatting)
- Very little RAM use (just a configurable buffer for the incoming command line)
In EmbShell:
- All commands and configuration are set at `comptime` to optimise footprint
- All arguments are separated by whitespace, there is no support for quoted strings, multiline commands or escaped data
- All handler arguments are strings, leaving it to the app to decide how to parse them
- No runtime memory allocations
## Using
Developed with `zig 0.14.0`
### Run the sample
cd example-posix
zig build run
```
myshell> help
echo
led
myshell> echo hello world
You said: { echo, hello, world }
OK
myshell> led 1
If we had an LED it would be set to true
OK
```
## Using in your own project
First add the library as a dependency in your `build.zig.zon` file.
`zig fetch --save git+https://github.com/ringtailsoftware/zig-embshell.git`
And add it to `build.zig` file.
```zig
const embshell_dep = b.dependency("embshell", .{
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("embshell", embshell_dep.module("embshell"));
```
`@import` the module and provide a configuration.
- `.prompt` is the string shown to the user before each command is entered
- `.maxargs` is the maximum number of arguments EmbShell will process (e.g. "mycmd foo bar" is 3 arguments)
- `.maxlinelen` is the maximum length of a line to be handled, a buffer of this size will be created
- `.cmdtable` an array of names and handler function for commands
```zig
const UserdataT = u32;
const EmbShellT = @import("embshell").EmbShellFixedParams(UserdataT);
const EmbShell = @import("embshell").EmbShellFixed(.{
.prompt = "myshell> ",
.maxargs = 16,
.maxlinelen = 128,
.cmdtable = &.{
.{ .name = "echo", .handler = echoHandler },
.{ .name = "led", .handler = ledHandler },
},
.userdataT = UserdataT,
});
```
Each handler function is in the following form. EmbShell prints "OK" after successfully executing each function and "Failed" if an error is returned.
```zig
fn myHandler(userdata: UserdataT, args:[][]const u8) anyerror!void {
// process args
// optionally return error
}
```
Next, call `.init()` and provide a write callback to allow EmbShell to emit data
```zig
fn write(data:[]const u8) void {
// emit data to terminal
}
var shell = try EmbShell.init(write, userdata);
```
Finally, feed EmbShell with incoming data from the terminal to be processed
```zig
const buf = readFromMyTerminal();
shell.feed(buf)
```