After years of searching and trying to write one myself, I finally found a good outliner for Emacs! (And I could not have discovered it earlier, because it’s only a few weeks old.)
I am talking of orgstruct++-mode
, a minor-mode implemented by
org-mode
. You probably know org-mode
, a
whopping monster of over 40kLOC of Elisp. In spite of trying to be an
outliner itself, it has, however, a nice feature to edit indented
lists of “bullet points”, for example:
- foo
- bar
- baz
You can just write the first line “manually” and then use M-RET to add new bullet points. Then, you can indent them with M-left and M-right. These keys are only bound on bullet points and have their usual behavior else (e.g. I use them for the excellent elscreen to change tabs). E.g. I can indent the “baz”-line with M-right:
- foo
- bar
- baz
And then I can indent the “bar”-line and it will shift recursively:
- foo
- bar
- baz
This sounds pretty trivial, but if you think it is, you haven’t tried
to implement it yourself. Your bullet points also can span multiple
lines and have several paragraphs. For this you need
orgstruct++-mode
, the ++
add the indentation features. C-j and
M-q work as expected:
- foo foofoo foofoofoo foo foofoo foofoofoo
foo foofoo foofoofoo
foo foofoo foofoofoo
meh mehmeh mehmehmeh
then turns to:
- foo foofoo foofoofoo foo foofoo foofoofoo foo foofoo foofoofoo
foo foofoo foofoofoo
meh mehmeh mehmehmeh
Also, TAB will smart-indent accordingly. Thus, we have almost everything we need for outlining. It simply feels right. A few more features:
- shuffling items
- M-up: Move item up
- M-down: Move item down
- C-c ^: Sort items
- miscellaneous
- C-c -: Change item marker (-, +, *, 1., 1))
- C-c C-c: Toggle checkbox ([ ] -> [X])
Unfortunately, there are no options yet for folding in
orgstruct++-mode
. However, since the thing is indentation-based you
can use, for example, selective display with C-x $ to get an overview
of your outline. It would be nice to have better navigation in
orgstruct as well. In the meantime, you can bind org-next-item like
this:
(org-defkey orgstruct-mode-map [(C-up)]
(orgstruct-make-binding 'org-previous-item 66601 [(C-up)]))
(org-defkey orgstruct-mode-map [(C-down)]
(orgstruct-make-binding 'org-next-item 66602 [(C-down)]))
Also, for convenience, to create a subitem (please mail if you know how to do this easier):
(define-key orgstruct-mode-map [C-return]
'(lambda () "Insert a new heading or item demoted once."
(interactive)
(execute-kbd-macro [M-return M-right])))
Finally, I have written some tools to load dashed-lists in Ruby and convert them to org-lists, HTML (XOXO) and linear text. It also can insert correct header numbering, either plain depth or Wittgenstein style.