(add-to-list 'load-path "~/src/emacs/org-mode/lisp")
(setq org-modules '(org-bibtex org-gnus org-info)
org-log-done t
org-todo-keywords '((sequence "TODO" "STARTED" "|" "DONE" "NA(@)"))
org-use-speed-commands t
org-fast-tag-selection-single-key 'expert
org-catch-invisible-edits 'error
org-goto-interface 'outline-path-completionp
org-src-fontify-natively t
org-special-ctrl-k t
org-outline-path-complete-in-steps nil
org-completion-use-ido t
org-blank-before-new-entry '((heading . t) (plain-list-item . auto)))
(setq org-capture-templates
'(("t" "task" entry (file+headline "~/notes/tasks.org" "Inbox")
"* TODO %?\n%i")
("d" "date" entry (file+headline "~/notes/calendar.org" "Inbox")
"* %?\n%i")
;; Link counterparts
("T" "task link" entry (file+headline "~/notes/tasks.org" "Inbox")
"* TODO %?\n%i\nLink: %a")
("D" "date link" entry (file+headline "~/notes/calendar.org" "Inbox")
"* %?\n%i\nLink: %a")
;; Clipboard
("x" "task clipboard" entry (file+headline "~/notes/tasks.org" "Inbox")
"* TODO %?\n%x")))
(key-chord-define-global ",t" 'org-capture)
(defun km/open-main-orgfile ()
(interactive)
(find-file org-default-notes-file))
(global-set-key (kbd "C-c o l") 'org-store-link)
(global-set-key (kbd "C-c o a") 'org-agenda)
(global-set-key (kbd "C-c o b") 'org-iswitchb)
(global-set-key (kbd "C-c o s") 'org-save-all-org-buffers)
(global-set-key (kbd "C-c o m") 'km/open-main-orgfile)
(key-chord-define-global ",a" 'org-agenda)
(setq org-structure-template-alist
'(("p" "#+property: " "")
("o" "#+options: " "")
("d" "#+date: " "")
("t" "#+title: " "")
("S" "#+setupfile: ?" "")
("n" "#+begin_note\n ?\n#+end_note" "\n?\n")
("w" "#+begin_note\n ?\n#+end_note" "\n?\n")
("C" "#+caption: " "")
("b" "#+label: " "")
("r" "#+attr_latex: " "")
("R" "#+attr_html: " "")
;; Lower case versions of defaults
("s" "#+begin_src ?\n \n#+end_src" "\n\n")
("e" "#+begin_example\n ?\n#+end_example" "\n?\n")
("q" "#+begin_quote\n ?\n#+end_quote" "\n?\n
")
("v" "#+begin_versen ?\n#+end_verse" "\n?\n")
("V" "#+begin_verbatim\n ?\n#+end_verbatim" "\n?\n")
("c" "#+begin_center\n ?\n#+end_center" "
\n?\n")
("l" "#+begin_latex\n ?\n#+end_latex" "\n?\n")
("L" "#+latex: " "?")
("h" "#+begin_html\n ?\n#+end_html" "\n?\n")
("H" "#+html: " "?")
("a" "#+begin_ascii\n ?\n#+end_ascii" "")
("A" "#+ascii: " "")
("i" "#+index: ?" "#+index: ?")
("I" "#+include: %file ?" "")))
(eval-after-load 'org
'(progn
(define-key org-mode-map (kbd "C-c C-x B")
'km/org-tree-to-indirect-buffer-current-window)
;; Don't let `org-cycle-agenda-files' binding override custom
;; `backward-kill-word' binding (`org-cycle-agenda-files' is still bound
;; to C-,).
(define-key org-mode-map (kbd "C-'") nil)
;; Rebind `org-insert-drawer' to so that `org-metadown' has the
;; expected "C-c C-x" keybinding.
(define-key org-mode-map (kbd "C-c C-x d") 'org-metadown)
(define-key org-mode-map (kbd "C-c C-x w") 'org-insert-drawer)
;; Avoid conflict when amsmath is loaded.
(setcar (rassoc '("wasysym" t) org-latex-default-packages-alist)
"nointegrals")
(add-to-list 'org-latex-packages-alist '("" "amsmath" t))))
(add-to-list 'auto-mode-alist '("\\.org.txt$" . org-mode))
(defadvice org-tree-to-indirect-buffer (before
org-keep-previous-indirect
(&optional arg)
activate)
"Retain previous indirect buffer from `org-tree-to-indirect-buffer'.
By default, `org-tree-to-indirect-buffer' deletes the previous
indirect buffer when making a new one to avoid accumulating
buffers, which can be overriden by a C-u prefix. This advice
reverses this behavior so that the prefix must be given in order
to delete the previous indirect buffer. If the argument is a
number, which has a different meaning, it is left untouched."
(unless (numberp arg)
(setq arg (not arg))))
(defun km/org-tree-to-indirect-buffer-current-window (&optional arg)
"Create indirect buffer and narrow to subtree in this window.
Before running `org-tree-to-indirect-buffer',
`org-indirect-buffer-display' is set to `current-window'."
(interactive "P")
(let ((org-indirect-buffer-display 'current-window))
(org-tree-to-indirect-buffer arg)))
(defun km/org-sort-parent (arg)
"Sort on parent heading ARG levels up.
After sorting, the point is returned to its previous location
under the current heading."
(interactive "p")
(let ((heading (org-no-properties (org-get-heading t t)))
starting-pos
chars-after-heading)
(setq starting-pos (point))
(save-excursion
(org-back-to-heading t)
(setq chars-after-heading (- starting-pos (point)))
(outline-up-heading arg)
(call-interactively 'org-sort))
(goto-char (+ (org-find-exact-headline-in-buffer heading nil t)
chars-after-heading))))
;;; Org in other modes
(defun km/load-orgstruct ()
(turn-on-orgstruct++)
(turn-on-orgtbl))
(add-hook 'message-mode-hook 'km/load-orgstruct)
(add-hook 'git-commit-mode-hook 'km/load-orgstruct)
(eval-after-load 'org
'(diminish 'orgstruct-mode "Os"))
(eval-after-load 'org-table
'(diminish 'orgtbl-mode "Ot"))
(add-hook 'next-error-hook '(lambda ()
(when (eq major-mode 'org-mode)
(org-show-context))))
(defadvice magit-visit
(after magit-visit-show-org-context activate)
"Show context if visiting Org buffer.
This is an improvement, but still not great. It requires the
point be on or under a heading in the Magit diff. If above, the
context will be shown for above heading."
(when (eq major-mode 'org-mode)
(org-show-context)))
;;; Agenda
(defadvice org-agenda-list (around org-agenda-fullscreen activate)
"Start agenda in fullscreen.
After agenda loads, delete other windows.
`org-agenda-restore-windows-after-quit' should non-nil to restore
the previous window configuration. If `org-agenda-sticky' is
non-nil, configurations with more than one window do not seem to
be restored properly."
ad-do-it
(delete-other-windows))
(setq org-agenda-restore-windows-after-quit t
org-agenda-sticky nil)
(setq org-default-notes-file "~/notes/tasks.org"
org-agenda-files '("~/notes/agenda")
org-agenda-show-all-dates t
org-agenda-skip-deadline-if-done t
org-agenda-skip-scheduled-if-done t
org-agenda-start-on-weekday nil
org-reverse-note-order t)
(setq org-agenda-text-search-extra-files
(file-expand-wildcards "~/notes/extra/*.org"))
(setq org-agenda-custom-commands
'(("d" todo "DONE" nil)
("u" "Unschedule TODO entries" alltodo ""
((org-agenda-skip-function
(lambda nil
(org-agenda-skip-entry-if 'scheduled 'deadline
'regexp "\n]+>")))
(org-agenda-overriding-header "Unscheduled TODO entries: ")))
("p" "Past timestamps" tags "TIMESTAMP<=\"\"")))
;;; Refiling
(defun km/verify-refile-target ()
"Exclude DONE state from refile targets."
(not (member (nth 2 (org-heading-components)) org-done-keywords)))
(setq org-refile-targets `((nil :maxlevel . 3)
(,(append org-agenda-files
org-agenda-text-search-extra-files)
:maxlevel . 2)))
(setq org-refile-target-verify-function 'km/verify-refile-target)
(defun km/org-refile-to-other-file (file &optional maxlevel)
"Refile with `org-refile-targets' set to FILE.
A numeric prefix can be given to set MAXLEVEL (defaults to 2)."
(interactive "fFile: \nP")
(let* ((maxlevel (prefix-numeric-value (or maxlevel 2)))
(file (substring-no-properties file))
(org-refile-targets `((,file :maxlevel . ,maxlevel))))
(org-refile)))
(defun km/org-refile-to-other-org-buffer (buffer &optional maxlevel)
"Refile with `org-refile-targets' set to BUFFER file name.
A numeric prefix can be given to set MAXLEVEL (defaults to 2)."
(interactive (list (km/get-org-file-buffer) current-prefix-arg))
(let ((buffer-file (buffer-file-name buffer)))
(km/org-refile-to-other-file buffer-file maxlevel)))
(defun km/get-org-file-buffer ()
(get-buffer
(org-icompleting-read "Buffer: " (mapcar 'buffer-name
(org-buffer-list 'files)))))
(defun km/org-set-refiling-buffer (maxlevel)
"Choose buffer to set as sole target in `org-refile-targets'.
If `org-refile-targets' is already a local variable, restore the
global value. A numeric prefix can be given to set
MAXLEVEL (defaults to 2)."
(interactive "P")
(if (local-variable-p 'org-refile-targets)
(kill-local-variable 'org-refile-targets)
(let* ((buffer-file (substring-no-properties
(buffer-file-name (km/get-org-file-buffer))))
(maxlevel (prefix-numeric-value (or maxlevel 2))))
(set (make-local-variable 'org-refile-targets)
`((,buffer-file :maxlevel . ,maxlevel))))))
(eval-after-load 'org
'(add-to-list 'org-mode-hook
'(lambda ()
(local-set-key (kbd "C-c m w")
'km/org-refile-to-other-org-buffer)
(local-set-key (kbd "C-c m W")
'km/org-refile-to-other-file)
(local-set-key (kbd "C-c m s")
'km/org-sort-parent)
(local-set-key (kbd "C-c m o")
'ace-link-org))))
(provide 'init-org)