kilo简介:A text editor in less than 1000 LOC with syntax highlight and search.
kilo由redis的作者antirez 编写的,代码只有短短的1k行,但是基本功能都有,也有代码高亮。很短但很强大。
其实kilo代码逻辑很简单。顺着main函数看下去就行,数据结构也不复杂。花个小半天捋一捋,差不多能弄懂脉络。
先来看数据结构
语法结构体
struct editorSyntax {
char **filematch;
char **keywords;
char singleline_comment_start[2];
char multiline_comment_start[3];
char multiline_comment_end[3];
int flags;
};
//editor row 一行的数据 主要是idx , chars ,reders hl这个几个变量
typedef struct erow {
int idx; /* 当前行的索引 */
int size; /* 一行的大小*/
int rsize; /* 渲染的一行大小,这个值>= size*/
char *chars; /* 一行数据的原始内容*/
char *render; /* 一行渲染的内容 添加了一些终端控制符*/
unsigned char *hl; /* 高亮类型 如:\003\003,每一个字符都是高亮类型*/
int hl_oc; /* 多行注释标示 */
} erow;
//editConfig是核心配置一切都是围绕这它来进行的。程序中会定义一个静态全局变量,editConfig E。
struct editorConfig {
int cx,cy; /* 光标的x,y位置*/
int rowoff; /* 行偏移量*/
int coloff; /* 列偏移量*/
int screenrows; /* 屏幕能显示多少行*/
int screencols; /* 屏幕能显示多少列*/
int numrows; /* 实际多少行*/
int rawmode; /* raw 模式*/
erow *row; /* Rows 真正的内容 row指针,row行指针 row[0] row[1] 以numrows数量,因为内存中连续存储的,所以就可以for numrows来遍历所有的row*/
int dirty; /* 文件内容是否被修改*/
char *filename; /* 文件名字*/
char statusmsg[80]; //状态
time_t statusmsg_time; //状态条时间
struct editorSyntax *syntax; /* 语法高亮 */
};
下面是main函数
initEditor();
editorSelectSyntaxHighlight(argv[1]);
editorOpen(argv[1]);
enableRawMode(STDIN_FILENO);
editorSetStatusMessage(
"HELP: Ctrl-S = save | Ctrl-Q = quit | Ctrl-F = find");
while(1) {
editorRefreshScreen();
editorProcessKeypress(STDIN_FILENO);
}
static struct editorConfig E;
initEditor 就是初始化全局变量E
editorSelectSyntaxHighlight(argv[1]); 根据文件的后缀类型,判断用什么的高亮方法
editorOpen(argv[1]);
E中的erow指针后面是一段连续的erow类型结构内存,数量是numrows个,erow是头指针。
读取文件内容,放到E.erow连续内存中
读取一行,原始数据放置到erow中的chars中,渲染后的数据放到erow的render中
enableRawMode(STDIN_FILENO);
启用终端的raw模式
editorSetStatusMessage(
"HELP: Ctrl-S = save | Ctrl-Q = quit | Ctrl-F = find");
设置底部的状态信息栏,占两行
真正的主逻辑是下面的几行
while(1) {
editorRefreshScreen();
editorProcessKeypress(STDIN_FILENO);
}
简单说就是editorRefreshScreen();
将ebow数组中的数据 存放到abuf的b变量中
struct abuf {
char *b;
int len;
};
然后write到终端输出
editorProcessKeypress(STDIN_FILENO);
读取键盘的input输入,进行相应的处理
插入新行,保存,查找,删除一行,添加字符,换行等
都是操作erow中的原始数据chars,对应的进行erow中的render更新。
然后由editorRefreshScreen函数更新到屏幕上。
大概的说明是这些。当然远远不止这些。具体可以我写的源码的注释
kilo注释源码下载
------------------------------------------------------------------------
也可以查看我的github,fork的kilo分支
https://github.com/prownd/kilo