/hierarchy

Emacs library to create, query, navigate and display hierarchy structures

Primary LanguageEmacs LispGNU General Public License v3.0GPL-3.0

Hierarchy

Build Status Coverage Status

Summary

Library to create, query, navigate and display hierarchy structures. You might want to read the introductory blog post.

Installing

Use melpa.

Using

After having created a hierarchy with hierarchy-new, populate it by calling hierarchy-add-tree or hierarchy-add-trees. You can then optionally sort its element with hierarchy-sort. For example, you can create an animal hierarchy by passing a child-to-parent function to hierarchy-add-tree:

(require 'hierarchy)

(setq animals (hierarchy-new))

(let ((parentfn
       ;; Given an item, return its parent
       (lambda (item)
         (cl-case item
           (dove 'bird)
           (pigeon 'bird)
           (bird 'animal)
           (dolphin 'animal)
           (cow 'animal)))))
  (hierarchy-add-tree animals 'dove parentfn)
  (hierarchy-add-tree animals 'pigeon parentfn)
  (hierarchy-add-tree animals 'dolphin parentfn)
  (hierarchy-add-tree animals 'cow parentfn))

(hierarchy-sort animals)

You can learn more about your hierarchy by using functions such as hierarchy-roots, hierarchy-length, hierarchy-children, hierarchy-descendant-p. For example, hierarchy-roots returns any item without a parent in a hierarchy:

(hierarchy-roots animals)
animal

animal is the only item of the animals hierarchy with no parent. To get all items with no child, use hierarchy-leafs:

(hierarchy-leafs animals)
dovepigeondolphincow

It is possible to get the children of an item by using hierarchy-children:

(hierarchy-children animals 'animal)
birdcowdolphin

We see here that animal has three children.

You can navigate a hierarchy using hierarchy-map-item, hierarchy-map and hierarchy-map-tree. For example, this code inserts a text view of a hierarchy in a buffer:

(with-temp-buffer
  (hierarchy-map
   (hierarchy-labelfn-indent
    (lambda (animal _) (insert (symbol-name animal) "\n")))
   animals)
  (buffer-substring (point-min) (point-max)))
animal
  bird
    dove
    pigeon
  cow
  dolphin

The indentation between a parent and its child can be configured by passing one more parameter to hierarchy-labelfn-indent. You can also display clickable buttons instead of just plain text using either hierarchy-labelfn-button or hierarchy-labelfn-button-if.

If you want a buffer containing only a hierarchy while being able to navigate it with standard key-bindings use either hierarchy-tabulated-display or hierarchy-tree-display as shown in below animated pictures.

(switch-to-buffer
 (hierarchy-tabulated-display
  animals
  (hierarchy-labelfn-indent
   (hierarchy-labelfn-button
    (lambda (item _) (insert (symbol-name item)))
    (lambda (item _) (message "You clicked on: %s" item))))))

media/animals-tabulated-anime.gif

(switch-to-buffer
 (hierarchy-tree-display
  animals
  (lambda (item _) (insert (symbol-name item)))))

media/animals-tree-anime.gif

Examples

File-system example

The hierarchy library can be used to display any kind of hierarchy you need. For example, a file-system navigator is provided as an example.

(load "./examples/hierarchy-examples-fs.el")

;; Execute one of the following lines to show the `.emacd.d' hierarchy
;; in either a tabulated list or a tree widget. This takes around 3
;; seconds on my computer.

(hierarchy-examples-fs-display-filesystem "~/.emacs.d")

(hierarchy-examples-fs-display-filesystem-tree "~/.emacs.d")

media/files-tabulated-anime.gif

media/files-tree-anime.gif

Faces hierarchy example

Emacs and packages define quite a lot of faces. Because a face may inherit from another one, we can get a hierarchy of them:

media/faces-tree.png

This is based on an idea and code from Yuan Fu.

Major modes hierarchy example

Emacs and packages define quite a lot of major modes. A major mode usually derives from another one which means we can get a hierarchy of major modes:

media/major-modes-tabulated.png

Class hierarchy example

With a bit more work, the hierarchy library can also be used to display class hierarchies (as I am currently experimenting in this project).

media/klassified-tabulated-anime.gif

JSON navigator example

A JSON navigator is also implemented as yet another example.

media/json-tree-anime.gif

Contributing

Yes, please do! See CONTRIBUTING for guidelines.

License

See COPYING. Copyright (c) 2017 Damien Cassou.