mirror of
https://codeberg.org/andyscott/dotfiles.git
synced 2024-12-22 18:03:11 -05:00
491 lines
18 KiB
EmacsLisp
491 lines
18 KiB
EmacsLisp
|
;;; org-mode.el --- org-mode customizations -*- lexical-binding: t -*-
|
||
|
|
||
|
;; Author: Andrew Scott <git at andyscott dot me>
|
||
|
;; Keywords: org, convenience, tools
|
||
|
;; URL: https://codeberg.org/andyscott/dotfiles
|
||
|
|
||
|
;; This file is not part of GNU Emacs
|
||
|
|
||
|
;; Copyright (c) 2024 Andrew Scott
|
||
|
|
||
|
;; MIT No Attribution
|
||
|
|
||
|
;; Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||
|
;; software and associated documentation files (the "Software"), to deal in the Software
|
||
|
;; without restriction, including without limitation the rights to use, copy, modify,
|
||
|
;; merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||
|
;; permit persons to whom the Software is furnished to do so.
|
||
|
|
||
|
;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||
|
;; INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||
|
;; PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||
|
;; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||
|
;; OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||
|
;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
|
||
|
;;; Commentary:
|
||
|
|
||
|
;; My org-mode customizations.
|
||
|
|
||
|
;;; Code:
|
||
|
|
||
|
(use-feature org
|
||
|
:bind
|
||
|
(:map as/org-prefix-map
|
||
|
("a" . org-agenda)
|
||
|
("c" . org-capture)
|
||
|
("d" . org-priority-down)
|
||
|
("h" . consult-org-heading)
|
||
|
("l" . org-store-link)
|
||
|
("s" . org-insert-subheading)
|
||
|
("u" . org-priority-up)
|
||
|
("y" . org-todo-yesterday)
|
||
|
("C-h" . consult-org-agenda)
|
||
|
("C-l" . embark-org-copy-link-target) ; `embark'
|
||
|
("M-l" . org-toggle-link-display) ; `ol'
|
||
|
("t" . org-tags-view)) ; `org-agenda'
|
||
|
(:map org-mode-map
|
||
|
;; supposed to be set by `org-use-extra-keys'
|
||
|
;; and still overwritten with `org-insert-drawer' when `org' is loaded
|
||
|
("C-c C-x d" . org-metadown))
|
||
|
:config
|
||
|
;; General options TODO: Comment various options more descriptively
|
||
|
(setopt org-adapt-indentation nil
|
||
|
org-agenda-files (directory-files-recursively org-directory "org$")
|
||
|
org-archive-location (expand-file-name "archive/%s_archive.org::" org-directory)
|
||
|
org-blank-before-new-entry '((heading . t)
|
||
|
(plain-list-item . t))
|
||
|
org-deadline-warning-days 5
|
||
|
org-default-notes-file (expand-file-name "inbox.org" org-directory)
|
||
|
org-enforce-todo-checkbox-dependencies t
|
||
|
org-fontify-done-headline t
|
||
|
org-fontify-todo-headline nil
|
||
|
org-goto-interface 'outline-path-completion ; `org-goto'
|
||
|
org-hide-emphasis-markers t
|
||
|
org-insert-heading-respect-content t
|
||
|
org-log-done 'time
|
||
|
org-log-into-drawer t
|
||
|
org-log-redeadline 'time
|
||
|
org-M-RET-may-split-line nil
|
||
|
org-pretty-entities t
|
||
|
org-pretty-entities-include-sub-superscripts nil
|
||
|
org-reverse-note-order t ; Add/refile notes at the beginning of an entry
|
||
|
org-special-ctrl-a/e t
|
||
|
org-special-ctrl-k t
|
||
|
org-startup-folded 'content
|
||
|
org-tags-column 0
|
||
|
org-todo-keywords '((sequence "TODO(t)"
|
||
|
"NEXT(x)"
|
||
|
"PROG(p)"
|
||
|
"WAIT(w@/!)"
|
||
|
"|"
|
||
|
"DONE(d!)"
|
||
|
"WONT(n@/!)")
|
||
|
(sequence "IDEA(i)" "|"))
|
||
|
org-todo-repeat-to-state "TODO")
|
||
|
:defer 3
|
||
|
:hook
|
||
|
(org-mode . org-indent-mode)
|
||
|
(org-mode . variable-pitch-mode)
|
||
|
:init
|
||
|
(bind-keys :prefix-map as/org-prefix-map
|
||
|
:prefix "C-c o")
|
||
|
(setopt org-directory "~/Nextcloud/Documents/org"
|
||
|
org-use-extra-keys t))
|
||
|
|
||
|
;;; Built-in Packages:
|
||
|
|
||
|
(use-feature oc
|
||
|
:after (org)
|
||
|
:config
|
||
|
(setopt org-cite-export-processors '((latex biblatex)
|
||
|
(t csl))
|
||
|
org-cite-global-bibliography '("~/Nextcloud/Library/bib/library.bib"))
|
||
|
(when (elpaca-installed-p 'citar)
|
||
|
(setopt org-cite-activate-processor 'citar
|
||
|
org-cite-follow-processor 'citar
|
||
|
org-cite-insert-processor 'citar)))
|
||
|
|
||
|
(use-feature oc-csl
|
||
|
:after (citeproc oc)
|
||
|
:config
|
||
|
(let ((zotero_styles (expand-file-name
|
||
|
"Zotero/styles/" (or (getenv "XDG_DATA_HOME") "~/.local/share/"))))
|
||
|
(if (file-directory-p zotero_styles)
|
||
|
(setopt org-cite-csl-styles-dir zotero_styles))))
|
||
|
|
||
|
(use-feature org-agenda
|
||
|
:after (org)
|
||
|
:bind
|
||
|
(:map org-agenda-mode-map
|
||
|
("C-c C-r" . as/org-agenda-reconcile-inbox-item))
|
||
|
:config
|
||
|
(setopt org-agenda-block-separator ?-
|
||
|
org-agenda-skip-deadline-if-done nil
|
||
|
org-agenda-skip-scheduled-if-deadline-is-shown nil
|
||
|
org-agenda-skip-scheduled-if-done nil
|
||
|
org-agenda-start-on-weekday nil
|
||
|
org-agenda-start-with-log-mode '(clock closed state)
|
||
|
org-agenda-tags-column 0)
|
||
|
(defun as/org-agenda-reconcile-inbox-item ()
|
||
|
"Process and refile an org-agenda item"
|
||
|
(interactive)
|
||
|
(org-with-wide-buffer
|
||
|
(org-agenda-set-tags)
|
||
|
(org-agenda-priority)
|
||
|
(if (y-or-n-p "Schedule item?")
|
||
|
(org-agenda-schedule nil nil))
|
||
|
(org-agenda-refile nil nil t))))
|
||
|
|
||
|
(use-feature org-capture
|
||
|
:after (org)
|
||
|
:config
|
||
|
(setq org-capture-templates ; `org-capture'
|
||
|
`(
|
||
|
("i" "Inbox"
|
||
|
entry (file+headline "inbox.org" "Ideas")
|
||
|
"** IDEA %?"
|
||
|
:empty-lines 1
|
||
|
)
|
||
|
|
||
|
("j" "Log Entry"
|
||
|
entry (file+datetree "log.org")
|
||
|
"** %?"
|
||
|
:empty-lines 1)
|
||
|
|
||
|
("n" "Note"
|
||
|
entry (file+headline "inbox.org" "Notes")
|
||
|
"** %?
|
||
|
:PROPERTIES:
|
||
|
:CREATED: %U
|
||
|
:END:"
|
||
|
:empty-lines 1)
|
||
|
|
||
|
("t" "Todo" entry (file+headline "inbox.org" "Tasks")
|
||
|
"** TODO [#B] %?
|
||
|
:PROPERTIES:
|
||
|
:CREATED: %U
|
||
|
:END:
|
||
|
%i\n%a
|
||
|
Notes: "
|
||
|
:empty-lines 1)
|
||
|
)
|
||
|
)
|
||
|
)
|
||
|
|
||
|
(use-feature org-clock
|
||
|
:after (org)
|
||
|
:config
|
||
|
(setopt org-clock-in-resume t
|
||
|
org-clock-in-switch-to-state "PROG"
|
||
|
org-clock-persist t
|
||
|
org-clock-rounding-minutes 5
|
||
|
org-clock-string-limit 20))
|
||
|
|
||
|
(use-feature org-faces
|
||
|
:after (org)
|
||
|
:config
|
||
|
(setopt org-fontify-quote-and-verse-blocks t
|
||
|
org-todo-keyword-faces '(("TODO" . (:inherit dired-mark :inverse-video t))
|
||
|
("PROG" . (:inherit match :inverse-video t))
|
||
|
("NEXT" . (:inherit dired-special :inverse-video t))
|
||
|
("WAIT" . (:inherit shadow :inverse-video t))
|
||
|
("WONT" . (:inherit org-done))
|
||
|
("DONE" . (:inherit org-done))
|
||
|
("IDEA" . (:inherit bold :inverse-video t)))
|
||
|
org-priority-faces '((?A . (:inherit error :weight semibold :inverse-video t))
|
||
|
(?B . (:inherit warning :weight semibold :inverse-video t))
|
||
|
(?C . (:inherit mode-line-inactive :weight semibold :inverse-video t))))
|
||
|
:custom-face
|
||
|
;; Headlines
|
||
|
(org-level-1 ((t (:inherit outline-1 :height 1.5))))
|
||
|
(org-level-2 ((t (:inherit outline-2 :height 1.4))))
|
||
|
(org-level-3 ((t (:inherit outline-3 :height 1.4))))
|
||
|
(org-level-4 ((t (:inherit outline-4 :height 1.2))))
|
||
|
(org-level-5 ((t (:inherit outline-5 :height 1.1))))
|
||
|
;; Ensure monospace Keywords/Tags/Blocks
|
||
|
(org-block ((t (:inherit fixed-pitch)))) ; inherited by `org-code'
|
||
|
(org-block-begin-line ((t (:inherit fixed-pitch))))
|
||
|
(org-block-end-line ((t (:inherit (org-block-begin-line fixed-pitch)))))
|
||
|
(org-checkbox ((t (:inherit (org-todo fixed-pitch)))))
|
||
|
(org-checkbox-statistics-todo ((t (:inherit (org-todo fixed-pitch)))))
|
||
|
(org-date ((t (:inherit fixed-pitch))))
|
||
|
(org-document-info-keyword ((t (:inherit (shadow fixed-pitch)))))
|
||
|
(org-drawer ((t (:inherit fixed-pitch))))
|
||
|
(org-indent ((t (:inherit (org-hide fixed-pitch)))))
|
||
|
(org-link ((t (:foreground "dark cyan" :underline t))))
|
||
|
(org-list-dt ((t (:inherit fixed-pitch))))
|
||
|
(org-meta-line ((t (:inherit (fixed-pitch)))))
|
||
|
(org-property-value ((t (:inherit fixed-pitch))))
|
||
|
(org-special-keyword ((t (:inherit fixed-pitch))))
|
||
|
(org-table ((t (:inherit fixed-pitch))))
|
||
|
(org-tag ((t (:inherit (fixed-pitch) :height 0.8))))
|
||
|
(org-verbatim ((t (:inherit fixed-pitch)))))
|
||
|
|
||
|
(use-feature org-fold
|
||
|
:after (org)
|
||
|
:config (setopt org-fold-catch-invisible-edits 'show-and-error))
|
||
|
|
||
|
(use-feature org-habit
|
||
|
:after (org))
|
||
|
|
||
|
(use-feature org-id
|
||
|
:after (org)
|
||
|
:config
|
||
|
(setopt org-id-link-to-org-use-id t
|
||
|
org-id-locations-file (locate-user-emacs-file "org-id-locations")
|
||
|
org-id-method 'ts
|
||
|
org-id-ts-format "%Y%m%dT%H%M%S.%2N%z"))
|
||
|
|
||
|
(use-feature org-keys
|
||
|
:after (org)
|
||
|
:config
|
||
|
(setopt org-return-follows-link t))
|
||
|
|
||
|
(use-feature org-list
|
||
|
:after (org)
|
||
|
:config (setopt org-list-demote-modify-bullet '(("+" . "-")
|
||
|
("-" . "+")
|
||
|
("*" . "+"))))
|
||
|
|
||
|
(use-feature org-refile
|
||
|
:after (org)
|
||
|
:config
|
||
|
(setopt org-log-refile 'note
|
||
|
org-outline-path-complete-in-steps nil
|
||
|
org-refile-allow-creating-parent-nodes 'confirm
|
||
|
org-refile-targets '((nil :maxlevel . 3)
|
||
|
(org-agenda-files :maxlevel . 2))
|
||
|
org-refile-use-outline-path 'file))
|
||
|
|
||
|
(use-feature org-src
|
||
|
:after (org)
|
||
|
:config
|
||
|
(setopt org-edit-src-content-indentation 0
|
||
|
org-src-preserve-indentation t
|
||
|
org-src-tab-acts-natively t))
|
||
|
|
||
|
;;; 3rd-party Packages:
|
||
|
|
||
|
(use-package citar
|
||
|
:after (oc)
|
||
|
:config
|
||
|
(setopt citar-bibliography org-cite-global-bibliography
|
||
|
citar-library-paths '("~/Nextcloud/Library/"))
|
||
|
;; (when (elpaca-installed-p 'citar-embark)
|
||
|
;; (setopt citar-at-point-function 'embark-act))
|
||
|
:hook (org-mode . citar-capf-setup))
|
||
|
|
||
|
(use-package citar-embark
|
||
|
:after (citar embark)
|
||
|
:config (citar-embark-mode))
|
||
|
|
||
|
(use-package citar-org-roam
|
||
|
:after (citar org-roam)
|
||
|
:config
|
||
|
(setopt citar-org-roam-capture-template-key "r"
|
||
|
citar-org-roam-note-title-template "${title} - ${author}"
|
||
|
citar-org-roam-subdir "references")
|
||
|
(citar-org-roam-mode))
|
||
|
|
||
|
(use-package citeproc
|
||
|
:defer t)
|
||
|
|
||
|
(use-package org-appear
|
||
|
:bind
|
||
|
(:prefix-map as/org-appear
|
||
|
:prefix "C-c C-q")
|
||
|
:config
|
||
|
(setopt org-appear-autoentities t
|
||
|
org-appear-autolinks nil
|
||
|
org-appear-autosubmarkers t
|
||
|
org-appear-trigger 'on-change)
|
||
|
:hook (org-mode . org-appear-mode))
|
||
|
|
||
|
(use-package org-edna
|
||
|
:bind
|
||
|
(:map as/org-prefix-map
|
||
|
("e" . org-edna-edit))
|
||
|
:config (setopt org-edna-finder-use-cache t)
|
||
|
:hook (org-mode . org-edna-mode))
|
||
|
|
||
|
(use-package org-noter
|
||
|
:disabled t
|
||
|
:after (org)
|
||
|
:config
|
||
|
(setopt org-noter-notes-search-path (list (concat org-directory "/roam")))
|
||
|
(org-noter-enable-org-roam-integration))
|
||
|
|
||
|
(use-package org-pomodoro
|
||
|
:after (org-clock)
|
||
|
:bind
|
||
|
(:map as/org-prefix-map
|
||
|
("m" . org-pomodoro))
|
||
|
:commands (org-pomodoro)
|
||
|
:config
|
||
|
(setopt alert-user-configuration ; Send messages to libnotify
|
||
|
'((((:category . "org-pomodoro")) libnotify nil))
|
||
|
org-pomodoro-audio-player (concat (executable-find "pw-cat") " -p")
|
||
|
org-pomodoro-keep-killed-pomodoro-time t
|
||
|
org-pomodoro-length 50
|
||
|
org-pomodoro-long-break-frequency 2
|
||
|
org-pomodoro-manual-break t
|
||
|
org-pomodoro-short-break-length 10))
|
||
|
|
||
|
(use-package org-roam
|
||
|
;; :after (org)
|
||
|
:bind
|
||
|
(:map as/org-roam-prefix-map
|
||
|
("b" . org-roam-buffer-display-dedicated)
|
||
|
("c" . org-roam-capture)
|
||
|
("f" . org-roam-node-find)
|
||
|
("i" . org-roam-node-insert))
|
||
|
:config
|
||
|
(setopt org-roam-database-connector 'sqlite-builtin
|
||
|
org-roam-directory (file-name-as-directory (expand-file-name "roam" org-directory)))
|
||
|
(setq org-roam-db-gc-threshold most-positive-fixnum) ; doesn't like the new `setopt'
|
||
|
(add-to-list 'display-buffer-alist
|
||
|
'("\\*org-roam\\*"
|
||
|
(display-buffer-in-direction)
|
||
|
(direction . right)
|
||
|
(window-width . 0.33)
|
||
|
(window-height . fit-window-to-buffer)))
|
||
|
(add-to-list 'org-roam-capture-templates
|
||
|
'("r" "reference" plain
|
||
|
"%?"
|
||
|
:target
|
||
|
(file+head "references/${citar-citekey}.org"
|
||
|
"#+title: ${note-title}\n")
|
||
|
:empty-lines 1
|
||
|
:unnarrowed t
|
||
|
))
|
||
|
(add-to-list 'org-roam-capture-templates
|
||
|
`("p" "project" plain (file ,(concat org-roam-directory
|
||
|
"/templates/projects.org"))
|
||
|
:target
|
||
|
(file+head "projects/%<%Y%m%d%H%M%S>-${slug}.org"
|
||
|
"#+title: ${title}\n#+filetags: :projects:")
|
||
|
:empty-lines 1
|
||
|
:unnarrowed t))
|
||
|
(org-roam-db-autosync-mode)
|
||
|
:ensure (org-roam :files (:defaults "extensions/*"))
|
||
|
:init
|
||
|
(bind-keys :prefix-map as/org-roam-prefix-map
|
||
|
:prefix "C-c r"))
|
||
|
|
||
|
(use-package org-super-agenda
|
||
|
:hook (org-agenda-mode . org-super-agenda-mode)
|
||
|
:init
|
||
|
(setq org-agenda-custom-commands
|
||
|
'(("u" "Super agenda"
|
||
|
|
||
|
((agenda "" ((org-agenda-prefix-format " %-12t% s%?-6e")
|
||
|
;;(org-agenda-prefix-format " %?-12t %s")
|
||
|
(org-agenda-remove-tags t)
|
||
|
(org-agenda-skip-function '(org-agenda-skip-entry-if
|
||
|
'todo '("WONT")))
|
||
|
(org-agenda-span 'day)))
|
||
|
|
||
|
(alltodo "" ((org-agenda-overriding-header "\nI'M DOING IT...")
|
||
|
(org-agenda-prefix-format " %-20T")
|
||
|
;; (org-agenda-prefix-format " %?-12t %s")
|
||
|
(org-agenda-remove-tags t)
|
||
|
(org-super-agenda-groups
|
||
|
'(
|
||
|
(:name "Done Today" ; FIXME
|
||
|
:todo "DONE"
|
||
|
:log t
|
||
|
:order 95)
|
||
|
|
||
|
(:name "Overdue"
|
||
|
:deadline past
|
||
|
:scheduled past
|
||
|
:order 1)
|
||
|
|
||
|
(:name "Waiting"
|
||
|
:todo "WAIT"
|
||
|
:order 80)
|
||
|
|
||
|
(:name "Upcoming"
|
||
|
:deadline future
|
||
|
:scheduled future
|
||
|
:order 99)
|
||
|
|
||
|
(:name "High Priority"
|
||
|
:priority "A"
|
||
|
:order 5)
|
||
|
|
||
|
(:name "Now"
|
||
|
:todo ("PROG" "NEXT")
|
||
|
:order 10)
|
||
|
|
||
|
(:name "Personal"
|
||
|
:and (:deadline today :tag "personal")
|
||
|
:and (:scheduled today :tag "personal")
|
||
|
:order 30)
|
||
|
|
||
|
(:name "Household"
|
||
|
:and (:deadline today :tag "household")
|
||
|
:and (:scheduled today :tag "household")
|
||
|
:order 35)
|
||
|
|
||
|
(:name "Today"
|
||
|
:deadline today
|
||
|
:scheduled today
|
||
|
:order 15)
|
||
|
|
||
|
(:name "Project Backlog"
|
||
|
:and (:todo "TODO" :tag "projects")
|
||
|
:order 20)
|
||
|
|
||
|
(:name "Research"
|
||
|
:tag "research"
|
||
|
:order 40)
|
||
|
|
||
|
(:name "Personal Backlog"
|
||
|
:and (:todo "TODO" :tag "personal")
|
||
|
:and (:todo "TODO" :tag "job_search")
|
||
|
:order 45)
|
||
|
|
||
|
(:name "Household Backlog"
|
||
|
:and (:todo "TODO" :priority<= "B" :tag "household")
|
||
|
:order 50)
|
||
|
|
||
|
(:name "Inbox"
|
||
|
:tag "inbox"
|
||
|
:order 90)
|
||
|
|
||
|
|
||
|
)))))
|
||
|
))))
|
||
|
|
||
|
(use-package org-superstar
|
||
|
:config
|
||
|
(if org-odd-levels-only
|
||
|
(setopt org-superstar-headline-bullets-list '(?◉ ?- ?🞛 ?- ?○ ?- ?▷ ?- ?✸ ?- ?✿ ?-))
|
||
|
(setopt org-superstar-headline-bullets-list '(?◉ ?🞛 ?○ ?▷ ?✸ ?✿)))
|
||
|
(setopt org-indent-mode-turns-on-hiding-stars nil ; needed for `org-superstar-leading-bullet'
|
||
|
org-superstar-leading-bullet ?\s
|
||
|
org-superstar-hide-leading-stars t
|
||
|
org-superstar-special-todo-items t
|
||
|
org-superstar-todo-bullet-alist '(("TODO" . ?☐)
|
||
|
("NEXT" . ?☐)
|
||
|
("PROG" . ?☐)
|
||
|
("WAIT" . ?☐)
|
||
|
("DONE" . ?☑)
|
||
|
("WONT" . ?☑)))
|
||
|
:hook (org-mode . org-superstar-mode))
|
||
|
|
||
|
(use-package org-timeblock
|
||
|
:bind
|
||
|
(:map as/org-prefix-map
|
||
|
("b" . org-timeblock))
|
||
|
:config
|
||
|
(setopt org-timeblock-new-task-time 'pick
|
||
|
org-timeblock-show-future-repeats 'next
|
||
|
org-timeblock-scale-options (cons 7 20)
|
||
|
org-timeblock-span 3))
|
||
|
|
||
|
(provide 'init-org)
|
||
|
;;; org-mode.el ends here
|