aboutsummaryrefslogtreecommitdiff
path: root/docs/pages/3-features/3-comp.md
blob: 259e17477509c08656984d08c16c5d56c27c1ce3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<h1 align="center">Completion</h1>
<p align="center">
    Mingling's Features
</p>

---

## Enable Feature

`comp` is the command-line completion feature provided by **Mingling**. Its approach is not static completion but rather dynamic completion by invoking your program itself.

Enable this feature as follows:

```toml
[dependencies]
mingling = { 
    version = "...", 
    features = ["comp"] 
}
```

## Setup

Once `comp` is enabled, `gen_program!` will automatically generate a `CompletionDispatcher`, which is a command with the node `__comp`: the completion script will call this subcommand.

Add this [Dispatcher](pages/2-basic/3-dispatcher) to your [Program](pages/2-basic/1-program):

```rust
fn main() {
    let mut program = ThisProgram::new();
    program.with_dispatcher(CompletionDispatcher);
    program.exec();
}
```

## Usage

You can use the `completion!` macro to bind completion logic to your command entry point. The syntax is as follows:

```rust
// Define Dispatcher
dispatcher!("test-comp", 
    TestCompletionCommand => TestCompletionEntry
);

// Establish completion logic, bound to `TestCompletionEntry`
#[completion(TestCompletionEntry)]
fn comp_test_comp_cmd(_ctx: &ShellContext) -> Suggest {
    suggest!()
}
```

You can obtain the context passed by the shell via `ShellContext` and return the generated suggestions:

```rust
#[completion(TestCompletionEntry)]
fn comp_test_comp_cmd(ctx: &ShellContext) -> Suggest {
    if ctx.current_word.starts_with("-") {
        // Comp flags
        return suggest!(
            "--name": "Names",
            "--age": "Age"
        );
    }

    if ctx.previous_word == "--name" {
        return suggest!("Bob", "Alice"); // Comp names
    }

    if ctx.previous_word == "--age" {
        return suggest!(); // If typing age, suggest nothing
    }

    suggest!() // Comp nothing
}
```

> 🎬 Logic
>
> When the user inputs `bin test-<TAB>`, it completes to `bin test-comp`.
>
> When the user inputs `bin test-comp -<TAB>`, it suggests `--age` / `--name`.
>
> When the user inputs `bin test-comp --name <TAB>`, it suggests `Bob` / `Alice`.
>
> In other cases, no suggestions are generated.

## Generate Completion Script

Any shell requires registering a relevant completion script to enable your command's completion capability. However, **Mingling** provides a related build script:

Please add the following to `build-dependencies` in your `Cargo.toml`:

```toml
[build-dependencies]
mingling = { version = "...", features = ["comp"] }
```

Next, call the following logic in your project's `build.rs`:

```rust
use mingling::build::build_comp_scripts;

fn main() {
    // Generate completion scripts for the current program
    // build_comp_scripts().unwrap();

    // Or specify a specific name
    build_comp_scripts("your_cmd").unwrap();
}
```

`build_comp_scripts` will generate the corresponding completion scripts based on your platform and output them to the `target` directory.

> [!Note]
> The completion script does not contain the actual completion logic; 
>
> it is just a thin invocation layer.