legacy-dotfiles/emacs/.emacs.d/site-lisp/org-init.el
Tom Willemse 3eb9eb45f3 Skip next steps in org todo lists
Projects can fill up the task list quite easily, though actually only
the immediately next task is of real interest.
2015-05-25 19:26:51 +02:00

224 lines
8.2 KiB
EmacsLisp

;;; org-init.el --- Org initialization
;; Copyright (C) 2012 Tom Willemse
;; Author: Tom Willemse <slash@drd>
;; Keywords:
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
;;; Code:
(require 'appt)
(require 'org-habit)
(require 'org-protocol)
(eval-after-load "org"
'(require 'org-contacts nil :noerror))
(eval-when-compile
(require 'desktop)
(require 'org-capture))
(autoload 'org-clocking-p "org-clock")
(with-eval-after-load 'org-crypt
(org-crypt-use-before-save-magic))
(eval-and-compile
(add-to-list 'load-path "~/.emacs.d/vendor-lisp/habitrpg.el"))
(defun tagify (str)
"Remove dots, replace - with _ in STR."
(replace-regexp-in-string
"-" "_" (replace-regexp-in-string "\\." "" (downcase str))))
(defun oni:color-for (object)
"Generate a hex color by taking the first 6 characters of OBJECT's MD5 sum."
(format "#%s" (substring (md5 object) 0 6)))
(defun oni:org-colors-for (names)
"Create an alist for NAMES with corresponding colors."
(mapcar (lambda (name) (cons name (oni:color-for name))) names))
(defun oni:note-template ()
(concat
"* %<%c>\n"
" :DIRECTORY: =" default-directory "=\n"
(when (buffer-file-name) " :FILE: [[file:%F][%F]]\n")
(when (org-clocking-p) " :TASK: %K\n")
(when desktop-dirname
(concat " :PROJECT: "
(file-name-base (directory-file-name desktop-dirname))))
"\n %?"))
(defun taiga-org-task-template ()
"Turn taiga task TASK into an org task."
(let* ((project (taiga-read-project))
(user-story (taiga-read-userstory (alist-get 'id project)))
(task (taiga-read-task (alist-get 'id project)
(alist-get 'id user-story))))
(concat
"* " (alist-get 'subject task) "\n")))
(defun oni:org-maybe-outline-path ()
(let ((outline-path (org-format-outline-path (org-get-outline-path))))
(unless (string= outline-path "")
(setq outline-path (concat "[ " outline-path " ] ")))
outline-path))
(defun oni:org-heading-has-predecessor-p ()
"Determine if a heading has a predecessor.
Only tasks of a level greater than 3 are considered. A task has a
predecessor if there is a non-DONE sibling defined before it."
(let ((point (point)))
(save-excursion
(org-backward-heading-same-level 1)
(let ((components (org-heading-components)))
(not (or (< (car components) 3)
(= point (point))
(member (elt components 2) org-done-keywords)))))))
(defun oni:next-heading-position ()
(or (ignore-errors (org-forward-element)
(point))
(point-max)))
(defun org-init-skip-tags ()
"Skip the \"ex\" and \"unconfirmed\" tags."
(let ((tags (org-get-tags-at (point))))
(when (or (member "ex" tags)
(member "unconfirmed" tags)
(oni:org-heading-has-predecessor-p))
(oni:next-heading-position))))
(defun org-init-get-tag-name ()
"Get the name for a new tag for the currently loaded desktop."
(let ((dname (desktop-registry-current-desktop)))
(if dname
(let ((tag (read-string "Tag(s): " (tagify dname))))
(if (not (string= tag ""))
(format ":%s:" tag)
""))
"")))
(setq org-agenda-cmp-user-defined (lambda (a b) 1))
(setq org-agenda-prefix-format
'((agenda . " %i %-12:c%?-12t% s")
(timeline . " % s")
(todo . " %i %-12:c %(oni:org-maybe-outline-path)")
(tags . " %i %-12:c %(oni:org-maybe-outline-path)")
(search . " %i %-12:c")))
(setq org-agenda-sorting-strategy
'((agenda habit-down time-up priority-down category-keep)
(todo priority-down user-defined-down)
(tags priority-down category-keep)
(search category-keep)))
(setq org-agenda-tags-column (1+ (- (window-width))))
(setq org-directory (expand-file-name "~/documents/org"))
(setq org-default-notes-file (concat org-directory "/org"))
(setq org-capture-templates
`(("t" "Task" entry (file+headline "~/documents/org/tasks" "Inbox")
"* TODO %? %(org-init-get-tag-name)"
:empty-lines 1)
("T" "Linked task" entry (file "~/documents/org/tasks" "Inbox")
"* TODO %? %(org-init-get-tag-name)\n\n %a"
:empty-lines 1)
("a" "Appointment" entry (file "~/documents/org/tasks" "Inbox")
"* %?\n %^T\n\n %a"
:empty-lines-before 1)
("n" "General note" entry (file ,org-default-notes-file)
(function oni:note-template)
:empty-lines-before 1)
("l" "Log entry" entry (file+datetree "~/documents/org/log.org")
"* %<%c>\n <%<%Y-%m-%d %H:%M>>\n\n %?"
:empty-lines-before 1)
("d" "10 things to do today" entry (file+datetree "~/documents/org/dailies.org")
"* %<%R> [0/10]\n\n - [ ] %?\n - [ ] \n - [ ] \n - [ ] \n - [ ] \n - [ ] \n - [ ] \n - [ ] \n - [ ] \n - [ ] "
:empty-lines-before 1)
("w" "Taiga task" entry (file+headline "~/documents/org/tasks" "Inbox")
(function taiga-org-task-template)
:empty-lines-before 1)))
(setq org-contacts-files '("~/documents/org/misc/contacts.org"))
(setq org-agenda-show-outline-path nil)
(setq org-agenda-todo-ignore-deadlines 'far)
(setq org-agenda-todo-ignore-scheduled t)
(setq org-export-htmlize-output-type 'css)
(setq org-feed-alist
'(("MyEpisodes"
"http://www.myepisodes.com/rss.php?feed=mylist&uid=Slash&pwdmd5=04028968e1f0b7ee678b748a4320ac17"
"~/documents/org/tasks" "MyEpisodes"
:formatter oni:myepisodes-formatter)
("Lookat bookmarks"
"https://ryuslash.org/scuttle/api/posts_all.php?tag=lookat&order=asc&type=rss"
"~/documents/org/tasks" "Inbox"
:template "
* TODO %h :bookmark:
%U
%description
%a
")))
(setq org-fontify-done-headline t)
(setq org-hide-emphasis-markers t)
(setq org-outline-path-complete-in-steps t)
(setq org-refile-allow-creating-parent-nodes t)
(setq org-refile-use-outline-path 'file)
(setq org-return-follows-link t)
(setq org-src-fontify-natively t)
(setq org-tags-column (- 70))
(setq org-tags-exclude-from-inheritance '("crypt"))
(setq org-todo-keyword-faces
(oni:org-colors-for '("TODO" "WIP" "DONE" "CANCELLED" "FAILED"
"ACQUIRE" "IGNORED" "COMMENT" "GOT")))
(setq org-tag-faces
(oni:org-colors-for '("noexport" "tv" "dailies" "ex" "maintenance"
"housework" "cdispass" "clark" "emacsd"
"eye_on_manga" "kaarvok" "silbot" "hypo"
"unconfirmed" "gitto" "urxvt_modeline"
"scrumli" "clark_conkeror"
"git_auto_commit_mode" "mode_icons"
"dispassel" "hypo_emacs" "hypo_cli"
"conkeror" "transient_navigation" "pkgbuilds"
"edocs" "cask" "fiplr" "avandu"
"gitolite_admin" "yoshi_theme" "dvdroid"
"commit_check" "imsleepy" "indent_shift"
"work" "picturefix" "euler" "scss_imenu"
"bookmark" "blog")))
(setq org-use-fast-todo-selection t)
(setq org-agenda-skip-function-global 'org-init-skip-tags)
(setq org-use-property-inheritance '("slug"))
(setq org-M-RET-may-split-line '((default . t)
(headline)))
(setq org-insert-heading-respect-content t)
(setf (cdar org-blank-before-new-entry) t)
(add-hook 'org-agenda-mode-hook 'org-agenda-to-appt)
(add-to-list 'org-modules 'habit)
(org-agenda-to-appt)
(ad-activate 'org-agenda-redo)
(setq org-mobile-directory "~/ownCloud/MobileOrg"
org-mobile-inbox-for-pull "~/documents/org/inbox.org")
(setq org-extend-today-until 4)
(provide 'org-init)
;;; org-init.el ends here