gpt4 book ai didi

c++ - Readline:如何在双选项卡上列出所有自动完成匹配项?

转载 作者:太空宇宙 更新时间:2023-11-04 04:37:50 24 4
gpt4 key购买 nike

我正在使用“readline”库为我的程序创建控制台界面。我可以使用 tab 自动完成单词,但是当我有共享相同前缀的单词时,例如 (car, card, carbon) 它总是选择最短的一个。这是我的程序(主要取自 link ):

#include <readline/readline.h>
#include <readline/history.h>
#include <stdlib.h>
#include <iostream>

const char *words[] = {"add", "remove", "rm", "update", "child", "children", "wife", "wifes"};

void *xmalloc (int size)
{
void *buf;
buf = malloc (size);
if (!buf)
{
fprintf (stderr, "Error: Out of memory. Exiting.\n");
exit (1);
}
return buf;
}

char *dupstr (const char *str)
{
char *temp;
temp = (char *) xmalloc (strlen (str) + 1);
strcpy (temp, str);
return (temp);
}

char *my_generator (const char *text, int state)
{
static int list_index, len;
const char *name;

if (!state)
{
list_index = 0;
len = strlen (text);
}

while (name = words[list_index])
{
list_index++;
if (strncmp (name, text, len) == 0) return dupstr (name);
}

// If no names matched, then return NULL.
return ((char *) NULL);
}

static char **my_completion (const char *text, int start, int end)
{
char **matches = (char **) NULL;
if (start == 0)
{
matches = rl_completion_matches ((char *) text, &my_generator);
}
else rl_bind_key ('\t', rl_abort);
return matches;
}

int main (int argc, char *argv[])
{
char *buf;
rl_attempted_completion_function = my_completion;

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

if (strcmp (buf, "exit") == 0) break;
else if (buf[0] == '\0') continue;
else
{
std::cout << buf << std::endl;
add_history (buf);
}
}
free (buf);

return 0;
}

是否可以像在 ubuntu 终端中一样在双 tab 上列出所有匹配项?

最佳答案

我设法通过注释掉这两行让它工作:

rl_bind_key ('\t', rl_complete);

和:

else rl_bind_key ('\t', rl_abort);

readline 的默认完成行为与 ubuntu 终端完全一样,一个选项卡完成,两个选项卡列出可能的完成。不确定与 Tab 键绑定(bind)的默认完成函数是什么,来自 documentation我认为它是 rl_possible_completions 但它没有给出相同的结果。

我还在 my_completion 函数中添加了以下行,以防止在匹配词的末尾添加空格:

rl_completion_append_character = '\0';

我删除了 dupstrfunction 它并用原生的 strdup 函数代替它(这与自动完成问题无关,只是为了删除不必要的代码) .

这是最终代码:

#include <readline/readline.h>
#include <readline/history.h>
#include <stdlib.h>
#include <iostream>

const char *words[] = {"add", "remove", "rm", "update", "child", "children", "wife", "wives"};

// Generator function for word completion.
char *my_generator (const char *text, int state)
{
static int list_index, len;
const char *name;

if (!state)
{
list_index = 0;
len = strlen (text);
}

while (name = words[list_index])
{
list_index++;
if (strncmp (name, text, len) == 0) return strdup (name);
}

// If no names matched, then return NULL.
return ((char *) NULL);
}

// Custom completion function
static char **my_completion (const char *text, int start, int end)
{
// This prevents appending space to the end of the matching word
rl_completion_append_character = '\0';

char **matches = (char **) NULL;
if (start == 0)
{
matches = rl_completion_matches ((char *) text, &my_generator);
}
// else rl_bind_key ('\t', rl_abort);
return matches;
}

int main (int argc, char *argv[])
{
char *buf;
rl_attempted_completion_function = my_completion;

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

if (strcmp (buf, "exit") == 0) break;
else if (buf[0] == '\0')
{
free (buf);
continue;
}
else
{
std::cout << buf << std::endl;
add_history (buf);
}

free (buf);
buf = NULL;
}
if (buf != NULL) free (buf);

return 0;
}

关于c++ - Readline:如何在双选项卡上列出所有自动完成匹配项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29301242/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com