当前位置: 首页 > 工具软件 > Kilo Editor > 使用案例 >

1k行代码的编辑器-kilo源码分析

戚哲
2023-12-01

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






 类似资料: