terminal

# CLI-API Terminal Example

This example demonstrates the **CLI-API** terminal features: line editing (TAB completion, argument hints, UP/DOWN history, Backspace), the `Terminal mode` menuconfig option, and the `history` / `sync` commands.

## Commands

| Command              | Description                                                  |
|----------------------|--------------------------------------------------------------|
| `term`               | Shows the configured terminal mode and the one actually in use |
| `counter-add -n <N>` | Adds `N` to a counter (shows an argument hint while typing)  |
| `counter-show`       | Prints the counter                                           |
| `counter-reset`      | Resets the counter to 0                                      |
| `history`            | Lists the in-memory command history, numbered from 1         |
| `history -c`         | Clears the history (UP/DOWN recall too)                      |
| `sync`               | Saves the history to `/data/history.txt` on the "storage" partition |

`history` and `sync` are registered by the component itself because the example sets `cli_config_t.history_sync = true`.

## How to Use

### Build and Flash

```bash
idf.py -p PORT flash monitor
```

(Replace `PORT` with the serial port name, e.g., `/dev/ttyUSB0` or `COM3`.)

### Try It

1. Run `term`. It should report `Mode in use: line editing`. If it reports `dumb`, see [Terminal Mode](#terminal-mode) below.
2. Type `cou` and press **TAB**. The line completes to `counter-add`. Press **TAB** again to cycle through `counter-reset` and `counter-show`.
3. Type `counter-add` followed by a space. The hint `-n <value>` appears after the cursor.
4. Run `counter-add -n 5`, then `counter-show`. Press **UP** and **DOWN** to browse them.
5. Type a few characters and press **Backspace**. Each press erases a character and moves the cursor back.
6. Run `history` to list everything typed so far, then `history -c` to clear it. Press **UP**: nothing is recalled.
7. Run `sync` to save the history to flash, then reset the board. `history` and **UP** still show the saved commands.

### Example Output

```bash
=== CLI-API Terminal Example ===
Try the line editing features:
  TAB        complete a command (type 'cou', then TAB again to cycle)
  UP/DOWN    browse previous commands
  Backspace  erase the last character

Commands:
  term               show the configured and in-use terminal mode
  counter-add -n N   add N to the counter (watch the hint while typing)
  counter-show       print the counter
  counter-reset      reset the counter
  history [-c]       list (or clear) the command history
  sync               save the history to flash
================================

term> term
Configured mode: Auto-detect
Mode in use:     line editing

term> counter-add -n 5
Counter: 5

term> counter-show
Counter: 5

term> history
   1  term
   2  counter-add -n 5
   3  counter-show
   4  history

term> history -c
History cleared
```

## Terminal Mode

Line editing needs a terminal that understands VT100 escape sequences. The component picks the mode at boot according to `idf.py menuconfig` > `CLI API Configuration` > `Terminal mode`:

| Option               | Behavior                                                                 | When to pick it |
|----------------------|--------------------------------------------------------------------------|-----------------|
| Auto-detect (default) | Sends a Device Status Request (`ESC[5n`) at boot; line editing if the terminal answers, dumb mode otherwise. USB Serial JTAG always gets line editing. | Most setups (`idf.py monitor`, PuTTY, Windows Terminal, VS Code). |
| Force line editing   | Skips the probe, always line editing.                                    | Your terminal supports VT100 but `term` reports `dumb` under Auto. |
| Force dumb mode      | Skips the probe, always dumb mode (plain line input, no TAB/arrows).      | Web Serial pages and other hosts that print escape sequences as text. |

This example's [sdkconfig.defaults](sdkconfig.defaults) selects Auto and lists the other two options as comments.

## Code Highlight

Turning on `history_sync` registers both `history` and `sync`:

```c
cli_config_t cli_cfg = {
  .prompt = "term> ",
  .register_help = true,
  .history_sync = true, /* registers 'history' and 'sync' */
};
ESP_ERROR_CHECK(cli_init(&cli_cfg));
```

A command with arguments and `.hint = NULL` gets its hint generated from those arguments:

```c
static const cli_command_t counter_add_cmd = {
  .name = "counter-add",
  .description = "Adds a value to the counter",
  .hint = NULL, /* NULL: esp_console builds the hint from the arguments */
  .callback = cmd_counter_add,
  .args = {{.short_opt = "n", .long_opt = "value", .datatype = "<value>",
            .description = "Value to add (may be negative)", .type = CLI_ARG_TYPE_INT, .required = true}},
  .arg_count = 1,
};
```

## Project Structure

```text
examples/terminal/
├── CMakeLists.txt
├── partitions_example.csv
├── sdkconfig.defaults
├── README.md
└── main/
    ├── CMakeLists.txt
    ├── idf_component.yml
    └── main.c
```

To create a project from this example, run:

idf.py create-project-from-example "pedroluisdionisiofraga/cli-api=1.2.1:terminal"

or download archive (~5.51 KB)