λ init - the main init file

Author: lispcat 187922791+lispcat@users.noreply.github.com

The main init file. This is automatically ran at startup after early-init.el.

% Vars

Set various vars for sane defaults.

;; run .el instead of .elc if newer
(setq load-prefer-newer t)

;; silence compiler warnings
(setq native-comp-async-report-warnings-errors nil)

% no-littering

(progn ;; no-littering

  ;; manually add
  (add-to-list 'load-path
               (file-name-concat +emacs-submodules-dir
                                 "no-littering"))

  (require 'no-littering)
  ;; variables
  (setq auto-save-default nil)          ; don't autosave all file buffers
  (setq backup-by-copying t)            ; safer backups
  (setq undo-tree-auto-save-history nil)
  ;; Dont litter project folders with backup files
  (let ((backup-dir (no-littering-expand-var-file-name "backup/")))
    (make-directory backup-dir t)
    (setq backup-directory-alist
          `(("\\`/tmp/" . nil)
            ("\\`/dev/shm/" . nil)
            ("." . ,backup-dir))))
  ;; Tidy up auto-save files
  (let ((auto-save-dir (no-littering-expand-var-file-name "auto-save/")))
    (make-directory auto-save-dir t)
    (setq auto-save-file-name-transforms
          `(("\\`/[^/]*:\\([^/]*/\\)*\\([^/]*\\)\\'"
             ,(concat (file-name-as-directory temporary-file-directory) "\\2") t)
            ("\\`/tmp\\([^/]*/\\)*\\(.*\\)\\'" "\\2")
            ("\\`/dev/shm\\([^/]*/\\)*\\(.*\\)\\'" "\\2")
            ("." ,auto-save-dir t)))))

% elpaca

