about summary refs log tree commit diff stats
path: root/lisp/+cus-edit.el
blob: a67279cb7f546b999fb43f5c6e7b9285f4d40d3d (plain)
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
;;; +cus-edit.el -*- lexical-binding: t; -*-

;;; Commentary:

;; The naming convention for this library, called "cus-edit.el" on the
;; filesystem, is all over the damn place.  Whatever.

;;; Code:

(require 'cl-lib)
(require 'seq)

(defgroup +customize nil
  "Extra customize customizations."
  :prefix "+customize-"
  :group 'customize)

(defcustom +cus-edit-imenu-generic-expression ; thanks u/oantolin!
  `(("Faces" ,(rx (seq bol
                      (or "Show" "Hide") " "
                      (group (zero-or-more nonl))
                      " face: [sample]"))
     1)
    ("Variables" ,(rx (seq bol
                          (or "Show Value" "Hide") " "
                          (group (zero-or-more
                                  (not (any "\n:"))))))
     1))
  "Show faces and variables in `imenu' in a `customize' buffer."
  :type 'sexp                           ; This is .. over-simplified.
  )

(defcustom +custom-variable-allowlist nil
  "Variables to allow changing while loading the Custom file.")

(defcustom +custom-after-load-hook nil
  "Functions to run after loading the custom file.")

(defun +custom-load-ignoring-most-customizations (&optional
                                                     error
                                                     nomessage
                                                     nosuffix
                                                     must-suffix)
  "Load `custom-file', ignoring most customizations.
Ignore all faces, and only load variables in
`+customize-variable-allowlist'.  All the optional
variables---ERROR, NOMESSAGE, NOSUFFIX, MUST-SUFFIX---are
passed on to `load'.

NOTE: ERROR is the opposite of its value in `load' -- meaning
that this function by default does /not/ error, but will if you
pass t to it."
  (cl-letf (((symbol-function 'custom-set-faces) 'ignore)
            ((symbol-function 'custom-set-variables)
             (lambda (&rest args)
               (apply #'custom-theme-set-variables 'user
                      (seq-filter (lambda (el)
                                    (memq (car el)
                                          +custom-variable-allowlist))
                                  args)))))
    (load custom-file (not error) nomessage nosuffix must-suffix))
  (run-hooks '+custom-after-load-hook))

(defun +cus-edit-expand-widgets (&rest _)
  "Expand descriptions in `Custom-mode' buffers."
  (interactive)
  ;; "More/Hide" widgets (thanks alphapapa!)
  (widget-map-buttons (lambda (widget _)
                        (pcase (widget-get widget :off)
                          ("More" (widget-apply-action widget)))
                        nil))
  ;; "Show Value" widgets (the little triangles)
  (widget-map-buttons (lambda (widget _)
                        (pcase (widget-get widget :off)
                          ("Show Value"
                           (widget-apply-action widget)))
                        nil)))

(provide '+cus-edit)
;;; +cus-edit.el ends here