Custom Emacs functions No. 2 - Modules

Modules

The module timu-bits.el in my Emacs configuration is the first to loaded after the init file.

Why? It handles packages and the proper loading of all other modules.

Commands and functions

timu-bits-install-packages

I quite like the way Emacs Prelude handles automatic package installation. This means of course stealing some code here.

What I did not like was the fact that this is split into several functions. I reworked this into one single function.

This checks whether the packages in the variable timu-package-list (list) are installed or not and installs the missing from package archives.

(defun timu-bits-install-packages ()
  "Check if all packages in `timu-package-list' are installed.
Install the missing packages and if not.

Credit: https://github.com/bbatsov/prelude
Credit: https://chat.openai.com/chat."
  (interactive)
  (let ((missing-packages
         (cl-remove-if #'package-installed-p timu-package-list)))
    (when missing-packages
      ;; check for new packages (package versions)
      (message "%s" "Reloading packages DB...")
      (package-refresh-contents)
      (message "%s" " done.")
      ;; install the missing packages
      (mapc #'package-install missing-packages))))

This function is used in the init.el before the other configuration is loaded of course.

timu-bits-require

A simple-ish macro to robustly require packages, libraries and modules.

(defmacro timu-bits-require (&rest modules)
  "Load MODULES, if they are not already loaded and are installed.
Skips any modules that are not found.

Displays a message in the minibuffer for any modules that are not found.
Displays a message in the minibuffer for any modules that are already loaded.

Credit: https://chat.openai.com/chat."
  `(progn
     ,@(mapcar (lambda (module)
                 `(when (not (featurep ',module))
                    (if (locate-library ,(symbol-name module))
                        (progn
                          (require ',module)
                          (message "Loaded module '%s'" ',module))
                      (message "Module '%s' not found" ',module))))
               modules)))

The following code …

(timu-bits-require timu-bits)

… would expand to

(progn
  (when
      (not
       (featurep 'timu-bits))
    (if
        (locate-library "timu-bits")
        (progn
          (require 'timu-bits)
          (message "Loaded module '%s'" 'timu-bits))
      (message "Module '%s' not found" 'timu-bits))))

Nice bonus. There is a message trace for potential debugging. All i have to do is use the micro in my configuration, which I don’t yet.

timu-bits-load

This one is really simple. It is called in the init.el to load my custom modules in the configuration.

Might user timu-bits-require instead of require in the future.

(defun timu-bits-load ()
  "Load all custom the modules using `require'.
The order in which the modules are loaded is important."
  (interactive)
  (require 'timu-evil)
  (require 'timu-base)
  (require 'timu-personal)
  (with-eval-after-load 'dired
    (require 'timu-dired))
  (require 'timu-ui)
  (with-eval-after-load 'org
    (require 'timu-org))
  (require 'timu-roam)
  (require 'timu-nav)
  (require 'timu-modes)
  (require 'timu-edit)
  (with-eval-after-load 'eshell
    (require 'timu-shell))
  (require 'timu-fun)
  (require 'timu-map)
  (require 'timu-scratch)
  (pcase system-type
    ((or 'darwin 'gnu/linux)
     (with-eval-after-load 'pdf-view
       (require 'timu-pdf))
     (with-eval-after-load 'magit
       (require 'timu-git))
     (require 'timu-mu4e)
     (require 'timu-elfeed)
     (require 'timu-prog)
     (with-eval-after-load 'latex
       (require 'timu-latex))
     (require 'timu-work)
     (require 'timu-try))))

The end!

UPDATE - 27. May 2023

Renamed a few modules (now ‘bits’). Hence the few changes in this post.