文本编辑理论

时间:2010-07-02 22:23:16

标签: data-structures editor text-editor theory

由于我总是对现有编辑不满意,我一直想要开始的项目是我自己的文本编辑器。但是,进行文本编辑是一项严肃的事情。

除了分析现有文本编辑器的源代码外,是否有关于此主题的书籍或其他资源(如学术工作)?我特别感兴趣的是教会如何处理内存以及如何管理文本插入(如果你有一个100 MB的文件并想在 x 位置添加一个字符,你不能只是{ {1}}巨大的文本块......)。

11 个答案:

答案 0 :(得分:16)

看看Rob Pike对他Sam text editor的描述。请务必浏览高级概述和命令语言。他在本文后面描述了解析,内存管理和数据结构。

另外,看看Russ Cox的simple regular expression implementation。它很容易理解,可能会在现有正则表达式库之外打开一些门。

答案 1 :(得分:14)

多年来,我写了很多不同的文本编辑器。当然,最简单的方法是管理一长串字符,您可以复制所有字符以插入任何字符。我使用的其他技术包括:

  • 将文本文件表示为双向链接的文本行列表。
  • 构造一个树状数据结构(有时称为"rope"),它以一个实心字符串开头,但能够分割,插入和删除文本块,而无需移动所有其余的文字围绕着。

许多旧的Borland示例书使用文本编辑器作为教程示例。您偶尔也可以在二手书店找到这些副本几乎免费。

答案 2 :(得分:10)

这里提供了一个很好的教程,涵盖了更现代背景下的许多相关主题:

这个问题的其他答案涵盖了间隙缓冲区。

另一个现代报道是AvalonEdit的描述

以及来自:

的额外细节

本书中有大量的细节/内容(关于SharpDevelop):

答案 3 :(得分:9)

促请按要求回答:

Kernighan和Plaugher的古董“Software Tools in Pascal”用一种既没有真正的字符串也没有指针的语言来实现ed编辑器。它包含了任何文本编辑器背后的设计考虑因素的概述。

答案 4 :(得分:8)

一种仍然有效的旧方法称为间隙缓冲区。基本思想是将文本放入缓冲区,但不是将其全部放在一个块中,而是在光标处创建一个“间隙”,将光标前的所有文本放在缓冲区的开头,并且所有文本都放在缓冲区的开头。光标在缓冲区末尾的文本。大多数插入发生在光标处,您可以在不移动任何内容的情况下进行插入(直到或除非您溢出缓冲区)。当用户移动光标时,您将相应的文本从分割的一侧移动到另一侧。

鉴于典型的控件(光标左,右,上,下,上翻,下翻页),您通常处理的最大移动是一次一页,通常易于处理比键盘重复快一点。当然,如果你有一个真正庞大的文件和一个“goto line”命令,或者那个命令上的东西,它可以减慢一点。如果你要做很多事情,毫无疑问会有更好的结构......

答案 5 :(得分:7)

Craig Finseth根据他的硕士论文

The Craft of Text Editing介绍了这些主题。它在网上免费。 OTOH它已经很老了,并没有提到一些想法,比如在过去的小型计算机上不太实用的绳索。

答案 6 :(得分:5)

This paper比较了许多可用于文本编辑器的数据结构,包括这里已经提到的一些数据结构(例如,间隙缓冲区)以及其他几个(例如,片段表)。这篇文章很旧,但我相信它仍然涵盖了所有主要选择,并且在性能,复杂性和空间开销方面对它们进行了很好的比较。

我知道Stack Overflow的答案不仅仅是链接,但这仍然是我找到的所需信息的最佳信息来源,而且这里的答案总结得太长了。如果链接失效,请搜索新墨西哥大学的查尔斯克劳利的“Data Structures for Text Sequences”。

答案 7 :(得分:3)

Scintilla组件使用分割缓冲区,沿着Scintilla and SciTE Related Sites页面中链接的文本中解释的理论。 链接的页面为Data Structures in a Bit-Mapped Text Editor 分割缓冲区证明即使使用兆字节文件也能正常工作。使用二级结构(例如,行开始列表)也可以提供帮助。

答案 8 :(得分:2)

以下是微软的“专业人士”如何做到这一点:

MS Word使用片表数据结构。字符位置的升序数组与包含指向原始文件(文件加载时加载的文本)或新添加字符的仅附加缓冲区的指针的较大结构数组并行维护。

Windows中使用的EDIT控件根本不使用任何数据结构。记事本只是使用多行EDIT控件。使用堆查看器检查它。 EDIT控件仅维护换行符和制表位的缓冲区。

如果您要在Windows中创建一个简单的非格式化文本编辑器,您可以轻松地将EDIT控件子类化以添加功能。

答案 9 :(得分:1)

  

如何管理文本插入(如果你有一个100 MB的文件,并希望在x位置添加一个字符,你不能只记得那个巨大的文本块......)。

使文本文件成为链接列表,其中每一行都是一个条目。

答案 10 :(得分:1)

好吧,如果你知道一般人们会有相对较少的插入点,你可以在原始文本缓冲区中保存一个指针数组,当用户试图在其中插入时,你通过产生另一个指针“拆分”缓冲区到缓冲区的其余部分,使第一个指针的长度停在插入点并为要插入的文本添加第3个指针,有点像:

long original text la la la
^                *^
|                 2nd part
1st part

星星指向一个新的文本缓冲区,您可以在其中添加要插入的文本。

当你渲染(或通常解析)你的文本文件时,你遍历指针数组,然后在每个缓冲区上做你的工作。当然,如果缓冲区足够小,你可以跳过添加一个新的缓冲区部分,但这只是启发式,尝试每一个并感受最佳效果。

您还可以考虑将加载时的文本文件拆分为多个缓冲区,例如每1MB左右,因为如果您在单个缓冲区中加载文件,则需要根据大小为插入的文本创建新的缓冲区。同样,这是一种启发式优化。