linenoise源码解析

原创 2016年06月01日 20:59:36

一、简介:

linenoise是一个命令行编辑库(line editing library),readline的替代品,可以用于tab自动补全方法的实现。目前linenoise已经在Redis, MongoDB,Android中使用。其支持特性如下:


1) 尽可能简小,无配置,支持BSD授权。

2) 单行或多行编辑模式,实现常用的快捷键绑定。

3)支持历史键入文本查询。

4)兼容性。

5)大约只有1100行代码。

6)只使用VT100 escapes键码的子集。

注:readline是一个提供了交互式的文本编辑功能的开源跨平台程序库,它最早由Brian Fox使用C语言开发,于1989年发布。


二、文件构成:

linenoise库核心文件仅仅是linenoise.c和linenoise.h,在linenoise.h中定义了一个数据结构linenoiseCompletions,用于记录一行行完整的匹配输入。

typedef struct linenoiseCompletions {
  size_t len;
  char **cvec;
} linenoiseCompletions;

其中:

a)len表示完整的匹配输入的数目。

b)cvec相当于一个二维字符数组char[len][ ],用于记录len条匹配输入。

注意:真正的匹配输入需要在自己的注册函数中完成,也就是linenoise中的completionCallback。


三、函数调用:

linenoise.c中定义了很多函数,下面几个图方便大家理清各函数之间的关系:

图3.1 函数调用图
1、其中completionCallback是定义的函数指针。
static linenoiseCompletionCallback *completionCallback = NULL;
再来看看linenoise.h文件中的函数定义:
typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *);
void linenoiseSetCompletionCallback(linenoiseCompletionCallback *);
2、completionCallback就是需要用户自己去定义和实现的匹配自动补全方法。
3、函数char *linenoise(const char *prompt);是提供给用户去调用的API接口。


图3.2 History函数调用

4、函数通过linenoiseHistoryLoad提供用户加载文件中的history记录,需要用户自己调用。

其实linenoiseHistoryLoad也是通过linenoiseHistoryAdd来添加history历史记录的,linenoiseHistoryAdd也可以供用户自己调用。

5、对于与linenoise edit相关度函数都是在completeEdit()函数中调用的,具体代码就不再赘述。


四、示例代码:

由于completionCallback函数需要用户自己去定义的自动补全方法,下面是一个示例代码,仅供参考。

SYS_CMD cmd[SYS_CMD_NUM] = {
    {"enable",      ENABLE},
    {"disable",     DISABLE},
    {"log",         LOG},
    {"dump",        DUMP},
    {"all",         ALL},
    {"status",      0},
    {"help",        0},
    {"exit",        0},
};
list<MENU_PAIR> componentList;

void tabCompletion(const char *buf, linenoiseCompletions *lc) {
    unsigned int  index =0, uLen = 0;
    const char *pLastWord = NULL;
    char *completion = NULL;

    if (buf) {
        pLastWord = buf;
        if (strlen(buf) > 0) {
            pLastWord += strlen(buf) - 1;
            while (uLen < strlen(buf) && *pLastWord != ' ') {
                pLastWord--; uLen++;
            }
            pLastWord++;
            uLen = strlen(pLastWord);
        }
        uLen = strlen(buf) - uLen;
        completion = (char *)malloc(sizeof(char) * (uLen + MAX_CMD_LEN));
        if (completion == NULL) {
            return;
        }
        memset(completion, 0, sizeof(char) * (uLen + MAX_CMD_LEN));
        strncpy(completion, buf, uLen);
        for(index = 0; index < SYS_CMD_NUM; index++) {
            if(strncmp(cmd[index].cmd, pLastWord, strlen(pLastWord)) == 0){
                strcpy(&completion[uLen],cmd[index].cmd);
                linenoiseAddCompletion(lc,completion);
            }
        }
        free(completion);
    }
}


linenoise 源码分析(一)

linenoise,一个命令行编辑库(line editing library)的源码分析
  • u012842205
  • u012842205
  • 2016年03月31日 09:58
  • 1704

linenoise 源码分析(二)

linenoise 命令行编辑库源码分析,linenoiseState结构体,history模块。
  • u012842205
  • u012842205
  • 2016年04月01日 12:59
  • 739

linenoise 源码分析(一)

linenoise,一个命令行编辑库(line editing library)的源码分析
  • u012842205
  • u012842205
  • 2016年03月31日 09:58
  • 1704

深入源码分析go类型系统

深入源码分析go类型系统   Ø runtime/type.h    go类型描述的静态信息 //type  go类型最通用定义,go的类型系统通过这个数据结构来进行驱动 /...
  • hittata
  • hittata
  • 2016年03月17日 17:23
  • 1621

深度解读 AlphaGo 算法原理

深度解读AlphaGo
  • songrotek
  • songrotek
  • 2016年04月05日 22:07
  • 53259

linenoise 源码分析(一)

linenoise,一个命令行编辑库(line editing library)的源码分析
  • u012842205
  • u012842205
  • 2016年03月31日 09:58
  • 1704

linenoise 源码分析(二)

linenoise 命令行编辑库源码分析,linenoiseState结构体,history模块。
  • u012842205
  • u012842205
  • 2016年04月01日 12:59
  • 739

【MyBatis源码分析】mappers解析属性配置元素详述

mapper加载 config.xml中两个最重要的标签,一个是(JDBC环境信息),另一个就是mapper(sql文件映射)了。 Mapper映射文件是一个xml格式文件,必须遵循相应的...
  • qq_35807136
  • qq_35807136
  • 2018年01月17日 16:33
  • 2

java日志系统--log4j配置解析过程,源码分析

Logger.getLogger(Test.class);从getLogger开始,就启动了log4j的整个工作流程,通过调用LogManager获取logger实例return LogManager...
  • c5113620
  • c5113620
  • 2018年01月17日 15:49
  • 22

Glide源码解析(二)

上面一篇我们讲了Glide的with方法,没有看的请戳Glide源码解析(一), 这篇我们来看Glide的load方法,with方法返回的是一个GlideRequests,那么load肯定是在这个类里...
  • pmx_121212
  • pmx_121212
  • 2018年01月17日 14:08
  • 3
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linenoise源码解析
举报原因:
原因补充:

(最多只允许输入30个字)