Refactor lang/org
This commit is contained in:
parent
c0c4b897ea
commit
fa26dc1269
7 changed files with 253 additions and 271 deletions
|
@ -1,7 +1,5 @@
|
||||||
;;; lang/org/+attach.el -*- lexical-binding: t; -*-
|
;;; lang/org/+attach.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
(add-hook 'org-load-hook #'+org|init-attach)
|
|
||||||
|
|
||||||
;; I believe Org's native attachment system is over-complicated and litters
|
;; I believe Org's native attachment system is over-complicated and litters
|
||||||
;; files with metadata I don't want. So I wrote my own, which:
|
;; files with metadata I don't want. So I wrote my own, which:
|
||||||
;;
|
;;
|
||||||
|
@ -25,7 +23,37 @@
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Packages
|
;;; Bootstrap
|
||||||
|
|
||||||
|
(setq org-attach-directory (expand-file-name +org-attach-dir org-directory)
|
||||||
|
org-download-image-dir org-attach-directory
|
||||||
|
org-download-heading-lvl nil
|
||||||
|
org-download-timestamp "_%Y%m%d_%H%M%S")
|
||||||
|
|
||||||
|
;; A shorter link to attachments
|
||||||
|
(add-to-list 'org-link-abbrev-alist (cons "attach" (abbreviate-file-name org-attach-directory)))
|
||||||
|
|
||||||
|
(org-link-set-parameters
|
||||||
|
"attach"
|
||||||
|
:follow (lambda (link) (find-file (expand-file-name link org-attach-directory)))
|
||||||
|
:complete (lambda (&optional _arg)
|
||||||
|
(+org--relpath (+org-link-read-file "attach" org-attach-directory)
|
||||||
|
org-attach-directory))
|
||||||
|
:face (lambda (link)
|
||||||
|
(if (file-exists-p (expand-file-name link org-attach-directory))
|
||||||
|
'org-link
|
||||||
|
'error)))
|
||||||
|
|
||||||
|
(after! projectile
|
||||||
|
(add-to-list 'projectile-globally-ignored-directories
|
||||||
|
(car (last (split-string +org-attach-dir "/" t)))))
|
||||||
|
|
||||||
|
(after! recentf
|
||||||
|
(add-to-list 'recentf-exclude (format "%s.+$" (regexp-quote org-attach-directory))))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Packages
|
||||||
|
|
||||||
(def-package! org-download
|
(def-package! org-download
|
||||||
:commands (org-download-dnd org-download-dnd-base64)
|
:commands (org-download-dnd org-download-dnd-base64)
|
||||||
|
@ -62,35 +90,3 @@
|
||||||
(advice-add #'org-download--dir-2 :override #'ignore)
|
(advice-add #'org-download--dir-2 :override #'ignore)
|
||||||
(advice-add #'org-download--fullname
|
(advice-add #'org-download--fullname
|
||||||
:filter-return #'+org-attach*download-fullname))
|
:filter-return #'+org-attach*download-fullname))
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Bootstrap
|
|
||||||
|
|
||||||
(defun +org|init-attach ()
|
|
||||||
(setq org-attach-directory (expand-file-name +org-attach-dir org-directory))
|
|
||||||
(setq-default org-download-image-dir org-attach-directory
|
|
||||||
org-download-heading-lvl nil
|
|
||||||
org-download-timestamp "_%Y%m%d_%H%M%S")
|
|
||||||
|
|
||||||
;; A shorter link to attachments
|
|
||||||
(add-to-list 'org-link-abbrev-alist (cons "attach" (abbreviate-file-name org-attach-directory)))
|
|
||||||
|
|
||||||
(org-link-set-parameters
|
|
||||||
"attach"
|
|
||||||
:follow (lambda (link) (find-file (expand-file-name link org-attach-directory)))
|
|
||||||
:complete (lambda (&optional _arg)
|
|
||||||
(+org--relpath (+org-link-read-file "attach" org-attach-directory)
|
|
||||||
org-attach-directory))
|
|
||||||
:face (lambda (link)
|
|
||||||
(if (file-exists-p (expand-file-name link org-attach-directory))
|
|
||||||
'org-link
|
|
||||||
'error)))
|
|
||||||
|
|
||||||
(after! projectile
|
|
||||||
(add-to-list 'projectile-globally-ignored-directories
|
|
||||||
(car (last (split-string +org-attach-dir "/" t)))))
|
|
||||||
|
|
||||||
(after! recentf
|
|
||||||
(add-to-list 'recentf-exclude (format "%s.+$" (regexp-quote org-attach-directory)))))
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
;;; lang/org/+babel.el -*- lexical-binding: t; -*-
|
;;; lang/org/+babel.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
(add-hook 'org-load-hook #'+org|init-babel)
|
|
||||||
|
|
||||||
(defvar +org-babel-mode-alist
|
(defvar +org-babel-mode-alist
|
||||||
'((cpp . C)
|
'((cpp . C)
|
||||||
(C++ . C)
|
(C++ . C)
|
||||||
|
@ -16,48 +14,51 @@ For example, with (fish . shell) will cause #+BEGIN_SRC fish to load ob-shell.el
|
||||||
when executed.")
|
when executed.")
|
||||||
|
|
||||||
(defvar +org-babel-load-functions ()
|
(defvar +org-babel-load-functions ()
|
||||||
"A list of functions for loading the current executing src block. They take
|
"A list of functions executed to load the current executing src block. They
|
||||||
one argument (the language specified in the src block, as a string). Stops at
|
take one argument (the language specified in the src block, as a string). Stops
|
||||||
the first function to return non-nil.")
|
at the first function to return non-nil.")
|
||||||
|
|
||||||
(defun +org|init-babel ()
|
|
||||||
(setq org-src-fontify-natively t ; make code pretty
|
|
||||||
org-src-preserve-indentation t ; use native major-mode indentation
|
|
||||||
org-src-tab-acts-natively t
|
|
||||||
org-src-window-setup 'current-window
|
|
||||||
org-confirm-babel-evaluate nil) ; you don't need my permission
|
|
||||||
|
|
||||||
(defun +org*babel-lazy-load-library (info)
|
|
||||||
"Load babel libraries as needed when babel blocks are executed."
|
|
||||||
(let* ((lang (nth 0 info))
|
|
||||||
(lang (if (symbolp lang) lang (intern lang)))
|
|
||||||
(lang (or (cdr (assq lang +org-babel-mode-alist))
|
|
||||||
lang)))
|
|
||||||
(when (and (not (cdr (assq lang org-babel-load-languages)))
|
|
||||||
(or (run-hook-with-args-until-success '+org-babel-load-functions lang)
|
|
||||||
(require (intern (format "ob-%s" lang)) nil t)))
|
|
||||||
(when (assq :async (nth 2 info))
|
|
||||||
;; ob-async has its own agenda for lazy loading packages (in the
|
|
||||||
;; child process), so we only need to make sure it's loaded.
|
|
||||||
(require 'ob-async nil t))
|
|
||||||
(add-to-list 'org-babel-load-languages (cons lang t)))
|
|
||||||
t))
|
|
||||||
(advice-add #'org-babel-confirm-evaluate :after-while #'+org*babel-lazy-load-library)
|
|
||||||
|
|
||||||
;; I prefer C-c C-c over C-c ' (more consistent)
|
|
||||||
(define-key org-src-mode-map (kbd "C-c C-c") #'org-edit-src-exit)
|
|
||||||
|
|
||||||
;; `org-babel-get-header' was removed from org in 9.0. Quite a few babel
|
|
||||||
;; plugins use it, so until those plugins update, this polyfill will do:
|
|
||||||
(defun org-babel-get-header (params key &optional others)
|
|
||||||
(cl-loop with fn = (if others #'not #'identity)
|
|
||||||
for p in params
|
|
||||||
if (funcall fn (eq (car p) key))
|
|
||||||
collect p)))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Packages
|
;;; Bootstrap
|
||||||
|
|
||||||
|
(setq org-src-fontify-natively t ; make code pretty
|
||||||
|
org-src-preserve-indentation t ; use native major-mode indentation
|
||||||
|
org-src-tab-acts-natively t
|
||||||
|
org-src-window-setup 'current-window
|
||||||
|
org-confirm-babel-evaluate nil) ; you don't need my permission
|
||||||
|
|
||||||
|
(defun +org*babel-lazy-load-library (info)
|
||||||
|
"Load babel libraries lazily when babel blocks are executed."
|
||||||
|
(let* ((lang (nth 0 info))
|
||||||
|
(lang (if (symbolp lang) lang (intern lang)))
|
||||||
|
(lang (or (cdr (assq lang +org-babel-mode-alist))
|
||||||
|
lang)))
|
||||||
|
(when (and (not (cdr (assq lang org-babel-load-languages)))
|
||||||
|
(or (run-hook-with-args-until-success '+org-babel-load-functions lang)
|
||||||
|
(require (intern (format "ob-%s" lang)) nil t)))
|
||||||
|
(when (assq :async (nth 2 info))
|
||||||
|
;; ob-async has its own agenda for lazy loading packages (in the
|
||||||
|
;; child process), so we only need to make sure it's loaded.
|
||||||
|
(require 'ob-async nil t))
|
||||||
|
(add-to-list 'org-babel-load-languages (cons lang t)))
|
||||||
|
t))
|
||||||
|
(advice-add #'org-babel-confirm-evaluate :after-while #'+org*babel-lazy-load-library)
|
||||||
|
|
||||||
|
;; I prefer C-c C-c over C-c ' (more consistent)
|
||||||
|
(define-key org-src-mode-map (kbd "C-c C-c") #'org-edit-src-exit)
|
||||||
|
|
||||||
|
;; `org-babel-get-header' was removed from org in 9.0. Quite a few babel
|
||||||
|
;; plugins use it, so until those plugins update, this polyfill will do:
|
||||||
|
(defun org-babel-get-header (params key &optional others)
|
||||||
|
(cl-loop with fn = (if others #'not #'identity)
|
||||||
|
for p in params
|
||||||
|
if (funcall fn (eq (car p) key))
|
||||||
|
collect p))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Packages
|
||||||
|
|
||||||
(def-package! ob-ipython
|
(def-package! ob-ipython
|
||||||
:when (featurep! +ipython)
|
:when (featurep! +ipython)
|
||||||
|
@ -83,7 +84,6 @@ the first function to return non-nil.")
|
||||||
("\\*Python:.*"
|
("\\*Python:.*"
|
||||||
:slot 0 :side right :size 100
|
:slot 0 :side right :size 100
|
||||||
:select nil :quit nil :transient nil)))
|
:select nil :quit nil :transient nil)))
|
||||||
;; TODO Add more popup styles
|
|
||||||
|
|
||||||
;; advices for remote kernel and org-src-edit
|
;; advices for remote kernel and org-src-edit
|
||||||
(advice-add 'org-babel-edit-prep:ipython :override #'+org*org-babel-edit-prep:ipython)
|
(advice-add 'org-babel-edit-prep:ipython :override #'+org*org-babel-edit-prep:ipython)
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
;;; lang/org/+capture.el -*- lexical-binding: t; -*-
|
;;; lang/org/+capture.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
(add-hook 'org-load-hook #'+org|init-capture)
|
|
||||||
|
|
||||||
;; Sets up some reasonable defaults, as well as two `org-capture' workflows that
|
;; Sets up some reasonable defaults, as well as two `org-capture' workflows that
|
||||||
;; I like:
|
;; I like:
|
||||||
;;
|
;;
|
||||||
|
@ -28,68 +26,62 @@ Is relative to `org-directory', unless it is absolute. Is used in Doom's default
|
||||||
|
|
||||||
It is used in Doom's default `org-capture-templates'.")
|
It is used in Doom's default `org-capture-templates'.")
|
||||||
|
|
||||||
(defvar org-capture-templates
|
|
||||||
'(("t" "Personal todo" entry
|
|
||||||
(file+headline +org-capture-todo-file "Inbox")
|
|
||||||
"* [ ] %?\n%i\n%a" :prepend t :kill-buffer t)
|
|
||||||
("n" "Personal notes" entry
|
|
||||||
(file+headline +org-capture-notes-file "Inbox")
|
|
||||||
"* %u %?\n%i\n%a" :prepend t :kill-buffer t)
|
|
||||||
|
|
||||||
;; Will use {project-root}/{todo,notes,changelog}.org, unless a
|
|
||||||
;; {todo,notes,changelog}.org file is found in a parent directory.
|
|
||||||
("p" "Templates for projects")
|
|
||||||
("pt" "Project todo" entry ; {project-root}/todo.org
|
|
||||||
(file+headline +org-capture-project-todo-file "Inbox")
|
|
||||||
"* TODO %?\n%i\n%a" :prepend t :kill-buffer t)
|
|
||||||
("pn" "Project notes" entry ; {project-root}/notes.org
|
|
||||||
(file+headline +org-capture-project-notes-file "Inbox")
|
|
||||||
"* TODO %?\n%i\n%a" :prepend t :kill-buffer t)
|
|
||||||
("pc" "Project changelog" entry ; {project-root}/changelog.org
|
|
||||||
(file+headline +org-capture-project-notes-file "Unreleased")
|
|
||||||
"* TODO %?\n%i\n%a" :prepend t :kill-buffer t)))
|
|
||||||
|
|
||||||
|
|
||||||
(defvar org-default-notes-file nil) ; defined in org.el
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
(defun +org|init-capture ()
|
;;; Bootstrap
|
||||||
(dolist (var '(+org-capture-todo-file
|
|
||||||
+org-capture-notes-file))
|
|
||||||
(set var (expand-file-name (symbol-value var) org-directory)))
|
|
||||||
(unless org-default-notes-file
|
|
||||||
(setq org-default-notes-file +org-capture-notes-file))
|
|
||||||
|
|
||||||
(add-hook 'org-capture-after-finalize-hook #'+org-capture|cleanup-frame)
|
(setq org-capture-templates
|
||||||
|
'(("t" "Personal todo" entry
|
||||||
|
(file+headline +org-capture-todo-file "Inbox")
|
||||||
|
"* TODO %?\n%i\n%a" :prepend t :kill-buffer t)
|
||||||
|
("n" "Personal notes" entry
|
||||||
|
(file+headline +org-capture-notes-file "Inbox")
|
||||||
|
"* %u %?\n%i\n%a" :prepend t :kill-buffer t)
|
||||||
|
|
||||||
(defun +org*expand-variable-paths (file)
|
;; Will use {project-root}/{todo,notes,changelog}.org, unless a
|
||||||
"If a variable is used for a file path in `org-capture-template', it is used
|
;; {todo,notes,changelog}.org file is found in a parent directory.
|
||||||
|
("p" "Templates for projects")
|
||||||
|
("pt" "Project todo" entry ; {project-root}/todo.org
|
||||||
|
(file+headline +org-capture-project-todo-file "Inbox")
|
||||||
|
"* TODO %?\n%i\n%a" :prepend t :kill-buffer t)
|
||||||
|
("pn" "Project notes" entry ; {project-root}/notes.org
|
||||||
|
(file+headline +org-capture-project-notes-file "Inbox")
|
||||||
|
"* TODO %?\n%i\n%a" :prepend t :kill-buffer t)
|
||||||
|
("pc" "Project changelog" entry ; {project-root}/changelog.org
|
||||||
|
(file+headline +org-capture-project-notes-file "Unreleased")
|
||||||
|
"* TODO %?\n%i\n%a" :prepend t :kill-buffer t)))
|
||||||
|
|
||||||
|
(defvaralias '+org-capture-notes-file 'org-default-notes-file)
|
||||||
|
|
||||||
|
(add-hook 'org-capture-after-finalize-hook #'+org-capture|cleanup-frame)
|
||||||
|
|
||||||
|
(defun +org*capture-expand-variable-file (file)
|
||||||
|
"If a variable is used for a file path in `org-capture-template', it is used
|
||||||
as is, and expanded relative to `default-directory'. This changes it to be
|
as is, and expanded relative to `default-directory'. This changes it to be
|
||||||
relative to `org-directory', unless it is an absolute path."
|
relative to `org-directory', unless it is an absolute path."
|
||||||
(if (and (symbolp file) (boundp file))
|
(if (and (symbolp file) (boundp file))
|
||||||
(expand-file-name (symbol-value file) org-directory)
|
(expand-file-name (symbol-value file) org-directory)
|
||||||
file))
|
file))
|
||||||
(advice-add #'org-capture-expand-file :filter-args #'+org*expand-variable-paths)
|
(advice-add #'org-capture-expand-file :filter-args #'+org*capture-expand-variable-file)
|
||||||
|
|
||||||
(defun +org*prevent-save-prompts-when-refiling (&rest _)
|
(defun +org*prevent-save-prompts-when-refiling (&rest _)
|
||||||
"Fix #462: when refiling from org-capture, Emacs prompts to kill the
|
"Fix #462: when refiling from org-capture, Emacs prompts to kill the
|
||||||
underlying, modified buffer. This fixes that."
|
underlying, modified buffer. This fixes that."
|
||||||
(when (bound-and-true-p org-capture-is-refiling)
|
(when (bound-and-true-p org-capture-is-refiling)
|
||||||
(org-save-all-org-buffers)))
|
(org-save-all-org-buffers)))
|
||||||
(advice-add 'org-refile :after #'+org*prevent-save-prompts-when-refiling)
|
(advice-add 'org-refile :after #'+org*prevent-save-prompts-when-refiling)
|
||||||
|
|
||||||
(defun +org|show-target-in-capture-header ()
|
(defun +org|show-target-in-capture-header ()
|
||||||
(setq header-line-format
|
(setq header-line-format
|
||||||
(format "%s%s%s"
|
(format "%s%s%s"
|
||||||
(propertize (abbreviate-file-name (buffer-file-name (buffer-base-buffer)))
|
(propertize (abbreviate-file-name (buffer-file-name (buffer-base-buffer)))
|
||||||
'face 'font-lock-string-face)
|
'face 'font-lock-string-face)
|
||||||
org-eldoc-breadcrumb-separator
|
org-eldoc-breadcrumb-separator
|
||||||
header-line-format)))
|
header-line-format)))
|
||||||
(add-hook 'org-capture-mode-hook #'+org|show-target-in-capture-header)
|
(add-hook 'org-capture-mode-hook #'+org|show-target-in-capture-header)
|
||||||
|
|
||||||
(when (featurep! :feature evil)
|
(when (featurep! :feature evil)
|
||||||
(add-hook 'org-capture-mode-hook #'evil-insert-state))
|
(add-hook 'org-capture-mode-hook #'evil-insert-state))
|
||||||
|
|
||||||
(when (featurep! :ui doom-dashboard)
|
(when (featurep! :ui doom-dashboard)
|
||||||
(add-hook '+doom-dashboard-inhibit-functions #'+org-capture-frame-p)))
|
(add-hook '+doom-dashboard-inhibit-functions #'+org-capture-frame-p))
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
;;; lang/org/+export.el -*- lexical-binding: t; -*-
|
;;; lang/org/+export.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
(add-hook 'org-load-hook #'+org|init-export)
|
|
||||||
|
|
||||||
;; I don't have any beef with org's built-in export system, but I do wish it
|
;; I don't have any beef with org's built-in export system, but I do wish it
|
||||||
;; would export to a central directory (by default), rather than
|
;; would export to a central directory (by default), rather than
|
||||||
;; `default-directory'. This is because all my org files are usually in one
|
;; `default-directory'. This is because all my org files are usually in one
|
||||||
|
@ -14,30 +12,29 @@ path too.")
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
(defun +org|init-export ()
|
(setq org-export-backends '(ascii html latex md)
|
||||||
(setq org-export-backends '(ascii html latex md)
|
org-publish-timestamp-directory (concat doom-cache-dir "org-timestamps/"))
|
||||||
org-publish-timestamp-directory (concat doom-cache-dir "org-timestamps/"))
|
|
||||||
|
|
||||||
(when (and (executable-find "pandoc")
|
(when (and (executable-find "pandoc")
|
||||||
(require 'ox-pandoc nil t))
|
(require 'ox-pandoc nil t))
|
||||||
(add-to-list 'org-export-backends 'pandoc nil #'eq)
|
(add-to-list 'org-export-backends 'pandoc nil #'eq)
|
||||||
(setq org-pandoc-options
|
(setq org-pandoc-options
|
||||||
'((standalone . t)
|
'((standalone . t)
|
||||||
(mathjax . t)
|
(mathjax . t)
|
||||||
(variable . "revealjs-url=https://cdn.jsdelivr.net/npm/reveal.js@3/"))))
|
(variable . "revealjs-url=https://cdn.jsdelivr.net/npm/reveal.js@3/"))))
|
||||||
|
|
||||||
;; Export to a central location by default or if target isn't in
|
;; Export to a central location by default or if target isn't in
|
||||||
;; `org-directory'.
|
;; `org-directory'.
|
||||||
(defun +org*export-output-file-name (args)
|
(defun +org*export-output-file-name (args)
|
||||||
"Return a centralized export location unless one is provided or the current
|
"Return a centralized export location unless one is provided or the current
|
||||||
file isn't in `org-directory'."
|
file isn't in `org-directory'."
|
||||||
(when (and (not (nth 2 args))
|
(when (and (not (nth 2 args))
|
||||||
buffer-file-name
|
buffer-file-name
|
||||||
(file-in-directory-p buffer-file-name org-directory))
|
(file-in-directory-p buffer-file-name org-directory))
|
||||||
(cl-destructuring-bind (extension &optional subtreep _pubdir) args
|
(cl-destructuring-bind (extension &optional subtreep _pubdir) args
|
||||||
(let ((dir (expand-file-name +org-export-dir org-directory)))
|
(let ((dir (expand-file-name +org-export-dir org-directory)))
|
||||||
(unless (file-directory-p dir)
|
(unless (file-directory-p dir)
|
||||||
(make-directory dir t))
|
(make-directory dir t))
|
||||||
(setq args (list extension subtreep dir)))))
|
(setq args (list extension subtreep dir)))))
|
||||||
args)
|
args)
|
||||||
(advice-add #'org-export-output-file-name :filter-args #'+org*export-output-file-name))
|
(advice-add #'org-export-output-file-name :filter-args #'+org*export-output-file-name)
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
;;; lang/org/+present.el -*- lexical-binding: t; -*-
|
;;; lang/org/+present.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
(add-hook 'org-load-hook #'+org|init-present)
|
|
||||||
|
|
||||||
(defvar +org-present-text-scale 7
|
(defvar +org-present-text-scale 7
|
||||||
"The `text-scale-amount' for `org-tree-slide-mode'.")
|
"The `text-scale-amount' for `org-tree-slide-mode'.")
|
||||||
|
|
||||||
|
@ -10,7 +8,7 @@
|
||||||
;; Packages
|
;; Packages
|
||||||
|
|
||||||
(def-package! ox-reveal
|
(def-package! ox-reveal
|
||||||
:defer t
|
:after ox
|
||||||
:init
|
:init
|
||||||
;; Fix #1127, where ox-reveal adds an errant entry to
|
;; Fix #1127, where ox-reveal adds an errant entry to
|
||||||
;; `org-structure-template-alist'
|
;; `org-structure-template-alist'
|
||||||
|
@ -34,18 +32,10 @@
|
||||||
:n [left] #'org-tree-slide-move-previous-tree)
|
:n [left] #'org-tree-slide-move-previous-tree)
|
||||||
|
|
||||||
(add-hook! 'org-tree-slide-mode-after-narrow-hook
|
(add-hook! 'org-tree-slide-mode-after-narrow-hook
|
||||||
#'(+org-present|detect-slide +org-present|add-overlays org-display-inline-images))
|
#'(+org-present|detect-slide
|
||||||
|
+org-present|add-overlays
|
||||||
|
org-display-inline-images))
|
||||||
|
|
||||||
(add-hook 'org-tree-slide-mode-hook #'+org-present|init-org-tree-window)
|
(add-hook 'org-tree-slide-mode-hook #'+org-present|init-org-tree-window)
|
||||||
(advice-add #'org-tree-slide--display-tree-with-narrow
|
(advice-add #'org-tree-slide--display-tree-with-narrow
|
||||||
:around #'+org-present*narrow-to-subtree))
|
:around #'+org-present*narrow-to-subtree))
|
||||||
|
|
||||||
|
|
||||||
(def-package! centered-window :commands centered-window-mode)
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Bootstrap
|
|
||||||
|
|
||||||
(defun +org|init-present ()
|
|
||||||
(require 'ox-reveal))
|
|
||||||
|
|
|
@ -13,3 +13,20 @@
|
||||||
(format "%s:%s"
|
(format "%s:%s"
|
||||||
key
|
key
|
||||||
(file-relative-name file dir))))
|
(file-relative-name file dir))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +org-inline-data-image (_protocol link _description)
|
||||||
|
"Interpret LINK as base64-encoded image data."
|
||||||
|
(base64-decode-string link))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +org-image-link (protocol link _description)
|
||||||
|
"Interpret LINK as base64-encoded image data."
|
||||||
|
(when (image-type-from-file-name link)
|
||||||
|
(if-let* ((buf (url-retrieve-synchronously (concat protocol ":" link))))
|
||||||
|
(with-current-buffer buf
|
||||||
|
(goto-char (point-min))
|
||||||
|
(re-search-forward "\r?\n\r?\n" nil t)
|
||||||
|
(buffer-substring-no-properties (point) (point-max)))
|
||||||
|
(message "Download of image \"%s\" failed" link)
|
||||||
|
nil)))
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
;;; lang/org/config.el -*- lexical-binding: t; -*-
|
;;; lang/org/config.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
;; FIXME deprecated
|
|
||||||
(define-obsolete-variable-alias '+org-dir 'org-directory "2.1.0")
|
|
||||||
|
|
||||||
;; Changed org defaults (should be set before org loads)
|
;; Changed org defaults (should be set before org loads)
|
||||||
(defvar org-directory "~/org/")
|
(defvar org-directory "~/org/")
|
||||||
(defvar org-modules
|
(defvar org-modules
|
||||||
|
@ -17,25 +14,58 @@
|
||||||
;; org-rmail
|
;; org-rmail
|
||||||
))
|
))
|
||||||
|
|
||||||
;; Sub-modules
|
|
||||||
(if (featurep! +attach) (load! "+attach"))
|
|
||||||
(if (featurep! +babel) (load! "+babel"))
|
|
||||||
(if (featurep! +capture) (load! "+capture"))
|
|
||||||
(if (featurep! +export) (load! "+export"))
|
|
||||||
(if (featurep! +present) (load! "+present"))
|
|
||||||
;; TODO (if (featurep! +publish) (load! "+publish"))
|
|
||||||
|
|
||||||
(doom-load-packages-incrementally
|
;;
|
||||||
'(calendar find-func format-spec org-macs org-compat
|
;;; Bootstrap
|
||||||
org-faces org-entities org-list org-pcomplete org-src
|
|
||||||
org-footnote org-macro ob org org-agenda org-capture))
|
(def-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)
|
||||||
|
:init
|
||||||
|
(add-hook! 'org-load-hook
|
||||||
|
#'(+org|setup-ui
|
||||||
|
+org|setup-popup-rules
|
||||||
|
+org|setup-agenda
|
||||||
|
+org|setup-keybinds
|
||||||
|
+org|setup-hacks
|
||||||
|
+org|setup-pretty-code
|
||||||
|
+org|setup-custom-links))
|
||||||
|
|
||||||
|
(add-hook! 'org-mode-hook
|
||||||
|
#'(org-bullets-mode ; "prettier" bullets
|
||||||
|
org-indent-mode ; margin-based indentation
|
||||||
|
toc-org-enable ; auto-table of contents
|
||||||
|
auto-fill-mode ; line wrapping
|
||||||
|
;; `show-paren-mode' causes flickering with indentation margins made by
|
||||||
|
;; `org-indent-mode', so we simply turn off show-paren-mode altogether."
|
||||||
|
doom|disable-show-paren-mode
|
||||||
|
|
||||||
|
+org|enable-auto-reformat-tables
|
||||||
|
+org|enable-auto-update-cookies
|
||||||
|
+org|smartparens-compatibility-config
|
||||||
|
+org|unfold-to-2nd-level-or-point))
|
||||||
|
|
||||||
|
:config
|
||||||
|
;; Sub-modules
|
||||||
|
(if (featurep! +attach) (load! "+attach"))
|
||||||
|
(if (featurep! +babel) (load! "+babel"))
|
||||||
|
(if (featurep! +capture) (load! "+capture"))
|
||||||
|
(if (featurep! +export) (load! "+export"))
|
||||||
|
(if (featurep! +present) (load! "+present")))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Packages
|
;;; Packages
|
||||||
|
|
||||||
;; `toc-org'
|
;; `toc-org'
|
||||||
(setq toc-org-hrefify-default "org")
|
(setq toc-org-hrefify-default "gh")
|
||||||
|
(defun +org*unfold-toc (&rest _)
|
||||||
|
(save-excursion
|
||||||
|
(when (re-search-forward toc-org-toc-org-regexp (point-max) t)
|
||||||
|
(+org/open-fold))))
|
||||||
|
(advice-add #'toc-org-insert-toc :before #'+org*unfold-toc)
|
||||||
|
|
||||||
(def-package! evil-org
|
(def-package! evil-org
|
||||||
:when (featurep! :feature evil +everywhere)
|
:when (featurep! :feature evil +everywhere)
|
||||||
|
@ -43,7 +73,7 @@
|
||||||
:init
|
:init
|
||||||
(defvar evil-org-key-theme '(navigation insert textobjects))
|
(defvar evil-org-key-theme '(navigation insert textobjects))
|
||||||
(defvar evil-org-special-o/O '(table-row))
|
(defvar evil-org-special-o/O '(table-row))
|
||||||
(add-hook 'org-load-hook #'+org|setup-evil)
|
(add-hook 'org-load-hook #'+org|setup-evil-keybinds)
|
||||||
(add-hook 'evil-org-mode-hook #'evil-normalize-keymaps)
|
(add-hook 'evil-org-mode-hook #'evil-normalize-keymaps)
|
||||||
:config
|
:config
|
||||||
;; change `evil-org-key-theme' instead
|
;; change `evil-org-key-theme' instead
|
||||||
|
@ -56,65 +86,34 @@
|
||||||
:when (featurep! :tools pdf)
|
:when (featurep! :tools pdf)
|
||||||
:commands (org-pdfview-open)
|
:commands (org-pdfview-open)
|
||||||
:init
|
:init
|
||||||
(after! org
|
(delete '("\\.pdf\\'" . default) org-file-apps)
|
||||||
(delete '("\\.pdf\\'" . default) org-file-apps)
|
;; org links to pdf files are opened in pdf-view-mode
|
||||||
;; org links to pdf files are opened in pdf-view-mode
|
(add-to-list 'org-file-apps '("\\.pdf\\'" . (lambda (_file link) (org-pdfview-open link))))
|
||||||
(add-to-list 'org-file-apps '("\\.pdf\\'" . (lambda (_file link) (org-pdfview-open link))))
|
;; support for links to specific pages
|
||||||
;; support for links to specific pages
|
(add-to-list 'org-file-apps '("\\.pdf::\\([[:digit:]]+\\)\\'" . (lambda (_file link) (org-pdfview-open link)))))
|
||||||
(add-to-list 'org-file-apps '("\\.pdf::\\([[:digit:]]+\\)\\'" . (lambda (_file link) (org-pdfview-open link))))))
|
|
||||||
|
|
||||||
(def-package! org-yt
|
(def-package! org-crypt ; built-in
|
||||||
:after org
|
:commands org-encrypt-entries
|
||||||
|
:hook (org-reveal-start . org-decrypt-entry)
|
||||||
|
:init
|
||||||
|
(add-hook! 'org-mode-hook
|
||||||
|
(add-hook 'before-save-hook 'org-encrypt-entries nil t))
|
||||||
:config
|
:config
|
||||||
(defun +org-inline-data-image (_protocol link _description)
|
(setq org-tags-exclude-from-inheritance '("crypt")
|
||||||
"Interpret LINK as base64-encoded image data."
|
org-crypt-key user-mail-address))
|
||||||
(base64-decode-string link))
|
|
||||||
|
|
||||||
(defun +org-image-link (protocol link _description)
|
(def-package! org-clock ; built-in
|
||||||
"Interpret LINK as base64-encoded image data."
|
:commands org-clock-save
|
||||||
(when (image-type-from-file-name link)
|
:hook (org-mode . org-clock-load)
|
||||||
(if-let* ((buf (url-retrieve-synchronously (concat protocol ":" link))))
|
:init
|
||||||
(with-current-buffer buf
|
(setq org-clock-persist 'history
|
||||||
(goto-char (point-min))
|
org-clock-persist-file (concat doom-etc-dir "org-clock-save.el"))
|
||||||
(re-search-forward "\r?\n\r?\n" nil t)
|
:config
|
||||||
(buffer-substring-no-properties (point) (point-max)))
|
(add-hook 'kill-emacs-hook #'org-clock-save))
|
||||||
(message "Download of image \"%s\" failed" link)
|
|
||||||
nil)))
|
|
||||||
|
|
||||||
(org-link-set-parameters "http" :image-data-fun #'+org-image-link)
|
|
||||||
(org-link-set-parameters "https" :image-data-fun #'+org-image-link)
|
|
||||||
(org-link-set-parameters "img" :image-data-fun #'+org-inline-data-image))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Bootstrap
|
;;; `org-mode' hooks
|
||||||
|
|
||||||
(add-hook! 'org-load-hook
|
|
||||||
#'(+org|setup-ui
|
|
||||||
+org|setup-popup-rules
|
|
||||||
+org|setup-agenda
|
|
||||||
+org|setup-keybinds
|
|
||||||
+org|setup-hacks
|
|
||||||
+org|setup-pretty-code
|
|
||||||
+org|setup-custom-links))
|
|
||||||
|
|
||||||
(add-hook! 'org-mode-hook
|
|
||||||
#'(org-bullets-mode ; "prettier" bullets
|
|
||||||
org-indent-mode ; margin-based indentation
|
|
||||||
toc-org-enable ; auto-table of contents
|
|
||||||
auto-fill-mode ; line wrapping
|
|
||||||
;; `show-paren-mode' causes flickering with indentation margins made by
|
|
||||||
;; `org-indent-mode', so we simply turn off show-paren-mode altogether."
|
|
||||||
doom|disable-show-paren-mode
|
|
||||||
|
|
||||||
+org|enable-auto-reformat-tables
|
|
||||||
+org|enable-auto-update-cookies
|
|
||||||
+org|smartparens-compatibility-config
|
|
||||||
+org|unfold-to-2nd-level-or-point))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; `org-mode' hooks
|
|
||||||
|
|
||||||
(defun +org|unfold-to-2nd-level-or-point ()
|
(defun +org|unfold-to-2nd-level-or-point ()
|
||||||
"My version of the 'overview' #+STARTUP option: expand first-level headings.
|
"My version of the 'overview' #+STARTUP option: expand first-level headings.
|
||||||
|
@ -163,7 +162,7 @@ unfold to point on startup."
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; `org-load' hooks
|
;;; `org-load' hooks
|
||||||
|
|
||||||
(defun +org|setup-agenda ()
|
(defun +org|setup-agenda ()
|
||||||
(unless org-agenda-files
|
(unless org-agenda-files
|
||||||
|
@ -179,6 +178,7 @@ unfold to point on startup."
|
||||||
org-agenda-start-on-weekday nil
|
org-agenda-start-on-weekday nil
|
||||||
org-agenda-start-day "-3d"))
|
org-agenda-start-day "-3d"))
|
||||||
|
|
||||||
|
|
||||||
(defun +org|setup-popup-rules ()
|
(defun +org|setup-popup-rules ()
|
||||||
"Defines popup rules for org-mode (does nothing if :ui popup is disabled)."
|
"Defines popup rules for org-mode (does nothing if :ui popup is disabled)."
|
||||||
(set-popup-rules!
|
(set-popup-rules!
|
||||||
|
@ -189,6 +189,7 @@ unfold to point on startup."
|
||||||
("^\\*Org Src" :size 0.3 :quit nil :select t :autosave t :ttl nil)
|
("^\\*Org Src" :size 0.3 :quit nil :select t :autosave t :ttl nil)
|
||||||
("^CAPTURE.*\\.org$" :size 0.2 :quit nil :select t :autosave t))))
|
("^CAPTURE.*\\.org$" :size 0.2 :quit nil :select t :autosave t))))
|
||||||
|
|
||||||
|
|
||||||
(defun +org|setup-pretty-code ()
|
(defun +org|setup-pretty-code ()
|
||||||
"Setup the default pretty symbols for"
|
"Setup the default pretty symbols for"
|
||||||
(set-pretty-symbols! 'org-mode
|
(set-pretty-symbols! 'org-mode
|
||||||
|
@ -196,6 +197,7 @@ unfold to point on startup."
|
||||||
:src_block "#+BEGIN_SRC"
|
:src_block "#+BEGIN_SRC"
|
||||||
:src_block_end "#+END_SRC"))
|
:src_block_end "#+END_SRC"))
|
||||||
|
|
||||||
|
|
||||||
(defun +org|setup-custom-links ()
|
(defun +org|setup-custom-links ()
|
||||||
"Set up custom org links."
|
"Set up custom org links."
|
||||||
(setq org-link-abbrev-alist
|
(setq org-link-abbrev-alist
|
||||||
|
@ -235,7 +237,14 @@ unfold to point on startup."
|
||||||
(+org-def-link "org" org-directory)
|
(+org-def-link "org" org-directory)
|
||||||
(+org-def-link "doom" doom-emacs-dir)
|
(+org-def-link "doom" doom-emacs-dir)
|
||||||
(+org-def-link "doom-docs" doom-docs-dir)
|
(+org-def-link "doom-docs" doom-docs-dir)
|
||||||
(+org-def-link "doom-modules" doom-modules-dir))
|
(+org-def-link "doom-modules" doom-modules-dir)
|
||||||
|
|
||||||
|
(def-package! org-yt
|
||||||
|
:config
|
||||||
|
(org-link-set-parameters "http" :image-data-fun #'+org-image-link)
|
||||||
|
(org-link-set-parameters "https" :image-data-fun #'+org-image-link)
|
||||||
|
(org-link-set-parameters "img" :image-data-fun #'+org-inline-data-image)))
|
||||||
|
|
||||||
|
|
||||||
(defun +org|setup-ui ()
|
(defun +org|setup-ui ()
|
||||||
"Configures the UI for `org-mode'."
|
"Configures the UI for `org-mode'."
|
||||||
|
@ -272,8 +281,8 @@ unfold to point on startup."
|
||||||
org-startup-with-inline-images nil
|
org-startup-with-inline-images nil
|
||||||
org-tags-column 0
|
org-tags-column 0
|
||||||
org-todo-keywords
|
org-todo-keywords
|
||||||
'((sequence "[ ](t)" "[-](p)" "[?](m)" "|" "[X](d)")
|
'((sequence "TODO(t)" "|" "DONE(d)")
|
||||||
(sequence "TODO(T)" "|" "DONE(D)")
|
(sequence "[ ](T)" "[-](p)" "[?](m)" "|" "[X](D)")
|
||||||
(sequence "NEXT(n)" "WAITING(w)" "LATER(l)" "|" "CANCELLED(c)"))
|
(sequence "NEXT(n)" "WAITING(w)" "LATER(l)" "|" "CANCELLED(c)"))
|
||||||
org-todo-keyword-faces
|
org-todo-keyword-faces
|
||||||
'(("[-]" :inherit (font-lock-constant-face bold))
|
'(("[-]" :inherit (font-lock-constant-face bold))
|
||||||
|
@ -303,6 +312,7 @@ unfold to point on startup."
|
||||||
:background nil t))))
|
:background nil t))))
|
||||||
(add-hook 'doom-load-theme-hook #'+org|update-latex-preview-background-color))
|
(add-hook 'doom-load-theme-hook #'+org|update-latex-preview-background-color))
|
||||||
|
|
||||||
|
|
||||||
(defun +org|setup-keybinds ()
|
(defun +org|setup-keybinds ()
|
||||||
"Sets up org-mode and evil keybindings. Tries to fix the idiosyncrasies
|
"Sets up org-mode and evil keybindings. Tries to fix the idiosyncrasies
|
||||||
between the two."
|
between the two."
|
||||||
|
@ -331,7 +341,8 @@ between the two."
|
||||||
[remap doom/backward-to-bol-or-indent] #'org-beginning-of-line
|
[remap doom/backward-to-bol-or-indent] #'org-beginning-of-line
|
||||||
[remap doom/forward-to-last-non-comment-or-eol] #'org-end-of-line))
|
[remap doom/forward-to-last-non-comment-or-eol] #'org-end-of-line))
|
||||||
|
|
||||||
(defun +org|setup-evil (&rest args)
|
|
||||||
|
(defun +org|setup-evil-keybinds (&rest args)
|
||||||
;; In case this hook is used in an advice on `evil-org-set-key-theme', this
|
;; In case this hook is used in an advice on `evil-org-set-key-theme', this
|
||||||
;; prevents recursive requires.
|
;; prevents recursive requires.
|
||||||
(unless args (require 'evil-org))
|
(unless args (require 'evil-org))
|
||||||
|
@ -420,6 +431,7 @@ between the two."
|
||||||
"G" (λ! (org-clock-goto 'select))
|
"G" (λ! (org-clock-goto 'select))
|
||||||
"x" #'org-clock-cancel)))
|
"x" #'org-clock-cancel)))
|
||||||
|
|
||||||
|
|
||||||
(defun +org|setup-hacks ()
|
(defun +org|setup-hacks ()
|
||||||
"Getting org to behave."
|
"Getting org to behave."
|
||||||
;; Don't open separate windows
|
;; Don't open separate windows
|
||||||
|
@ -469,29 +481,7 @@ conditions where a window's buffer hasn't changed at the time this hook is run."
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Built-in libraries
|
;;; In case org has already been loaded (or you're running `doom/reload')
|
||||||
|
|
||||||
(def-package! org-crypt ; built-in
|
|
||||||
:commands org-encrypt-entries
|
|
||||||
:hook (org-reveal-start . org-decrypt-entry)
|
|
||||||
:init
|
|
||||||
(add-hook! 'org-mode-hook
|
|
||||||
(add-hook 'before-save-hook 'org-encrypt-entries nil t))
|
|
||||||
:config
|
|
||||||
(setq org-tags-exclude-from-inheritance '("crypt")
|
|
||||||
org-crypt-key user-mail-address))
|
|
||||||
|
|
||||||
(def-package! org-clock
|
|
||||||
:commands org-clock-save
|
|
||||||
:hook (org-mode . org-clock-load)
|
|
||||||
:defer-incrementally t
|
|
||||||
:init
|
|
||||||
(setq org-clock-persist 'history
|
|
||||||
org-clock-persist-file (concat doom-etc-dir "org-clock-save.el"))
|
|
||||||
:config
|
|
||||||
(add-hook 'kill-emacs-hook #'org-clock-save))
|
|
||||||
|
|
||||||
|
|
||||||
;; In case org has already been loaded (or you're running `doom/reload')
|
|
||||||
(when (featurep 'org)
|
(when (featurep 'org)
|
||||||
(run-hooks 'org-load-hook))
|
(run-hooks 'org-load-hook))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue