Fix Emacs Elpaca bootstrap and startup
This commit is contained in:
@@ -1347,6 +1347,7 @@ Paradox is a package.el extension. I have no use for it now that I use straight.
|
||||
** load-dir
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package load-dir
|
||||
:ensure (:host github :repo "emacs-straight/load-dir")
|
||||
:demand t
|
||||
:config
|
||||
(progn
|
||||
@@ -2670,7 +2671,7 @@ The following is taken from [[https://github.com/syl20bnr/spacemacs/blob/a650877
|
||||
**** clj-refactor
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
;;@WORKAROUND clj-refactor dependency inflections Version metadata
|
||||
(use-package inflections :ensure (:depth nil :version elpaca-latest-tag :version-regexp "[[:digit:]]\\.[[:digit:]]"))
|
||||
(use-package inflections)
|
||||
(use-package clj-refactor
|
||||
:commands clj-refactor-mode)
|
||||
#+END_SRC
|
||||
@@ -4108,8 +4109,19 @@ load-theme hook (See the heading below).
|
||||
#+END_SRC
|
||||
** Set Font
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(add-to-list 'default-frame-alist
|
||||
'(font . "JetBrainsMono Nerd Font-10:weight=medium"))
|
||||
(defvar imalison:preferred-font-families
|
||||
'("JetBrainsMono Nerd Font"
|
||||
"JetBrains Mono"
|
||||
"JetBrainsMono Nerd Font Mono"))
|
||||
|
||||
(defun imalison:default-font-parameter ()
|
||||
(catch 'font
|
||||
(dolist (family imalison:preferred-font-families)
|
||||
(when (find-font (font-spec :family family))
|
||||
(throw 'font (format "%s-10" family))))))
|
||||
|
||||
(when-let ((font (imalison:default-font-parameter)))
|
||||
(add-to-list 'default-frame-alist `(font . ,font)))
|
||||
#+END_SRC
|
||||
** imalison:appearance
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
;; -*- lexical-binding: t; -*-
|
||||
|
||||
(setq package-enable-at-startup nil)
|
||||
|
||||
@@ -1,6 +1,23 @@
|
||||
;; Elpaca Installer -*- lexical-binding: t; -*-
|
||||
(defvar elpaca-installer-version 0.12)
|
||||
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
|
||||
|
||||
(defun elpaca-installer--state-root ()
|
||||
"Return a writable root for Elpaca state."
|
||||
(let* ((preferred user-emacs-directory)
|
||||
(fallback (expand-file-name
|
||||
"emacs/"
|
||||
(or (getenv "XDG_STATE_HOME")
|
||||
(expand-file-name "~/.local/state/")))))
|
||||
(condition-case nil
|
||||
(progn
|
||||
(make-directory preferred t)
|
||||
preferred)
|
||||
(file-error
|
||||
(make-directory fallback t)
|
||||
fallback))))
|
||||
|
||||
(defvar elpaca-directory
|
||||
(expand-file-name "elpaca/" (elpaca-installer--state-root)))
|
||||
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
|
||||
(defvar elpaca-sources-directory (expand-file-name "sources/" elpaca-directory))
|
||||
(defvar elpaca-legacy-repos-directory (expand-file-name "repos/" elpaca-directory))
|
||||
@@ -9,6 +26,26 @@
|
||||
:files (:defaults "elpaca-test.el" (:exclude "extensions"))
|
||||
:build (:not elpaca-activate)))
|
||||
|
||||
(defun elpaca-installer--ensure-symlink (target alias)
|
||||
"Create symlink from ALIAS to TARGET, ignoring pre-existing paths."
|
||||
(condition-case nil
|
||||
(make-symbolic-link target alias)
|
||||
(file-already-exists nil)))
|
||||
|
||||
(defun elpaca-installer--build-stale-p (build)
|
||||
"Return non-nil when BUILD contains older compiled artifacts than its sources."
|
||||
(when (file-directory-p build)
|
||||
(catch 'stale
|
||||
(dolist (entry (directory-files build t "\\.elc?\\'"))
|
||||
(when (string-suffix-p ".elc" entry)
|
||||
(let* ((source (substring entry 0 -1))
|
||||
(source-truename (and (file-exists-p source)
|
||||
(ignore-errors (file-truename source)))))
|
||||
(when (and source-truename
|
||||
(file-newer-than-file-p source-truename entry))
|
||||
(throw 'stale t)))))
|
||||
nil)))
|
||||
|
||||
(defun elpaca-installer--repo-installer-version (repo)
|
||||
"Return the installer version expected by elpaca checkout at REPO."
|
||||
(let ((elpaca-el (expand-file-name "elpaca.el" repo)))
|
||||
@@ -34,9 +71,18 @@
|
||||
(dolist (entry (directory-files build t directory-files-no-dot-files-regexp))
|
||||
(when-let* ((target (file-symlink-p entry))
|
||||
(truename (ignore-errors (file-truename entry)))
|
||||
(source-root (and truename
|
||||
(directory-file-name
|
||||
(file-name-directory truename)))))
|
||||
(source-root
|
||||
(catch 'source-root
|
||||
(dolist (root roots)
|
||||
(when (string-prefix-p root truename)
|
||||
(let* ((relative (file-relative-name truename root))
|
||||
(repo-name (car (split-string relative "/" t)))
|
||||
(repo-root (and repo-name
|
||||
(expand-file-name repo-name root))))
|
||||
(when (file-directory-p repo-root)
|
||||
(throw 'source-root
|
||||
(directory-file-name repo-root))))))
|
||||
nil)))
|
||||
(dolist (root roots)
|
||||
(when (string-prefix-p root truename)
|
||||
(when (file-directory-p source-root)
|
||||
@@ -68,39 +114,21 @@
|
||||
((file-symlink-p source)
|
||||
(delete-file source)
|
||||
(if desired-source
|
||||
(make-symbolic-link desired-source
|
||||
(directory-file-name source))
|
||||
(elpaca-installer--ensure-symlink
|
||||
desired-source
|
||||
(directory-file-name source))
|
||||
(delete-directory build 'recursive)))
|
||||
((file-exists-p source) nil)
|
||||
(desired-source
|
||||
(make-symbolic-link desired-source
|
||||
(directory-file-name source)))
|
||||
(elpaca-installer--ensure-symlink
|
||||
desired-source
|
||||
(directory-file-name source)))
|
||||
(t
|
||||
(delete-directory build 'recursive))))))))
|
||||
|
||||
(defun elpaca-installer--repair-source-dir-aliases ()
|
||||
"Create compatibility symlinks for legacy repos ending in `.el'."
|
||||
(when (file-directory-p elpaca-sources-directory)
|
||||
(dolist (entry (directory-files elpaca-sources-directory t directory-files-no-dot-files-regexp))
|
||||
(when-let* (((file-directory-p entry))
|
||||
(name (file-name-nondirectory (directory-file-name entry)))
|
||||
((string-suffix-p ".el" name))
|
||||
(alias-name (substring name 0 (- (length name) 3)))
|
||||
(alias (expand-file-name alias-name elpaca-sources-directory))
|
||||
(target (ignore-errors
|
||||
(directory-file-name (file-truename entry)))))
|
||||
(cond
|
||||
((and (file-symlink-p alias)
|
||||
(equal (ignore-errors (directory-file-name (file-truename alias)))
|
||||
target))
|
||||
nil)
|
||||
((file-symlink-p alias)
|
||||
(delete-file alias)
|
||||
(make-symbolic-link target alias))
|
||||
((file-exists-p alias)
|
||||
nil)
|
||||
(t
|
||||
(make-symbolic-link target alias)))))))
|
||||
"Compatibility hook retained for older configs."
|
||||
nil)
|
||||
;; Elpaca now expects package sources under `sources/`. Preserve older local
|
||||
;; installs that still use `repos/` so startup can recover without recloning.
|
||||
(when (and (file-directory-p elpaca-legacy-repos-directory)
|
||||
@@ -109,8 +137,9 @@
|
||||
(directory-file-name elpaca-sources-directory)))
|
||||
(when (and (file-directory-p elpaca-sources-directory)
|
||||
(not (file-exists-p elpaca-legacy-repos-directory)))
|
||||
(make-symbolic-link (directory-file-name elpaca-sources-directory)
|
||||
(directory-file-name elpaca-legacy-repos-directory)))
|
||||
(elpaca-installer--ensure-symlink
|
||||
(directory-file-name elpaca-sources-directory)
|
||||
(directory-file-name elpaca-legacy-repos-directory)))
|
||||
(elpaca-installer--repair-source-dir-aliases)
|
||||
(elpaca-installer--repair-build-source-layout)
|
||||
(let* ((repo (expand-file-name "elpaca/" elpaca-sources-directory))
|
||||
@@ -124,13 +153,14 @@
|
||||
((not (equal repo-version (format "%s" elpaca-installer-version)))))
|
||||
(when (file-directory-p build)
|
||||
(delete-directory build 'recursive))
|
||||
(when (file-directory-p elpaca-cache-directory)
|
||||
(when (and (boundp 'elpaca-cache-directory)
|
||||
(file-directory-p elpaca-cache-directory))
|
||||
(delete-directory elpaca-cache-directory 'recursive))
|
||||
(when (file-directory-p repo)
|
||||
(delete-directory repo 'recursive)))
|
||||
(when (elpaca-installer--build-stale-p build)
|
||||
(delete-directory build 'recursive))
|
||||
(add-to-list 'load-path repo)
|
||||
(when (file-exists-p build)
|
||||
(add-to-list 'load-path build))
|
||||
(unless (file-exists-p repo)
|
||||
(make-directory repo t)
|
||||
(when (<= emacs-major-version 28) (require 'subr-x))
|
||||
@@ -154,5 +184,7 @@
|
||||
(require 'elpaca)
|
||||
(elpaca-generate-autoloads "elpaca" repo)
|
||||
(let ((load-source-file-function nil)) (load autoloads))))
|
||||
(require 'elpaca)
|
||||
(setq elpaca-log-functions '(elpaca-log-command-query))
|
||||
(add-hook 'after-init-hook #'elpaca-process-queues)
|
||||
(elpaca `(,@elpaca-order))
|
||||
|
||||
@@ -8,11 +8,76 @@
|
||||
(defvar imalison:do-benchmark nil)
|
||||
|
||||
(defun emacs-directory-filepath (filename)
|
||||
(concat (file-name-directory load-file-name) filename))
|
||||
(expand-file-name filename user-emacs-directory))
|
||||
|
||||
(load-file (expand-file-name "elpaca-installer.el" user-emacs-directory))
|
||||
|
||||
;; Elpaca's initial queue logger can fire during self-bootstrap before its
|
||||
;; helper is callable under --debug-init. Keep command logging, but skip the
|
||||
;; fragile initial-queue logger so startup diagnostics reach the real config.
|
||||
(setq elpaca-log-functions '(elpaca-log-command-query))
|
||||
;; Default hosted git clones to SSH (e.g., git@github.com:owner/repo.git).
|
||||
(setq elpaca-order-defaults (plist-put elpaca-order-defaults :protocol 'ssh))
|
||||
|
||||
(defun imalison:existing-executable (&rest candidates)
|
||||
(seq-find #'file-executable-p (delq nil candidates)))
|
||||
|
||||
(defun imalison:emacs-bin-directory ()
|
||||
(let ((emacsclient (or (executable-find "emacsclient")
|
||||
(when invocation-directory
|
||||
(expand-file-name "emacsclient" invocation-directory))
|
||||
(when invocation-directory
|
||||
(expand-file-name "../../../../bin/emacsclient"
|
||||
invocation-directory)))))
|
||||
(when (and emacsclient (file-executable-p emacsclient))
|
||||
(directory-file-name (file-name-directory emacsclient)))))
|
||||
|
||||
(defun imalison:emacsclient-executable ()
|
||||
(imalison:existing-executable
|
||||
(executable-find "emacsclient")
|
||||
(when invocation-directory
|
||||
(expand-file-name "emacsclient" invocation-directory))
|
||||
(when invocation-directory
|
||||
(expand-file-name "../../../../bin/emacsclient" invocation-directory))))
|
||||
|
||||
;; GUI Emacs launched from the app bundle may not inherit a PATH that contains
|
||||
;; the matching emacsclient binary.
|
||||
(when-let ((emacs-bin (imalison:emacs-bin-directory)))
|
||||
(add-to-list 'exec-path emacs-bin)
|
||||
(setenv "PATH" (concat emacs-bin path-separator (or (getenv "PATH") ""))))
|
||||
(setq emacsclient-program-name
|
||||
(imalison:emacsclient-executable))
|
||||
(setq with-editor-emacsclient-executable
|
||||
(imalison:emacsclient-executable))
|
||||
|
||||
(defun imalison:elpaca-menu-local-repos (request &optional item)
|
||||
(when (eq request 'index)
|
||||
(let ((root elpaca-sources-directory))
|
||||
(cl-labels
|
||||
((item-info
|
||||
(pkg)
|
||||
(let* ((name (symbol-name pkg))
|
||||
(dir (expand-file-name name root))
|
||||
(git-dir (expand-file-name ".git" dir)))
|
||||
(when (file-directory-p git-dir)
|
||||
(with-temp-buffer
|
||||
(when (zerop (call-process "git" nil t nil "-C" dir "config" "--get" "remote.origin.url"))
|
||||
(let ((remote (string-trim (buffer-string))))
|
||||
(when (not (string-empty-p remote))
|
||||
(list :source "Local repos"
|
||||
:recipe (list :package name
|
||||
:repo remote
|
||||
:local-repo name))))))))))
|
||||
(if item
|
||||
(item-info item)
|
||||
(cl-loop for path in (directory-files root nil "^[^.]" t)
|
||||
for pkg = (intern path)
|
||||
for info = (item-info pkg)
|
||||
when info
|
||||
collect (cons pkg info)))))))
|
||||
|
||||
(add-to-list 'elpaca-menu-functions #'imalison:elpaca-menu-local-repos t)
|
||||
|
||||
(elpaca elpaca-use-package (elpaca-use-package-mode))
|
||||
(elpaca-wait)
|
||||
(setq use-package-enable-imenu-support t)
|
||||
@@ -40,6 +105,15 @@
|
||||
:config
|
||||
(progn (dash-enable-font-lock)))
|
||||
|
||||
;; Some split packages fall through the active menus in this config. Give
|
||||
;; Elpaca an explicit source so startup doesn't get stuck on recipe lookup or
|
||||
;; stale branch-mapped clones.
|
||||
(elpaca `(queue :host github :repo "emacs-straight/queue"))
|
||||
(elpaca `(git-commit :host github :repo "magit/magit"
|
||||
:files ("lisp/git-commit.el" "lisp/git-commit-pkg.el")))
|
||||
(elpaca `(magit-section :host github :repo "magit/magit"
|
||||
:files ("lisp/magit-section.el" "lisp/magit-section-pkg.el")))
|
||||
|
||||
(use-package gh
|
||||
:defer t
|
||||
:ensure (:host github :repo "IvanMalison/gh.el"))
|
||||
@@ -85,6 +159,22 @@
|
||||
|
||||
(elpaca-wait)
|
||||
|
||||
(require 'org)
|
||||
|
||||
(defun imalison:load-literate-file (org-file)
|
||||
(let ((el-file (concat (file-name-sans-extension org-file) ".el")))
|
||||
;; Prefer the tangled file on normal startup and only re-tangle when the
|
||||
;; Org source changed.
|
||||
(if (and (file-exists-p el-file)
|
||||
(not (file-newer-than-file-p org-file el-file)))
|
||||
(load-file el-file)
|
||||
(org-babel-load-file org-file))))
|
||||
|
||||
(defun imalison:load-kat-mode ()
|
||||
(let ((debug-on-error t))
|
||||
(imalison:load-literate-file
|
||||
(emacs-directory-filepath "kat-mode.org"))))
|
||||
|
||||
;; Install transient early to prevent built-in version from loading
|
||||
;; Workaround: overriding-text-conversion-style is void on pgtk builds (no
|
||||
;; HAVE_TEXT_CONVERSION) but transient's .elc compiled on X11 has static-if
|
||||
@@ -99,29 +189,25 @@
|
||||
;; Magit's split packages are compiled separately; make them available before
|
||||
;; the larger config queue reaches magit itself.
|
||||
(use-package git-commit
|
||||
:ensure (:host github :repo "magit/magit"
|
||||
:files ("lisp/git-commit.el" "lisp/git-commit-pkg.el")
|
||||
:wait t)
|
||||
:ensure nil
|
||||
:defer t)
|
||||
|
||||
(use-package magit-section
|
||||
:ensure (:host github :repo "magit/magit"
|
||||
:files ("lisp/magit-section.el" "lisp/magit-section-pkg.el")
|
||||
:wait t)
|
||||
:ensure nil
|
||||
:defer t)
|
||||
|
||||
(elpaca-wait)
|
||||
|
||||
(when (or (equal (s-trim (shell-command-to-string "whoami")) "kat")
|
||||
imalison:kat-mode)
|
||||
(let ((debug-on-error t))
|
||||
(org-babel-load-file
|
||||
(concat (file-name-directory load-file-name) "kat-mode.org"))))
|
||||
|
||||
(let ((debug-on-error t))
|
||||
(org-babel-load-file
|
||||
(imalison:load-literate-file
|
||||
(expand-file-name "README.org" user-emacs-directory)))
|
||||
|
||||
(when (or (equal (s-trim (shell-command-to-string "whoami")) "kat")
|
||||
imalison:kat-mode)
|
||||
;; Machine-specific overrides can reuse packages declared in README once
|
||||
;; Elpaca has activated the main init queue.
|
||||
(add-hook 'elpaca-after-init-hook #'imalison:load-kat-mode))
|
||||
|
||||
;; (when imalison:do-benchmark (benchmark-init/deactivate))
|
||||
|
||||
;; Local Variables:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
* evil
|
||||
#+begin_src emacs-lisp
|
||||
(use-package evil
|
||||
:ensure nil
|
||||
:demand t
|
||||
:config
|
||||
(progn
|
||||
@@ -22,6 +23,7 @@
|
||||
This makes evil-mode play nice with org-fc
|
||||
#+begin_src emacs-lisp
|
||||
(use-package org-fc
|
||||
:ensure (:host github :repo "l3kn/org-fc")
|
||||
:demand t
|
||||
:config
|
||||
(progn
|
||||
@@ -49,6 +51,7 @@ This makes evil-mode play nice with org-fc
|
||||
#+begin_src emacs-lisp
|
||||
(setq imalison:org-whoami "Kat Huang")
|
||||
(setq org-directory "~/org/") ; This is the directory where you want to save your Org files. Change as necessary.
|
||||
(defvar org-capture-templates nil)
|
||||
(add-to-list 'org-capture-templates
|
||||
'("j" "Journal" entry (file+datetree "~/org/daily-journal.org")
|
||||
"* %?\nEntered on %U\n %i\n %a"))
|
||||
@@ -61,7 +64,7 @@ This makes evil-mode play nice with org-fc
|
||||
** Journal
|
||||
#+begin_src emacs-lisp
|
||||
(setq imalison:journal-template-filepath
|
||||
(imalison:join-paths org-directory "templates" "daily-journal-template.org"))
|
||||
(expand-file-name "templates/daily-journal-template.org" org-directory))
|
||||
#+end_src
|
||||
** Insert a link to a task selected from agenda
|
||||
#+begin_src emacs-lisp
|
||||
@@ -119,6 +122,7 @@ This makes evil-mode play nice with org-fc
|
||||
* Disable autoflake
|
||||
#+begin_src emacs-lisp
|
||||
(use-package apheleia
|
||||
:ensure nil
|
||||
:demand t
|
||||
:config
|
||||
(progn
|
||||
@@ -131,11 +135,6 @@ This makes evil-mode play nice with org-fc
|
||||
* Packages
|
||||
#+begin_src emacs-lisp
|
||||
(use-package org-drill)
|
||||
(require 'package)
|
||||
(add-to-list 'package-archives
|
||||
'("melpa" . "https://melpa.org/packages/") t)
|
||||
(package-initialize)
|
||||
|
||||
#+end_src
|
||||
|
||||
* Disable wild notifactions
|
||||
@@ -145,26 +144,17 @@ This makes evil-mode play nice with org-fc
|
||||
|
||||
* Swift
|
||||
#+begin_src emacs-lisp
|
||||
(require 'package)
|
||||
(add-to-list 'package-archives
|
||||
'("melpa" . "https://melpa.org/packages/") t)
|
||||
(package-initialize)
|
||||
(use-package swift-mode
|
||||
:ensure nil
|
||||
:demand t
|
||||
:config
|
||||
(add-to-list 'auto-mode-alist '("\\.swift\\'" . swift-mode)))
|
||||
|
||||
(unless (package-installed-p 'swift-mode)
|
||||
(package-refresh-contents)
|
||||
(package-install 'swift-mode))
|
||||
|
||||
(unless (package-installed-p 'lsp-mode)
|
||||
(package-refresh-contents)
|
||||
(package-install 'lsp-mode))
|
||||
|
||||
;; Swift Mode
|
||||
(require 'swift-mode)
|
||||
(add-to-list 'auto-mode-alist '("\\.swift\\'" . swift-mode))
|
||||
|
||||
;; LSP Mode
|
||||
(require 'lsp-mode)
|
||||
(add-hook 'swift-mode-hook #'lsp)
|
||||
(use-package lsp-mode
|
||||
:ensure nil
|
||||
:commands lsp
|
||||
:config
|
||||
(add-hook 'swift-mode-hook #'lsp))
|
||||
|
||||
;; Set the path to SourceKit-LSP if it's not in your PATH
|
||||
(setq lsp-sourcekit-executable "/path/to/sourcekit-lsp")
|
||||
@@ -173,4 +163,3 @@ This makes evil-mode play nice with org-fc
|
||||
(setq lsp-sourcekit-executable-args '("-toolchain" "/path/to/swift-toolchain"))
|
||||
|
||||
#+end_src
|
||||
|
||||
|
||||
@@ -1011,6 +1011,7 @@ alphanumeric characters only."
|
||||
** org-roam
|
||||
#+begin_src emacs-lisp
|
||||
(use-package org-roam
|
||||
:if (file-directory-p (expand-file-name "~/org/roam/"))
|
||||
:after org
|
||||
:defer 1
|
||||
:preface
|
||||
@@ -1060,7 +1061,7 @@ alphanumeric characters only."
|
||||
org-roam-buffer-visibility-fn 'imalison:org-roam-frame-based-buffer-visibility-fn)
|
||||
(emit-make-mode-dependent imalison:org-roam-set-frame-visibility-mode frame-mode)))
|
||||
:custom
|
||||
(org-roam-directory (file-truename "~/org/roam/")))
|
||||
(org-roam-directory (expand-file-name "~/org/roam/")))
|
||||
#+end_src
|
||||
***** ui
|
||||
#+begin_src emacs-lisp
|
||||
|
||||
Reference in New Issue
Block a user