diff options
Diffstat (limited to 'docs/pages/advanced')
| -rw-r--r-- | docs/pages/advanced/.name | 1 | ||||
| -rw-r--r-- | docs/pages/advanced/1-completion.md | 83 | ||||
| -rw-r--r-- | docs/pages/advanced/2-structural-renderer.md | 120 |
3 files changed, 204 insertions, 0 deletions
diff --git a/docs/pages/advanced/.name b/docs/pages/advanced/.name new file mode 100644 index 0000000..a8a2c7e --- /dev/null +++ b/docs/pages/advanced/.name @@ -0,0 +1 @@ +Advanced diff --git a/docs/pages/advanced/1-completion.md b/docs/pages/advanced/1-completion.md new file mode 100644 index 0000000..a90c3ce --- /dev/null +++ b/docs/pages/advanced/1-completion.md @@ -0,0 +1,83 @@ +<h1 align="center">Completion</h1> +<p align="center"> + Fully dynamic completion system via the `comp` feature +</p> + +Mingling's completion is **fully dynamic** — no static completion files, suggestions are computed at runtime based on the user's current input. + +## Enable `comp` + +```toml +# Cargo.toml +[dependencies.mingling] +features = ["comp"] + +[build-dependencies.mingling] +features = [ + "comp", + # Enable `builds` for build-time support + "builds" +] +``` + +## How it works + +When the user presses `TAB`, the completion script calls the program's hidden subcommand `__comp`, which dynamically queries the best suggestions based on the provided `ShellContext`. + +This hidden subcommand is auto-generated by `gen_program!()` when the `comp` feature is enabled. Its dispatcher is `CMDCompletion` — you need to add it to your program via `with_dispatcher`. + +Completion flow: + +1. Re-match the user's current input to a `Dispatcher` +2. Call the corresponding `#[completion]` function +3. The function returns a `Suggest` (file completion or a list of suggestions) +4. Notify the shell to display the suggestions + +## Define completions + +Use `#[completion(EntryType)]` to define completion logic for an Entry: + +```rust +// Features: ["comp"] +@@@use mingling::prelude::*; +@@@use mingling::{ShellContext, Suggest, SuggestItem}; +@@@use std::collections::BTreeSet; +@@@dispatcher!("greet", CMDGreet => EntryGreet); + +#[completion(EntryGreet)] +fn complete_greet(ctx: &ShellContext) -> Suggest { + if ctx.previous_word == "greet" { + let mut items = BTreeSet::new(); + items.insert(SuggestItem::new_with_desc("Alice".into(), "Likes to receive messages".into())); + items.insert(SuggestItem::new("World".into())); + Suggest::Suggest(items) + } else { + Suggest::FileCompletion + } +} +``` + +The `suggest!` macro is a more concise way to write the same thing: + +```rust +// Features: ["comp"] +@@@use mingling::macros::suggest; +@@@fn example() { +suggest! { + "Alice": "Likes to receive messages", + "World" +}; +@@@} +``` + +`ShellContext` holds the user's current input state (`previous_word`, `current_word`, `all_words`, etc.). `Suggest` has two variants: `Suggest::Suggest(list)` returns a suggestion list, `Suggest::FileCompletion` delegates file completion to the shell. + +## Generate completion scripts + +Call `build_comp_scripts` in `build.rs` to generate completion scripts (requires `builds` + `comp` features). + +See [example-completion](https://mingling-rs.github.io/mingling/docs/example-viewer.html?name=example-completion). + +<p align="center" style="font-size: 0.85em; color: gray;"> + Written by @Weicao-CatilGrass +</p> diff --git a/docs/pages/advanced/2-structural-renderer.md b/docs/pages/advanced/2-structural-renderer.md new file mode 100644 index 0000000..09c86d1 --- /dev/null +++ b/docs/pages/advanced/2-structural-renderer.md @@ -0,0 +1,120 @@ +<h1 align="center">Structural Rendering</h1> +<p align="center"> + Use the <code>structural_renderer</code> feature to render output as serialized text +</p> + +With `structural_renderer` enabled, your program can switch output to a structured format via `--json`, `--yaml`, etc., making it easy to integrate with other tools. + +## Enabling the Feature + +```toml +[dependencies.mingling] +features = ["structural_renderer"] +``` + +`structural_renderer` automatically enables `json_serde_fmt`. + +For more formats, enable `structural_renderer_full` (includes JSON, YAML, TOML, RON). + +> [!NOTE] +> To customize output types, see [Features](./pages/other/features) + +## Basic Usage + +After enabling `StructuralRendererSetup`, use `pack_structural!` instead of `pack!` to declare types that support structured output: + +```rust +// Features: ["structural_renderer"] +// Dependencies: +// serde = "1" +@@@use mingling::setup::StructuralRendererSetup; +@@@dispatcher!("render", CMDRender => EntryRender); + +// pack_structural! is equivalent to pack! + StructuralData +pack_structural!(ResultInfo = (String, i32)); + +#[chain] +fn handle_render(args: EntryRender) -> Next { + let name = args.inner.first().cloned().unwrap_or_default(); + let age = args.inner.get(1).and_then(|s| s.parse().ok()).unwrap_or(0); + ResultInfo::new((name, age)) +} + +#[renderer] +fn render_info(r: ResultInfo) { + r_println!("{:?}", *r); +} +``` + +Output: + +```text +~# my-cli render Bob 22 +("Bob", 22) + +~# my-cli render Bob 22 --json +{"inner":["Bob",22]} +``` + +When the user passes `--json`, the framework automatically serializes the render result as JSON — no business logic changes needed. + +## Customizing Output Structure + +The default output from `pack_structural!` includes an `inner` field. For full control over the output structure, define the type manually with `#[derive(StructuralData, Serialize, Groupped)]`: + +```rust +// Features: ["structural_renderer"] +// Dependencies: +// serde = "1" +@@@use mingling::prelude::*; +@@@use mingling::setup::StructuralRendererSetup; +@@@use mingling::StructuralData; +@@@use serde::Serialize; +@@@dispatcher!("render", CMDRender => EntryRender); + +#[derive(Serialize, StructuralData, Groupped)] +struct Info { + name: String, + age: i32, +} + +#[chain] +fn handle_render(args: EntryRender) -> Next { + let name = args.inner.first().cloned().unwrap_or_default(); + let age = args.inner.get(1).and_then(|s| s.parse().ok()).unwrap_or(0); + Info { name, age }.to_render() +} + +#[renderer] +fn render_info(info: Info) { + r_println!("{} is {} years old", info.name, info.age); +} +@@@ +@@@fn main() { +@@@ let mut program = ThisProgram::new(); +@@@ program.with_setup(StructuralRendererSetup); +@@@ program.with_dispatcher(CMDRender); +@@@ program.exec(); +@@@} +@@@gen_program!(); +``` + +Now `--json` outputs: + +```json +{ "name": "Bob", "age": 22 } +``` + +## Notes + +- Supported formats: JSON, YAML, TOML, RON (depends on enabled features) +- `StructuralRendererSetup` registers global params like `--json`, `--yaml`, `--toml`, `--ron` + +> [!NOTE] +> Each type still needs an **empty Renderer**, otherwise that type **is not considered renderable** + +See [example-structural-renderer](https://mingling-rs.github.io/mingling/docs/example-viewer.html?name=example-structural-renderer). + +<p align="center" style="font-size: 0.85em; color: gray;"> + Written by @Weicao-CatilGrass +</p> |
