web-dev-qa-db-ja.com

テキストエディタ理論

私はいつも既存のエディターに不満を持っているので、私がいつも始めたかったプロジェクトは私自身のテキストエディターです。ただし、テキスト編集を行うことは深刻なビジネスです。

既存のテキストエディタのソースコードを分析する以外に、このトピックに関する本やその他のリソース(学術研究など)はありますか?特に、メモリの処理方法とテキスト挿入の管理方法を教えるものに興味があります(100 MBのファイルがあり、xの位置に文字を追加したい場合は、memmoveだけでは不十分です。巨大なテキストブロック...)。

48
lornova

Rob Pikeの彼の Samテキストエディタ の説明を見てください。必ず、高レベルの概要とコマンド言語を参照してください。彼は、このホワイトペーパーの後半で、解析、メモリ管理、およびデータ構造について説明しています。

さらに、Russ Coxの 単純な正規表現の実装 を見てください。従うのは簡単で、既存の正規表現ライブラリの外にいくつかの扉を開くかもしれません。

16
Corbin March

何年にもわたって、私はかなりの数の異なるテキストエディタを書いてきました。確かに最も簡単な方法は、文字の長いシーケンスを管理することです。ここでは、すべてをコピーして任意の文字を挿入します。私が使用した他のテクニックは次のとおりです。

  • テキストファイルを、二重にリンクされたテキスト行のリストとして表します。
  • ツリーのようなデータ構造( "rope" と呼ばれることもあります)を構築します。これは、文字列として始まりますが、テキストのブロックを移動せずに分割、挿入、および削除する機能があります。周りの残りのすべてのテキスト。

古いボーランドのサンプルブックの多くは、チュートリアルの例としてテキストエディタを使用していました。これらのコピーは、古本屋でほぼ無料で見つけることができます。

14
Greg Hewgill

より現代的な文脈で多くの関連トピックをカバーする優れたチュートリアルがここにあります:

この質問に対する他の回答は、ギャップバッファをカバーしています。

もう1つの最新の報道は、AvalonEditの説明です。

および追加の詳細:

この本には(SharpDevelopについての)膨大な量の詳細/コンテンツがあります。

10
StephenD

リクエストによる回答に昇格:

KernighanとPlaugherによるアンティークの " Pascalのソフトウェアツール "は、実際の文字列もポインタもない言語でedエディタを実装しています。これには、テキストエディタの根底にある設計上の考慮事項の概要が含まれています。

9
msw

まだ機能している古い方法の1つは、ギャップバッファと呼ばれます。基本的な考え方は、テキストをバッファに入れることですが、すべてを1つのブロックに入れる代わりに、カーソルに「ギャップ」を作成し、すべてのテキストをバッファの先頭にあるカーソルの前に置きます。バッファの終わりにあるカーソルの後のテキスト。ほとんどの挿入はカーソルで行われます。これは、何も移動せずに(バッファがオーバーフローするまで、またはオーバーフローしない限り)実行できます。ユーザーがカーソルを移動すると、適切なテキストが分割の一方の側からもう一方の側に移動します。

典型的なコントロール(カーソルの左、右、上、下、ページアップ、ページダウン)を考えると、通常処理する最大の移動は一度に1ページです。これは、通常かなり扱いやすいです。キーボードが繰り返すよりも速い。もちろん、本当に巨大なファイルと「goto line」コマンド、またはその順序の何かがある場合は、少し遅くなる可能性があります。あなたがそれをたくさんするつもりなら、間違いなくより良い構造があります...

8
Jerry Coffin

テキスト編集の技術 Craig Finsethは、修士論文に基づいて、これらのトピックをカバーしています。ウェブ上では無料です。 OTOHそれはかなり古く、昔の小さなコンピューターではあまり実用的ではなかったロープのようないくつかのアイデアについては言及していません。

7
Darius Bacon

このペーパー テキストエディタに使用できる多くのデータ構造を比較します。これには、すでにここで説明したもの(ギャップバッファなど)と、その他のいくつか(ピーステーブルなど)が含まれます。この記事は古いものですが、それでもすべての主要な選択肢を網羅していると思います。パフォーマンス、複雑さ、スペースのオーバーヘッドの点でそれらをうまく比較しています。

Stack Overflowの回答は単なるリンクではないことは知っていますが、これは要求された情報について私がこれまでに見つけた最高の情報源であり、ここで回答に要約するには長すぎます。リンクが古くなった場合は、ニューメキシコ大学のCharlesCrowleyによる " テキストシーケンスのデータ構造 "を検索してください。

5
Adrian McCarthy

Scintillaコンポーネントは、 ScintillaおよびSciTE関連サイト ページにリンクされているテキストで説明されている理論に沿って、分割バッファーを使用します。
リンクされたページは ビットマップテキストエディタのデータ構造 です。
分割バッファは、メガバイトファイルでもうまく機能することを証明しました。二次構造(たとえば、行の開始のリスト)を使用することも役立ちます。

3
PhiLho

Microsoftの「プロ」がそれを行う方法は次のとおりです。

MS Wordは、ピーステーブルのデータ構造を使用します。文字位置の昇順配列は、元のファイル(ファイルのロード時にロードされるテキスト)または新しく追加された文字の追加専用バッファーへのポインターを含む、より大きな構造体の配列と並行して維持されます。

Windowsのあらゆる場所で使用されているEDITコントロールは、データ構造をまったく使用していません。メモ帳は、単に複数行のEDITコントロールを使用します。ヒープビューアで確認してください。 EDITコントロールは、改行とタブストップのバッファーのみを維持します。

Windowsでフォーマットされていない単純なテキストエディタを作成する場合は、EDITコントロールを簡単にサブクラス化して機能を追加できます。

2
James

テキスト挿入を管理する方法(100 MBのファイルがあり、xの位置に文字を追加したい場合、巨大なテキストブロックを単に記憶することはできません...)。

テキストファイルをリンクリストにします。すべての行がエントリです。

1

一般に、挿入ポイントが比較的少ないことがわかっている場合は、元のテキストバッファにポインタの配列を保持し、ユーザーがその中に挿入しようとすると、残りのポインタに別のポインタを生成してバッファを「分割」します。バッファの、挿入ポイントで停止するように最初のポインタの長さを作成し、間に挿入されるテキストの3番目のポインタを追加します。

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

そして、星は、挿入するテキストの追加を開始する新しいテキストバッファを指します。

テキストファイルをレンダリング(または一般的に解析)するときは、ポインターの配列をループしてから、各バッファーで作業を行います。もちろん、バッファーが十分に小さい場合は、新しいバッファー部分の追加をスキップしますが、これは単なるヒューリスティックであり、それぞれを試して、どれが最適かを判断してください。

また、ロード時にテキストファイルを1MB程度ごとに複数のバッファに分割することも検討できます。これは、ファイルを単一のバッファにロードする場合、サイズが原因で挿入されたテキスト用に新しいバッファを作成する必要があるためです。繰り返しますが、これはヒューリスティックな最適化です。

1
Blindy