diff --git a/core/core.el b/core/core.el index 91531e739..7dda9a4b2 100644 --- a/core/core.el +++ b/core/core.el @@ -300,6 +300,69 @@ original value of `symbol-file'." (add-hook 'minibuffer-exit-hook #'doom|restore-garbage-collection) +;; +;; Incremental lazy-loading + +(defvar doom-incremental-packages '(t) + "A list of packages to load incrementally after startup. Any large packages +here may cause noticable pauses, so it's recommended you break them up into +sub-packages. For example, `org' is comprised of many packages, and can be broken up into: + + (doom-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 +`doom|load-packages-incrementally' from `emacs-startup-hook' or set +`doom-incremental-first-idle-timer' to nil.") + +(defvar doom-incremental-first-idle-timer 2 + "How long (in idle seconds) until incremental loading starts. + +Set this to nil to disable incremental loading.") + +(defvar doom-incremental-idle-timer 1.5 + "How long (in idle seconds) in between incrementally loading packages.") + +(defun doom-load-packages-incrementally (packages &optional now) + "Registers PACKAGES to be loaded incrementally. + +If NOW is non-nil, load PACKAGES incrementally, in `doom-incremental-idle-timer' +intervals." + (if (not now) + (nconc doom-incremental-packages packages) + (when packages + (let ((gc-cons-threshold doom-gc-cons-upper-limit) + file-name-handler-alist) + (let* ((reqs (cl-remove-if #'featurep packages)) + (req (ignore-errors (pop reqs)))) + (when req + (when doom-debug-mode + (message "Incrementally loading %s" req)) + (require req) + (when reqs + (run-with-idle-timer doom-incremental-idle-timer + nil #'doom-load-packages-incrementally + reqs t)))))))) + +(defun doom|load-packages-incrementally () + "Begin incrementally loading packages in `doom-incremental-packages'. + +If this is a daemon session, load them all immediately instead." + (if (daemonp) + (mapc #'require (cdr doom-incremental-packages)) + (when (integerp doom-incremental-first-idle-timer) + (run-with-idle-timer doom-incremental-first-idle-timer + nil #'doom-load-packages-incrementally + (cdr doom-incremental-packages) t)))) + +(add-hook 'emacs-startup-hook #'doom|load-packages-incrementally) + + ;; ;; Bootstrap helpers diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index 271451a4e..750a3d015 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -13,6 +13,12 @@ (if (featurep! +present) (load! "+present")) ;; TODO (if (featurep! +publish) (load! "+publish")) +(doom-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)) + ;; ;; Packages diff --git a/modules/tools/magit/config.el b/modules/tools/magit/config.el index 68ee8cb05..8157147db 100644 --- a/modules/tools/magit/config.el +++ b/modules/tools/magit/config.el @@ -18,6 +18,8 @@ available.") :commands magit-file-delete :init (setq magit-auto-revert-mode nil) ; we already use `global-auto-revert-mode' + (doom-load-packages-incrementally + '(dash f s with-editor git-commit package magit)) :config (setq magit-completing-read-function (if (featurep! :completion ivy)