Files
sydnix/users/crumb/programs/emacs/modules/syd-org.el
2025-02-13 15:32:30 -07:00

182 lines
6.7 KiB
EmacsLisp
Executable File

;;; syd-org.el -*- lexical-binding: t; -*-
(require 'syd-prose)
(defun syd-org--init-hacks-h ()
;; Open file links in current window, rather than new ones
(setf (alist-get 'file org-link-frame-setup) #'find-file)
;; Open directory links in dired
(add-to-list 'org-file-apps '(directory . emacs))
(add-to-list 'org-file-apps '(remote . emacs))
(defun syd-org--restart-mode-h ()
"Restart `org-mode', but only once."
(syd-quietly (org-mode-restart))
(setq org-agenda-new-buffers
(delq (current-buffer)
org-agenda-new-buffers))
(run-hooks 'find-file-hook))
(syd-add-hook 'org-agenda-finalize-hook
(defun syd-org-exclude-agenda-buffers-from-workspace-h ()
"Don't associate temporary agenda buffers with current workspace."
(when (and org-agenda-new-buffers
(bound-and-true-p persp-mode)
(not org-agenda-sticky))
(let (persp-autokill-buffer-on-remove)
(persp-remove-buffer org-agenda-new-buffers
(get-current-persp)
nil)))))
(defun syd-org--restart-mode-before-indirect-buffer-a (&optional buffer _)
"Restart `org-mode' in buffers in which the mode has been deferred (see
`syd-org-defer-mode-in-agenda-buffers-h') before they become the base buffer for an
indirect org-cpature buffer. This ensures that the buffer is fully functional
not only when the *user* visits it, but also when org-capture interacts with it
via an indirect buffer."
(with-current-buffer (or buffer (current-buffer))
(when (memq #'syd-org--restart-mode-h on-switch-buffer-hook)
(syd-org--restart-mode-h))))
(advice-add #'org-capture-get-indirect-buffer
:before #'syd-org--restart-mode-before-indirect-buffer-a)
(defvar recentf-exclude)
(syd-defadvice syd-org--optimize-backgrounded-agenda-buffers-a (fn file)
"Disable `org-mode's startup processes for temporary agenda buffers.
Prevents recentf pollution as well. However, if the user tries to visit one of
these buffers they'll see a gimped, half-broken org buffer, so to avoid that,
install a hook to restart `org-mode' when they're switched to so they can grow
up to be fully-fledged org-mode buffers."
:around #'org-get-agenda-file-buffer
(if-let* ((buf (org-find-base-buffer-visiting file)))
buf
(let ((recentf-exclude '(always))
;; (doom-inhibit-large-file-detection t)
;; (doom-inhibit-local-var-hooks t)
(org-inhibit-startup t)
vc-handled-backends
enable-local-variables
find-file-hook)
(when-let ((buf (delay-mode-hooks (funcall fn file))))
(with-current-buffer buf
(add-hook 'on-switch-buffer-hook #'syd-org--restart-mode-h
nil 'local))
buf))))
(syd-defadvice syd-org--fix-inconsistent-uuidgen-case-a (uuid)
"Ensure uuidgen is always lowercase (consistent) regardless of system.
See https://lists.gnu.org/archive/html/emacs-orgmode/2019-07/msg00081.html."
:filter-return #'org-id-new
(if (eq org-id-method 'uuid)
(downcase uuid)
uuid)))
(defun syd-org-init-faces ()
(let ((headline `(:weight bold)))
(custom-theme-set-faces
'user
;; It is important that the `org-indent' face uses a fixed-pitch font, lest
;; e.g. multi-line bullets appear misaligned.
'(org-indent ((t (:inherit (org-hide fixed-pitch)))))
;; Must be fixed-pitch; `[ ]` and `[X]' should be the same width.
'(org-checkbox ((t (:inherit fixed-pitch))))
'(org-drawer ((t (:inherit (font-lock-comment-face fixed-pitch)))))
'(org-property-value ((t (:inherit fixed-pitch)))))))
(defun syd-org-init-keybinds ()
(general-def
:keymaps 'org-mode-map
:states '(insert emacs)
[tab] #'org-cycle
[C-M-return] #'org-insert-subheading)
(general-def
:prefix-map 'syd-org-mode-links-map
"l" #'org-insert-link)
(general-define-key
:keymaps 'org-mode-map
:states '(normal visual motion emacs insert)
:major-modes t
:prefix syd-localleader-key
:non-normal-prefix syd-alt-localleader-key
"m" `("Org-roam" . ,org-roam-mode-map)
"." #'consult-org-heading
"/" #'consult-org-agenda
"@" #'org-cite-insert
"e" #'org-export-dispatch
"f" #'org-footnote-action
"h" #'org-toggle-heading
"i" #'org-toggle-item
"I" #'org-id-get-create
"k" #'org-babel-remove-result
"l" `("Links" . ,syd-org-mode-links-map)))
(use-package org
:defer-incrementally
calendar find-func format-spec org-macs org-compat org-faces org-entities
org-list org-pcomplete org-src org-footnote org-macro ob org org-agenda
org-capture
:custom ((org-startup-folded 'content)
(org-directory "~/org"))
:preface
;; Speed up initialisation by disabling modules we don't need.
(defvar org-modules
'(;; ol-w3m
;; ol-bbdb
ol-bibtex
;; ol-docview
;; ol-gnus
;; ol-info
;; ol-irc
;; ol-mhe
;; ol-rmail
;; ol-eww
))
:config
(syd-add-hook 'org-mode-hook
#'org-indent-mode
#'syd-prose-mode)
(syd-org-init-faces)
(syd-org-init-keybinds))
(defun syd-org--init-roam-keybinds ()
)
(use-package org-roam
:hook (org-load . syd-org-init-roam-h)
:commands (org-roam-buffer-toggle-display
org-roam-dailies-find-date
org-roam-dailies-find-today
org-roam-dailies-find-tomorrow
org-roam-dailies-find-yesterday)
:init (progn (syd-org--init-roam-keybinds)
(syd-load-packages-incrementally
'(ansi-color dash f rx seq magit-section emacsql)))
:custom ((org-roam-directory org-directory)
(org-roam-db-location (file-name-concat syd-data-dir
"org-roam.db"))
;; Make org-roam buffer sticky; i.e. don't replace it when opening a
;; file with an *-other-window command.
(org-roam-buffer-window-parameters '((no-delete-other-windows . t)))
(org-roam-completion-everywhere t))
:config
(defun syd-org-init-roam-h ()
"Setup `org-roam' but don't immediately initialize its database. Instead,
initialize it when it will be actually needed."
(cl-letf (((symbol-function #'org-roam-db-sync) #'ignore))
(org-roam-db-autosync-enable)))
(syd-org--init-roam-keybinds)
(syd-defadvice syd-org-roam-try-init-db-a (&rest _)
"Try to initialize org-roam database at the last possible safe moment.
In case of failure, fail gracefully."
:before #'org-roam-db-query
(message "Initializing org-roam database...")
(advice-remove 'org-roam-db-query #'syd-org-roam-try-init-db-a)
(org-roam-db-sync)))
(provide 'syd-org)
;;; syd-org.el ends here