readline是linux下常用的CLI交互式开源库,readline可以实现命令编辑,自动命令补全,历史命令搜索等人性化的交互方式。
系统实现了rl_filename_completion_function和rl_username_completion_function自动补全,实现自定义命令的自动补全需要实现rl_attemped_completion_function函数。
工作原理:
1.通过rl_complete()调用rl_completion_matches()来产生补全字符。
2.rl_completion_matches() 使用程序提供的generator函数产生补全字符。
3.generator函数会在rl_completion_matches()中不断调用,每次返回一个字符串。
Generator( const char *text,int state ) 第一个参数为当前输入字符,state为调用次数。第一次调用返回补全字符串,第二次必须返回0,终止匹配过程,否则会陷入死循环(不知API为何如此设计)。
具体补全参见:$(READLINE)/examples/fileman.c
调用代码:
initialize_readline() rl_attempted_completion_function = fileman_completion; fileman_comletion() matches = rl_completion_matches (text, command_generator);
// 命令补全
char *command_generator ( const char *text, int state )
{
static int list_index, len;
char *name;
// 第一次查找
if (!state)
{
list_index = 0; // 注:该list_index一定要设置为static,下次再调用时无法找到name而结束匹配过程
len = strlen (text);
}
// 遍历命令列表
while (name = commands[list_index].name)
{
list_index++;
// 如部分匹配,则返回该name
if (strncmp (name, text, len) == 0)
{
return dupstr(name);
}
}
// 无名称匹配,找到NULL
return ((char *)NULL);
}