C中的选项卡完成(readline库)

时间:2011-08-30 00:57:40

标签: c tabs readline libreadline

我一直试图让标签完成工作..我很困惑,不知道该怎么做。你能不能看看我的代码并告诉我如何解决它。

顺便说一下,我使用rl_attempted_completion_function,因为我从在线教程中得到它,但它是一个C ++函数。我可以使用什么功能来替换它而无需进行更改。

由于

   static char** completion( const char * text , int start,  int end){
            char **matches;
            matches = (char **)NULL;

            if (start == 0)
                    matches = rl_completion_matches ((char*)text, &generator);

            return (matches);
    }

    char* generator(const char* text, int state) {
            int index, len;
            char *comm;
            if (!state) {
                    index = 0;
                    len = (int)strlen (text);
            }

            while ( (*comm = newEnv[index])) {
                    index++;
                    if (strncmp (comm, text, len) == 0)
                            return ((comm));
            }
            return NULL;
    }

    int main (int argc,  char * argv[]) {

            using_history();
            rl_readline_name = basename(argv[0]);

            rl_attempted_completion_function = completion;

            while ( readline(">> ")!= NULL )  
                    rl_bind_key('\t',rl_complete);

            return 0;
    }

3 个答案:

答案 0 :(得分:2)

我注意到了这一点:

char *comm;
...
while ( (*comm = newEnv[index])) {

我不知道newEnv的返回类型是什么,但您可能希望将其放在comm中,而不是*comm,因为您没有指出{{1}任何事情。

答案 1 :(得分:1)

您的代码与readline手册中的示例非常相似。我看到的错误是你没有在生成器函数中声明index和len为 static

答案 2 :(得分:0)

如Tom Zych的最高答案所述,您应将*comm = newEnv[index]更改为comm = newEnv[index]

但是我也看到了其他一些问题

其中之一,这两个变量应该是静态的:

int index, len;

像这样: 静态整数索引len;

否则,您总是返回第一个匹配项(如果存在匹配项,我认为您可能会陷入无限循环)。使这些为静态可以使后续对非零状态的调用从最后一次匹配开始寻找匹配。如果我理解正确的话,对于每个制表符完成请求的第一次完成建议搜索,您都会获得0状态(将静态索引重置为0)

仅在状态为0时查找输入的长度是一种优化(由于将获得相同的输入,因此可以对它进行“缓存”),但是静态索引不是:这是必需的

接下来,您应该更改

return ((comm));

收件人

return strdup(comm);

最后,将完成更改为:

char **completion(const char *text, int start, int end)
{
    return rl_completion_matches(text, generator);
}

不需要0开始检查

此外,请确保newEnv数组的末尾具有NULL值,如下所示:

char* envVar[] = {"a", "b", NULL};

此外,请确保在generator中使用completion之前先声明或定义{{1}}