DamienCassou / Hierarchy
- ⚠ Integration into Emas core
This project got integrated into Emacs core after the release of Emacs 27.1. Please contribute patches to Emacs core directly instead of here.
** Summary
Library to create, query, navigate and display hierarchy structures. You might want to read the [[https://emacs.cafe/emacs/guest-post/2017/06/26/hierarchy.html][introductory blog post]].
** Installing
Use [[http://melpa.org/][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:
#+BEGIN_SRC emacs-lisp :session animals (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) #+END_SRC
#+RESULTS: | bird | animal |
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:
#+BEGIN_SRC emacs-lisp :session animals :exports both (hierarchy-roots animals) #+END_SRC
#+RESULTS: | animal |
animal is the only item of the animals hierarchy with no
parent. To get all items with no child, use hierarchy-leafs:
#+BEGIN_SRC emacs-lisp :session animals :exports both (hierarchy-leafs animals) #+END_SRC
#+RESULTS: | dove | pigeon | dolphin | cow |
It is possible to get the children of an item by using
hierarchy-children:
#+BEGIN_SRC emacs-lisp :session animals :exports both (hierarchy-children animals 'animal) #+END_SRC
#+RESULTS: | 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:
#+BEGIN_SRC emacs-lisp :session animals :exports both (with-temp-buffer (hierarchy-map (hierarchy-labelfn-indent (lambda (animal _) (insert (symbol-name animal) "\n"))) animals) (buffer-substring (point-min) (point-max))) #+END_SRC
#+RESULTS: : 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.
#+BEGIN_SRC emacs-lisp :session animals :exports code (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)))))) #+END_SRC
#+RESULTS: : #<buffer hierarchy-tabulated<2>>
[[file:media/animals-tabulated-anime.gif]]
#+BEGIN_SRC emacs-lisp :session animals :exports code (switch-to-buffer (hierarchy-tree-display animals (lambda (item _) (insert (symbol-name item))))) #+END_SRC
#+RESULTS: : t
[[file: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:examples/hierarchy-examples-fs.el][file-system navigator]] is provided as an example.
#+BEGIN_SRC emacs-lisp :session animals :exports code (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") #+END_SRC
#+RESULTS: : #<buffer hierarchy-examples-fs-tree>
[[file:media/files-tabulated-anime.gif]]
[[file: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 [[file:examples/hierarchy-examples-faces.el][a hierarchy of them]]:
[[file:media/faces-tree.png]]
This is based on an [[https://github.com/DamienCassou/hierarchy/issues/74][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 [[file:examples/hierarchy-examples-major-modes.el][hierarchy of major modes]]:
[[file: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 [[https://github.com/DamienCassou/klassified.el][this project]]).
[[file:media/klassified-tabulated-anime.gif]] *** JSON navigator example A [[https://github.com/DamienCassou/json-navigator][JSON navigator]] is also implemented as yet another example.
[[file:media/json-tree-anime.gif]] ** Contributing
Yes, please do! See [[file:CONTRIBUTING.md][CONTRIBUTING]] for guidelines.
** License
See [[file:COPYING][COPYING]]. Copyright (c) 2017 Damien Cassou.