aboutsummaryrefslogtreecommitdiffstats
path: root/elpa/doom-themes-20220504.1557/doom-themes-ext-org.el
blob: 775410d1e3db2d6ab2e9f71af412203cdc8b6fab (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
;;; doom-themes-ext-org.el --- fix fontification issues in org-mode -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2017-2022 Henrik Lissner
;;
;; Author: Henrik Lissner <contact@henrik.io>
;; Maintainer: Henrik Lissner <contact@henrik.io>
;; Created: August 3, 2017
;;
;; This file is not part of GNU Emacs.
;;
;;; Commentary:
;;
;; Fixes a few fontification issues in org-mode and adds special fontification
;; for @-tags and #hashtags. Simply load this file to use it.
;;
;;   (with-eval-after-load 'org-mode
;;     (require 'doom-themes-ext-org))
;;
;; Or call `doom-themes-enable-org-config', which does nothing but load this
;; package (because it's autoloaded).
;;
;;   (with-eval-after-load 'org-mode
;;     (doom-themes-enable-org-config))
;;
;;; Code:

(defgroup doom-themes-org nil
  "Options for doom's org customizations."
  :group 'doom-themes)

(define-obsolete-variable-alias
  'doom-org-special-tags 'doom-themes-org-fontify-special-tags
  "2021-02-10")
(defcustom doom-themes-org-fontify-special-tags t
  "If non-nil, fontify #hashtags and @attags.
Uses `doom-themes-org-at-tag' and `doom-themes-org-hash-tag' faces."
  :type 'boolean
  :group 'doom-themes-org)

(defcustom doom-themes-org-fontify-exclude-types
  '(src-block
    link
    citation-reference)
  "A list of org elements not to highlight special tags in.
See `doom-themes-org-fontify-special-tags'."
  :type '(repeat symbol)
  :group 'doom-themes-org)

(defface doom-themes-org-at-tag '((t :inherit org-formula))
  "Face used to fontify @-tags in org-mode."
  :group 'doom-themes-org)

(defface doom-themes-org-hash-tag '((t :inherit org-tag))
  "Face used to fontify #hashtags in org-mode."
  :group 'doom-themes-org)


(defvar org-done-keywords)
(defvar org-font-lock-extra-keywords)
(defvar org-heading-keyword-regexp-format)
(defvar org-todo-regexp)
(defvar org-fontify-done-headline)
(defvar org-activate-links)
(declare-function org-delete-all "ext:org-macs" (elts list))
(declare-function org-element-type "ext:org-element" (element))
(declare-function org-element-context "ext:org-element" (&optional element))

;;
(defun doom-themes--org-tag-face (n)
  "Return the face to use for the currently matched tag.
N is the match index."
  (declare (pure t) (side-effect-free t))
  (let ((context (save-match-data (org-element-context))))
    (unless (memq (org-element-type context) doom-themes-org-fontify-exclude-types)
      (pcase (match-string n)
        ("#" 'doom-themes-org-hash-tag)
        ("@" 'doom-themes-org-at-tag)))))

(defun doom-themes-enable-org-fontification ()
  "Correct (and improve) org-mode's font-lock keywords.

  1. Re-set `org-todo' & `org-headline-done' faces, to make them respect
     (inherit) underlying faces.
  2. Make statistic cookies respect (inherit) underlying faces.
  3. Fontify item bullets (make them stand out)
  4. Fontify item checkboxes (and when they're marked done), like TODOs that are
     marked done.
  5. Fontify dividers/separators (5+ dashes)
  6. Fontify #hashtags and @at-tags, for personal convenience; see
     `doom-org-special-tags' to disable this."
  (let ((org-todo (format org-heading-keyword-regexp-format
                          org-todo-regexp))
        (org-done (format org-heading-keyword-regexp-format
                          (concat "\\(?:" (mapconcat #'regexp-quote org-done-keywords
                                                     "\\|")
                                  "\\)"))))
    (setq
     org-font-lock-extra-keywords
     (append (org-delete-all
              (append `(("\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]"
                         (0 (org-get-checkbox-statistics-face) t))
                        (,org-todo (2 (org-get-todo-face 2) t)))
                      (when org-fontify-done-headline
                        `((,org-done (2 'org-headline-done t))))
                      (when (memq 'date org-activate-links)
                        '((org-activate-dates (0 'org-date t)))))
              org-font-lock-extra-keywords)
             ;; respsect underlying faces!
             `((,org-todo (2 (org-get-todo-face 2) prepend)))
             (when org-fontify-done-headline
               `((,org-done (2 'org-headline-done prepend))))
             (when (memq 'date org-activate-links)
               '((org-activate-dates (0 'org-date prepend))))
             ;; Make checkbox statistic cookies respect underlying faces
             '(("\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]"
                (0 (org-get-checkbox-statistics-face) prepend))
               ;; make plain list bullets stand out
               ("^ *\\([-+]\\|\\(?:[0-9]+\\|[a-zA-Z]\\)[).]\\)[ \t]" 1 'org-list-dt append)
               ;; and separators/dividers
               ("^ *\\(-----+\\)$" 1 'org-meta-line))
             ;; I like how org-mode fontifies checked TODOs and want this to
             ;; extend to checked checkbox items:
             (when org-fontify-done-headline
               '(("^[ \t]*\\(?:[-+*]\\|[0-9]+[).]\\)[ \t]+\\(\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[\\(?:X\\|\\([0-9]+\\)/\\2\\)\\][^\n]*\n\\)"
                  1 'org-headline-done prepend)))
             ;; custom #hashtags & @at-tags for another level of organization
             (when doom-themes-org-fontify-special-tags
               '(("\\(?:\\s-\\|^\\)\\(\\([#@]\\)[A-Za-z0-9_.-]+\\)"
                  1 (doom-themes--org-tag-face 2) prepend)))))))

(add-hook 'org-font-lock-set-keywords-hook #'doom-themes-enable-org-fontification)

;;;###autoload
(defun doom-themes-org-config ()
  "Load `doom-themes-ext-org'.")

(provide 'doom-themes-ext-org)
;;; doom-themes-ext-org.el ends here