2017-12-08 22:59:42 -05:00
|
|
|
;;; lang/org/config.el -*- lexical-binding: t; -*-
|
|
|
|
|
2017-07-05 02:33:41 +02:00
|
|
|
;;
|
2019-03-07 00:15:15 -05:00
|
|
|
;;; `org-load' hooks
|
2018-01-08 20:38:46 -05:00
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-agenda-h ()
|
2018-09-30 15:14:01 -04:00
|
|
|
(unless org-agenda-files
|
|
|
|
(setq org-agenda-files (list org-directory)))
|
2017-07-05 02:33:41 +02:00
|
|
|
(setq-default
|
2019-07-22 00:36:02 +02:00
|
|
|
;; Hide blocked tasks in the agenda view.
|
|
|
|
org-agenda-dim-blocked-tasks 'invisible
|
2017-07-05 02:33:41 +02:00
|
|
|
org-agenda-inhibit-startup t
|
2018-06-10 01:32:19 +02:00
|
|
|
org-agenda-skip-unavailable-files t
|
|
|
|
;; Move the agenda to show the previous 3 days and the next 7 days for a bit
|
|
|
|
;; better context instead of just the current week which is a bit confusing
|
|
|
|
;; on, for example, a sunday
|
|
|
|
org-agenda-span 10
|
|
|
|
org-agenda-start-on-weekday nil
|
|
|
|
org-agenda-start-day "-3d"))
|
2018-01-08 20:38:46 -05:00
|
|
|
|
2019-03-07 00:15:15 -05:00
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-appearance-h ()
|
2018-01-08 20:38:46 -05:00
|
|
|
"Configures the UI for `org-mode'."
|
|
|
|
(setq-default
|
|
|
|
org-adapt-indentation nil
|
2017-07-05 02:33:41 +02:00
|
|
|
org-cycle-include-plain-lists t
|
2018-08-04 18:24:54 +02:00
|
|
|
org-eldoc-breadcrumb-separator " → "
|
2018-02-02 19:45:25 -05:00
|
|
|
org-entities-user
|
|
|
|
'(("flat" "\\flat" nil "" "" "266D" "♭")
|
|
|
|
("sharp" "\\sharp" nil "" "" "266F" "♯"))
|
2017-07-05 02:33:41 +02:00
|
|
|
org-fontify-done-headline t
|
|
|
|
org-fontify-quote-and-verse-blocks t
|
|
|
|
org-fontify-whole-heading-line t
|
|
|
|
org-footnote-auto-label 'plain
|
|
|
|
org-hidden-keywords nil
|
|
|
|
org-hide-emphasis-markers nil
|
|
|
|
org-hide-leading-stars t
|
|
|
|
org-hide-leading-stars-before-indent-mode t
|
|
|
|
org-image-actual-width nil
|
|
|
|
org-indent-indentation-per-level 2
|
|
|
|
org-indent-mode-turns-on-hiding-stars t
|
2018-03-12 13:20:09 -04:00
|
|
|
org-list-description-max-indent 4
|
2017-07-05 02:33:41 +02:00
|
|
|
org-pretty-entities nil
|
|
|
|
org-pretty-entities-include-sub-superscripts t
|
2017-10-05 17:01:10 +02:00
|
|
|
org-priority-faces
|
2018-06-27 02:53:18 +02:00
|
|
|
'((?a . error)
|
|
|
|
(?b . warning)
|
|
|
|
(?c . success))
|
2018-09-08 18:42:03 -04:00
|
|
|
org-refile-targets
|
|
|
|
'((nil :maxlevel . 3)
|
|
|
|
(org-agenda-files :maxlevel . 3))
|
2017-07-05 02:33:41 +02:00
|
|
|
org-startup-folded t
|
|
|
|
org-startup-indented t
|
|
|
|
org-startup-with-inline-images nil
|
|
|
|
org-tags-column 0
|
2017-11-09 00:35:53 +01:00
|
|
|
org-todo-keywords
|
2019-06-28 16:53:26 +02:00
|
|
|
'((sequence "TODO(t)" "PROJ(p)" "|" "DONE(d)")
|
|
|
|
(sequence "[ ](T)" "[-](P)" "[?](M)" "|" "[X](D)")
|
|
|
|
(sequence "NEXT(n)" "WAIT(w)" "HOLD(h)" "|" "ABRT(c)"))
|
2018-09-26 20:44:54 -04:00
|
|
|
org-todo-keyword-faces
|
2019-03-02 12:38:15 -05:00
|
|
|
'(("[-]" :inherit (font-lock-constant-face bold))
|
|
|
|
("[?]" :inherit (warning bold))
|
2019-06-28 16:53:26 +02:00
|
|
|
("PROJ" :inherit (bold default))
|
|
|
|
("HOLD" :inherit (warning bold))
|
|
|
|
("ABRT" :inherit (error bold)))
|
2017-07-05 02:33:41 +02:00
|
|
|
org-use-sub-superscripts '{}
|
|
|
|
|
2018-06-03 12:23:17 +02:00
|
|
|
;; Scale up LaTeX previews a bit (default is too small)
|
|
|
|
org-format-latex-options (plist-put org-format-latex-options :scale 1.5))
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(advice-add #'org-eldoc-documentation-function :around #'+org-display-link-in-eldoc-a)
|
2019-02-22 02:07:44 -05:00
|
|
|
|
2018-07-29 02:54:19 +02:00
|
|
|
;; Don't do automatic indent detection in org files
|
|
|
|
(add-to-list 'doom-detect-indentation-excluded-modes 'org-mode nil #'eq)
|
|
|
|
|
2018-06-27 02:53:18 +02:00
|
|
|
;; Previews are usually rendered with light backgrounds, so ensure their
|
|
|
|
;; background (and foreground) match the current theme.
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-update-latex-preview-background-color-h ()
|
2018-06-03 12:23:17 +02:00
|
|
|
(setq-default
|
|
|
|
org-format-latex-options
|
|
|
|
(plist-put org-format-latex-options
|
|
|
|
:background
|
|
|
|
(face-attribute (or (cadr (assq 'default face-remapping-alist))
|
|
|
|
'default)
|
|
|
|
:background nil t))))
|
2019-07-21 02:38:42 +02:00
|
|
|
(add-hook 'doom-load-theme-hook #'+org-update-latex-preview-background-color-h)
|
2019-06-28 16:53:26 +02:00
|
|
|
|
|
|
|
(set-pretty-symbols! 'org-mode
|
|
|
|
:name "#+NAME:"
|
|
|
|
:src_block "#+BEGIN_SRC"
|
|
|
|
:src_block_end "#+END_SRC"))
|
|
|
|
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-babel-h ()
|
2019-06-28 16:53:26 +02:00
|
|
|
(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
|
|
|
|
|
|
|
|
;; 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)
|
|
|
|
|
|
|
|
;; Use major-mode native TAB indentation in SRC blocks
|
2019-07-21 02:38:42 +02:00
|
|
|
(advice-add #'org-return-indent :after #'+org-fix-newline-and-indent-in-src-blocks-a)
|
2019-06-28 16:53:26 +02:00
|
|
|
|
|
|
|
;; `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))
|
|
|
|
|
2019-06-30 02:27:07 +02:00
|
|
|
;; Fixes for various babel plugins
|
|
|
|
(setq org-babel-js-function-wrapper "console.log(require('util').inspect(function(){\n%s\n}()));"))
|
2019-06-28 16:53:26 +02:00
|
|
|
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-babel-lazy-loader-h ()
|
2019-06-28 16:53:26 +02:00
|
|
|
"Load babel libraries lazily when babel blocks are executed."
|
|
|
|
(defvar +org-babel-mode-alist
|
|
|
|
'((cpp . C)
|
|
|
|
(C++ . C)
|
|
|
|
(D . C)
|
|
|
|
(sh . shell)
|
|
|
|
(bash . shell)
|
|
|
|
(matlab . octave))
|
|
|
|
"An alist mapping languages to babel libraries. This is necessary for babel
|
|
|
|
libraries (ob-*.el) that don't match the name of the language.
|
|
|
|
|
|
|
|
For example, with (fish . shell) will cause #+BEGIN_SRC fish to load ob-shell.el
|
|
|
|
when executed.")
|
|
|
|
|
|
|
|
(defvar +org-babel-load-functions ()
|
|
|
|
"A list of functions executed to load the current executing src block. They
|
|
|
|
take one argument (the language specified in the src block, as a string). Stops
|
|
|
|
at the first function to return non-nil.")
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(def-advice! +org--src-lazy-load-library-a (lang)
|
2019-07-10 19:30:56 +02:00
|
|
|
"Lazy load a babel package to ensure syntax highlighting."
|
2019-07-21 02:38:42 +02:00
|
|
|
:before #'org-src--get-lang-mode
|
2019-07-10 19:30:56 +02:00
|
|
|
(or (cdr (assoc lang org-src-lang-modes))
|
|
|
|
(fboundp (intern-soft (format "%s-mode" lang)))
|
|
|
|
(require (intern-soft (format "ob-%s" lang)) nil t)))
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(def-advice! +org--babel-lazy-load-library-a (info)
|
2019-06-28 16:53:26 +02:00
|
|
|
"Load babel libraries lazily when babel blocks are executed."
|
2019-07-21 02:38:42 +02:00
|
|
|
:after-while #'org-babel-confirm-evaluate
|
2019-06-28 16:53:26 +02:00
|
|
|
(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)))
|
2019-07-21 02:38:42 +02:00
|
|
|
t)))
|
2019-06-28 16:53:26 +02:00
|
|
|
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-capture-defaults-h ()
|
2019-06-28 16:53:26 +02:00
|
|
|
"Sets up some reasonable defaults, as well as two `org-capture' workflows that
|
|
|
|
I like:
|
|
|
|
|
|
|
|
1. The traditional way: invoking `org-capture' directly, via SPC X, or through
|
|
|
|
the :cap ex command.
|
|
|
|
2. Through a org-capture popup frame that is invoked from outside Emacs (the
|
|
|
|
~/.emacs.d/bin/org-capture script). This can be invoked from qutebrowser,
|
|
|
|
vimperator, dmenu or a global keybinding."
|
|
|
|
|
|
|
|
(defvar +org-capture-todo-file "todo.org"
|
|
|
|
"Default target for todo entries.
|
|
|
|
|
|
|
|
Is relative to `org-directory', unless it is absolute. Is used in Doom's default
|
|
|
|
`org-capture-templates'.")
|
|
|
|
|
|
|
|
(defvar +org-capture-changelog-file "changelog.org"
|
|
|
|
"Default target for changelog entries.
|
|
|
|
|
|
|
|
Is relative to `org-directory' unless it is absolute. Is used in Doom's default
|
|
|
|
`org-capture-templates'.")
|
|
|
|
|
|
|
|
(defvar +org-capture-notes-file "notes.org"
|
|
|
|
"Default target for storing notes.
|
|
|
|
|
|
|
|
Used as a fall back file for org-capture.el, for templates that do not specify a
|
|
|
|
target file.
|
|
|
|
|
|
|
|
Is relative to `org-directory', unless it is absolute. Is used in Doom's default
|
|
|
|
`org-capture-templates'.")
|
|
|
|
|
|
|
|
(setq org-default-notes-file
|
|
|
|
(expand-file-name +org-capture-notes-file org-directory)
|
|
|
|
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)
|
|
|
|
|
|
|
|
;; Will use {project-root}/{todo,notes,changelog}.org, unless a
|
|
|
|
;; {todo,notes,changelog}.org file is found in a parent directory.
|
|
|
|
;; Uses the basename from `+org-capture-todo-file',
|
|
|
|
;; `+org-capture-changelog-file' and `+org-capture-notes-file'.
|
|
|
|
("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)))
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(def-advice! +org-capture-expand-variable-file-a (file)
|
2019-06-28 16:53:26 +02:00
|
|
|
"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
|
|
|
|
relative to `org-directory', unless it is an absolute path."
|
2019-07-21 02:38:42 +02:00
|
|
|
:filter-args #'org-capture-expand-file
|
2019-06-28 16:53:26 +02:00
|
|
|
(if (and (symbolp file) (boundp file))
|
|
|
|
(expand-file-name (symbol-value file) org-directory)
|
|
|
|
file))
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(def-advice! +org--prevent-save-prompts-when-refiling-a (&rest _)
|
2019-06-28 16:53:26 +02:00
|
|
|
"Fix #462: when refiling from org-capture, Emacs prompts to kill the
|
|
|
|
underlying, modified buffer. This fixes that."
|
2019-07-21 02:38:42 +02:00
|
|
|
:after 'org-refile
|
2019-06-28 16:53:26 +02:00
|
|
|
(when (bound-and-true-p org-capture-is-refiling)
|
|
|
|
(org-save-all-org-buffers)))
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(add-hook 'org-capture-mode-hook
|
|
|
|
(defun +org-show-target-in-capture-header-h ()
|
|
|
|
(setq header-line-format
|
|
|
|
(format "%s%s%s"
|
|
|
|
(propertize (abbreviate-file-name (buffer-file-name (buffer-base-buffer)))
|
|
|
|
'face 'font-lock-string-face)
|
|
|
|
org-eldoc-breadcrumb-separator
|
|
|
|
header-line-format))))
|
2019-06-28 16:53:26 +02:00
|
|
|
|
|
|
|
(when (featurep! :editor evil)
|
|
|
|
(add-hook 'org-capture-mode-hook #'evil-insert-state)))
|
|
|
|
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-capture-frame-h ()
|
|
|
|
(add-hook 'org-capture-after-finalize-hook #'+org-capture-cleanup-frame-h)
|
2019-06-28 16:53:26 +02:00
|
|
|
|
|
|
|
(when (featurep! :ui doom-dashboard)
|
|
|
|
(add-hook '+doom-dashboard-inhibit-functions #'+org-capture-frame-p)))
|
|
|
|
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-centralized-attachments-h ()
|
2019-06-28 16:53:26 +02:00
|
|
|
"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:
|
|
|
|
|
|
|
|
+ Places attachments in a centralized location (`org-attach-directory' in
|
|
|
|
`org-directory').
|
|
|
|
+ Adds attach:* link abbreviation for quick links to these files from anywhere.
|
|
|
|
+ Use `+org-attach/sync' to index all attachments in `org-directory' that use
|
|
|
|
the attach:* abbreviation and delete orphaned ones that are no longer
|
|
|
|
referenced.
|
|
|
|
+ This compliments the +dragndrop flag which provides drag'n'drop support for
|
|
|
|
images (with preview) and media files.
|
|
|
|
|
|
|
|
Some commands of interest:
|
|
|
|
+ `org-download-screenshot'
|
|
|
|
+ `+org-attach/file'
|
|
|
|
+ `+org-attach/url'
|
|
|
|
+ `+org-attach/sync'"
|
2019-07-21 23:31:42 +02:00
|
|
|
(setq org-attach-directory (doom-dir org-directory org-attach-directory))
|
2019-06-28 16:53:26 +02:00
|
|
|
|
2019-07-18 15:10:36 +02:00
|
|
|
;; A shorter link to attachments
|
2019-07-21 23:31:42 +02:00
|
|
|
(add-to-list 'org-link-abbrev-alist
|
|
|
|
(cons "attach"
|
|
|
|
(abbreviate-file-name org-attach-directory)))
|
2019-07-18 15:10:36 +02:00
|
|
|
|
2019-06-28 16:53:26 +02:00
|
|
|
(org-link-set-parameters
|
|
|
|
"attach"
|
2019-07-21 23:31:42 +02:00
|
|
|
:follow (lambda (link) (find-file (doom-path org-attach-directory link)))
|
2019-06-28 16:53:26 +02:00
|
|
|
: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 org-attach-directory))
|
|
|
|
|
|
|
|
(after! recentf
|
|
|
|
(add-to-list 'recentf-exclude
|
|
|
|
(lambda (file) (file-in-directory-p file org-attach-directory)))))
|
|
|
|
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-centralized-exports-h ()
|
2019-06-28 16:53:26 +02:00
|
|
|
"TODO"
|
|
|
|
(defvar +org-enable-centralized-exports t
|
|
|
|
"If non-nil, files exported from files in `org-directory' will be stored in
|
|
|
|
`+org-export-directory', rather than the same directory has the input file(s).")
|
|
|
|
|
|
|
|
(defvar +org-export-directory ".export/"
|
|
|
|
"Where to store exported files relative to `org-directory'. Can be an absolute
|
|
|
|
path too.")
|
|
|
|
|
|
|
|
;; 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
|
|
|
|
;; `default-directory'. This is because all my org files are usually in one
|
|
|
|
;; place, and I want to be able to refer back to old exports if needed.
|
|
|
|
(setq +org-export-directory (expand-file-name +org-export-directory org-directory))
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(def-advice! +org--export-output-file-name-a (args)
|
2019-06-28 16:53:26 +02:00
|
|
|
"Return a centralized export location unless one is provided or the current
|
|
|
|
file isn't in `org-directory'."
|
2019-07-21 02:38:42 +02:00
|
|
|
:filter-args #'org-export-output-file-name
|
2019-06-28 16:53:26 +02:00
|
|
|
(when (and +org-enable-centralized-exports
|
|
|
|
(not (nth 2 args))
|
|
|
|
buffer-file-name
|
|
|
|
(file-in-directory-p buffer-file-name org-directory))
|
|
|
|
(cl-destructuring-bind (extension &optional subtreep _pubdir) args
|
|
|
|
(let ((dir (expand-file-name +org-export-directory org-directory)))
|
|
|
|
(unless (file-directory-p dir)
|
|
|
|
(make-directory dir t))
|
|
|
|
(setq args (list extension subtreep dir)))))
|
2019-07-21 02:38:42 +02:00
|
|
|
args))
|
2019-06-28 16:53:26 +02:00
|
|
|
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-custom-links-h ()
|
2019-06-28 16:53:26 +02:00
|
|
|
(defun +org--relpath (path root)
|
|
|
|
(if (and buffer-file-name (file-in-directory-p buffer-file-name root))
|
|
|
|
(file-relative-name path)
|
|
|
|
path))
|
|
|
|
|
|
|
|
(defun +org-def-link (key dir)
|
|
|
|
(org-link-set-parameters
|
|
|
|
key
|
|
|
|
:complete (lambda () (+org--relpath (+org-link-read-file key dir) dir))
|
|
|
|
:follow (lambda (link) (find-file (expand-file-name link dir)))
|
|
|
|
:face (lambda (link)
|
|
|
|
(if (file-exists-p (expand-file-name link dir))
|
|
|
|
'org-link
|
|
|
|
'error))))
|
2019-03-07 00:15:15 -05:00
|
|
|
|
2019-06-28 16:53:26 +02:00
|
|
|
;; Highlight broken file links
|
|
|
|
(org-link-set-parameters
|
|
|
|
"file"
|
|
|
|
:face (lambda (path)
|
|
|
|
(if (or (file-remote-p path)
|
|
|
|
(file-exists-p path))
|
|
|
|
'org-link
|
|
|
|
'error)))
|
|
|
|
|
|
|
|
;; Add custom link types
|
|
|
|
(setq org-link-abbrev-alist
|
|
|
|
'(("github" . "https://github.com/%s")
|
|
|
|
("youtube" . "https://youtube.com/watch?v=%s")
|
|
|
|
("google" . "https://google.com/search?q=")
|
|
|
|
("gimages" . "https://google.com/images?q=%s")
|
|
|
|
("gmap" . "https://maps.google.com/maps?q=%s")
|
|
|
|
("duckduckgo" . "https://duckduckgo.com/?q=%s")
|
|
|
|
("wolfram" . "https://wolframalpha.com/input/?i=%s")
|
|
|
|
("doom-repo" . "https://github.com/hlissner/doom-emacs/%s")))
|
|
|
|
|
|
|
|
(+org-def-link "org" org-directory)
|
|
|
|
(+org-def-link "doom" doom-emacs-dir)
|
|
|
|
(+org-def-link "doom-docs" doom-docs-dir)
|
|
|
|
(+org-def-link "doom-modules" doom-modules-dir)
|
|
|
|
|
|
|
|
;; Allow inline image previews of http(s)? urls or data uris
|
|
|
|
(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)
|
|
|
|
|
|
|
|
;; Add support for youtube links + previews
|
|
|
|
(def-package! org-yt))
|
|
|
|
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-export-h ()
|
2019-06-28 16:53:26 +02:00
|
|
|
(when (featurep! :lang markdown)
|
|
|
|
(add-to-list 'org-export-backends 'md))
|
|
|
|
|
|
|
|
(def-package! ox-pandoc
|
|
|
|
:when (and (featurep! +pandoc)
|
|
|
|
(executable-find "pandoc"))
|
|
|
|
:after ox
|
|
|
|
:init
|
|
|
|
(add-to-list 'org-export-backends 'pandoc)
|
|
|
|
:config
|
|
|
|
(setq org-pandoc-options
|
|
|
|
'((standalone . t)
|
|
|
|
(mathjax . t)
|
|
|
|
(variable . "revealjs-url=https://cdn.jsdelivr.net/npm/reveal.js@3/")))))
|
|
|
|
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-habit-h ()
|
2019-06-28 16:53:26 +02:00
|
|
|
"TODO"
|
|
|
|
(defvar +org-habit-graph-padding 2
|
|
|
|
"The padding added to the end of the consistency graph")
|
|
|
|
|
|
|
|
(defvar +org-habit-min-width 30
|
|
|
|
"Hides the consistency graph if the `org-habit-graph-column' is less than this value")
|
|
|
|
|
|
|
|
(defvar +org-habit-graph-window-ratio 0.3
|
|
|
|
"The ratio of the consistency graphs relative to the window width")
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(add-hook 'org-agenda-mode-hook
|
|
|
|
(defun +org-habit-resize-graph-h ()
|
|
|
|
"Right align and resize the consistency graphs based on
|
2019-06-28 16:53:26 +02:00
|
|
|
`+org-habit-graph-window-ratio'"
|
2019-07-21 02:38:42 +02:00
|
|
|
(require 'org-habit)
|
|
|
|
(let* ((total-days (float (+ org-habit-preceding-days org-habit-following-days)))
|
|
|
|
(preceding-days-ratio (/ org-habit-preceding-days total-days))
|
|
|
|
(graph-width (floor (* (window-width) +org-habit-graph-window-ratio)))
|
|
|
|
(preceding-days (floor (* graph-width preceding-days-ratio)))
|
|
|
|
(following-days (- graph-width preceding-days))
|
|
|
|
(graph-column (- (window-width) (+ preceding-days following-days)))
|
|
|
|
(graph-column-adjusted (if (> graph-column +org-habit-min-width)
|
|
|
|
(- graph-column +org-habit-graph-padding)
|
|
|
|
nil)))
|
|
|
|
(setq-local org-habit-preceding-days preceding-days)
|
|
|
|
(setq-local org-habit-following-days following-days)
|
|
|
|
(setq-local org-habit-graph-column graph-column-adjusted)))))
|
|
|
|
|
|
|
|
|
|
|
|
(defun +org-init-hacks-h ()
|
2019-06-28 16:53:26 +02:00
|
|
|
"Getting org to behave."
|
|
|
|
;; Don't open separate windows
|
|
|
|
(setf (alist-get 'file org-link-frame-setup) #'find-file)
|
|
|
|
;; Open directory links in Emacs
|
|
|
|
(add-to-list 'org-file-apps '(directory . emacs))
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(add-hook 'org-follow-link-hook
|
|
|
|
(defun +org-delayed-recenter-h ()
|
|
|
|
"`recenter', but after a tiny delay. Necessary to prevent certain race
|
2019-06-28 16:53:26 +02:00
|
|
|
conditions where a window's buffer hasn't changed at the time this hook is run."
|
2019-07-21 02:38:42 +02:00
|
|
|
(run-at-time 0.1 nil #'recenter)))
|
2019-06-28 16:53:26 +02:00
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(def-advice! +org--strip-properties-from-outline-a (orig-fn path &optional width prefix separator)
|
2019-06-28 16:53:26 +02:00
|
|
|
"Remove link syntax and fix variable height text (e.g. org headings) in the
|
|
|
|
eldoc string."
|
2019-07-21 02:38:42 +02:00
|
|
|
:around #'org-format-outline-path
|
2019-06-28 16:53:26 +02:00
|
|
|
(let ((result (funcall orig-fn path width prefix separator))
|
|
|
|
(separator (or separator "/")))
|
|
|
|
(string-join
|
|
|
|
(cl-loop for part
|
|
|
|
in (split-string (substring-no-properties result) separator)
|
|
|
|
for n from 0
|
|
|
|
for face = (nth (% n org-n-level-faces) org-level-faces)
|
|
|
|
collect
|
|
|
|
(org-add-props (replace-regexp-in-string org-any-link-re "\\4" part)
|
|
|
|
nil 'face `(:foreground ,(face-foreground face nil t) :weight bold)))
|
|
|
|
separator)))
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(add-hook 'org-agenda-finalize-hook
|
|
|
|
(defun +org-exclude-agenda-buffers-from-workspace-h ()
|
|
|
|
"Prevent from temporarily-opened agenda buffers from being associated with
|
2019-06-28 16:53:26 +02:00
|
|
|
the current workspace."
|
2019-07-21 02:38:42 +02:00
|
|
|
(when (and org-agenda-new-buffers (bound-and-true-p persp-mode))
|
|
|
|
(let (persp-autokill-buffer-on-remove)
|
|
|
|
(persp-remove-buffer org-agenda-new-buffers
|
|
|
|
(get-current-persp)
|
|
|
|
nil)))))
|
|
|
|
|
|
|
|
(def-advice! +org--exclude-agenda-buffers-from-recentf-a (orig-fn file)
|
2019-06-28 16:53:26 +02:00
|
|
|
"Prevent temporarily opened agenda buffers from polluting recentf."
|
2019-07-21 02:38:42 +02:00
|
|
|
:around #'org-get-agenda-file-buffer
|
2019-06-28 16:53:26 +02:00
|
|
|
(let ((recentf-exclude (list (lambda (_file) t))))
|
2019-07-21 02:38:42 +02:00
|
|
|
(funcall orig-fn file))))
|
2019-06-28 16:53:26 +02:00
|
|
|
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-keybinds-h ()
|
2017-07-05 02:33:41 +02:00
|
|
|
"Sets up org-mode and evil keybindings. Tries to fix the idiosyncrasies
|
|
|
|
between the two."
|
2019-07-21 02:38:42 +02:00
|
|
|
(add-hook 'doom-escape-hook #'+org-remove-occur-highlights-h)
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2018-02-18 00:26:27 -05:00
|
|
|
;; C-a & C-e act like `doom/backward-to-bol-or-indent' and
|
|
|
|
;; `doom/forward-to-last-non-comment-or-eol', but with more org awareness.
|
|
|
|
(setq org-special-ctrl-a/e t)
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2018-07-04 13:16:11 +02:00
|
|
|
(setq org-M-RET-may-split-line nil
|
|
|
|
;; insert new headings after current subtree rather than inside it
|
|
|
|
org-insert-heading-respect-content t)
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(add-hook! 'org-tab-first-hook #'(+org-indent-maybe-h +org-yas-expand-maybe-h))
|
|
|
|
(add-hook 'doom-delete-backward-functions #'+org-delete-backward-char-and-realign-table-maybe-h)
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2019-01-22 18:51:45 -05:00
|
|
|
(map! :map org-mode-map
|
|
|
|
;; textmate-esque newline insertion
|
2019-06-28 16:53:26 +02:00
|
|
|
[C-return] #'+org/insert-item-below
|
|
|
|
[C-S-return] #'+org/insert-item-above
|
2019-01-22 18:51:45 -05:00
|
|
|
"C-c C-S-l" #'+org/remove-link
|
|
|
|
"C-c C-i" #'org-toggle-inline-images
|
|
|
|
[remap doom/backward-to-bol-or-indent] #'org-beginning-of-line
|
2019-04-04 18:47:40 -04:00
|
|
|
[remap doom/forward-to-last-non-comment-or-eol] #'org-end-of-line
|
|
|
|
|
|
|
|
:localleader
|
2019-05-12 01:46:29 -04:00
|
|
|
"'" #'org-edit-special
|
2019-04-05 04:12:56 -04:00
|
|
|
"," #'org-switchb
|
2019-04-05 04:33:26 -04:00
|
|
|
"." #'org-goto
|
|
|
|
(:when (featurep! :completion ivy)
|
|
|
|
"." #'counsel-org-goto
|
|
|
|
"/" #'counsel-org-goto-all)
|
|
|
|
(:when (featurep! :completion helm)
|
|
|
|
"." #'helm-org-in-buffer-headings
|
|
|
|
"/" #'helm-org-agenda-files-headings)
|
2019-04-04 18:47:40 -04:00
|
|
|
"d" #'org-deadline
|
|
|
|
"f" #'org-footnote-new
|
2019-05-12 01:46:29 -04:00
|
|
|
"h" #'org-toggle-heading
|
|
|
|
"i" #'org-toggle-item
|
|
|
|
"I" #'org-toggle-inline-images
|
2019-04-04 18:47:40 -04:00
|
|
|
"l" #'org-insert-link
|
|
|
|
"L" #'org-store-link
|
2019-05-13 10:40:43 +02:00
|
|
|
"q" #'org-set-tags-command
|
2019-04-04 18:47:40 -04:00
|
|
|
"r" #'org-refile
|
2019-04-05 04:12:56 -04:00
|
|
|
"s" #'org-schedule
|
2019-05-12 01:46:29 -04:00
|
|
|
"t" #'org-todo
|
|
|
|
"T" #'org-todo-list
|
2019-04-04 18:47:40 -04:00
|
|
|
(:prefix ("c" . "clock")
|
|
|
|
"c" #'org-clock-in
|
|
|
|
"C" #'org-clock-out
|
2019-04-05 04:12:56 -04:00
|
|
|
"d" #'org-clock-mark-default-task
|
|
|
|
"e" #'org-clock-modify-effort-estimate
|
|
|
|
"l" #'org-clock-in-last
|
2019-04-04 18:47:40 -04:00
|
|
|
"g" #'org-clock-goto
|
|
|
|
"G" (λ! (org-clock-goto 'select))
|
2019-04-05 04:12:56 -04:00
|
|
|
"x" #'org-clock-cancel
|
|
|
|
"=" #'org-clock-timestamps-up
|
|
|
|
"-" #'org-clock-timestamps-down)
|
2019-04-04 18:47:40 -04:00
|
|
|
(:prefix ("e" . "export")
|
|
|
|
:desc "to markdown" "m" #'org-md-export-to-markdown
|
|
|
|
:desc "to markdown & open" "M" #'org-md-export-as-markdown
|
|
|
|
:desc "to reveal.js" "r" #'org-reveal-export-to-html
|
|
|
|
:desc "to reveal.js & open" "R" #'org-reveal-export-to-html-and-browse
|
|
|
|
(:prefix ("b" . "from beamer")
|
|
|
|
:desc "to latex" "l" #'org-beamer-export-to-latex
|
|
|
|
:desc "to latex & open" "L" #'org-beamer-export-as-latex
|
|
|
|
:desc "as pdf" "p" #'org-beamer-export-to-pdf))
|
2019-04-05 04:12:56 -04:00
|
|
|
(:prefix ("g" . "goto")
|
|
|
|
"g" #'org-goto
|
|
|
|
(:when (featurep! :completion ivy)
|
|
|
|
"g" #'counsel-org-goto
|
|
|
|
"G" #'counsel-org-goto-all)
|
|
|
|
"a" #'org-agenda-goto
|
|
|
|
"A" #'org-agenda-clock-goto
|
|
|
|
"c" #'org-clock-goto
|
|
|
|
"C" (λ! (org-clock-goto 'select))
|
|
|
|
"i" #'org-id-goto
|
|
|
|
"r" #'org-refile-goto-last-stored
|
|
|
|
"x" #'org-capture-goto-last-stored)
|
|
|
|
(:prefix ("b" . "tables")
|
2019-04-04 18:47:40 -04:00
|
|
|
"a" #'org-table-align
|
|
|
|
"e" #'org-table-edit-field
|
|
|
|
"h" #'org-table-field-info
|
2019-06-28 16:53:26 +02:00
|
|
|
(:when (featurep! +gnuplot)
|
|
|
|
"p" #'org-plot/gnuplot)
|
2019-04-04 18:47:40 -04:00
|
|
|
(:prefix ("i" . "insert")
|
|
|
|
"-" #'org-table-insert-hline
|
|
|
|
"h" #'+org/table-insert-column-left
|
|
|
|
"j" #'+org/table-insert-row-below
|
2019-04-04 19:00:43 -04:00
|
|
|
"k" #'org-table-insert-row
|
2019-04-04 18:47:40 -04:00
|
|
|
"l" #'+org/table-insert-column-right)
|
|
|
|
(:prefix ("m" . "move")
|
|
|
|
"h" #'org-table-move-column-left
|
|
|
|
"j" #'org-table-move-row-down
|
|
|
|
"k" #'org-table-move-row-up
|
|
|
|
"l" #'org-table-move-column-right)
|
|
|
|
(:prefix ("f" . "formula")
|
|
|
|
"c" #'org-table-create
|
|
|
|
"r" #'org-table-recalculate
|
|
|
|
"e" #'org-table-edit-formulas
|
2019-05-10 08:16:09 +02:00
|
|
|
"=" #'org-table-eval-formulas)))
|
|
|
|
|
2019-07-21 23:31:42 +02:00
|
|
|
;; HACK Fixes #1483: this messy hack fixes `org-agenda' or `evil-org-agenda'
|
|
|
|
;; overriding SPC, breaking the localleader
|
2019-06-28 16:53:26 +02:00
|
|
|
(define-minor-mode org-agenda-localleader-mode "TODO"
|
|
|
|
:keymap (make-sparse-keymap))
|
|
|
|
(add-hook 'org-agenda-mode-hook #'org-agenda-localleader-mode)
|
|
|
|
|
|
|
|
(map! :map org-agenda-localleader-mode-map
|
2019-05-10 08:16:09 +02:00
|
|
|
:localleader
|
|
|
|
"d" #'org-agenda-deadline
|
2019-05-10 15:03:29 +02:00
|
|
|
"q" #'org-agenda-set-tags
|
2019-05-10 08:16:09 +02:00
|
|
|
"r" #'org-agenda-refile
|
|
|
|
"s" #'org-agenda-schedule
|
|
|
|
"t" #'org-agenda-todo))
|
2019-03-07 00:15:15 -05:00
|
|
|
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-keybinds-for-evil-h (&rest args)
|
2019-06-28 16:53:26 +02:00
|
|
|
"TODO"
|
|
|
|
(when (featurep! :editor evil +everywhere)
|
|
|
|
(def-package! evil-org
|
|
|
|
:hook (org-mode . evil-org-mode)
|
|
|
|
:init
|
|
|
|
(defvar evil-org-key-theme '(navigation insert textobjects))
|
|
|
|
(defvar evil-org-retain-visual-state-on-shift t)
|
|
|
|
(defvar evil-org-special-o/O '(table-row))
|
|
|
|
(add-hook 'evil-org-mode-hook #'evil-normalize-keymaps)
|
|
|
|
:config
|
|
|
|
;; change `evil-org-key-theme' instead
|
|
|
|
(advice-add #'evil-org-set-key-theme :override #'ignore))
|
|
|
|
|
|
|
|
(def-package! evil-org-agenda
|
|
|
|
:after org-agenda
|
|
|
|
:config (evil-org-agenda-set-keys))
|
|
|
|
|
|
|
|
;; Only fold the current tree, rather than recursively
|
2019-07-21 02:38:42 +02:00
|
|
|
(add-hook 'org-tab-first-hook #'+org-cycle-only-current-subtree-h t)
|
2019-06-28 16:53:26 +02:00
|
|
|
|
|
|
|
;; Fix o/O creating new list items in the middle of nested plain lists. Only
|
|
|
|
;; has an effect when `evil-org-special-o/O' has `item' in it (not the
|
|
|
|
;; default).
|
2019-07-21 02:38:42 +02:00
|
|
|
(advice-add #'evil-org-open-below :around #'+org-evil-org-open-below-a)
|
2019-06-28 16:53:26 +02:00
|
|
|
|
|
|
|
(map! :map outline-mode-map
|
|
|
|
;; Undo keybinds from `evil-collection-outline'
|
|
|
|
:n "^" nil
|
|
|
|
:n [backtab] nil
|
|
|
|
:n "M-j" nil
|
|
|
|
:n "M-k" nil
|
|
|
|
:n "C-j" nil
|
|
|
|
:n "C-k" nil
|
|
|
|
:n "]" nil
|
|
|
|
:n "[" nil
|
|
|
|
|
|
|
|
:map evil-org-mode-map
|
|
|
|
:ni [C-return] #'+org/insert-item-below
|
|
|
|
:ni [C-S-return] #'+org/insert-item-above
|
|
|
|
;; navigate table cells (from insert-mode)
|
|
|
|
:i "C-l" (general-predicate-dispatch 'org-end-of-line
|
|
|
|
(org-at-table-p) 'org-table-next-field)
|
|
|
|
:i "C-h" (general-predicate-dispatch 'org-beginning-of-line
|
|
|
|
(org-at-table-p) 'org-table-previous-field)
|
|
|
|
:i "C-k" (general-predicate-dispatch 'org-up-element
|
|
|
|
(org-at-table-p) '+org/table-previous-row)
|
|
|
|
:i "C-j" (general-predicate-dispatch 'org-down-element
|
|
|
|
(org-at-table-p) 'org-table-next-row)
|
|
|
|
;; expanding tables (prepend/append columns/rows)
|
|
|
|
:ni "C-S-l" (general-predicate-dispatch 'org-shiftmetaright
|
|
|
|
(org-at-table-p) 'org-table-insert-column)
|
|
|
|
:ni "C-S-h" (general-predicate-dispatch 'org-shiftmetaleft
|
|
|
|
(org-at-table-p) '+org/table-insert-column-left)
|
|
|
|
:ni "C-S-k" (general-predicate-dispatch 'org-shiftmetaup
|
|
|
|
(org-at-table-p) 'org-table-insert-row)
|
|
|
|
:ni "C-S-j" (general-predicate-dispatch 'org-shiftmetadown
|
|
|
|
(org-at-table-p) '+org/table-insert-row-below)
|
|
|
|
;; shifting table rows/columns
|
|
|
|
:ni "C-M-S-l" (general-predicate-dispatch 'org-metaright
|
|
|
|
(org-at-table-p) 'org-table-move-column-right)
|
|
|
|
:ni "C-M-S-h" (general-predicate-dispatch 'org-metaleft
|
|
|
|
(org-at-table-p) 'org-table-move-column-left)
|
|
|
|
:ni "C-M-S-k" (general-predicate-dispatch 'org-metaup
|
|
|
|
(org-at-table-p) 'org-table-move-row-up)
|
|
|
|
:ni "C-M-S-j" (general-predicate-dispatch 'org-metadown
|
|
|
|
(org-at-table-p) 'org-table-move-row-down)
|
|
|
|
;; more intuitive RET keybinds
|
|
|
|
:i [return] #'org-return-indent
|
|
|
|
:i "RET" #'org-return-indent
|
|
|
|
:n [return] #'+org/dwim-at-point
|
|
|
|
:n "RET" #'+org/dwim-at-point
|
|
|
|
;; more vim-esque org motion keys (not covered by evil-org-mode)
|
|
|
|
:m "]]" (λ! (org-forward-heading-same-level nil) (org-beginning-of-line))
|
|
|
|
:m "[[" (λ! (org-backward-heading-same-level nil) (org-beginning-of-line))
|
|
|
|
:m "]h" #'org-next-visible-heading
|
|
|
|
:m "[h" #'org-previous-visible-heading
|
|
|
|
:m "]l" #'org-next-link
|
|
|
|
:m "[l" #'org-previous-link
|
|
|
|
:m "]c" #'org-babel-next-src-block
|
|
|
|
:m "[c" #'org-babel-previous-src-block
|
|
|
|
:m "^" #'evil-org-beginning-of-line
|
|
|
|
:m "0" (λ! (let (visual-line-mode) (org-beginning-of-line)))
|
|
|
|
:n "gQ" #'org-fill-paragraph
|
|
|
|
;; sensible vim-esque folding keybinds
|
|
|
|
:n "za" #'+org/toggle-fold
|
|
|
|
:n "zA" #'org-shifttab
|
|
|
|
:n "zc" #'+org/close-fold
|
|
|
|
:n "zC" #'outline-hide-subtree
|
|
|
|
:n "zm" #'+org/hide-next-fold-level
|
|
|
|
:n "zn" #'org-narrow-to-subtree
|
|
|
|
:n "zN" #'org-tree-to-indirect-buffer
|
|
|
|
:n "zo" #'+org/open-fold
|
|
|
|
:n "zO" #'outline-show-subtree
|
|
|
|
:n "zr" #'+org/show-next-fold-level
|
|
|
|
:n "zR" #'outline-show-all
|
|
|
|
:n "zi" #'org-toggle-inline-images
|
|
|
|
|
|
|
|
:map org-read-date-minibuffer-local-map
|
|
|
|
"C-h" (λ! (org-eval-in-calendar '(calendar-backward-day 1)))
|
|
|
|
"C-l" (λ! (org-eval-in-calendar '(calendar-forward-day 1)))
|
|
|
|
"C-k" (λ! (org-eval-in-calendar '(calendar-backward-week 1)))
|
|
|
|
"C-j" (λ! (org-eval-in-calendar '(calendar-forward-week 1)))
|
|
|
|
"C-S-h" (λ! (org-eval-in-calendar '(calendar-backward-month 1)))
|
|
|
|
"C-S-l" (λ! (org-eval-in-calendar '(calendar-forward-month 1)))
|
|
|
|
"C-S-k" (λ! (org-eval-in-calendar '(calendar-backward-year 1)))
|
|
|
|
"C-S-j" (λ! (org-eval-in-calendar '(calendar-forward-year 1))))))
|
|
|
|
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-popup-rules-h ()
|
2019-06-28 16:53:26 +02:00
|
|
|
(set-popup-rules!
|
|
|
|
'(("^\\*Org Links" :slot -1 :vslot -1 :size 2 :ttl 0)
|
|
|
|
("^\\*\\(?:Agenda Com\\|Calendar\\|Org \\(?:Export Dispatcher\\|Select\\)\\)"
|
|
|
|
:slot -1 :vslot -1 :size #'+popup-shrink-to-fit :ttl 0)
|
|
|
|
("^\\*Org Agenda" :size 0.35 :select 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))))
|
|
|
|
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-protocol-lazy-loader-h ()
|
2019-06-28 16:53:26 +02:00
|
|
|
"Brings lazy-loaded support for org-protocol, so external programs (like
|
|
|
|
browsers) can invoke specialized behavior from Emacs. Normally you'd simply
|
|
|
|
require `org-protocol' and use it, but the package loads all of org for no
|
|
|
|
compelling reason, so..."
|
2019-07-21 02:38:42 +02:00
|
|
|
(def-advice! +org--server-visit-files-a (args)
|
2019-06-28 16:53:26 +02:00
|
|
|
"Advise `server-visit-flist' to invoke `org-protocol' lazily."
|
2019-07-21 02:38:42 +02:00
|
|
|
:filter-args #'server-visit-files
|
2019-06-28 16:53:26 +02:00
|
|
|
(cl-destructuring-bind (files proc &optional nowait) args
|
|
|
|
(catch 'greedy
|
|
|
|
(let ((flist (reverse files)))
|
|
|
|
(dolist (var flist)
|
|
|
|
(when (string-match-p ":/+" (car var))
|
|
|
|
(require 'server)
|
|
|
|
(require 'org-protocol)
|
|
|
|
;; `\' to `/' on windows
|
|
|
|
(let ((fname (org-protocol-check-filename-for-protocol
|
|
|
|
(expand-file-name (car var))
|
|
|
|
(member var flist)
|
|
|
|
proc)))
|
|
|
|
(cond ((eq fname t) ; greedy? We need the t return value.
|
|
|
|
(setq files nil)
|
|
|
|
(throw 'greedy t))
|
|
|
|
((stringp fname) ; probably filename
|
|
|
|
(setcar var fname))
|
|
|
|
((setq files (delq var files)))))))))
|
|
|
|
(list files proc nowait)))
|
|
|
|
|
|
|
|
;; Disable built-in, clumsy advice
|
|
|
|
(after! org-protocol
|
|
|
|
(ad-disable-advice 'server-visit-files 'before 'org-protocol-detect-protocol-server)))
|
|
|
|
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-protocol-h ()
|
2019-06-28 16:53:26 +02:00
|
|
|
;; TODO org-board or better link grabbing support
|
|
|
|
;; TODO org-capture + org-protocol instead of bin/org-capture
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
(defun +org-init-smartparens-h ()
|
2019-06-28 16:53:26 +02:00
|
|
|
"TODO"
|
|
|
|
(after! smartparens
|
|
|
|
(defun +org-sp-point-in-checkbox-p (_id action _context)
|
|
|
|
(and (eq action 'insert)
|
|
|
|
(sp--looking-at-p "\\s-*]")))
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2019-06-28 16:53:26 +02:00
|
|
|
(defun +org-sp-point-at-bol-p (_id action _context)
|
|
|
|
(and (eq action 'insert)
|
|
|
|
(eq (char-before) ?*)
|
|
|
|
(sp--looking-back-p "^\\**" (line-beginning-position))))
|
2018-05-11 20:16:19 +02:00
|
|
|
|
2019-06-28 16:53:26 +02:00
|
|
|
;; make delimiter auto-closing a little more conservative
|
|
|
|
(sp-with-modes 'org-mode
|
|
|
|
(sp-local-pair "*" "*" :unless '(:add sp-point-before-word-p sp-in-math-p +org-sp-point-at-bol-p))
|
|
|
|
(sp-local-pair "_" "_" :unless '(:add sp-point-before-word-p sp-in-math-p))
|
|
|
|
(sp-local-pair "/" "/" :unless '(:add sp-point-before-word-p sp-in-math-p +org-sp-point-in-checkbox-p))
|
|
|
|
(sp-local-pair "~" "~" :unless '(:add sp-point-before-word-p))
|
|
|
|
(sp-local-pair "=" "=" :unless '(:add sp-point-before-word-p sp-in-math-p)))))
|
2018-05-14 20:49:43 +02:00
|
|
|
|
2018-05-18 01:43:37 +02:00
|
|
|
|
|
|
|
;;
|
2019-04-10 18:47:21 -04:00
|
|
|
;;; Bootstrap
|
|
|
|
|
|
|
|
(def-package! org
|
|
|
|
:defer-incrementally
|
2019-06-28 16:53:26 +02:00
|
|
|
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
|
|
|
|
:preface
|
|
|
|
;; Change org defaults (should be set before org loads)
|
|
|
|
(defvar org-directory "~/org/")
|
|
|
|
(defvar org-attach-directory ".attach/")
|
2019-07-08 11:58:58 +02:00
|
|
|
(defvar org-clock-persist-file (concat doom-etc-dir "org-clock-save.el"))
|
2019-06-28 16:53:26 +02:00
|
|
|
(defvar org-publish-timestamp-directory (concat doom-cache-dir "org-timestamps/"))
|
2019-07-08 11:58:58 +02:00
|
|
|
(defvar org-preview-latex-image-directory (concat doom-cache-dir "org-latex/"))
|
2019-06-28 16:53:26 +02:00
|
|
|
|
|
|
|
(defvar org-modules
|
|
|
|
'(;; org-w3m
|
|
|
|
;; org-bbdb
|
|
|
|
org-bibtex
|
|
|
|
;; org-docview
|
|
|
|
;; org-gnus
|
|
|
|
;; org-info
|
|
|
|
;; org-irc
|
|
|
|
;; org-mhe
|
|
|
|
;; org-rmail
|
|
|
|
))
|
|
|
|
|
2019-04-10 18:47:21 -04:00
|
|
|
(add-hook! 'org-mode-hook
|
|
|
|
#'(org-bullets-mode ; "prettier" bullets
|
|
|
|
org-indent-mode ; margin-based indentation
|
|
|
|
toc-org-enable ; auto-table of contents
|
2019-06-28 16:53:26 +02:00
|
|
|
auto-fill-mode ; hard line wrapping
|
2019-04-10 18:47:21 -04:00
|
|
|
;; `show-paren-mode' causes flickering with indentation margins made by
|
2019-05-16 15:57:08 -04:00
|
|
|
;; `org-indent-mode', so we turn off show-paren-mode altogether
|
2019-07-18 15:27:20 +02:00
|
|
|
doom-disable-show-paren-mode-h
|
2019-05-16 15:57:08 -04:00
|
|
|
;; Shows a lot of false positives, so...
|
2019-07-18 15:27:20 +02:00
|
|
|
doom-disable-show-trailing-whitespace-h
|
2019-04-10 18:47:21 -04:00
|
|
|
|
2019-07-21 02:38:42 +02:00
|
|
|
+org-enable-auto-reformat-tables-h
|
|
|
|
+org-enable-auto-update-cookies-h
|
|
|
|
+org-unfold-to-2nd-level-or-point-h))
|
2019-04-10 18:47:21 -04:00
|
|
|
|
2019-06-28 16:53:26 +02:00
|
|
|
(add-hook! 'org-load-hook
|
2019-07-21 02:38:42 +02:00
|
|
|
#'(+org-init-appearance-h
|
|
|
|
+org-init-agenda-h
|
|
|
|
+org-init-babel-h
|
|
|
|
+org-init-babel-lazy-loader-h
|
|
|
|
+org-init-capture-defaults-h
|
|
|
|
+org-init-capture-frame-h
|
|
|
|
+org-init-centralized-attachments-h
|
|
|
|
+org-init-centralized-exports-h
|
|
|
|
+org-init-custom-links-h
|
|
|
|
+org-init-export-h
|
|
|
|
+org-init-habit-h
|
|
|
|
+org-init-hacks-h
|
|
|
|
+org-init-keybinds-h
|
|
|
|
+org-init-keybinds-for-evil-h ; will noop without :editor evil
|
|
|
|
+org-init-popup-rules-h
|
|
|
|
+org-init-protocol-h
|
|
|
|
+org-init-protocol-lazy-loader-h
|
|
|
|
+org-init-smartparens-h))
|
2019-06-28 16:53:26 +02:00
|
|
|
|
|
|
|
;; In case the user has eagerly loaded org from their configs
|
|
|
|
(when (featurep 'org)
|
|
|
|
(message "`org' was already loaded by the time lang/org loaded, this may cause issues")
|
|
|
|
(run-hooks 'org-load-hook))
|
2019-04-10 18:47:21 -04:00
|
|
|
|
2019-06-28 16:53:26 +02:00
|
|
|
;;; Custom org modules
|
|
|
|
(if (featurep! +dragndrop) (load! "contrib/dragndrop"))
|
2019-07-08 22:07:52 +02:00
|
|
|
(if (featurep! +ipython) (load! "contrib/ipython"))
|
2019-06-28 16:53:26 +02:00
|
|
|
(if (featurep! +present) (load! "contrib/present"))
|
|
|
|
|
2019-07-08 22:07:52 +02:00
|
|
|
:config
|
:boom: revise advice naming convention (1/2)
This is first of three big naming convention updates that have been a
long time coming. With 2.1 on the horizon, all the breaking updates will
batched together in preparation for the long haul.
In this commit, we do away with the asterix to communicate that a
function is an advice function, and we replace it with the '-a' suffix.
e.g.
doom*shut-up -> doom-shut-up-a
doom*recenter -> doom-recenter-a
+evil*static-reindent -> +evil--static-reindent-a
The rationale behind this change is:
1. Elisp's own formatting/indenting tools would occasionally struggle
with | and * (particularly pp and cl-prettyprint). They have no
problem with / and :, fortunately.
2. External syntax highlighters (like pygmentize, discord markdown or
github markdown) struggle with it, sometimes refusing to highlight
code beyond these symbols.
3. * and | are less expressive than - and -- in communicating the
intended visibility, versatility and stability of a function.
4. It complicated the regexps we must use to search for them.
5. They were arbitrary and over-complicated to begin with, decided
on haphazardly way back when Doom was simply "my private config".
Anyhow, like how predicate functions have the -p suffix, we'll adopt the
-a suffix for advice functions, -h for hook functions and -fn for
variable functions.
Other noteable changes:
- Replaces advice-{add,remove}! macro with new def-advice!
macro. The old pair weren't as useful. The new def-advice! saves on a
lot of space.
- Removed "stage" assertions to make sure you were using the right
macros in the right place. Turned out to not be necessary, we'll
employ better checks later.
2019-07-18 15:42:52 +02:00
|
|
|
(add-hook 'org-open-at-point-functions #'doom-set-jump-h)
|
2019-07-08 22:07:52 +02:00
|
|
|
|
2019-06-28 16:53:26 +02:00
|
|
|
;;; Packages
|
|
|
|
(after! toc-org
|
|
|
|
(setq toc-org-hrefify-default "gh")
|
2019-07-21 02:38:42 +02:00
|
|
|
(def-advice! +org-unfold-toc-a (&rest _)
|
|
|
|
:before #'toc-org-insert-toc
|
2019-06-28 16:53:26 +02:00
|
|
|
(save-excursion
|
|
|
|
(when (re-search-forward toc-org-toc-org-regexp (point-max) t)
|
2019-07-21 02:38:42 +02:00
|
|
|
(+org/open-fold)))))
|
2019-06-28 16:53:26 +02:00
|
|
|
|
|
|
|
(def-package! org-pdfview
|
|
|
|
:when (featurep! :tools pdf)
|
|
|
|
:commands (org-pdfview-open)
|
|
|
|
:init
|
|
|
|
(delete '("\\.pdf\\'" . default) org-file-apps)
|
|
|
|
;; 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))))
|
|
|
|
;; support for links to specific pages
|
|
|
|
(add-to-list 'org-file-apps '("\\.pdf::\\([[:digit:]]+\\)\\'" . (lambda (_file link) (org-pdfview-open link)))))
|
|
|
|
|
|
|
|
(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))
|
2019-07-08 11:58:58 +02:00
|
|
|
(add-to-list 'org-tags-exclude-from-inheritance "crypt")
|
|
|
|
(setq org-crypt-key user-mail-address))
|
2019-06-28 16:53:26 +02:00
|
|
|
|
|
|
|
(def-package! org-clock ; built-in
|
|
|
|
:commands org-clock-save
|
2019-07-21 02:38:42 +02:00
|
|
|
:init
|
|
|
|
(setq org-clock-persist t)
|
|
|
|
(def-advice! +org-clock-load-a (&rest _)
|
|
|
|
:before '(org-clock-in
|
|
|
|
org-clock-out
|
|
|
|
org-clock-in-last
|
|
|
|
org-clock-goto
|
|
|
|
org-clock-cancel)
|
|
|
|
(org-clock-load))
|
|
|
|
:config
|
|
|
|
(add-hook 'kill-emacs-hook #'org-clock-save)))
|
2019-07-21 15:39:45 +02:00
|
|
|
|
|
|
|
|
|
|
|
;; HACK A necessary hack because org requires a compilation step after being
|
|
|
|
;; cloned, and during that compilation a org-version.el is generated with these
|
|
|
|
;; two functions, which return the output of a 'git describe ...' call in the
|
|
|
|
;; repo's root. Of course, this command won't work in a sparse clone, and more
|
|
|
|
;; than that, initiating these compilation step is a hassle, so...
|
|
|
|
(defun org-release () "")
|
|
|
|
(defun org-git-version () "")
|