# pan menu — Interactive Tree Menu
Displays a hierarchical menu from JSON input and lets the user navigate, expand/collapse branches, and select a leaf node.
## Usage
```
pan menu [OPTIONS] [FILE]
```
## Arguments
| `FILE` | Path to input file (reads stdin if empty)|
## Options
| `-f`, `--format` | `auto` | Input format: auto, json, plano |
| `-t`, `--title` | `"Menú"` | Title in the popup header |
| `-W`, `--width` | `0` (auto) | Popup width |
| `-H`, `--height` | `0` (auto) | Popup height |
| `--guide` | | Show this guide |
## Format detection
When `--format auto` (default), the format is detected from the file extension:
| `.json` | json |
| other | plano |
For stdin (no FILE argument), defaults to `plano`.
## Input formats
### JSON
```json
[
{
"id": 1,
"text": "Option 1",
"children": [
{ "id": 2, "text": "Sub-option 1" }
]
}
]
```
| `id` | number | Unique id (required, must be unique) |
| `text` | string | Display text |
| `children` | array | Optional nested nodes |
### Plano
One path per line, segments separated by `/`:
```
Archivo/Nuevo/Documento
Archivo/Abrir
Editar/Deshacer
```
Ids are auto-generated. No comments.
## Output
On selection, prints the full path from root to leaf, segments joined by `/`:
```
Editar/Deshacer/Deshacer escritura
```
## Exit codes
| 0 | Selection made (text on stdout) |
| 1 | User cancelled (no output) |
## Capturar la selección en bash
> ⚠️ **No uses `$(pan menu ...)`** para capturar el resultado.
> La sustitución de comandos `$()` crea un subshell que desconecta el TTY,
> por lo que `pan menu` no puede leer el teclado ni mostrar la interfaz.
Usa un **archivo temporal** con redirección `>` y `read`:
```bash
#!/bin/bash
ENTRY_FILE=$(mktemp /tmp/pan_menu.XXXXXX)
trap 'rm -f "$ENTRY_FILE"' EXIT
pan menu -t "Menú" menu.txt > "$ENTRY_FILE" < /dev/tty
read -r SEL < "$ENTRY_FILE"
case "$SEL" in
"Opción 1") echo "elegiste 1" ;;
"Salir") exit 0 ;;
esac
```
Si no tienes acceso a `/dev/tty`, abre stdin explícitamente:
```bash
pan menu -t "Menú" menu.txt > "$ENTRY_FILE" 0<&-
```
### Bucle hasta salir
```bash
while true; do
pan menu -t "Menú" menu.txt > "$ENTRY_FILE" < /dev/tty
[ $? -ne 0 ] && break
read -r SEL < "$ENTRY_FILE"
[ "$SEL" = "Salir" ] && break
# procesar $SEL
done
```
## Examples
```bash
# JSON file (auto-detected)
pan menu menu.json
# Plano file (auto-detected from .txt)
pan menu menu.txt
# Explicit format
pan menu -f plano menu.txt
# Pipe stdin (defaults to plano)
printf 'Archivo/Nuevo\nArchivo/Abrir\n' | pan menu
# Custom title
pan menu menu.json -t "Projects"
# Explicit size
pan menu menu.json -W 60 -H 20
```
## Mouse
- **Click item**: select that item
- **Drag**: click and hold the border or title bar to move the popup
## Keyboard
| `↑` / `k` | Navigate up |
| `↓` / `j` | Navigate down |
| `Tab` | Navigate down |
| `Shift+Tab` | Navigate up |
| `Enter` | Expand/collapse branch, or select leaf |
| `→` / `Space` | Expand branch |
| `←` | Collapse branch |
| `gg` | Go to first item |
| `G` | Go to last item |
| `Esc` / `q` | Cancel |
| `Ctrl` + `c` | Emergency exit |