fedora-csb-system-manager
1;;; init.el --- init configuration file -*- lexical-binding: t; -*-
2
3;; Copyright (c) 2020-2023 Vincent Demeester <vincent@sbr.pm>
4
5;; Author: Vincent Demeester <vincent@sbr.pm>
6;; URL: https://git.sr.ht/~vdemeester/home
7;; Version: 0.1.0
8;; Package-Requires: ((emacs "29.1"))
9
10;; This file is NOT part of GNU Emacs.
11
12;; This file is free software: you can redistribute it and/or modify it
13;; under the terms of the GNU General Public License as published by the
14;; Free Software Foundation, either version 3 of the License, or (at
15;; your option) any later version.
16;;
17;; This file is distributed in the hope that it will be useful, but
18;; WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20;; General Public License for more details.
21;;
22;; You should have received a copy of the GNU General Public License
23;; along with this file. If not, see <http://www.gnu.org/licenses/>.
24
25;;; Commentary:
26
27;; See my dotfiles: https://git.sr.ht/~vdemeester/home
28
29;;; Code:
30
31
32(defconst emacs-start-time (current-time))
33
34(let ((minver 29))
35 (unless (>= emacs-major-version minver)
36 (error "Your Emacs is too old -- this configuration requires v%s or higher" minver)))
37
38(setq inhibit-default-init t) ; Disable the site default settings
39
40(setq confirm-kill-emacs #'y-or-n-p)
41(setq initial-major-mode 'fundamental-mode
42 initial-scratch-message nil)
43
44;; Might not work as well on Windows but meh, I don't use it.
45(prefer-coding-system 'utf-8)
46(set-default-coding-systems 'utf-8)
47(set-language-environment 'utf-8)
48(set-selection-coding-system 'utf-8)
49(set-terminal-coding-system 'utf-8)
50
51(setq custom-file (locate-user-emacs-file "custom.el"))
52(setq
53 custom-buffer-done-kill nil ; Kill when existing
54 custom-buffer-verbose-help nil ; Remove redundant help text
55 custom-unlispify-tag-names nil ; Show me the real variable name
56 custom-unlispify-menu-entries nil)
57;; Create the custom-file if it doesn't exists
58(unless (file-exists-p custom-file)
59 (write-region "" nil custom-file))
60(load custom-file :no-error-if-file-is-missing)
61
62(setq echo-keystrokes 0.1) ;; display command keystrokes quickly
63
64(global-unset-key (kbd "C-z"))
65(global-unset-key (kbd "C-x C-z"))
66(global-unset-key (kbd "C-h h"))
67
68;; Disable owerwrite-mode, iconify-frame and diary
69(mapc
70 (lambda (command)
71 (put command 'disabled t))
72 '(overwrite-mode iconify-frame diary))
73;; And enable those commands (disabled by default)
74(mapc
75 (lambda (command)
76 (put command 'disabled nil))
77 '(list-timers narrow-to-region narrow-to-page upcase-region downcase-region))
78
79(defun prot/keyboard-quit-dwim ()
80 "Do-What-I-Mean behaviour for a general `keyboard-quit'.
81
82The generic `keyboard-quit' does not do the expected thing when
83the minibuffer is open. Whereas we want it to close the
84minibuffer, even without explicitly focusing it.
85
86The DWIM behaviour of this command is as follows:
87
88- When the region is active, disable it.
89- When a minibuffer is open, but not focused, close the minibuffer.
90- When the Completions buffer is selected, close it.
91- In every other case use the regular `keyboard-quit'."
92 (interactive)
93 (cond
94 ((region-active-p)
95 (keyboard-quit))
96 ((derived-mode-p 'completion-list-mode)
97 (delete-completion-window))
98 ((> (minibuffer-depth) 0)
99 (abort-recursive-edit))
100 (t
101 (keyboard-quit))))
102
103(define-key global-map (kbd "C-g") #'prot/keyboard-quit-dwim)
104
105(add-to-list 'load-path (concat user-emacs-directory "/lisp/"))
106(add-to-list 'load-path (concat user-emacs-directory "/lisp/aider.el"))
107(add-to-list 'load-path (concat user-emacs-directory "/lisp/auto-side-windows"))
108(add-to-list 'load-path (concat user-emacs-directory "/lisp/consult-mu"))
109(add-to-list 'load-path (concat user-emacs-directory "/lisp/consult-mu/extras"))
110(add-to-list 'load-path (concat user-emacs-directory "/config/"))
111
112(unless noninteractive
113 (defconst font-height 130
114 "Default font-height to use.")
115 ;; 2024-10-05: Switching from Ubuntu Mono to Cascadia Mono
116 ;; 2024-96-06: Switching from Cascadia Mono to JetBrains Mono
117 (defconst font-family-mono "JetBrains Mono"
118 "Default monospace font-family to use.")
119 (defconst font-family-sans "Ubuntu Sans"
120 "Default sans font-family to use.")
121 ;; Middle/Near East: שלום, السّلام عليكم
122 (when (member "Noto Sans Arabic" (font-family-list))
123 (set-fontset-font t 'arabic "Noto Sans Arabic"))
124 (when (member "Noto Sans Hebrew" (font-family-list))
125 (set-fontset-font t 'arabic "Noto Sans Hebrew"))
126 ;; Africa: ሠላም
127 (when (member "Noto Sans Ethiopic" (font-family-list))
128 (set-fontset-font t 'ethiopic "Noto Sans Ethiopic"))
129
130 ;; If font-family-mono or font-family-sans are not available, use the default Emacs face
131 (set-face-attribute 'default nil
132 :family font-family-mono
133 :height font-height
134 :weight 'regular)
135 (set-face-attribute 'fixed-pitch nil
136 :family font-family-mono
137 :weight 'medium
138 :height font-height)
139 (set-face-attribute 'variable-pitch nil
140 :family font-family-sans
141 :weight 'regular)
142
143 (set-fontset-font t 'symbol "Apple Color Emoji")
144 (set-fontset-font t 'symbol "Noto Color Emoji" nil 'append)
145 (set-fontset-font t 'symbol "Segoe UI Emoji" nil 'append)
146 (set-fontset-font t 'symbol "Symbola" nil 'append)
147
148 (defvar contrib/after-load-theme-hook nil
149 "Hook run after a color theme is loaded using `load-theme'.")
150
151 (defun contrib/run-after-load-theme-hook (&rest _)
152 "Run `contrib/after-load-theme-hook'."
153 (run-hooks 'contrib/after-load-theme-hook))
154
155 (advice-add #'load-theme :after #'contrib/run-after-load-theme-hook)
156
157 (require 'modus-themes)
158 (setq modus-themes-to-toggle '(modus-operandi modus-vivendi)
159 modus-themes-slanted-constructs nil
160 modus-themes-italic-constructs nil
161 modus-themes-bold-constructs nil
162 modus-themes-mixed-fonts t
163 modus-themes-subtle-diffs t
164 modus-themes-fringes 'subtle ; {nil,'subtle,'intense}
165 modus-themes-headings '((0 . (variable-pitch semilight 1.5))
166 (1 . (regular 1.4))
167 (2 . (regular 1.3))
168 (3 . (regular 1.2))
169 (agenda-structure . (variable-pitch light 2.2))
170 (agenda-date . (variable-pitch regular 1.3))
171 (t . (regular 1.15)))
172 modus-themes-intense-paren-match t
173 modus-themes-completions '(opinionated) ; {nil,'moderate,'opinionated}
174 modus-themes-diffs 'desaturated ; {nil,'desaturated,'fg-only}
175 modus-themes-org-blocks 'gray-background
176 modus-themes-paren-match '(subtle-bold)
177 modus-themes-variable-pitch-headings nil
178 modus-themes-rainbow-headings t
179 modus-themes-section-headings nil
180 modus-themes-scale-headings t
181 )
182
183 (defun my-update-active-mode-line-colors ()
184 (set-face-attribute
185 'mode-line nil
186 :foreground (modus-themes-get-color-value 'fg-mode-line-active)
187 :background (modus-themes-get-color-value 'bg-blue-nuanced)))
188 (add-hook 'modus-themes-after-load-theme-hook #'my-update-active-mode-line-colors)
189 (define-key global-map (kbd "C-<f5>") #'modus-themes-toggle)
190
191 (load-theme 'modus-operandi :no-confirm)
192 (my-update-active-mode-line-colors))
193
194(setq load-prefer-newer t) ; Always load newer compiled files
195(setq ad-redefinition-action 'accept) ; Silence advice redefinition warnings
196
197;; Init `delight'
198;; (unless (package-installed-p 'delight)
199;; (package-refresh-contents)
200;; (package-install 'delight))
201
202;; Configure `use-package' prior to loading it.
203(eval-and-compile
204 (setq use-package-always-ensure nil)
205 (setq use-package-always-defer nil)
206 (setq use-package-always-demand nil)
207 (setq use-package-expand-minimally nil)
208 (setq use-package-enable-imenu-support t)
209 (setq use-package-compute-statistics t))
210
211;; (unless (package-installed-p 'use-package)
212;; (package-refresh-contents)
213;; (package-install 'use-package))
214
215(eval-when-compile
216 (require 'use-package))
217
218(setenv "SSH_AUTH_SOCK" "/run/user/1000/yubikey-agent/yubikey-agent.sock")
219;; (setenv "SSH_AUTH_SOCK" "/run/user/1000/gnupg/S.gpg-agent.ssh")
220
221(defconst vde/custom-file (locate-user-emacs-file "custom.el")
222 "File used to store settings from Customization UI.")
223
224;; Remove built-in org-mode
225(require 'cl-seq)
226(setq load-path
227 (cl-remove-if
228 (lambda (x)
229 (string-match-p "org$" x))
230 load-path))
231
232;; 2024-07-12: I wonder if I should be explicit instead, as using
233;; `require' explicitly. The benefit would be that I decide the order
234;; they load instead of relying on file-system.
235;; (vde/el-load-dir (concat user-emacs-directory "/config/"))
236(require 'init-func)
237(require 'org-func)
238(require 'project-func)
239
240;; Make native compilation silent and prune its cache.
241(when (native-comp-available-p)
242 (setq native-comp-async-report-warnings-errors 'silent) ; Emacs 28 with native compilation
243 (setq native-compile-prune-cache t)
244 (setq native-comp-jit-compilation t)
245 (setq native-comp-async-query-on-exit t)) ; Emacs 29
246
247(setq byte-compile-warnings '(not free-vars unresolved noruntime lexical make-local))
248
249;; Refactor this completely. Reduce to the minimum.
250(unless noninteractive
251 (require '00-clean) ;; Maybe refactor no-littering
252 (require 'config-keybindings)
253 (require 'config-editing)
254 (require 'config-files)
255 (require 'config-misc)
256 (require 'config-appearance)
257 (require 'config-buffers)
258 (require 'config-compile)
259 (require 'config-completion)
260 (require 'config-dired)
261 (require 'config-mouse)
262 (require 'config-navigating)
263 (require 'config-org)
264 (require 'config-programming)
265 (require 'config-projects)
266 (require 'config-search)
267 (require 'config-shells)
268 (require 'config-vcs)
269 (require 'config-web)
270 (require 'config-windows)
271 (require 'config-llm)
272 (require 'programming-config)
273 (require 'programming-containers)
274 (require 'programming-cue)
275 (require 'programming-elisp)
276 (require 'programming-eglot)
277 (require 'programming-go)
278 (require 'programming-js)
279 (require 'programming-nix)
280 (require 'programming-treesitter)
281 (require 'programming-web)
282 (require 'config-mu4e))
283
284(if (file-exists-p (downcase (concat user-emacs-directory "/hosts/" (vde/short-hostname) ".el")))
285 (load-file (downcase (concat user-emacs-directory "/hosts/" (vde/short-hostname) ".el"))))
286
287(let ((elapsed (float-time (time-subtract (current-time)
288 emacs-start-time))))
289 (message "Loading %s...done (%.3fs)" load-file-name elapsed))
290
291(add-hook 'after-init-hook
292 `(lambda ()
293 (let ((elapsed
294 (float-time
295 (time-subtract (current-time) emacs-start-time))))
296 (message "Loading %s...done (%.3fs) [after-init]"
297 ,load-file-name elapsed))) t)