kas-gui / kas-text

Rich text processing
Apache License 2.0
58 stars 2 forks source link

Efficient editing for larger texts #15

Open dhardy opened 3 years ago

dhardy commented 3 years ago

Currently:

  1. we store the text as a single String
  2. we discover bidirectional embedding levels and break points over the whole text, forming runs
  3. we shape runs and calculate size metrics for each run
  4. we apply line wrapping and per-line reordering for embedded bidirectional text

On editing text, we currently redo all steps, and for larger documents this doesn't work well.

Using a rope over String would help but is insignificant compared to other operations. It also prevents exposing the text as a single slice.

If explicit line-breaks and paragraph breaks are preserved, only a smaller portion of the text need be updated (steps 2 and 3), while step 4 is reasonably fast anyway (provided we're not talking about huge documents).

Bidirectional embedding level discovery is supposed to only reset on paragraph breaks so the above isn't perfect. When input comes from Markdown or HTML we can normally insert enough paragraph breaks, but for something like viewing a log file or source code it might be necessary to reset discovery per line.

Regarding (4) on large documents, with a bit of work updating only the affected line(s) is possible, however...

... to scale to large documents, it would be desirable not to run shaping or line-wrapping except on visible portions of the document, hence one cannot really discover the line height everywhere (resulting in imperfect scrolling). Here, though, requirements are quite different from other uses, so this should be a separate type.

Additionally, text editors often like to show line numbers, which should possibly be integrated?

Summary: several possible optimisations for large documents, and signs that one prepared::Text type won't be able to satisfy all uses.