summary refs log tree commit diff stats
path: root/lisp/+init.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/+init.el')
-rw-r--r--lisp/+init.el92
1 files changed, 92 insertions, 0 deletions
diff --git a/lisp/+init.el b/lisp/+init.el new file mode 100644 index 0000000..3ab0486 --- /dev/null +++ b/lisp/+init.el
@@ -0,0 +1,92 @@
1;;; +init.el --- extra init.el stuff -*- lexical-binding: t -*-
2
3;;; Commentary:
4
5;; Yes, I edit my init.el often enough I need to write a mode for it.
6
7;;; Code:
8
9(require '+lisp)
10
11;;; Sort `setup' forms
12
13(defun +init--sexp-setup-p (sexp-str &optional head)
14 "Is SEXP-STR a `setup' form, optionally with a HEAD form?"
15 (let ((head (if (and head (symbolp head))
16 (symbol-name head)
17 head)))
18 (and (string-match-p (rx (: bos (* whitespace) "(setup")) sexp-str)
19 (if head
20 (string-match-p (concat "\\`.*" head) sexp-str)
21 t))))
22
23(defun +init-sort ()
24 "Sort init.el.
25Sort based on the following heuristic: `setup' forms (the
26majority of my init.el) are sorted after everything else, and
27within that group, forms with a HEAD of `:require' are sorted
28first, and `:straight' HEADs are sorted last. All other forms
29are sorted lexigraphically."
30 (interactive)
31 (save-excursion
32 (save-restriction
33 (widen)
34 (+lisp-sort-sexps
35 (point-min) (point-max)
36 ;; Key function
37 nil
38 ;; Sort function
39 (lambda (s1 s2)
40 (let ((s1 (cdr s1)) (s2 (cdr s2)))
41 (cond
42 ;; Sort everything /not/ `setup' /before/ `setup'
43 ((and (+init--sexp-setup-p s1)
44 (not (+init--sexp-setup-p s2)))
45 nil)
46 ((and (+init--sexp-setup-p s2)
47 (not (+init--sexp-setup-p s1)))
48 t)
49 ;; otherwise...
50 (t (let ((s1-straight (+init--sexp-setup-p s1 :straight))
51 (s2-straight (+init--sexp-setup-p s2 :straight))
52 (s1-require (+init--sexp-setup-p s1 :require))
53 (s2-require (+init--sexp-setup-p s2 :require)))
54 (cond
55 ;; `:straight' setups have extra processing
56 ((and s1-straight s2-straight)
57 (let* ((r (rx (: ":straight" (? "-when") (* space) (? "("))))
58 (s1 (replace-regexp-in-string r "" s1))
59 (s2 (replace-regexp-in-string r "" s2)))
60 (string< s1 s2)))
61 ;; `:require' setups go first
62 ((and s1-require (not s2-require)) t)
63 ((and s2-require (not s1-require)) nil)
64 ;; `:straight' setups go last
65 ((and s1-straight (not s2-straight)) nil)
66 ((and s2-straight (not s1-straight)) t)
67 ;; otherwise, sort lexigraphically
68 (t (string< s1 s2))))))))))))
69
70;;; Add `setup' forms to `imenu-generic-expression'
71
72(defun +init-add-setup-to-imenu ()
73 "Recognize `setup' forms in `imenu'."
74 ;; `imenu-generic-expression' automatically becomes buffer-local when set
75 (setf (alist-get "Setup" imenu-generic-expression nil nil 'string-equal)
76 (list
77 (rx (: bol (* space)
78 "(setup" (+ space)
79 (group (? "(") (* nonl))))
80 1)))
81
82;;; Major mode
83
84;;;###autoload
85(define-derived-mode +init-mode emacs-lisp-mode "Init.el"
86 "`emacs-lisp-mode', but with a few specialized bits and bobs for init.el.")
87
88;;;###autoload
89(add-to-list 'auto-mode-alist '("/init\\.el\\'" . +init-mode))
90
91(provide '+init)
92;;; +init.el ends here