Trivium

March 2009

23mar2009

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.

Copyright © 2008–2021