c++ - 编辑器核心缓冲区类型和语法突出显示

标签 c++ vim editor syntax-highlighting buffer

我一直在思考如何让编辑器的核心功能与 vim 兼容,类似于 yzis。

最大的问题是使用什么类型的缓冲区。

要求是:

  • 可以实现快速语法突出显示、正则表达式。
  • 可以在单个文件中实现多个语法突出显示。类似于 textmates 范围
  • 删除插入时正确的移动标记。以便它们在列中正确调整。与 vim 不同。
  • 处理并突出显示至少 100 MB 的文件,不会出现太大问题和内存开销。

可能的缓冲区类型:

  • 间隙缓冲区
  • 基于行的编辑

我读到间隙缓冲区在较长的运行中会导致相当大的内存碎片。而且 emacs 语法高亮引擎非常慢。(不知道为什么,可能与缓冲区类型没有真正关系)

所以问题是:

  1. 哪种缓冲区类型最适合快速编程编辑器?
  2. 什么是快速/完整的正则表达式引擎? (也许这包括下一点)。 TextMate 使用 oniguruma,这是一个明智的选择吗?
  3. 什么是快速语法突出显示引擎?
  4. 关于标记和语法高亮。 emacs 叠加层是如何工作的,有帮助吗?

谢谢, 礼萨

最佳答案

一个好的文本编辑器应该对程序员可能从事的各种工作都有用,其中包括打开有时可能有几千兆字节大小的文件。因此,我不建议将所有内容都缓冲在 RAM 中。

我建议设置代表文件的切片搜索树,其中单个切片可能是:

  1. 对磁盘上实际文件中的字节范围的引用,或
  2. 对已编辑“页面”的引用。

当您打开文件时,首先将单个项目插入树中,该项目只是代表整个文件的范围,例如对于 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

您可以将内存映射文件用于只读缓冲区(源文件)和复制的可编辑缓冲区(后者将放置在临时目录中)。这也允许在编辑器崩溃时进行恢复。

使用固定大小的页面将大大减少内存堆的碎片,因为所有 block 都具有相同的大小,并且插入文本永远不需要在您前面移动超过 4 KiB 的数据。

这是一个简化的描述,旨在给出总体思路,而不会涉及太多具体细节。真正的实现很可能需要更加复杂,例如允许页面中的可变数据量来处理溢出的页面,并将许多小切片合并在一起,以便在大文件中运行正则表达式替换不会创建太多的小缓冲区。树中同时拥有的切片数量可能需要受到限制,但关键点是,当您开始插入某处时,您应该确保使用的切片不太大。

对于正则表达式,我认为只要整个编辑器在运行时不挂起,性能就不是什么大问题。试试Boost.Regex ,它很可能足够快,足以满足您的需求,而且它也足够通用,可以插入您需要的任何缓冲策略。

这同样适用于语法突出显示,如果您在后台运行它,它不会在用户打字时打扰太多。您可以在此处使用切片方法来获得好处:

  • 每个切片都可以有一个互斥锁,可以在编辑操作期间锁定该互斥锁,从而允许语法突出显示或“智能感知”类型分析在后台线程中运行。
  • 您可以存储语法突出显示引擎的状态,以便每当您在切片中进行编辑时,都可以从该切片的开头(而不是从文件的开头)重新启动语法突出显示。

我不知道有任何独立的语法突出显示引擎,但它们通常基于正则表达式替换(例如,参见 vim 中的语法突出显示文件)。

关于c++ - 编辑器核心缓冲区类型和语法突出显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/531957/

相关文章:

c++ - 条件语句中的逗号有什么好处?

c++ - 套接字 write() 函数的问题

c++ - -fobjc-arc 不支持脆弱的 abi

regex - 在 BASH 中,删除两组字符之间的所有内容

vim - 如何在 vim 和 tmux 的 Pane 之间导航

c++ - 如何确定要 dynamic_cast 到哪种类型?

Xcode 数据模型编辑器没有出现

c# - Visual Studio 2008 断点可见样式

javascript - tinymce getcontent 获取未应用过滤器的完整 html

linux - Ctrl+v 在终端粘贴