coal 0.1.0
coal: ^0.1.0 copied to clipboard
Composable utilities for Dart command-line apps.
Coal #
Composable utilities for Dart command-line apps.
Coal is not a CLI framework. It provides focused helpers that can be used with plain Dart CLIs or existing command packages.
Modules #
| Entry | Description |
|---|---|
package:coal/args.dart |
Lightweight command-line argument parsing. |
package:coal/keypass.dart |
Terminal key sequence decoding and binding dispatch. |
package:coal/prompt.dart |
Basic text prompt flow for terminal CLIs. |
package:coal/prompt_utils.dart |
Reusable prompt helpers for common CLI questions. |
package:coal/readline.dart |
Interactive line input with editing keys and history. |
package:coal/utils.dart |
ANSI escape-code and terminal text helpers. |
package:coal/tab.dart |
Shell completion definitions and script generation. |
package:coal/tab/args.dart |
Adapter for package:args CommandRunner apps. |
Installation #
dart pub add coal
Keypass #
Decode complete terminal key sequences and dispatch key bindings:
import 'package:coal/keypass.dart';
final keys = Keypass();
keys.bind('ctrl+c', (event) => print('cancel'));
keys.bind('up', (event) => print('history up'));
keys.handleSequence('\x03'); // ctrl+c
keys.handleSequence('\x1b[A'); // up
Prompt #
Ask for a text value with a basic prompt lifecycle:
import 'package:coal/prompt.dart';
Future<void> main() async {
final prompt = Prompt.stdio();
try {
final name = await prompt.text('Name', defaultValue: 'anonymous');
print('Hello, ${name ?? 'cancelled'}');
} finally {
await prompt.close();
}
}
Prompt Utils #
Use common prompt helpers on top of Prompt:
import 'package:coal/prompt.dart';
import 'package:coal/prompt_utils.dart';
Future<void> main() async {
final prompt = Prompt.stdio();
try {
final publish = await prompt.confirm('Publish?', defaultValue: false);
print(publish == true ? 'confirmed' : 'skipped');
} finally {
await prompt.close();
}
}
Readline #
Read one edited line from a terminal:
import 'package:coal/readline.dart';
Future<void> main() async {
final readline = Readline.stdio();
try {
final name = await readline.readLine(prompt: 'Name: ');
print('Hello, ${name ?? 'anonymous'}');
} finally {
await readline.close();
}
}
<TAB> #
Core #
Define a completion tree and print shell scripts from your CLI:
import 'package:coal/tab.dart';
final tab = Tab();
final complete = tab.command('complete', '<TAB> autocompletion');
complete.argument('shell', (complete, _) {
complete('bash', 'Setup bash shell completion');
complete('zsh', 'Setup zsh shell completion');
complete('fish', 'Setup fish shell completion');
complete('powershell', 'Setup powershell shell completion');
});
See the runnable <TAB> example.
Completion scripts are synced from upstream Cobra behavior and covered by script contract tests. Maintainer sync and test details live in TAB Maintenance.
Dart CLI Completion #
Install Coal globally and load completion for the Dart SDK command:
dart pub global activate coal
source <(coal tab dart bash)
dart <TAB>
Current-session setup:
# bash, with bash-completion loaded
source <(coal tab dart bash)
# zsh, after compinit
source <(coal tab dart zsh)
# fish
coal tab dart fish | source
# powershell
coal tab dart powershell | Out-String | Invoke-Expression
Persistent setup examples:
# bash
coal tab dart bash > ~/.dart-completion.bash
printf '\nsource ~/.dart-completion.bash\n' >> ~/.bashrc
# zsh
coal tab dart zsh > ~/.dart-completion.zsh
printf '\nsource ~/.dart-completion.zsh\n' >> ~/.zshrc
# fish
coal tab dart fish > ~/.config/fish/completions/dart.fish
coal tab dart powershell > $HOME\.dart-completion.ps1
Add-Content -Path $PROFILE -Value '. $HOME\.dart-completion.ps1'
Args Parser #
Parse raw command-line tokens into a JSON-friendly argument tree:
import 'package:coal/args.dart';
const input = [
'--a=1',
'-b',
'--bool',
'--no-boop',
'--multi=foo',
'--multi=baz',
'-xyz',
];
final args = Args.parse(input, list: ['multi']);
print(args.toJson());
{
"a": 1,
"b": true,
"bool": true,
"boop": false,
"multi": ["foo", "baz"],
"x": true,
"y": true,
"z": true
}
ANSI Utility #
Generate ANSI escape codes and measure or wrap terminal text:
- Clear: Clear screen utilities.
- Cursor: Cursor manipulation utilities.
- Erase: Text erasing utilities.
- Scroll: Screen scrolling utilities.
- Text: Text styling and manipulation utilities.
Clear #
| Name | Description |
|---|---|
clearScreen |
Clear the terminal screen. |
Cursor #
| Name | Description |
|---|---|
cursorUp() |
Move the cursor up by count lines. |
cursorDown() |
Move the cursor down by count lines. |
cursorForward() |
Move the cursor forward by count columns. |
cursorBackward() |
Move the cursor backward by count columns. |
cursorNextLine() |
Move the cursor to the next line by count lines. |
cursorPrevLine() |
Move the cursor to the previous line by count lines. |
cursorTo() |
Move the cursor to the specified position. |
cursorMove() |
Move the cursor by x columns and y lines. |
cursorShow |
Show the cursor. |
cursorHide |
Hide the cursor. |
cursorSave |
Save the cursor position. |
cursorRestore |
Restore the cursor position. |
cursorLeft |
Move the cursor to the first column. |
Erase #
| Name | Description |
|---|---|
eraseScreen |
Erase the entire screen. |
eraseLine |
Erase the current line. |
eraseLineStart |
Erase from the current cursor position to the beginning of the line. |
eraseLineEnd |
Erase from the current cursor position to the end of the line. |
eraseUp() |
Erase count lines above the current cursor position. |
eraseDown() |
Erase count lines below the current cursor position. |
eraseLines() |
Erase count lines above and below the current cursor position. |
Scroll #
| Name | Description |
|---|---|
scrollUp() |
Scroll the screen up by count lines. |
scrollDown() |
Scroll the screen down by count lines. |
scrollLeft() |
Scroll the screen left by count columns. |
scrollRight() |
Scroll the screen right by count columns. |
Text #
stripVTControlCharacters(): Remove all VT control characters. Use to estimate displayed string width.getTextTruncatedWidth(): Get the width of a string when truncated to fit within a given width.getTextWidth(): Get the width of a string.wrapAnsi(): Wrap a string to fit within a given width.styleText(): Generate a string with ANSI escape codes for styling.
Style Text
final text = styleText('Hello, World!', [TextStyle.red, TextStyle.bold]);