hecto - 手把手教你写个 文本编辑器
https://www.philippflenker.com/hecto/ 的阅读笔记。 我是学完[[Rust权威指南]] 之后才看的这个。
手把手教你写个 文本编辑器(1300+行代码)。
作者是真有耐心,真手把手教。看文章+手敲一遍,我大概花了十几个小时。
收获很大,很值得。
文章目录
- day1 环境搭建
- day2 读用户输入
- day3 原始输入和输出
- day4 查看文件
- day5 编辑文件
- day6 搜索
- day7 语法高亮
day1 环境搭建
https://www.philippflenker.com/hecto-chapter-1/
就是初始化项目。
day2 读用户输入
https://www.philippflenker.com/hecto-chapter-2/
介绍了 io的模式。
默认模式是缓冲i/o , 缓冲i/o 是遇到回车才发送给用户程序。
但是文本编辑器需要即时i/o, 即没输入1个字符,程序都需要立即拿到。
第三方库termion
可以让我们使用 raw mode
(即时I/O)。
之所以stdout().into_raw_mode().unwrap()
是因为stdout 才是控制 终端模式的。
变量名_stdout
之所以加个_
是rust 的所有权机制导致的。
如果不加,会马上释放掉,从而丢失了状态。
提到了控制字符和打印字符。
0-31,127 都是控制字符。
32-126 都是打印字符。
ctrl+x
就是把x的前3位置0了。
二进制表示用{:#b}
占位符。
提到了错误处理。。rust
是用Result
来传递错误。Result
是个枚举,要么有值,有么错误。 unwrap
就是配合Result
使用的。如果值正常,就返回值,否则panic
。
提到了match
模式匹配。
day3 原始输入和输出
https://www.philippflenker.com/hecto-chapter-3/
讲的就是不要重复造轮子,直接用termion
实现按键的检测。
Key::Char
,Key::Ctrl
,Key::Alt
等
去掉了底层的处理,,
从处理字节 变成了处理字符。
提到了Matches
必须穷举。
提到了分离代码。。main只提供入口,尽量精简。
然后没有;
的语句是表达式,也是函数的返回值。
struct
里的函数,第一个参数不是&self
的是关联函数,也叫静态方法。否则就是关联方法。
cargo clippy
可以提供一些建议,让我们的代码更地道。
提到了转义序列 可以指示中断干些事,譬如为文本着色啥的。
x1b[2J
x1b
= 按下esc
具体说明看vt100
J
是清除屏幕命令
2
是J
的参数。0表示清除cursor-end 位置的屏幕。1表示清除start-cursor 位置的屏幕。2表示清除start-end 位置的屏幕。默认值是0
然后关于转义序列的知识 termion
也封装好了。
控制鼠标的位置,也是用的转义序列。用的H
命令。譬如\x1b[12;40H
鼠标显示在12行,40列。
使用了pub use terminal::Terminal;
重导出声明,这样后面用的时候 直接用Terminal
就可以了
saturating_add
用户防止移除的。。譬如u8 最大致是255
直接 255+1 = 0
但是使用 255.saturating_add(1) 返回的是255, 可能产生溢出时,直接返回最大值。
隐藏/显示 鼠标 这里也是转义序列:
x1b[25h
隐藏。x1b[?25l
x1b[25l
显示。 x1b[?25h
第一次提到了解构。 let Position{mut x, mut y} = position;
day4 查看文件
https://www.philippflenker.com/hecto-chapter-4/
新增Row
, 和 Document
结构体。
引入了宏#[derive(Default)]
这玩意是实现代码的代码,会自动给你实现Default
方法。
引入了From
trait, 这个用于类型转换的。用的挺多的。
例子中就是把&str
转成了Row
对象。
Since we have implemented default
on Document
, we can use unwrap_or_default
here.
现在才懂unwrap_or_default
干嘛用的。。就是有值返回值,没值是也不抛出错误,而是调用default方法。
目前的结构体:
editor: 主体
document: 文件内容
row: 一行内容
terminal: 表达展示的,譬如移动鼠标,清屏等。
cursor_position: 跟踪鼠标位置
offset: 跟踪document内容偏移量。
https://play.rust-lang.org/ 可用来实验简单的代码。
我们计算鼠标位置 只适应于ascii.
像utf8, 有的字符有2/3个字节,就有问题了。
得把按字节计算的方式改成按字符的方式计算了。
这个借助于第三方库unicode-segmentation
day5 编辑文件
https://www.philippflenker.com/hecto-chapter-5/
这篇感觉没啥新东西。
只能说设计的结构良好。
就是在编辑rows和row 2个数据。
后面说的都是 clippy 提示的。
然后性能优化了下。
极致的性能一般会导致可维护问题,这需要权衡。
day6 搜索
https://www.philippflenker.com/hecto-chapter-6/
1
开始实现的简单搜索,就是在每行里搜字符串,这里要注意的是,返回的索引位置是字符位置,而不是字节位置。
并且遇到第一个匹配行就返回了。
之前封装的prompt
派到用场了。。就是接收用户输入的字符串。。
Option
用的很多。让你不得不考虑可能为空的情况。
2.
然后实现的是实时搜索。就是没输入1个字符就搜素。
这里引入了闭包,作为prompt每次按键的一个回调。同时也引入了泛型。
|_,_,__|{}
这就是个闭包函数。
如果用户取消搜索。还原光标位置。没啥好说的,增加个变量存下原位置。
引入了clone
, 有深拷贝和浅拷贝。clone
,copy
trait。
针对1的。这里可以通过按键,滚动到上一个/下一个匹配的位置上。
向前搜索容易,搜索起始位置就是当前的鼠标位置即可。
向后搜索,得加个方向参数了。遍历的时候也要反向遍历。
这里方向参数用的枚举。
rust
的枚举相当强大。还可以带数据的。
#[derive(PartialEq, Copy, Clone)]
pub enum SearchDirection { Forward, Backward,
}
不得不说rfind
真好。省事。
day7 语法高亮
https://www.philippflenker.com/hecto-chapter-7/
加颜色
还是用的 转义序列。 前景色+字符+重置前景色
这个作者牛逼,只需要改row.rs
里的render
函数就可以了。改进。
上面的有明显的缺陷。
不够抽象,太具体。不能复用。 增加新的特征加高亮时不方便。
改进方式是抽象了Type
类型,提供了to_color
返回对应的前景色。
row
增加了highlighting改进。之前每个字符都加了颜色。但是连续的字符用同样的颜色时,加一个就够了。
_ => color::Rgb(0,0,0)
, 这里我改成了黑色。要不然有点不正常。把高亮规则 应用到搜索结果上。增加
Match
成员。
又复用了之前写的find
方法。很快搜出匹配的下标,增加高亮类型。改进数字高亮,变量名带数字的不能高亮。。必须是被空格/符号 分隔开的数字才高量。 这个感觉容易,修改
highlight
方法就可以了。优化,让数字可以支持小数点。这个实现其实有bug,
3.4.5
也会当成数字高亮。增加文件类型检测。就是根据文件名检测。
前面的行号是我尝试加的。
应用文件类型,,根据文件类型做高亮。
修改highlight
方法, 增加个HighlightingOptions 参数,然后改调用就可以。比较简单。另存为是有问题,没有恰当高亮。修复下
这里隐藏了numbers属性,改成了提供方法。增加特性,高亮字符串。就是"包起来的字符"。引入了新概念
*c
解引用。
修复bug,
\"
有转义时不能当做结束字符。 处理有点巧妙。遇到\
直接高亮2个字符。增加特性,高亮字符。‘a’ 这种。和高亮字符串不一样。因为还有生命周期
'a
语法是不用闭合的。合法的其实只有2中。'x' 和 '\x'
.
增加特性,高亮 单行注释。 这个较简单。
重构,提高代码质量
把hightlight
分功能出来。不同的高亮规则用自己的函数。高亮关键词。
有之前的铺垫,这个应该好容易。。关键词 就是 高亮搜索词 一样的逻辑。
感觉实现的有问题。譬如in
fix
in
的问题
需要有分隔符的 才是关键词。类似数字一样 得加个判断。
is_separator
调用得改成Self::is_separator
。高亮次要关键词。和高亮主要关键词 一样的。
高亮 多行注释。
这个特殊点,之前都是单行处理。这个要跨行了。
方法是修改highlight
方法,增加个是否是多行注释的标记。
同时增删改 都需要修改。性能优化
控制高亮从 document 移动 editor中。因为只有需要显示的文档才需要高亮。
改动分2步。
第一步 是 高亮文档开始 到 显示的行。
第二步是 只高亮 显示的行。
hecto - 手把手教你写个 文本编辑器相关推荐
- 手把手教你写网站:Python WEB开发技术实战
摘要:本文详细介绍了Python WEB开发的基础入门.以一个博客站点的开发为例讲解了基于Django框架开发WEB站点的全过程.通过本文的学习可以快速掌握基于Django的Python WEB的开发 ...
- iOS逆向-手把手教你写支付宝蚂蚁森林收集能量助手
iOS逆向-手把手教你写支付宝蚂蚁森林收集能量助手 前言 发现iOS支付宝逆向的分析并不多,蚂蚁森林基于H5应用 套着UIWebView 基本也没这类JS和原生交互分析的帖子,就拿此练手吧 作技术分享 ...
- 手把手教你写一个Matlab App(一)
对于传统工科的学生用的最多的编程软件应该就是matlab,其集成度高,计算能力强,容易上手,颇受大众青睐.今天挖的这个新坑,主要是分享用matlab app designer设计GUI界面的一些方法和 ...
- socket 长链接linux,手把手教你写 Socket 长连接
原标题:手把手教你写 Socket 长连接 8点43分打卡 就是真爱 本文转载自公众号 玉刚说,由玉刚说写作平台[1]提供写作赞助 原作者:水晶虾饺[2] 版权声明:本文版权归微信公众号玉刚说所有,未 ...
- 手把手教你写批处理-批处理的介绍
标题:手把手教你写批处理-批处理的介绍 作者:佚名 编者:Climbing 出处:中国 DOS 联盟之联合 DOS 论坛 题注:willsort 日期:2004-09-21 ------------- ...
- 自己写富文本编辑器jss_JSS选择器和语法规则
自己写富文本编辑器jss JSS is a JavaScript library that allows you to create objects that follow a CSS-like sy ...
- Vue3 Typescript + Axios 全栈开发教程:手把手教你写「待办清单」APP
本文完整版:<Vue3 Typescript + Axios 全栈开发教程:手把手教你写「待办清单」APP> Vue3 Typescript + Axios 全栈开发教程 前端 Vue3 ...
- 【转载文章】手把手教你写批处理______附加我的读书笔记
https://www.w3cschool.cn/dosmlxxsc1/uebwv9.html 手把手教你写批处理 由 ✎﹏๓₯㎕ζั͡❦﹏﹏♛ 创建, 最后一次修改 2015-11-06 手把手教你 ...
- python网络爬虫网易云音乐_手把手教你写网络爬虫(1):网易云音乐歌单
大家好,<手把手教你写网络爬虫>连载开始了!在笔者的职业生涯中,几乎没有发现像网络爬虫这样的编程实践,可以同时吸引程序员和门外汉的注意.本文由浅入深的把爬虫技术和盘托出,为初学者提供一种轻 ...
最新文章
- Docker 服务终端 UI 管理工具
- 使用ASP.NET2.0显示照片
- 如果再不要求进步,那么你就是下一个陨落的巨头
- 【无码专区4】幸运数字4(折半搜索+计数+结论)
- x3-02 java_Day13 -- Java流程控制02
- C++primer 第 3 章 字符串、向量和数组 3 . 4 迭代器介绍
- 充电枪cp信号控制板_筋膜枪究竟是不是智商税?体验评测后,我的回答更肯定了...
- LED 将为我闪烁: 控帘 j发光二级管
- 思科中国创新中心落户广州 打造年产值超千亿元万物互联“智慧城市”
- 金山网盾3.5实战流氓软件
- 12.解决SUSE Linux无法使用SSH登录的问题
- IntelliJ IDEA + EmmyLua:Lua IDE的安装与使用
- 智能合约语言 传统编程语言 异同
- 肯德基champs各个字母代表什么_百度知道
- Arduino uno LED灯实验
- 【CV-Learning】线性分类器(SVM基础)
- Linux之安装显卡驱动
- 36. 有效的数独(技巧)
- NEYC 1702 排座 问题模型
- 微信小程序实现开关原理、动态添加class