UP | HOME

Org Mode

Table of Contents

1 Configuration

This is my current configuration for org-mode, some parts aren't used anymore, but I keep them for historical purposes.

  • Include some packages
    (require 'org-install)
    (require 'org-publish)
    (require 'org-mime)
    (require 'org-checklist)
    
    • Use org-mode for the extensions .org and .orgarchive.
      (add-to-list 'auto-mode-alist '("\\.\\(org\\|org_archive\\)$" . org-mode))
      
    • Global shortcuts, pick the ones you like
      ;; Standard key bindings
      (global-set-key "\C-cl" 'org-store-link)
      (global-set-key "\C-ca" 'org-agenda)
      (global-set-key "\C-cb" 'org-iswitchb)
      (global-set-key (kbd "<f12>") 'org-agenda)
      (global-set-key (kbd "<f5>") 'bh/org-todo)
      (global-set-key (kbd "<S-f5>") 'widen)
      (global-set-key (kbd "<f7>") 'set-truncate-lines)
      (global-set-key (kbd "<f8>") 'org-cycle-agenda-files)
      (global-set-key (kbd "<f9> b") 'bbdb)
      (global-set-key (kbd "<f9> c") 'calendar)
      (global-set-key (kbd "<f9> f") 'boxquote-insert-file)
      (global-set-key (kbd "<f9> g") 'gnus)
      (global-set-key (kbd "<f9> h") 'hide-other)
      (global-set-key (kbd "<f9> O") 'org-clock-out)
      (global-set-key (kbd "<f9> r") 'boxquote-region)
      (global-set-key (kbd "<f9> s") (lambda () (interactive) (switch-to-buffer "*scratch*") (delete-other-windows)))
      (global-set-key (kbd "<f9> u") (lambda ()
                                       (interactive)
                                       (untabify (point-min) (point-max))))
      (global-set-key (kbd "<f9> v") 'visible-mode)
      (global-set-key (kbd "C-<f9>") 'previous-buffer)
      (global-set-key (kbd "C-x n r") 'narrow-to-region)
      (global-set-key (kbd "C-<f10>") 'next-buffer)
      (global-set-key (kbd "<f11>") 'org-clock-goto)
      (global-set-key (kbd "C-<f11>") 'org-clock-in)
      (global-set-key (kbd "M-<f11>") 'org-resolve-clocks)
      (global-set-key (kbd "C-M-r") 'org-remember)
      
    • enable spell checking whenever you open a file with org-mode
      (add-hook 'org-mode-hook
                (lambda ()
                  ;; flyspell mode to spell check everywhere
                  (flyspell-mode 1)))
      
      
    • Enable the keyboard shortcuts to change the priority of your tasks
      (setq org-enable-priority-commands t)
      
    • Define custom states (and transitions) of your tasks
      ;; ToDo states
      (setq org-todo-keywords (quote ((sequence "TODO(t)" "STARTED(s!)" "|" "DONE(d!/!)" "REJECTED(r)")
                                      (sequence "WAITING(w@/!)" "SOMEDAY(S!)" "OPEN(O@)" "|" "CANCELLED(c@/!)")
                                      (sequence "QUOTE(q!)" "QUOTED(Q!)" "|" "APPROVED(A@)" "EXPIRED(E@)" "REJECTED(R@)"))))
      
    • Set some nice colors for each new state
      (setq org-todo-keyword-faces (quote (("TODO" :foreground "#FFCC6E" :weight bold)
                                           ("STARTED" :foreground "blue" :weight bold)
                                           ("DONE" :foreground "forest green" :weight bold)
                                           ("WAITING" :foreground "orange" :weight bold)
                                           ("SOMEDAY" :foreground "magenta" :weight bold)
                                           ("CANCELLED" :foreground "forest green" :weight bold)
                                           ("QUOTE" :foreground "red" :weight bold)
                                           ("QUOTED" :foreground "magenta" :weight bold)
                                           ("APPROVED" :foreground "forest green" :weight bold)
                                           ("EXPIRED" :foreground "forest green" :weight bold)
                                           ("REJECTED" :foreground "forest green" :weight bold)
                                           ("FAIL" :foreground "red" :weight bold)
                                           ("OPEN" :foreground "blue" :weight bold))))
      
    • Set color for priorities
      (setq org-priority-faces (quote (("A" :foreground "#E01B4C")
                                       ("B" :foreground "#1739BF")
                                       ("#C" :foreground "#575757"))))
      
      
    • (setq org-fast-tag-selection-include-todo t)
      (setq org-use-fast-todo-selection t)
      (setq org-treat-S-cursor-todo-selection-as-state-change t)
      
    • Include a timestamp when a task is finished
      (setq org-log-done 'time)
      
    • Track time spent on your tasks
      (setq org-todo-state-tags-triggers
            (quote (("CANCELLED" ("CANCELLED" . t))
                    ("WAITING" ("WAITING" . t) ("NEXT"))
                    ("SOMEDAY" ("WAITING" . t))
                    (done ("NEXT") ("WAITING"))
                    ("TODO" ("WAITING") ("CANCELLED") ("NEXT"))
                    ("STARTED" ("WAITING"))
                    ("DONE" ("WAITING") ("CANCELLED") ("NEXT")))
      
                ;; Change task state to STARTED from TODO when clocking in
                   (defun bh/clock-in-to-started (kw)
                     "Switch task from TODO to STARTED when clocking in"
                     (if (and (string-equal kw "TODO")
                              (not (string-equal (buffer-name) "*Remember*")))
                         "STARTED"
                       nil))))
      
      (setq org-clock-in-switch-to-state (quote bh/clock-in-to-started))
      
      ;;
      ;; Resume clocking tasks when emacs is restarted
      (org-clock-persistence-insinuate)
      ;;
      ;; Yes it's long... but more is better ;)
      (setq org-clock-history-length 28)
      ;; Resume clocking task on clock-in if the clock is open
      (setq org-clock-in-resume t)
      ;; Change task state to NEXT when clocking in
      (setq org-clock-in-switch-to-state (quote bh/clock-in-to-next))
      ;; Separate drawers for clocking and logs
      (setq org-drawers (quote ("PROPERTIES" "LOGBOOK" "CLOCK")))
      ;; Save clock data in the CLOCK drawer and state changes and notes in the LOGBOOK drawer
      (setq org-clock-into-drawer "CLOCK")
      ;; Sometimes I change tasks I'm clocking quickly - this removes clocked tasks with 0:00 duration
      (setq org-clock-out-remove-zero-time-clocks t)
      ;; Clock out when moving task to a done state
      (setq org-clock-out-when-done t)
      ;; Save the running clock and all clock history when exiting Emacs, load it on startup
      (setq org-clock-persist (quote history))
      ;; Enable auto clock resolution for finding open clocks
      (setq org-clock-auto-clock-resolution (quote when-no-clock-is-running))
      ;; Include current clocking task in clock reports
      (setq org-clock-report-include-clocking-task t)
      
      (setq bh/keep-clock-running nil)
      
      (defun bh/clock-in ()
        (interactive)
        (setq bh/keep-clock-running t)
        (if (marker-buffer org-clock-default-task)
            (unless (org-clock-is-active)
              (bh/clock-in-default-task))
          (unless (marker-buffer org-clock-default-task)
            (org-agenda nil "c"))))
      
      (defun bh/clock-out ()
        (interactive)
        (setq bh/keep-clock-running nil)
        (when (org-clock-is-active)
          (org-clock-out)))
      
      (defun bh/clock-in-default-task ()
        (save-excursion
          (org-with-point-at org-clock-default-task
            (org-clock-in))))
      
      (defun bh/clock-out-maybe ()
        (when (and bh/keep-clock-running (not org-clock-clocking-in) (marker-buffer org-clock-default-task))
          (bh/clock-in-default-task)))
      
      (add-hook 'org-clock-out-hook 'bh/clock-out-maybe 'append)
      
      (require 'org-id)
      (defun bh/clock-in-task-by-id (id)
        "Clock in a task by id"
        (save-restriction
          (widen)
          (org-with-point-at (org-id-find id 'marker)
            (org-clock-in nil))))
      
      (defun bh/clock-in-last-task ()
        "Clock in the interrupted task if there is one"
        (interactive)
        (let ((clock-in-to-task (if (org-clock-is-active)
                                    (setq clock-in-to-task (cadr org-clock-history))
                                  (setq clock-in-to-task (car org-clock-history)))))
          (org-with-point-at clock-in-to-task
            (org-clock-in nil))))
      
      (defun bh/clock-in-to-next (kw)
        "Switch task from TODO to NEXT when clocking in.
      Skips capture tasks and tasks with subtasks"
        (if (and (string-equal kw "TODO")
                 (not (and (boundp 'org-capture-mode) org-capture-mode)))
            (let ((subtree-end (save-excursion (org-end-of-subtree t)))
                  (has-subtask nil))
              (save-excursion
                (forward-line 1)
                (while (and (not has-subtask)
                            (< (point) subtree-end)
                            (re-search-forward "^\*+ " subtree-end t))
                  (when (member (org-get-todo-state) org-not-done-keywords)
                    (setq has-subtask t))))
              (when (not has-subtask)
                "STARTED"))))
      
      
      
      (global-set-key (kbd "C-<f9> i") 'bh/clock-in)
      (global-set-key (kbd "C-<f9> o") 'bh/clock-out)
      
  • Use org mode to htmlize the content of a buffer (ideal to send html mails with gnus)
    (defun dmj/org-export-region-as-html-attachment (beg end arg)
      "Export region between BEG and END as html attachment.
    If BEG and END are not set, use current subtree.  Region or
    subtree is exported to html without header and footer, prefixed
    with a mime entity string and pushed to clipboard and killring.
    When called with prefix, mime entity is not marked as
    attachment."
      (interactive "r\nP")
      (save-excursion
        (let* ((beg (if (region-active-p) (region-beginning)
                      (progn
                        (org-back-to-heading)
                        (point))))
               (end (if (region-active-p) (region-end)
                      (progn
                        (org-end-of-subtree)
                        (point))))
               (html (concat "--[[text/html"
                             (if arg "" "\nContent-Disposition: attachment")
                             "]]\n"
                             (org-export-region-as-html beg end t 'string))))
          (when (fboundp 'x-set-selection)
            (ignore-errors (x-set-selection 'PRIMARY html))
            (ignore-errors (x-set-selection 'CLIPBOARD html)))
          (print html (get-buffer "*scratch*"))
          (message "html export done, pushed to kill ring and clipboard"))))
    
    
    (add-hook 'org-mime-html-hook
              (lambda ()
                (org-mime-change-element-style
                 "blockquote" "border-left: 2px solid gray; padding-left: 4px;")))
    
    (add-hook 'org-mime-html-hook
              (lambda ()
                (org-mime-change-element-style
                 "pre" (format "color: %s; background-color: %s; padding: 0.5em;"
                               "#E6E1DC" "#232323"))))
    (add-hook 'org-mime-html-hook
              (lambda ()
                (org-mime-change-element-style
                 "table" (format "color: %s; background-color: %s; padding: 0.5em;"
                               "#E6E1DC" "#232323"))))
    
    
    (add-hook 'org-mime-html-hook
              (lambda ()
                (org-mime-change-class-style
                 "done DONE" (format "color: %s; "
                               "green"))))
    
    (add-hook 'org-mime-html-hook
              (lambda ()
                (org-mime-change-class-style
                 "done FAIL" (format "color: %s; "
                               "red"))))
    
    (add-hook 'org-mime-html-hook
              (lambda ()
                (org-mime-change-class-style
                 "done WARN" (format "color: %s; "
                               "yellow"))))
    
    
    ;;; http://www.mail-archive.com/emacs-orgmode@gnu.org/msg23148.html
    (defun org-mml-htmlize (arg)
      "Export a portion of an email body composed using `mml-mode' to
    html using `org-mode'.  If called with an active region only
    export that region, otherwise export the entire body."
      (interactive "P")
      (let* ((region-p (org-region-active-p))
             (html-start (or (and region-p (region-beginning))
                             (save-excursion
                               (goto-char (point-min))
                               (search-forward mail-header-separator)
                               (point))))
             (html-end (or (and region-p (region-end))
                           ;; TODO: should catch signature...
                           (point-max)))
             (body (buffer-substring html-start html-end))
             (tmp-file (make-temp-name (expand-file-name "mail" "/tmp/")))
             ;; because we probably don't want to skip part of our mail
             (org-export-skip-text-before-1st-heading nil)
             ;; because we probably don't want to export a huge style file
             (org-export-htmlize-output-type 'inline-css)
             ;; makes the replies with ">"s look nicer
             (org-export-preserve-breaks t)
             (html (if arg
                       (format "<pre style=\"font-family: courier, monospace;\">\n%s</pre>\n" body)
                     (save-excursion
                       (with-temp-buffer
                         (insert body)
                         (write-file tmp-file)
                         ;; convert to html -- mimicing `org-run-like-in-org-mode'
                         (eval (list 'let org-local-vars
                                     (list 'org-export-as-html nil nil nil ''string t))))))))
        (delete-region html-start html-end)
        (save-excursion
          (goto-char html-start)
          (insert
           (format
            "\n<#multipart type=alternative>\n<#part type=text/html>%s<#/multipart>\n"
            html)))))
    
    • enable windmove in org-mode
      ;; Make windmove work in org-mode:
      (add-hook 'org-shiftup-final-hook 'windmove-up)
      (add-hook 'org-shiftleft-final-hook 'windmove-left)
      (add-hook 'org-shiftdown-final-hook 'windmove-down)
      (add-hook 'org-shiftright-final-hook 'windmove-right)
      
    • Include your tasks in agenda
      (custom-set-variables
       '(org-agenda-files (quote ("~/Dropbox/bar.org"
                                  "~/Dropbox/todo.org"
                                  )))
      )
      (add-hook 'org-agenda-mode-hook 'hl-line-mode)
      

Author: Felipe Reyes (freyes@tty.cl)

Generated by Org version 7.5 with Emacs version 23 on 2010-09-01 Wed

Validate XHTML 1.0

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License”.