2017-12-03 09:19:05 +01:00
|
|
|
|
;;; org.el -- Daniel's org mode configuration -*- lexical-binding: t -*-
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
2018-01-21 18:12:48 +01:00
|
|
|
|
;; Everything in here influences the standard commands coming with org-mode,
|
|
|
|
|
;; either by setting variables, adding hooks, or by overriding.
|
|
|
|
|
|
2017-07-16 18:07:00 +02:00
|
|
|
|
;;; Code:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; Basic Setup
|
|
|
|
|
|
2017-08-14 08:18:55 +02:00
|
|
|
|
(require 'org)
|
|
|
|
|
|
2017-07-16 18:07:00 +02:00
|
|
|
|
(setq org-deadline-warning-days 14
|
|
|
|
|
org-read-date-popup-calendar t
|
|
|
|
|
org-insert-heading-respect-content t
|
|
|
|
|
org-list-description-max-indent 5
|
|
|
|
|
org-adapt-indentation nil
|
|
|
|
|
org-edit-timestamp-down-means-later t
|
|
|
|
|
org-archive-location "%s_archive.gpg::"
|
|
|
|
|
org-image-actual-width nil
|
2017-08-14 08:18:55 +02:00
|
|
|
|
org-footnote-section nil
|
|
|
|
|
org-log-into-drawer "LOGBOOK"
|
|
|
|
|
org-log-reschedule 'time
|
|
|
|
|
org-clone-delete-id t
|
2017-11-13 20:45:36 +01:00
|
|
|
|
org-catch-invisible-edits 'error
|
2018-01-21 16:12:55 +01:00
|
|
|
|
org-M-RET-may-split-line '((default . nil))
|
2018-07-08 13:13:13 +02:00
|
|
|
|
org-highlight-latex-and-related '(latex)
|
|
|
|
|
org-use-sub-superscripts '{}
|
2018-07-31 20:55:59 +02:00
|
|
|
|
org-src-fontify-natively t
|
|
|
|
|
org-src-preserve-indentation t)
|
2017-08-14 08:18:55 +02:00
|
|
|
|
|
|
|
|
|
(bind-key [remap org-return] 'org-return-indent org-mode-map)
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
|
|
|
|
(setq org-todo-keywords
|
|
|
|
|
'((sequence "TODO(t)" "CONT(n!)" "|" "DONE(d@)")
|
|
|
|
|
(sequence "GOTO(g)" "ATTN(a)" "|" "DONE(d@)")
|
|
|
|
|
(sequence "READ(r)" "CONT(n!)" "|" "DONE(d@)")
|
|
|
|
|
(sequence "DELG(e@/!)" "WAIT(w@/!)" "HOLD(h@/!)" "|" "CANC(c@/!)" "PHONE" "MEETING")))
|
|
|
|
|
|
|
|
|
|
(setq org-todo-state-tags-triggers
|
|
|
|
|
'(("WAIT" ("WAIT" . t))
|
|
|
|
|
("HOLD" ("HOLD" . t))
|
2017-07-27 13:06:54 +02:00
|
|
|
|
(done ("HOLD") ("WAIT") ("DATE") ("NO_EXPORT" . t))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
("TODO" ("HOLD") ("WAIT") ("NO_EXPORT"))
|
|
|
|
|
("READ" ("READ" . t) ("HOLD") ("WAIT"))
|
|
|
|
|
("GOTO" ("DATE" . t) ("HOLD") ("WAIT"))
|
|
|
|
|
("CONT" ("HOLD") ("WAIT"))
|
|
|
|
|
("ATTN" ("HOLD") ("WAIT"))))
|
|
|
|
|
|
|
|
|
|
(setq org-tag-alist
|
|
|
|
|
'((:startgroup . nil)
|
|
|
|
|
("WORK" . ?w)
|
|
|
|
|
("HOME" . ?h)
|
|
|
|
|
("FUN" . ?f)
|
|
|
|
|
("UNTAGGED" . ?u)
|
|
|
|
|
(:endgroup . nil)
|
|
|
|
|
("NOTE" . ?n)))
|
|
|
|
|
|
|
|
|
|
(setq org-treat-S-cursor-todo-selection-as-state-change nil
|
|
|
|
|
org-fast-tag-selection-single-key 'expert)
|
|
|
|
|
|
|
|
|
|
(setq org-global-properties
|
|
|
|
|
'(("Effort_ALL" . "0:00 0:15 0:30 0:45 1:00 2:00 3:00 4:00 5:00 6:00")))
|
|
|
|
|
|
|
|
|
|
(setq org-columns-default-format
|
|
|
|
|
"%80ITEM(Task) %10Effort(Effort){:} %10CLOCKSUM")
|
|
|
|
|
|
2018-07-31 20:55:59 +02:00
|
|
|
|
(setq org-structure-template-alist
|
|
|
|
|
'(("s" "#+begin_src ?\n\n#+end_src" "<src lang=\"?\">\n\n</src>")
|
|
|
|
|
("e" "#+begin_example\n?\n#+end_example" "<example>\n?\n</example>")
|
|
|
|
|
("q" "#+begin_quote\n?\n#+end_quote" "<quote>\n?\n</quote>")
|
|
|
|
|
("Q" "#+begin_equation\n?\n#+end_equation"
|
|
|
|
|
"<equation>\n?\n</equation>")
|
|
|
|
|
("v" "#+begin_verse\n?\n#+end_verse" "<verse>\n?\n</verse>")
|
|
|
|
|
("V" "#+begin_verbatim\n?\n#+end_verbatim" "<verbatim>\n?\n</verbatim>")
|
|
|
|
|
("c" "#+begin_center\n?\n#+end_center" "<center>\n?\n</center>")
|
|
|
|
|
("l" "#+begin_latex\n?\n#+end_latex"
|
|
|
|
|
"<literal style=\"latex\">\n?\n</literal>")
|
|
|
|
|
("l" "#+latex: " "<literal style=\"latex\">?</literal>")
|
|
|
|
|
("h" "#+begin_html\n?\n#+end_html"
|
|
|
|
|
"<literal style=\"html\">\n?\n</literal>")
|
|
|
|
|
("h" "#+html: " "<literal style=\"html\">?</literal>")
|
|
|
|
|
("a" "#+begin_ascii\n?\n#+end_ascii" "")
|
|
|
|
|
("a" "#+ascii: " "")
|
|
|
|
|
("i" "#+index: ?" "#+index: ?")
|
|
|
|
|
("i" "#+include: %file ?"
|
|
|
|
|
"<include file=%file markup=\"?\">")))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; How to open files and links
|
|
|
|
|
|
2017-10-20 17:59:16 +02:00
|
|
|
|
;; open directory links in emacs itself
|
|
|
|
|
(add-to-list 'org-file-apps '(directory . emacs))
|
|
|
|
|
|
2018-07-06 19:37:15 +02:00
|
|
|
|
;; use system default for Microsoft stuff
|
2018-08-15 17:54:50 +02:00
|
|
|
|
(add-to-list 'org-file-apps '("\\.docx?\\'" . default))
|
|
|
|
|
(add-to-list 'org-file-apps '("\\.pptx?\\'" . default))
|
|
|
|
|
(add-to-list 'org-file-apps '("\\.xlsx?\\'" . default))
|
2017-10-30 20:04:04 +01:00
|
|
|
|
|
2018-08-14 19:50:10 +02:00
|
|
|
|
(when (eq system-type 'cygwin)
|
2018-08-15 17:51:59 +02:00
|
|
|
|
(add-to-list 'org-file-apps '(t . "cygstart %s") t))
|
2018-08-14 19:50:10 +02:00
|
|
|
|
|
2018-07-31 20:55:59 +02:00
|
|
|
|
(when (eq system-type 'windows-nt)
|
|
|
|
|
(org-link-set-parameters "onenote" :follow #'db/org-onenote-open)
|
|
|
|
|
|
|
|
|
|
(defun db/org-onenote-open (path)
|
|
|
|
|
"Visit OneNote document on PATH."
|
|
|
|
|
(start-process "OneNote" nil "OneNote" "/hyperlink" path)))
|
|
|
|
|
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
|
|
|
|
;;; Faces
|
|
|
|
|
|
|
|
|
|
(setq org-todo-keyword-faces
|
|
|
|
|
'(("TODO" :foreground "red" :weight normal)
|
|
|
|
|
("GOTO" :foreground "red" :weight normal)
|
|
|
|
|
("READ" :foreground "red" :weight normal)
|
|
|
|
|
("CONT" :foreground "DeepSkyBlue" :weight normal)
|
|
|
|
|
("ATTN" :foreground "DeepSkyBlue" :weight normal)
|
|
|
|
|
("DONE" :foreground "forest green" :weight normal)
|
|
|
|
|
("DELG" :foreground "dark orange" :weight normal)
|
|
|
|
|
("WAIT" :foreground "orange" :weight normal)
|
|
|
|
|
("HOLD" :foreground "magenta" :weight normal)
|
|
|
|
|
("CANC" :foreground "lime green" :weight normal)
|
|
|
|
|
("MEETING" :foreground "forest green" :weight normal)
|
|
|
|
|
("PHONE" :foreground "forest green" :weight normal)
|
|
|
|
|
("REPEAT" :foreground "indian red" :weight normal)))
|
|
|
|
|
|
|
|
|
|
(setq org-fontify-done-headline nil)
|
|
|
|
|
|
|
|
|
|
(setq org-priority-faces
|
|
|
|
|
'((?A . (:foreground "Red" :weight bold))
|
|
|
|
|
(?B . (:foreground "firebrick"))
|
|
|
|
|
(?C . (:foreground "tomato"))))
|
|
|
|
|
|
2017-10-28 14:29:07 +02:00
|
|
|
|
(org-link-set-parameters
|
|
|
|
|
"file"
|
|
|
|
|
:face (lambda (path) (if (file-exists-p path) 'org-link 'org-warning)))
|
|
|
|
|
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
|
|
|
|
;;; Clocking
|
|
|
|
|
|
|
|
|
|
(setq org-clock-history-length 23
|
|
|
|
|
org-clock-in-resume t
|
|
|
|
|
org-clock-into-drawer t
|
|
|
|
|
org-clock-idle-time nil
|
|
|
|
|
org-clock-out-remove-zero-time-clocks t
|
|
|
|
|
org-clock-out-when-done '("DONE" "CANC" "WAIT" "HOLD")
|
|
|
|
|
org-clock-auto-clock-resolution 'when-no-clock-is-running
|
|
|
|
|
org-clock-mode-line-total 'auto
|
2017-09-02 13:33:57 +02:00
|
|
|
|
org-clock-report-include-clocking-task t
|
2018-01-16 17:55:15 +01:00
|
|
|
|
org-clock-in-switch-to-state (lambda (_)
|
2017-07-16 18:07:00 +02:00
|
|
|
|
(when (and (not
|
|
|
|
|
(and (boundp 'org-capture-mode)
|
|
|
|
|
org-capture-mode)))
|
|
|
|
|
(cond
|
2018-01-16 17:55:15 +01:00
|
|
|
|
((member (org-get-todo-state)
|
|
|
|
|
(list "TODO" "READ"))
|
|
|
|
|
"CONT")
|
|
|
|
|
((member (org-get-todo-state)
|
|
|
|
|
(list "GOTO"))
|
|
|
|
|
"ATTN")))))
|
2017-08-14 08:18:55 +02:00
|
|
|
|
|
|
|
|
|
(org-clock-persistence-insinuate)
|
|
|
|
|
|
|
|
|
|
(setq org-clock-persist t
|
|
|
|
|
org-clock-persist-query-resume nil)
|
|
|
|
|
|
2017-10-17 18:30:42 +02:00
|
|
|
|
(setq org-duration-format 'h:mm
|
2017-08-14 08:18:55 +02:00
|
|
|
|
org-time-stamp-rounding-minutes '(1 1))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
|
|
|
|
;; Default Tasks for Working, Home, Breaks
|
|
|
|
|
|
2017-10-17 22:08:25 +02:00
|
|
|
|
(defcustom org-working-task-id ""
|
|
|
|
|
"Task ID of default working task."
|
|
|
|
|
:group 'personal-settings
|
|
|
|
|
:type 'string)
|
|
|
|
|
|
|
|
|
|
(defcustom org-break-task-id ""
|
|
|
|
|
"Task ID of default break task."
|
|
|
|
|
:group 'personal-settings
|
|
|
|
|
:type 'string)
|
|
|
|
|
|
|
|
|
|
(defcustom org-home-task-id ""
|
|
|
|
|
"Task ID of default home task."
|
|
|
|
|
:group 'personal-settings
|
|
|
|
|
:type 'string)
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
|
|
|
|
(add-hook 'org-clock-in-hook ; mark current default task
|
|
|
|
|
(lambda ()
|
|
|
|
|
(let ((current-id (org-id-get org-clock-marker)))
|
|
|
|
|
(when (member current-id (list org-working-task-id
|
|
|
|
|
org-home-task-id))
|
|
|
|
|
(org-clock-mark-default-task)))))
|
|
|
|
|
|
|
|
|
|
;; Clock in default task if no other task is given
|
|
|
|
|
|
|
|
|
|
(defun db/find-parent-task ()
|
|
|
|
|
;; http://doc.norang.ca/org-mode.html#Clocking
|
|
|
|
|
"Return point of the nearest parent task, and NIL if no such task exists."
|
|
|
|
|
(save-mark-and-excursion
|
|
|
|
|
(save-restriction
|
|
|
|
|
(widen)
|
|
|
|
|
(let ((parent-task nil))
|
|
|
|
|
(or (org-at-heading-p)
|
|
|
|
|
(org-back-to-heading t))
|
|
|
|
|
(while (and (not parent-task)
|
|
|
|
|
(org-up-heading-safe))
|
|
|
|
|
(let ((tags (nth 5 (org-heading-components))))
|
|
|
|
|
(unless (and tags (member "NOP" (split-string tags ":" t)))
|
|
|
|
|
(setq parent-task (point)))))
|
|
|
|
|
parent-task))))
|
|
|
|
|
|
|
|
|
|
(defun db/ensure-running-clock ()
|
|
|
|
|
"Clocks in into the parent task, if it exists, or the default task."
|
|
|
|
|
(when (and (not org-clock-clocking-in)
|
|
|
|
|
(not org-clock-resolving-clocks-due-to-idleness))
|
|
|
|
|
(let ((parent-task (db/find-parent-task)))
|
|
|
|
|
(save-mark-and-excursion
|
|
|
|
|
(cond
|
|
|
|
|
(parent-task
|
|
|
|
|
;; found parent task
|
|
|
|
|
(org-with-point-at parent-task
|
|
|
|
|
(org-clock-in)))
|
|
|
|
|
((and (markerp org-clock-default-task)
|
|
|
|
|
(marker-buffer org-clock-default-task))
|
|
|
|
|
;; default task is set
|
|
|
|
|
(org-with-point-at org-clock-default-task
|
|
|
|
|
(org-clock-in)))
|
|
|
|
|
(t
|
|
|
|
|
(org-clock-in '(4))))))))
|
|
|
|
|
|
|
|
|
|
(add-hook 'org-clock-out-hook #'db/ensure-running-clock 'append)
|
|
|
|
|
|
|
|
|
|
;; clock-in helpers
|
|
|
|
|
|
|
|
|
|
(defun clock-in-task-by-id (task-id)
|
|
|
|
|
"Clock in org mode task as given by TASK-ID."
|
|
|
|
|
(org-with-point-at (org-id-find task-id 'marker)
|
|
|
|
|
(org-clock-in))
|
|
|
|
|
(org-save-all-org-buffers))
|
|
|
|
|
|
|
|
|
|
(defun clock-out-task-by-id (task-id)
|
|
|
|
|
"Clock out org mode task as given by TASK-ID."
|
|
|
|
|
(org-with-point-at (org-id-find task-id 'marker)
|
|
|
|
|
(org-clock-out))
|
|
|
|
|
(org-save-all-org-buffers))
|
|
|
|
|
|
|
|
|
|
(defun db/org-clock-in-last-task (&optional arg)
|
|
|
|
|
;; from doc.norang.ca, originally bh/clock-in-last-task
|
|
|
|
|
"Clock in the interrupted task if there is one.
|
|
|
|
|
|
|
|
|
|
Skip the default task and get the next one. If ARG is given,
|
|
|
|
|
forces clocking in of the default task."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(let ((clock-in-to-task
|
|
|
|
|
(cond
|
|
|
|
|
((eq arg 4) org-clock-default-task)
|
|
|
|
|
((and (org-clock-is-active)
|
|
|
|
|
(equal org-clock-default-task (cadr org-clock-history)))
|
|
|
|
|
(caddr org-clock-history))
|
|
|
|
|
((org-clock-is-active) (cadr org-clock-history))
|
|
|
|
|
((equal org-clock-default-task (car org-clock-history))
|
|
|
|
|
(cadr org-clock-history))
|
|
|
|
|
(t (car org-clock-history)))))
|
|
|
|
|
(widen)
|
|
|
|
|
(org-with-point-at clock-in-to-task
|
|
|
|
|
(org-clock-in nil))))
|
|
|
|
|
|
|
|
|
|
;; Communicate the currently clocked in task to the outside world
|
|
|
|
|
|
|
|
|
|
(defvar db/org-clock-current-task-file
|
|
|
|
|
"~/.org-current-task")
|
|
|
|
|
|
|
|
|
|
(defun db/org-current-task ()
|
|
|
|
|
"Format currently clocked task and write it to
|
|
|
|
|
`db/org-clock-current-task-file'."
|
|
|
|
|
(with-temp-file db/org-clock-current-task-file
|
|
|
|
|
(let ((clock-buffer (marker-buffer org-clock-marker)))
|
|
|
|
|
(if (null clock-buffer)
|
2017-10-01 16:02:20 +02:00
|
|
|
|
(insert "No running clock")
|
|
|
|
|
(insert org-clock-heading)))))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
|
|
|
|
(add-hook 'org-clock-in-hook #'db/org-current-task)
|
|
|
|
|
|
|
|
|
|
(defun db/select-clocking-task ()
|
|
|
|
|
"Select task from recent clocked-in tasks."
|
|
|
|
|
(interactive)
|
|
|
|
|
(org-clock-in '(4)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; Agenda Customization
|
|
|
|
|
|
2017-10-27 21:14:26 +02:00
|
|
|
|
(defun db/update-org-agenda-files (symbol value)
|
|
|
|
|
"Set SYMBOL to VALUE and update `org-agenda-files’ afterwards."
|
|
|
|
|
(set-default symbol value)
|
2018-01-16 17:55:15 +01:00
|
|
|
|
(setq org-agenda-files (cl-remove-duplicates
|
2017-10-27 21:14:26 +02:00
|
|
|
|
(cl-remove-if #'string-empty-p
|
2017-10-28 09:43:28 +02:00
|
|
|
|
(mapcar (lambda (symbol)
|
|
|
|
|
(when (boundp symbol)
|
|
|
|
|
(symbol-value symbol)))
|
|
|
|
|
'(db/org-default-home-file
|
|
|
|
|
db/org-default-work-file
|
|
|
|
|
db/org-default-refile-file
|
|
|
|
|
db/org-default-notes-file)))
|
2018-01-23 17:50:23 +01:00
|
|
|
|
:test #'cl-equalp)))
|
2017-10-27 21:14:26 +02:00
|
|
|
|
|
2017-10-17 22:08:25 +02:00
|
|
|
|
(defcustom db/org-default-work-file ""
|
|
|
|
|
"Path to default org-mode file at work."
|
|
|
|
|
:group 'personal-settings
|
2017-10-27 21:14:26 +02:00
|
|
|
|
:type 'string
|
|
|
|
|
:set #'db/update-org-agenda-files)
|
2017-10-17 22:08:25 +02:00
|
|
|
|
|
|
|
|
|
(defcustom db/org-default-home-file ""
|
|
|
|
|
"Path to default org-mode file at home."
|
|
|
|
|
:group 'personal-settings
|
2017-10-27 21:14:26 +02:00
|
|
|
|
:type 'string
|
|
|
|
|
:set #'db/update-org-agenda-files)
|
2017-10-17 22:08:25 +02:00
|
|
|
|
|
|
|
|
|
(defcustom db/org-default-notes-file ""
|
|
|
|
|
"Path to default org-mode file for notes."
|
|
|
|
|
:group 'personal-settings
|
2017-10-27 21:14:26 +02:00
|
|
|
|
:type 'string
|
|
|
|
|
:set #'db/update-org-agenda-files)
|
2017-10-17 22:08:25 +02:00
|
|
|
|
|
|
|
|
|
(defcustom db/org-default-refile-file ""
|
|
|
|
|
"Path to default org-mode file for capturing."
|
|
|
|
|
:group 'personal-settings
|
2017-10-27 21:14:26 +02:00
|
|
|
|
:type 'string
|
|
|
|
|
:set #'db/update-org-agenda-files)
|
2017-10-17 22:08:25 +02:00
|
|
|
|
|
|
|
|
|
(defcustom db/org-default-pensieve-file ""
|
|
|
|
|
"Path to default org-mode file for private notes."
|
|
|
|
|
:group 'personal-settings
|
2017-10-27 21:14:26 +02:00
|
|
|
|
:type 'string
|
|
|
|
|
:set #'db/update-org-agenda-files)
|
|
|
|
|
|
2018-10-31 13:51:39 +01:00
|
|
|
|
(setq org-agenda-include-diary t
|
2017-07-16 18:07:00 +02:00
|
|
|
|
org-agenda-span 1
|
|
|
|
|
org-agenda-diary-file db/org-default-refile-file
|
|
|
|
|
org-agenda-insert-diary-strategy 'top-level
|
|
|
|
|
org-catch-invisible-edits 'show
|
|
|
|
|
org-agenda-sorting-strategy '((agenda time-up habit-up priority-down)
|
|
|
|
|
(todo category-keep)
|
|
|
|
|
(tags category-keep)
|
|
|
|
|
(search category-keep)))
|
|
|
|
|
|
|
|
|
|
(setq org-agenda-window-setup 'current-window
|
|
|
|
|
org-agenda-restore-windows-after-quit t
|
|
|
|
|
org-agenda-compact-blocks nil)
|
|
|
|
|
|
|
|
|
|
(setq org-agenda-todo-ignore-with-date nil
|
|
|
|
|
org-agenda-todo-ignore-deadlines nil
|
|
|
|
|
org-agenda-todo-ignore-scheduled nil
|
|
|
|
|
org-agenda-todo-ignore-timestamp nil
|
|
|
|
|
org-agenda-skip-deadline-if-done t
|
|
|
|
|
org-agenda-skip-scheduled-if-done t
|
|
|
|
|
org-agenda-skip-timestamp-if-done t
|
|
|
|
|
org-agenda-skip-scheduled-if-deadline-is-shown 'not-today
|
|
|
|
|
org-agenda-tags-todo-honor-ignore-options t
|
|
|
|
|
org-agenda-start-with-log-mode nil
|
|
|
|
|
org-agenda-log-mode-items '(closed state)
|
|
|
|
|
org-agenda-remove-tags t
|
|
|
|
|
org-agenda-sticky nil
|
|
|
|
|
org-agenda-inhibit-startup t
|
|
|
|
|
org-agenda-tags-todo-honor-ignore-options t
|
|
|
|
|
org-agenda-dim-blocked-tasks nil
|
|
|
|
|
org-enforce-todo-checkbox-dependencies t
|
|
|
|
|
org-enforce-todo-dependencies t
|
|
|
|
|
org-agenda-use-time-grid t
|
|
|
|
|
org-agenda-persistent-filter t
|
|
|
|
|
org-agenda-search-headline-for-time nil)
|
|
|
|
|
|
|
|
|
|
(setq org-agenda-clock-consistency-checks
|
2017-10-30 20:04:45 +01:00
|
|
|
|
'(:max-duration 9999999
|
2017-07-16 18:07:00 +02:00
|
|
|
|
:min-duration 0
|
|
|
|
|
:max-gap 0
|
|
|
|
|
:gap-ok-around nil
|
|
|
|
|
:default-face ((:background "DarkRed") (:foreground "white"))
|
|
|
|
|
:overlap-face nil :gap-face nil :no-end-time-face nil
|
|
|
|
|
:long-face nil :short-face nil))
|
|
|
|
|
|
|
|
|
|
(add-hook 'org-agenda-mode-hook #'hl-line-mode 'append)
|
|
|
|
|
|
|
|
|
|
(setq org-agenda-clockreport-parameter-plist
|
|
|
|
|
'(:link t :maxlevel 4 :compact t :narrow 60 :fileskip0 t))
|
|
|
|
|
|
|
|
|
|
(setq org-stuck-projects
|
2018-08-15 17:49:27 +02:00
|
|
|
|
'("-DATE-HOLD-REGULAR-HOLD-NOTE+TODO=\"\""
|
2017-07-16 18:07:00 +02:00
|
|
|
|
("CONT" "TODO" "READ" "WAIT" "GOTO" "DELG")
|
2018-08-15 17:49:27 +02:00
|
|
|
|
("NOP")
|
2017-07-16 18:07:00 +02:00
|
|
|
|
""))
|
|
|
|
|
|
|
|
|
|
(defun db/org-agenda-list-deadlines (&optional match)
|
|
|
|
|
;; XXX org-agenda-later does not work, fix this
|
|
|
|
|
"Prepare agenda view that only lists upcoming deadlines.
|
|
|
|
|
|
|
|
|
|
Ignores MATCH."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(catch 'exit
|
|
|
|
|
(org-agenda-prepare "Deadlines")
|
|
|
|
|
(org-compile-prefix-format 'agenda)
|
|
|
|
|
(org-set-sorting-strategy 'agenda)
|
|
|
|
|
|
|
|
|
|
(let* ((today (org-today))
|
|
|
|
|
(thefiles (org-agenda-files nil 'ifmode))
|
|
|
|
|
(inhibit-redisplay (not debug-on-error))
|
2018-01-16 17:55:15 +01:00
|
|
|
|
s rtn rtnall file files date start-pos)
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
|
|
|
|
;; headline
|
|
|
|
|
(unless org-agenda-compact-blocks
|
|
|
|
|
(setq s (point))
|
|
|
|
|
(if org-agenda-overriding-header
|
|
|
|
|
(insert (org-add-props (copy-sequence org-agenda-overriding-header)
|
|
|
|
|
nil 'face 'org-agenda-structure) "\n"))
|
|
|
|
|
(org-agenda-mark-header-line s))
|
|
|
|
|
|
|
|
|
|
;; actual content
|
|
|
|
|
(setq date (calendar-gregorian-from-absolute today)
|
|
|
|
|
s (point)
|
|
|
|
|
start-pos (point)
|
|
|
|
|
files thefiles
|
|
|
|
|
rtnall nil)
|
|
|
|
|
(while (setq file (pop files))
|
|
|
|
|
(catch 'nextfile
|
|
|
|
|
(org-check-agenda-file file)
|
|
|
|
|
(setq rtn (apply 'org-agenda-get-day-entries
|
|
|
|
|
file date
|
|
|
|
|
'(:deadline)))
|
|
|
|
|
(setq rtnall (append rtnall rtn)))) ;; all entries
|
|
|
|
|
(when rtnall
|
|
|
|
|
(insert (org-agenda-finalize-entries rtnall 'agenda)
|
|
|
|
|
"\n"))
|
|
|
|
|
|
|
|
|
|
;; finalize
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(or org-agenda-multi (org-agenda-fit-window-to-buffer))
|
|
|
|
|
(unless (and (pos-visible-in-window-p (point-min))
|
|
|
|
|
(pos-visible-in-window-p (point-max)))
|
|
|
|
|
(goto-char (1- (point-max)))
|
|
|
|
|
(recenter -1)
|
|
|
|
|
(if (not (pos-visible-in-window-p (or start-pos 1)))
|
|
|
|
|
(progn
|
|
|
|
|
(goto-char (or start-pos 1))
|
|
|
|
|
(recenter 1))))
|
|
|
|
|
(goto-char (or start-pos 1))
|
|
|
|
|
(add-text-properties
|
|
|
|
|
(point-min) (point-max)
|
|
|
|
|
`(org-agenda-type agenda
|
|
|
|
|
org-redo-cmd
|
|
|
|
|
(db/org-agenda-list-deadlines ,match)))
|
|
|
|
|
(org-agenda-finalize)
|
|
|
|
|
(setq buffer-read-only t)
|
|
|
|
|
(message ""))))
|
|
|
|
|
|
|
|
|
|
(defun db/org-agenda-skip-tag (tag &optional others)
|
|
|
|
|
;; https://stackoverflow.com/questions/10074016/org-mode-filter-on-tag-in-agenda-view
|
|
|
|
|
"Skip all entries that correspond to TAG.
|
|
|
|
|
|
|
|
|
|
If OTHERS is true, skip all entries that do not correspond to TAG."
|
|
|
|
|
(let* ((next-headline (save-mark-and-excursion
|
|
|
|
|
(or (outline-next-heading) (point-max))))
|
|
|
|
|
(current-headline (or (and (org-at-heading-p)
|
|
|
|
|
(point))
|
|
|
|
|
(save-mark-and-excursion
|
|
|
|
|
;; remember to also consider invisible headings
|
|
|
|
|
(org-back-to-heading t))))
|
|
|
|
|
(has-tag (member tag (org-get-tags-at current-headline))))
|
|
|
|
|
(if (or (and others (not has-tag))
|
|
|
|
|
(and (not others) has-tag))
|
|
|
|
|
next-headline
|
|
|
|
|
nil)))
|
|
|
|
|
|
|
|
|
|
(defun db/cmp-date-property (prop)
|
|
|
|
|
;; https://emacs.stackexchange.com/questions/26351/custom-sorting-for-agenda
|
|
|
|
|
"Compare two `org-mode' agenda entries, `A' and `B', by some date property.
|
|
|
|
|
|
|
|
|
|
If a is before b, return -1. If a is after b, return 1. If they
|
|
|
|
|
are equal return nil."
|
|
|
|
|
(lexical-let ((prop prop))
|
|
|
|
|
#'(lambda (a b)
|
|
|
|
|
(let* ((a-pos (get-text-property 0 'org-marker a))
|
|
|
|
|
(b-pos (get-text-property 0 'org-marker b))
|
|
|
|
|
(a-date (or (org-entry-get a-pos prop)
|
|
|
|
|
(format "<%s>" (org-read-date t nil "now"))))
|
|
|
|
|
(b-date (or (org-entry-get b-pos prop)
|
|
|
|
|
(format "<%s>" (org-read-date t nil "now"))))
|
|
|
|
|
(cmp (compare-strings a-date nil nil b-date nil nil)))
|
2018-01-16 17:55:15 +01:00
|
|
|
|
(if (eq cmp t) nil (cl-signum cmp))))))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
|
|
|
|
(setq org-agenda-custom-commands
|
|
|
|
|
`(("A" "Main List"
|
|
|
|
|
((agenda
|
|
|
|
|
""
|
|
|
|
|
((org-agenda-entry-types '(:timestamp :sexp :scheduled :deadline))
|
2017-10-28 14:31:17 +02:00
|
|
|
|
(org-deadline-warning-days 0)))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
(db/org-agenda-list-deadlines
|
|
|
|
|
""
|
|
|
|
|
((org-agenda-overriding-header "Deadlines")
|
|
|
|
|
(org-agenda-sorting-strategy '(deadline-up priority-down))
|
|
|
|
|
(org-deadline-warning-days 30)))
|
|
|
|
|
(tags-todo "-NOAGENDA/WAIT|DELG"
|
|
|
|
|
((org-agenda-overriding-header "Waiting-fors")
|
|
|
|
|
(org-agenda-todo-ignore-deadlines t)
|
|
|
|
|
(org-agenda-todo-ignore-scheduled t)))
|
|
|
|
|
(tags "REFILE"
|
|
|
|
|
((org-agenda-files (list db/org-default-refile-file))
|
|
|
|
|
(org-agenda-overriding-header "Things to refile")))))
|
|
|
|
|
("R" "Reading List"
|
|
|
|
|
((tags-todo "READ/-DONE-CANC"
|
|
|
|
|
((org-agenda-overriding-header "To Read (unscheduled)")
|
|
|
|
|
(org-agenda-cmp-user-defined (db/cmp-date-property "CREATED"))
|
|
|
|
|
(org-agenda-sorting-strategy '(user-defined-up))
|
|
|
|
|
(org-agenda-todo-ignore-scheduled t)))))
|
|
|
|
|
("E" "Everything"
|
|
|
|
|
((tags-todo "/WAIT"
|
|
|
|
|
((org-agenda-overriding-header "Tasks requiring response/input")))
|
|
|
|
|
(tags-todo "-HOLD-READ-SOMEWHEN/-DONE"
|
|
|
|
|
((org-agenda-overriding-header "Things not being scheduled or deadlined")
|
|
|
|
|
(org-tags-match-list-sublevels t)
|
|
|
|
|
(org-agenda-todo-ignore-with-date t)
|
|
|
|
|
(org-agenda-sorting-strategy
|
|
|
|
|
'(priority-down time-up category-keep))))
|
|
|
|
|
(stuck ""
|
|
|
|
|
((org-agenda-overriding-header "Stuck Tasks")))))
|
|
|
|
|
("S" "Somewhen"
|
2018-01-01 15:34:51 +01:00
|
|
|
|
((tags-todo "SOMEWHEN/-CANC-DONE"
|
|
|
|
|
((org-agenda-overriding-header "Things to do somewhen")
|
|
|
|
|
(org-agenda-todo-ignore-with-date t)
|
|
|
|
|
(org-tags-match-list-sublevels nil)))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
(tags-todo "/HOLD"
|
|
|
|
|
((org-agenda-overriding-header "Tasks on Hold")))))
|
|
|
|
|
("W" "Weekly Review"
|
|
|
|
|
((agenda ""
|
|
|
|
|
((org-agenda-span 7)
|
|
|
|
|
(org-agenda-archives-mode t)
|
|
|
|
|
(org-agenda-dim-blocked-tasks nil)
|
|
|
|
|
(org-agenda-skip-deadline-prewarning-if-scheduled t)))))
|
|
|
|
|
("M" "Monthly Preview"
|
|
|
|
|
((db/org-agenda-list-deadlines
|
|
|
|
|
""
|
|
|
|
|
((org-agenda-overriding-header "Deadlines")
|
|
|
|
|
(org-agenda-sorting-strategy '(deadline-up priority-down))
|
|
|
|
|
(org-deadline-warning-days 90)))
|
|
|
|
|
(agenda ""
|
|
|
|
|
((org-agenda-span 'month)
|
|
|
|
|
(org-agenda-dim-blocked-tasks nil)
|
|
|
|
|
(org-deadline-warning-days 0) ; covered by display above
|
|
|
|
|
))))
|
|
|
|
|
("N" "Notes" tags "NOTE"
|
|
|
|
|
((org-agenda-overriding-header "Notes")
|
|
|
|
|
(org-use-tag-inheritance nil)
|
|
|
|
|
(org-agenda-prefix-format '((tags . " ")))))))
|
|
|
|
|
|
|
|
|
|
;; A Hydra for changing agenda appearance
|
|
|
|
|
;; http://oremacs.com/2016/04/04/hydra-doc-syntax/
|
|
|
|
|
|
|
|
|
|
(defun db/org-agenda-span ()
|
|
|
|
|
"Return the display span of the current shown agenda."
|
|
|
|
|
(let ((args (get-text-property
|
|
|
|
|
(min (1- (point-max)) (point))
|
|
|
|
|
'org-last-args)))
|
|
|
|
|
(nth 2 args)))
|
|
|
|
|
|
2018-07-31 21:01:18 +02:00
|
|
|
|
(require 'hydra)
|
|
|
|
|
|
2017-07-16 18:07:00 +02:00
|
|
|
|
(defhydra hydra-org-agenda-view (:hint none)
|
|
|
|
|
"
|
|
|
|
|
_d_: ?d? day _g_: time grid=?g? _a_: arch-trees
|
|
|
|
|
_w_: ?w? week _[_: inactive _A_: arch-files
|
|
|
|
|
_t_: ?t? fortnight _F_: follow=?F? _r_: report=?r?
|
|
|
|
|
_m_: ?m? month _e_: entry =?e? _D_: diary=?D?
|
|
|
|
|
_y_: ?y? year _q_: quit _L__l__c_: ?l?
|
|
|
|
|
|
|
|
|
|
"
|
|
|
|
|
("SPC" org-agenda-reset-view)
|
|
|
|
|
("d" org-agenda-day-view
|
|
|
|
|
(if (eq 'day (db/org-agenda-span))
|
|
|
|
|
"[x]" "[ ]"))
|
|
|
|
|
("w" org-agenda-week-view
|
|
|
|
|
(if (eq 'week (db/org-agenda-span))
|
|
|
|
|
"[x]" "[ ]"))
|
|
|
|
|
("t" org-agenda-fortnight-view
|
|
|
|
|
(if (eq 'fortnight (db/org-agenda-span))
|
|
|
|
|
"[x]" "[ ]"))
|
|
|
|
|
("m" org-agenda-month-view
|
|
|
|
|
(if (eq 'month (db/org-agenda-span)) "[x]" "[ ]"))
|
|
|
|
|
("y" org-agenda-year-view
|
|
|
|
|
(if (eq 'year (db/org-agenda-span)) "[x]" "[ ]"))
|
|
|
|
|
("l" org-agenda-log-mode
|
|
|
|
|
(format "% -3S" org-agenda-show-log))
|
|
|
|
|
("L" (org-agenda-log-mode '(4)))
|
|
|
|
|
("c" (org-agenda-log-mode 'clockcheck))
|
|
|
|
|
("F" org-agenda-follow-mode
|
|
|
|
|
(format "% -3S" org-agenda-follow-mode))
|
|
|
|
|
("a" org-agenda-archives-mode)
|
|
|
|
|
("A" (org-agenda-archives-mode 'files))
|
|
|
|
|
("r" org-agenda-clockreport-mode
|
|
|
|
|
(format "% -3S" org-agenda-clockreport-mode))
|
|
|
|
|
("e" org-agenda-entry-text-mode
|
|
|
|
|
(format "% -3S" org-agenda-entry-text-mode))
|
|
|
|
|
("g" org-agenda-toggle-time-grid
|
|
|
|
|
(format "% -3S" org-agenda-use-time-grid))
|
|
|
|
|
("D" org-agenda-toggle-diary
|
|
|
|
|
(format "% -3S" org-agenda-include-diary))
|
|
|
|
|
("!" org-agenda-toggle-deadlines)
|
|
|
|
|
("["
|
|
|
|
|
(let ((org-agenda-include-inactive-timestamps t))
|
|
|
|
|
(org-agenda-check-type t 'timeline 'agenda)
|
|
|
|
|
(org-agenda-redo)))
|
|
|
|
|
("q" (message "Abort") :exit t))
|
|
|
|
|
|
2018-08-15 21:12:42 +02:00
|
|
|
|
(with-eval-after-load 'org-agenda
|
|
|
|
|
(bind-key "v" #'hydra-org-agenda-view/body org-agenda-mode-map))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; Capturing
|
|
|
|
|
|
|
|
|
|
;; disable usage of helm for `org-capture'
|
2018-08-15 21:12:42 +02:00
|
|
|
|
(with-eval-after-load 'helm-mode
|
|
|
|
|
(defvar helm-completing-read-handlers-alist) ; for the byte compiler
|
|
|
|
|
(add-to-list 'helm-completing-read-handlers-alist
|
|
|
|
|
'(org-capture . nil)))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
2017-07-18 18:14:58 +02:00
|
|
|
|
(setq org-capture-use-agenda-date nil)
|
|
|
|
|
|
2017-07-16 18:07:00 +02:00
|
|
|
|
(setq org-capture-templates
|
2017-07-18 18:14:58 +02:00
|
|
|
|
`(("t" "Todo"
|
2017-07-16 18:07:00 +02:00
|
|
|
|
entry
|
|
|
|
|
(file db/org-default-refile-file)
|
|
|
|
|
,(concat "* TODO %^{What}\n"
|
|
|
|
|
"SCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n"
|
|
|
|
|
":PROPERTIES:\n:CREATED: %U\n:END:\n"
|
2017-07-31 13:21:19 +02:00
|
|
|
|
"%?"))
|
2017-07-18 18:14:58 +02:00
|
|
|
|
("n" "Note"
|
2017-07-16 18:07:00 +02:00
|
|
|
|
entry
|
2018-03-03 10:56:55 +01:00
|
|
|
|
(file db/org-default-refile-file)
|
2018-01-01 15:34:40 +01:00
|
|
|
|
"* %^{About} :NOTE:\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%?"
|
2017-11-06 21:30:57 +01:00
|
|
|
|
:clock-in t :clock-resume t)
|
2017-07-18 18:14:58 +02:00
|
|
|
|
("d" "Date"
|
2017-07-16 18:07:00 +02:00
|
|
|
|
entry
|
|
|
|
|
(file db/org-default-refile-file)
|
2018-09-12 17:08:51 +02:00
|
|
|
|
"* GOTO %^{What} :DATE:\n%^{When}t\n%a%?")
|
2017-07-18 18:14:53 +02:00
|
|
|
|
("i" "Interruptions")
|
|
|
|
|
("in" "Interruption now"
|
|
|
|
|
entry
|
|
|
|
|
(file db/org-default-refile-file)
|
2017-07-27 13:08:05 +02:00
|
|
|
|
"* DONE %^{What}\n\n%?"
|
2017-07-18 18:14:53 +02:00
|
|
|
|
:clock-in t :clock-resume t)
|
|
|
|
|
("ip" "Interruption previously" ; bad English vs mnemonics
|
|
|
|
|
entry
|
|
|
|
|
(file db/org-default-refile-file)
|
|
|
|
|
,(concat "* DONE %^{What}\n"
|
|
|
|
|
":LOGBOOK:\n"
|
|
|
|
|
"%(db/read-clockline)\n" ; evaluated before above prompt?
|
2017-07-27 13:08:05 +02:00
|
|
|
|
":END:\n"
|
2017-07-18 18:14:53 +02:00
|
|
|
|
"%?"))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
("j" "journal entry"
|
|
|
|
|
plain
|
|
|
|
|
(file+datetree db/org-default-pensieve-file)
|
2017-07-22 19:16:18 +02:00
|
|
|
|
"\n%i%U\n\n%?\n")
|
2017-07-16 18:07:00 +02:00
|
|
|
|
("r" "respond"
|
|
|
|
|
entry
|
|
|
|
|
(file db/org-default-refile-file)
|
|
|
|
|
,(concat "* TODO E-Mail: %:subject (%:from) :EMAIL:\n"
|
|
|
|
|
"SCHEDULED: %^{Reply when?}t\n"
|
|
|
|
|
":PROPERTIES:\n:CREATED: %U\n:END:\n"
|
|
|
|
|
"\n%a")
|
|
|
|
|
:immediate-finish t)
|
|
|
|
|
("R" "read"
|
|
|
|
|
entry
|
|
|
|
|
(file db/org-default-refile-file)
|
|
|
|
|
,(concat "* READ %:subject :READ:\n"
|
|
|
|
|
;; "DEADLINE: <%(org-read-date nil nil \"+1m\")>\n"
|
|
|
|
|
":PROPERTIES:\n:CREATED: %U\n:END:\n"
|
2017-08-14 20:36:18 +02:00
|
|
|
|
"\n%a"))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
("U" "Read current content of clipboard"
|
|
|
|
|
entry
|
|
|
|
|
(file db/org-default-refile-file)
|
|
|
|
|
,(concat "* READ %^{Description} :READ:\n"
|
|
|
|
|
":PROPERTIES:\n:CREATED: %U\n:END:\n"
|
2017-08-14 20:36:18 +02:00
|
|
|
|
"\n%(current-kill 0)"))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
("m" "Meeting"
|
|
|
|
|
entry
|
|
|
|
|
(file db/org-default-refile-file)
|
2018-01-23 17:51:00 +01:00
|
|
|
|
,(concat "* MEETING %^{What} :MEETING:\n"
|
2017-07-16 18:07:00 +02:00
|
|
|
|
":PROPERTIES:\n:CREATED: %U\n:END:\n"
|
|
|
|
|
"\n%?")
|
|
|
|
|
:clock-in t :clock-resume t)
|
|
|
|
|
("p" "Phone call"
|
|
|
|
|
entry
|
|
|
|
|
(file db/org-default-refile-file)
|
|
|
|
|
,(concat "* PHONE %^{Calling} :PHONE:\n"
|
|
|
|
|
":PROPERTIES:\n:CREATED: %U\n:END:\n"
|
|
|
|
|
"\n%?")
|
|
|
|
|
:clock-in t :clock-resume t)
|
|
|
|
|
("w" "Weekly Summary"
|
|
|
|
|
entry
|
|
|
|
|
(file+datetree db/org-default-pensieve-file)
|
2017-11-04 11:31:47 +01:00
|
|
|
|
"* Weekly Review\n\n%?")
|
2018-07-08 13:13:28 +02:00
|
|
|
|
("b" "Bookmark"
|
2017-11-04 11:31:47 +01:00
|
|
|
|
entry
|
2018-07-08 13:13:28 +02:00
|
|
|
|
(file+headline db/org-default-notes-file "Bookmarks")
|
|
|
|
|
,(concat "* [[%^{Link}][%^{Caption}]]\n"
|
|
|
|
|
":PROPERTIES:\n:CREATED: %U\n:END:\n\n")
|
|
|
|
|
:immediate-finish t)))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
2017-07-18 18:14:53 +02:00
|
|
|
|
(defun db/org-timestamp-difference (stamp-1 stamp-2)
|
|
|
|
|
"Returns time difference between two given org-mode timestamps."
|
|
|
|
|
;; Things copied from `org-clock-update-time-maybe’
|
|
|
|
|
(let* ((s (-
|
|
|
|
|
(float-time
|
2018-01-16 17:55:15 +01:00
|
|
|
|
(apply #'encode-time (org-parse-time-string stamp-2 t)))
|
2017-07-18 18:14:53 +02:00
|
|
|
|
(float-time
|
2018-01-16 17:55:15 +01:00
|
|
|
|
(apply #'encode-time (org-parse-time-string stamp-1 t)))))
|
2017-07-18 18:14:53 +02:00
|
|
|
|
(neg (< s 0))
|
|
|
|
|
(s (abs s))
|
|
|
|
|
(h (floor (/ s 3600)))
|
|
|
|
|
(m (floor (/ (- s (* 3600 h)) 60))))
|
|
|
|
|
(format (if neg "-%d:%02d" "%2d:%02d") h m)))
|
|
|
|
|
|
|
|
|
|
(defun db/read-clockline ()
|
|
|
|
|
"Read starting and ending time from user and return org mode
|
|
|
|
|
clock line."
|
|
|
|
|
(let* ((now (format-time-string "%H:%M"))
|
|
|
|
|
(starting (format "[%s]" (org-read-date t nil nil "Started: "
|
|
|
|
|
(current-time)
|
|
|
|
|
now)))
|
|
|
|
|
(ending (format "[%s]" (org-read-date t nil nil "Ended: "
|
|
|
|
|
(current-time)
|
|
|
|
|
now)))
|
|
|
|
|
(difference (db/org-timestamp-difference starting ending)))
|
|
|
|
|
(format "CLOCK: %s--%s => %s" starting ending difference)))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
2018-08-18 16:18:14 +02:00
|
|
|
|
;; Capture Code Snippets
|
|
|
|
|
;; from http://ul.io/nb/2018/04/30/better-code-snippets-with-org-capture/
|
|
|
|
|
|
|
|
|
|
(defun db/org-capture-code-snippet (filename)
|
2018-08-18 16:32:30 +02:00
|
|
|
|
"Format Org mode entry for capturing code in active region in
|
|
|
|
|
the buffer visiting FILENAME."
|
2018-08-18 16:18:14 +02:00
|
|
|
|
(with-current-buffer (find-buffer-visiting filename)
|
|
|
|
|
(let ((code-snippet (buffer-substring-no-properties (mark) (- (point) 1)))
|
|
|
|
|
(func-name (which-function))
|
|
|
|
|
(file-name (buffer-file-name))
|
|
|
|
|
(line-number (line-number-at-pos (region-beginning)))
|
|
|
|
|
(org-src-mode (let ((mm (intern (replace-regexp-in-string
|
|
|
|
|
"-mode" "" (format "%s" major-mode)))))
|
|
|
|
|
(or (car (rassoc mm org-src-lang-modes))
|
|
|
|
|
(format "%s" mm)))))
|
|
|
|
|
(format
|
|
|
|
|
"file:%s::%s
|
|
|
|
|
In ~%s~:
|
|
|
|
|
#+BEGIN_SRC %s
|
|
|
|
|
%s
|
|
|
|
|
#+END_SRC"
|
|
|
|
|
file-name
|
|
|
|
|
line-number
|
|
|
|
|
func-name
|
|
|
|
|
org-src-mode
|
|
|
|
|
code-snippet))))
|
|
|
|
|
|
|
|
|
|
(add-to-list 'org-capture-templates
|
|
|
|
|
'("s" "Code Snippet" entry (file db/org-default-refile-file)
|
|
|
|
|
"* %?\n%(db/org-capture-code-snippet \"%F\")")
|
|
|
|
|
t)
|
|
|
|
|
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
|
|
|
|
;;; Refiling
|
|
|
|
|
|
|
|
|
|
;; Refiling targets include this file and any file contributing to the agenda,
|
|
|
|
|
;; up to 9 levels deep
|
2018-08-14 19:50:25 +02:00
|
|
|
|
(setq org-refile-targets '((org-agenda-files . (:maxlevel . 9))
|
|
|
|
|
(nil . (:maxlevel . 9))))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
|
|
|
|
;; Use full outline paths for refile targets
|
|
|
|
|
(setq org-refile-use-outline-path 'file)
|
|
|
|
|
|
|
|
|
|
(setq org-refile-allow-creating-parent-nodes 'confirm)
|
|
|
|
|
(setq org-indirect-buffer-display 'current-window)
|
|
|
|
|
(setq org-outline-path-complete-in-steps nil)
|
|
|
|
|
|
2018-02-14 22:06:42 +01:00
|
|
|
|
; Exclude DONE state tasks from refile targets (from bh)
|
|
|
|
|
(defun db/verify-refile-target ()
|
|
|
|
|
"Exclude todo keywords with a done state from refile targets"
|
|
|
|
|
(not (member (nth 2 (org-heading-components)) org-done-keywords)))
|
|
|
|
|
|
|
|
|
|
(setq org-refile-target-verify-function 'db/verify-refile-target)
|
|
|
|
|
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
2017-08-12 11:25:04 +02:00
|
|
|
|
;;; Reset checklists
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
2017-08-12 11:25:04 +02:00
|
|
|
|
;; from `org-checklist’ by James TD Smith (@ ahktenzero (. mohorovi cc)),
|
|
|
|
|
;; version: 1.0
|
|
|
|
|
|
|
|
|
|
(defun org-reset-checkbox-state-maybe ()
|
|
|
|
|
"Reset all checkboxes in an entry if the `RESET_CHECK_BOXES' property is set"
|
|
|
|
|
(interactive "*")
|
|
|
|
|
(if (org-entry-get (point) "RESET_CHECK_BOXES")
|
|
|
|
|
(org-reset-checkbox-state-subtree)))
|
|
|
|
|
|
|
|
|
|
(add-hook 'org-after-todo-state-change-hook 'org-reset-checkbox-state-maybe)
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; Calendar
|
|
|
|
|
|
2018-01-21 18:12:48 +01:00
|
|
|
|
;; XXX: calendar stuff should go to `db-utils’
|
|
|
|
|
|
2017-07-16 18:07:00 +02:00
|
|
|
|
(use-package ox-icalendar
|
|
|
|
|
:commands (org-icalendar-combine-agenda-files)
|
|
|
|
|
:config (progn
|
|
|
|
|
(setq org-icalendar-include-body nil
|
|
|
|
|
org-icalendar-store-UID t
|
|
|
|
|
org-icalendar-use-deadline nil
|
|
|
|
|
org-icalendar-use-scheduled nil
|
|
|
|
|
org-icalendar-include-todo nil
|
2017-10-21 09:02:46 +02:00
|
|
|
|
org-icalendar-exclude-tags '("NO_EXPORT"))))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
|
|
|
|
(defun db/export-diary ()
|
2017-10-21 09:02:46 +02:00
|
|
|
|
"Export diary.org as ics file to the current value of `org-icalendar-combined-agenda-file’.
|
|
|
|
|
This is done only if the value of this variable is not null."
|
2017-07-16 18:07:00 +02:00
|
|
|
|
(interactive)
|
2017-10-29 22:27:38 +01:00
|
|
|
|
(require 'ox-icalendar)
|
2018-03-17 11:11:37 +01:00
|
|
|
|
(cond
|
|
|
|
|
((null org-icalendar-combined-agenda-file)
|
2018-03-17 11:39:46 +01:00
|
|
|
|
(message "`org-icalendar-combined-agenda-file’ not set, not exporting diary."))
|
2018-03-17 11:11:37 +01:00
|
|
|
|
((not (file-name-absolute-p org-icalendar-combined-agenda-file))
|
|
|
|
|
(user-error "`org-icalendar-combined-agenda-file’ not an absolute path, aborting."))
|
|
|
|
|
(t
|
2017-10-29 22:27:38 +01:00
|
|
|
|
(progn
|
|
|
|
|
(org-save-all-org-buffers)
|
2017-11-11 08:53:56 +01:00
|
|
|
|
(let ((org-agenda-files (cl-remove-if #'string-empty-p
|
|
|
|
|
(list db/org-default-home-file
|
|
|
|
|
db/org-default-work-file)))
|
2017-10-29 22:27:38 +01:00
|
|
|
|
(org-agenda-new-buffers nil))
|
|
|
|
|
;; check whether we need to do something
|
2018-01-16 17:55:15 +01:00
|
|
|
|
(when (cl-some (lambda (org-file)
|
|
|
|
|
(file-newer-than-file-p org-file
|
|
|
|
|
org-icalendar-combined-agenda-file))
|
|
|
|
|
org-agenda-files)
|
2017-10-29 22:27:38 +01:00
|
|
|
|
(message "Exporting diary ...")
|
2017-11-11 09:36:38 +01:00
|
|
|
|
;; open files manually to avoid polluting `org-agenda-new-buffers’; we
|
|
|
|
|
;; don’t want these buffers to be closed after exporting
|
2017-11-11 08:53:56 +01:00
|
|
|
|
(mapc #'find-file-noselect org-agenda-files)
|
2017-11-11 09:36:38 +01:00
|
|
|
|
;; actual export; calls `org-release-buffers’ and may thus close
|
|
|
|
|
;; buffers we want to keep around … which is why we set
|
|
|
|
|
;; `org-agenda-new-buffers’ to nil
|
2018-10-07 19:19:33 +02:00
|
|
|
|
(when (file-exists-p org-icalendar-combined-agenda-file)
|
|
|
|
|
(delete-file org-icalendar-combined-agenda-file)
|
|
|
|
|
(sit-for 3))
|
2017-10-29 22:27:38 +01:00
|
|
|
|
(org-icalendar-combine-agenda-files)
|
2018-03-17 11:11:37 +01:00
|
|
|
|
(message "Exporting diary ... done.")))))))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; Fixes
|
|
|
|
|
|
|
|
|
|
(defun endless/org-ispell ()
|
|
|
|
|
"Configure `ispell-skip-region-alist' for `org-mode'."
|
|
|
|
|
(make-local-variable 'ispell-skip-region-alist)
|
|
|
|
|
(add-to-list 'ispell-skip-region-alist '(org-property-drawer-re))
|
|
|
|
|
(add-to-list 'ispell-skip-region-alist '("~" "~"))
|
|
|
|
|
(add-to-list 'ispell-skip-region-alist '("=" "="))
|
|
|
|
|
(add-to-list 'ispell-skip-region-alist '("^#\\+BEGIN_SRC" . "^#\\+END_SRC")))
|
|
|
|
|
|
|
|
|
|
(add-hook 'org-mode-hook #'endless/org-ispell)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; Exporting
|
|
|
|
|
|
2018-09-09 11:43:24 +02:00
|
|
|
|
(setq org-export-use-babel nil)
|
|
|
|
|
|
|
|
|
|
(setq org-export-with-broken-links 'mark
|
2018-09-08 10:27:02 +02:00
|
|
|
|
org-export-with-sub-superscripts '{}
|
|
|
|
|
org-export-with-author nil
|
|
|
|
|
org-export-with-date nil
|
|
|
|
|
org-export-with-toc nil
|
|
|
|
|
org-export-with-archived-trees nil
|
|
|
|
|
org-export-with-tags t
|
|
|
|
|
org-export-with-priority nil
|
|
|
|
|
org-export-with-creator nil
|
|
|
|
|
org-export-with-entities t
|
|
|
|
|
org-export-with-special-strings t
|
|
|
|
|
org-export-with-todo-keywords nil)
|
|
|
|
|
|
|
|
|
|
(use-package ox-latex
|
|
|
|
|
:defer t
|
|
|
|
|
:config (progn
|
|
|
|
|
(setq org-latex-default-class "scrartcl"
|
2018-09-08 13:15:59 +02:00
|
|
|
|
org-latex-listings t
|
|
|
|
|
org-latex-compiler "lualatex")
|
2018-09-08 10:27:02 +02:00
|
|
|
|
(add-to-list 'org-latex-classes
|
|
|
|
|
`("scrartcl"
|
2018-09-08 21:36:15 +02:00
|
|
|
|
,(concat "\\documentclass[parskip=half,colorlinks]{scrartcl}\n"
|
2018-09-08 10:27:02 +02:00
|
|
|
|
"[DEFAULT-PACKAGES]"
|
|
|
|
|
"[PACKAGES]"
|
2018-09-08 13:16:20 +02:00
|
|
|
|
"
|
|
|
|
|
\\lstset{
|
|
|
|
|
basewidth=0.5em,
|
2018-09-08 21:44:04 +02:00
|
|
|
|
keywordstyle=\\textcolor{blue!80!white},
|
2018-09-08 21:36:15 +02:00
|
|
|
|
basicstyle=\\ttfamily,
|
2018-09-08 13:16:20 +02:00
|
|
|
|
commentstyle={\\itshape},
|
|
|
|
|
frame=tb,
|
|
|
|
|
showspaces=false,
|
|
|
|
|
showtabs=false,
|
|
|
|
|
showstringspaces=false,
|
|
|
|
|
}
|
|
|
|
|
"
|
2018-09-08 10:27:02 +02:00
|
|
|
|
"[EXTRA]\n")
|
|
|
|
|
("\\section{%s}" . "\\section*{%s}")
|
|
|
|
|
("\\subsection{%s}" . "\\subsection*{%s}")
|
|
|
|
|
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
|
|
|
|
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
|
|
|
|
("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
|
|
|
|
|
(add-to-list 'org-latex-classes
|
|
|
|
|
`("beamer"
|
|
|
|
|
,(concat "\\documentclass[presentation]{beamer}\n"
|
|
|
|
|
"[DEFAULT-PACKAGES]"
|
|
|
|
|
"[PACKAGES]"
|
2018-09-09 10:59:46 +02:00
|
|
|
|
"
|
|
|
|
|
\\lstset{
|
|
|
|
|
basewidth=0.5em,
|
|
|
|
|
keywordstyle=\\textcolor{blue!80!white},
|
|
|
|
|
basicstyle=\\ttfamily,
|
|
|
|
|
commentstyle={\\itshape},
|
|
|
|
|
frame=tb,
|
|
|
|
|
showspaces=false,
|
|
|
|
|
showtabs=false,
|
|
|
|
|
showstringspaces=false,
|
|
|
|
|
}
|
|
|
|
|
"
|
2018-09-08 10:27:02 +02:00
|
|
|
|
"[EXTRA]\n")
|
|
|
|
|
("\\section{%s}" . "\\section*{%s}")
|
|
|
|
|
("\\subsection{%s}" . "\\subsection*{%s}")
|
|
|
|
|
("\\subsubsection{%s}" . "\\subsubsection*{%s}")))
|
|
|
|
|
(add-to-list 'org-latex-packages-alist
|
|
|
|
|
'("" "listings"))
|
|
|
|
|
(add-to-list 'org-latex-packages-alist
|
|
|
|
|
'("" "xcolor"))))
|
2018-05-05 20:41:49 +02:00
|
|
|
|
|
2018-09-08 10:30:39 +02:00
|
|
|
|
(use-package ox-html
|
|
|
|
|
:defer t
|
|
|
|
|
:config (setq org-html-postamble nil))
|
|
|
|
|
|
2018-05-05 20:41:49 +02:00
|
|
|
|
(use-package ox
|
|
|
|
|
:defer t
|
2018-08-01 16:28:37 +02:00
|
|
|
|
:config (progn
|
|
|
|
|
(with-demoted-errors "Cannot load package: %s"
|
|
|
|
|
(require 'ox-md)
|
|
|
|
|
(require 'ox-pandoc))
|
|
|
|
|
(setq org-export-exclude-tags '("NO_EXPORT"))))
|
2017-07-16 18:07:00 +02:00
|
|
|
|
|
2017-08-06 13:56:14 +02:00
|
|
|
|
|
|
|
|
|
;;; Hydra
|
|
|
|
|
|
|
|
|
|
(defhydra hydra-org-clock (:color blue)
|
|
|
|
|
"
|
|
|
|
|
Current Task: %`org-clock-current-task; "
|
|
|
|
|
("w" (lambda ()
|
|
|
|
|
(interactive)
|
|
|
|
|
(clock-in-task-by-id org-working-task-id)))
|
|
|
|
|
("h" (lambda ()
|
|
|
|
|
(interactive)
|
|
|
|
|
(clock-in-task-by-id org-home-task-id)))
|
2017-09-15 17:14:14 +02:00
|
|
|
|
("b" (lambda ()
|
|
|
|
|
(interactive)
|
|
|
|
|
(clock-in-task-by-id org-break-task-id)))
|
2017-08-06 13:56:14 +02:00
|
|
|
|
("i" (lambda ()
|
|
|
|
|
(interactive)
|
|
|
|
|
(org-clock-in '(4))))
|
|
|
|
|
("a" counsel-org-goto-all)
|
|
|
|
|
("o" org-clock-out)
|
|
|
|
|
("l" db/org-clock-in-last-task)
|
|
|
|
|
("p" db/play-playlist)
|
|
|
|
|
("d" (lambda ()
|
|
|
|
|
(interactive)
|
|
|
|
|
(when (org-clock-is-active)
|
|
|
|
|
(save-window-excursion
|
|
|
|
|
(org-clock-goto)
|
|
|
|
|
(let ((org-inhibit-logging 'note))
|
|
|
|
|
(org-todo 'done)
|
|
|
|
|
(org-save-all-org-buffers)))))))
|
|
|
|
|
|
2018-02-22 16:43:42 +01:00
|
|
|
|
|
|
|
|
|
;;; Drag-and-Drop images into org-mode buffer
|
|
|
|
|
|
|
|
|
|
(when (package-installed-p 'org-download)
|
|
|
|
|
(use-package org-download))
|
|
|
|
|
|
2018-08-04 12:32:54 +02:00
|
|
|
|
|
|
|
|
|
;;; Babel
|
|
|
|
|
|
2018-09-09 11:43:24 +02:00
|
|
|
|
(use-package ob-core
|
|
|
|
|
:defer t
|
|
|
|
|
:config (setf (alist-get :results org-babel-default-header-args)
|
|
|
|
|
"output code replace"))
|
|
|
|
|
|
2018-08-04 12:32:54 +02:00
|
|
|
|
(defun org-babel-execute:hy (body params)
|
|
|
|
|
;; http://kitchingroup.cheme.cmu.edu/blog/2016/03/30/OMG-A-Lisp-that-runs-python/
|
|
|
|
|
"Execute hy code BODY with parameters PARAMS."
|
|
|
|
|
(ignore params)
|
|
|
|
|
(let* ((temporary-file-directory ".")
|
|
|
|
|
(tempfile (make-temp-file "hy-")))
|
|
|
|
|
(with-temp-file tempfile
|
|
|
|
|
(insert body))
|
|
|
|
|
(unwind-protect
|
|
|
|
|
(shell-command-to-string
|
|
|
|
|
(format "hy %s" tempfile))
|
|
|
|
|
(delete-file tempfile))))
|
|
|
|
|
|
2018-09-12 17:08:28 +02:00
|
|
|
|
|
|
|
|
|
;;; Hacks
|
|
|
|
|
|
|
|
|
|
;; The default implementation is too slow, because it is parsing all properties
|
|
|
|
|
;; of an entry by default. Let’s simplify this to only parse what we are
|
|
|
|
|
;; looking for. This makes tag search *much* faster!
|
|
|
|
|
|
|
|
|
|
(with-eval-after-load 'org
|
|
|
|
|
(defun org-cached-entry-get (pom property)
|
|
|
|
|
(if (or (eq t org-use-property-inheritance)
|
|
|
|
|
(and (stringp org-use-property-inheritance)
|
|
|
|
|
(let ((case-fold-search t))
|
|
|
|
|
(string-match-p org-use-property-inheritance property)))
|
|
|
|
|
(and (listp org-use-property-inheritance)
|
|
|
|
|
(member-ignore-case property org-use-property-inheritance)))
|
|
|
|
|
;; Caching is not possible, check it directly.
|
|
|
|
|
(org-entry-get pom property 'inherit)
|
|
|
|
|
;; This is different in the original implementation
|
2018-10-21 09:44:58 +02:00
|
|
|
|
(org-entry-get pom property))))
|
2018-09-12 17:08:28 +02:00
|
|
|
|
|
2017-12-02 20:00:58 +01:00
|
|
|
|
|
2017-07-16 18:07:00 +02:00
|
|
|
|
;;; End
|
|
|
|
|
|
|
|
|
|
(provide 'db-org)
|
|
|
|
|
|
|
|
|
|
;;; db-org.el ends here
|