Tom Willemse
30952ab6a5
The first part is an artifact from the way I've been using GTD and the other parts (if any) make the first implicit.
225 lines
8.3 KiB
EmacsLisp
225 lines
8.3 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
|
|
(cdr (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
|