5.7 KiB
5.7 KiB
Custom Elisp Functions
As of now, I haven't added anything here, though I do expect to start adding some custom functions as I learn more about Elisp.
Org Roam Dailies Shortcuts
Shortcut to goto todays org-roam dailies document.
(defun jm/org-roam-goto-day (days)
(let* ((rel-time (+ (time-convert (current-time) 'integer) (* days 86400)))
(path (format-time-string "%Y-%m-%d.org" rel-time))
(full-path (file-name-concat org-roam-directory "daily" path)))
(if (file-exists-p full-path)
(find-file full-path)
(org-roam-dailies--capture rel-time))))
(jm/leader-keys
"oy" '((lambda () (interactive) (jm/org-roam-goto-day -1)) :which-key "Open/create yesterday's daily notes file")
"ot" '((lambda () (interactive) (jm/org-roam-goto-day 0)) :which-key "Open/create today's daily notes file")
"ok" '((lambda () (interactive) (jm/org-roam-goto-day 1)) :which-key "Open/create tomorrow's daily notes file"))
Capture Template Functions
These functions are for my org roam daily capture template.
Helper Functions
(defun jm/dt-filter-tasks (helper query)
(let ((entries (org-map-entries helper query 'agenda)))
(mapconcat #'identity (delq nil entries) "\n")))
(defun jm/dt-format-link (prefix)
(let ((item-name (org-entry-get nil "ITEM"))
(item-id (org-id-get-create))
(doc-title (org-get-title)))
(format "%s [[id:%s][%s - %s]]" prefix item-id doc-title item-name)))
Queries
(defun jm/dt-get-priority (priority &optional prompt)
(jm/dt-filter-tasks
(lambda () (when (equal priority (org-entry-get nil "PRIORITY"))
(jm/dt-format-link (or prompt "-"))))
"TODO=\"TODO\"|TODO=\"IN PROGRESS\""))
(defun jm/dt-get-due-within (days &optional prompt)
(let* ((time (or (org-capture-get :default-time) (current-time)))
(date (+ (time-convert time 'integer) (* days 86400))))
(jm/dt-filter-tasks
(lambda () (when (member (org-get-todo-state) '("TODO" "IN PROGRESS"))
(jm/dt-format-link (or prompt "-"))))
(format-time-string "DEADLINE<=\"<%Y-%m-%d>\"" date))))
(defun jm/dt-get-status (status &optional prompt)
(jm/dt-filter-tasks (lambda () (jm/dt-format-link (or prompt "- [ ]")))
(concat "TODO=\"" status "\"")))
Dynamic Habits
(defun jm/dt-habit (habit)
(let* ((org-date (or (org-capture-get :default-time) (current-time)))
(today (downcase (format-time-string "%a" org-date))))
(when (seq-contains-p (cdr habit) today)
(car habit))))
(defun jm/dt-habits (habits)
(let ((out-list '()))
(dolist (habit habits out-list)
(when-let (out (jm/dt-habit habit))
(push out out-list)))
(mapconcat #'identity out-list "\n")))
Weekly Scorecard
Taken from the book 12 Week Year, the weekly scorecard is a way to measure how well you've been acting on your plan towards your weekly goal. By seeing how effective you're execution is, you are forced to face the objective truths about your productivity.
- My test checkbox.
- Other checkbox.
- My test checkbox.
(defun jm/checkbox-checked-p (checkbox)
(cond ((eq 'on (org-element-property :checkbox checkbox)) t)
((eq 'off (org-element-property :checkbox checkbox)) nil)
((org-element-property :checkbox checkbox) (error "Invalid checkbox status"))))
(defun jm/catalog-checkboxes (buffer)
(with-current-buffer buffer
(let* ((filter-fn (lambda (elem) (when (org-element-property :checkbox elem) elem)))
(elem-list (org-element-map (org-element-parse-buffer) 'item filter-fn)))
(delq nil elem-list))))
(defun jm/score-checkboxes (file-path &optional dictionary)
(let ((buffer (find-file-noselect file-path))
(was-open (get-file-buffer file-path)))
(dolist (box (jm/catalog-checkboxes buffer) dictionary)
(with-current-buffer buffer
(let* ((start (org-element-property :contents-begin box))
(end (progn (goto-char start)
(or (- (search-forward "\n" nil t) 1) (point-max))))
(key (buffer-substring-no-properties start end))
(checked (if (jm/checkbox-checked-p box) 1 0))
(pair (assoc key dictionary))
(counts (cdr pair)))
(if pair
(setcdr pair (list (+ checked (car counts)) (1+ (cadr counts))))
(push (cons key (list checked 1)) dictionary)))))
(unless was-open
(kill-buffer buffer))
dictionary))
(defun jm/n-day-scorecard (n)
(let ((time (time-convert (or (org-capture-get :default-time) (current-time)) 'integer))
(dailies-directory (expand-file-name org-roam-dailies-directory org-roam-directory))
(dict nil))
(dotimes (i n dict)
(message (format-time-string "%Y-%m-%d.org" (- time (* i 86400))))
(setq dict (jm/score-checkboxes
(expand-file-name
(format-time-string "%Y-%m-%d.org" (- time (* i 86400)))
dailies-directory)
dict)))))
(defun jm/weekly-scorecard (&optional days)
(interactive)
(let ((table "| Task | Completed | Total | Percentage |\n"))
(dolist (box (jm/n-day-scorecard (or days 7)) table)
(let* ((name (car box))
(checked (cadr box))
(total (cadr (cdr box)))
(percentage (/ (float checked) total)))
(setq table
(concat table "| " name " | "
(number-to-string checked) " | "
(number-to-string total) " | "
(number-to-string percentage) " |\n"))))))