我试图为游戏中的 lua 控制台制作自动完成和历史功能。有人建议我使用 readline 库(准确地说是它的 BSD 模拟 libedit,但它有类似的 apis 和 rl-code 构建,但标题略有变化),我选择了带有历史补丁的 lua-rlcompleter 的lua 绑定。历史运作良好,但我对 readline 功能有一些问题。对于自动完成,我需要将 lua 字符串传递给 readline 函数,但默认情况下此函数从标准输入读取。我找到了将 rl_instream 更改为 FILE* 的解决方案。为此,我创建了 tmpfile 并写入它。但它的工作原理很奇怪,以这种方式读取字符串时,readline 什么也不返回。
// This definitions is just example, not working code
// it shows the environment
static FILE *tempfile = tmpfile();
rl_instream = tempfile;
rl_initialize();
static int lreadline(lua_State *L)
{
const char *prompt = lua_tostring(L, 1);
char *line;
if(rl_instream == NULL)
// In case we using stdin
line = readline(prompt);
else{
fputs(prompt, tempfile);
/* maybe I need a fseek here? It not helps though.
* fseek(tempfile, -strlen(prompt), SEEK_CUR);
*/
line = readline(NULL);
}
lua_pushstring(L, line);
free(line);
return 1;
}
我不确定发生了什么,但认为它可能与 readline 函数文件中的读取位置有关。我试图阅读 libedit 的源代码,但为什么我的代码不能按预期工作是没有意义的。由于使用 Eclipse 调试共享库时出现问题,我无法对此进行调试,但计划使用纯 gdb,不确定它是否会有所帮助。
另外,也许我做错了,还有另一种简单的方法可以在基于 lua 的控制台模拟器中自动完成和历史记录?