Files
sydnix/modules/home/users/msyds/emacs/lisp/syd/use-package.el
2025-11-23 04:06:39 -07:00

107 lines
4.5 KiB
EmacsLisp
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
;;; -*- lexical-binding: t; -*-
(defvar syd-incremental-idle-timer 0.75
"How long (in idle seconds) in between incrementally loading packages.")
(defvar syd-incremental-first-idle-timer (if (daemonp) 0 2.0)
"How long (in idle seconds) until incremental loading starts.
Set this to nil to disable incremental loading at startup.
Set this to 0 to load all incrementally deferred packages immediately at
`after-init-hook'.")
(defvar syd-incremental-packages '(t)
"A list of packages to load incrementally after startup. Any large packages
here may cause noticeable pauses, so it's recommended you break them up into
sub-packages. For example, `org' is comprised of many packages, and might be
broken up into:
(syd-load-packages-incrementally
'(calendar find-func format-spec org-macs org-compat
org-faces org-entities org-list org-pcomplete org-src
org-footnote org-macro ob org org-clock org-agenda
org-capture))
This is already done by the lang/org module, however.
If you want to disable incremental loading altogether, either remove
`syd-load-packages-incrementally-h' from `after-init-hook' or set
`syd-incremental-first-idle-timer' to nil. Incremental loading does not occur
in daemon sessions (they are loaded immediately at startup).")
(defun syd-load-packages-incrementally (packages &optional now)
"Registers PACKAGES to be loaded incrementally.
If NOW is non-nil, PACKAGES will be marked for incremental loading next time
Emacs is idle for `syd-incremental-first-idle-timer' seconds (falls back to
`syd-incremental-idle-timer'), then in `syd-incremental-idle-timer' intervals
afterwards."
(let* ((gc-cons-threshold most-positive-fixnum)
(first-idle-timer (or syd-incremental-first-idle-timer
syd-incremental-idle-timer)))
(if (not now)
(cl-callf append syd-incremental-packages packages)
(while packages
(let ((req (pop packages))
idle-time)
(unless (featurep req)
(condition-case-unless-debug e
(and
(or (null (setq idle-time (current-idle-time)))
(< (float-time idle-time) first-idle-timer)
(not
(while-no-input
;; If `default-directory' doesn't exist or is
;; unreadable, Emacs throws file errors.
(let ((default-directory user-emacs-directory)
(inhibit-message t)
(file-name-handler-alist
(list (rassq 'jka-compr-handler file-name-handler-alist))))
(message "loading %s" req)
(require req nil t)
t))))
(push req packages))
(error
(message "Error: failed to incrementally load %S because: %s" req e)
(setq packages nil)))
(unless (null packages)
(run-at-time (if idle-time
syd-incremental-idle-timer
first-idle-timer)
nil #'syd-load-packages-incrementally
packages t)
(setq packages nil))))))))
(defun syd-load-packages-incrementally-h ()
"Begin incrementally loading packages in `syd-incremental-packages'.
If this is a daemon session, load them all immediately instead."
(when (numberp syd-incremental-first-idle-timer)
(if (zerop syd-incremental-first-idle-timer)
(mapc #'require (cdr syd-incremental-packages))
(run-with-idle-timer syd-incremental-first-idle-timer
nil #'syd-load-packages-incrementally
(cdr syd-incremental-packages) t))))
(unless noninteractive
(add-hook 'after-init-hook #'syd-load-packages-incrementally-h 100))
(with-eval-after-load 'use-package-core
(push :defer-incrementally use-package-deferring-keywords)
(setq use-package-keywords (use-package-list-insert
:defer-incrementally use-package-keywords :after))
(defalias 'use-package-normalize/:defer-incrementally
#'use-package-normalize-symlist)
(defun use-package-handler/:defer-incrementally
(name _keyword targets rest state)
(use-package-concat
`((syd-load-packages-incrementally
',(if (equal targets '(t))
(list name)
(append targets (list name)))))
(use-package-process-keywords name rest state))))
(provide 'syd/use-package)