-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinit.el
More file actions
109 lines (97 loc) · 4.63 KB
/
Copy pathinit.el
File metadata and controls
109 lines (97 loc) · 4.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
;;; init.el --- User Emacs config bootstrap -*- lexical-binding: t -*-
;;; Commentary:
;; Bootstrap order:
;; 1. Configure package archives and bootstrap a few packages we rely on
;; before any `use-package' clauses run.
;; 2. Resolve the shell PATH so external tooling (LSP servers, formatters)
;; is reachable.
;; 3. Enable `envrc-global-mode' for direnv/nix project environments.
;; 4. Auto-load every .el file in customizations/ in alphabetic order. The
;; numeric prefixes on core modules (00-, 10-, ...) and the `lang-'
;; prefix on language modules document and enforce load order.
;; 5. Load `custom.el' (auto-generated, gitignored) for customize-driven
;; settings.
;; 6. Load `local.el' last (gitignored, optional) for per-machine overrides.
;;; Code:
(require 'package)
;; Workaround for Emacs 30 GnuTLS error -54 (PULL_ERROR) when negotiating
;; TLS 1.3 with elpa.gnu.org. Disabling TLS 1.3 forces a working handshake;
;; MELPA works either way. Without this, package-refresh-contents silently
;; fails for the ELPA archive and any package whose deps live there
;; (e.g. lsp-mode -> spinner) cannot be installed on a fresh checkout.
(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("melpa-stable" . "https://stable.melpa.org/packages/")
("elpa" . "https://elpa.gnu.org/packages/")))
(package-initialize)
;; Retry package installs to handle transient network/archive failures.
(defvar my/package-bootstrap-max-retries 3)
(defvar my/package-bootstrap-retry-delay 2)
(defun my/ensure-package-with-retries (pkg &optional retries delay)
(let* ((max-attempts (or retries my/package-bootstrap-max-retries))
(retry-delay (or delay my/package-bootstrap-retry-delay))
(attempt 1)
(installed (package-installed-p pkg))
last-error)
(while (and (not installed) (<= attempt max-attempts))
(condition-case err
(progn
(package-refresh-contents)
(package-install pkg)
(setq installed (package-installed-p pkg)))
(error
(setq last-error err)
(when (< attempt max-attempts)
(sleep-for retry-delay))))
(setq attempt (1+ attempt)))
(unless installed
(error
"Failed to install `%s` after %d attempt(s): %s"
pkg
max-attempts
(if last-error (error-message-string last-error) "unknown error")))
installed))
(defun my/ensure-required-packages ()
"Install packages that customization files depend on at load time."
(dolist (pkg '(flycheck lsp-mode ruff-format))
(my/ensure-package-with-retries pkg)))
(my/ensure-required-packages)
;; Copy PATH from a deterministic login shell.
;; launchctl can set SHELL to /bin/sh for daemon sessions, so we map by OS.
(let* ((preferred-shell (cond
((eq system-type 'darwin) "/bin/zsh")
((eq system-type 'gnu/linux) "/bin/bash")
(t "/bin/sh")))
(login-shell (if (file-exists-p preferred-shell)
preferred-shell
"/bin/sh"))
(shell-path-cmd (format "%s -l -c 'printf %%s \"$PATH\"'"
(shell-quote-argument login-shell)))
(shell-path (string-trim-right (shell-command-to-string shell-path-cmd)))
(path (concat (getenv "HOME") "/.asdf/shims:" shell-path)))
(setenv "PATH" path)
(setq exec-path (parse-colon-path path)))
(use-package envrc
:ensure t
:config
(envrc-global-mode)
(setq envrc-show-summary-in-minibuffer nil))
;; Auto-load every .el file under customizations/ in alphabetic order.
;; To add a new module, drop a file in customizations/ — no edits to init.el
;; needed. Use numeric prefixes (00-, 10-, ...) on core modules to control
;; load order, and the `lang-' prefix for language modules.
(let ((customizations-dir (expand-file-name "customizations" user-emacs-directory)))
(add-to-list 'load-path customizations-dir)
(dolist (file (directory-files customizations-dir t "\\.el\\'"))
(load (file-name-sans-extension file))))
;; Make GC pauses faster after init by lowering the threshold.
(setq gc-cons-threshold (* 2 1000 1000))
;; Auto-generated by Emacs's customize system; gitignored.
(setq custom-file (concat user-emacs-directory "custom.el"))
(load custom-file 'noerror)
;; Per-machine overrides (gitignored). Loaded last so it can shadow anything.
(let ((local (concat user-emacs-directory "local.el")))
(when (file-exists-p local)
(load local 'noerror)))
(provide 'init)
;;; init.el ends here