C 实现Tab补全命令

1.GUN C readline Library

用过Bash的朋友,都知道Bash有一个键自动补全,那么,它是通过什么实现的呢?
没错,就是readline这个库。
一开始这是Bash内置的库,不过之后把它独立了出来。。。
2.readline库的使用
原型

  1. 读取输入的文本
    `char *readline (const char *prompt);
  • prompt 提示符(例如bash的$)
  1. 绑定函数
    char **rl_completion_matches(const char *text, rl_compentry_func_t *entry_func);
  • text 输入内容
  • entry_func 结构体指针
    原型:typedef char *rl_compentry_func_t(const char *text, int state);

3.具体实现

  • 需要的头文件
#include <stdio.h>
#include <readline/readline.h>
#include <stdbool.h>
#include <string.h>
  • 定义COMMAND结构体,存储命令和对应函数指针
typedef struct {
    char *name;
    // 根据需要,修改函数入参及其返回值
    void (*func)(int status);
} COMMAND;
  • 存储命令及其对应函数
COMMAND commands[] = {
    {"exit", exit}
};
  • 实现命令补全算法
char * command_generator(const char *text, int state) {
    char *name = NULL;
    if (!state) {
        // 迭代命令列表
        for (int i = 0; (name = commands[i].name); i++) {
           // 判断输入命令与输入部分完全一致
            if (!strncmp(name, text, strlen(text))) {
               // 返回完整命令名称并结束函数
                return strdup(name); 
            }
        }
    }
    // 若没有匹配的命令,则返回空指针
    return NULL;
}
  • 实现对外接口
char **command_complete(const char *text, int start, int end) {
    char **matches = NULL;
    if (!start) {
        matches = rl_completion_matches(text, command_generator);
    }
    return matches;
}
  • 执行命令
void execute(char *text) {
    // 迭代命令列表
    for (int i = 0; i < sizeof(commands) / sizeof(COMMAND); i++) {
       // 判断命令与命令列表相同
        if (!strcmp(text, commands[i].name)) {
           // 真正执行命令(这里根据自己需要修改参数"0")
            (*(commands[i].func))(0);
            break;
        }
    }
}
  • 主函数
int main(void) {
    // 定义临时变量,存储命令
    char *text = NULL;
    // 设置补全函数command_complete
    rl_attempted_completion_function = command_complete;
    // 循环监听输入
    while (true) {
        // 存储输入
        text = readline("nsf > ");
        // 判断命令是否为空
        if (text) {
            // 执行命令
            execute(text);
        }
    }
}
posted @ 2022-02-15 10:49  当地微  阅读(899)  评论(0)    收藏  举报