From a2657993bad828af6743c68931a0e848bfcdec53 Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Sun, 21 Nov 2021 23:57:41 -0600 Subject: I DECLARE BANKRUPTCY ... 8 Didn't think to do this till pretty .. written, so here we are. --- lisp/+init.el | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 lisp/+init.el (limited to 'lisp/+init.el') 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 @@ +;;; +init.el --- extra init.el stuff -*- lexical-binding: t -*- + +;;; Commentary: + +;; Yes, I edit my init.el often enough I need to write a mode for it. + +;;; Code: + +(require '+lisp) + +;;; Sort `setup' forms + +(defun +init--sexp-setup-p (sexp-str &optional head) + "Is SEXP-STR a `setup' form, optionally with a HEAD form?" + (let ((head (if (and head (symbolp head)) + (symbol-name head) + head))) + (and (string-match-p (rx (: bos (* whitespace) "(setup")) sexp-str) + (if head + (string-match-p (concat "\\`.*" head) sexp-str) + t)))) + +(defun +init-sort () + "Sort init.el. +Sort based on the following heuristic: `setup' forms (the +majority of my init.el) are sorted after everything else, and +within that group, forms with a HEAD of `:require' are sorted +first, and `:straight' HEADs are sorted last. All other forms +are sorted lexigraphically." + (interactive) + (save-excursion + (save-restriction + (widen) + (+lisp-sort-sexps + (point-min) (point-max) + ;; Key function + nil + ;; Sort function + (lambda (s1 s2) + (let ((s1 (cdr s1)) (s2 (cdr s2))) + (cond + ;; Sort everything /not/ `setup' /before/ `setup' + ((and (+init--sexp-setup-p s1) + (not (+init--sexp-setup-p s2))) + nil) + ((and (+init--sexp-setup-p s2) + (not (+init--sexp-setup-p s1))) + t) + ;; otherwise... + (t (let ((s1-straight (+init--sexp-setup-p s1 :straight)) + (s2-straight (+init--sexp-setup-p s2 :straight)) + (s1-require (+init--sexp-setup-p s1 :require)) + (s2-require (+init--sexp-setup-p s2 :require))) + (cond + ;; `:straight' setups have extra processing + ((and s1-straight s2-straight) + (let* ((r (rx (: ":straight" (? "-when") (* space) (? "(")))) + (s1 (replace-regexp-in-string r "" s1)) + (s2 (replace-regexp-in-string r "" s2))) + (string< s1 s2))) + ;; `:require' setups go first + ((and s1-require (not s2-require)) t) + ((and s2-require (not s1-require)) nil) + ;; `:straight' setups go last + ((and s1-straight (not s2-straight)) nil) + ((and s2-straight (not s1-straight)) t) + ;; otherwise, sort lexigraphically + (t (string< s1 s2)))))))))))) + +;;; Add `setup' forms to `imenu-generic-expression' + +(defun +init-add-setup-to-imenu () + "Recognize `setup' forms in `imenu'." + ;; `imenu-generic-expression' automatically becomes buffer-local when set + (setf (alist-get "Setup" imenu-generic-expression nil nil 'string-equal) + (list + (rx (: bol (* space) + "(setup" (+ space) + (group (? "(") (* nonl)))) + 1))) + +;;; Major mode + +;;;###autoload +(define-derived-mode +init-mode emacs-lisp-mode "Init.el" + "`emacs-lisp-mode', but with a few specialized bits and bobs for init.el.") + +;;;###autoload +(add-to-list 'auto-mode-alist '("/init\\.el\\'" . +init-mode)) + +(provide '+init) +;;; +init.el ends here -- cgit 1.4.1-21-gabe81