summaryrefslogtreecommitdiff
path: root/init.el
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2025-07-16 01:02:35 +0300
committerGravatar Uko Kokņevičs2025-07-16 01:02:35 +0300
commite543e54b76c1e97017c7e847dc7105ff95a10d6a (patch)
treea50b536b76b9f16e6460fe1782a2c711aaa0f700 /init.el
parentAdd swift-mode (diff)
downloaddotfiles-e543e54b76c1e97017c7e847dc7105ff95a10d6a.tar.gz
dotfiles-e543e54b76c1e97017c7e847dc7105ff95a10d6a.tar.xz
dotfiles-e543e54b76c1e97017c7e847dc7105ff95a10d6a.zip
Move Emacs stuff to emacs/.config/emacs
Diffstat (limited to 'init.el')
-rw-r--r--init.el436
1 files changed, 0 insertions, 436 deletions
diff --git a/init.el b/init.el
deleted file mode 100644
index 69dc9d1..0000000
--- a/init.el
+++ /dev/null
@@ -1,436 +0,0 @@
1;; -*- lexical-binding: t -*-
2;; Copyright © 2018-2025 Uko Koknevics
3
4;; Make sure early-init has been loaded.
5(unless (boundp 'loaded-early-init)
6 (load (expand-file-name "early-init" (file-name-directory load-file-name)) nil t))
7
8(when (version< emacs-version "29.1")
9 (error "Using %s. Minimum supported version is 29.1."
10 (emacs-version)))
11
12(setq-default user-full-name "Uko Kokņevičs"
13 user-email-address "perkontevs@gmail.com")
14
15(defconst +emacs29+ (version< emacs-version "30.0"))
16
17(defconst +linux+ (eq system-type 'gnu/linux))
18(defconst +mac+ (eq system-type 'darwin))
19(defconst +bsd+ (or +mac+ (eq system-type 'berkeley-unix)))
20(defconst +windows+ (memq system-type '(cygwin windows-nt ms-dos)))
21
22(defconst base-dir user-emacs-directory)
23(defconst local-dir (expand-file-name "local" base-dir))
24(defconst local-config-dir (expand-file-name "config" local-dir))
25(defconst tmp-dir (expand-file-name "tmp" local-dir))
26(defconst shared-dir (expand-file-name "shared" base-dir))
27
28;; TODO: Check how to do add smth like `:advice (fn :around advice)` sometime
29(require 'use-package)
30(use-package use-package)
31
32;; Early configurations
33(setq shared-game-score-directory (expand-file-name "shared-game-score" shared-dir))
34
35(use-package cus-edit
36 :defer t
37 :custom
38 (custom-file (expand-file-name "custom.el" shared-dir)))
39
40(defun $adv-write-to-sane-paths (fn &rest args)
41 "Write 3rd party files to `local-config-dir` to keep `user-emacs-directory` clean."
42 (let ((user-emacs-directory local-config-dir)
43 (user-init-file custom-file))
44 (apply fn args)))
45
46(use-package files
47 :defer t
48 :custom
49 (auto-mode-case-fold nil)
50 (auto-save-file-name-transforms `((".*" ,tmp-dir t)))
51 (backup-directory-alist `((".*" . ,tmp-dir)))
52 (major-mode-remap-alist '((c-mode . c-ts-mode)
53 (c-or-c++-mode . c-or-c++-ts-mode)
54 (c++-mode . c++-ts-mode)
55 (cmake-mode . cmake-ts-mode)
56 (csharp-mode . csharp-ts-mode)
57 (css-mode . css-ts-mode)
58 (dockerfile-mode . dockerfile-ts-mode)
59 (go-mode . go-ts-mode)
60 (go-mod-mode . go-mod-ts-mode)
61 (html-mode . mhtml-mode)
62 (java-mode . java-ts-mode)
63 (js-mode . js-ts-mode)
64 (json-mode . json-ts-mode)
65 (python-mode . python-ts-mode)
66 (ruby-mode . ruby-ts-mode)
67 (rust-mode . rust-ts-mode)
68 (yaml-mode . yaml-ts-mode)
69 (toml-mode . toml-ts-mode)
70 (tsx-mode . tsx-ts-mode)
71 (typescript-mode . typescript-ts-mode)))
72 :config
73 (advice-add #'locate-user-emacs-file :around #'$adv-write-to-sane-paths))
74
75(use-package novice
76 :defer t
77 :config
78 (advice-add #'enable-command :around #'$adv-write-to-sane-paths)
79 (advice-add #'disable-command :around #'$adv-write-to-sane-paths))
80
81;; Improve Emacs security somewhat
82(setq gnutls-min-prime-bits 3072
83 gnutls-verify-error (and (fboundp 'gnutls-available-p)
84 (gnutls-available-p)
85 (not (getenv-internal "INSECURE")))
86 tls-checktrust gnutls-verify-error
87 tls-program '("openssl s_client -connect %h:%p -CAfile %t -nbio -no_ssl3 -no_tls1 -no_tls1_1 -ign_eof"
88 "gnutls-cli -p %p --dh-bits=3072 --ocsp --x509cafile=%t --strict-tofu --priority='SECURE128:+SECURE192:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3' %h"
89 "gnutls-cli -p %p %h"))
90
91(when (boundp 'libgnutls-version)
92 (setq gnutls-algorithm-priority
93 (concat "SECURE128:+SECURE192:-VERS-ALL"
94 (if (and (not +windows+)
95 (>= libgnutls-version 30605))
96 ":+VERS-TLS1.3:+VERS-TLS1.2"
97 ":+VERS-TLS1.2"))))
98
99(when +mac+
100 (setq mac-option-modifier 'meta
101 mac-command-modifier 'super))
102
103(when (file-exists-p custom-file)
104 (add-hook 'elpaca-after-init-hook (lambda () (load custom-file 'noerror))))
105
106(use-package auth-source
107 :defer t
108 :custom
109 ;; Make sure authinfo is GPG'd
110 (auth-sources (list (expand-file-name "authinfo.gpg" local-config-dir)
111 "~/.authinfo.gpg")))
112
113(use-package ffap
114 :defer t
115 :custom
116 ;; Don't ping random stuff
117 (ffap-machine-p-known 'reject))
118
119(use-package startup
120 :defer t
121 :custom
122 (inhibit-default-init t)
123 (inhibit-startup-echo-area-message user-login-name)
124 (inhibit-startup-screen t)
125 (initial-major-mode 'fundamental-mode)
126 (initial-scratch-message nil))
127
128;; Don't draw stuff in other windows.
129(setq-default cursor-in-non-selected-windows nil)
130(setq highlight-nonselected-windows nil)
131
132;; Faster scrolling
133(setq fast-but-imprecise-scrolling t)
134
135;; Inhibit frame resizing
136(setq frame-inhibit-implied-resize t)
137
138;; Don’t compact font caches during GC.
139(setq inhibit-compacting-font-caches t)
140
141(setq read-process-output-max (* 64 1024))
142
143;; Don't fontify if stuck on reading input
144(setq redisplay-skip-fontification-on-input t)
145
146(when +windows+
147 (setq w32-get-true-file-attributes nil
148 w32-pipe-read-delay 0
149 w32-pipe-buffer-size read-process-output-max))
150
151;; Install elpaca
152(progn
153 (defvar elpaca-installer-version 0.11)
154 (defvar elpaca-directory (expand-file-name "elpaca/" local-dir))
155 (defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
156 (defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
157 (defvar elpaca-lock-file (expand-file-name "elpaca-lock.el" shared-dir))
158 (defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
159 :ref nil :depth 1 :inherit ignore
160 :files (:defaults "elpaca-test.el" (:exclude "extensions"))
161 :build (:not elpaca--activate-package)))
162 (let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory))
163 (build (expand-file-name "elpaca/" elpaca-builds-directory))
164 (order (cdr elpaca-order))
165 (default-directory repo))
166 (add-to-list 'load-path (if (file-exists-p build) build repo))
167 (unless (file-exists-p repo)
168 (make-directory repo t)
169 (when (<= emacs-major-version 28) (require 'subr-x))
170 (condition-case-unless-debug err
171 (if-let* ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
172 ((zerop (apply #'call-process `("git" nil ,buffer t "clone"
173 ,@(when-let* ((depth (plist-get order :depth)))
174 (list (format "--depth=%d" depth) "--no-single-branch"))
175 ,(plist-get order :repo) ,repo))))
176 ((zerop (call-process "git" nil buffer t "checkout"
177 (or (plist-get order :ref) "--"))))
178 (emacs (concat invocation-directory invocation-name))
179 ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
180 "--eval" "(byte-recompile-directory \".\" 0 'force)")))
181 ((require 'elpaca))
182 ((elpaca-generate-autoloads "elpaca" repo)))
183 (progn (message "%s" (buffer-string)) (kill-buffer buffer))
184 (error "%s" (with-current-buffer buffer (buffer-string))))
185 ((error) (warn "%s" err) (delete-directory repo 'recursive))))
186 (unless (require 'elpaca-autoloads nil t)
187 (require 'elpaca)
188 (elpaca-generate-autoloads "elpaca" repo)
189 (let ((load-source-file-function nil)) (load "./elpaca-autoloads"))))
190 (add-hook 'after-init-hook #'elpaca-process-queues)
191 (elpaca `(,@elpaca-order))
192 (when +windows+
193 (elpaca-no-symlink-mode)))
194
195(progn
196 (elpaca elpaca-use-package
197 (elpaca-use-package-mode))
198 (elpaca-wait))
199
200;; Builtins that I update with elpaca.
201;; Consider adding some to elpaca-ignored-dependencies if problems arise.
202(progn
203 (defun arkta/elpaca-build-with-unload (pkg)
204 (append (butlast (if (file-exists-p (file-name-concat elpaca-builds-directory
205 (symbol-name pkg)))
206 elpaca--pre-built-steps
207 elpaca-build-steps))
208 (list `(lambda (e)
209 (when (featurep ',pkg)
210 (unload-feature ',pkg t))
211 (elpaca--continue-build e))
212 'elpaca--activate-package)))
213 (use-package seq
214 :ensure `(seq :build ,(arkta/elpaca-build-with-unload 'seq)))
215 (use-package transient
216 :ensure `(transient :build ,(arkta/elpaca-build-with-unload 'transient))))
217
218(defun arkta/update-packages ()
219 (interactive)
220 (elpaca-update-all)
221 (elpaca-write-lock-file elpaca-lock-file))
222
223(defun arkta/fix-versions ()
224 (interactive)
225 (elpaca-write-lock-file elpaca-lock-file))
226
227;; compat
228(use-package compat-30
229 :if +emacs29+
230 :ensure 'compat)
231
232;; Helper functions
233(defmacro defsetter (name &rest emacs-names)
234 (let ((name (intern (concat "set-" (symbol-name name)))))
235 `(defun ,name (value &optional default)
236 (if default
237 (progn
238 ,@(mapcar (lambda (name) `(setq-default ,name value)) emacs-names))
239 ,@(mapcar (lambda (name) `(setq ,name value)) emacs-names)))))
240
241(defsetter fill-width fill-column)
242(defsetter tab-usage indent-tabs-mode)
243(defsetter tab-width c-basic-offset nasm-offset standard-indent tab-width)
244
245;; Miscellany
246
247(set-fill-width 120 t)
248(set-tab-usage nil t)
249(set-tab-width 4 t)
250
251;; HIC SVNT DRACONES
252
253(require 'arkta-cosmetic)
254(require 'arkta-progmodes)
255(require 'arkta-project)
256
257(use-package ace-window
258 :ensure t
259 :bind (([remap other-window] . ace-window)
260 ("C-x o" . ace-window)))
261
262(use-package amx
263 :ensure t
264 :config
265 (amx-mode +1))
266
267(use-package company
268 :ensure t
269 :custom
270 (company-format-margin-function #'company-text-icons-margin)
271 (company-text-face-extra-attributes '(:weight bold))
272 (company-text-icons-add-background t)
273 (company-tooltip-flip-when-above nil)
274 (company-tooltip-limit 6)
275 (company-tooltip-minimum 6)
276 (company-tooltip-offset-display 'lines)
277 :config
278 (global-company-mode +1))
279
280(use-package compile
281 :ensure nil
282 :bind (("C-c k" . compile))
283 :custom
284 (compilation-scroll-output 'first-error))
285
286(use-package copyright
287 :ensure nil
288 :init
289 (defun arkta/maybe-fix-copyright ()
290 (save-mark-and-excursion
291 (copyright-update)
292 (copyright-fix-years)))
293 :hook (before-save . arkta/maybe-fix-copyright)
294 :custom
295 (copyright-names-regexp "Eris\\|Ukko\\|Uko\\|Free Software")
296 (copyright-year-ranges t))
297
298(use-package counsel
299 :ensure t
300 :after amx
301 :config
302 (counsel-mode +1))
303
304(use-package dashboard
305 :ensure t
306 :demand t
307 :hook (server-after-make-frame . dashboard-open)
308 :custom
309 (dashboard-center-content nil)
310 (dashboard-startup-banner (expand-file-name "logo.png" user-emacs-directory))
311 (dashboard-items '((projects . 5) (recents . 5) (bookmarks . 5)))
312 (dashboard-projects-backend 'project-el)
313 (dashboard-remove-missing-entry nil)
314 (dashboard-set-heading-icons t)
315 (dashboard-set-file-icons t)
316 (dashboard-set-init-info t)
317 :config
318 (dashboard-setup-startup-hook))
319
320(use-package editorconfig
321 :ensure t
322 :config
323 (editorconfig-mode +1))
324
325(use-package eglot
326 :ensure nil
327 :hook ((gdscript-mode go-ts-mode) . eglot-ensure)
328 :custom
329 (eglot-ignored-server-capabilities '(:documentFormattingProvider
330 :documentRangeFormattingProvider
331 :documentOnTypeFormattingProvider))
332 (eglot-autoshutdown t))
333
334(use-package elpher
335 :ensure t
336 :commands (elpher)
337 :custom (elpher-default-url-type "gemini"))
338
339(use-package envrc
340 :when nil
341 :ensure t
342 ;; This actually has to be hooked to after-init to be one of the first minor modes enabled
343 :hook (elpaca-after-init . envrc-global-mode))
344
345(use-package forge
346 :ensure t
347 :after magit)
348
349(use-package gcmh
350 :ensure t
351 :custom
352 (gcmh-idle-delay 'auto)
353 (gcmh-auto-idle-delay-factor 10)
354 (gcmh-high-cons-threshold (* 16 1024 1024))
355 :config
356 (gcmh-mode +1))
357
358(use-package ibuffer
359 :ensure nil
360 :bind (("C-x C-b" . ibuffer)
361 ([remap list-buffers] . ibuffer)))
362
363(use-package ivy
364 :ensure t
365 :after (counsel swiper)
366 :demand t
367 :bind (("C-c r" . ivy-resume)
368 ("C-c v" . ivy-push-view)
369 ("C-c V" . ivy-pop-view))
370 :custom
371 (ivy-use-virtual-buffers t)
372 (ivy-count-format "(%d/%d) ")
373 :config
374 (ivy-mode +1))
375
376(use-package magit
377 ;; TODO: Do some proper setup
378 :ensure t)
379
380(use-package simple
381 :ensure nil
382 :hook ((text-mode . turn-on-auto-fill)
383 (before-save . delete-trailing-whitespace))
384 :custom
385 (backward-delete-char-untabify-method nil))
386
387(use-package swiper
388 :ensure t
389 :bind (([remap isearch-forward] . swiper-isearch)
390 ([remap isearch-backward] . swiper-isearch-backward)
391 ("C-s" . swiper-isearch)
392 ("C-r" . swiper-isearch-backward)))
393
394(use-package treemacs
395 :ensure t
396 :commands (treemacs treemacs-select-window)
397 :custom
398 (treemacs-select-when-already-in-treemacs 'next-or-back)
399 :bind (("C-c SPC" . treemacs-select-window)
400 ("C-c C-SPC" . treemacs-select-window)))
401
402(use-package treesit
403 :ensure nil
404 :config
405 (setq treesit-extra-load-path
406 (list (expand-file-name "tree-sitter" local-config-dir)))
407 (setq treesit-language-source-alist
408 '((c "https://github.com/tree-sitter/tree-sitter-c.git")
409 (cmake "https://github.com/uyha/tree-sitter-cmake.git")
410 (cpp "https://github.com/tree-sitter/tree-sitter-cpp.git")
411 (c-sharp "https://github.com/tree-sitter/tree-sitter-c-sharp.git")
412 (css "https://github.com/tree-sitter/tree-sitter-css.git")
413 (dockerfile "https://github.com/camdencheek/tree-sitter-dockerfile.git")
414 (go "https://github.com/tree-sitter/tree-sitter-go.git")
415 (gomod "https://github.com/camdencheek/tree-sitter-go-mod.git")
416 (java "https://github.com/tree-sitter/tree-sitter-java.git")
417 (javascript "https://github.com/tree-sitter/tree-sitter-javascript.git")
418 (json "https://github.com/tree-sitter/tree-sitter-json.git")
419 (kotlin "https://github.com/fwcd/tree-sitter-kotlin")
420 (python "https://github.com/tree-sitter/tree-sitter-python.git")
421 (ruby "https://github.com/tree-sitter/tree-sitter-ruby.git")
422 (rust "https://github.com/tree-sitter/tree-sitter-rust.git")
423 (toml "https://github.com/ikatyang/tree-sitter-toml.git")
424 (tsx "https://github.com/tree-sitter/tree-sitter-typescript.git" nil "tsx/src")
425 (typescript "https://github.com/tree-sitter/tree-sitter-typescript.git" nil "typescript/src")
426 (typst "https://github.com/uben0/tree-sitter-typst")
427 (yaml "https://github.com/ikatyang/tree-sitter-yaml.git")))
428 (mapc (lambda (spec)
429 (let ((name (car spec)))
430 (unless (treesit-language-available-p name)
431 (treesit-install-language-grammar name))))
432 treesit-language-source-alist))
433
434(use-package warnings
435 :ensure nil
436 :custom (warning-suppress-types '(comp)))