Mind maps for Org, in pure Unicode, for quick and easy editing.
A tool to draw mind maps in Org Mode blocks, optimized for fast input and editing. Not perfect visually, but pretty enough to be attractive. The map is just text, no rendering is required. And since a mind map is just a list drawn in a fancy way, you can convert a list into a map and the other way around.
Just C-c C-, m anywhere in an Org buffer and start writing. Move nodes around as your map grows. Focus on the content, let the engine handle the visuals.
If you’re using Emacs version 29 or later:
(use-package org-mindmap
:vc (:url "https://github.com/krvkir/org-mindmap.git" :rev :newest)
:after org
:config
(add-hook 'org-mode-hook #'org-mindmap-mode))If you’re using Emacs version prior to 29, clone this repo and use this:
(use-package org-mindmap
:load-path "~/repos/emacs/org-mindmap/"
:after org
:config
(add-hook 'org-mode-hook #'org-mindmap-mode))The package defines a minor mode (org-mindmap-mode) which you’ll need to turn on to work with maps. It binds frequently used editing commands (see Usage). You may want to hook this minor mode to Org Mode (as it’s done in setup snippets above) so that it auto-enables in each Org buffer, otherwise you’ll need to enable it manually in each Org mode buffer.
You may also want to map some other commands, like list-to/from-map conversion and layout switching, into C-c m prefix space:
(use-package org-mindmap
:vc (:url "https://github.com/krvkir/org-mindmap.git" :rev :newest)
:after org
:bind
(:map org-mindmap-mode-map
("C-c m c" . org-mindmap-insert-child)
("C-c m s" . org-mindmap-insert-sibling)
("C-c m d" . org-mindmap-delete-node)
("C-c m v" . org-mindmap-switch-layout)
("C-c m p" . org-mindmap-switch-compaction)
("C-c m m" . org-mindmap-list-to-mindmap)
("C-c m l" . org-mindmap-to-list))
:config
(add-hook 'org-mode-hook #'org-mindmap-mode))Insert a mindmap block via org-insert-structure-template with C-c C-, m:
#+begin_mindmap #+end_mindmap
Add one root node. Just write it between the mindmap delimiters:
#+begin_mindmap Root node #+end_mindmap
Press C-c C-c to redraw the map. Root node brackets should be added:
⏴ Root node ⏵
Add several child nodes with TAB and siblings with RET:
╭─ First node
⏴ Root node ⏵ ┼─ Second node
╰─ Third node
Edit the text of a node at point with M-RET: this will preserve the layout. Or, if your edits are tiny, just edit the text and redraw the map with C-c C-c.
Move nodes around with M-<up>, M-<down>, M-<left> and M-<right>. Put the cursor on the node text and press one of those keys:
Second node ─┬ ⏴ Root node ⏵ ┬─ First node Fourth node ─╯ ╰─ Third node
Here is the keys reference:
| Command | Hotkey | Description |
|---|---|---|
org-mindmap-edit-node | M-RET | edit node at point[fn:1] |
org-mindmap-insert-sibling | RET | add a node near the current one (as its sibling) |
org-mindmap-insert-child | TAB | add a child node to the current one |
org-mindmap-move-down | M-<down> | move node one sibling down |
org-mindmap-move-up | M-<up> | move node one sibling up |
org-mindmap-promote | M-<left> or M-<right> [fn:2] | move node one level up, i.e. make it its parent’s sibling |
org-mindmap-demote | M-<left> or M-<right> [fn:2] | move node one level down, i.e. make it its sibling’s child |
org-mindmap-delete-node | delete the node and all its descendants | |
org-mindmap-switch-layout | toggle between top and centered layouts | |
org-mindmap-switch-compaction | toggle node compaction (gap-filling) on/off | |
org-mindmap-align | re-align the mindmap | |
org-mindmap-list-to-mindmap | converts an Org list at point into a mind map | |
org-mindmap-to-list | converts a mind map at point to an Org list |
There are no specialized key maps for navigation: just use the usual text navigation keys.
[fn:1] If you’re editing a leaf node and there’s no markup ahead of it, or you just need to fix a typo or insert a character or two, you may do that without org-mindmap-edit-node, but when the node length changes significantly and map structure lines shift, the map will likely fail to recover its structure after the edit.
[fn:2] M-<left> calls org-mindmap-promote on the right side of the map and org-mindmap-demote on its left side, so nodes move leftwards every time. M-<right> works the same way.
Lists and mindmaps are mostly isomorphic: any list can be transformed to a corresponding mindmap without loss of data (except that bullet types and enumerated lists are not supported for now), and vice versa.
If you have a list, you can transform it to mindmap with org-mindmap-list-to-mindmap:
- For want of a nail - the shoe was lost, - For want of a shoe - the horse was lost, - For want of a horse - the rider was lost, - For want of a rider - the battle was lost, - For want of a battle - the kingdom was lost, - And all for the want - of horseshoe nail.
╭─ For want of a nail ── the shoe was lost, ├─ For want of a shoe ── the horse was lost, ⏴⏵ ┼─ For want of a horse ── the rider was lost, ├─ For want of a rider ── the battle was lost, ├─ For want of a battle ── the kingdom was lost, ╰─ And all for the want ── of horseshoe nail.
… and back to list with org-mindmap-to-list.
The package does its best to let you focus on the map contents and structure, by providing reasonably good visuals without ability to tweak the minute details by hand:
- it arranges the nodes and wraps the wide ones so that your map fits into the window — but you can’t move nodes and subtrees into arbitrary locations;
- it paints subtrees into different colors, so that you can visually discern which node belongs to which subtree — but you can’t assign individual colors to nodes.
The general idea is that you set the rules, like the layout or coloring, via block parameters and global defaults, and the engine applies them to your map.
(This was initially a technical limitation–any metadata would bloat the map–but appears to be a way to keep the package focused.)
There are two primary layouts, and a separate compacted compaction option:
top(formerlyleft), the simplest layout, where the root is at the top of children.
#+begin_mindmap :layout top
⏴⏵ ┬─ root ng ┬─ node b ┬─ node d
│ │ ├─ node c
│ │ ╰─ node e ── node f
│ ╰─ node a
╰─ disk c: ┬─ Windows
╰─ Users
#+end_mindmap
centered, the more natural layout where the root node is vertically centered against its children. This one is default.
#+begin_mindmap :layout centered :compacted t
╭─ node d
╭─ root ng ┬─ node b ┼─ node c
⏴⏵ ┤ ╰─ node a ╰─ node e ── node f
╰─ disk c: ┬─ Windows
╰─ Users
#+end_mindmap
To toggle compaction (which allows nodes to float up/down to occupy vacant space), use the :compacted t property or execute org-mindmap-switch-compaction. Layout switching with org-mindmap-switch-layout cycles layout between top and centered.
No formatting inside a node text is supported yet. You can use Org text modifiers (bold, italics, code etc.) but beware that the visual structure may break if markup characters are hidden (this won’t break the map for the parser, only visual presentation will suffer).
You’re safe if markup hiding is disabled or if you use markup only in the leaf nodes of the right side, with compaction disabled.
Long node text can be wrapped at word boundaries to keep the map within the window width. Add a :max-width property (integer) to the block header.
For example, to wrap text at 7 character columns (soft, at word boundaries):
#+begin_mindmap :max-width 7
Use :max-width auto to automatically calculate a width based on the tree depth and window width:
#+begin_mindmap :max-width auto
To keep leaf nodes (nodes without children) unwrapped while wrapping the rest, use :wrap-leaves nil:
#+begin_mindmap :max-width 10 :wrap-leaves nil
The :wrap-leaves property can also be a float multiplier, e.g. 1.5 gives leaf nodes 50% more width than non-leaf nodes.
Wrapping is purely visual: the logical node text stays unchanged (newlines replace spaces when rendering, spaces replace newlines when parsing).
The main goal of painting is to make nodes from neighbour subtrees visually discernable, so that you know from the first glance what subtree a node belongs to. There’s no goal to customize each node’s color, as I believe it only hinders thinking.
What you can customize is:
- the palette (via
org-mindmap-color-palette-fn) and blending proportions (org-mindmap-paint-tinge-fgandorg-mindmap-paint-tinge-bg); - the way colors are assigned to subtrees (via
org-mindmap-color-assign-fn); - the depth from which the subtrees are painted (via
:paint-depthparameter andorg-mindmap-default-paint-depthoption).
The colors are enabled by default, with some sane settings. If you don’t want colors at all, set org-mindmap-default-paint-depth to nil.
Colors are applied when the map is first rendered. If you close an Org file and open it anew, you’ll need to redraw the maps (C-c C-c inside the map block) for colors to reappear.
You may customize the fonts used for the map (see M-x customize-group org-mindmap), but make sure the font is monospace, otherwise the map will be misaligned. I’ve tested the package with Hack font, and things seem to work fine.
Some fonts declare double size for symbols which are used as root node markers by default. You may either change your font or change default symbols for the root node (make sure those symbols are not ones used to draw map connectors and will not occur in your map nodes as text).
The package tries to eliminate those gaps, so if you see gaps between vertical connectors on adjacent lines, the culprits could be:
- You have a package or mode that additionally propertizes text in your org buffer, e.g.
org-indent. Try disabling it and see what happens. - Your lines include characters higher than the regular ones. I saw that with CJK glyphs.
Other packages dealing with unicode, like uniline, encounter the same problem. Even Org tables have those gaps. Unfortunately, it doesn’t seem that Emacs has facilities to patch those gaps as modern terminals do.
I did my best to support CJK characters, though I speak no Chinese, Japanese or Korean and can’t really test it. If you find bugs, please report.
You’ll need a font which sets width for those characters to be exactly double of the regular characters, otherwise your map will be visually crumpled, vertical connectors will not align.
Right-to-left text may work, but it was not tested. If you have bugs or, on the opposite, can confirm that it works, please report.
Here’s one more complex example mindmap for a chapter from Sönke Ahrens — How to Take Smart Notes.
╭─ thinking
├─ studying
╭─ Writing ── is an aid for ┼─ generating ideas
│ ├─ reading
│ ╰─ understanding
├─ Thinking ── happens on paper
├─ Rules ── keep a pen at hand
├─ fleeting ╭─ fleeting :: reminders of thoughts ┬─ put in one place
│ │ ╭─ when reading ╰─ process later
│ │ ├─ briefly
│ ├─ literature ┼─ selectively ── for your own topics
│ │ ├─ in your own words
│ │ ├─ with bibliographic data
│ │ ╰─ put to the reference system
⏴⏵ ┤ │ ╭─ feeting
│ │ ╭─ review notes ┼─ literature
│ │ │ ╰─ once a day ╭─ research
╰─ Process ┬─ collect notes ┤ ├─ think ── how they relate to ┼─ reflections
│ │ ├─ one note for each idea ╰─ interests
│ │ │ ╭─ full sentences
│ │ │ ├─ sources
│ ╰─ permanent ┼─ as for another person ┼─ links
├─ turn into draft ├─ discard ── fleeting ├─ precisely
╰─ edit │ ├─ clearly
│ ╰─ briefly
├─ add ┬─ behind the note it relates to directly
│ ╰─ links
╰─ make sure ── you can find it ┬─ in the index
╰─ at entry point
One more map, from another book: Ervand Abrahamian. A History of Modern Iran.
constant ─╮
3 x France ─┬ size ─┤
6 x UK ─╯ │
Persian Gulf ── south ─┤
Khurasan ─╮ │ ╭─ (property) ── (beg XX) ── (beg XXI)
Sistan ─┼ mountains of ── east ─┤ ├─ population ── 12 mln ── 69 mln
Baluchestan ─╯ │ ├─ .. village ── 60% ── <30%
Shatt al-Arab marshes ─┬ west ─┤ ├─ .. nomads ── 25% ── 3%
Kurdish mountains ─╯ ├ Geography ── ⏴ Iran ⏵ ── Identity ┼─ .. urban ── 15% ── 66%
Aras ─┬ rivers ── north ─┤ ├─ .. of Tehran ── 200k ── 6.5mln
Artak ─╯ │ ├─ life expectancy ── 30y ── 70y
rainfall ── lacks ─┤ ├─ child mortality ── 50% ── 3%
Azerbaijan ─╮ │ ├─ literacy ── 5% ── 85%
Kurdestan ─┤ │ ╰─ .. in Persian ── <50% ── >85%
Caspian coast ─┼ only ── farming ─╯
irrigated villages ─┤
near mountains ── oases ─╯
The map about org-mindmap:
this is centered ── centered ─╮
and this is top ── top ─┼ two layouts ─╮
switch with C-c m v ─╯ │ ╭─ =M-<up>/<down>= ── move up/down
soft-wrap nodes at n ── :max-width ─╮ │ ╭─ move nodes ┼─ =M-<left>/<right>= ── move up/down the tree
chars <n> │ │ │ ╰─ works with subtrees
compute based on the ─╮ │ │ │ ╭─ to org list ── =C-c m l=
width of your window ├ :max-width ─┤ │ │ │ ╭─ =C-c m m=
and the depth of your ─╯ auto ├ wrap long ─┤ │ │ ├─ but map ── yet
map │ nodes │ ├─ convert ┴─ from a list ╯ settings
don't wrap leaves at all ── nil ─╮ │ │ │ from the
p times longer than ── <p> ─┴ :wrap-leaves ─╯ │ │ header are
non-leaves │ │ not saved
supports two-sided maps! ─┤ │ ╭─ Chinese ── 你好世界
and preserved ─╮ │ │ ├─ Japanese ── こんにちは世界
see the point in the ─┴ point is ─┼ align ─╮ │ ╭─ variable ┼─ Korean ── 안녕하세요
middle of the node tracked │ mindmaps │ │ │ width chars ╰─ but you'll need a CJK
for large maps ─╮ │ │ ├─ supports ┤ monospace font
subtrees can be shifted ─┼ compaction ─┤ ├ « what can it » ┤ │ ╭─ nodes ── font properties
upwards │ │ │ do? │ │ ├─ connectors ── and ── but better it use the
if there is free space ─╯ │ │ │ ╰─ customization ┤ whitespaces same bg
will fix small ─╮ │ │ │ ╰─ root ── =M-x customize-group
misalignments │ │ │ │ delimiters org-mindmap=
with a node in front of ─╮ │ │ │ │ ╭─ add nodes on the right
it │ │ │ │ │ ╭─ M-ret to ┤ side
and this mode's ─┤ ├ robustness ─╯ │ │ │ edit a node ╰─ then move to the left
connectors shift ├ if you edit ─╯ │ │ │ one
it'll try to recover ─┤ a node │ │ ├─ start typing ── then M-ret ── and continue in
see =recovery-drift= ─╯ │ ╰─ tips ┤ minibuffer
option │ ├─ use ┬─ for the long blocks
no rendering ─╮ │ │ footnotes ╰─ [fn:1]
editing mode ─┬ between ── no discrepancy ─┤ │ │ ╭─ consider setting
and view mode ─╯ ├ text only ─╯ ╰─ if you need ── and they're ╯ =alloc-gc-cons-percentage=
as regular text ── can edit it ─┤ large maps laggy option to 0.5-0.7
no extra dependencies ─┤
no js ─╯
[fn:1] In a footnote below the map one can insert links, use markup, even tables, and whatever Org provides. A possible use case is to draft a report as a mindmap, write a paragraph or two for each leaf, and then to assemble a report from those pieces.