;; elpaca 0.11
(progn
  (defvar elpaca-installer-version 0.11)
  (defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
  (defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
  (defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
  (defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
                                :ref nil :depth 1 :inherit ignore
                                :files (:defaults "elpaca-test.el" (:exclude "extensions"))
                                :build (:not elpaca--activate-package)))
  (let* ((repo  (expand-file-name "elpaca/" elpaca-repos-directory))
         (build (expand-file-name "elpaca/" elpaca-builds-directory))
         (order (cdr elpaca-order))
         (default-directory repo))
    (add-to-list 'load-path (if (file-exists-p build) build repo))
    (unless (file-exists-p repo)
      (make-directory repo t)
      (when (<= emacs-major-version 28) (require 'subr-x))
      (condition-case-unless-debug err
          (if-let* ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
                    ((zerop (apply #'call-process `("git" nil ,buffer t "clone"
                                                    ,@(when-let* ((depth (plist-get order :depth)))
                                                        (list (format "--depth=%d" depth) "--no-single-branch"))
                                                    ,(plist-get order :repo) ,repo))))
                    ((zerop (call-process "git" nil buffer t "checkout"
                                          (or (plist-get order :ref) "--"))))
                    (emacs (concat invocation-directory invocation-name))
                    ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
                                          "--eval" "(byte-recompile-directory \".\" 0 'force)")))
                    ((require 'elpaca))
                    ((elpaca-generate-autoloads "elpaca" repo)))
              (progn (message "%s" (buffer-string)) (kill-buffer buffer))
            (error "%s" (with-current-buffer buffer (buffer-string))))
        ((error) (warn "%s" err) (delete-directory repo 'recursive))))
    (unless (require 'elpaca-autoloads nil t)
      (require 'elpaca)
      (elpaca-generate-autoloads "elpaca" repo)
      (let ((load-source-file-function nil)) (load "./elpaca-autoloads"))))
  (add-hook 'after-init-hook #'elpaca-process-queues)
  (elpaca `(,@elpaca-order)))


;; install use-package
(elpaca elpaca-use-package
  (elpaca-use-package-mode)
  (setq use-package-always-ensure t)
  (setq use-package-always-defer t))

;; hack: exclude all externally installed packages from elpaca.
(progn
  (require 'elpaca)
  (require 'cl-lib)
  (eval-when-compile (require 'subr-x)) ;; is this ok?

  (defun +elpaca-get-external-pkgs ()
    "Based on `package-load-all-descriptors'."
    (let ((pkg-dir-lst nil)
          (res nil))
      (dolist (dir (cons package-user-dir package-directory-list))
        (when (file-directory-p dir)
          (dolist (pkg-dir (directory-files dir t "\\`[^.]"))
            (when (file-directory-p pkg-dir)
              (push pkg-dir pkg-dir-lst)))))
      (dolist (pkg-dir pkg-dir-lst)
        (let ((pkg-file (expand-file-name (package--description-file pkg-dir)
                                          pkg-dir))
              (signed-file (concat pkg-dir ".signed")))
          (when (file-exists-p pkg-file)
            (with-temp-buffer
              (insert-file-contents pkg-file)
              (goto-char (point-min))
              (let ((pkg-text (read (current-buffer))))
                (if (not (eq 'define-package (car-safe pkg-text)))
                    (error "Package %s doesn't have \"define-package\"" pkg-file)
                  (let ((name (cadr pkg-text)))
                    (when name
                      (cl-pushnew (intern name) res)))))))))
      res))

  (dolist (pkg (+elpaca-get-external-pkgs))
    (push pkg elpaca-ignored-dependencies)))

% leaf

(elpaca leaf
  ;; add my own keywords
  (eval-after-load 'leaf
    (lambda nil
      (setq leaf-keywords
            (append
             leaf-keywords
             `(:elpaca-wait `(,@leaf--body :wait))))))
  :wait)

(elpaca leaf-keywords
  ;; custom keywords
  (leaf-keywords-init)
  (setq leaf-alias-keyword-alist '((:ensure . :elpaca)))
  (setq leaf-defaults (append '(:elpaca t) leaf-system-defaults))
  :wait)

;; hack: fix org version mismatch
;; (elpaca org)

;; finish all queues now to prevent async issues later
(elpaca-process-queues)

% necessary packages

(leaf general :elpaca-wait t
  :init
  (general-create-definer leader-bind
    :prefix "C-c"))

(leaf diminish :elpaca-wait t
  :require t)

(leaf which-key :elpaca-wait t
  :config
  (setq which-key-idle-delay 0.3)
  (which-key-mode 1)
  :diminish which-key-mode)

;; lingering key menus for repeated keypresses
(leaf hydra :elpaca-wait t)

;; functional programming library
;; https://github.com/magnars/dash.el
(leaf dash :elpaca-wait t
  :require t
  :config
  (defun -debug (label)
    "Debugging helper function for dash.el."
    (lambda (m)
      (message "%s: %S" label m)
      m))

  (defmacro -tap (value form)
    "Evaluate FORM with VALUE as its argument, then return VALUE unchanged.
This is the non-anaphoric version - VALUE is passed as an argument to FORM."
    `(let ((val ,value))
       ,form
       val))

  ;; (defmacro --tap (value &rest body)
;;     "Evaluate BODY with VALUE bound to `it`, then return VALUE unchanged.
;; This is the anaphoric version - VALUE is available as `it` in BODY."
;;     `(let ((it ,value))
;;        ,@body
;;        it))

  ;; (defmacro --tap (value &rest body)
;;     "Evaluate BODY with VALUE bound to `it`, then return VALUE unchanged.
;; This is the anaphoric version - VALUE is available as `it` in BODY."
;;     (declare (debug (form body)) (indent 1))
;;     (let ((val (make-symbol "value")))
;;       `(let ((,val ,value))
;;          (let ((it ,val))
;;            (ignore it)
;;            ,@body)
;;          ,val)))
  )


;; files/dirs library
;; https://github.com/rejeep/f.el
(leaf f :elpaca-wait t)

;; ;; string manipulation library
;; ;; https://github.com/magnars/s.el
(leaf s :elpaca-wait t)

;; finish all queues now to prevent async issues later
(elpaca-process-queues)

> adding to the load-path

load-path

  • A variable; a list of paths.
  • Paths to search for when loading an elisp file (like with require).
  • Typically, for every elisp package, you add its root dir to this list so that its main .el file is visible, and thus loadable.
  • To make adding paths to this variable easier, we define the following function.
  "Add PATH and its recursive subdirs to `load-path'.

DEPTH specifies how deeply to recurse. 0 for just PATH, 1 for PATH and its
subdirs, n>1 for till depth n, and -1 for infinite depth.

If EXCLUDE-SELF is non-nil, exclude PATH, and include only its recursive
subdirs.

If PATH or a subdir contains a =.nosearch= file, it's excluded.

This function returns a list of paths that were added to (or already exist in)
`load-path'."
  (cl-labels
      (;; return t if .nosearch file exists within dir
       (nosearch-subfile-p (d)
         (file-exists-p (expand-file-name ".nosearch" d)))

       ;; collect recursive subdirs
       (collect-fn (current-dir current-depth)
         (when (and (integerp current-depth)
                    ;; base case (unless inf depth)
                    (/= current-depth 0)
                    (file-directory-p current-dir))
           (let ((subdirs
                  (->> (directory-files current-dir t
                                        directory-files-no-dot-files-regexp)
                       (-filter #'file-directory-p)
                       (-remove #'nosearch-subfile-p))))
             ;; collect [ subdirs + (recurse subdirs) ]
             (->> subdirs
                  (-mapcat (lambda (sub)
                             (collect-fn sub (1- current-depth))))
                  (append subdirs))))))
    (let* ((collected (collect-fn path depth))
           (result (if (or exclude-self (nosearch-subfile-p path))
                       collected
                     (cons path collected))))

      ;; add result to `load-path'
      (--each result (add-to-list 'load-path it))
      result)))

(+add-to-load-path-recursively +emacs-src-dir -1)
(+add-to-load-path-recursively +emacs-submodules-dir 1)

> loading functions

require

  • A function that searches for and loads a corresponding elisp file from the load-path.
  • Any files loaded with require will be saved to the features var, so it can keep track of which files were loaded, prevent duplicate loads, and manage dependencies.
    • A side effect is that re-running require with the same arg will do nothing.
  • By default, if it throws an error, it terminates Emacs initialization. To prevent this, we write a wrapper +require that catches any errors and converts them into warnings.

load

  • A function similar to require, but with some key differences:
  • Can take any arbitrary file path.
  • Allows dupulicate loads.
  • Does not add to the features var.
  • We make a wrapper +load for this function as well.

+require-or-load

  • Runs +require if not yet loaded, and +load if already loaded.
(defmacro +require (feature &optional filename noerror)
  "A wrapper around `require' to warn instead of error."
  `(progn
     (condition-case-unless-debug err
         (require ,feature ,filename ,noerror)
       (error
        (display-warning 'require
                         (format "Failed to require: %s" err)
                         :error)))))

(defmacro +load (file &optional noerror nomessage nosuffix must-suffix)
  "A wrapper around `load' to warn instead of error."
  `(progn
     (condition-case-unless-debug err
         (load ,file ,noerror ,nomessage ,nosuffix ,must-suffix)
       (error
        (display-warning 'load
                         (format "Failed to load: %s" err)
                         :error)))))

(defmacro +require-or-load (feature)
  "If FEATURE is loaded, run `+load', Else, run `+require'."
  `(progn
     (unless (symbolp ,feature)
       (error "Expected symbol, got: %S" ,feature))
     (if (featurep ,feature)
         (+load (symbol-name ,feature))
       (+require ,feature))))

% startup hooks

emacs-startup-hook

  • evals after emacs-startup.

elpaca-after-init-hook

  • evals after elpaca finishes installing all packages.
  • essentially after-init-hook but elpaca-compatible.
;; print init time
(add-hook 'emacs-startup-hook
          (lambda ()
            (message "*** Emacs loaded in %s seconds with %d garbage collections."
                     (emacs-init-time "%.2f")
                     gcs-done)))

;; increase gc freq
(add-hook 'elpaca-after-init-hook
          (lambda ()
            (setq gc-cons-threshold (* 10000 10000))))

;; load saved customizations file
(add-hook 'elpaca-after-init-hook
          (lambda ()
            (when (file-exists-p custom-file)
              (load custom-file))))

% import

The rest of the configuration is loaded from ./src/src.el.

;; load ./src/src.el
(+require-or-load '_src)

> end

(provide 'init)

% init.el ends here


Last updated: August 22, 2025