Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions docs/cli_commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,46 @@ This document provides an overview of CLI commands that can be sent to MeshCore

---

#### Bulk-define region hierarchy (single line)
**Usage:**
- `region bulk <token> [<token> ...]`

**Parameters (tokens):** Space-separated. A logical **cursor** starts at the wildcard `*`.

- **`name`** — Create `name` as a child of the current cursor (same as `region put name` with that parent). Cursor moves to `name`.
- **`name|jump`** or **`name,jump`** — Create `name` as a child of the current cursor, then move the cursor to `jump` (must already exist: created earlier in this command or already on the node). `jump` is **not** the parent of `name`; use this to pop back up and start another branch.

**Note:** Same flood defaults as `region put` (flood allowed on each created region).

**Note:** Does **not** persist to flash. The reply is the region tree (same format as bare `region`) so you can review before **`region save`**.

**Note:** On error, the reply is a short `Err - ...` message; regions placed before the failure remain (same as a partial chain of `region put`).

**Note:** Repeater serial accepts one line up to **160 characters** total; split very large trees across multiple `region bulk` commands.

**Note:** `|` only splits once per token. `region bulk a|b|c|d` is **not** a flat-list shorthand — use `region bulk a|* b|* c|* d|*` for multiple children of `*`.

**Example — linear chain:**
```
region bulk west pnw wa w-wa sea
region save
```

**Example — branched tree** (equivalent to `region put west` … `region put sw-wa wa`):
```
region bulk west pnw or pdx|pnw wa sw-wa
region save
```
Same with comma as jump delimiter: `region bulk west pnw or pdx,pnw wa sw-wa`

**Example — flat list** (each region child of `*`):
```
region bulk west|* pnw|* or|* pdx|* wa|* sw-wa
region save
```

---

#### Remove a region
**Usage:**
- `region remove <name>`
Expand Down
64 changes: 64 additions & 0 deletions src/helpers/CommonCLI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,70 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep
void CommonCLI::handleRegionCmd(char* command, char* reply) {
reply[0] = 0;

// `region bulk ...` — cursor-walk over space-separated tokens (must run before
// parseTextParts, which only keeps 4 segments and mutates the buffer).
char* cmd = command;
while (*cmd == ' ') cmd++;
if (strncmp(cmd, "region bulk", 11) == 0 && (cmd[11] == ' ' || cmd[11] == '\0')) {
char* payload = cmd + 11;
while (*payload == ' ') payload++;
if (*payload == '\0') {
snprintf(reply, 160, "Err - empty bulk");
return;
}
RegionEntry* cursor = &_region_map->getWildcard();
char* p = payload;
while (*p) {
while (*p == ' ') p++;
if (*p == '\0') break;
char* tok = p;
while (*p && *p != ' ') p++;
if (*p) *p++ = '\0';

char* jump = nullptr;
for (char* q = tok; *q; q++) {
if (*q == '|' || *q == ',') {
*q = '\0';
jump = q + 1;
break;
}
}
char* name = tok;
while (*name == ' ') name++;
if (jump) {
while (*jump == ' ') jump++;
char* je = jump + strlen(jump);
while (je > jump && je[-1] == ' ') *--je = '\0';
}
if (*name == '\0') {
snprintf(reply, 160, "Err - empty name");
return;
}
if (jump && *jump == '\0') {
snprintf(reply, 160, "Err - empty jump");
return;
}
auto r = _region_map->putRegion(name, cursor->id);
if (r == NULL) {
snprintf(reply, 160, "Err - put failed: %s", name);
return;
}
r->flags = 0;
if (jump) {
auto j = _region_map->findByNamePrefix(jump);
if (j == NULL) {
snprintf(reply, 160, "Err - unknown jump: %s", jump);
return;
}
cursor = j;
} else {
cursor = r;
}
}
_region_map->exportTo(reply, 160);
return;
}

const char* parts[4];
int n = mesh::Utils::parseTextParts(command, parts, 4, ' ');
if (n == 1) {
Expand Down
Loading