gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-31 01:23:53 24 4
gpt4 key购买 nike

我一直在思考如何使编辑器的核心功能与 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 ,它很可能足够快以满足您的需求,并且它也足够通用以插入您需要的任何缓冲策略。

这同样适用于语法高亮,如果你在后台运行它,它就不会在用户打字时打扰到他。您可以在这里使用 slice 方法来获得好处:

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

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

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

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com