If you want to have structured nodal data in a buffer, the cookie package can be a help to you.
Cookie is a package that implements a connection between a
dll (a doubly linked list) and the contents of a buffer.
Possible uses are
dired (have all files in a list, and show them),
kom-prioritize (in the LysKOM elisp client) and
others. `pcl-cvs.el' uses `cookie.el'.
The cookie package uses its own terminology. Here are some important definitions.
Cookie does not affect the mode of the buffer in any way. It merely makes it easy to connect an underlying data representation to the buffer contents.
A collection is a very dynamic thing. You can easily add or delete cookies. You can sort all cookies in a collection (you have to supply a function that compares two cookies). You can apply a function to all cookies in a collection, et c, et c.
Remember that a cookie can be anything. Your imagination is the limit! It is even possible to have another collection as a cookie. In that way some kind of tree hierarchy can be created.
All functions that are intended for external use begin with one of the prefixes `cookie-', `collection-' or `tin-'. The prefix `icookie-' is currently used for internal functions and macros. Currently, no global or buffer-local variables are used.
Many functions operate on tins instead of cookies. For most functions, the prefix used should help tell which kind of object the function uses.
Most doc-strings contains an "Args:" line that lists the arguments.
(collection-create buffer pretty-printer &optional header footer pos)
insert, and not
insert-before-markers. Optional third argument header is a string that will always be present at the top of the collection. header should end with a newline. Optionaly fourth argument footer is similar, and will always be inserted at the bottom of the collection. Optional fifth argument pos is a buffer position, specifying where the collection will be inserted. It defaults to the begining of the buffer. pos will probably default to the current value of
(point)in future releases of Elib, so you should not depend on this default in cases where it matters.
These functions can be used to insert one or more cookies
into a collection. The printed representation will
immediately and automatically be updated by the cookie
package. (It will call the pretty-printer that was
(cookie-enter-first collection cookie)
(cookie-enter-last collection cookie)
(cookie-enter-after-tin collection tin cookie)
(cookie-enter-before-tin collection tin cookie)
(collection-append-cookies (collection cookie-list))
(tin-cookie collection tin)
There are a couple of different ways to delete cookies from the collection.
(tin-delete collection tin)
nilif there are no cookies left in collection.
nilif there are no cookies left in collection.
The following two functions can be used to delete several cookies that fulfills certain criteria.
(collection-filter-cookies collection predicate &rest extra-args)
collection-filter-cookiesthey will be passed unmodified to predicate.
(collection-filter-tins collection predicate &rest extra-args)
collection-filter-cookies, but predicate is called with a tin instead of a cookie.
And finally, a way to delete all cookies in one swift function call:
The functions in this section treat the collection as a doubly linked list.
(tin-nth collection n)
nilis returned if there is less than n cookies. If n is negative, return the -(n+1)th last element. Thus,
(tin-nth dll 0)returns the first node, and
(tin-nth dll -1)returns the last node. Use
tin-cookieto extract the cookie from the tin (or use
(cookie-nth collection n)
tin-nth, but the cookie is returned instead of the tin.
(tin-next collection tin)
nilor refers to the last cookie in collection.
(tin-previous collection tin)
nilor refers to the first cookie in collection.
(cookie-sort collection predicate)
(cookie-map map-function collection &rest map-args)
nilthe cookie will be refreshed (its pretty-printer will be called once again). Note that the buffer for collection will be current buffer when map-function is called. map-function must restore the current buffer to buffer before it returns, if it changes it. If more than two arguments are given to
cookie-map, remaining arguments will be passed to map-function.
(cookie-map-reverse map-function collection &rest map-args)
cookie-map, but map-function will be applied to the last cookie first.
(collection-collect-tin collection predicate &rest predicate-args)
collection-collect-tinthe remaining arguments will be passed to predicate.
(collection-collect-cookie collection predicate &rest predicate-args)
collection-collect-tin, but a list of cookies is returned.
tin-invalidateis more efficient if only a small number of cookies needs to be refreshed.
(tin-invalidate collection &rest tins)
(collection-set-goal-column collection goal)
(tin-goto-previous collection pos arg)
(tin-goto-next collection pos arg)
tin-goto-previous, but move towards the end of the buffer instead.
(tin-goto collection tin)
(tin-locate collection pos &optional guess)
Since the cookie package uses dll, cookie applications can be hard to debug. Fortunately, the same technique can be used here--just load dll-debug prior to loading cookie. See section Debugging dll applications.
Warning! Don't load a byte-compiled `cookie.elc' that was compiled using dll (as opposed to dll-debug) when you have dll-debug in memory. Your Emacs will be seriously confused.