User interface 文本编辑器通常是如何实现的?

User interface 文本编辑器通常是如何实现的?,user-interface,language-agnostic,string,text-editor,User Interface,Language Agnostic,String,Text Editor,这个问题可能会让我听起来很无知。那是因为我是 我只是在想,如果我假设有兴趣设计自己的文本编辑器GUI控件、小部件或任何你想称之为它的东西(我不是),我会怎么做呢 对于像我这样的新手来说,以字符串的形式存储文本编辑器的内容是一种诱惑,这似乎相当昂贵(我并不太熟悉不同语言/平台的字符串实现之间的差异;但我知道,例如在.NET中,它们是不可变的,因此频繁的操作(如您需要在文本编辑器中支持的操作)将是极大的浪费,以非常快的速度连续构建一个又一个字符串实例) 可能会使用一些包含文本的可变数据结构;但要弄清

这个问题可能会让我听起来很无知。那是因为我是

我只是在想,如果我假设有兴趣设计自己的文本编辑器GUI控件、小部件或任何你想称之为它的东西(我不是),我会怎么做呢

对于像我这样的新手来说,以字符串的形式存储文本编辑器的内容是一种诱惑,这似乎相当昂贵(我并不太熟悉不同语言/平台的字符串实现之间的差异;但我知道,例如在.NET中,它们是不可变的,因此频繁的操作(如您需要在文本编辑器中支持的操作)将是极大的浪费,以非常快的速度连续构建一个又一个字符串实例)

可能会使用一些包含文本的可变数据结构;但要弄清楚这种结构可能是什么样子,我觉得有点困难。随机访问会很好(我想,无论如何,你不希望用户能够跳转到文本中的任何地方吗?)但是,我想知道,比如说,导航到一个巨大文件中间的某个地方并立即开始键入的成本。我认为这会导致非常糟糕的性能,就像用户键入的每个字符一样,会有大量的数据需要“转换”

因此,如果我不得不猜测,我会假设文本编辑器采用某种结构,将文本分解成更小的片段(可能是行?),它们分别由随机访问的字符数组组成,并且它们本身可以作为离散块随机访问。尽管如此,如果从一开始就非常接近的话,这看起来一定是一个非常可怕的过度简化

当然,我也意识到文本编辑器的实现可能没有一种“标准”的方式;也许不同的编辑器之间差异很大。但我认为,由于这显然是一个已经被多次解决的问题,也许多年来出现了一种相对普遍的方法


无论如何,我只是想知道是否有人对这个话题有一些了解。就像我说的,我绝对不想写我自己的文本编辑器;我只是好奇。

一种常见的技术(尤其是在旧的编辑器中)称为拆分缓冲区。基本上,你“中断”文本分为光标前的所有内容和光标后的所有内容。光标前的所有内容位于缓冲区的开头。光标后的所有内容位于缓冲区的结尾

当用户键入文本时,它会进入中间的空白区域,而不移动任何数据。当用户移动光标时,您会从“break”的一侧移动适当数量的文本另一方面,通常在一个区域会有大量的移动,所以一次通常只移动少量的文本。最大的例外是如果你有“转到第xxx行”的功能


Charles Crowley已经写了一篇更完整的文章。您可能还想看看,其中涵盖了拆分缓冲区(以及其他可能性)深度要大得多。

根据一次需要在编辑器中输入的文本量,使用一个字符串作为整个缓冲区的方法可能会很好。我认为记事本可以做到这一点——有没有注意到在大文件中插入文本会慢得多

在哈希表中每行有一个字符串似乎是一个很好的折衷方案。它可以使导航到特定行和删除/粘贴变得高效,而不会带来太多复杂性


如果你想实现一个撤销功能,你需要一个表示法,它允许你返回到以前的版本,而不需要存储整个文件的30个副本来进行30次更改,不过如果文件足够小的话,这可能也没问题。

最简单的方法是使用即使是一个简单的char对象数组也可以在必要时使用

追加、替换和查找文本的速度相对较快。当然,其他操作可能更耗时,在缓冲区的开头插入一系列字符是成本更高的操作之一

然而,对于一个简单的用例来说,这在性能方面是完全可以接受的

如果插入和删除的成本特别大,我会尝试通过创建一个缓冲区包装类来优化,该类在内部维护缓冲区对象列表这不会发生在现有缓冲区的尾部,这将导致相关缓冲区在相关点被拆分,因此可以在其尾部修改缓冲区。但是,外部包装将保持与简单缓冲区相同的接口,因此我不必重写例如我的搜索操作

当然,这个简单的方法很快就会出现一个非常零碎的缓冲区,我会考虑在适当的时候使用某种规则来合并缓冲区,或者推迟在一个字符插入的情况下分裂一个缓冲区。也许规则是,我最多只能拥有2个内部缓冲区,我会合并。在创建一个新的缓冲区之前,或者当有人要求我立即查看整个缓冲区时,请先删除它们。不确定

关键是,我会从简单开始,但通过一个精心选择的接口访问可变缓冲区,如果分析显示我需要的话,可以使用内部实现


然而,我绝对不会从不可变的字符串对象开始!

不久前,我用Tcl编写了自己的文本编辑器(实际上,我从某处偷了代码,并将其扩展到了无法识别的程度,啊,开源的奇迹)

正如您所提到的,在非常非常大的字符串上执行字符串操作可能非常昂贵