23 January 2011



Quick catchup

About a year ago I blogged an idea about combining cords and emacs1. Now that it has jangled around in my head for another year, I have some further thoughts. Yesterday I talked about how emacs wants to structure text and how it pretends to.

Now I want to talk about the ramifications of structured text on my wild idea of combining emacs and cords.

Don't ask buffer to hold a list etc

One things I talked about yesterday was how some modes want the buffer to be a list or tree of objects. It's tempting, then, to imagine that some buffers would hold a list or tree of printable objects instead of text.

But it wouldn't work well. Even when printable objects fully control their own representation, as widgets and ewocs do, they are generally do not want to be the whole printed representation. They want accoutrements, often headers, footers, and separators.

So just one object

So buffer would hold at most one object, either (as now) a text string, or a printable object that manages both its own sub-objects (the model) and the cord that it presents for display (the view).

Presumably the design is basically recursive, something like this: The root object supplies a template and farms most of its representation out to its sub-objects. They in turn farm it out to sub-sub-objects, etc. Each subN-object generates a cord from data that it owns.

Dynamic content

Our subN-objects will create content dynamically. Cords support that with CORD_from_fn. But doing only that has some drawbacks:

  • CORD_fn wants to give one character at a time. That's very inefficient.
  • Each displayable object would have to manage caching etc itself.
  • We'll want different things from it for different purposes:
    • To display
      • It might be blank or abbreviated for invisibility or folding. Emacs does this by looking at a magic text property, but it's really a display concern.
      • It might include ornaments that are not part of the proper text.
    • To search.
      • If an item is folded, we generally still want to search its text.
      • For widgets and similar, we'd like to search on just the real text and not ornaments in the display such as button characters.
    • To save to file.
      • This representation might be completely different that the displayed text, eg as we do for project-buffer-mode buffers.
    • Other lesser purposes, such as:
      • Displaying differently in different windows.
      • Exporting

So let's make these objects' lives a little easier. I suggest adding to the roster of cords types a super-CORD_from_fn, which would contain:

  • clientdata as for CORD_from_fn
  • A cache for each major use-type above (display,search,save)
    • A dirty or uninitialized cache could be indicated as a magic object.
    • Possibly also a catchall cache for other use-types.
  • A method that:
    • Takes client_data
    • Takes an object indicating the use-type
    • Returns a cord
  • Not length. It may differ across use-types. If cache is dirty, it's not known, while if cache is clean, one can just find length in it.

Some quick notes

Display and faces

Displaying in different faces need no longer be a trick. We could add to the roster of cords types a "face" cord that controls the face that text enclosed in it is displayed in.

We could also provide an "image" cord, meaning to show that image inline with the text.

How to read such files?

How does one know to use this structuring for a given file? Just about as now: an auto-mode-alist tells what mode to use. A "mode" file-local variable can be used to supplement this mechanism. Just let modes can control the read and hand the buffer a super-CORD_from_fn object instead of a plain text cord object.

A file could be visited as plain text by another command, `find-file-as-text'.


1 Quick summary: Cords are neat and mondo efficient, Emacs, for all its greatness, uses buffer-gap which is much weaker. But emacs text isn't just text, it has properties and markers and other useful stuff. To make that work, we'd have to add some stuff onto cords, but it's doable.

No comments:

Post a Comment