我一直在考虑将编辑器核心功能明智地与vim兼容,类似于yzis。
最大的问题是要使用的缓冲区类型。
要求是:
可能的缓冲区类型:
我读到间隙缓冲区在长时间运行时会导致相当大的内存碎片。 emacs语法高亮引擎也非常慢。(不知道为什么,可能与缓冲区类型没有关系)
所以问题:
谢谢, 礼
答案 0 :(得分:4)
一个好的文本编辑器应该对程序员可能做的各种工作很有用,包括打开有时可能是几千兆字节的文件。因此,我不建议将所有内容缓存在RAM中的思维方式。
我建议设置一个代表文件的切片搜索树,其中一个切片可能是:
当您打开文件时,首先将单个项目插入树中,这只是表示整个文件的范围,例如:对于10-MiB文件:
std::map<size_t, slice_info> slices;
slices[0].size = 10*1024*1024;
当用户编辑文件时,在编辑点周围创建一个合理大小的“页面”,例如4 KiB。树在那一点被拼接。在该示例中,编辑点位于5 MiB:
size_t const PAGE_SIZE = 4*1024;
slices[0].size = 5*1024*1024;
slices[5*1024*1024].size = PAGE_SIZE;
slices[5*1024*1024].buffer = create_buffer(file, 5*1024*1024, PAGE_SIZE);
slices[5*1024*1024 + PAGE_SIZE].size = 5*1024*1024 - PAGE_SIZE
您可以将内存映射文件用于只读缓冲区(源文件)和复制的可编辑缓冲区(后者将放在临时目录中)。如果编辑器崩溃,这也允许恢复。
使用固定大小的页面将大大减少内存堆的碎片,因为所有块都具有相同的大小,插入文本永远不需要在您之前移动超过4 KiB的数据。
这是一个简化的描述,给出了一般的想法,而没有涉及太多的细节。一个真正的实现很可能需要更复杂,例如允许页面中的可变数量的数据来处理溢出的页面,并将许多小切片合并在一起,以便在大文件中运行正则表达式替换不会创建太多的小缓冲区。可能需要同时对树中应该具有的切片数量进行限制,但关键是当您开始插入某处时,应该确保使用的切片不是太大。< / p>
对于正则表达式,只要整个编辑器在运行时没有挂起,我认为性能不是很大的问题。试试Boost.Regex,它很可能足够快,满足您的需求,而且它也足以插入您需要的任何缓冲策略。
这同样适用于语法高亮,如果你在后台运行它,它在打字时不会打扰用户这么多。您可以在此处使用切片方法获益:
我不知道有任何独立的语法突出显示引擎,但它们通常基于正则表达式替换(参见例如vim中的语法突出显示文件)。
答案 1 :(得分:0)
您可以使用Scintilla类。您的视图可以从Scintilla View派生,它提供语法突出显示。