changeset 677: |
585f14458a65 |
parent: |
af486e0a40c9
|
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Tue, 24 Sep 2024 22:19:05 -0400 |
permissions: |
-rw-r--r-- |
description: |
tweaks |
1 ;;; lib/inbox.el --- Inbox API -*- lexical-binding: t -*- 3 ;; Copyright (C) 2023 Richard Westhaver 5 ;; Keywords: maint, tools, outlines, extensions 7 ;; This program is free software; you can redistribute it and/or modify 8 ;; it under the terms of the GNU General Public License as published by 9 ;; the Free Software Foundation, either version 3 of the License, or 10 ;; (at your option) any later version. 12 ;; This program is distributed in the hope that it will be useful, 13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 ;; GNU General Public License for more details. 17 ;; You should have received a copy of the GNU General Public License 18 ;; along with this program. If not, see <https://www.gnu.org/licenses/>. 22 ;; This is the elisp interface to the CC Inbox system. The main 23 ;; interface is the inbox.org file which manages personal tasks. 25 ;; Users may use `org-capture' to insert tasks and notes into their 26 ;; own `org-inbox-file' and refactor them to a more sensible 27 ;; destination with `org-refile'. 33 ;; (require 'uml-mode) 40 (defcustom org-inbox-file 41 (concat (file-name-as-directory org-directory) "inbox.org") 42 "Custom inbox file location." 46 (defcustom org-inbox-date-start-format "<%Y-%m-%d %a>" 47 "Format of DATE_START property timestamp for week headings. See 48 `org-time-stamp-formats' for accepted values." 52 (defvar org-inbox-buffer-name "*Inbox*" 53 "The name of the org-inbox buffer.") 55 (defvar org-inbox-config-buffer-name "*Inbox Config*" 56 "Then name of the org-inbox configuration buffer.") 58 (defvar org-inbox-properties 59 '("NEXT" "PREV" "FROM" "TO" "OWNER" "PROJECT" "BLOCKER" "VERSION")) 61 (defvar org-inbox-db-schema 62 '(id file node edge contents properties schedule)) 65 (setq org-id-link-to-org-use-id t 66 org-protocol-default-template-key "L") 69 (setq org-capture-templates 70 `(("i" "inbox-item" entry (file ,org-inbox-file) 73 ("t" "inbox-task" entry (file ,org-inbox-file) "* TODO %^{item}\n") 74 ("n" "inbox-note" entry (file ,org-inbox-file) "* %^{item}\n%a") 75 ("w" "inbox-web-link" entry (file ,org-inbox-file) 79 (org-web-tools-insert-link-for-url (org-web-tools--get-first-url)))) 80 ("1" "current-task-item" item (clock) "%i%?") 81 ("2" "current-task-checkbox" checkitem (clock) "%i%?") 82 ("3" "current-task-region" plain (clock) "%i" :immediate-finish t :empty-lines 1) 83 ("4" "current-task-kill" plain (clock) "%c" :immediate-finish t :empty-lines 1) 84 ("l" "log" item (file+headline "log.org" "log") "%U %?" :prepend t) 85 ("s" "secret" table-line (file+function "krypt" org-ask-location) "| %^{key} | %^{val} |" :immediate-finish t :kill-buffer t) 86 ("N" "note-item" plain (file+function "notes.org" org-ask-location) "%?"))) 88 (add-hook 'org-after-todo-state-change-hook #'org-id-get-create) 89 (add-hook 'org-after-todo-state-change-hook #'org-expiry-insert-created) 91 (setq org-default-notes-file (join-paths org-directory "inbox.org") 92 org-capture-use-agenda-date t 93 org-archive-location "archive.org::") 96 ;; `org-archive-all-done' doesn't work the way we want. This function 97 ;; will archive all done tasks in the current subtree, or the whole file 98 ;; if prefix arg is given. 99 (defun org-archive-done (&optional scope) 100 "archive all tasks with todo-state of 'DONE' or 'NOPE'." 104 (org-archive-subtree) 105 (setq org-map-continue-from (org-element-property :begin (org-element-at-point)))) 106 "/+DONE|NOPE" scope)) 108 (defun org-children-done () 109 "Mark all sub-tasks in this heading as 'DONE'." 113 (unless (= (org-current-level) 1) 117 (defmacro with-inbox-buffer (&rest body) 119 (with-current-buffer (find-file org-inbox-file) 122 (defun org-sort-todo-priority () 123 "Sorting function used by `org-sort' to sort by todo order 124 followed by priority. Returns a pair of numbers (TODO . PRIO)." 125 (let* ((elt (cadr (org-element-at-point))) 126 (todo (when-let ((kw (plist-get elt :todo-keyword))) 128 (substring-no-properties kw)))) 129 (prio (pcase (plist-get elt :priority) 135 ;; FIXME todo states shouldn't be hardcoded 137 ((null todo) (setq res (cons 3 prio))) 138 ((string= todo "WATCH") (setq res (cons 3 prio))) 139 ((string= todo "WAIT") (setq res (cons 1 prio))) 140 ((string= todo "HOLD") (setq res (cons 1 prio))) 141 ((string= todo "WIP") (setq res (cons 1 prio))) 142 ((string= todo "GOTO") (setq res (cons 2 prio))) 143 ((string= todo "TODO") (setq res (cons 2 prio))) 144 ((string= todo "RESEARCH") (setq res (cons 3 prio))) 145 ((string= todo "DONE") (setq res (cons 4 prio))) 146 ((string= todo "NOPE") (setq res (cons 4 prio)))) 147 (unless res (setq res (cons 0 prio))) 150 (defun org-sort-compare-todo-priority (a b) 151 "Given two cons consisting of (TODO . PRIO), return t if A 152 should come before B." 153 (message "a: %S b: %S" a b) 155 ((< (car a) (car b)) t) 156 ((> (car a) (car b)) nil) 159 ((< (cdr a) (cdr b)) t) 160 ((> (cdr a) (cdr b)) nil))))) 163 (defun org-inbox-sort () 164 "Sort the current heading by todo order followed by priority." 167 (org-sort-entries nil ?f #'org-sort-todo-priority #'org-sort-compare-todo-priority))) 169 (defun org-inbox-compact () 170 "Assign missing IDs and creation dates, archive DONE tasks." 173 (org-id-update-id-locations) 174 (org-id-add-to-headlines-in-file) 176 (org-map-entries #'org-expiry-insert-created) 179 (defun org-inbox-open () 180 "Open `org-inbox-file' or switch to its buffer if already open." 182 (if-let ((inbox (get-buffer org-inbox-buffer-name))) 183 (switch-to-buffer inbox) 184 (find-file org-inbox-file) 185 (rename-buffer org-inbox-buffer-name))) 187 (defun org-inbox-close () 188 "Close the org-inbox and associated buffers." 190 (when-let ((inbox (get-buffer org-inbox-buffer-name))) 191 (kill-buffer inbox))) 196 (defun org-dblock-write:summary (params) 197 "Generate a file or heading summary section.") 199 (defun org-summary () 200 "Insert or update a summary section.") 202 (defun org-inbox-configure-dblock () 203 "Configure the current org-inbox-dblock at point." 205 (with-demoted-errors "Error: %S" 206 (let* ((beginning (org-beginning-of-dblock)) 207 (parameters (org-prepare-dblock))) 208 (org-inbox-show-config-buffer (current-buffer) beginning parameters)))) 211 (defun org-inbox-show-config (&optional buffer position parameters) 213 (switch-to-buffer org-inbox-config-buffer-name) 216 (widget-insert "\n\n") 217 (widget-create 'push-button 218 :notify (lambda(_widget &rest _ignore) 219 (with-current-buffer buffer 224 (propertize "Apply" 'face 'font-lock-comment-face)) 226 (widget-create 'push-button 227 :notify (lambda (_widget &rest _ignore) 229 (propertize "Cancel" 'face 'font-lock-string-face)) 230 (use-local-map widget-keymap) 234 ;; inbox.el ends here