# 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 ```