;;; +setup.el -- my `setup' commands -*- lexical-binding: t -*- ;; Author: Case Duckworth ;; This file is NOT part of GNU Emacs. ;;; License: ;; Everyone is permitted to do whatever with this software, without ;; limitation. This software comes without any warranty whatsoever, ;; but with two pieces of advice: ;; - Don't hurt yourself. ;; - Make good choices. ;;; Commentary: ;; `setup', by Philip Kaludercic, is a wonderful package that works ;; sort of like `use-package', but to my mind it's cleaner and easier ;; to extend. These are my additions to the local macros provided by ;; the package. ;;; Code: (require 'el-patch) (require 'setup) (require 'straight) ;; I don't like the "magic" `setup' performs to ensure a symbol is a ;; function in `:global', `:bind', `:hook', `:hook-into', and others. ;; So here, I'll just make it return the symbol unmodified. (el-patch-feature setup) (with-eval-after-load 'setup (el-patch-defvar (el-patch-add setup-ensure-function-inhibit nil "Whether to inhibit `setup-ensure-function'.")) (el-patch-defun setup-ensure-function (sexp) (el-patch-concat "Attempt to return SEXP as a quoted function name." (el-patch-add "\nIf `setup-ensure-function-inhibit' is non-nil, just return SEXP.")) (el-patch-wrap 3 0 (if (and setup-ensure-function-inhibit (not (eq sexp (setup-get 'mode)))) sexp (cond ((eq (car-safe sexp) 'function) sexp) ((eq (car-safe sexp) 'quote) `#',(cadr sexp)) ((symbolp sexp) `#',sexp) (sexp)))))) (setup-define :face (lambda (face spec) `(custom-set-faces '(,face ,spec 'now "Customized by `setup'."))) :documentation "Customize FACE with SPEC using `custom-set-faces'." :repeatable t) (setup-define :load-after (lambda (&rest features) (let ((body `(require ',(setup-get 'feature)))) (dolist (feature (nreverse features)) (setq body `(with-eval-after-load ',feature ,body))) body)) :documentation "Load the current feature after FEATURES.") (setup-define :also-straight (lambda (recipe) `(setup (:straight ,recipe))) :documentation "Install RECIPE with `straight-use-package', after loading FEATURE." :repeatable t :after-loaded t) (setup-define :straight (lambda (recipe) `(unless (ignore-errors (straight-use-package ',recipe)) ,(setup-quit))) :documentation "Install RECIPE with `straight-use-package'. This macro can be used as HEAD, and will replace itself with the first RECIPE's package." :repeatable t :shorthand (lambda (sexp) (let ((recipe (cadr sexp))) (if (consp recipe) (car recipe) recipe)))) (setup-define :straight-when (lambda (recipe condition) `(unless (and ,condition (straight-use-package ',recipe)) ,(setup-quit))) :documentation "Install RECIPE with `straight-use-package' when CONDITION is met. If CONDITION is false, or if `straight-use-package' fails, stop evaluating the body. This macro can be used as HEAD, and will replace itself with the RECIPE's package." :repeatable 2 :indent 1 :shorthand (lambda (sexp) (let ((recipe (cadr sexp))) (if (consp recipe) (car recipe) recipe)))) (provide '+setup) ;;; +setup.el ends here