complete-computing-environment/org_mode_installation.org

10 KiB

Org Mode Installation

(provide 'cce/org-mode)

Org Mode is a flexible, malleable information organization tool. It's the lynch pin of my thinking workflow, as has no doubt been demonstrated all over this collection of documents. Org-mode is the software which movitated me to switch from a life of "hardcore freestyle vim" to Emacs.

It's a well-designed markup format and a pile of Emacs Lisp, both distributed "first party" and written by third parties, and as you'll see below, the second party as well. Org-mode introduces me to the concept of org-mode meta applications, simple libraries which extend an org-mode buffer, or a set of headings which match tags or a format, to extend it.

A simple org-mode document, for example, is a little bit of syntax highlighting and overlays on top of Emacs's outline-mode. A more complicated org-mode document can add structured data, tags, date stamps and "heading states" like NEXT INPROGRESS and DONE which can be used to assemble an org-mode agenda.

Org-mode documents can also contain code, as these ones have, creating a Literate Programming environment which can pull together code from multiple languages, write them out to disk, or execute them.

Org-mode supports a "pluggable" link infrastructure, allowing you to deep-link from org-mode documents in to things like web URLs, Emails, elisp code, shell commands, etc.

It's an incredibly powerful tool for those who choose to wield it.

org-modules allows me to easily import a bunch of modules out of the contrib portion of org-plus-contrib as distributed by the org-mode developers.

  • org-gnus1: Allow org-store-link and org-insert-link to grok Gnus URLs, and to be able to link directly to groups and messages. This is key for capturing email tasks and RSS reads.
  • org-id2: Gives each entry a GUID which can be referenced easily with org-id-get, org-id-find, org-id-goto etc functions.
  • org-habit3: Habits are a part of Org mode which allows you to create repeating events that have a certain elasticity to them, as well as view the history of them easily in agendas.
  • org-protocol4: Intercepts certain types of emacsclient calls to seamlessly org-capture. I use this to feed browser tabs in to Org-mode.
  • org-bbdb5: Another link integration module, linking to BBDB entries in Org-mode.
  • org-depend allows me to define dependencies between org-mode headings, allowing me to say "finish this subtask, then clock the next one" basically, which is useful
(setq org-modules '(ol-w3m ol-bbdb ol-bibtex ol-docview ol-gnus ol-info ol-irc ol-mhe ol-rmail ol-eww org-id org-habit org-protocol org-depend))

These things will be configured in depth in other pages.

Wherever I am, I can hit C-c l to store a link to that thing (assuming its a mode that supports Org-mode links), or I can hit C-c c to enter Org capture, which I'll get in to in another document. These are prefixed as C-c instead of off of my Evil Mode leader mostly because of muscle memory. I'd like to unify these some days. I define a small mountain of global org-mode keybindings.

("C-c l" . org-store-link)
("C-c c" . org-capture)

I have to be honest. I don't understand a lot of my org-mode configuration. Some of this is my oldest configuration elements, code imported from Bernt Hansen's Norang Org Mode configuration. Over the years, I have spent some time adapting it to my needs, but nonetheless there are decisions that were made in it that I never made myself. Given how integral this is to my productivity. I will be trying to make sense of this all in code that will run after this org-mode configuration is loaded, in Norang Org Mode Configuration.

Use Unicode bullets for org-mode headings:

(use-package org-bullets
  :after org
  :hook (org-mode . org-bullets-mode))

Org Indent is a library within org-mode which indents text based on how far in to the outline it is. The first heading's text is indented by to, the second heading is indented by three, the third heading is indented by four, so that the text is underneath the heading's text start, rather than the edge of the frame. if that makes sense… It makes the buffers easier to read.

(use-package org-indent
  :after org
  :ensure nil
  :diminish
  :config
  (setq org-startup-indented t
        org-hide-leading-stars nil)
  :hook (org-mode . org-indent-mode))

Move this to its own buffer, I use UTF-8 everywhere.

(setq org-export-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
(set-charset-priority 'unicode)
(setq default-process-coding-system '(utf-8-unix . utf-8-unix))

I want org-mode to open as many things inside of Emacs as it can, this is where I focus all of my effort, but I can see using an image viewer like Gwenview for image content, but for now I keep things in Emacs.

(setq org-file-apps '((auto-mode . emacs)
                      (t . system)))

Org-mode can generate and use IDs to reference headers uniquely, rather than a tuple of file->match-string or file->line. These IDs aren't used in the context of files, and so their importance is much much lower in my current ecosystem than it was before. I retain this configuration nonetheless, because it's useful and easy to create permanent anchor IDs in HTML documents with this.

(use-package org-id
  :after org
  :ensure nil
  :config
  (setq org-id-method 'ts)
  (setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id)
  (setq org-clone-delete-id t)
  (defun bh/clock-in-task-by-id (id)
    "Clock in a task by id"
    (org-with-point-at (org-id-find id 'marker)
      (org-clock-in nil))))

Org mode clocking configuration should go in to its own file with documentation around my clocking habits.

Bernt Hansen defines a bunch of neat helper functions for working with his project workflow, which I copy and fill in a bit on below.

Clocked tasks in NEXT state swap to INPROGRESS

(setq org-clock-in-switch-to-state 'bh/clock-in-to-inprogress)
(defun bh/clock-in-to-inprogress (kw)
  "Switch a task from NEXT to INPROGRESS when clocking in.
Skips capture tasks, projects, and subprojects.
Switch projects and subprojects from NEXT back to TODO"
  (when (not (and (boundp 'org-capture-mode) org-capture-mode))
    (cond
     ((member (org-get-todo-state) (list "NEXT"))
      "INPROGRESS"))))

Open links and things in current window as always. One of these days, I will sit down long enough to understand how other-window and other-frame can be bent to my will, but I find myself getting vexed by it more often than not. Need to think about how to fix this.

(setq org-link-frame-setup '((vm . vm-visit-folder)
                             (gnus . org-gnus-no-new-news)
                             (file . find-file)))
(setq org-src-window-setup 'current-window)

I want every type of list to just become dash-delimited. I don't really need the differences, I like unified styles.

(setq org-list-demote-modify-bullet '(("+" . "-")
                                      ("*" . "-")
                                      ("1." . "-")
                                      ("1)" . "-")
                                      ("A)" . "-")
                                      ("B)" . "-")
                                      ("a)" . "-")
                                      ("b)" . "-")
                                      ("A." . "-")
                                      ("B." . "-")
                                      ("a." . "-")
                                      ("b." . "-")))
(setq org-image-actual-width nil)
(use-package org
  :demand
  :bind
  <<global-bindings>>
  :config
  (require 'org-compat)
  (setq org-startup-folded t
        org-catch-invisible-edits 'error
        org-src-fontify-natively t
        org-return-follows-link t
        org-edit-src-content-indentation 0)
  ;; use org-mode in org files
  (add-to-list 'auto-mode-alist
               '("\\.\\(org\\|org_archive\\)$" . org-mode))
  ;; org-modules defines a bunch of "plugins" to load
  <<org-modules>>
  ;; configurations
  <<org-list-flatten>>
  <<org-file-apps>>
  <<org-image-width>>)
(use-package org-contrib
  :after org)

org-auto-tangle will automatically tangle Org Babel files on save, asynchronously

I use this to tangle all of the files in the CCE automatically. Some of them like Nix Version Pins and eventually Arroyo files use noweb syntax to generate documents dynamically and have to be marked as safe so that there is no arbitrary code execution security problems.

(use-package org-auto-tangle
 :config
  (setq org-auto-tangle-babel-safelist '("/home/rrix/org/cce/version_pins.org"))
 :hook (org-mode . org-auto-tangle-mode))