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)