diff options
Diffstat (limited to 'lisp/+init.el')
-rw-r--r-- | lisp/+init.el | 92 |
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. | ||
25 | Sort based on the following heuristic: `setup' forms (the | ||
26 | majority of my init.el) are sorted after everything else, and | ||
27 | within that group, forms with a HEAD of `:require' are sorted | ||
28 | first, and `:straight' HEADs are sorted last. All other forms | ||
29 | are 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 | ||