refactor(emacs): move random-require code into its own module
This commit is contained in:
@@ -3,18 +3,9 @@
|
|||||||
(add-to-list 'load-path
|
(add-to-list 'load-path
|
||||||
(file-name-concat user-emacs-directory "lisp"))
|
(file-name-concat user-emacs-directory "lisp"))
|
||||||
|
|
||||||
(defconst syd-init-load-order-seed
|
|
||||||
(or (when-let ((x (getenv "SYD_INIT_LOAD_ORDER_SEED")))
|
|
||||||
(string-to-number x))
|
|
||||||
(random))
|
|
||||||
"Seed used to load top-level modules in pseudo-random order. Loading modules
|
|
||||||
in an unpredictable order by default is a tactic to prevent implicit
|
|
||||||
dependencies between modules. For debugging purposes, the load-order may be
|
|
||||||
made deterministic by starting Emacs with the environment variable
|
|
||||||
SYD_INIT_LOAD_ORDER_SEED set to a non-negative integer.")
|
|
||||||
|
|
||||||
;; Log as early as possible to make it difficult to miss.
|
;; Load `syd/random-require' before the UI exists so `syd-init-load-order-seed'
|
||||||
(message "Top-level modules will be loaded in the order determined by seed %d"
|
;; is printed to the console instead of the message buffer.
|
||||||
syd-init-load-order-seed)
|
(require 'syd/random-require)
|
||||||
|
|
||||||
(require 'syd/disable-package)
|
(require 'syd/disable-package)
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
;;; init.el -*- lexical-binding: t -*-
|
;;; init.el -*- lexical-binding: t -*-
|
||||||
|
|
||||||
(require 'cl-lib)
|
(syd-require-features
|
||||||
|
|
||||||
(defconst syd-features
|
|
||||||
'(syd/base
|
'(syd/base
|
||||||
syd/constants
|
syd/constants
|
||||||
syd/dash
|
syd/dash
|
||||||
@@ -49,20 +47,3 @@
|
|||||||
syd/display-startup-time
|
syd/display-startup-time
|
||||||
syd/dired
|
syd/dired
|
||||||
syd/ligature))
|
syd/ligature))
|
||||||
|
|
||||||
(defun syd-random-permutation (lst &optional seed)
|
|
||||||
"Return a random permutation of list LST using SEED as the random state. The
|
|
||||||
permutation is deterministic for a given SEED."
|
|
||||||
(let* ((random-state (cl-make-random-state (or seed (random))))
|
|
||||||
(len (length lst))
|
|
||||||
(vec (vconcat lst)))
|
|
||||||
;; Fisher-Yates shuffle.
|
|
||||||
(cl-loop for i from (1- len) downto 1 do
|
|
||||||
(cl-rotatef (aref vec i)
|
|
||||||
(aref vec (cl-random (1+ i) random-state))))
|
|
||||||
;; Convert vector to list.
|
|
||||||
(append vec nil)))
|
|
||||||
|
|
||||||
(dolist (feature (syd-random-permutation syd-features
|
|
||||||
syd-init-load-order-seed))
|
|
||||||
(require feature))
|
|
||||||
|
|||||||
50
modules/home/users/msyds/emacs/lisp/syd/random-require.el
Normal file
50
modules/home/users/msyds/emacs/lisp/syd/random-require.el
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
;;; -*- lexical-binding: t -*-
|
||||||
|
;;;
|
||||||
|
;;; This is one of my config's weirder bits. My config is organised into many
|
||||||
|
;;; disjoint "modules," configuring one group of related things at a time. I
|
||||||
|
;;; want these modules to be as independent as possible — you should be able to
|
||||||
|
;;; add and remove individual modules and the only modules that should stop
|
||||||
|
;;; working are those which inherently build off of the removed module's
|
||||||
|
;;; functionality. Thus, I want to discourage any reliance on some implicit
|
||||||
|
;;; load order — all dependencies should be explicit. As one method to shake
|
||||||
|
;;; the tree of dependencies, so to speak, I came up with the idea of loading my
|
||||||
|
;;; "top-level" modules in a pseudo-random order, which has proven incredibly
|
||||||
|
;;; effective in catching accidental implicit dependencies thus far!
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
|
||||||
|
(defconst syd-init-load-order-seed
|
||||||
|
(or (when-let ((x (getenv "SYD_INIT_LOAD_ORDER_SEED")))
|
||||||
|
(string-to-number x))
|
||||||
|
(random))
|
||||||
|
"Seed used to load top-level modules in pseudo-random order. Loading modules
|
||||||
|
in an unpredictable order by default is a tactic to prevent implicit
|
||||||
|
dependencies between modules. For debugging purposes, the load-order may be
|
||||||
|
made deterministic by starting Emacs with the environment variable
|
||||||
|
SYD_INIT_LOAD_ORDER_SEED set to a non-negative integer.")
|
||||||
|
|
||||||
|
;; Log as early as possible to make it difficult to miss.
|
||||||
|
(message "Top-level modules will be loaded in the order determined by SYD_INIT_LOAD_ORDER_SEED=%d"
|
||||||
|
syd-init-load-order-seed)
|
||||||
|
|
||||||
|
(defun syd-random-permutation (lst &optional seed)
|
||||||
|
"Return a random permutation of list LST using SEED as the random state. The
|
||||||
|
permutation is deterministic for a given SEED."
|
||||||
|
(let* ((random-state (cl-make-random-state (or seed (random))))
|
||||||
|
(len (length lst))
|
||||||
|
(vec (vconcat lst)))
|
||||||
|
;; Fisher-Yates shuffle.
|
||||||
|
(cl-loop for i from (1- len) downto 1 do
|
||||||
|
(cl-rotatef (aref vec i)
|
||||||
|
(aref vec (cl-random (1+ i) random-state))))
|
||||||
|
;; Convert vector to list.
|
||||||
|
(append vec nil)))
|
||||||
|
|
||||||
|
(defun syd-require-features (features)
|
||||||
|
"Require each of FEATURES in the pseudo-random order defined by
|
||||||
|
`syd-init-load-order-seed' and `syd-random-permutation'."
|
||||||
|
(dolist (feature (syd-random-permutation
|
||||||
|
features syd-init-load-order-seed))
|
||||||
|
(require feature)))
|
||||||
|
|
||||||
|
(provide 'syd/random-require)
|
||||||
Reference in New Issue
Block a user