Hierarchy
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)| dove | pigeon | dolphin | cow |
It is possible to get the children of an item by using
hierarchy-children:
(hierarchy-children animals 'animal)| bird | cow | dolphin |
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))))))(switch-to-buffer
(hierarchy-tree-display
animals
(lambda (item _) (insert (symbol-name item)))))Examples
This library can be used to manipulate any kind of hierarchy. The following demonstrates this claim.
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")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).
JSON navigator example
A JSON navigator is also implemented as yet another example.
Contributing
Yes, please do! See CONTRIBUTING for guidelines.
License
See COPYING. Copyright (c) 2017 Damien Cassou.





