2015-10-26 59 views
4

我能够给用户输入限制为5个字符使用GNU readlinereadline的使用默认值

#include <readline/readline.h> 
#include <stdio.h> 
#include <stdlib.h> 

static int limit_rl(FILE *f) 
{ 
    if (rl_end > 5) { 
     return '\b'; 
    } 
    return rl_getc(f); 
} 

int main(void) 
{ 
    char *str; 

    rl_getc_function = limit_rl; 
    str = readline("> "); 
    printf("%s\n", str); 
    free(str); 
    return 0; 
} 

但是,如何读取默认值(不提示)输入,如:

> ummy 
^cursor here 

如果用户类型d输入回归 “虚拟”

如果用户类型DEL输入返回“MMY”

+0

你的意思是'ummy'应该存在了吗? – ameyCU

+3

查看'rl'示例 - 可以设置一次执行'rl_insert_text'的启动钩子('rl_startup_hook'),然后禁用它自己。 – usr2564301

+0

@ameyCU,是的,它必须出现在'rl_line缓冲区'和屏幕 –

回答

2

在一个可能的用途是提到的readline主页:

rl.c是使用的ReadLine读取输入的来自线路的示例方案用户并将其回显到标准输出,适用于shell脚本。

由于编辑一个现有的条目可能是其中的一部分,我决定看看它的源代码(direct download link)。这确实显示了如何将其显示在屏幕上,通过使用钩子函数的前插入一个字符串成readline使用的缓冲区:

变量:rl_hook_func_t * rl_startup_hook

如果非零,则这是在readline打印第一个提示之前要调用的函数的地址。
https://cnswww.cns.cwru.edu/php/chet/readline/readline.html#IDX223

内部钩子函数可以直接操纵内部缓冲区,例如插入文本:

函数:int rl_insert_text常量字符*文本

插入文本进入当前光标位置处的行。返回插入的字符数。
https://cnswww.cns.cwru.edu/php/chet/readline/readline.html#IDX295

钩子函数只需做一次(它被称为每readline调用一次内部readline_internal_setup),但显然RL的作者去了皮带和吊带的做法,特别禁用它在它被使用之后。

rl.c相关片断,评论,都是我的

/* a global char * to hold a default initial text */ 
static char *deftext; 

/* the callback function. The argument is supposed to be 'void' per 
    its declaration: 
     typedef int rl_hook_func_t (void); 
    so you cannot provide the default text here */ 
static int set_deftext() 
{ 
    if (deftext) 
    { 
     /* Apparently the "current cursor position" in which text is inserted 
     is 0, when initially called */ 
     rl_insert_text (deftext); 
     deftext = (char *)NULL; 

     /* disable the global 'rl_startup_hook' function by setting it to NULL */ 
     rl_startup_hook = (rl_hook_func_t *)NULL; 
    } 
    return 0; 
} 

// ... 
if (deftext && *deftext) 
    rl_startup_hook = set_deftext; 

temp = readline (prompt);