编辑文本缓冲区

时间:2008-09-30 18:06:54

标签: c++ c open-source editor

好的,这是一个有点厚颜无耻的问题。我想构建一个简单的文本编辑器(使用我自己的文本模式屏幕处​​理)。我只想要一个可用于表示文本缓冲区的数据结构的好例子,以及一些简单的char / text插入/删除示例。我自己可以处理所有其余代码(文件i / o,控制台i / o等)。一个很好的简单编辑器源的链接将很棒(C或C ++)。

11 个答案:

答案 0 :(得分:14)

我曾经为一家主要产品是文本编辑器的公司工作。虽然我主要使用脚本语言,但编辑器本身的内部设计自然是讨论的主要话题。

它似乎分解为两个一般的思路。一个是您自己存储每一行​​,然后将它们链接在链接列表或您满意的其他整体数据结构中。优点是任何面向行的编辑操作(例如删除整行,或移动文件中的行块)实现起来都是微不足道的,因此快速闪电。缺点是加载和保存文件需要更多的工作,因为你必须遍历整个文件并构建这些数据结构。

当时的另一个思路是尝试将文字保持在一起而不管换行时的断线,只有在编辑时才需要将它们分开。优点是文件的未编辑大块可以很容易地被发送到文件。如此简单的编辑加载文件,更改一行并保存文件,速度非常快。缺点是面向行或列块操作的执行非常耗时,因为您必须解析这些文本并移动大量数据。

我们始终坚持以线路为导向的设计,无论价值多少,我们的产品被认为是当时最快的编辑之一。

答案 1 :(得分:8)

“四人帮”一书(Design Patterns)有一个基于GUI的文本编辑器作为它的主要示例来源,是一本值得拥有的书。

一般的“纯文本”编辑器可能使用绳索,SGI的STL具有implementation。基本上,它们是字符缓冲区的链接列表。这样,插入/删除字符涉及更改较小的缓冲区和一些指针,而不是将整个文档存储在单个缓冲区中,并且必须移动所有内容。

答案 2 :(得分:7)

这是2008年。不要写文字编辑器;你正在重新开火。

还在吗?我不确定这是否适用或您计划支持哪些平台,但Neatpad series of tutorials是开始考虑编写文本编辑器的好地方。他们专注于Win32作为基础平台,但许多经验教训将适用于任何地方。

答案 3 :(得分:7)

我最喜欢的解决方案是gap buffer,因为它很容易实现并具有良好的摊销效率。只需使用单个字符数组,将区域指定为间隙。一旦理解了这个概念,代码几乎就会自然而然地发生。

您还需要辅助数组[vector< int>]来跟踪每行开头的索引 - 以便您可以轻松提取特定的文本行。只有在间隙移动或插入/移除换行符时才需要更新辅助阵列。

答案 4 :(得分:5)

这两个在线文档为文本编辑提供了一个小而有用的“众所周知”数据结构/技术的聚宝盆。

  1. Data Structures for Text Sequences描述并实验性地分析了一些数据结构,倾向于将片表作为所选择的数据结构。然而,Net.wisdom似乎倾向于差距缓冲区,因为它足以进行文本编辑,并且更容易实现/调试。
  2. “文本编辑工艺”(www.finseth.com/craft/)是一项较早的作品,不仅仅涉及数据结构,还面向Emacs风格的编辑器;但这些概念通常很有用。

答案 5 :(得分:3)

一种简单的方法是面向行 - 将文件表示为char / wchar_t数组/向量的数组/向量,每行一个。插入和删除按照您期望的方式工作,尽管行尾是特殊情况。

我从那开始,并且可能用更有效的方式替换行数据结构,以便在其他所有工作之后支持长行上的插入/删除。

答案 6 :(得分:3)

您几乎可以使用任何数据结构来编写文本编辑器。 200万个字符是相当厚实的小说打字,你可以在不到十分之一秒的时间内轻松地上/下移动(对于简单数组中的插入/删除)。不要听任何告诉你不要建造一个的人,你会得到一些在所有小细节中完全正确的东西。

在我做了太多的网页浏览之后,我写了我的内容,我习惯于向上/向下翻页,就像点击滚动条拇指上方/下方一样。当您在普通编辑器中输入一个字符时,跳回到开始滚动条导航之前,对我来说太烦人了,所以我自己写了。

如果我要进行重写(我只是在当前版本的每个文本缓冲区中使用delphi ansistrings,并且嵌入了换行符),我会为每个字符使用整数或int64并编码块开始/停止,光标位置和行高位中的标记,这样您在插入或删除内容时就不必调整指针。

答案 7 :(得分:2)

您的主要数据结构是包含文本的结构。您可能不需要使用长缓冲区来包含文本,而是需要一个行数组,因为将字符插入到行的中间会更快,然后将字符插入大缓冲区的中间。

您需要确定文本编辑器是否应支持嵌入格式。例如,如果您需要使用字体,粗体,下划线等,那么您的数据结构将需要包含在文本中嵌入格式代码的方法。在8位字符的旧时代,我们可以使用整数的高8位来存储任何格式化标志,使用低8位来存储字符本身。

实际代码取决于您使用的语言。在C#或C ++中,您可能会为这些行使用一个字符串数组。在C中,您将拥有一组基于堆的字符数组。

尽可能将显示代码与文本处理代码分开。代码的中心将是一个紧凑的循环,如:

while (editing) {
    GetCharacter();
    ProcessCharacter();
    UpdateDisplay();
}

更复杂的编辑器将使用单独的线程进行角色获取/处理和显示更新。

答案 8 :(得分:1)

这实际上取决于您的设计。几年前,我用诅咒写了一个小编辑。我使用了双链表,其中每个节点都是一个字符(设计非常浪费..但它使格式化和屏幕刷新程序变得非常容易)。

我朋友使用的其他数据结构(这是一个家庭作业项目): 1)链接的数组列表,每个数组代表一行。 2)2D链表(只是由该名称组成)..它是一个链接的字符列表,但每个字符都链接到上下字符。 3)链表数组

但是,我建议你浏览像pico这样的简单编辑器的源代码,看看他们使用的是什么。

答案 9 :(得分:1)

您是否查看了Scintilla的源代码?

答案 10 :(得分:-1)

查看vim,它是开源的。在它周围看看它是如何处理你想要的。