83 lines
2.7 KiB
Markdown
83 lines
2.7 KiB
Markdown
# Tab 命令补全功能实现
|
||
|
||
## 日期
|
||
|
||
2026-06-12
|
||
|
||
## 概述
|
||
|
||
为 CLI 交互实现多级 Tab 命令补全:第一个词补全命令名,后续词根据命令上下文补全子功能。
|
||
|
||
## 实现内容
|
||
|
||
### 1. 数据结构扩展(myCmd.h)
|
||
|
||
`stru_cmd` 增加 `complete` 回调字段:
|
||
|
||
```c
|
||
typedef struct
|
||
{
|
||
const char *name;
|
||
void (*func)(int argc, char *argv[]);
|
||
const char *desc;
|
||
void (*complete)(const char *buf, char ***completions, int *ncomp);
|
||
}stru_cmd;
|
||
```
|
||
|
||
`CMD_REGISTER` 宏改为支持可变参数,`cmd_manager_add_command` 增加默认参数 `complete = NULL`。
|
||
|
||
### 2. 上下文感知补全(my_cmd.cpp)
|
||
|
||
`cmd_complete` 逻辑:
|
||
- 无空格 → 命令名前缀匹配(原行为)
|
||
- 有空格 → 提取第一个词查找命令,调用其 `complete` 回调获取子补全
|
||
|
||
`cmd_sub_complete` 辅助函数:给定子命令列表和前缀,返回匹配项。
|
||
|
||
### 3. 前缀保留修复(my_cmd.cpp)
|
||
|
||
`linenoiseEdit` 中 Tab 键处理原本用补全结果**覆盖整行**,导致子命令补全时命令名前缀丢失。改为找到最后一个空格,只替换空格之后的当前词:
|
||
|
||
```c
|
||
// 修复前:strncpy(buf, completions[0], ...); // 整行覆盖
|
||
// 修复后:
|
||
char *last_space = strrchr_manual(buf, pos);
|
||
if (NULL != last_space)
|
||
strncpy(last_space + 1, completions[0], ...); // 只替换当前词
|
||
else
|
||
strncpy(buf, completions[0], ...); // 第一个词仍覆盖整行
|
||
```
|
||
|
||
### 4. 各模块子补全注册
|
||
|
||
| 命令 | 子命令 |
|
||
|------|--------|
|
||
| `datacenter` | `out`, `in`, `yk`, `ao`, `param`, `all` |
|
||
| `iec` | `run_cnt` |
|
||
| `iec61850m` | `info`, `yk`, `set` |
|
||
| `self_ptl` | `1`, `3`, `5`, `6`, `9`, `11` |
|
||
|
||
### 5. 构建系统修复
|
||
|
||
[release/src/system/makefile](release/src/system/makefile) 中 8 个子模块 SUBDIRS 被注释导致增量编译失效,已取消注释。
|
||
|
||
## 影响文件
|
||
|
||
| 文件 | 改动 |
|
||
|------|------|
|
||
| [myCmd.h](release/inc/myCmd.h) | stru_cmd 增加 complete 字段;CMD_REGISTER 可变参数;cmd_sub_complete 声明 |
|
||
| [my_cmd.cpp](src/public/libcmd/src/my_cmd.cpp) | cmd_complete 上下文感知;cmd_sub_complete;Tab 替换前缀保留 |
|
||
| [dc_signal.cpp](src/system/libdatacenter/src/dc_signal.cpp) | datacenter 子补全 |
|
||
| [iec.cpp](src/system/libiec/src/iec.cpp) | iec 子补全 |
|
||
| [iec61850m.cpp](src/system/libiec61850m/src/iec61850m.cpp) | iec61850m 子补全 |
|
||
| [method.cpp](src/system/libself_ptl/src/method.cpp) | self_ptl 子补全 |
|
||
| [release/src/system/makefile](release/src/system/makefile) | 取消 SUBDIRS 注释 |
|
||
|
||
## 使用效果
|
||
|
||
```
|
||
cmd > d + Tab → datacenter
|
||
cmd > datacenter + p + Tab → datacenter param
|
||
cmd > iec + r + Tab → iec run_cnt
|
||
```
|